73 lines
2.1 KiB
C++

// Copyright (c) 2011 The Native Client 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 "opengl_context.h"
#include <pthread.h>
#include "ppapi/gles2/gl2ext_ppapi.h"
namespace {
// This is called by the brower when the 3D context has been flushed to the
// browser window.
void FlushCallback(void* data, int32_t result) {
static_cast<tumbler::OpenGLContext*>(data)->set_flush_pending(false);
}
} // namespace
namespace tumbler {
OpenGLContext::OpenGLContext(pp::Instance* instance)
: pp::Graphics3DClient_Dev(instance),
flush_pending_(false) {
pp::Module* module = pp::Module::Get();
assert(module);
gles2_interface_ = static_cast<const struct PPB_OpenGLES2_Dev*>(
module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE));
assert(gles2_interface_);
}
OpenGLContext::~OpenGLContext() {
glSetCurrentContextPPAPI(0);
}
bool OpenGLContext::MakeContextCurrent(pp::Instance* instance) {
if (instance == NULL) {
glSetCurrentContextPPAPI(0);
return false;
}
// Lazily create the Pepper context.
if (context_.is_null()) {
context_ = pp::Context3D_Dev(*instance, 0, pp::Context3D_Dev(), NULL);
if (context_.is_null()) {
glSetCurrentContextPPAPI(0);
return false;
}
surface_ = pp::Surface3D_Dev(*instance, 0, NULL);
context_.BindSurfaces(surface_, surface_);
instance->BindGraphics(surface_);
}
glSetCurrentContextPPAPI(context_.pp_resource());
return true;
}
void OpenGLContext::InvalidateContext(pp::Instance* instance) {
if (instance == NULL)
return;
// Unbind the existing surface and re-bind to null surfaces.
instance->BindGraphics(pp::Surface3D_Dev());
context_.BindSurfaces(pp::Surface3D_Dev(), pp::Surface3D_Dev());
glSetCurrentContextPPAPI(0);
}
void OpenGLContext::FlushContext() {
if (flush_pending()) {
// A flush is pending so do nothing; just drop this flush on the floor.
return;
}
set_flush_pending(true);
surface_.SwapBuffers(pp::CompletionCallback(&FlushCallback, this));
}
} // namespace tumbler