1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <math.h>
6#include <stdio.h>
7
8#include "ppapi_simple/ps.h"
9#include "ppapi_simple/ps_context_2d.h"
10#include "ppapi_simple/ps_event.h"
11#include "ppapi_simple/ps_interface.h"
12#include "ppapi_simple/ps_main.h"
13
14#ifdef WIN32
15#undef PostMessage
16#endif
17
18namespace {
19
20const int kMaxPointCount = 1000000000;  // The total number of points to draw.
21const double kSecsPerFrame = 0.005;  // How long to draw points before swapping.
22const uint32_t kOpaqueColorMask = 0xff000000;  // Opaque pixels.
23const uint32_t kRedMask = 0xff0000;
24const uint32_t kBlueMask = 0xff;
25const uint32_t kRedShift = 16;
26const uint32_t kBlueShift = 0;
27
28int g_points_in_circle = 0;
29int g_total_points = 0;
30double g_pi = 0;
31
32}  // namespace
33
34bool Render(PSContext2D_t* ctx) {
35  PSContext2DGetBuffer(ctx);
36
37  if (NULL == ctx->data)
38    return true;
39
40  PP_TimeTicks start_time = PSInterfaceCore()->GetTimeTicks();
41  while (PSInterfaceCore()->GetTimeTicks() - start_time < kSecsPerFrame) {
42    double x = static_cast<double>(rand()) / RAND_MAX;
43    double y = static_cast<double>(rand()) / RAND_MAX;
44    double distance = sqrt(x * x + y * y);
45    int px = x * ctx->width;
46    int py = (1.0 - y) * ctx->height;
47    uint32_t color = ctx->data[ctx->width * py + px];
48
49    ++g_total_points;
50    if (distance < 1.0) {
51      ++g_points_in_circle;
52      g_pi = 4.0 * g_points_in_circle / g_total_points;
53      // Set color to blue.
54      color += 4 << kBlueShift;
55      color &= kBlueMask;
56    } else {
57      // Set color to red.
58      color += 4 << kRedShift;
59      color &= kRedMask;
60    }
61    ctx->data[ctx->width * py + px] = color | kOpaqueColorMask;
62  }
63
64  PSContext2DSwapBuffer(ctx);
65  return g_total_points != kMaxPointCount;
66}
67
68/*
69 * Starting point for the module.  We do not use main since it would
70 * collide with main in libppapi_cpp.
71 */
72int example_main(int argc, char* argv[]) {
73  unsigned int seed = 1;
74  srand(seed);
75
76  PSEventSetFilter(PSE_ALL);
77
78  PSContext2D_t* ctx = PSContext2DAllocate(PP_IMAGEDATAFORMAT_BGRA_PREMUL);
79  bool running = true;
80  while (running) {
81    PSEvent* event;
82
83    // Consume all available events
84    while ((event = PSEventTryAcquire()) != NULL) {
85      PSContext2DHandleEvent(ctx, event);
86      PSEventRelease(event);
87    }
88
89    if (ctx->bound) {
90      running = Render(ctx);
91    }
92
93    // Send the current PI value to JavaScript.
94    PP_Var var = PP_MakeDouble(g_pi);
95    PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), var);
96  }
97
98  return 0;
99}
100
101/*
102 * Register the function to call once the Instance Object is initialized.
103 * see: pappi_simple/ps_main.h
104 */
105PPAPI_SIMPLE_REGISTER_MAIN(example_main);
106