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

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

Powered by Google App Engine
This is Rietveld 408576698