diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-20 00:56:25 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-20 00:56:25 +0000 |
commit | d717e03b637b8bd133db3fde5f3108b999a51a88 (patch) | |
tree | aca70991012a49441d24bbd201d894903ba05416 /chrome/plugin | |
parent | 5fe524efcaf51b401067d936b5ff331249dc99df (diff) | |
download | chromium_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.cc | 84 | ||||
-rw-r--r-- | chrome/plugin/command_buffer_stub.h | 11 | ||||
-rw-r--r-- | chrome/plugin/command_buffer_stub_win.cc | 78 |
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); +} |