summaryrefslogtreecommitdiffstats
path: root/chrome/plugin
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-20 00:56:25 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-20 00:56:25 +0000
commitd717e03b637b8bd133db3fde5f3108b999a51a88 (patch)
treeaca70991012a49441d24bbd201d894903ba05416 /chrome/plugin
parent5fe524efcaf51b401067d936b5ff331249dc99df (diff)
downloadchromium_src-d717e03b637b8bd133db3fde5f3108b999a51a88.zip
chromium_src-d717e03b637b8bd133db3fde5f3108b999a51a88.tar.gz
chromium_src-d717e03b637b8bd133db3fde5f3108b999a51a88.tar.bz2
GPU plugin forwards repaint events to Pepper plugin.
WM_PAINT results in a call to Pepper repaint callback. Implemented WM_ERASEBKGND to prevent flickering on repaint. Implemented PGL_NO_CONTEXT (copied from EGL spec). This is already reviewed by alokp but unfortunately got entangled with this CL. TEST=none BUG=none Review URL: http://codereview.chromium.org/571018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39530 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin')
-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
3 files changed, 149 insertions, 24 deletions
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index e6f4b76..21e53e3 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,35 +68,54 @@ 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));
-#if defined(OS_MACOSX)
- processor_->SetSwapBuffersCallback(
- NewCallback(this,
- &CommandBufferStub::SwapBuffersCallback));
-#endif
- buffer.shared_memory->ShareToProcess(peer_handle, ring_buffer);
- } else {
- processor_ = NULL;
- command_buffer_.reset();
- }
- }
+ // Initialize the CommandBufferService.
+ if (!command_buffer_->Initialize(size)) {
+ Destroy();
+ return;
}
- base::CloseProcessHandle(peer_handle);
+ // 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));
+#endif
}
void CommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) {
@@ -147,6 +167,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) {
uint64 new_backing_store = processor_->SetWindowSize(width, height);
diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h
index f0d8ac0..f7bd691 100644
--- a/chrome/plugin/command_buffer_stub.h
+++ b/chrome/plugin/command_buffer_stub.h
@@ -37,6 +37,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);
@@ -49,6 +53,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);
+}