| Index: ppapi/examples/gles2/gles2.cc
|
| diff --git a/ppapi/examples/gles2/gles2.cc b/ppapi/examples/gles2/gles2.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fee9364bacac7c9ec8b565116927b2e9e1fdc9b0
|
| --- /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 <string.h>
|
| +
|
| +#include <iostream>
|
| +#include <sstream>
|
| +
|
| +#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 <assert.h> 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.h>
|
| +
|
| +// 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<GLES2DemoInstance> 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<const PPB_OpenGLES2*>(
|
| + 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
|
|
|