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

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: Restore images 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 2011 The Native Client SDK Authors. All rights reserved.
binji 2013/05/23 18:06:49 2013
noelallen1 2013/05/30 18:07:18 Done.
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_graphics_2d.h"
13 #include "ppapi/c/ppb_image_data.h"
14 #include "ppapi/c/ppb_input_event.h"
15 #include "ppapi/c/ppb_instance.h"
16 #include "ppapi/c/ppb_view.h"
17
18 #include "ppapi_simple/ppapi_event.h"
19 #include "ppapi_simple/ppapi_simple_main.h"
20
21 PPB_Core* g_pCore;
22 PPB_Graphics2D* g_pGraphics2D;
23 PPB_ImageData* g_pImageData;
24 PPB_Instance* g_pInstance;
25 PPB_View* g_pView;
26 PPB_InputEvent* g_pInputEvent;
27 PPB_KeyboardInputEvent* g_pKeyboardInput;
28 PPB_MouseInputEvent* g_pMouseInput;
29 PPB_TouchInputEvent* g_pTouchInput;
30
31 struct {
binji 2013/05/23 18:06:49 why store this is a struct instead of individual g
noelallen1 2013/05/23 22:01:24 Just for organization reasons.
32 PP_Resource ctx_;
binji 2013/05/23 18:06:49 public members for structs don't have trailing _
noelallen1 2013/05/23 22:01:24 Done.
33 struct PP_Size size_;
34 int bound_;
35 uint8_t* cell_in_;
36 uint8_t* cell_out_;
37 } g_Context;
38
39
40 const unsigned int kInitialRandSeed = 0xC0DE533D;
41
42 #define MakeRGBA(r, g, b, a) \
43 (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
44
45 // Map of neighboring colors.
binji 2013/05/23 18:06:49 these numbers seem pretty random. Maybe explain a
noelallen1 2013/05/23 22:01:24 Done.
46 const uint32_t kNeighborColors[] = {
47 MakeRGBA(0x00, 0x00, 0x00, 0xff),
48 MakeRGBA(0x00, 0x40, 0x00, 0xff),
49 MakeRGBA(0x00, 0x60, 0x00, 0xff),
50 MakeRGBA(0x00, 0x80, 0x00, 0xff),
51 MakeRGBA(0x00, 0xA0, 0x00, 0xff),
52 MakeRGBA(0x00, 0xC0, 0x00, 0xff),
53 MakeRGBA(0x00, 0xE0, 0x00, 0xff),
54 MakeRGBA(0x00, 0x00, 0x00, 0xff),
55 MakeRGBA(0x00, 0x40, 0x00, 0xff),
56 MakeRGBA(0x00, 0x60, 0x00, 0xff),
57 MakeRGBA(0x00, 0x80, 0x00, 0xff),
58 MakeRGBA(0x00, 0xA0, 0x00, 0xff),
59 MakeRGBA(0x00, 0xC0, 0x00, 0xff),
60 MakeRGBA(0x00, 0xE0, 0x00, 0xff),
61 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
62 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
63 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
64 MakeRGBA(0x00, 0xFF, 0x00, 0xff),
65 };
66
67 // These represent the new health value of a cell based on its neighboring
68 // values. The health is binary: either alive or dead.
69 const uint8_t kIsAlive[] = {
70 0, 0, 0, 1, 0, 0, 0, 0, 0, // Values if the center cell is dead.
71 0, 0, 1, 1, 0, 0, 0, 0, 0 // Values if the center cell is alive.
72 };
73
74
75 void UpdateContext(uint32_t width, uint32_t height) {
76 size_t size = width * height;
77 size_t index;
78
79 free(g_Context.cell_in_);
80 free(g_Context.cell_out_);
81
82 //
83 // Create a new context
84 //
85 g_Context.cell_in_ = (uint8_t*) malloc(size);
86 g_Context.cell_out_ = (uint8_t*) malloc(size);
87
88 memset(g_Context.cell_out_, 0, size);
89 for (index = 0; index < size; index++) {
90 g_Context.cell_in_[index] = rand() & 1;
91 }
92 }
93
94 void ProcessEvent(PSEvent* event) {
95 static int mouse_down = 0;
binji 2013/05/23 18:06:49 unused
noelallen1 2013/05/23 22:01:24 Done.
96
97 switch(event->type_) {
98 /* If the view updates, build a new Graphics 2D Context */
99 case PS_VIEW_EVENT: {
100 struct PP_Rect rect;
101 int32_t width;
102 int32_t height;
103 if (g_Context.ctx_) {
104 g_pCore->ReleaseResource(g_Context.ctx_);
105 g_Context.ctx_ = 0;
106 }
107
108 g_pView->GetRect(event->resource_, &rect);
109 width = rect.size.width;
110 height = rect.size.height;
111
112 if (width != g_Context.size_.width || height != g_Context.size_.height) {
113 UpdateContext(rect.size.width, rect.size.height);
114 }
115 if (width != g_Context.size_.width || height != g_Context.size_.height ||
116 !g_Context.bound_) {
117 g_Context.ctx_ =
118 g_pGraphics2D->Create(PSGetInstanceId(), &rect.size, PP_TRUE);
119 g_Context.bound_ =
120 g_pInstance->BindGraphics(PSGetInstanceId(), g_Context.ctx_);
121 g_Context.size_ = rect.size;
122 }
123 break;
124 }
125
126 case PS_INPUT_EVENT: {
nfullagar1 2013/05/23 21:58:36 I'm not super keen on how PS is defining a PS_INPU
noelallen1 2013/05/30 18:07:18 Done.
127 PP_InputEvent_Type type = g_pInputEvent->GetType(event->resource_);
128 PP_InputEvent_Modifier modifiers =
129 g_pInputEvent->GetModifiers(event->resource_);
130 int32_t width = g_Context.size_.width;
131 int32_t height = g_Context.size_.height;
132
133 switch(type) {
134 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
135 {
136 struct PP_Point location =
137 g_pMouseInput->GetPosition(event->resource_);
138
139 if (!g_Context.cell_in_) break;
140
141 // If the button is down, draw
142 if (modifiers & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
143 int x = location.x;
144 int y = location.y;
145
146 if (x > 0 && x < width && y > 0 && y < height) {
binji 2013/05/23 18:06:49 x < width - 1 y < height - 1
noelallen1 2013/05/23 22:01:24 Done.
binji 2013/05/30 05:07:50 Missed this one.
noelallen1 2013/05/30 18:07:18 Done.
147 g_Context.cell_in_[x-1 + y * width] = 1;
148 g_Context.cell_in_[x+1 + y * width] = 1;
149 g_Context.cell_in_[x + (y - 1) * width] = 1;
150 g_Context.cell_in_[x + (y + 1) * width] = 1;
151 }
152 }
153 }
154 break;
155
156 case PP_INPUTEVENT_TYPE_KEYUP: {
157 if (g_pKeyboardInput->GetKeyCode(event->resource_) == 13) {
binji 2013/05/23 18:06:49 enter key
noelallen1 2013/05/30 18:07:18 Done.
158 // PSToggleFullscreen();
binji 2013/05/23 18:06:49 does this not work?
noelallen1 2013/05/23 22:01:24 Done.
159 }
160 break;
161 }
162
163 default:
164 break;
165 }
166 break;
167 }
168
169 default:
170 break;
171 }
172 }
173
174
175 void Stir(uint32_t width, uint32_t height) {
176 int i;
177 if (g_Context.cell_in_ == NULL || g_Context.cell_out_ == NULL)
178 return;
179
180 for (i = 0; i < width; ++i) {
181 g_Context.cell_in_[i] = rand() & 1;
binji 2013/05/23 18:06:49 probably not a big deal, but I always heard that t
182 g_Context.cell_in_[i + (height - 1) * width] = rand() & 1;
183 }
184 for (i = 0; i < height; ++i) {
185 g_Context.cell_in_[i * width] = rand() & 1;
186 g_Context.cell_in_[i * width + (width - 1)] = rand() & 1;
187 }
188 }
189
190 void Render() {
191 struct PP_Size* psize = &g_Context.size_;
192 PP_ImageDataFormat format = g_pImageData->GetNativeImageDataFormat();
193 PP_Resource image =
194 g_pImageData->Create(PSGetInstanceId(), format, psize, PP_FALSE);
binji 2013/05/23 18:06:49 seems strange to create a new image every frame. M
noelallen1 2013/05/23 22:01:24 Done.
195 uint8_t* pixels = g_pImageData->Map(image);
196
197 struct PP_ImageDataDesc desc;
198 uint8_t* cell_temp;
199 uint32_t x, y;
200
201 // If we somehow have not allocated these pointers yet, skip this frame.
202 if (!g_Context.cell_in_ || !g_Context.cell_out_) return;
203
204 // Get the stride
205 g_pImageData->Describe(image, &desc);
nfullagar1 2013/05/23 21:58:36 For consistency, use the desc.size.width & height
noelallen1 2013/05/24 18:08:31 Done.
206
207 // Stir up the edges to prevent the simulation from reaching steady state.
208 Stir(psize->width, psize->height);
209
210 // Do neighbor sumation; apply rules, output pixel color.
binji 2013/05/23 18:06:49 sp: summation
noelallen1 2013/05/23 22:01:24 Done.
211 for (y = 1; y < (psize->height - 1); ++y) {
binji 2013/05/23 18:06:49 why ()?
noelallen1 2013/05/23 22:01:24 Done.
212 uint8_t *src0 = (g_Context.cell_in_ + (y - 1) * psize->width) + 1;
213 uint8_t *src1 = src0 + psize->width;
214 uint8_t *src2 = src1 + psize->width;
215 int count;
216 uint32_t color;
217 uint8_t *dst = (g_Context.cell_out_ + (y) * psize->width) + 1;
binji 2013/05/23 18:06:49 why (y)?
noelallen1 2013/05/23 22:01:24 Done.
218 uint32_t *pixel_line = (uint32_t*) (pixels + y * desc.stride);
219
220 for (x = 1; x < (psize->width - 1); ++x) {
221 // Build sum, weight center by 9x.
222 count = src0[-1] + src0[0] + src0[1] +
223 src1[-1] + src1[0] * 9 + src1[1] +
224 src2[-1] + src2[0] + src2[1];
225 color = kNeighborColors[count];
226
227 *pixel_line++ = color;
228 *dst++ = kIsAlive[count];
229 ++src0;
230 ++src1;
231 ++src2;
232 }
233 }
234
235 cell_temp = g_Context.cell_in_;
236 g_Context.cell_in_ = g_Context.cell_out_;
237 g_Context.cell_out_ = cell_temp;
238
239 /* Unmap the range, we no longer need it. */
240 g_pImageData->Unmap(image);
241
242 /* Replace the contexts, and block until it's on the screen. */
243 g_pGraphics2D->ReplaceContents(g_Context.ctx_, image);
244 g_pGraphics2D->Flush(g_Context.ctx_, PP_BlockUntilComplete());
245
246 /* Release the image data, we no longer need it. */
247 g_pCore->ReleaseResource(image);
248 }
249
250
251 int my_main(int argc, const char *argv[]) {
binji 2013/05/23 18:06:49 might want to mention this can be called anything
noelallen1 2013/05/23 22:01:24 Done.
252 fprintf(stdout,"Started main.\n");
253 g_pCore = (PPB_Core*)PSGetInterface(PPB_CORE_INTERFACE);
254 g_pGraphics2D = (PPB_Graphics2D*)PSGetInterface(PPB_GRAPHICS_2D_INTERFACE);
255 g_pInstance = (PPB_Instance*)PSGetInterface(PPB_INSTANCE_INTERFACE);
256 g_pImageData = (PPB_ImageData*)PSGetInterface(PPB_IMAGEDATA_INTERFACE);
257 g_pView = (PPB_View*)PSGetInterface(PPB_VIEW_INTERFACE);
258
259 g_pInputEvent =
260 (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
261 g_pKeyboardInput = (PPB_KeyboardInputEvent*)
262 PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
263 g_pMouseInput =
264 (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
265 g_pTouchInput =
binji 2013/05/23 18:06:49 unused
noelallen1 2013/05/30 18:07:18 Done.
266 (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
267
268 PSSetEventFilter(PS_ALL_EVENTS);
269 while (1) {
270 /* Process all waiting events without blocking */
271 PSEvent* event;
272 while ((event = PSAcquireEvent(0)) != NULL) {
binji 2013/05/23 18:06:49 what is 0?
noelallen1 2013/05/23 22:01:24 Means don't block, see comment above.
273 ProcessEvent(event);
274 PSReleaseEvent(event);
275 }
276
277 /* Render a frame, blocking until complete. */
278 if (g_Context.bound_) {
279 Render();
280 }
281 }
282 return 0;
283 }
284
nfullagar1 2013/05/23 21:58:36 How would this sample differ if PPAPI_SIMPLE_MAIN2
noelallen1 2013/05/24 18:08:31 The idea is that PPAPI_SIMPLE_MAIN2D would automat
285 PPAPI_SIMPLE_MAIN(my_main);
binji 2013/05/23 18:06:49 what is this doing? Maybe a little comment.
noelallen1 2013/05/23 22:01:24 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698