summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 22:27:04 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 22:27:04 +0000
commit8ceb44c74fc375df749b60acc6fc01b5327c6d18 (patch)
tree0512ef018e445f45d142e8a79ed4a19b9390b6d3
parentc16b5958cc9a47992e6c24473258582773036af5 (diff)
downloadchromium_src-8ceb44c74fc375df749b60acc6fc01b5327c6d18.zip
chromium_src-8ceb44c74fc375df749b60acc6fc01b5327c6d18.tar.gz
chromium_src-8ceb44c74fc375df749b60acc6fc01b5327c6d18.tar.bz2
I just put the code that does not compile on ARM. Trybots will fail because I had to remove these from the CL to make gcl upload properly accept it.
A + base\scoped_open_process.h A + chrome\plugin\command_buffer_stub_win.cc TEST=try BUG=none Review URL: http://codereview.chromium.org/661022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39937 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/base.gypi1
-rw-r--r--base/scoped_open_process.h49
-rwxr-xr-xchrome/chrome.gyp3
-rw-r--r--chrome/common/command_buffer_messages_internal.h4
-rw-r--r--chrome/plugin/command_buffer_stub.cc84
-rw-r--r--chrome/plugin/command_buffer_stub.h11
-rw-r--r--chrome/plugin/command_buffer_stub_win.cc78
-rw-r--r--chrome/renderer/command_buffer_proxy.cc19
-rw-r--r--chrome/renderer/command_buffer_proxy.h9
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc44
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h11
-rw-r--r--gpu/demos/framework/demo.cc4
-rw-r--r--gpu/demos/framework/demo.h4
-rw-r--r--gpu/demos/framework/main_pepper.cc5
-rw-r--r--gpu/demos/framework/plugin.cc35
-rw-r--r--gpu/demos/framework/plugin.h4
-rw-r--r--gpu/demos/framework/window_win.cc4
-rw-r--r--gpu/demos/gles2_book/simple_vertex_shader.cc4
-rw-r--r--gpu/pgl/pgl.cc2
-rw-r--r--gpu/pgl/pgl.h16
-rw-r--r--third_party/npapi/bindings/npapi_extensions.h10
-rw-r--r--webkit/tools/pepper_test_plugin/plugin_object.cc4
22 files changed, 335 insertions, 70 deletions
diff --git a/base/base.gypi b/base/base.gypi
index aee1361..1d4b3e0 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -179,6 +179,7 @@
'scoped_nsautorelease_pool.mm',
'scoped_nsdisable_screen_updates.h',
'scoped_nsobject.h',
+ 'scoped_open_process.h',
'scoped_ptr.h',
'scoped_temp_dir.cc',
'scoped_temp_dir.h',
diff --git a/base/scoped_open_process.h b/base/scoped_open_process.h
new file mode 100644
index 0000000..9badc76
--- /dev/null
+++ b/base/scoped_open_process.h
@@ -0,0 +1,49 @@
+// 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 BASE_SCOPED_OPEN_PROCESS_H_
+#define BASE_SCOPED_OPEN_PROCESS_H_
+
+#include "base/process.h"
+#include "base/process_util.h"
+
+namespace base {
+
+// A class that opens a process from its process id and closes it when the
+// instance goes out of scope.
+class ScopedOpenProcess {
+ public:
+ ScopedOpenProcess() : handle_(kNullProcessHandle) {
+ }
+
+ // Automatically close the process.
+ ~ScopedOpenProcess() {
+ Close();
+ }
+
+ // Open a new process by pid. Closes any previously opened process (even if
+ // opening the new one fails).
+ bool Open(ProcessId pid) {
+ Close();
+ return OpenProcessHandle(pid, &handle_);
+ }
+
+ // Close the previously opened process.
+ void Close() {
+ if (handle_ == kNullProcessHandle)
+ return;
+
+ CloseProcessHandle(handle_);
+ handle_ = kNullProcessHandle;
+ }
+
+ ProcessHandle handle() const { return handle_; }
+
+ private:
+ ProcessHandle handle_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedOpenProcess);
+};
+} // namespace base
+
+#endif // BASE_SCOPED_OPEN_PROCESS_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 1441086..fa209a7 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -529,7 +529,8 @@
'sources': [
'plugin/command_buffer_stub.cc',
'plugin/command_buffer_stub.h',
- ],
+ 'plugin/command_buffer_stub_win.cc',
+ ],
},],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
'dependencies': [
diff --git a/chrome/common/command_buffer_messages_internal.h b/chrome/common/command_buffer_messages_internal.h
index 6d08dd3..5a62b00 100644
--- a/chrome/common/command_buffer_messages_internal.h
+++ b/chrome/common/command_buffer_messages_internal.h
@@ -55,6 +55,10 @@ IPC_BEGIN_MESSAGES(CommandBuffer)
base::SharedMemoryHandle /* transfer_buffer */,
uint32 /* size */)
+ // Send from command buffer stub to proxy when window is invalid and must be
+ // repainted.
+ IPC_MESSAGE_ROUTED0(CommandBufferMsg_NotifyRepaint)
+
#if defined(OS_MACOSX)
// On Mac OS X the GPU plugin must be offscreen, because there is no
// true cross-process window hierarchy. For this reason we must send
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index 103bde3..d8cc7d4 100644
--- a/chrome/plugin/command_buffer_stub.cc
+++ b/chrome/plugin/command_buffer_stub.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/callback.h"
-#include "base/process_util.h"
+#include "base/scoped_open_process.h"
#include "base/shared_memory.h"
#include "chrome/common/command_buffer_messages.h"
#include "chrome/common/plugin_messages.h"
@@ -23,6 +23,7 @@ CommandBufferStub::CommandBufferStub(PluginChannel* channel,
}
CommandBufferStub::~CommandBufferStub() {
+ Destroy();
channel_->RemoveRoute(route_id_);
}
@@ -67,38 +68,57 @@ void CommandBufferStub::OnInitialize(int32 size,
// Assume service is responsible for duplicating the handle from the calling
// process.
- base::ProcessHandle peer_handle;
- if (!base::OpenProcessHandle(channel_->peer_pid(), &peer_handle))
+ base::ScopedOpenProcess peer_process;
+ if (!peer_process.Open(channel_->peer_pid()))
return;
command_buffer_.reset(new gpu::CommandBufferService);
- // Initialize the CommandBufferService and GPUProcessor.
- if (command_buffer_->Initialize(size)) {
- Buffer buffer = command_buffer_->GetRingBuffer();
- if (buffer.shared_memory) {
- processor_ = new gpu::GPUProcessor(command_buffer_.get());
- if (processor_->Initialize(window_)) {
- command_buffer_->SetPutOffsetChangeCallback(
- NewCallback(processor_.get(),
- &gpu::GPUProcessor::ProcessCommands));
+ // Initialize the CommandBufferService.
+ if (!command_buffer_->Initialize(size)) {
+ Destroy();
+ return;
+ }
+
+ // Get the ring buffer.
+ Buffer buffer = command_buffer_->GetRingBuffer();
+ if (!buffer.shared_memory) {
+ Destroy();
+ return;
+ }
+
+ // Initialize the GPUProcessor.
+ processor_ = new gpu::GPUProcessor(command_buffer_.get());
+ if (!processor_->Initialize(window_)) {
+ Destroy();
+ return;
+ }
+
+ // Perform platform specific initialization.
+ if (!InitializePlatformSpecific()) {
+ Destroy();
+ return;
+ }
+
+ // Share the ring buffer to the client process.
+ if (!buffer.shared_memory->ShareToProcess(peer_process.handle(),
+ ring_buffer)) {
+ Destroy();
+ return;
+ }
+
+ // Setup callbacks for events.
+ command_buffer_->SetPutOffsetChangeCallback(
+ NewCallback(processor_.get(),
+ &gpu::GPUProcessor::ProcessCommands));
#if defined(OS_MACOSX)
- processor_->SetSwapBuffersCallback(
- NewCallback(this,
- &CommandBufferStub::SwapBuffersCallback));
+ processor_->SetSwapBuffersCallback(
+ NewCallback(this,
+ &CommandBufferStub::SwapBuffersCallback));
processor_->SetTransportDIBAllocAndFree(
NewCallback(this, &CommandBufferStub::AllocTransportDIB),
NewCallback(this, &CommandBufferStub::FreeTransportDIB));
#endif
- buffer.shared_memory->ShareToProcess(peer_handle, ring_buffer);
- } else {
- processor_ = NULL;
- command_buffer_.reset();
- }
- }
- }
-
- base::CloseProcessHandle(peer_handle);
}
void CommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) {
@@ -150,6 +170,22 @@ void CommandBufferStub::OnGetTransferBuffer(
base::CloseProcessHandle(peer_handle);
}
+void CommandBufferStub::Destroy() {
+ processor_ = NULL;
+ command_buffer_.reset();
+
+ DestroyPlatformSpecific();
+}
+
+#if !defined(OS_WIN)
+bool CommandBufferStub::InitializePlatformSpecific() {
+ return true;
+}
+
+void CommandBufferStub::DestroyPlatformSpecific() {
+}
+#endif // defined(OS_WIN)
+
#if defined(OS_MACOSX)
void CommandBufferStub::OnSetWindowSize(int32 width, int32 height) {
// Try using the IOSurface version first.
diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h
index 219aadb..0b0a556 100644
--- a/chrome/plugin/command_buffer_stub.h
+++ b/chrome/plugin/command_buffer_stub.h
@@ -38,6 +38,10 @@ class CommandBufferStub : public IPC::Channel::Listener,
int route_id() const { return route_id_; }
+ // Notify the client that it must repaint due to the window becoming invalid
+ // or a lost context.
+ void NotifyRepaint();
+
private:
// Message handlers:
void OnInitialize(int32 size, base::SharedMemoryHandle* ring_buffer);
@@ -50,6 +54,13 @@ class CommandBufferStub : public IPC::Channel::Listener,
void OnGetTransferBuffer(int32 id,
base::SharedMemoryHandle* transfer_buffer,
uint32* size);
+
+ // Destroy all owned objects.
+ void Destroy();
+
+ bool InitializePlatformSpecific();
+ void DestroyPlatformSpecific();
+
#if defined(OS_MACOSX)
void OnSetWindowSize(int32 width, int32 height);
void SwapBuffersCallback();
diff --git a/chrome/plugin/command_buffer_stub_win.cc b/chrome/plugin/command_buffer_stub_win.cc
new file mode 100644
index 0000000..656bbd1
--- /dev/null
+++ b/chrome/plugin/command_buffer_stub_win.cc
@@ -0,0 +1,78 @@
+// 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 <windows.h>
+
+#include "chrome/common/command_buffer_messages.h"
+#include "chrome/plugin/command_buffer_stub.h"
+
+namespace {
+const wchar_t* kPreviousWndProcProperty = L"CommandBufferStubPrevWndProc";
+const wchar_t* kCommandBufferStubProperty = L"CommandBufferStub";
+
+// Message handler for the GPU plugin's child window. Used to intercept
+// WM_PAINT events and forward repaint notifications to the client.
+LRESULT WINAPI WndProc(HWND handle,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ WNDPROC previous_wnd_proc = reinterpret_cast<WNDPROC>(
+ ::GetProp(handle, kPreviousWndProcProperty));
+ CommandBufferStub* stub = reinterpret_cast<CommandBufferStub*>(
+ ::GetProp(handle, kCommandBufferStubProperty));
+
+ switch (message) {
+ case WM_ERASEBKGND:
+ // Do not clear background. Avoids flickering.
+ return 1;
+ case WM_PAINT:
+ // Validate the whole window to prevent another WM_PAINT message.
+ ValidateRect(handle, NULL);
+
+ // Notify client that the window is invalid and needs to be repainted.
+ stub->NotifyRepaint();
+
+ return 1;
+ default:
+ return CallWindowProc(previous_wnd_proc,
+ handle,
+ message,
+ w_param,
+ l_param);
+ }
+}
+} // namespace anonymous
+
+void CommandBufferStub::NotifyRepaint() {
+ Send(new CommandBufferMsg_NotifyRepaint(route_id_));
+}
+
+bool CommandBufferStub::InitializePlatformSpecific() {
+ // Subclass window.
+ WNDPROC previous_wnd_proc = reinterpret_cast<WNDPROC>(
+ ::GetWindowLongPtr(window_, GWLP_WNDPROC));
+ ::SetProp(window_,
+ kPreviousWndProcProperty,
+ reinterpret_cast<HANDLE>(previous_wnd_proc));
+ ::SetWindowLongPtr(window_,
+ GWLP_WNDPROC,
+ reinterpret_cast<LONG_PTR>(WndProc));
+
+ // Record pointer to this in window.
+ ::SetProp(window_,
+ kCommandBufferStubProperty,
+ reinterpret_cast<HANDLE>(this));
+
+ return true;
+}
+
+void CommandBufferStub::DestroyPlatformSpecific() {
+ // Restore window.
+ WNDPROC previous_wnd_proc = reinterpret_cast<WNDPROC>(
+ ::GetProp(window_, kPreviousWndProcProperty));
+ ::SetWindowLongPtr(window_, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(
+ previous_wnd_proc));
+ ::RemoveProp(window_, kPreviousWndProcProperty);
+ ::RemoveProp(window_, kCommandBufferStubProperty);
+}
diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc
index 2b71fa8..b2eaa86 100644
--- a/chrome/renderer/command_buffer_proxy.cc
+++ b/chrome/renderer/command_buffer_proxy.cc
@@ -37,6 +37,8 @@ CommandBufferProxy::~CommandBufferProxy() {
void CommandBufferProxy::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(CommandBufferProxy, message)
IPC_MESSAGE_HANDLER(CommandBufferMsg_UpdateState, OnUpdateState);
+ IPC_MESSAGE_HANDLER(CommandBufferMsg_NotifyRepaint,
+ OnNotifyRepaint);
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
@@ -142,16 +144,7 @@ Buffer CommandBufferProxy::GetTransferBuffer(int32 id) {
}
// Cache the transfer buffer shared memory object client side.
-#if defined(OS_WIN)
- // TODO(piman): Does Windows needs this version of the constructor ? It
- // duplicates the handle, but I'm not sure why it is necessary - it was
- // already duped by the CommandBufferStub.
- base::SharedMemory* shared_memory =
- new base::SharedMemory(handle, false, base::GetCurrentProcessHandle());
-#else
- base::SharedMemory* shared_memory =
- new base::SharedMemory(handle, false);
-#endif
+ base::SharedMemory* shared_memory = new base::SharedMemory(handle, false);
// Map the shared memory on demand.
if (!shared_memory->memory()) {
@@ -175,6 +168,12 @@ void CommandBufferProxy::SetToken(int32 token) {
NOTREACHED();
}
+void CommandBufferProxy::OnNotifyRepaint() {
+ if (notify_repaint_task_.get())
+ MessageLoop::current()->PostNonNestableTask(
+ FROM_HERE, notify_repaint_task_.release());
+}
+
void CommandBufferProxy::SetParseError(
gpu::error::Error error) {
// Not implemented in proxy.
diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h
index a2fb9c4..990f6f3 100644
--- a/chrome/renderer/command_buffer_proxy.h
+++ b/chrome/renderer/command_buffer_proxy.h
@@ -51,6 +51,12 @@ class CommandBufferProxy : public gpu::CommandBuffer,
virtual void SetToken(int32 token);
virtual void SetParseError(gpu::error::Error error);
+ // Set a task that will be invoked the next time the window becomes invalid
+ // and needs to be repainted. Takes ownership of task.
+ void SetNotifyRepaintTask(Task* task) {
+ notify_repaint_task_.reset(task);
+ }
+
#if defined(OS_MACOSX)
virtual void SetWindowSize(int32 width, int32 height);
#endif
@@ -71,6 +77,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
private:
// Message handlers:
void OnUpdateState(gpu::CommandBuffer::State state);
+ void OnNotifyRepaint();
// As with the service, the client takes ownership of the ring buffer.
int32 size_;
@@ -90,6 +97,8 @@ class CommandBufferProxy : public gpu::CommandBuffer,
typedef std::queue<linked_ptr<Task> > AsyncFlushTaskQueue;
AsyncFlushTaskQueue pending_async_flush_tasks_;
+ scoped_ptr<Task> notify_repaint_task_;
+
DISALLOW_COPY_AND_ASSIGN(CommandBufferProxy);
};
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index ad8a952..10c66cd 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -168,17 +168,7 @@ void WebPluginDelegatePepper::UpdateGeometry(
if (!instance())
return;
- // TODO(sehr): do we need all this?
- window_.clipRect.top = clip_rect_.y();
- window_.clipRect.left = clip_rect_.x();
- window_.clipRect.bottom = clip_rect_.y() + clip_rect_.height();
- window_.clipRect.right = clip_rect_.x() + clip_rect_.width();
- window_.height = window_rect_.height();
- window_.width = window_rect_.width();
- window_.x = window_rect_.x();
- window_.y = window_rect_.y();
- window_.type = NPWindowTypeDrawable;
- instance()->NPP_SetWindow(&window_);
+ ForwardSetWindow();
}
NPObject* WebPluginDelegatePepper::GetPluginScriptableObject() {
@@ -373,8 +363,11 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
Buffer ring_buffer = command_buffer_->GetRingBuffer();
context->commandBuffer = ring_buffer.ptr;
context->commandBufferSize = state.size;
+ context->repaintCallback = NULL;
Synchronize3DContext(context, state);
+ ScheduleHandleRepaint(instance_->npp(), context);
+
// Ensure the service knows the window size before rendering anything.
nested_delegate_->UpdateGeometry(window_rect_, clip_rect_);
#if defined(OS_MACOSX)
@@ -646,6 +639,19 @@ WebPluginDelegatePepper::~WebPluginDelegatePepper() {
DestroyInstance();
}
+void WebPluginDelegatePepper::ForwardSetWindow() {
+ window_.clipRect.top = clip_rect_.y();
+ window_.clipRect.left = clip_rect_.x();
+ window_.clipRect.bottom = clip_rect_.y() + clip_rect_.height();
+ window_.clipRect.right = clip_rect_.x() + clip_rect_.width();
+ window_.height = window_rect_.height();
+ window_.width = window_rect_.width();
+ window_.x = window_rect_.x();
+ window_.y = window_rect_.y();
+ window_.type = NPWindowTypeDrawable;
+ instance()->NPP_SetWindow(&window_);
+}
+
void WebPluginDelegatePepper::PluginDestroyed() {
delete this;
}
@@ -799,6 +805,21 @@ bool WebPluginDelegatePepper::HandleInputEvent(const WebInputEvent& event,
}
#if defined(ENABLE_GPU)
+
+void WebPluginDelegatePepper::ScheduleHandleRepaint(
+ NPP npp, NPDeviceContext3D* context) {
+ command_buffer_->SetNotifyRepaintTask(method_factory3d_.NewRunnableMethod(
+ &WebPluginDelegatePepper::ForwardHandleRepaint,
+ npp,
+ context));
+}
+
+void WebPluginDelegatePepper::ForwardHandleRepaint(
+ NPP npp, NPDeviceContext3D* context) {
+ context->repaintCallback(npp, context);
+ ScheduleHandleRepaint(npp, context);
+}
+
void WebPluginDelegatePepper::Synchronize3DContext(
NPDeviceContext3D* context,
gpu::CommandBuffer::State state) {
@@ -819,6 +840,7 @@ void WebPluginDelegatePepper::Device3DUpdateState(
callback(npp, context, NPERR_NO_ERROR, user_data);
}
}
+
#endif // ENABLE_GPU
void WebPluginDelegatePepper::SendNestedDelegateGeometryToBrowser(
diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h
index 5082d64..a67b530 100644
--- a/chrome/renderer/webplugin_delegate_pepper.h
+++ b/chrome/renderer/webplugin_delegate_pepper.h
@@ -150,9 +150,9 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
NPAPI::PluginInstance *instance);
~WebPluginDelegatePepper();
- // Tells the plugin about the current state of the window.
- // See NPAPI NPP_SetWindow for more information.
- void WindowlessSetWindow(bool force_set_window);
+ // Set a task that calls the repaint callback the next time the window
+ // is invalid and needs to be repainted.
+ void ScheduleHandleRepaint(NPP npp, NPDeviceContext3D* context);
//-----------------------------------------
// used for windowed and windowless plugins
@@ -162,7 +162,12 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
// Closes down and destroys our plugin instance.
void DestroyInstance();
+ void ForwardSetWindow();
+
#if defined(ENABLE_GPU)
+
+ void ForwardHandleRepaint(NPP npp, NPDeviceContext3D* context);
+
// Synchronize a 3D context state with the service.
void Synchronize3DContext(NPDeviceContext3D* context,
gpu::CommandBuffer::State state);
diff --git a/gpu/demos/framework/demo.cc b/gpu/demos/framework/demo.cc
index 49fa519..1679b3f 100644
--- a/gpu/demos/framework/demo.cc
+++ b/gpu/demos/framework/demo.cc
@@ -31,5 +31,9 @@ void Demo::Draw() {
Render(elapsed_sec);
}
+bool Demo::IsAnimated() {
+ return false;
+}
+
} // namespace demos
} // namespace gpu
diff --git a/gpu/demos/framework/demo.h b/gpu/demos/framework/demo.h
index 801609b..28c8923 100644
--- a/gpu/demos/framework/demo.h
+++ b/gpu/demos/framework/demo.h
@@ -33,6 +33,10 @@ class Demo {
// a rendering context has already been created and made current.
virtual bool InitGL() = 0;
+ // Returns whether the demo is animated. Animated demos are drawn
+ // continuously. Unanimated demos are only drawn when the window is invalid.
+ virtual bool IsAnimated();
+
// 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.
diff --git a/gpu/demos/framework/main_pepper.cc b/gpu/demos/framework/main_pepper.cc
index 6937b62..cf8f510 100644
--- a/gpu/demos/framework/main_pepper.cc
+++ b/gpu/demos/framework/main_pepper.cc
@@ -90,6 +90,11 @@ void NPP_Print(NPP instance, NPPrint* platformPrint) {
}
int16 NPP_HandleEvent(NPP instance, void* event) {
+ Plugin* plugin = static_cast<Plugin*>(instance->pdata);
+
+ if (plugin)
+ return plugin->HandleEvent(*static_cast<NPPepperEvent*>(event));
+
return 0;
}
diff --git a/gpu/demos/framework/plugin.cc b/gpu/demos/framework/plugin.cc
index 0514f81..9ba01d4 100644
--- a/gpu/demos/framework/plugin.cc
+++ b/gpu/demos/framework/plugin.cc
@@ -74,8 +74,13 @@ NPClass plugin_class = {
PluginSetProperty,
};
-void PaintCallback(void* data) {
- reinterpret_cast<gpu::demos::Plugin*>(data)->Paint();
+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();
}
}
@@ -96,7 +101,7 @@ Plugin::~Plugin() {
// Destroy demo while GL context is current and before it is destroyed.
pglMakeCurrent(pgl_context_);
demo_.reset();
- pglMakeCurrent(NULL);
+ pglMakeCurrent(PGL_NO_CONTEXT);
DestroyContext();
}
@@ -121,10 +126,22 @@ void Plugin::SetWindow(const NPWindow& window) {
if (!pgl_context_) {
CreateContext();
+
+ // Schedule first call to Tick.
+ if (demo_->IsAnimated())
+ g_browser->pluginthreadasynccall(npp_, TickCallback, this);
}
+}
- // Schedule the first call to Draw.
- g_browser->pluginthreadasynccall(npp_, PaintCallback, 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() {
@@ -136,10 +153,7 @@ void Plugin::Paint() {
demo_->Draw();
pglSwapBuffers();
- pglMakeCurrent(NULL);
-
- // Schedule another call to Paint.
- g_browser->pluginthreadasynccall(npp_, PaintCallback, this);
+ pglMakeCurrent(PGL_NO_CONTEXT);
}
void Plugin::CreateContext() {
@@ -149,6 +163,7 @@ void Plugin::CreateContext() {
NPDeviceContext3DConfig config;
config.commandBufferSize = kCommandBufferSize;
device3d_->initializeContext(npp_, &config, &context3d_);
+ context3d_.repaintCallback = RepaintCallback;
// Create a PGL context.
pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_);
@@ -156,7 +171,7 @@ void Plugin::CreateContext() {
// Initialize demo.
pglMakeCurrent(pgl_context_);
CHECK(demo_->InitGL());
- pglMakeCurrent(NULL);
+ pglMakeCurrent(PGL_NO_CONTEXT);
}
void Plugin::DestroyContext() {
diff --git a/gpu/demos/framework/plugin.h b/gpu/demos/framework/plugin.h
index 0f4b55e..640d9c0 100644
--- a/gpu/demos/framework/plugin.h
+++ b/gpu/demos/framework/plugin.h
@@ -26,6 +26,10 @@ class Plugin : public NPObject {
NPP npp() const { return npp_; }
void New(NPMIMEType pluginType, int16 argc, char* argn[], char* argv[]);
void SetWindow(const NPWindow& window);
+ int32 HandleEvent(const NPPepperEvent& event);
+
+ // Called continuously for animated demos.
+ void Tick();
// Called by the browser to paint the window.
void Paint();
diff --git a/gpu/demos/framework/window_win.cc b/gpu/demos/framework/window_win.cc
index 37f41c2..dfd79fc 100644
--- a/gpu/demos/framework/window_win.cc
+++ b/gpu/demos/framework/window_win.cc
@@ -2,6 +2,7 @@
// 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/window.h"
namespace {
@@ -52,7 +53,8 @@ void Window::MainLoop() {
::DispatchMessage(&msg);
}
// Message queue is empty and application has not quit yet - keep painting.
- if (!done) ::InvalidateRect(window_handle_, NULL, FALSE);
+ if (!done && demo_->IsAnimated())
+ ::InvalidateRect(window_handle_,NULL, FALSE);
}
}
diff --git a/gpu/demos/gles2_book/simple_vertex_shader.cc b/gpu/demos/gles2_book/simple_vertex_shader.cc
index dff99ca..0f8b72e 100644
--- a/gpu/demos/gles2_book/simple_vertex_shader.cc
+++ b/gpu/demos/gles2_book/simple_vertex_shader.cc
@@ -22,6 +22,10 @@ class SimpleVertexShader : public Example<SVSUserData> {
const wchar_t* Title() const {
return L"Simple Vertex Shader";
}
+
+ virtual bool IsAnimated() {
+ return true;
+ }
};
} // namespace gles2_book
diff --git a/gpu/pgl/pgl.cc b/gpu/pgl/pgl.cc
index d357fe2..59c2635 100644
--- a/gpu/pgl/pgl.cc
+++ b/gpu/pgl/pgl.cc
@@ -223,7 +223,7 @@ PGLBoolean pglDestroyContext(PGLContext pgl_context) {
return PGL_FALSE;
if (pgl_context == pglGetCurrentContext())
- pglMakeCurrent(NULL);
+ pglMakeCurrent(PGL_NO_CONTEXT);
delete static_cast<PGLContextImpl*>(pgl_context);
return PGL_TRUE;
diff --git a/gpu/pgl/pgl.h b/gpu/pgl/pgl.h
index ac67ec1..118d6fe 100644
--- a/gpu/pgl/pgl.h
+++ b/gpu/pgl/pgl.h
@@ -8,8 +8,10 @@
#include "npapi.h"
#include "npapi_extensions.h"
-#define PGL_TRUE 1
-#define PGL_FALSE 0
+#define PGL_TRUE 1
+#define PGL_FALSE 0
+
+#define PGL_NO_CONTEXT ((PGLContext) 0)
#ifdef __cplusplus
extern "C" {
@@ -21,11 +23,11 @@ typedef int32 PGLInt;
// These are the same error codes as used by EGL.
enum {
- PGL_SUCCESS = 0x3000,
- PGL_NOT_INITIALIZED = 0x3001,
- PGL_BAD_CONTEXT = 0x3006,
- PGL_BAD_PARAMETER = 0x300C,
- PGL_CONTEXT_LOST = 0x300E
+ PGL_SUCCESS = 0x3000,
+ PGL_NOT_INITIALIZED = 0x3001,
+ PGL_BAD_CONTEXT = 0x3006,
+ PGL_BAD_PARAMETER = 0x300C,
+ PGL_CONTEXT_LOST = 0x300E
};
// Initialize the PGL library. This must have completed before any other PGL
diff --git a/third_party/npapi/bindings/npapi_extensions.h b/third_party/npapi/bindings/npapi_extensions.h
index fca509e..011628e 100644
--- a/third_party/npapi/bindings/npapi_extensions.h
+++ b/third_party/npapi/bindings/npapi_extensions.h
@@ -295,6 +295,11 @@ typedef enum _NPDeviceContext3DError {
NPDeviceContext3DError_GenericError
} NPDeviceContext3DError;
+typedef struct _NPDeviceContext3D NPDeviceContext3D;
+
+typedef void (*NPDeviceContext3DRepaintPtr)(NPP npp,
+ NPDeviceContext3D* context);
+
typedef struct _NPDeviceContext3D
{
void* reserved;
@@ -322,6 +327,11 @@ typedef struct _NPDeviceContext3D
// Last processed token. Synchronized on flush.
int32 token;
+ // Callback invoked on the main thread when the context must be repainted.
+ // TODO(apatrick): move this out of the context struct like the rest of the
+ // fields.
+ NPDeviceContext3DRepaintPtr repaintCallback;
+
// Error status. Synchronized on flush.
NPDeviceContext3DError error;
} NPDeviceContext3D;
diff --git a/webkit/tools/pepper_test_plugin/plugin_object.cc b/webkit/tools/pepper_test_plugin/plugin_object.cc
index 35c2a2c..6e755ef 100644
--- a/webkit/tools/pepper_test_plugin/plugin_object.cc
+++ b/webkit/tools/pepper_test_plugin/plugin_object.cc
@@ -422,7 +422,7 @@ void PluginObject::Initialize3D() {
// Initialize the demo GL state.
pglMakeCurrent(pgl_context_);
GLFromCPPInit();
- pglMakeCurrent(NULL);
+ pglMakeCurrent(PGL_NO_CONTEXT);
#endif // INDEPENDENT_PLUGIN
}
@@ -458,7 +458,7 @@ void PluginObject::Draw3D() {
glViewport(0, 0, width_, height_);
GLFromCPPDraw();
pglSwapBuffers();
- pglMakeCurrent(NULL);
+ pglMakeCurrent(PGL_NO_CONTEXT);
// Async flushes just to see them working.
context3d_.waitForProgress = true;