Index: content/common/gpu/gpu_surface_stub.cc |
=================================================================== |
--- content/common/gpu/gpu_surface_stub.cc (revision 86313) |
+++ content/common/gpu/gpu_surface_stub.cc (working copy) |
@@ -4,435 +4,34 @@ |
#if defined(ENABLE_GPU) |
-#include "base/bind.h" |
-#include "base/debug/trace_event.h" |
-#include "base/process_util.h" |
-#include "base/shared_memory.h" |
-#include "build/build_config.h" |
-#include "content/common/child_thread.h" |
+#include "content/common/gpu/gpu_surface_stub.h" |
+ |
#include "content/common/gpu/gpu_channel.h" |
-#include "content/common/gpu/gpu_channel_manager.h" |
-#include "content/common/gpu/gpu_command_buffer_stub.h" |
-#include "content/common/gpu/gpu_messages.h" |
-#include "content/common/gpu/gpu_watchdog.h" |
-#include "gpu/command_buffer/common/constants.h" |
-#include "ui/gfx/gl/gl_context.h" |
-#include "ui/gfx/gl/gl_surface.h" |
+#include "ipc/ipc_message_macros.h" |
-#if defined(OS_WIN) |
-#include "base/win/wrapped_window_proc.h" |
-#endif |
- |
-using gpu::Buffer; |
- |
-#if defined(OS_WIN) |
-#define kCompositorWindowOwner L"CompositorWindowOwner" |
-#endif // defined(OS_WIN) |
- |
-GpuCommandBufferStub::GpuCommandBufferStub( |
- GpuChannel* channel, |
- gfx::PluginWindowHandle handle, |
- GpuCommandBufferStub* parent, |
- const gfx::Size& size, |
- const gpu::gles2::DisallowedExtensions& disallowed_extensions, |
- const std::string& allowed_extensions, |
- const std::vector<int32>& attribs, |
- uint32 parent_texture_id, |
- int32 route_id, |
- int32 renderer_id, |
- int32 render_view_id, |
- GpuWatchdog* watchdog) |
+GpuSurfaceStub::GpuSurfaceStub(GpuChannel* channel, |
+ int route_id, |
+ gfx::GLSurface* surface) |
: channel_(channel), |
- handle_(handle), |
- parent_( |
- parent ? parent->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>()), |
- initial_size_(size), |
- disallowed_extensions_(disallowed_extensions), |
- allowed_extensions_(allowed_extensions), |
- requested_attribs_(attribs), |
- parent_texture_id_(parent_texture_id), |
route_id_(route_id), |
- renderer_id_(renderer_id), |
- render_view_id_(render_view_id), |
- watchdog_(watchdog), |
- task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
+ surface_(surface) { |
} |
-GpuCommandBufferStub::~GpuCommandBufferStub() { |
- if (scheduler_.get()) { |
- scheduler_->Destroy(); |
- } |
- |
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
- gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer( |
- handle_, renderer_id_, render_view_id_)); |
+GpuSurfaceStub::~GpuSurfaceStub() { |
} |
-bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
- // If the scheduler is unscheduled, defer sync and async messages until it is |
- // rescheduled. Also, even if the scheduler is scheduled, do not allow newly |
- // received messages to be handled before previously received deferred ones; |
- // append them to the deferred queue as well. |
- if ((scheduler_.get() && !scheduler_->IsScheduled()) || |
- !deferred_messages_.empty()) { |
- deferred_messages_.push(new IPC::Message(message)); |
- return true; |
- } |
- |
- // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers |
- // here. This is so the reply can be delayed if the scheduler is unscheduled. |
+bool GpuSurfaceStub::OnMessageReceived(const IPC::Message& message) { |
bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, |
- OnInitialize); |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState); |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Flush, OnFlush); |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateTransferBuffer, |
- OnCreateTransferBuffer); |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_RegisterTransferBuffer, |
- OnRegisterTransferBuffer); |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_DestroyTransferBuffer, |
- OnDestroyTransferBuffer); |
- IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer, |
- OnGetTransferBuffer); |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ResizeOffscreenFrameBuffer, |
- OnResizeOffscreenFrameBuffer); |
-#if defined(OS_MACOSX) |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetWindowSize, OnSetWindowSize); |
-#endif // defined(OS_MACOSX) |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP() |
+ //IPC_BEGIN_MESSAGE_MAP(GpuSurfaceStub, message) |
+ // IPC_MESSAGE_UNHANDLED(handled = false) |
+ //IPC_END_MESSAGE_MAP() |
DCHECK(handled); |
return handled; |
} |
-bool GpuCommandBufferStub::Send(IPC::Message* message) { |
+bool GpuSurfaceStub::Send(IPC::Message* message) { |
return channel_->Send(message); |
} |
-void GpuCommandBufferStub::OnInitialize( |
- base::SharedMemoryHandle ring_buffer, |
- int32 size, |
- IPC::Message* reply_message) { |
- DCHECK(!command_buffer_.get()); |
- bool result = false; |
- |
- command_buffer_.reset(new gpu::CommandBufferService); |
- |
-#if defined(OS_WIN) |
- // Windows dups the shared memory handle it receives into the current process |
- // and closes it when this variable goes out of scope. |
- base::SharedMemory shared_memory(ring_buffer, |
- false, |
- channel_->renderer_process()); |
-#else |
- // POSIX receives a dup of the shared memory handle and closes the dup when |
- // this variable goes out of scope. |
- base::SharedMemory shared_memory(ring_buffer, false); |
-#endif |
- |
- // Initialize the CommandBufferService and GpuScheduler. |
- if (command_buffer_->Initialize(&shared_memory, size)) { |
- gpu::GpuScheduler* parent_processor = |
- parent_ ? parent_->scheduler_.get() : NULL; |
- scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), NULL)); |
- if (scheduler_->Initialize( |
- handle_, |
- initial_size_, |
- disallowed_extensions_, |
- allowed_extensions_.c_str(), |
- requested_attribs_, |
- parent_processor, |
- parent_texture_id_)) { |
- command_buffer_->SetPutOffsetChangeCallback( |
- NewCallback(scheduler_.get(), |
- &gpu::GpuScheduler::PutChanged)); |
- scheduler_->SetSwapBuffersCallback( |
- NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); |
- scheduler_->SetLatchCallback(base::Bind( |
- &GpuChannel::OnLatchCallback, base::Unretained(channel_), route_id_)); |
- scheduler_->SetScheduledCallback( |
- NewCallback(this, &GpuCommandBufferStub::OnScheduled)); |
- if (watchdog_) |
- scheduler_->SetCommandProcessedCallback( |
- NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); |
- |
-#if defined(OS_MACOSX) |
- if (handle_) { |
- // This context conceptually puts its output directly on the |
- // screen, rendered by the accelerated plugin layer in |
- // RenderWidgetHostViewMac. Set up a pathway to notify the |
- // browser process when its contents change. |
- scheduler_->SetSwapBuffersCallback( |
- NewCallback(this, |
- &GpuCommandBufferStub::SwapBuffersCallback)); |
- } |
-#endif // defined(OS_MACOSX) |
- |
- // Set up a pathway for resizing the output window or framebuffer at the |
- // right time relative to other GL commands. |
- scheduler_->SetResizeCallback( |
- NewCallback(this, &GpuCommandBufferStub::ResizeCallback)); |
- |
- result = true; |
- } else { |
- scheduler_.reset(); |
- command_buffer_.reset(); |
- } |
- } |
- |
- GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, result); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) { |
- gpu::CommandBuffer::State state = command_buffer_->GetState(); |
- if (state.error == gpu::error::kLostContext && |
- gfx::GLContext::LosesAllContextsOnContextLost()) |
- channel_->LoseAllContexts(); |
- |
- GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnFlush(int32 put_offset, |
- int32 last_known_get, |
- IPC::Message* reply_message) { |
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnFlush"); |
- gpu::CommandBuffer::State state = command_buffer_->FlushSync(put_offset, |
- last_known_get); |
- if (state.error == gpu::error::kLostContext && |
- gfx::GLContext::LosesAllContextsOnContextLost()) |
- channel_->LoseAllContexts(); |
- |
- GpuCommandBufferMsg_Flush::WriteReplyParams(reply_message, state); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset) { |
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnAsyncFlush"); |
- command_buffer_->Flush(put_offset); |
- // TODO(piman): Do this everytime the scheduler finishes processing a batch of |
- // commands. |
- MessageLoop::current()->PostTask(FROM_HERE, |
- task_factory_.NewRunnableMethod(&GpuCommandBufferStub::ReportState)); |
-} |
- |
-void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size, |
- int32 id_request, |
- IPC::Message* reply_message) { |
- int32 id = command_buffer_->CreateTransferBuffer(size, id_request); |
- GpuCommandBufferMsg_CreateTransferBuffer::WriteReplyParams(reply_message, id); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnRegisterTransferBuffer( |
- base::SharedMemoryHandle transfer_buffer, |
- size_t size, |
- int32 id_request, |
- IPC::Message* reply_message) { |
-#if defined(OS_WIN) |
- // Windows dups the shared memory handle it receives into the current process |
- // and closes it when this variable goes out of scope. |
- base::SharedMemory shared_memory(transfer_buffer, |
- false, |
- channel_->renderer_process()); |
-#else |
- // POSIX receives a dup of the shared memory handle and closes the dup when |
- // this variable goes out of scope. |
- base::SharedMemory shared_memory(transfer_buffer, false); |
-#endif |
- |
- int32 id = command_buffer_->RegisterTransferBuffer(&shared_memory, |
- size, |
- id_request); |
- |
- GpuCommandBufferMsg_RegisterTransferBuffer::WriteReplyParams(reply_message, |
- id); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnDestroyTransferBuffer( |
- int32 id, |
- IPC::Message* reply_message) { |
- command_buffer_->DestroyTransferBuffer(id); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnGetTransferBuffer( |
- int32 id, |
- IPC::Message* reply_message) { |
- base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle(); |
- uint32 size = 0; |
- |
- // Fail if the renderer process has not provided its process handle. |
- if (!channel_->renderer_process()) |
- return; |
- |
- Buffer buffer = command_buffer_->GetTransferBuffer(id); |
- if (buffer.shared_memory) { |
- // Assume service is responsible for duplicating the handle to the calling |
- // process. |
- buffer.shared_memory->ShareToProcess(channel_->renderer_process(), |
- &transfer_buffer); |
- size = buffer.size; |
- } |
- |
- GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message, |
- transfer_buffer, |
- size); |
- Send(reply_message); |
-} |
- |
-void GpuCommandBufferStub::OnResizeOffscreenFrameBuffer(const gfx::Size& size) { |
- scheduler_->ResizeOffscreenFrameBuffer(size); |
-} |
- |
-void GpuCommandBufferStub::OnSwapBuffers() { |
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSwapBuffers"); |
- ReportState(); |
- Send(new GpuCommandBufferMsg_SwapBuffers(route_id_)); |
-} |
- |
-void GpuCommandBufferStub::OnCommandProcessed() { |
- if (watchdog_) |
- watchdog_->CheckArmed(); |
-} |
- |
-void GpuCommandBufferStub::HandleDeferredMessages() { |
- // Empty the deferred queue so OnMessageRecieved does not defer on that |
- // account and to prevent an infinite loop if the scheduler is unscheduled |
- // as a result of handling already deferred messages. |
- std::queue<IPC::Message*> deferred_messages_copy; |
- std::swap(deferred_messages_copy, deferred_messages_); |
- |
- while (!deferred_messages_copy.empty()) { |
- scoped_ptr<IPC::Message> message(deferred_messages_copy.front()); |
- deferred_messages_copy.pop(); |
- |
- OnMessageReceived(*message); |
- } |
-} |
- |
-void GpuCommandBufferStub::OnScheduled() { |
- // Post a task to handle any deferred messages. The deferred message queue is |
- // not emptied here, which ensures that OnMessageReceived will continue to |
- // defer newly received messages until the ones in the queue have all been |
- // handled by HandleDeferredMessages. HandleDeferredMessages is invoked as a |
- // task to prevent reentrancy. |
- MessageLoop::current()->PostTask( |
- FROM_HERE, |
- task_factory_.NewRunnableMethod( |
- &GpuCommandBufferStub::HandleDeferredMessages)); |
-} |
- |
-#if defined(OS_MACOSX) |
-void GpuCommandBufferStub::OnSetWindowSize(const gfx::Size& size) { |
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
- // Try using the IOSurface version first. |
- uint64 new_backing_store = scheduler_->SetWindowSizeForIOSurface(size); |
- if (new_backing_store) { |
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params; |
- params.renderer_id = renderer_id_; |
- params.render_view_id = render_view_id_; |
- params.window = handle_; |
- params.width = size.width(); |
- params.height = size.height(); |
- params.identifier = new_backing_store; |
- gpu_channel_manager->Send( |
- new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params)); |
- } else { |
- // TODO(kbr): figure out what to do here. It wouldn't be difficult |
- // to support the compositor on 10.5, but the performance would be |
- // questionable. |
- NOTREACHED(); |
- } |
-} |
- |
-void GpuCommandBufferStub::SwapBuffersCallback() { |
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::SwapBuffersCallback"); |
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
- params.renderer_id = renderer_id_; |
- params.render_view_id = render_view_id_; |
- params.window = handle_; |
- params.surface_id = scheduler_->GetSurfaceId(); |
- params.route_id = route_id(); |
- params.swap_buffers_count = scheduler_->swap_buffers_count(); |
- gpu_channel_manager->Send( |
- new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); |
- |
- scheduler_->SetScheduled(false); |
-} |
- |
-void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( |
- uint64 swap_buffers_count) { |
- TRACE_EVENT0("gpu", |
- "GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped"); |
- |
- // Multiple swapbuffers may get consolidated together into a single |
- // AcceleratedSurfaceBuffersSwapped call. Since OnSwapBuffers expects to be |
- // called one time for every swap, make up the difference here. |
- uint64 delta = swap_buffers_count - |
- scheduler_->acknowledged_swap_buffers_count(); |
- |
- scheduler_->set_acknowledged_swap_buffers_count(swap_buffers_count); |
- |
- for(uint64 i = 0; i < delta; i++) |
- OnSwapBuffers(); |
- |
- // Wake up the GpuScheduler to start doing work again. |
- scheduler_->SetScheduled(true); |
-} |
-#endif // defined(OS_MACOSX) |
- |
-void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { |
- if (handle_ == gfx::kNullPluginWindow) { |
- scheduler_->decoder()->ResizeOffscreenFrameBuffer(size); |
- scheduler_->decoder()->UpdateOffscreenFrameBufferSize(); |
- } else { |
-#if defined(OS_LINUX) && !defined(TOUCH_UI) || defined(OS_WIN) |
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
- gpu_channel_manager->Send( |
- new GpuHostMsg_ResizeView(renderer_id_, |
- render_view_id_, |
- route_id_, |
- size)); |
- |
- scheduler_->SetScheduled(false); |
-#endif |
- } |
-} |
- |
-void GpuCommandBufferStub::ViewResized() { |
-#if defined(OS_LINUX) && !defined(TOUCH_UI) || defined(OS_WIN) |
- DCHECK(handle_ != gfx::kNullPluginWindow); |
- scheduler_->SetScheduled(true); |
- |
- // Recreate the view surface to match the window size. TODO(apatrick): this is |
- // likely not necessary on all platforms. |
- gfx::GLContext* context = scheduler_->decoder()->GetGLContext(); |
- gfx::GLSurface* surface = scheduler_->decoder()->GetGLSurface(); |
- context->ReleaseCurrent(surface); |
- if (surface) { |
- surface->Destroy(); |
- surface->Initialize(); |
- } |
-#endif |
-} |
- |
-void GpuCommandBufferStub::ReportState() { |
- gpu::CommandBuffer::State state = command_buffer_->GetState(); |
- if (state.error == gpu::error::kLostContext && |
- gfx::GLContext::LosesAllContextsOnContextLost()) { |
- channel_->LoseAllContexts(); |
- } else { |
- IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state); |
- msg->set_unblock(true); |
- Send(msg); |
- } |
-} |
- |
#endif // defined(ENABLE_GPU) |