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

Side by Side Diff: ppapi/examples/compositor/compositor.cc

Issue 298023004: [PPAPI] Compositor API implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@compositor_api_def_new
Patch Set: Use a clip parent for clip_rect Created 6 years, 6 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
OLDNEW
(Empty)
1 // Copyright 2014 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
7 #include <vector>
8
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/pp_input_event.h"
11 #include "ppapi/cpp/compositor.h"
12 #include "ppapi/cpp/compositor_layer.h"
13 #include "ppapi/cpp/graphics_3d.h"
14 #include "ppapi/cpp/graphics_3d_client.h"
15 #include "ppapi/cpp/image_data.h"
16 #include "ppapi/cpp/input_event.h"
17 #include "ppapi/cpp/instance.h"
18 #include "ppapi/cpp/module.h"
19 #include "ppapi/cpp/rect.h"
20 #include "ppapi/examples/compositor/spinning_cube.h"
21 #include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
22 #include "ppapi/lib/gl/include/GLES2/gl2.h"
23 #include "ppapi/lib/gl/include/GLES2/gl2ext.h"
24 #include "ppapi/utility/completion_callback_factory.h"
25
26 // Use assert as a poor-man's CHECK, even in non-debug mode.
27 // Since <assert.h> redefines assert on every inclusion (it doesn't use
28 // include-guards), make sure this is the last file #include'd in this file.
29 #undef NDEBUG
30 #include <assert.h>
31
32 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a
33 // function to preserve line number information in the failure message.
34 #define AssertNoGLError() \
35 PP_DCHECK(!glGetError());
36
37 namespace {
38
39 const int32_t kTextureWidth = 800;
40 const int32_t kTextureHeight = 800;
41 const int32_t kImageWidth = 256;
42 const int32_t kImageHeight = 256;
43
44 class DemoInstance : public pp::Instance, public pp::Graphics3DClient {
45 public:
46 DemoInstance(PP_Instance instance);
47 virtual ~DemoInstance();
48
49 // pp::Instance implementation (see PPP_Instance).
50 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
51 virtual void DidChangeView(const pp::Rect& position,
52 const pp::Rect& clip);
53 virtual bool HandleInputEvent(const pp::InputEvent& event);
54
55 // pp::Graphics3DClient implementation.
56 virtual void Graphics3DContextLost();
57
58 private:
59 // GL-related functions.
60 void InitGL(int32_t result);
61 GLuint PrepareFramebuffer();
62 pp::ImageData PrepareImage();
63 void Paint(int32_t result, int32_t frame);
64 void OnTextureReleased(int32_t result, GLuint texture);
65 void OnImageReleased(int32_t result, const pp::ImageData& image);
66
67 pp::CompletionCallbackFactory<DemoInstance> callback_factory_;
68
69 // Owned data.
70 pp::Graphics3D* context_;
71
72 GLuint fbo_;
73 GLuint rbo_;
74
75 std::vector<GLuint> textures_;
76 std::vector<pp::ImageData> images_;
77
78 pp::Compositor compositor_;
79 pp::CompositorLayer color_layer_;
80 pp::CompositorLayer stable_texture_layer_;
81 pp::CompositorLayer texture_layer_;
82 pp::CompositorLayer image_layer_;
83
84 bool rebuild_layers_;
85
86 SpinningCube* cube_;
87 };
88
89 DemoInstance::DemoInstance(PP_Instance instance)
90 : pp::Instance(instance),
91 pp::Graphics3DClient(this),
92 callback_factory_(this),
93 context_(NULL),
94 fbo_(0),
95 rbo_(0),
96 compositor_(this),
97 rebuild_layers_(false),
98 cube_(new SpinningCube()) {
99 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
100 }
101
102 DemoInstance::~DemoInstance() {
103 delete cube_;
104 assert(glTerminatePPAPI());
105 delete context_;
106 }
107
108 bool DemoInstance::Init(uint32_t /*argc*/,
109 const char* /*argn*/[],
110 const char* /*argv*/[]) {
111 return !!glInitializePPAPI(pp::Module::Get()->get_browser_interface());
112 }
113
114 void DemoInstance::DidChangeView(
115 const pp::Rect& position, const pp::Rect& /*clip*/) {
116 if (position.width() == 0 || position.height() == 0)
117 return;
118 // Initialize graphics.
119 InitGL(0);
120 }
121
122 bool DemoInstance::HandleInputEvent(const pp::InputEvent& event) {
123 switch (event.GetType()) {
124 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
125 rebuild_layers_ = true;
126 return true;
127 default:
128 break;
129 }
130 return false;
131 }
132
133 void DemoInstance::Graphics3DContextLost() {
134 fbo_ = 0;
135 rbo_ = 0;
136 compositor_.ResetLayers();
137 color_layer_ = pp::CompositorLayer();
138 stable_texture_layer_ = pp::CompositorLayer();
139 texture_layer_ = pp::CompositorLayer();
140 image_layer_ = pp::CompositorLayer();
141 textures_.clear();
142 delete context_;
143 context_ = NULL;
144 cube_->OnGLContextLost();
145 pp::CompletionCallback cb = callback_factory_.NewCallback(
146 &DemoInstance::InitGL);
147 pp::Module::Get()->core()->CallOnMainThread(0, cb, 0);
148 }
149
150 void DemoInstance::InitGL(int32_t /*result*/) {
151 if (context_)
152 return;
153 int32_t context_attributes[] = {
154 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
155 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
156 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
157 PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
158 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
159 PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
160 PP_GRAPHICS3DATTRIB_SAMPLES, 0,
161 PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
162 PP_GRAPHICS3DATTRIB_WIDTH, 32,
163 PP_GRAPHICS3DATTRIB_HEIGHT, 32,
164 PP_GRAPHICS3DATTRIB_NONE,
165 };
166 context_ = new pp::Graphics3D(this, context_attributes);
167 assert(!context_->is_null());
168 assert(BindGraphics(compositor_));
169
170 glSetCurrentContextPPAPI(context_->pp_resource());
171
172 cube_->Init(kTextureWidth, kTextureHeight);
173
174 Paint(PP_OK, 0);
175 }
176
177 GLuint DemoInstance::PrepareFramebuffer() {
178 GLuint texture = 0;
179 if (textures_.empty()) {
180 // Create a texture object
181 glGenTextures(1, &texture);
182 glBindTexture(GL_TEXTURE_2D, texture);
183 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureWidth, kTextureHeight, 0,
184 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
185 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
186 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
187 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
188 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
189 glBindTexture(GL_TEXTURE_2D, 0);
190 } else {
191 texture = textures_.back();
192 textures_.pop_back();
193 }
194
195 if (!rbo_) {
196 // create a renderbuffer object to store depth info
197 glGenRenderbuffers(1, &rbo_);
198 glBindRenderbuffer(GL_RENDERBUFFER, rbo_);
199 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
200 kTextureWidth, kTextureHeight);
201 glBindRenderbuffer(GL_RENDERBUFFER, 0);
202 }
203
204 if (!fbo_) {
205 // create a framebuffer object
206 glGenFramebuffers(1, &fbo_);
207 }
208
209 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
210
211 // attach the texture to FBO color attachment point
212 glFramebufferTexture2D(GL_FRAMEBUFFER,
213 GL_COLOR_ATTACHMENT0,
214 GL_TEXTURE_2D,
215 texture,
216 0);
217
218 // attach the renderbuffer to depth attachment point
219 glFramebufferRenderbuffer(GL_FRAMEBUFFER,
220 GL_DEPTH_ATTACHMENT,
221 GL_RENDERBUFFER,
222 rbo_);
223
224 // check FBO status
225 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
226 assert(status == GL_FRAMEBUFFER_COMPLETE);
227
228 AssertNoGLError();
229 return texture;
230 }
231
232 pp::ImageData DemoInstance::PrepareImage() {
233 if (images_.empty()) {
234 return pp::ImageData(this,
235 PP_IMAGEDATAFORMAT_RGBA_PREMUL,
236 pp::Size(kImageWidth, kImageHeight),
237 false);
238 }
239 pp::ImageData image = images_.back();
240 images_.pop_back();
241 return image;
242 }
243
244 void DemoInstance::Paint(int32_t result, int32_t frame) {
245 if (result != PP_OK || !context_)
246 return;
247
248 if (rebuild_layers_) {
249 compositor_.ResetLayers();
250 color_layer_ = pp::CompositorLayer();
251 stable_texture_layer_ = pp::CompositorLayer();
252 texture_layer_ = pp::CompositorLayer();
253 image_layer_ = pp::CompositorLayer();
254 frame = 0;
255 rebuild_layers_ = false;
256 }
257
258 float factor_sin = sin(M_PI / 180 * frame);
259 float factor_cos = cos(M_PI / 180 * frame);
260 {
261 // Set the background color layer.
262 if (color_layer_.is_null()) {
263 color_layer_ = compositor_.AddLayer();
264 assert(!color_layer_.is_null());
265 static const float transform[16] = {
266 1.0f, 0.0f, 0.0f, 0.0f,
267 0.0f, 1.0f, 0.0f, 0.0f,
268 0.0f, 0.0f, 1.0f, 0.0f,
269 0.0f, 0.0f, 0.0f, 1.0f,
270 };
271 color_layer_.SetTransform(transform);
272 }
273 color_layer_.SetColor(fabs(factor_sin),
274 fabs(factor_cos),
275 fabs(factor_sin * factor_cos),
276 1.0f,
277 pp::Size(800, 600));
278 }
279
280 {
281 // Set the image layer
282 if (image_layer_.is_null()) {
283 image_layer_ = compositor_.AddLayer();
284 assert(!image_layer_.is_null());
285 }
286 float x = frame % 800;
287 float y = 200 - 200 * factor_sin;
288 const float transform[16] = {
289 fabs(factor_sin) + 0.2f, 0.0f, 0.0f, 0.0f,
290 0.0f, fabs(factor_sin) + 0.2f, 0.0f, 0.0f,
291 0.0f, 0.0f, 1.0f, 0.0f,
292 x, y, 0.0f, 1.0f,
293 };
294 image_layer_.SetTransform(transform);
295 pp::ImageData image = PrepareImage();
296 uint8_t *p = static_cast<uint8_t*>(image.data());
297 for (int x = 0; x < kImageWidth; ++x) {
298 for (int y = 0; y < kImageHeight; ++y) {
299 *(p++) = frame;
300 *(p++) = frame * x;
301 *(p++) = frame * y;
302 *(p++) = 255;
303 }
304 }
305 image_layer_.SetImage(image, pp::Size(kImageWidth, kImageHeight),
306 callback_factory_.NewCallback(&DemoInstance::OnImageReleased, image));
307 }
308
309 {
310 // Set the stable texture layer
311 if (stable_texture_layer_.is_null()) {
312 stable_texture_layer_ = compositor_.AddLayer();
313 assert(!stable_texture_layer_.is_null());
314 stable_texture_layer_.SetPremultipliedAlpha(PP_FALSE);
315 GLuint texture = PrepareFramebuffer();
316 cube_->UpdateForTimeDelta(0.02f);
317 cube_->Draw();
318 stable_texture_layer_.SetTexture(*context_, texture, pp::Size(600, 600),
319 callback_factory_.NewCallback(&DemoInstance::OnTextureReleased,
320 texture));
321 }
322
323 int32_t delta = 200 * fabsf(factor_sin);
324 if (delta != 0) {
325 int32_t x_y = 50 + delta;
326 int32_t w_h = 600 - delta - delta;
327 stable_texture_layer_.SetClipRect(pp::Rect(x_y, x_y, w_h, w_h));
328 } else {
329 stable_texture_layer_.SetClipRect(pp::Rect());
330 }
331
332 const float transform[16] = {
333 factor_cos, -factor_sin, 0.0f, 0.0f,
334 factor_sin, factor_cos, 0.0f, 0.0f,
335 0.0f, 0.0f, 1.0f, 0.0f,
336 50.0f, 50.0f, 0.0f, 1.0f,
337 };
338 stable_texture_layer_.SetTransform(transform);
339 }
340
341 {
342 // Set the dynamic texture layer.
343 if (texture_layer_.is_null()) {
344 texture_layer_ = compositor_.AddLayer();
345 assert(!texture_layer_.is_null());
346 static const float transform[16] = {
347 1.0f, 0.0f, 0.0f, 0.0f,
348 0.0f, 1.0f, 0.0f, 0.0f,
349 0.0f, 0.0f, 1.0f, 0.0f,
350 200.0f, 0.0f, 0.0f, 1.0f,
351 };
352 texture_layer_.SetTransform(transform);
353 texture_layer_.SetPremultipliedAlpha(PP_FALSE);
354 }
355
356 GLuint texture = PrepareFramebuffer();
357 cube_->UpdateForTimeDelta(0.02f);
358 cube_->Draw();
359 texture_layer_.SetTexture(*context_, texture, pp::Size(400, 400),
360 callback_factory_.NewCallback(&DemoInstance::OnTextureReleased,
361 texture));
362 }
363
364 compositor_.CommitLayers(
365 callback_factory_.NewCallback(&DemoInstance::Paint, ++frame));
366 }
367
368 void DemoInstance::OnTextureReleased(int32_t result, GLuint texture) {
369 if (result == PP_OK)
370 textures_.push_back(texture);
371 }
372
373 void DemoInstance::OnImageReleased(int32_t result, const pp::ImageData& image) {
374 if (result == PP_OK);
375 images_.push_back(image);
376 }
377
378 // This object is the global object representing this plugin library as long
379 // as it is loaded.
380 class DemoModule : public pp::Module {
381 public:
382 DemoModule() : Module() {}
383 virtual ~DemoModule() {}
384
385 virtual pp::Instance* CreateInstance(PP_Instance instance) {
386 return new DemoInstance(instance);
387 }
388 };
389
390 } // anonymous namespace
391
392 namespace pp {
393 // Factory function for your specialization of the Module object.
394 Module* CreateModule() {
395 return new DemoModule();
396 }
397 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698