Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / NativeClient / opengl_context.cc
1 // Copyright (c) 2011 The Native Client 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 "opengl_context.h"
6
7 #include <pthread.h>
8 #include "ppapi/gles2/gl2ext_ppapi.h"
9
10 namespace {
11 // This is called by the brower when the 3D context has been flushed to the
12 // browser window.
13 void FlushCallback(void* data, int32_t result) {
14   static_cast<tumbler::OpenGLContext*>(data)->set_flush_pending(false);
15 }
16 }  // namespace
17
18 namespace tumbler {
19
20 OpenGLContext::OpenGLContext(pp::Instance* instance)
21     : pp::Graphics3DClient_Dev(instance),
22       flush_pending_(false) {
23   pp::Module* module = pp::Module::Get();
24   assert(module);
25   gles2_interface_ = static_cast<const struct PPB_OpenGLES2_Dev*>(
26       module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE));
27   assert(gles2_interface_);
28 }
29
30 OpenGLContext::~OpenGLContext() {
31   glSetCurrentContextPPAPI(0);
32 }
33
34 bool OpenGLContext::MakeContextCurrent(pp::Instance* instance) {
35   if (instance == NULL) {
36     glSetCurrentContextPPAPI(0);
37     return false;
38   }
39   // Lazily create the Pepper context.
40   if (context_.is_null()) {
41     context_ = pp::Context3D_Dev(*instance, 0, pp::Context3D_Dev(), NULL);
42     if (context_.is_null()) {
43       glSetCurrentContextPPAPI(0);
44       return false;
45     }
46     surface_ = pp::Surface3D_Dev(*instance, 0, NULL);
47     context_.BindSurfaces(surface_, surface_);
48     instance->BindGraphics(surface_);
49   }
50   glSetCurrentContextPPAPI(context_.pp_resource());
51   return true;
52 }
53
54 void OpenGLContext::InvalidateContext(pp::Instance* instance) {
55   if (instance == NULL)
56     return;
57   // Unbind the existing surface and re-bind to null surfaces.
58   instance->BindGraphics(pp::Surface3D_Dev());
59   context_.BindSurfaces(pp::Surface3D_Dev(), pp::Surface3D_Dev());
60   glSetCurrentContextPPAPI(0);
61 }
62
63 void OpenGLContext::FlushContext() {
64   if (flush_pending()) {
65     // A flush is pending so do nothing; just drop this flush on the floor.
66     return;
67   }
68   set_flush_pending(true);
69   surface_.SwapBuffers(pp::CompletionCallback(&FlushCallback, this));
70 }
71 }  // namespace tumbler
72