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

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

Powered by Google App Engine
This is Rietveld 408576698