Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: native_client_sdk/src/examples/demo/life/life.c

Issue 15011003: ppapi_simple (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove raw Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Native Client SDK Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can
3 // be found in the LICENSE file.
4
5 #include <assert.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "ppapi/c/pp_resource.h"
11 #include "ppapi/c/ppb_core.h"
12 #include "ppapi/c/ppb_fullscreen.h"
13 #include "ppapi/c/ppb_graphics_2d.h"
14 #include "ppapi/c/ppb_image_data.h"
15 #include "ppapi/c/ppb_input_event.h"
16 #include "ppapi/c/ppb_instance.h"
17 #include "ppapi/c/ppb_view.h"
18
19 #include "ppapi_simple/ppapi_event.h"
20 #include "ppapi_simple/ppapi_simple_main.h"
21
22 PPB_Core* g_pCore;
23 PPB_Fullscreen* g_pFullscreen;
24 PPB_Graphics2D* g_pGraphics2D;
25 PPB_ImageData* g_pImageData;
26 PPB_Instance* g_pInstance;
27 PPB_View* g_pView;
28 PPB_InputEvent* g_pInputEvent;
29 PPB_KeyboardInputEvent* g_pKeyboardInput;
30 PPB_MouseInputEvent* g_pMouseInput;
31 PPB_TouchInputEvent* g_pTouchInput;
32
33 struct {
34 PP_Resource ctx;
35 struct PP_Size size;
36 int bound;
37 uint8_t* cell_in;
38 uint8_t* cell_out;
39 } g_Context;
40
41
42 const unsigned int kInitialRandSeed = 0xC0DE533D;
43
44 #define MakeRGBA(r, g, b, a) \
45 (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
46
47 // Given a count of cells in a 3x3 grid where cells are worth 1 except for
48 // the center which is worth 9, this is a color representation of how
49 // "alive" that cell is making for a more interesting representation than
50 // a binary alive or dead.
51 const uint32_t kNeighborColors[] = {
52 MakeRGBA(0x00, 0x00, 0x00, 0xff),
53 MakeRGBA(0x00, 0x40, 0x00, 0xff),
54 MakeRGBA(0x00, 0x60, 0x00, 0xff),
55 MakeRGBA(0x00, 0x80, 0x00, 0xff),
56 MakeRGBA(0x00, 0xA0, 0x00, 0xff),
57 MakeRGBA(0x00, 0xC0, 0x00, 0xff),
58 MakeRGBA(0x00, 0xE0, 0x00, 0xff),
59 MakeRGBA(0x00, 0x00, 0x00, 0xff),
60 MakeRGBA(0x00, 0x40, 0x00, 0xff),
61 MakeRGBA(0x00, 0x60, 0x00, 0xff),
62 MakeRGBA(0x00, 0x80, 0x00, 0xff),
63 MakeRGBA(0x00, 0xA0, 0x00, 0xff),
64 MakeRGBA(0x00, 0xC0, 0x00, 0xff),
65 MakeRGBA(0x00, 0xE0, 0x00, 0xff),
66 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
67 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
68 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
69 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
70 };
71
72 // These represent the new health value of a cell based on its neighboring
73 // values. The health is binary: either alive or dead.
74 const uint8_t kIsAlive[] = {
75 0, 0, 0, 1, 0, 0, 0, 0, 0, // Values if the center cell is dead.
76 0, 0, 1, 1, 0, 0, 0, 0, 0 // Values if the center cell is alive.
77 };
78
79
80 void UpdateContext(uint32_t width, uint32_t height) {
81 size_t size = width * height;
82 size_t index;
83
84 free(g_Context.cell_in);
85 free(g_Context.cell_out);
86
87 //
88 // Create a new context
89 //
90 g_Context.cell_in = (uint8_t*) malloc(size);
91 g_Context.cell_out = (uint8_t*) malloc(size);
92
93 memset(g_Context.cell_out, 0, size);
94 for (index = 0; index < size; index++) {
95 g_Context.cell_in[index] = rand() & 1;
96 }
97 }
98
99 void ProcessEvent(PSEvent* event) {
100 switch(event->type) {
101 /* If the view updates, build a new Graphics 2D Context */
102 case PS_VIEW_EVENT: {
103 struct PP_Rect rect;
104 int32_t width;
105 int32_t height;
106 if (g_Context.ctx) {
107 g_pCore->ReleaseResource(g_Context.ctx);
108 g_Context.ctx = 0;
109 }
110
111 g_pView->GetRect(event->as_resource, &rect);
112 width = rect.size.width;
113 height = rect.size.height;
114
115 if (width != g_Context.size.width || height != g_Context.size.height) {
116 UpdateContext(rect.size.width, rect.size.height);
nfullagar1 2013/05/28 18:28:53 small nit - UpdateContext() sounds like it should
noelallen_use_chromium 2013/05/30 00:25:07 Done.
117 }
118 if (width != g_Context.size.width || height != g_Context.size.height ||
119 !g_Context.bound) {
120 g_Context.ctx =
121 g_pGraphics2D->Create(PSGetInstanceId(), &rect.size, PP_TRUE);
122 g_Context.bound =
123 g_pInstance->BindGraphics(PSGetInstanceId(), g_Context.ctx);
124 g_Context.size = rect.size;
125 }
126 break;
127 }
128
129 case PS_INPUT_EVENT: {
nfullagar1 2013/05/28 18:28:53 small nit on PS_INPUT_EVENT: PPAPI doesn't have an
noelallen_use_chromium 2013/05/30 00:25:07 Done.
130 PP_InputEvent_Type type = g_pInputEvent->GetType(event->as_resource);
131 PP_InputEvent_Modifier modifiers =
132 g_pInputEvent->GetModifiers(event->as_resource);
133 int32_t width = g_Context.size.width;
134 int32_t height = g_Context.size.height;
135
136 switch(type) {
137 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
138 {
139 struct PP_Point location =
140 g_pMouseInput->GetPosition(event->as_resource);
141
142 if (!g_Context.cell_in) break;
143
144 // If the button is down, draw
145 if (modifiers & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
146 int x = location.x;
147 int y = location.y;
148
149 if (x > 0 && x < width && y > 0 && y < height) {
150 g_Context.cell_in[x - 1 + y * width] = 1;
151 g_Context.cell_in[x + 1 + y * width] = 1;
152 g_Context.cell_in[x + (y - 1) * width] = 1;
153 g_Context.cell_in[x + (y + 1) * width] = 1;
154 }
155 }
156 }
157 break;
158
159 case PP_INPUTEVENT_TYPE_KEYUP: {
160 PP_Bool fullscreen = g_pFullscreen->IsFullscreen(PSGetInstanceId());
161 g_pFullscreen->SetFullscreen(PSGetInstanceId(),
162 fullscreen ? PP_FALSE : PP_TRUE);
163 break;
164 }
165
166 default:
167 break;
168 }
169 break;
170 }
171
172 default:
173 break;
174 }
175 }
176
177
178 void Stir(uint32_t width, uint32_t height) {
179 int i;
180 if (g_Context.cell_in == NULL || g_Context.cell_out == NULL)
181 return;
182
183 for (i = 0; i < width; ++i) {
184 g_Context.cell_in[i] = rand() & 1;
185 g_Context.cell_in[i + (height - 1) * width] = rand() & 1;
186 }
187 for (i = 0; i < height; ++i) {
188 g_Context.cell_in[i * width] = rand() & 1;
189 g_Context.cell_in[i * width + (width - 1)] = rand() & 1;
190 }
191 }
192
193 void Render() {
194 struct PP_Size* psize = &g_Context.size;
195 PP_ImageDataFormat format = g_pImageData->GetNativeImageDataFormat();
196
197 // Create a buffer to draw into. Since we are waiting until the next flush
198 // chrome has an opportunity to cache this buffer see ppb_graphics_2d.h.
199 PP_Resource image =
200 g_pImageData->Create(PSGetInstanceId(), format, psize, PP_FALSE);
201 uint8_t* pixels = g_pImageData->Map(image);
202
203 struct PP_ImageDataDesc desc;
204 uint8_t* cell_temp;
205 uint32_t x, y;
206
207 // If we somehow have not allocated these pointers yet, skip this frame.
208 if (!g_Context.cell_in || !g_Context.cell_out) return;
209
210 // Get the stride
211 g_pImageData->Describe(image, &desc);
212
213 // Stir up the edges to prevent the simulation from reaching steady state.
214 Stir(desc.size.width, desc.size.height);
215
216 // Do neighbor summation; apply rules, output pixel color.
217 for (y = 1; y < desc.size.height - 1; ++y) {
218 uint8_t *src0 = (g_Context.cell_in + (y - 1) * desc.size.width) + 1;
219 uint8_t *src1 = src0 + desc.size.width;
220 uint8_t *src2 = src1 + desc.size.width;
221 int count;
222 uint32_t color;
223 uint8_t *dst = (g_Context.cell_out + y * desc.size.width) + 1;
224 uint32_t *pixel_line = (uint32_t*) (pixels + y * desc.stride);
225
226 for (x = 1; x < (desc.size.width - 1); ++x) {
227 // Build sum, weight center by 9x.
228 count = src0[-1] + src0[0] + src0[1] +
229 src1[-1] + src1[0] * 9 + src1[1] +
230 src2[-1] + src2[0] + src2[1];
231 color = kNeighborColors[count];
232
233 *pixel_line++ = color;
234 *dst++ = kIsAlive[count];
235 ++src0;
236 ++src1;
237 ++src2;
238 }
239 }
240
241 cell_temp = g_Context.cell_in;
242 g_Context.cell_in = g_Context.cell_out;
243 g_Context.cell_out = cell_temp;
244
245 /* Unmap the range, we no longer need it. */
246 g_pImageData->Unmap(image);
247
248 /* Replace the contexts, and block until it's on the screen. */
249 g_pGraphics2D->ReplaceContents(g_Context.ctx, image);
250 g_pGraphics2D->Flush(g_Context.ctx, PP_BlockUntilComplete());
251
252 /* Release the image data, we no longer need it. */
253 g_pCore->ReleaseResource(image);
254 }
255
256 // Starting point for the module. We do not use main since it would
257 // collide with main in libppapi_cpp.
258 int example_main(int argc, const char *argv[]) {
259 fprintf(stdout,"Started main.\n");
260 g_pCore = (PPB_Core*)PSGetInterface(PPB_CORE_INTERFACE);
261 g_pFullscreen = (PPB_Fullscreen*)PSGetInterface(PPB_FULLSCREEN_INTERFACE);
262 g_pGraphics2D = (PPB_Graphics2D*)PSGetInterface(PPB_GRAPHICS_2D_INTERFACE);
263 g_pInstance = (PPB_Instance*)PSGetInterface(PPB_INSTANCE_INTERFACE);
264 g_pImageData = (PPB_ImageData*)PSGetInterface(PPB_IMAGEDATA_INTERFACE);
265 g_pView = (PPB_View*)PSGetInterface(PPB_VIEW_INTERFACE);
266
267 g_pInputEvent =
268 (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
269 g_pKeyboardInput = (PPB_KeyboardInputEvent*)
270 PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
271 g_pMouseInput =
272 (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
273 g_pTouchInput =
274 (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
275
276 PSSetEventFilter(PS_ALL_EVENTS);
277 while (1) {
278 /* Process all waiting events without blocking */
279 PSEvent* event;
280 while ((event = PSTryToAcquireEvent()) != NULL) {
281 ProcessEvent(event);
282 PSReleaseEvent(event);
283 }
284
285 /* Render a frame, blocking until complete. */
286 if (g_Context.bound) {
287 Render();
288 }
289 }
290 return 0;
291 }
292
293 // Regsiter the function to call once the Instance Object is initialized.
294 // see: pappi_simple/ppapi_simple.h
nfullagar1 2013/05/28 18:28:53 small nit for comment above: ppapi_simple.h has PP
noelallen_use_chromium 2013/05/30 00:25:07 Done.
295 PPAPI_SIMPLE_REGISTER_MAIN(example_main);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698