15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Needed on Windows to get |M_PI| from math.h.
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef _WIN32
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define _USE_MATH_DEFINES
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <math.h>
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector>
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/c/pp_input_event.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/compositor.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/compositor_layer.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/graphics_3d.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/graphics_3d_client.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/image_data.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/input_event.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/instance.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/module.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/rect.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/cpp/var_dictionary.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/examples/compositor/spinning_cube.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/lib/gl/include/GLES2/gl2.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/lib/gl/include/GLES2/gl2ext.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use assert as a poor-man's CHECK, even in non-debug mode.
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Since <assert.h> redefines assert on every inclusion (it doesn't use
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// include-guards), make sure this is the last file #include'd in this file.
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef NDEBUG
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <assert.h>
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// When compiling natively on Windows, PostMessage can be #define-d to
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// something else.
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef PostMessage
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef PostMessage
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Assert |context_| isn't holding any GL Errors.  Done as a macro instead of a
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// function to preserve line number information in the failure message.
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define AssertNoGLError() \
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PP_DCHECK(!glGetError());
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int32_t kTextureWidth = 800;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int32_t kTextureHeight = 800;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int32_t kImageWidth = 256;
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int32_t kImageHeight = 256;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DemoInstance : public pp::Instance, public pp::Graphics3DClient {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemoInstance(PP_Instance instance);
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DemoInstance();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // pp::Instance implementation (see PPP_Instance).
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DidChangeView(const pp::Rect& position,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             const pp::Rect& clip);
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool HandleInputEvent(const pp::InputEvent& event);
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // pp::Graphics3DClient implementation.
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Graphics3DContextLost();
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GL-related functions.
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void InitGL(int32_t result);
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint PrepareFramebuffer();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::ImageData PrepareImage();
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void PrepareLayers(int32_t frame);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Paint(int32_t result, int32_t frame);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnTextureReleased(int32_t result, GLuint texture);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnImageReleased(int32_t result, const pp::ImageData& image);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::CompletionCallbackFactory<DemoInstance> callback_factory_;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Owned data.
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::Graphics3D* context_;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint fbo_;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint rbo_;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<GLuint> textures_;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<pp::ImageData> images_;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::Compositor compositor_;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::CompositorLayer color_layer_;
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::CompositorLayer stable_texture_layer_;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::CompositorLayer texture_layer_;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::CompositorLayer image_layer_;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool rebuild_layers_;
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32_t total_resource_;
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpinningCube* cube_;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DemoInstance::DemoInstance(PP_Instance instance)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : pp::Instance(instance),
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pp::Graphics3DClient(this),
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback_factory_(this),
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      context_(NULL),
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fbo_(0),
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rbo_(0),
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rebuild_layers_(true),
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      total_resource_(0),
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      cube_(new SpinningCube()) {
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DemoInstance::~DemoInstance() {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete cube_;
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(glTerminatePPAPI());
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete context_;
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DemoInstance::Init(uint32_t /*argc*/,
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const char* /*argn*/[],
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const char* /*argv*/[]) {
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !!glInitializePPAPI(pp::Module::Get()->get_browser_interface());
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::DidChangeView(
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const pp::Rect& position, const pp::Rect& /*clip*/) {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (position.width() == 0 || position.height() == 0)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Initialize graphics.
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitGL(0);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DemoInstance::HandleInputEvent(const pp::InputEvent& event) {
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (event.GetType()) {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rebuild_layers_ = true;
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::Graphics3DContextLost() {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fbo_ = 0;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rbo_ = 0;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rebuild_layers_ = true;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  total_resource_ -= static_cast<int32_t>(textures_.size());
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  textures_.clear();
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete context_;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  context_ = NULL;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cube_->OnGLContextLost();
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::CompletionCallback cb = callback_factory_.NewCallback(
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &DemoInstance::InitGL);
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::Module::Get()->core()->CallOnMainThread(0, cb, 0);
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::InitGL(int32_t /*result*/) {
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (context_)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32_t context_attributes[] = {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_SAMPLES, 0,
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_WIDTH, 32,
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_HEIGHT, 32,
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_GRAPHICS3DATTRIB_NONE,
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  context_ = new pp::Graphics3D(this, context_attributes);
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(!context_->is_null());
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(BindGraphics(compositor_));
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  glSetCurrentContextPPAPI(context_->pp_resource());
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cube_->Init(kTextureWidth, kTextureHeight);
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Paint(PP_OK, 0);
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GLuint DemoInstance::PrepareFramebuffer() {
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint texture = 0;
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (textures_.empty()) {
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    total_resource_++;
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Create a texture object
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glGenTextures(1, &texture);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, texture);
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTextureWidth, kTextureHeight, 0,
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, 0);
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    texture = textures_.back();
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    textures_.pop_back();
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!rbo_) {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // create a renderbuffer object to store depth info
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glGenRenderbuffers(1, &rbo_);
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindRenderbuffer(GL_RENDERBUFFER, rbo_);
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kTextureWidth, kTextureHeight);
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindRenderbuffer(GL_RENDERBUFFER, 0);
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!fbo_) {
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // create a framebuffer object
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glGenFramebuffers(1, &fbo_);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // attach the texture to FBO color attachment point
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  glFramebufferTexture2D(GL_FRAMEBUFFER,
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         GL_COLOR_ATTACHMENT0,
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         GL_TEXTURE_2D,
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         texture,
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         0);
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // attach the renderbuffer to depth attachment point
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  glFramebufferRenderbuffer(GL_FRAMEBUFFER,
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            GL_DEPTH_ATTACHMENT,
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            GL_RENDERBUFFER,
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            rbo_);
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // check FBO status
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(status == GL_FRAMEBUFFER_COMPLETE);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AssertNoGLError();
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return texture;
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)pp::ImageData DemoInstance::PrepareImage() {
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (images_.empty()) {
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    total_resource_++;
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return pp::ImageData(this,
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         PP_IMAGEDATAFORMAT_RGBA_PREMUL,
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         pp::Size(kImageWidth, kImageHeight),
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         false);
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::ImageData image = images_.back();
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  images_.pop_back();
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return image;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::Paint(int32_t result, int32_t frame) {
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(result == PP_OK);
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result != PP_OK || !context_)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rebuild_layers_) {
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    compositor_ = pp::Compositor(this);
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(BindGraphics(compositor_));
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    color_layer_ = pp::CompositorLayer();
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stable_texture_layer_ = pp::CompositorLayer();
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    texture_layer_ = pp::CompositorLayer();
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    image_layer_ = pp::CompositorLayer();
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    frame = 0;
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rebuild_layers_ = false;
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrepareLayers(frame);
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32_t rv = compositor_.CommitLayers(
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback_factory_.NewCallback(&DemoInstance::Paint, ++frame));
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(rv == PP_OK_COMPLETIONPENDING);
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::VarDictionary dict;
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dict.Set("total_resource", total_resource_);
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t free_resource = textures_.size() + images_.size();
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dict.Set("free_resource", static_cast<int32_t>(free_resource));
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PostMessage(dict);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::PrepareLayers(int32_t frame) {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32_t rv;
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float factor_sin = sin(M_PI / 180 * frame);
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float factor_cos = cos(M_PI / 180 * frame);
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Set the background color layer.
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (color_layer_.is_null()) {
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      color_layer_ = compositor_.AddLayer();
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(!color_layer_.is_null());
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static const float transform[16] = {
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        1.0f, 0.0f, 0.0f, 0.0f,
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        0.0f, 1.0f, 0.0f, 0.0f,
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        0.0f, 0.0f, 1.0f, 0.0f,
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        0.0f, 0.0f, 0.0f, 1.0f,
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      };
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rv = color_layer_.SetTransform(transform);
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(rv == PP_OK);
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = color_layer_.SetColor(fabs(factor_sin),
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               fabs(factor_cos),
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               fabs(factor_sin * factor_cos),
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               1.0f,
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               pp::Size(800, 600));
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK);
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Set the image layer
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (image_layer_.is_null()) {
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      image_layer_ = compositor_.AddLayer();
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(!image_layer_.is_null());
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    float x = frame % 800;
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    float y = 200 - 200 * factor_sin;
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const float transform[16] = {
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fabsf(factor_sin) + 0.2f, 0.0f, 0.0f, 0.0f,
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0.0f, fabsf(factor_sin) + 0.2f, 0.0f, 0.0f,
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0.0f, 0.0f, 1.0f, 0.0f,
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         x,    y, 0.0f, 1.0f,
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    };
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = image_layer_.SetTransform(transform);
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK);
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    pp::ImageData image = PrepareImage();
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint8_t *p = static_cast<uint8_t*>(image.data());
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int x = 0; x < kImageWidth; ++x) {
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (int y = 0; y < kImageHeight; ++y) {
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *(p++) = frame;
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *(p++) = frame * x;
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *(p++) = frame * y;
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *(p++) = 255;
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = image_layer_.SetImage(image, pp::Size(kImageWidth, kImageHeight),
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        callback_factory_.NewCallback(&DemoInstance::OnImageReleased, image));
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK_COMPLETIONPENDING);
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Set the stable texture layer
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (stable_texture_layer_.is_null()) {
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stable_texture_layer_ = compositor_.AddLayer();
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(!stable_texture_layer_.is_null());
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GLuint texture = PrepareFramebuffer();
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      cube_->UpdateForTimeDelta(0.02f);
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      cube_->Draw();
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rv = stable_texture_layer_.SetTexture(
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          *context_,
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GL_TEXTURE_2D,
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          texture,
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          pp::Size(600, 600),
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          callback_factory_.NewCallback(&DemoInstance::OnTextureReleased,
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        texture));
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(rv == PP_OK_COMPLETIONPENDING);
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rv = stable_texture_layer_.SetPremultipliedAlpha(PP_FALSE);
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(rv == PP_OK);
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32_t delta = 200 * fabsf(factor_sin);
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (delta != 0) {
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int32_t x_y = 25 + delta;
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int32_t w_h =  650 - delta - delta;
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rv = stable_texture_layer_.SetClipRect(pp::Rect(x_y, x_y, w_h, w_h));
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rv = stable_texture_layer_.SetClipRect(pp::Rect());
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK);
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const float transform[16] = {
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      factor_cos, -factor_sin, 0.0f, 0.0f,
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      factor_sin, factor_cos, 0.0f, 0.0f,
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0.0f, 0.0f, 1.0f, 0.0f,
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      50.0f, 50.0f, 0.0f, 1.0f,
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    };
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = stable_texture_layer_.SetTransform(transform);
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK);
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Set the dynamic texture layer.
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (texture_layer_.is_null()) {
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      texture_layer_ = compositor_.AddLayer();
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(!texture_layer_.is_null());
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static const float transform[16] = {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        1.0f, 0.0f, 0.0f, 0.0f,
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        0.0f, 1.0f, 0.0f, 0.0f,
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        0.0f, 0.0f, 1.0f, 0.0f,
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        200.0f, 0.0f, 0.0f, 1.0f,
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      };
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rv = texture_layer_.SetTransform(transform);
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      assert(rv == PP_OK);
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     }
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLuint texture = PrepareFramebuffer();
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cube_->UpdateForTimeDelta(0.02f);
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cube_->Draw();
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = texture_layer_.SetTexture(
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *context_,
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GL_TEXTURE_2D,
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        texture,
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        pp::Size(400, 400),
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        callback_factory_.NewCallback(&DemoInstance::OnTextureReleased,
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      texture));
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK_COMPLETIONPENDING);
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = texture_layer_.SetPremultipliedAlpha(PP_FALSE);
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(rv == PP_OK);
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::OnTextureReleased(int32_t result, GLuint texture) {
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == PP_OK) {
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    textures_.push_back(texture);
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glDeleteTextures(1, &texture);
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    total_resource_--;
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DemoInstance::OnImageReleased(int32_t result, const pp::ImageData& image) {
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == PP_OK) {
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    images_.push_back(image);
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    total_resource_--;
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This object is the global object representing this plugin library as long
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// as it is loaded.
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DemoModule : public pp::Module {
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DemoModule() : Module() {}
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~DemoModule() {}
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual pp::Instance* CreateInstance(PP_Instance instance) {
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return new DemoInstance(instance);
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // anonymous namespace
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace pp {
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Factory function for your specialization of the Module object.
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Module* CreateModule() {
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new DemoModule();
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace pp
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)