#include "base/bind.h"
#include "base/command_line.h"
-#include "content/child/child_thread.h"
#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_memory_buffer_factory.h"
#include "content/common/gpu/gpu_memory_manager.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/gpu/sync_point_manager.h"
+#include "content/common/message_router.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_program_cache.h"
+#include "gpu/command_buffer/service/shader_translator_cache.h"
+#include "ipc/message_filter.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_share_group.h"
namespace content {
-GpuChannelManager::ImageOperation::ImageOperation(
- int32 sync_point, base::Closure callback)
- : sync_point(sync_point),
- callback(callback) {
-}
+namespace {
-GpuChannelManager::ImageOperation::~ImageOperation() {
-}
+class GpuChannelManagerMessageFilter : public IPC::MessageFilter {
+ public:
+ GpuChannelManagerMessageFilter(
+ GpuMemoryBufferFactory* gpu_memory_buffer_factory)
+ : sender_(NULL), gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {}
+
+ virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE {
+ DCHECK(!sender_);
+ sender_ = sender;
+ }
+
+ virtual void OnFilterRemoved() OVERRIDE {
+ DCHECK(sender_);
+ sender_ = NULL;
+ }
+
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+ DCHECK(sender_);
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(GpuChannelManagerMessageFilter, message)
+ IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+ }
+
+ protected:
+ virtual ~GpuChannelManagerMessageFilter() {}
+
+ void OnCreateGpuMemoryBuffer(const gfx::GpuMemoryBufferHandle& handle,
+ const gfx::Size& size,
+ unsigned internalformat,
+ unsigned usage) {
+ TRACE_EVENT2("gpu",
+ "GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer",
+ "primary_id",
+ handle.global_id.primary_id,
+ "secondary_id",
+ handle.global_id.secondary_id);
+ sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated(
+ gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
+ handle, size, internalformat, usage)));
+ }
-GpuChannelManager::GpuChannelManager(ChildThread* gpu_child_thread,
+ IPC::Sender* sender_;
+ GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
+};
+
+} // namespace
+
+GpuChannelManager::GpuChannelManager(MessageRouter* router,
GpuWatchdog* watchdog,
base::MessageLoopProxy* io_message_loop,
- base::WaitableEvent* shutdown_event)
- : weak_factory_(this),
- io_message_loop_(io_message_loop),
+ base::WaitableEvent* shutdown_event,
+ IPC::SyncChannel* channel)
+ : io_message_loop_(io_message_loop),
shutdown_event_(shutdown_event),
- gpu_child_thread_(gpu_child_thread),
+ router_(router),
gpu_memory_manager_(
this,
GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
watchdog_(watchdog),
- sync_point_manager_(new SyncPointManager) {
- DCHECK(gpu_child_thread);
+ sync_point_manager_(new SyncPointManager),
+ gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create()),
+ channel_(channel),
+ filter_(new GpuChannelManagerMessageFilter(
+ gpu_memory_buffer_factory_.get())),
+ weak_factory_(this) {
+ DCHECK(router_);
DCHECK(io_message_loop);
DCHECK(shutdown_event);
+ channel_->AddFilter(filter_.get());
}
GpuChannelManager::~GpuChannelManager() {
default_offscreen_surface_->Destroy();
default_offscreen_surface_ = NULL;
}
- DCHECK(image_operations_.empty());
}
gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
return program_cache_.get();
}
+gpu::gles2::ShaderTranslatorCache*
+GpuChannelManager::shader_translator_cache() {
+ if (!shader_translator_cache_.get())
+ shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
+ return shader_translator_cache_.get();
+}
+
void GpuChannelManager::RemoveChannel(int client_id) {
Send(new GpuHostMsg_DestroyChannel(client_id));
gpu_channels_.erase(client_id);
}
void GpuChannelManager::AddRoute(int32 routing_id, IPC::Listener* listener) {
- gpu_child_thread_->AddRoute(routing_id, listener);
+ router_->AddRoute(routing_id, listener);
}
void GpuChannelManager::RemoveRoute(int32 routing_id) {
- gpu_child_thread_->RemoveRoute(routing_id);
+ router_->RemoveRoute(routing_id);
}
GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
if (iter == gpu_channels_.end())
return NULL;
else
- return iter->second.get();
+ return iter->second;
}
bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
- bool msg_is_ok = true;
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(GpuChannelManager, msg, msg_is_ok)
+ IPC_BEGIN_MESSAGE_MAP(GpuChannelManager, msg)
IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
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_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
+ IPC_END_MESSAGE_MAP()
return handled;
}
-bool GpuChannelManager::Send(IPC::Message* msg) {
- return gpu_child_thread_->Send(msg);
-}
+bool GpuChannelManager::Send(IPC::Message* msg) { return router_->Send(msg); }
-void GpuChannelManager::OnEstablishChannel(int client_id, bool share_context) {
+void GpuChannelManager::OnEstablishChannel(int client_id,
+ bool share_context,
+ bool allow_future_sync_points) {
IPC::ChannelHandle channel_handle;
gfx::GLShareGroup* share_group = NULL;
mailbox_manager = mailbox_manager_.get();
}
- scoped_refptr<GpuChannel> channel = new GpuChannel(this,
- watchdog_,
- share_group,
- mailbox_manager,
- client_id,
- false);
- if (channel->Init(io_message_loop_.get(), shutdown_event_)) {
- gpu_channels_[client_id] = channel;
- channel_handle.name = channel->GetChannelName();
+ scoped_ptr<GpuChannel> channel(new GpuChannel(this,
+ watchdog_,
+ share_group,
+ mailbox_manager,
+ client_id,
+ false,
+ allow_future_sync_points));
+ channel->Init(io_message_loop_.get(), shutdown_event_);
+ channel_handle.name = channel->GetChannelName();
#if defined(OS_POSIX)
- // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
- // that it gets closed after it has been sent.
- int renderer_fd = channel->TakeRendererFileDescriptor();
- DCHECK_NE(-1, renderer_fd);
- channel_handle.socket = base::FileDescriptor(renderer_fd, true);
+ // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
+ // that it gets closed after it has been sent.
+ int renderer_fd = channel->TakeRendererFileDescriptor();
+ DCHECK_NE(-1, renderer_fd);
+ channel_handle.socket = base::FileDescriptor(renderer_fd, true);
#endif
- }
+
+ gpu_channels_.set(client_id, channel.Pass());
Send(new GpuHostMsg_ChannelEstablished(channel_handle));
}
const gfx::GLSurfaceHandle& window,
int32 surface_id,
int32 client_id,
- const GPUCreateCommandBufferConfig& init_params) {
+ const GPUCreateCommandBufferConfig& init_params,
+ int32 route_id) {
DCHECK(surface_id);
- int32 route_id = MSG_ROUTING_NONE;
-
- GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
- if (iter != gpu_channels_.end()) {
- iter->second->CreateViewCommandBuffer(
- window, surface_id, init_params, &route_id);
- }
-
- Send(new GpuHostMsg_CommandBufferCreated(route_id));
-}
-
-void GpuChannelManager::CreateImage(
- gfx::PluginWindowHandle window, int32 client_id, int32 image_id) {
- gfx::Size size;
+ CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
if (iter != gpu_channels_.end()) {
- iter->second->CreateImage(window, image_id, &size);
+ result = iter->second->CreateViewCommandBuffer(
+ window, surface_id, init_params, route_id);
}
- Send(new GpuHostMsg_ImageCreated(size));
+ Send(new GpuHostMsg_CommandBufferCreated(result));
}
-
-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::DestroyGpuMemoryBuffer(
+ const gfx::GpuMemoryBufferHandle& handle) {
+ io_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
+ base::Unretained(this),
+ handle));
}
-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::DestroyGpuMemoryBufferOnIO(
+ const gfx::GpuMemoryBufferHandle& handle) {
+ gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(handle);
}
-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);
+void GpuChannelManager::OnDestroyGpuMemoryBuffer(
+ const gfx::GpuMemoryBufferHandle& handle,
+ int32 sync_point) {
+ if (!sync_point) {
+ DestroyGpuMemoryBuffer(handle);
} 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();
+ sync_point_manager()->AddSyncPointCallback(
+ sync_point,
+ base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
+ base::Unretained(this),
+ handle));
}
}
gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
if (!default_offscreen_surface_.get()) {
default_offscreen_surface_ =
- gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
+ gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
}
return default_offscreen_surface_.get();
}