diff options
Diffstat (limited to 'gpu/demos/framework')
-rw-r--r-- | gpu/demos/framework/demo.cc | 35 | ||||
-rw-r--r-- | gpu/demos/framework/demo.h | 67 | ||||
-rw-r--r-- | gpu/demos/framework/demo_factory.h | 17 | ||||
-rw-r--r-- | gpu/demos/framework/main_exe.cc | 24 | ||||
-rw-r--r-- | gpu/demos/framework/main_pepper.cc | 148 | ||||
-rw-r--r-- | gpu/demos/framework/platform.h | 25 | ||||
-rw-r--r-- | gpu/demos/framework/plugin.cc | 147 | ||||
-rw-r--r-- | gpu/demos/framework/plugin.def | 4 | ||||
-rw-r--r-- | gpu/demos/framework/plugin.h | 51 | ||||
-rw-r--r-- | gpu/demos/framework/plugin.rc | 35 | ||||
-rw-r--r-- | gpu/demos/framework/window.cc | 169 | ||||
-rw-r--r-- | gpu/demos/framework/window.h | 39 |
12 files changed, 761 insertions, 0 deletions
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/framework/platform.h b/gpu/demos/framework/platform.h new file mode 100644 index 0000000..cd6c003 --- /dev/null +++ b/gpu/demos/framework/platform.h @@ -0,0 +1,25 @@ +// 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. + +// Platform-specific types and definitions for native widget handles. + +#ifndef GPU_DEMOS_FRAMEWORK_PLATFORM_H_ +#define GPU_DEMOS_FRAMEWORK_PLATFORM_H_ + +#ifdef _WINDOWS +#include <windows.h> +#endif // _WINDOWS + +#include "build/build_config.h" + +namespace gpu { +namespace demos { + +#if defined(OS_WIN) +typedef HWND NativeWindowHandle; +#endif // defined(OS_WIN) + +} // 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/framework/window.cc b/gpu/demos/framework/window.cc new file mode 100644 index 0000000..6833feb --- /dev/null +++ b/gpu/demos/framework/window.cc @@ -0,0 +1,169 @@ +// 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/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; +using gpu::GPUProcessor; +using gpu::gles2::GLES2CmdHelper; +using gpu::gles2::GLES2Implementation; + +// TODO(alokp): Make this class cross-platform. Investigate using SDL. +namespace { +const int32 kCommandBufferSize = 1024 * 1024; +const int32 kTransferBufferSize = 512 * 1024; + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, + WPARAM w_param, LPARAM l_param) { + LRESULT result = 0; + switch (msg) { + case WM_CLOSE: + ::DestroyWindow(hwnd); + break; + case WM_DESTROY: + ::PostQuitMessage(0); + break; + case WM_ERASEBKGND: + break; + case WM_PAINT: { + gpu::demos::Window* window = reinterpret_cast<gpu::demos::Window*>( + GetWindowLongPtr(hwnd, GWL_USERDATA)); + if (window != NULL) window->OnPaint(); + ::ValidateRect(hwnd, NULL); + break; + } + default: + result = ::DefWindowProc(hwnd, msg, w_param, l_param); + break; + } + return result; +} + +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; + + 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); + + 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; + + ShowWindow(hwnd, SW_SHOWNORMAL); + // Set this to the GWL_USERDATA so that it is available to WindowProc. + SetWindowLongPtr(hwnd, GWL_USERDATA, user_data); + + return hwnd; +} + +bool InitRenderContext(HWND hwnd) { + CHECK(hwnd); + + scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); + if (!command_buffer->Initialize(kCommandBufferSize)) { + return false; + } + + scoped_refptr<GPUProcessor> gpu_processor( + new GPUProcessor(command_buffer.get())); + if (!gpu_processor->Initialize(hwnd)) { + return false; + } + + command_buffer->SetPutOffsetChangeCallback( + NewCallback(gpu_processor.get(), &GPUProcessor::ProcessCommands)); + + GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); + if (!helper->Initialize()) { + // TODO(alokp): cleanup. + return false; + } + + int32 transfer_buffer_id = + command_buffer->CreateTransferBuffer(kTransferBufferSize); + Buffer transfer_buffer = + command_buffer->GetTransferBuffer(transfer_buffer_id); + if (transfer_buffer.ptr == NULL) return false; + + gles2::SetGLContext(new GLES2Implementation(helper, + transfer_buffer.size, + transfer_buffer.ptr, + transfer_buffer_id)); + return command_buffer.release() != NULL; +} +} // namespace. + +namespace gpu { +namespace demos { + +Window::Window() + : window_handle_(NULL), + demo_(CreateDemo()) { +} + +Window::~Window() { +} + +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; + + 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 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_ |