summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authoralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-26 02:53:54 +0000
committeralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-26 02:53:54 +0000
commit326975bc6d456cf9fd4a6d944ce1f9f5f834e7e4 (patch)
tree544760f0e2efb3a6e81ab024ea51adc4b7c0dddd /gpu
parenta651b74d09d8f96d6dbb488dde3c494d97544886 (diff)
downloadchromium_src-326975bc6d456cf9fd4a6d944ce1f9f5f834e7e4.zip
chromium_src-326975bc6d456cf9fd4a6d944ce1f9f5f834e7e4.tar.gz
chromium_src-326975bc6d456cf9fd4a6d944ce1f9f5f834e7e4.tar.bz2
Added infrastructure to run gpu demos under Pepper3D. Created a Demo class that can be run as both standalone apps (exe) or pepper plugins (dll). Created entry points and framework classes for both platforms - exe and pepper. A demo application has three layers:
1. Entry point - standalone (main_exe.cc): Contains the main function for console applications. Instantiates and runs a window. - pepper (main_pepper.cc): Contains NPAPI entry points. Instantiates pepper plugin object. 2. Framework that hosts demo - standalone: Window - pepper: Plugin 3. Demo - One demo class for all platforms. This does all the rendering and event handling. BUG=26099 Review URL: http://codereview.chromium.org/554053 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37082 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/demos/app_framework/application.h68
-rw-r--r--gpu/demos/demos.gyp112
-rw-r--r--gpu/demos/framework/demo.cc35
-rw-r--r--gpu/demos/framework/demo.h67
-rw-r--r--gpu/demos/framework/demo_factory.h17
-rw-r--r--gpu/demos/framework/main_exe.cc24
-rw-r--r--gpu/demos/framework/main_pepper.cc148
-rw-r--r--gpu/demos/framework/platform.h (renamed from gpu/demos/app_framework/platform.h)12
-rw-r--r--gpu/demos/framework/plugin.cc147
-rw-r--r--gpu/demos/framework/plugin.def4
-rw-r--r--gpu/demos/framework/plugin.h51
-rw-r--r--gpu/demos/framework/plugin.rc35
-rw-r--r--gpu/demos/framework/window.cc (renamed from gpu/demos/app_framework/application.cc)182
-rw-r--r--gpu/demos/framework/window.h39
-rw-r--r--gpu/demos/gles2_book/example.h52
-rw-r--r--gpu/demos/gles2_book/hello_triangle.cc (renamed from gpu/demos/hello_triangle/main.cc)32
-rw-r--r--gpu/demos/pepper_gpu_demo.html12
17 files changed, 781 insertions, 256 deletions
diff --git a/gpu/demos/app_framework/application.h b/gpu/demos/app_framework/application.h
deleted file mode 100644
index d9d48e9..0000000
--- a/gpu/demos/app_framework/application.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2006-2009 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.
-
-// Base class for gles2 applications using command buffer.
-
-#ifndef GPU_DEMOS_APP_FRAMEWORK_APPLICATION_H_
-#define GPU_DEMOS_APP_FRAMEWORK_APPLICATION_H_
-
-#include "base/at_exit.h"
-#include "base/message_loop.h"
-#include "base/time.h"
-
-#include "gpu/demos/app_framework/platform.h"
-
-namespace gpu_demos {
-
-// Acts as a base class for GLES2 applications using command buffer.
-// The derived calls needs to call InitRenderContext() to create a render
-// surface and initialize a rendering context. Currently it only creates
-// an on-screen window. It will be extended to support pepper/nacl plugin
-// when pepper 3D api is in place.
-class Application {
- public:
- Application();
- virtual ~Application();
-
- // Enters the event processing loop.
- void MainLoop();
- void OnPaint();
-
- protected:
- // Returns the width of rendering surface.
- inline int width() const { return width_; }
- // Returns the height of rendering surface.
- inline int height() const { return height_; }
-
- bool InitRenderContext();
-
- // The framework calls this function for the derived classes to do custom
- // rendering. There is no default implementation. It must be defined by the
- // derived classes. The elapsed_sec param represents the time elapsed
- // (in seconds) after Draw was called the last time. It can be used to
- // make the application frame-rate independent. It is 0.0f for the
- // first draw call.
- virtual void Draw(float elapsed_sec) = 0;
-
- private:
- // Creates a native on-screen window.
- NativeWindowHandle CreateNativeWindow();
-
- int width_;
- int height_;
- NativeWindowHandle window_handle_;
-
- // Time at which draw was called last.
- base::Time last_draw_time_;
-
- // The following two variables are just needed to satisfy
- // the assumption that we are running inside a browser.
- base::AtExitManager at_exit_manager_;
- MessageLoopForUI message_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(Application);
-};
-
-} // namespace gpu_demos
-#endif // GPU_DEMOS_APP_FRAMEWORK_APPLICATION_H_
diff --git a/gpu/demos/demos.gyp b/gpu/demos/demos.gyp
index 99aa697..307e50b 100644
--- a/gpu/demos/demos.gyp
+++ b/gpu/demos/demos.gyp
@@ -11,93 +11,87 @@
],
'targets': [
{
- 'target_name': 'app_framework',
+ 'target_name': 'gpu_demo_framework',
'type': 'static_library',
'dependencies': [
- '../gpu.gyp:command_buffer_client',
- '../gpu.gyp:command_buffer_service',
- ],
- 'sources': [
- 'app_framework/application.cc',
- 'app_framework/application.h',
- 'app_framework/platform.h',
- ],
- },
- {
- 'target_name': 'hello_triangle',
- 'type': 'executable',
- 'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:hello_triangle',
- ],
- 'sources': [
- 'hello_triangle/main.cc',
- ],
- },
- {
- 'target_name': 'mip_map_2d',
- 'type': 'executable',
- 'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:mip_map_2d',
+ '../../base/base.gyp:base',
],
'sources': [
- 'mip_map_2d/main.cc',
+ 'framework/demo.cc',
+ 'framework/demo.h',
+ 'framework/demo_factory.h',
],
},
{
- 'target_name': 'simple_texture_2d',
- 'type': 'executable',
- 'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:simple_texture_2d',
- ],
- 'sources': [
- 'simple_texture_2d/main.cc',
- ],
- },
- {
- 'target_name': 'simple_texture_cubemap',
- 'type': 'executable',
+ 'target_name': 'gpu_demo_framework_exe',
+ 'type': 'static_library',
'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:simple_texture_cubemap',
+ 'gpu_demo_framework',
+ '../gpu.gyp:command_buffer_client',
+ '../gpu.gyp:command_buffer_service',
],
+ 'all_dependent_settings': {
+ 'sources': [
+ 'framework/main_exe.cc',
+ ],
+ },
'sources': [
- 'simple_texture_cubemap/main.cc',
+ 'framework/platform.h',
+ 'framework/window.cc',
+ 'framework/window.h',
],
},
{
- 'target_name': 'simple_vertex_shader',
- 'type': 'executable',
+ 'target_name': 'gpu_demo_framework_pepper',
+ 'type': 'static_library',
'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:simple_vertex_shader',
- ],
+ 'gpu_demo_framework',
+ '../gpu.gyp:pgl',
+ ],
+ 'all_dependent_settings': {
+ 'sources': [
+ 'framework/main_pepper.cc',
+ 'framework/plugin.def',
+ 'framework/plugin.rc',
+ ],
+ 'run_as': {
+ 'action': [
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)chrome<(EXECUTABLE_SUFFIX)',
+ '--no-sandbox',
+ '--internal-pepper',
+ '--enable-gpu-plugin',
+ '--load-plugin=$(TargetPath)',
+ 'file://$(ProjectDir)pepper_gpu_demo.html',
+ ],
+ },
+ },
'sources': [
- 'simple_vertex_shader/main.cc',
+ 'framework/plugin.cc',
+ 'framework/plugin.h',
],
},
{
- 'target_name': 'stencil_test',
+ 'target_name': 'hello_triangle_exe',
'type': 'executable',
'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:stencil_test',
+ 'gpu_demo_framework_exe',
+ '../../third_party/gles2_book/gles2_book.gyp:hello_triangle',
],
'sources': [
- 'stencil_test/main.cc',
+ 'gles2_book/example.h',
+ 'gles2_book/hello_triangle.cc',
],
},
{
- 'target_name': 'texture_wrap',
- 'type': 'executable',
+ 'target_name': 'hello_triangle_pepper',
+ 'type': 'shared_library',
'dependencies': [
- 'app_framework',
- '../../third_party/gles2_book/gles2_book.gyp:texture_wrap',
+ 'gpu_demo_framework_pepper',
+ '../../third_party/gles2_book/gles2_book.gyp:hello_triangle',
],
'sources': [
- 'texture_wrap/main.cc',
+ 'gles2_book/example.h',
+ 'gles2_book/hello_triangle.cc',
],
},
]
diff --git a/gpu/demos/framework/demo.cc b/gpu/demos/framework/demo.cc
new file mode 100644
index 0000000..49fa519
--- /dev/null
+++ b/gpu/demos/framework/demo.cc
@@ -0,0 +1,35 @@
+// 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/demo.h"
+#include "gpu/demos/framework/demo_factory.h"
+
+namespace gpu {
+namespace demos {
+
+Demo::Demo() : width_(0), height_(0) {
+}
+
+Demo::~Demo() {
+}
+
+void Demo::InitWindowSize(int width, int height) {
+ width_ = width;
+ height_ = height;
+}
+
+void Demo::Draw() {
+ float elapsed_sec = 0.0f;
+ const base::Time current_time = base::Time::Now();
+ if (!last_draw_time_.is_null()) {
+ base::TimeDelta time_delta = current_time - last_draw_time_;
+ elapsed_sec = static_cast<float>(time_delta.InSecondsF());
+ }
+ last_draw_time_ = current_time;
+
+ Render(elapsed_sec);
+}
+
+} // namespace demos
+} // namespace gpu
diff --git a/gpu/demos/framework/demo.h b/gpu/demos/framework/demo.h
new file mode 100644
index 0000000..801609b
--- /dev/null
+++ b/gpu/demos/framework/demo.h
@@ -0,0 +1,67 @@
+// 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.
+
+// Base class for gles2 demos.
+
+#ifndef GPU_DEMOS_FRAMEWORK_DEMO_H_
+#define GPU_DEMOS_FRAMEWORK_DEMO_H_
+
+#include "base/time.h"
+
+namespace gpu {
+namespace demos {
+
+// Base class for GLES2 demos. The same demo class is supposed to be run as
+// standalone apps (exe), pepper plugin (dll), and nacl module (nexe). This is
+// accomplished by creating framework for each platfom and hosting the demo
+// class object.
+class Demo {
+ public:
+ Demo();
+ virtual ~Demo();
+
+ // Returns the title of demo. This title is used to name the window or
+ // html page where demo is running.
+ virtual const wchar_t* Title() const = 0;
+
+ // Initializes the size of the window on which this demo object will render.
+ void InitWindowSize(int width, int height);
+
+ // This function is called by the framework to initialize the OpenGL state
+ // required by this demo. When this function is called, it is assumed that
+ // a rendering context has already been created and made current.
+ virtual bool InitGL() = 0;
+
+ // This function is called by the framework to perform OpenGL rendering.
+ // When this function is called, it is assumed that the rendering context
+ // has been made current.
+ void Draw();
+
+ protected:
+ // Returns the width of window.
+ int width() const { return width_; }
+ // Returns the height of window.
+ int height() const { return height_; }
+
+ // The framework calls this function for the derived classes to do custom
+ // rendering. There is no default implementation. It must be defined by the
+ // derived classes. The elapsed_sec param represents the time elapsed
+ // (in seconds) after Render was called the last time. It can be used to
+ // make the application frame-rate independent. It is 0.0f for the
+ // first render call.
+ virtual void Render(float elapsed_sec) = 0;
+
+ private:
+ int width_; // Window width.
+ int height_; // Window height.
+
+ // Time at which draw was called last.
+ base::Time last_draw_time_;
+
+ DISALLOW_COPY_AND_ASSIGN(Demo);
+};
+
+} // namespace demos
+} // namespace gpu
+#endif // GPU_DEMOS_FRAMEWORK_DEMO_H_
diff --git a/gpu/demos/framework/demo_factory.h b/gpu/demos/framework/demo_factory.h
new file mode 100644
index 0000000..1cecc9f
--- /dev/null
+++ b/gpu/demos/framework/demo_factory.h
@@ -0,0 +1,17 @@
+// 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.
+
+#ifndef GPU_DEMOS_FRAMEWORK_DEMO_FACTORY_H_
+#define GPU_DEMOS_FRAMEWORK_DEMO_FACTORY_H_
+
+namespace gpu {
+namespace demos {
+
+class Demo;
+
+extern Demo* CreateDemo();
+
+} // namespace demos
+} // namespace gpu
+#endif // GPU_DEMOS_FRAMEWORK_DEMO_FACTORY_H_
diff --git a/gpu/demos/framework/main_exe.cc b/gpu/demos/framework/main_exe.cc
new file mode 100644
index 0000000..fa4e726
--- /dev/null
+++ b/gpu/demos/framework/main_exe.cc
@@ -0,0 +1,24 @@
+// 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 "base/at_exit.h"
+#include "base/logging.h"
+#include "gpu/demos/framework/window.h"
+
+namespace {
+static const int kWindowWidth = 512;
+static const int kWindowHeight = 512;
+} // namespace.
+
+int main(int argc, char *argv[]) {
+ // AtExitManager is used by singleton classes to delete themselves when
+ // the program terminates.
+ base::AtExitManager at_exit_manager_;
+
+ gpu::demos::Window window;
+ CHECK(window.Init(kWindowWidth, kWindowHeight));
+
+ window.MainLoop();
+ return EXIT_SUCCESS;
+}
diff --git a/gpu/demos/framework/main_pepper.cc b/gpu/demos/framework/main_pepper.cc
new file mode 100644
index 0000000..d97cbd0
--- /dev/null
+++ b/gpu/demos/framework/main_pepper.cc
@@ -0,0 +1,148 @@
+// 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 "base/at_exit.h"
+#include "base/logging.h"
+#include "gpu/demos/framework/plugin.h"
+#include "webkit/glue/plugins/nphostapi.h"
+
+namespace {
+// AtExitManager is used by singleton classes to delete themselves when
+// the program terminates. There should be only one instance of this class
+// per thread;
+base::AtExitManager* g_at_exit_manager_;
+} // namespace
+
+namespace gpu {
+namespace demos {
+// NPP entry points.
+NPError NPP_New(NPMIMEType pluginType,
+ NPP instance,
+ uint16 mode,
+ int16 argc, char* argn[], char* argv[],
+ NPSavedData* saved) {
+ if (g_browser->version < NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) {
+ return NPERR_INCOMPATIBLE_VERSION_ERROR;
+ }
+
+ Plugin* plugin = static_cast<Plugin*>(
+ g_browser->createobject(instance, Plugin::GetPluginClass()));
+ instance->pdata = plugin;
+ plugin->New(pluginType, argc, argn, argv);
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_Destroy(NPP instance, NPSavedData** save) {
+ Plugin* plugin = static_cast<Plugin*>(instance->pdata);
+ if (plugin) g_browser->releaseobject(plugin);
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_SetWindow(NPP instance, NPWindow* window) {
+ Plugin* plugin = static_cast<Plugin*>(instance->pdata);
+ if (plugin) plugin->SetWindow(*window);
+
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_NewStream(NPP instance,
+ NPMIMEType type,
+ NPStream* stream,
+ NPBool seekable,
+ uint16* stype) {
+ *stype = NP_ASFILEONLY;
+ return NPERR_NO_ERROR;
+}
+
+NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {
+ return NPERR_NO_ERROR;
+}
+
+void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {
+}
+
+int32 NPP_Write(NPP instance,
+ NPStream* stream,
+ int32 offset,
+ int32 len,
+ void* buffer) {
+ return 0;
+}
+
+int32 NPP_WriteReady(NPP instance, NPStream* stream) {
+ return 0;
+}
+
+void NPP_Print(NPP instance, NPPrint* platformPrint) {
+}
+
+int16 NPP_HandleEvent(NPP instance, void* event) {
+ return 0;
+}
+
+void NPP_URLNotify(NPP instance, const char* url, NPReason reason,
+ void* notify_data) {
+}
+
+NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) {
+ NPError err = NPERR_NO_ERROR;
+
+ switch (variable) {
+ case NPPVpluginScriptableNPObject: {
+ void** v = reinterpret_cast<void**>(value);
+ Plugin* plugin = static_cast<Plugin*>(instance->pdata);
+ // Return value is expected to be retained
+ g_browser->retainobject(plugin);
+ *v = plugin;
+ break;
+ }
+ default:
+ LOG(INFO) << "Unhandled variable to NPP_GetValue\n";
+ err = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ return err;
+}
+
+NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value) {
+ return NPERR_GENERIC_ERROR;
+}
+} // namespace demos
+} // namespace gpu
+
+// NP entry points
+extern "C" {
+NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) {
+ plugin_funcs->version = NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL;
+ plugin_funcs->size = sizeof(plugin_funcs);
+ plugin_funcs->newp = gpu::demos::NPP_New;
+ plugin_funcs->destroy = gpu::demos::NPP_Destroy;
+ plugin_funcs->setwindow = gpu::demos::NPP_SetWindow;
+ plugin_funcs->newstream = gpu::demos::NPP_NewStream;
+ plugin_funcs->destroystream = gpu::demos::NPP_DestroyStream;
+ plugin_funcs->asfile = gpu::demos::NPP_StreamAsFile;
+ plugin_funcs->writeready = gpu::demos::NPP_WriteReady;
+ plugin_funcs->write = gpu::demos::NPP_Write;
+ plugin_funcs->print = gpu::demos::NPP_Print;
+ plugin_funcs->event = gpu::demos::NPP_HandleEvent;
+ plugin_funcs->urlnotify = gpu::demos::NPP_URLNotify;
+ plugin_funcs->getvalue = gpu::demos::NPP_GetValue;
+ plugin_funcs->setvalue = gpu::demos::NPP_SetValue;
+
+ return NPERR_NO_ERROR;
+}
+
+NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs) {
+ g_at_exit_manager_ = new base::AtExitManager();
+ gpu::demos::g_browser = browser_funcs;
+ return NPERR_NO_ERROR;
+}
+
+void API_CALL NP_Shutdown() {
+ delete g_at_exit_manager_;
+}
+} // extern "C"
diff --git a/gpu/demos/app_framework/platform.h b/gpu/demos/framework/platform.h
index 602979e..cd6c003 100644
--- a/gpu/demos/app_framework/platform.h
+++ b/gpu/demos/framework/platform.h
@@ -4,8 +4,8 @@
// Platform-specific types and definitions for native widget handles.
-#ifndef GPU_DEMOS_APP_FRAMEWORK_PLATFORM_H_
-#define GPU_DEMOS_APP_FRAMEWORK_PLATFORM_H_
+#ifndef GPU_DEMOS_FRAMEWORK_PLATFORM_H_
+#define GPU_DEMOS_FRAMEWORK_PLATFORM_H_
#ifdef _WINDOWS
#include <windows.h>
@@ -13,11 +13,13 @@
#include "build/build_config.h"
-namespace gpu_demos {
+namespace gpu {
+namespace demos {
#if defined(OS_WIN)
typedef HWND NativeWindowHandle;
#endif // defined(OS_WIN)
-} // namespace gpu_demos
-#endif // GPU_DEMOS_APP_FRAMEWORK_PLATFORM_H_
+} // namespace demos
+} // namespace gpu
+#endif // GPU_DEMOS_FRAMEWORK_PLATFORM_H_
diff --git a/gpu/demos/framework/plugin.cc b/gpu/demos/framework/plugin.cc
new file mode 100644
index 0000000..b5278b1
--- /dev/null
+++ b/gpu/demos/framework/plugin.cc
@@ -0,0 +1,147 @@
+// 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"
+
+namespace {
+const int32 kCommandBufferSize = 1024 * 1024;
+NPExtensions* g_extensions = NULL;
+
+// Plugin class functions.
+using gpu::demos::Plugin;
+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 PaintCallback(void* data) {
+ reinterpret_cast<gpu::demos::Plugin*>(data)->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() {
+ pglMakeCurrent(NULL);
+ pglDestroyContext(pgl_context_);
+}
+
+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) {
+ if (!pgl_context_) {
+ // Initialize a 3D context.
+ NPDeviceContext3DConfig config;
+ config.commandBufferEntries = kCommandBufferSize;
+ device3d_->initializeContext(npp_, &config, &context3d_);
+
+ // Create a PGL context.
+ pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_);
+
+ // Initialize demo.
+ pglMakeCurrent(pgl_context_);
+ demo_->InitWindowSize(window.width, window.height);
+ CHECK(demo_->InitGL());
+ pglMakeCurrent(NULL);
+ }
+
+ // Schedule the first call to Draw.
+ g_browser->pluginthreadasynccall(npp_, PaintCallback, this);
+}
+
+void Plugin::Paint() {
+ // Render some stuff.
+ pglMakeCurrent(pgl_context_);
+ demo_->Draw();
+ pglSwapBuffers();
+ pglMakeCurrent(NULL);
+
+ // Schedule another call to Paint.
+ g_browser->pluginthreadasynccall(npp_, PaintCallback, this);
+}
+
+} // namespace demos
+} // namespace gpu
diff --git a/gpu/demos/framework/plugin.def b/gpu/demos/framework/plugin.def
new file mode 100644
index 0000000..ddc24ce
--- /dev/null
+++ b/gpu/demos/framework/plugin.def
@@ -0,0 +1,4 @@
+EXPORTS
+ NP_GetEntryPoints @1
+ NP_Initialize @2
+ NP_Shutdown @3
diff --git a/gpu/demos/framework/plugin.h b/gpu/demos/framework/plugin.h
new file mode 100644
index 0000000..7832d3b
--- /dev/null
+++ b/gpu/demos/framework/plugin.h
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef GPU_DEMOS_FRAMEWORK_PLUGIN_H_
+#define GPU_DEMOS_FRAMEWORK_PLUGIN_H_
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "gpu/demos/framework/demo.h"
+#include "gpu/pgl/pgl.h"
+#include "webkit/glue/plugins/nphostapi.h"
+
+namespace gpu {
+namespace demos {
+
+// Acts as a framework for pepper3d demos. It is in fact a pepper plugin with
+// a pepper3d device. It delegates all rendering tasks to demo object.
+class Plugin : public NPObject {
+ public:
+ explicit Plugin(NPP npp);
+ ~Plugin();
+
+ static NPClass* GetPluginClass();
+
+ NPP npp() const { return npp_; }
+ void New(NPMIMEType pluginType, int16 argc, char* argn[], char* argv[]);
+ void SetWindow(const NPWindow& window);
+
+ // Called by the browser to paint the window.
+ void Paint();
+
+ private:
+ // This class object needs to be safely casted to NPObject* and cross
+ // c-c++ module boundaries. To accomplish that this class should not have
+ // any virtual member function.
+ NPP npp_;
+
+ NPDevice* device3d_;
+ NPDeviceContext3D context3d_;
+ PGLContext pgl_context_;
+ scoped_ptr<Demo> demo_;
+
+ DISALLOW_COPY_AND_ASSIGN(Plugin);
+};
+
+extern NPNetscapeFuncs* g_browser;
+
+} // namespace demos
+} // namespace gpu
+#endif // GPU_DEMOS_FRAMEWORK_PLUGIN_H_
diff --git a/gpu/demos/framework/plugin.rc b/gpu/demos/framework/plugin.rc
new file mode 100644
index 0000000..ee6b4fa
--- /dev/null
+++ b/gpu/demos/framework/plugin.rc
@@ -0,0 +1,35 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+1 VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x7L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Pepper GPU Demo"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "LegalCopyright", "Copyright (C) 2010"
+ VALUE "ProductName", "Pepper GPU Demo"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ VALUE "MIMEType", "pepper-application/x-gpu-demo"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/gpu/demos/app_framework/application.cc b/gpu/demos/framework/window.cc
index b82e691a..6833feb 100644
--- a/gpu/demos/app_framework/application.cc
+++ b/gpu/demos/framework/window.cc
@@ -1,13 +1,14 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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/app_framework/application.h"
+#include "gpu/demos/framework/window.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_lib.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/gpu_processor.h"
+#include "gpu/demos/framework/demo_factory.h"
using gpu::Buffer;
using gpu::CommandBufferService;
@@ -15,15 +16,13 @@ using gpu::GPUProcessor;
using gpu::gles2::GLES2CmdHelper;
using gpu::gles2::GLES2Implementation;
-// TODO(alokp): Implement it on mac and linux when gpu process is functional
-// on these OS'.
-#if defined(OS_WIN)
+// TODO(alokp): Make this class cross-platform. Investigate using SDL.
namespace {
-static const int32 kCommandBufferSize = 1024 * 1024;
-static const int32 kTransferBufferSize = 512 * 1024;
+const int32 kCommandBufferSize = 1024 * 1024;
+const int32 kTransferBufferSize = 512 * 1024;
-static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
- WPARAM w_param, LPARAM l_param) {
+LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
+ WPARAM w_param, LPARAM l_param) {
LRESULT result = 0;
switch (msg) {
case WM_CLOSE:
@@ -32,11 +31,12 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
case WM_DESTROY:
::PostQuitMessage(0);
break;
+ case WM_ERASEBKGND:
+ break;
case WM_PAINT: {
- using gpu_demos::Application;
- Application* app = reinterpret_cast<Application*>(
+ gpu::demos::Window* window = reinterpret_cast<gpu::demos::Window*>(
GetWindowLongPtr(hwnd, GWL_USERDATA));
- if (app != NULL) app->OnPaint();
+ if (window != NULL) window->OnPaint();
::ValidateRect(hwnd, NULL);
break;
}
@@ -46,51 +46,50 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
}
return result;
}
-} // namespace.
-
-namespace gpu_demos {
-Application::Application()
- : width_(512),
- height_(512),
- window_handle_(NULL) {
-}
+HWND CreateNativeWindow(const wchar_t* title, int width, int height,
+ LONG_PTR user_data) {
+ WNDCLASS wnd_class = {0};
+ HINSTANCE instance = GetModuleHandle(NULL);
+ wnd_class.style = CS_OWNDC;
+ wnd_class.lpfnWndProc = WindowProc;
+ wnd_class.hInstance = instance;
+ wnd_class.hbrBackground =
+ reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
+ wnd_class.lpszClassName = L"gpu_demo";
+ if (!RegisterClass(&wnd_class)) return NULL;
-Application::~Application() {
-}
+ DWORD wnd_style = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;
+ RECT wnd_rect;
+ wnd_rect.left = 0;
+ wnd_rect.top = 0;
+ wnd_rect.right = width;
+ wnd_rect.bottom = height;
+ AdjustWindowRect(&wnd_rect, wnd_style, FALSE);
-void Application::MainLoop() {
- MSG msg;
- bool done = false;
- while (!done) {
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT) done = true;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- // Message queue is empty and application has not quit yet - keep painting.
- if (!done) SendMessage(window_handle_, WM_PAINT, 0, 0);
- }
-}
+ HWND hwnd = CreateWindow(
+ wnd_class.lpszClassName,
+ title,
+ wnd_style,
+ 0,
+ 0,
+ wnd_rect.right - wnd_rect.left,
+ wnd_rect.bottom - wnd_rect.top,
+ NULL,
+ NULL,
+ instance,
+ NULL);
+ if (hwnd == NULL) return NULL;
-void Application::OnPaint() {
- float elapsed_sec = 0.0f;
- const base::Time current_time = base::Time::Now();
- if (!last_draw_time_.is_null()) {
- base::TimeDelta time_delta = current_time - last_draw_time_;
- elapsed_sec = static_cast<float>(time_delta.InSecondsF());
- }
- last_draw_time_ = current_time;
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ // Set this to the GWL_USERDATA so that it is available to WindowProc.
+ SetWindowLongPtr(hwnd, GWL_USERDATA, user_data);
- Draw(elapsed_sec);
- gles2::GetGLContext()->SwapBuffers();
+ return hwnd;
}
-bool Application::InitRenderContext() {
- window_handle_ = CreateNativeWindow();
- if (window_handle_ == NULL) {
- return false;
- }
+bool InitRenderContext(HWND hwnd) {
+ CHECK(hwnd);
scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService);
if (!command_buffer->Initialize(kCommandBufferSize)) {
@@ -99,7 +98,7 @@ bool Application::InitRenderContext() {
scoped_refptr<GPUProcessor> gpu_processor(
new GPUProcessor(command_buffer.get()));
- if (!gpu_processor->Initialize(window_handle_)) {
+ if (!gpu_processor->Initialize(hwnd)) {
return false;
}
@@ -118,52 +117,53 @@ bool Application::InitRenderContext() {
command_buffer->GetTransferBuffer(transfer_buffer_id);
if (transfer_buffer.ptr == NULL) return false;
- gles2::g_gl_impl = new GLES2Implementation(helper,
- transfer_buffer.size,
- transfer_buffer.ptr,
- transfer_buffer_id);
-
+ gles2::SetGLContext(new GLES2Implementation(helper,
+ transfer_buffer.size,
+ transfer_buffer.ptr,
+ transfer_buffer_id));
return command_buffer.release() != NULL;
}
+} // namespace.
-NativeWindowHandle Application::CreateNativeWindow() {
- WNDCLASS wnd_class = {0};
- HINSTANCE instance = GetModuleHandle(NULL);
- wnd_class.style = CS_OWNDC;
- wnd_class.lpfnWndProc = (WNDPROC)WindowProc;
- wnd_class.hInstance = instance;
- wnd_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wnd_class.lpszClassName = L"opengles2.0";
- if (!RegisterClass(&wnd_class)) return NULL;
+namespace gpu {
+namespace demos {
- DWORD wnd_style = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;
- RECT wnd_rect;
- wnd_rect.left = 0;
- wnd_rect.top = 0;
- wnd_rect.right = width_;
- wnd_rect.bottom = height_;
- AdjustWindowRect(&wnd_rect, wnd_style, FALSE);
+Window::Window()
+ : window_handle_(NULL),
+ demo_(CreateDemo()) {
+}
- HWND hwnd = CreateWindow(
- wnd_class.lpszClassName,
- wnd_class.lpszClassName,
- wnd_style,
- 0,
- 0,
- wnd_rect.right - wnd_rect.left,
- wnd_rect.bottom - wnd_rect.top,
- NULL,
- NULL,
- instance,
- NULL);
- if (hwnd == NULL) return NULL;
+Window::~Window() {
+}
- ShowWindow(hwnd, SW_SHOWNORMAL);
- // Set this to the GWL_USERDATA so that it is available to WindowProc.
- SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)this);
+bool Window::Init(int width, int height) {
+ window_handle_ = CreateNativeWindow(demo_->Title(), width, height,
+ reinterpret_cast<LONG_PTR>(this));
+ if (window_handle_ == NULL) return false;
+ if (!InitRenderContext(window_handle_)) return false;
- return hwnd;
+ demo_->InitWindowSize(width, height);
+ return demo_->InitGL();
+}
+
+void Window::MainLoop() {
+ MSG msg;
+ bool done = false;
+ while (!done) {
+ while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_QUIT) done = true;
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ // Message queue is empty and application has not quit yet - keep painting.
+ if (!done) ::UpdateWindow(window_handle_);
+ }
+}
+
+void Window::OnPaint() {
+ demo_->Draw();
+ ::gles2::GetGLContext()->SwapBuffers();
}
-} // namespace gpu_demos
-#endif // defined(OS_WIN)
+} // namespace demos
+} // namespace gpu
diff --git a/gpu/demos/framework/window.h b/gpu/demos/framework/window.h
new file mode 100644
index 0000000..dade945
--- /dev/null
+++ b/gpu/demos/framework/window.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2006-2009 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.
+
+#ifndef GPU_DEMOS_FRAMEWORK_WINDOW_H_
+#define GPU_DEMOS_FRAMEWORK_WINDOW_H_
+
+#include "base/scoped_ptr.h"
+#include "gpu/demos/framework/demo.h"
+#include "gpu/demos/framework/platform.h"
+
+namespace gpu {
+namespace demos {
+
+// Acts as a framework for standalone demos. It creates a window and delegates
+// all events to demo to perform rendering and other tasks.
+class Window {
+ public:
+ Window();
+ virtual ~Window();
+
+ // Initializes and creates a window with given dimensions.
+ bool Init(int width, int height);
+
+ // Enters the event processing loop.
+ void MainLoop();
+
+ void OnPaint();
+
+ private:
+ NativeWindowHandle window_handle_;
+ scoped_ptr<Demo> demo_;
+
+ DISALLOW_COPY_AND_ASSIGN(Window);
+};
+
+} // namespace demos
+} // namespace gpu
+#endif // GPU_DEMOS_FRAMEWORK_WINDOW_H_
diff --git a/gpu/demos/gles2_book/example.h b/gpu/demos/gles2_book/example.h
index 839dfe3..5facbdd 100644
--- a/gpu/demos/gles2_book/example.h
+++ b/gpu/demos/gles2_book/example.h
@@ -7,7 +7,7 @@
#ifndef GPU_DEMOS_GLES2_BOOK_EXAMPLE_H_
#define GPU_DEMOS_GLES2_BOOK_EXAMPLE_H_
-#include "gpu/demos/app_framework/application.h"
+#include "gpu/demos/framework/demo.h"
#include "third_party/gles2_book/Common/Include/esUtil.h"
namespace gpu {
@@ -28,47 +28,61 @@ typedef void ShutDownFunc(ESContext* context);
// 4. ShutDownFunc is called when program terminates
// This class encapsulates this pattern to make it easier to write classes
// for each example.
-template <typename UserData,
- InitFunc init_func,
- UpdateFunc update_func,
- DrawFunc draw_func,
- ShutDownFunc shut_down_func>
-class Example : public gpu_demos::Application {
+template <typename UserData>
+class Example : public gpu::demos::Demo {
public:
- Example() {
+ Example()
+ : init_func_(NULL),
+ update_func_(NULL),
+ draw_func_(NULL),
+ shut_down_func_(NULL) {
esInitContext(&context_);
memset(&user_data_, 0, sizeof(UserData));
context_.userData = &user_data_;
}
virtual ~Example() {
- shut_down_func(&context_);
+ shut_down_func_(&context_);
}
- bool Init() {
- if (!InitRenderContext()) return false;
+ virtual bool InitGL() {
+ // Note that update_func is optional.
+ CHECK(init_func_ && draw_func_ && shut_down_func_);
context_.width = width();
context_.height = height();
- if (!init_func(&context_)) return false;
+ if (!init_func_(&context_)) return false;
return true;
}
protected:
- virtual void Draw(float elapsed_sec) {
- update_func(&context_, elapsed_sec);
- draw_func(&context_);
+ void RegisterCallbacks(InitFunc* init_func,
+ UpdateFunc* update_func,
+ DrawFunc* draw_func,
+ ShutDownFunc* shut_down_func) {
+ init_func_ = init_func;
+ update_func_ = update_func;
+ draw_func_ = draw_func;
+ shut_down_func_ = shut_down_func;
+ }
+
+ virtual void Render(float elapsed_sec) {
+ if (update_func_) update_func_(&context_, elapsed_sec);
+ draw_func_(&context_);
}
private:
ESContext context_;
UserData user_data_;
+
+ // Callback functions.
+ InitFunc* init_func_;
+ UpdateFunc* update_func_;
+ DrawFunc* draw_func_;
+ ShutDownFunc* shut_down_func_;
+
DISALLOW_COPY_AND_ASSIGN(Example);
};
-// Many examples do need to update anything and hence do not provide an
-// update function. This no-op function can be used for such examples.
-inline void NoOpUpdateFunc(ESContext* context, float elapsed_sec) {}
-
} // namespace gles2_book
} // namespace demos
} // namespace gpu
diff --git a/gpu/demos/hello_triangle/main.cc b/gpu/demos/gles2_book/hello_triangle.cc
index 3e45ffc..806a0dd 100644
--- a/gpu/demos/hello_triangle/main.cc
+++ b/gpu/demos/gles2_book/hello_triangle.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -7,25 +7,29 @@
// example is to demonstrate the basic concepts of
// OpenGL ES 2.0 rendering.
+#include "gpu/demos/framework/demo_factory.h"
#include "gpu/demos/gles2_book/example.h"
#include "third_party/gles2_book/Chapter_2/Hello_Triangle/Hello_Triangle.h"
namespace gpu {
namespace demos {
+
namespace gles2_book {
-typedef Example<HTUserData,
- htInit,
- NoOpUpdateFunc,
- htDraw,
- htShutDown> HelloTriangle;
-} // namespace gles2_book
-} // namespace demos
-} // namespace gpu
+class HelloTriangle : public Example<HTUserData> {
+ public:
+ HelloTriangle() {
+ RegisterCallbacks(htInit, NULL, htDraw, htShutDown);
+ }
-int main(int argc, char *argv[]) {
- gpu::demos::gles2_book::HelloTriangle demo;
- CHECK(demo.Init());
+ const wchar_t* Title() const {
+ return L"Hello Triangle";
+ }
+};
+} // namespace gles2_book
- demo.MainLoop();
- return EXIT_SUCCESS;
+Demo* CreateDemo() {
+ return new gles2_book::HelloTriangle();
}
+
+} // namespace demos
+} // namespace gpu
diff --git a/gpu/demos/pepper_gpu_demo.html b/gpu/demos/pepper_gpu_demo.html
new file mode 100644
index 0000000..8be4e57
--- /dev/null
+++ b/gpu/demos/pepper_gpu_demo.html
@@ -0,0 +1,12 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Pepper GPU Demo</title>
+</head>
+
+<body style="background-color:Silver">
+
+<h1>Pepper GPU Demo</h1>
+<object id="plugin" type="pepper-application/x-gpu-demo" width="512" height="512" />
+
+</body>
+</html>