Index: content/common/gpu/gpu_channel_manager.cc |
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc |
index 1da6aecf2f3c82608fc57654592fc22c5d557c85..4b92daf9649272d17159953cd4b00b490ae88f41 100644 |
--- a/content/common/gpu/gpu_channel_manager.cc |
+++ b/content/common/gpu/gpu_channel_manager.cc |
@@ -18,6 +18,15 @@ |
#include "ui/gl/gl_bindings.h" |
#include "ui/gl/gl_share_group.h" |
+GpuChannelManager::ImageOperation::ImageOperation( |
+ int32 sync_point, base::Closure callback) |
+ : sync_point(sync_point), |
+ callback(callback) { |
+} |
+ |
+GpuChannelManager::ImageOperation::~ImageOperation() { |
+} |
+ |
GpuChannelManager::GpuChannelManager(ChildThread* gpu_child_thread, |
GpuWatchdog* watchdog, |
base::MessageLoopProxy* io_message_loop, |
@@ -42,6 +51,7 @@ GpuChannelManager::~GpuChannelManager() { |
default_offscreen_surface_->Destroy(); |
default_offscreen_surface_ = NULL; |
} |
+ DCHECK(image_operations_.empty()); |
} |
gpu::gles2::ProgramCache* GpuChannelManager::program_cache() { |
@@ -95,6 +105,8 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) { |
IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel) |
IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer, |
OnCreateViewCommandBuffer) |
+ IPC_MESSAGE_HANDLER(GpuMsg_CreateImage, OnCreateImage) |
+ IPC_MESSAGE_HANDLER(GpuMsg_DeleteImage, OnDeleteImage) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP_EX() |
return handled; |
@@ -169,6 +181,81 @@ void GpuChannelManager::OnCreateViewCommandBuffer( |
Send(new GpuHostMsg_CommandBufferCreated(route_id)); |
} |
+void GpuChannelManager::CreateImage( |
+ gfx::PluginWindowHandle window, int32 client_id, int32 image_id) { |
+ gfx::Size size; |
+ |
+ GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id); |
+ if (iter != gpu_channels_.end()) { |
+ iter->second->CreateImage(window, image_id, &size); |
+ } |
+ |
+ Send(new GpuHostMsg_ImageCreated(size)); |
+} |
+ |
+void GpuChannelManager::OnCreateImage( |
+ gfx::PluginWindowHandle window, int32 client_id, int32 image_id) { |
+ DCHECK(image_id); |
+ |
+ if (image_operations_.empty()) { |
+ CreateImage(window, client_id, image_id); |
+ } else { |
+ image_operations_.push_back( |
+ new ImageOperation(0, base::Bind(&GpuChannelManager::CreateImage, |
+ base::Unretained(this), |
+ window, |
+ client_id, |
+ image_id))); |
+ } |
+} |
+ |
+void GpuChannelManager::DeleteImage(int32 client_id, int32 image_id) { |
+ GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id); |
+ if (iter != gpu_channels_.end()) { |
+ iter->second->DeleteImage(image_id); |
+ } |
+} |
+ |
+void GpuChannelManager::OnDeleteImage( |
+ int32 client_id, int32 image_id, int32 sync_point) { |
+ DCHECK(image_id); |
+ |
+ if (!sync_point && image_operations_.empty()) { |
+ DeleteImage(client_id, image_id); |
+ } else { |
+ image_operations_.push_back( |
+ new ImageOperation(sync_point, |
+ base::Bind(&GpuChannelManager::DeleteImage, |
+ base::Unretained(this), |
+ client_id, |
+ image_id))); |
+ if (sync_point) { |
+ sync_point_manager()->AddSyncPointCallback( |
+ sync_point, |
+ base::Bind(&GpuChannelManager::OnDeleteImageSyncPointRetired, |
+ base::Unretained(this), |
+ image_operations_.back())); |
+ } |
+ } |
+} |
+ |
+void GpuChannelManager::OnDeleteImageSyncPointRetired( |
+ ImageOperation* image_operation) { |
+ // Mark operation as no longer having a pending sync point. |
+ image_operation->sync_point = 0; |
+ |
+ // De-queue operations until we reach a pending sync point. |
+ while (!image_operations_.empty()) { |
+ // Check if operation has a pending sync point. |
+ if (image_operations_.front()->sync_point) |
+ return; |
+ |
+ image_operations_.front()->callback.Run(); |
+ delete image_operations_.front(); |
+ image_operations_.pop_front(); |
+ } |
+} |
+ |
void GpuChannelManager::LoseAllContexts() { |
MessageLoop::current()->PostTask( |
FROM_HERE, |