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

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

Powered by Google App Engine
This is Rietveld 408576698