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.
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"
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.
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()));
37 class GLES2DemoInstance
: public pp::Instance
,
38 public pp::Graphics3DClient
{
40 GLES2DemoInstance(PP_Instance instance
, pp::Module
* module
);
41 virtual ~GLES2DemoInstance();
43 // pp::Instance implementation (see PPP_Instance).
44 virtual void DidChangeView(const pp::Rect
& position
,
45 const pp::Rect
& clip_ignored
);
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.
54 pp::CompletionCallback cb
= callback_factory_
.NewCallback(
55 &GLES2DemoInstance::InitGL
);
56 module_
->core()->CallOnMainThread(0, cb
, 0);
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_
);
69 // GL-related functions.
70 void InitGL(int32_t result
);
71 void FlickerAndPaint(int32_t result
, bool paint_blue
);
73 pp::Size plugin_size_
;
74 pp::CompletionCallbackFactory
<GLES2DemoInstance
> callback_factory_
;
77 const PPB_OpenGLES2
* gles2_if_
;
81 pp::Graphics3D
* context_
;
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
))),
94 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE
);
97 GLES2DemoInstance::~GLES2DemoInstance() {
101 void GLES2DemoInstance::DidChangeView(
102 const pp::Rect
& position
, const pp::Rect
& clip_ignored
) {
103 if (position
.width() == 0 || position
.height() == 0)
105 plugin_size_
= position
.size();
107 // Initialize graphics.
111 // This object is the global object representing this plugin library as long
113 class GLES2DemoModule
: public pp::Module
{
115 GLES2DemoModule() : pp::Module() {}
116 virtual ~GLES2DemoModule() {}
118 virtual pp::Instance
* CreateInstance(PP_Instance instance
) {
119 return new GLES2DemoInstance(instance
, this);
123 void GLES2DemoInstance::InitGL(int32_t result
) {
124 assert(plugin_size_
.width() && plugin_size_
.height());
127 context_
->ResizeBuffers(plugin_size_
.width(), plugin_size_
.height());
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
,
143 context_
= new pp::Graphics3D(this, context_attributes
);
144 assert(!context_
->is_null());
145 assert(BindGraphics(*context_
));
148 gles2_if_
->ClearColor(context_
->pp_resource(), 0, 1, 0, 1);
149 gles2_if_
->Clear(context_
->pp_resource(), GL_COLOR_BUFFER_BIT
);
153 FlickerAndPaint(0, true);
156 void GLES2DemoInstance::FlickerAndPaint(int32_t result
, bool paint_blue
) {
157 if (result
!= 0 || !context_
)
159 float r
= paint_blue
? 0 : 1.f
;
161 float b
= paint_blue
? 1.f
: 0;
163 gles2_if_
->ClearColor(context_
->pp_resource(), r
, g
, b
, a
);
164 gles2_if_
->Clear(context_
->pp_resource(), GL_COLOR_BUFFER_BIT
);
167 pp::CompletionCallback cb
= callback_factory_
.NewCallback(
168 &GLES2DemoInstance::FlickerAndPaint
, !paint_blue
);
169 context_
->SwapBuffers(cb
);
173 } // anonymous namespace
176 // Factory function for your specialization of the Module object.
177 Module
* CreateModule() {
178 return new GLES2DemoModule();