| // Copyright (c) 2010 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 "gpu/demos/framework/plugin.h" |
| |
| #include "base/logging.h" |
| #include "gpu/demos/framework/demo_factory.h" |
| |
| using gpu::demos::Plugin; |
| |
| namespace { |
| const int32 kCommandBufferSize = 1024 * 1024; |
| NPExtensions* g_extensions = NULL; |
| |
| // Plugin class functions. |
| NPObject* PluginAllocate(NPP npp, NPClass* the_class) { |
| Plugin* plugin = new Plugin(npp); |
| return plugin; |
| } |
| |
| void PluginDeallocate(NPObject* header) { |
| Plugin* plugin = static_cast<Plugin*>(header); |
| delete plugin; |
| } |
| |
| void PluginInvalidate(NPObject* obj) { |
| } |
| |
| bool PluginHasMethod(NPObject* obj, NPIdentifier name) { |
| return false; |
| } |
| |
| bool PluginInvoke(NPObject* header, |
| NPIdentifier name, |
| const NPVariant* args, uint32 arg_count, |
| NPVariant* result) { |
| return false; |
| } |
| |
| bool PluginInvokeDefault(NPObject* obj, |
| const NPVariant* args, uint32 arg_count, |
| NPVariant* result) { |
| VOID_TO_NPVARIANT(*result); |
| return true; |
| } |
| |
| bool PluginHasProperty(NPObject* obj, NPIdentifier name) { |
| return false; |
| } |
| |
| bool PluginGetProperty(NPObject* obj, |
| NPIdentifier name, |
| NPVariant* result) { |
| return false; |
| } |
| |
| bool PluginSetProperty(NPObject* obj, |
| NPIdentifier name, |
| const NPVariant* variant) { |
| return false; |
| } |
| |
| NPClass plugin_class = { |
| NP_CLASS_STRUCT_VERSION, |
| PluginAllocate, |
| PluginDeallocate, |
| PluginInvalidate, |
| PluginHasMethod, |
| PluginInvoke, |
| PluginInvokeDefault, |
| PluginHasProperty, |
| PluginGetProperty, |
| PluginSetProperty, |
| }; |
| |
| void TickCallback(void* data) { |
| reinterpret_cast<gpu::demos::Plugin*>(data)->Tick(); |
| } |
| |
| void RepaintCallback(NPP npp, NPDeviceContext3D* /* context */) { |
| Plugin* plugin = static_cast<Plugin*>(npp->pdata); |
| plugin->Paint(); |
| } |
| } |
| |
| namespace gpu { |
| namespace demos { |
| |
| NPNetscapeFuncs* g_browser; |
| |
| Plugin::Plugin(NPP npp) |
| : npp_(npp), |
| device3d_(NULL), |
| pgl_context_(NULL), |
| demo_(CreateDemo()) { |
| memset(&context3d_, 0, sizeof(context3d_)); |
| } |
| |
| Plugin::~Plugin() { |
| // Destroy demo while GL context is current and before it is destroyed. |
| pglMakeCurrent(pgl_context_); |
| demo_.reset(); |
| pglMakeCurrent(PGL_NO_CONTEXT); |
| |
| DestroyContext(); |
| } |
| |
| NPClass* Plugin::GetPluginClass() { |
| return &plugin_class; |
| } |
| |
| void Plugin::New(NPMIMEType pluginType, |
| int16 argc, char* argn[], char* argv[]) { |
| if (!g_extensions) { |
| g_browser->getvalue(npp_, NPNVPepperExtensions, &g_extensions); |
| CHECK(g_extensions); |
| } |
| |
| device3d_ = g_extensions->acquireDevice(npp_, NPPepper3DDevice); |
| CHECK(device3d_); |
| } |
| |
| void Plugin::SetWindow(const NPWindow& window) { |
| demo_->InitWindowSize(window.width, window.height); |
| |
| if (!pgl_context_) { |
| CreateContext(); |
| |
| // Schedule first call to Tick. |
| if (demo_->IsAnimated()) |
| g_browser->pluginthreadasynccall(npp_, TickCallback, this); |
| } |
| } |
| |
| int32 Plugin::HandleEvent(const NPPepperEvent& event) { |
| return 0; |
| } |
| |
| void Plugin::Tick() { |
| Paint(); |
| |
| // Schedule another call to Tick. |
| g_browser->pluginthreadasynccall(npp_, TickCallback, this); |
| } |
| |
| void Plugin::Paint() { |
| if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) { |
| DestroyContext(); |
| CreateContext(); |
| pglMakeCurrent(pgl_context_); |
| } |
| |
| demo_->Draw(); |
| pglSwapBuffers(); |
| pglMakeCurrent(PGL_NO_CONTEXT); |
| } |
| |
| void Plugin::CreateContext() { |
| DCHECK(!pgl_context_); |
| |
| // Initialize a 3D context. |
| NPDeviceContext3DConfig config; |
| config.commandBufferSize = kCommandBufferSize; |
| device3d_->initializeContext(npp_, &config, &context3d_); |
| context3d_.repaintCallback = RepaintCallback; |
| |
| // Create a PGL context. |
| pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_); |
| |
| // Initialize demo. |
| pglMakeCurrent(pgl_context_); |
| CHECK(demo_->InitGL()); |
| pglMakeCurrent(PGL_NO_CONTEXT); |
| } |
| |
| void Plugin::DestroyContext() { |
| DCHECK(pgl_context_); |
| |
| pglDestroyContext(pgl_context_); |
| pgl_context_ = NULL; |
| |
| device3d_->destroyContext(npp_, &context3d_); |
| } |
| |
| } // namespace demos |
| } // namespace gpu |