Home | History | Annotate | Download | only in gles2
      1 // Copyright (c) 2012 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 <string.h>
      6 
      7 #include <iostream>
      8 #include <sstream>
      9 
     10 #include "ppapi/c/pp_errors.h"
     11 #include "ppapi/c/ppb_opengles2.h"
     12 #include "ppapi/cpp/core.h"
     13 #include "ppapi/cpp/fullscreen.h"
     14 #include "ppapi/cpp/graphics_3d.h"
     15 #include "ppapi/cpp/graphics_3d_client.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.h"
     21 #include "ppapi/lib/gl/include/GLES2/gl2.h"
     22 #include "ppapi/utility/completion_callback_factory.h"
     23 
     24 // Use assert as a poor-man's CHECK, even in non-debug mode.
     25 // Since <assert.h> redefines assert on every inclusion (it doesn't use
     26 // include-guards), make sure this is the last file #include'd in this file.
     27 #undef NDEBUG
     28 #include <assert.h>
     29 
     30 // Assert |context_| isn't holding any GL Errors.  Done as a macro instead of a
     31 // function to preserve line number information in the failure message.
     32 #define assertNoGLError() \
     33   assert(!gles2_if_->GetError(context_->pp_resource()));
     34 
     35 namespace {
     36 
     37 class GLES2DemoInstance : public pp::Instance,
     38                           public pp::Graphics3DClient {
     39  public:
     40   GLES2DemoInstance(PP_Instance instance, pp::Module* module);
     41   virtual ~GLES2DemoInstance();
     42 
     43   // pp::Instance implementation (see PPP_Instance).
     44   virtual void DidChangeView(const pp::Rect& position,
     45                              const pp::Rect& clip_ignored);
     46 
     47   // pp::Graphics3DClient implementation.
     48   virtual void Graphics3DContextLost() {
     49     // TODO(jamesr): What's the state of context_? Should we delete the old one
     50     // or try to revive it somehow?
     51     // For now, just delete it and construct+bind a new context.
     52     delete context_;
     53     context_ = NULL;
     54     pp::CompletionCallback cb = callback_factory_.NewCallback(
     55         &GLES2DemoInstance::InitGL);
     56     module_->core()->CallOnMainThread(0, cb, 0);
     57   }
     58 
     59   virtual bool HandleInputEvent(const pp::InputEvent& event) {
     60     if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP) {
     61       fullscreen_ = !fullscreen_;
     62       pp::Fullscreen(this).SetFullscreen(fullscreen_);
     63     }
     64     return true;
     65   }
     66 
     67  private:
     68 
     69   // GL-related functions.
     70   void InitGL(int32_t result);
     71   void FlickerAndPaint(int32_t result, bool paint_blue);
     72 
     73   pp::Size plugin_size_;
     74   pp::CompletionCallbackFactory<GLES2DemoInstance> callback_factory_;
     75 
     76   // Unowned pointers.
     77   const PPB_OpenGLES2* gles2_if_;
     78   pp::Module* module_;
     79 
     80   // Owned data.
     81   pp::Graphics3D* context_;
     82   bool fullscreen_;
     83 };
     84 
     85 GLES2DemoInstance::GLES2DemoInstance(PP_Instance instance, pp::Module* module)
     86     : pp::Instance(instance), pp::Graphics3DClient(this),
     87       callback_factory_(this),
     88       gles2_if_(static_cast<const PPB_OpenGLES2*>(
     89           module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE))),
     90       module_(module),
     91       context_(NULL),
     92       fullscreen_(false) {
     93   assert(gles2_if_);
     94   RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
     95 }
     96 
     97 GLES2DemoInstance::~GLES2DemoInstance() {
     98   delete context_;
     99 }
    100 
    101 void GLES2DemoInstance::DidChangeView(
    102     const pp::Rect& position, const pp::Rect& clip_ignored) {
    103   if (position.width() == 0 || position.height() == 0)
    104     return;
    105   plugin_size_ = position.size();
    106 
    107   // Initialize graphics.
    108   InitGL(0);
    109 }
    110 
    111 // This object is the global object representing this plugin library as long
    112 // as it is loaded.
    113 class GLES2DemoModule : public pp::Module {
    114  public:
    115   GLES2DemoModule() : pp::Module() {}
    116   virtual ~GLES2DemoModule() {}
    117 
    118   virtual pp::Instance* CreateInstance(PP_Instance instance) {
    119     return new GLES2DemoInstance(instance, this);
    120   }
    121 };
    122 
    123 void GLES2DemoInstance::InitGL(int32_t result) {
    124   assert(plugin_size_.width() && plugin_size_.height());
    125 
    126   if (context_) {
    127     context_->ResizeBuffers(plugin_size_.width(), plugin_size_.height());
    128     return;
    129   }
    130   int32_t context_attributes[] = {
    131     PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
    132     PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
    133     PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
    134     PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
    135     PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
    136     PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
    137     PP_GRAPHICS3DATTRIB_SAMPLES, 0,
    138     PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
    139     PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(),
    140     PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(),
    141     PP_GRAPHICS3DATTRIB_NONE,
    142   };
    143   context_ = new pp::Graphics3D(this, context_attributes);
    144   assert(!context_->is_null());
    145   assert(BindGraphics(*context_));
    146 
    147   // Clear color bit.
    148   gles2_if_->ClearColor(context_->pp_resource(), 0, 1, 0, 1);
    149   gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
    150 
    151   assertNoGLError();
    152 
    153   FlickerAndPaint(0, true);
    154 }
    155 
    156 void GLES2DemoInstance::FlickerAndPaint(int32_t result, bool paint_blue) {
    157   if (result != 0 || !context_)
    158     return;
    159   float r = paint_blue ? 0 : 1;
    160   float g = 0;
    161   float b = paint_blue ? 1 : 0;
    162   float a = 0.75;
    163   gles2_if_->ClearColor(context_->pp_resource(), r, g, b, a);
    164   gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
    165   assertNoGLError();
    166 
    167   pp::CompletionCallback cb = callback_factory_.NewCallback(
    168       &GLES2DemoInstance::FlickerAndPaint, !paint_blue);
    169   context_->SwapBuffers(cb);
    170   assertNoGLError();
    171 }
    172 
    173 }  // anonymous namespace
    174 
    175 namespace pp {
    176 // Factory function for your specialization of the Module object.
    177 Module* CreateModule() {
    178   return new GLES2DemoModule();
    179 }
    180 }  // namespace pp
    181