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