diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 22:27:04 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-24 22:27:04 +0000 |
commit | 8ceb44c74fc375df749b60acc6fc01b5327c6d18 (patch) | |
tree | 0512ef018e445f45d142e8a79ed4a19b9390b6d3 /chrome | |
parent | c16b5958cc9a47992e6c24473258582773036af5 (diff) | |
download | chromium_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
Diffstat (limited to 'chrome')
-rwxr-xr-x | chrome/chrome.gyp | 3 | ||||
-rw-r--r-- | chrome/common/command_buffer_messages_internal.h | 4 | ||||
-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 | ||||
-rw-r--r-- | chrome/renderer/command_buffer_proxy.cc | 19 | ||||
-rw-r--r-- | chrome/renderer/command_buffer_proxy.h | 9 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.cc | 44 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.h | 11 |
9 files changed, 214 insertions, 49 deletions
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); |