15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iostream> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_opengles2.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/core.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/fullscreen.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/graphics_3d.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/graphics_3d_client.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/input_event.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/rect.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/lib/gl/include/GLES2/gl2.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use assert as a poor-man's CHECK, even in non-debug mode. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Since <assert.h> redefines assert on every inclusion (it doesn't use 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// include-guards), make sure this is the last file #include'd in this file. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef NDEBUG 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function to preserve line number information in the failure message. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define assertNoGLError() \ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!gles2_if_->GetError(context_->pp_resource())); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2DemoInstance : public pp::Instance, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public pp::Graphics3DClient { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLES2DemoInstance(PP_Instance instance, pp::Module* module); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~GLES2DemoInstance(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pp::Instance implementation (see PPP_Instance). 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DidChangeView(const pp::Rect& position, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& clip_ignored); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pp::Graphics3DClient implementation. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Graphics3DContextLost() { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jamesr): What's the state of context_? Should we delete the old one 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or try to revive it somehow? 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, just delete it and construct+bind a new context. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete context_; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_ = NULL; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallback cb = callback_factory_.NewCallback( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GLES2DemoInstance::InitGL); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module_->core()->CallOnMainThread(0, cb, 0); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool HandleInputEvent(const pp::InputEvent& event) { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fullscreen_ = !fullscreen_; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pp::Fullscreen(this).SetFullscreen(fullscreen_); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GL-related functions. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitGL(int32_t result); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FlickerAndPaint(int32_t result, bool paint_blue); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size plugin_size_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallbackFactory<GLES2DemoInstance> callback_factory_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unowned pointers. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_OpenGLES2* gles2_if_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module* module_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Owned data. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics3D* context_; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fullscreen_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLES2DemoInstance::GLES2DemoInstance(PP_Instance instance, pp::Module* module) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pp::Instance(instance), pp::Graphics3DClient(this), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_factory_(this), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module_(module), 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_(NULL), 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fullscreen_(false) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLES2DemoInstance::~GLES2DemoInstance() { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete context_; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLES2DemoInstance::DidChangeView( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& position, const pp::Rect& clip_ignored) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (position.width() == 0 || position.height() == 0) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_size_ = position.size(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize graphics. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitGL(0); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This object is the global object representing this plugin library as long 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as it is loaded. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2DemoModule : public pp::Module { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLES2DemoModule() : pp::Module() {} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~GLES2DemoModule() {} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual pp::Instance* CreateInstance(PP_Instance instance) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new GLES2DemoInstance(instance, this); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLES2DemoInstance::InitGL(int32_t result) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(plugin_size_.width() && plugin_size_.height()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_->ResizeBuffers(plugin_size_.width(), plugin_size_.height()); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t context_attributes[] = { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_RED_SIZE, 8, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_SAMPLES, 0, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(), 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(), 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_GRAPHICS3DATTRIB_NONE, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_ = new pp::Graphics3D(this, context_attributes); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!context_->is_null()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(BindGraphics(*context_)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear color bit. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->ClearColor(context_->pp_resource(), 0, 1, 0, 1); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FlickerAndPaint(0, true); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLES2DemoInstance::FlickerAndPaint(int32_t result, bool paint_blue) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != 0 || !context_) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float r = paint_blue ? 0 : 1; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float g = 0; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float b = paint_blue ? 1 : 0; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float a = 0.75; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->ClearColor(context_->pp_resource(), r, g, b, a); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::CompletionCallback cb = callback_factory_.NewCallback( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GLES2DemoInstance::FlickerAndPaint, !paint_blue); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->SwapBuffers(cb); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertNoGLError(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Factory function for your specialization of the Module object. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Module* CreateModule() { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new GLES2DemoModule(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace pp 180