From 86e729249f34f4a37602f256da2b0361330d4751 Mon Sep 17 00:00:00 2001 From: "jamesr@chromium.org" Date: Sat, 10 Mar 2012 06:25:29 +0000 Subject: Add a very simple example pepper plugin that uses a 3d context This plugin (based off the gles2 demo before it got video stuff) instantiates a pepper 3d context and continually renders into it with glClear(). It also has very simple lost context recovery. BUG=none Review URL: http://codereview.chromium.org/9625029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126011 0039d316-1c4b-4281-b951-d872f2087c98 --- ppapi/examples/gles2/gles2.cc | 168 ++++++++++++++++++++++++++++++++++++++++ ppapi/examples/gles2/gles2.html | 18 +++++ ppapi/ppapi_tests.gypi | 15 ++++ 3 files changed, 201 insertions(+) create mode 100644 ppapi/examples/gles2/gles2.cc create mode 100644 ppapi/examples/gles2/gles2.html diff --git a/ppapi/examples/gles2/gles2.cc b/ppapi/examples/gles2/gles2.cc new file mode 100644 index 0000000..fee9364 --- /dev/null +++ b/ppapi/examples/gles2/gles2.cc @@ -0,0 +1,168 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include +#include + +#include "ppapi/c/dev/ppb_console_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_opengles2.h" +#include "ppapi/cpp/core.h" +#include "ppapi/cpp/graphics_3d.h" +#include "ppapi/cpp/graphics_3d_client.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/rect.h" +#include "ppapi/cpp/var.h" +#include "ppapi/lib/gl/include/GLES2/gl2.h" +#include "ppapi/utility/completion_callback_factory.h" + +// Use assert as a poor-man's CHECK, even in non-debug mode. +// Since redefines assert on every inclusion (it doesn't use +// include-guards), make sure this is the last file #include'd in this file. +#undef NDEBUG +#include + +// Assert |context_| isn't holding any GL Errors. Done as a macro instead of a +// function to preserve line number information in the failure message. +#define assertNoGLError() \ + assert(!gles2_if_->GetError(context_->pp_resource())); + +namespace { + +class GLES2DemoInstance : public pp::Instance, + public pp::Graphics3DClient { + public: + GLES2DemoInstance(PP_Instance instance, pp::Module* module); + virtual ~GLES2DemoInstance(); + + // pp::Instance implementation (see PPP_Instance). + virtual void DidChangeView(const pp::Rect& position, + const pp::Rect& clip_ignored); + + // pp::Graphics3DClient implementation. + virtual void Graphics3DContextLost() { + // TODO(jamesr): What's the state of context_? Should we delete the old one + // or try to revive it somehow? + // For now, just delete it and construct+bind a new context. + delete context_; + context_ = NULL; + pp::CompletionCallback cb = callback_factory_.NewCallback( + &GLES2DemoInstance::InitGL); + module_->core()->CallOnMainThread(0, cb, 0); + } + + private: + + // GL-related functions. + void InitGL(int32_t result); + void FlickerAndPaint(int32_t result, bool paint_blue); + + pp::Size plugin_size_; + pp::CompletionCallbackFactory callback_factory_; + + // Unowned pointers. + const PPB_OpenGLES2* gles2_if_; + pp::Module* module_; + + // Owned data. + pp::Graphics3D* context_; +}; + +GLES2DemoInstance::GLES2DemoInstance(PP_Instance instance, pp::Module* module) + : pp::Instance(instance), pp::Graphics3DClient(this), + callback_factory_(this), + module_(module), + context_(NULL) { + assert((gles2_if_ = static_cast( + module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); +} + +GLES2DemoInstance::~GLES2DemoInstance() { + delete context_; +} + +void GLES2DemoInstance::DidChangeView( + const pp::Rect& position, const pp::Rect& clip_ignored) { + if (position.width() == 0 || position.height() == 0) + return; + if (plugin_size_.width()) { + assert(position.size() == plugin_size_); + return; + } + plugin_size_ = position.size(); + + // Initialize graphics. + InitGL(0); +} + +// This object is the global object representing this plugin library as long +// as it is loaded. +class GLES2DemoModule : public pp::Module { + public: + GLES2DemoModule() : pp::Module() {} + virtual ~GLES2DemoModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new GLES2DemoInstance(instance, this); + } +}; + +void GLES2DemoInstance::InitGL(int32_t result) { + assert(plugin_size_.width() && plugin_size_.height()); + + assert(!context_); + int32_t context_attributes[] = { + PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, + PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, + PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, + PP_GRAPHICS3DATTRIB_RED_SIZE, 8, + PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, + PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, + PP_GRAPHICS3DATTRIB_SAMPLES, 0, + PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, + PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(), + PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(), + PP_GRAPHICS3DATTRIB_NONE, + }; + context_ = new pp::Graphics3D(this, context_attributes); + assert(!context_->is_null()); + assert(BindGraphics(*context_)); + + // Clear color bit. + gles2_if_->ClearColor(context_->pp_resource(), 0, 1, 0, 1); + gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); + + assertNoGLError(); + + FlickerAndPaint(0, true); +} + +void GLES2DemoInstance::FlickerAndPaint(int32_t result, bool paint_blue) { + if (result != 0 || !context_) + return; + float r = paint_blue ? 0 : 1; + float g = 0; + float b = paint_blue ? 1 : 0; + float a = 0.75; + gles2_if_->ClearColor(context_->pp_resource(), r, g, b, a); + gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); + assertNoGLError(); + + pp::CompletionCallback cb = callback_factory_.NewCallback( + &GLES2DemoInstance::FlickerAndPaint, !paint_blue); + context_->SwapBuffers(cb); + assertNoGLError(); +} + +} // anonymous namespace + +namespace pp { +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new GLES2DemoModule(); +} +} // namespace pp diff --git a/ppapi/examples/gles2/gles2.html b/ppapi/examples/gles2/gles2.html new file mode 100644 index 0000000..e1d610d --- /dev/null +++ b/ppapi/examples/gles2/gles2.html @@ -0,0 +1,18 @@ + + + + + GLES2 Example + + + + + + + + diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 558fc55..96d914f 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -366,6 +366,21 @@ ], }, { + 'target_name': 'ppapi_example_gles2', + 'dependencies': [ + 'ppapi_example_skeleton', + 'ppapi.gyp:ppapi_cpp', + 'ppapi.gyp:ppapi_gles2', + 'ppapi.gyp:ppapi_egl', + ], + 'include_dirs': [ + 'lib/gl/include', + ], + 'sources': [ + 'examples/gles2/gles2.cc', + ], + }, + { 'target_name': 'ppapi_example_video_decode', 'dependencies': [ 'ppapi_example_skeleton', -- cgit v1.1