Remove renderer dependencies from the GPU client classes.
A future CL will move them out of content/renderer so that they can be used by
the browser process.
All requests to singleton-like things - e.g. establish a channel to the GPU
process - go through a GpuChannelHostFactory, implemented by RenderThreadImpl.
BUG=99516
TEST=manually tested Chrome with accelerated content.
Review URL: http://codereview.chromium.org/9270025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120701 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/renderer/gpu/command_buffer_proxy.cc b/content/renderer/gpu/command_buffer_proxy.cc
index 384e6e2..82c0676 100644
--- a/content/renderer/gpu/command_buffer_proxy.cc
+++ b/content/renderer/gpu/command_buffer_proxy.cc
@@ -101,8 +101,7 @@
}
bool CommandBufferProxy::Initialize() {
- ChildThread* child_thread = ChildThread::current();
- if (!child_thread)
+ if (!channel_->factory()->IsMainThread())
return false;
bool result;
@@ -179,30 +178,18 @@
if (last_state_.error != gpu::error::kNoError)
return -1;
- ChildThread* child_thread = ChildThread::current();
- if (!child_thread)
- return -1;
-
- base::SharedMemoryHandle handle;
- if (!child_thread->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory(
- size,
- &handle))) {
- return -1;
- }
-
- if (!base::SharedMemory::IsHandleValid(handle))
- return -1;
-
- // Handle is closed by the SharedMemory object below. This stops
- // base::FileDescriptor from closing it as well.
-#if defined(OS_POSIX)
- handle.auto_close = false;
-#endif
-
// Take ownership of shared memory. This will close the handle if Send below
// fails. Otherwise, callee takes ownership before this variable
// goes out of scope by duping the handle.
- base::SharedMemory shared_memory(handle, false);
+ scoped_ptr<base::SharedMemory> shm(
+ channel_->factory()->AllocateSharedMemory(size));
+ if (!shm.get())
+ return -1;
+
+ base::SharedMemoryHandle handle = shm->handle();
+#if defined(OS_POSIX)
+ DCHECK(!handle.auto_close);
+#endif
int32 id;
if (!Send(new GpuCommandBufferMsg_RegisterTransferBuffer(route_id_,
diff --git a/content/renderer/gpu/gpu_channel_host.cc b/content/renderer/gpu/gpu_channel_host.cc
index 96c652b..05d73d5 100644
--- a/content/renderer/gpu/gpu_channel_host.cc
+++ b/content/renderer/gpu/gpu_channel_host.cc
@@ -7,14 +7,18 @@
#include "base/bind.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
-#include "content/common/child_process.h"
+#include "content/common/child_thread.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/renderer/gpu/command_buffer_proxy.h"
-#include "content/renderer/render_process.h"
-#include "content/renderer/render_thread_impl.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_sync_message_filter.h"
+GpuChannelHostFactory* GpuChannelHostFactory::instance_ = NULL;
+
+GpuChannelHostFactory::~GpuChannelHostFactory() {
+ DCHECK(!instance_);
+}
+
using base::AutoLock;
using base::MessageLoopProxy;
@@ -36,7 +40,7 @@
int route_id,
base::WeakPtr<IPC::Channel::Listener> listener,
scoped_refptr<MessageLoopProxy> loop) {
- DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
+ DCHECK(parent_->factory_->IsIOThread());
DCHECK(listeners_.find(route_id) == listeners_.end());
GpuListenerInfo info;
info.listener = listener;
@@ -45,7 +49,7 @@
}
void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
- DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
+ DCHECK(parent_->factory_->IsIOThread());
ListenerMap::iterator it = listeners_.find(route_id);
if (it != listeners_.end())
listeners_.erase(it);
@@ -53,7 +57,7 @@
bool GpuChannelHost::MessageFilter::OnMessageReceived(
const IPC::Message& message) {
- DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
+ DCHECK(parent_->factory_->IsIOThread());
// Never handle sync message replies or we will deadlock here.
if (message.is_reply())
return false;
@@ -76,7 +80,7 @@
}
void GpuChannelHost::MessageFilter::OnChannelError() {
- DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
+ DCHECK(parent_->factory_->IsIOThread());
// Inform all the proxies that an error has occurred. This will be reported
// via OpenGL as a lost context.
for (ListenerMap::iterator it = listeners_.begin();
@@ -90,14 +94,14 @@
listeners_.clear();
- ChildThread* main_thread = RenderProcess::current()->main_thread();
- MessageLoop* main_loop = main_thread->message_loop();
+ MessageLoop* main_loop = parent_->factory_->GetMainLoop();
main_loop->PostTask(FROM_HERE,
base::Bind(&GpuChannelHost::OnChannelError, parent_));
}
-GpuChannelHost::GpuChannelHost()
- : state_(kUnconnected) {
+GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory)
+ : factory_(factory),
+ state_(kUnconnected) {
}
GpuChannelHost::~GpuChannelHost() {
@@ -106,16 +110,16 @@
void GpuChannelHost::Connect(
const IPC::ChannelHandle& channel_handle,
base::ProcessHandle renderer_process_for_gpu) {
- DCHECK(RenderThreadImpl::current());
+ DCHECK(factory_->IsMainThread());
// Open a channel to the GPU process. We pass NULL as the main listener here
// since we need to filter everything to route it to the right thread.
channel_.reset(new IPC::SyncChannel(
channel_handle, IPC::Channel::MODE_CLIENT, NULL,
- ChildProcess::current()->io_message_loop_proxy(), true,
- ChildProcess::current()->GetShutDownEvent()));
+ factory_->GetIOLoopProxy(), true,
+ factory_->GetShutDownEvent()));
sync_filter_ = new IPC::SyncMessageFilter(
- ChildProcess::current()->GetShutDownEvent());
+ factory_->GetShutDownEvent());
channel_->AddFilter(sync_filter_.get());
@@ -163,12 +167,12 @@
// Currently we need to choose between two different mechanisms for sending.
// On the main thread we use the regular channel Send() method, on another
// thread we use SyncMessageFilter. We also have to be careful interpreting
- // RenderThreadImpl::current() since it might return NULL during shutdown,
+ // IsMainThread() since it might return false during shutdown,
// impl we are actually calling from the main thread (discard message then).
//
// TODO: Can we just always use sync_filter_ since we setup the channel
// without a main listener?
- if (RenderThreadImpl::current()) {
+ if (factory_->IsMainThread()) {
if (channel_.get())
return channel_->Send(message);
} else if (MessageLoop::current()) {
@@ -188,7 +192,7 @@
const std::vector<int32>& attribs,
const GURL& active_url,
gfx::GpuPreference gpu_preference) {
- DCHECK(ChildThread::current());
+ DCHECK(factory_->IsMainThread());
#if defined(ENABLE_GPU)
AutoLock lock(context_lock_);
// An error occurred. Need to get the host again to reinitialize it.
@@ -202,15 +206,7 @@
init_params.attribs = attribs;
init_params.active_url = active_url;
init_params.gpu_preference = gpu_preference;
- int32 route_id;
- if (!ChildThread::current()->Send(
- new GpuHostMsg_CreateViewCommandBuffer(
- surface_id,
- init_params,
- &route_id))) {
- return NULL;
- }
-
+ int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params);
if (route_id == MSG_ROUTING_NONE)
return NULL;
@@ -291,7 +287,7 @@
int route_id, base::WeakPtr<IPC::Channel::Listener> listener) {
DCHECK(MessageLoopProxy::current());
- MessageLoopProxy* io_loop = RenderProcess::current()->io_message_loop_proxy();
+ MessageLoopProxy* io_loop = factory_->GetIOLoopProxy();
io_loop->PostTask(FROM_HERE,
base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
channel_filter_.get(), route_id, listener,
@@ -299,7 +295,7 @@
}
void GpuChannelHost::RemoveRoute(int route_id) {
- MessageLoopProxy* io_loop = RenderProcess::current()->io_message_loop_proxy();
+ MessageLoopProxy* io_loop = factory_->GetIOLoopProxy();
io_loop->PostTask(FROM_HERE,
base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
channel_filter_.get(), route_id));
diff --git a/content/renderer/gpu/gpu_channel_host.h b/content/renderer/gpu/gpu_channel_host.h
index 554fe19..f06f1c90 100644
--- a/content/renderer/gpu/gpu_channel_host.h
+++ b/content/renderer/gpu/gpu_channel_host.h
@@ -15,6 +15,7 @@
#include "base/memory/weak_ptr.h"
#include "base/process_util.h"
#include "base/synchronization/lock.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/common/message_router.h"
#include "content/public/common/gpu_info.h"
#include "content/renderer/gpu/gpu_video_decode_accelerator_host.h"
@@ -26,8 +27,10 @@
#include "ui/gfx/size.h"
class CommandBufferProxy;
+struct GPUCreateCommandBufferConfig;
class GURL;
class TransportTextureService;
+class MessageLoop;
namespace base {
class MessageLoopProxy;
@@ -45,6 +48,31 @@
scoped_refptr<base::MessageLoopProxy> loop;
};
+class GpuChannelHostFactory {
+ public:
+ virtual ~GpuChannelHostFactory();
+ static GpuChannelHostFactory* instance() { return instance_; }
+
+ virtual bool IsMainThread() = 0;
+ virtual bool IsIOThread() = 0;
+ virtual MessageLoop* GetMainLoop() = 0;
+ virtual base::MessageLoopProxy* GetIOLoopProxy() = 0;
+ virtual base::WaitableEvent* GetShutDownEvent() = 0;
+ virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(uint32 size) = 0;
+ virtual int32 CreateViewCommandBuffer(
+ int32 surface_id, const GPUCreateCommandBufferConfig& init_params) = 0;
+ virtual GpuChannelHost* EstablishGpuChannelSync(
+ content::CauseForGpuLaunch) = 0;
+
+ protected:
+ static void set_instance(GpuChannelHostFactory* instance) {
+ instance_ = instance;
+ }
+
+ private:
+ static GpuChannelHostFactory* instance_;
+};
+
// Encapsulates an IPC channel between the renderer and one plugin process.
// On the plugin side there's a corresponding GpuChannel.
class GpuChannelHost : public IPC::Message::Sender,
@@ -61,7 +89,7 @@
};
// Called on the render thread
- GpuChannelHost();
+ explicit GpuChannelHost(GpuChannelHostFactory* factory);
virtual ~GpuChannelHost();
// Connect to GPU process channel.
@@ -128,6 +156,8 @@
// the state on this side to lost.
void ForciblyCloseChannel();
+ GpuChannelHostFactory* factory() const { return factory_; }
+
private:
// A filter used internally to route incoming messages from the IO thread
// to the correct message loop.
@@ -152,6 +182,8 @@
ListenerMap listeners_;
};
+ GpuChannelHostFactory* factory_;
+
State state_;
content::GPUInfo gpu_info_;
diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
index da294f1..de9e1d641 100644
--- a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
+++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
@@ -10,7 +10,6 @@
#include "content/common/gpu/gpu_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/gpu/gpu_channel_host.h"
-#include "content/renderer/render_thread_impl.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
diff --git a/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc b/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
index cf65d36..99f839d 100644
--- a/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.cc
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#if defined(ENABLE_GPU)
-
#include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h"
#include "third_party/khronos/GLES2/gl2.h"
@@ -24,17 +22,12 @@
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/synchronization/lock.h"
-#include "content/common/child_process.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/gpu/command_buffer_proxy.h"
#include "content/renderer/gpu/gpu_channel_host.h"
-#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/common/constants.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
static base::LazyInstance<base::Lock>::Leaky
@@ -52,14 +45,17 @@
} // namespace anonymous
-WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl()
+WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
+ int surface_id,
+ const GURL& active_url,
+ const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client)
: initialize_failed_(false),
context_(NULL),
gl_(NULL),
- web_view_(NULL),
-#if defined(OS_MACOSX)
- plugin_handle_(NULL),
-#endif // defined(OS_MACOSX)
+ host_(NULL),
+ surface_id_(surface_id),
+ active_url_(active_url),
+ swap_client_(swap_client),
context_lost_callback_(0),
context_lost_reason_(GL_NO_ERROR),
swapbuffers_complete_callback_(0),
@@ -86,14 +82,12 @@
delete context_;
}
-bool WebGraphicsContext3DCommandBufferImpl::initialize(
- WebGraphicsContext3D::Attributes attributes,
- WebKit::WebView* web_view,
- bool render_directly_to_web_view) {
+bool WebGraphicsContext3DCommandBufferImpl::Initialize(
+ const WebGraphicsContext3D::Attributes& attributes) {
DCHECK(!context_);
TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
- RenderThreadImpl* render_thread = RenderThreadImpl::current();
- if (!render_thread)
+ GpuChannelHostFactory* factory = GpuChannelHostFactory::instance();
+ if (!factory)
return false;
// The noExtensions and canRecoverFromContextLoss flags are
@@ -106,7 +100,7 @@
// Note similar code in Pepper PlatformContext3DImpl::Init.
do {
- host_ = render_thread->EstablishGpuChannelSync(
+ host_ = factory->EstablishGpuChannelSync(
content::
CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
if (!host_)
@@ -137,18 +131,7 @@
return false;
}
- if (web_view && web_view->mainFrame())
- active_url_ = GURL(web_view->mainFrame()->document().url());
-
attributes_ = attributes;
- render_directly_to_web_view_ = render_directly_to_web_view;
- if (render_directly_to_web_view_) {
- RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_view);
- if (!render_view)
- return false;
- surface_id_ = render_view->surface_id();
- web_view_ = web_view;
- }
return true;
}
@@ -161,12 +144,11 @@
TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL");
// If the context is being initialized on something other than the main
- // thread, then drop the web_view_ pointer so we don't accidentally
- // dereference it.
- MessageLoop* main_message_loop =
- ChildProcess::current()->main_thread()->message_loop();
- if (MessageLoop::current() != main_message_loop)
- web_view_ = NULL;
+ // thread, then make sure the swap_client_ pointer is NULL so we don't
+ // accidentally dereference it.
+ GpuChannelHostFactory* factory = GpuChannelHostFactory::instance();
+ if (!factory || !factory->IsMainThread())
+ DCHECK(!swap_client_.get());
// Convert WebGL context creation attributes into RendererGLContext / EGL size
// requests.
@@ -199,7 +181,7 @@
NULL : (*g_all_shared_contexts.Pointer()->begin())->context_;
}
- if (render_directly_to_web_view_) {
+ if (surface_id_) {
context_ = RendererGLContext::CreateViewContext(
host_,
surface_id_,
@@ -297,10 +279,8 @@
void WebGraphicsContext3DCommandBufferImpl::prepareTexture() {
// Copies the contents of the off-screen render target into the texture
// used by the compositor.
- RenderViewImpl* renderview =
- web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL;
- if (renderview)
- renderview->OnViewContextSwapBuffersPosted();
+ if (swap_client_.get())
+ swap_client_->OnViewContextSwapBuffersPosted();
context_->SwapBuffers();
context_->Echo(base::Bind(
&WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
@@ -317,10 +297,8 @@
int x, int y, int width, int height) {
// Same flow control as WebGraphicsContext3DCommandBufferImpl::prepareTexture
// (see above).
- RenderViewImpl* renderview =
- web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL;
- if (renderview)
- renderview->OnViewContextSwapBuffersPosted();
+ if (swap_client_.get())
+ swap_client_->OnViewContextSwapBuffersPosted();
gl_->PostSubBufferCHROMIUM(x, y, width, height);
context_->Echo(base::Bind(
&WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete,
@@ -1131,14 +1109,11 @@
}
void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() {
+ typedef WebGraphicsContext3DSwapBuffersClient WGC3DSwapClient;
// This may be called after tear-down of the RenderView.
- RenderViewImpl* renderview =
- web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL;
- if (renderview) {
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&RenderViewImpl::OnViewContextSwapBuffersComplete,
- renderview));
+ if (swap_client_.get()) {
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ &WGC3DSwapClient::OnViewContextSwapBuffersComplete, swap_client_));
}
if (swapbuffers_complete_callback_)
@@ -1203,10 +1178,6 @@
}
if (attributes_.shareResources)
ClearSharedContexts();
- RenderViewImpl* renderview =
- web_view_ ? RenderViewImpl::FromWebView(web_view_) : NULL;
- if (renderview)
- renderview->OnViewContextSwapBuffersAborted();
+ if (swap_client_.get())
+ swap_client_->OnViewContextSwapBuffersAborted();
}
-
-#endif // defined(ENABLE_GPU)
diff --git a/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h b/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h
index 0137b38..778c2ce 100644
--- a/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h
+++ b/content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h
@@ -6,8 +6,6 @@
#define CONTENT_RENDERER_GPU_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_
#pragma once
-#if defined(ENABLE_GPU)
-
#include <string>
#include <vector>
@@ -47,17 +45,29 @@
using WebKit::WGC3Dintptr;
using WebKit::WGC3Dsizeiptr;
+// TODO(piman): move this logic to the compositor and remove it from the
+// context...
+class WebGraphicsContext3DSwapBuffersClient {
+ public:
+ virtual ~WebGraphicsContext3DSwapBuffersClient() { }
+ virtual void OnViewContextSwapBuffersPosted() = 0;
+ virtual void OnViewContextSwapBuffersComplete() = 0;
+ virtual void OnViewContextSwapBuffersAborted() = 0;
+};
+
class WebGraphicsContext3DCommandBufferImpl
: public WebKit::WebGraphicsContext3D {
public:
- WebGraphicsContext3DCommandBufferImpl();
+ WebGraphicsContext3DCommandBufferImpl(
+ int surface_id,
+ const GURL& active_url,
+ const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client);
virtual ~WebGraphicsContext3DCommandBufferImpl();
+ bool Initialize(const Attributes& attributes);
+
//----------------------------------------------------------------------
// WebGraphicsContext3D methods
- virtual bool initialize(WebGraphicsContext3D::Attributes attributes,
- WebKit::WebView*,
- bool renderDirectlyToWebView);
// Must be called after initialize() and before any of the following methods.
// Permanently binds to the first calling thread. Returns false if the
@@ -490,19 +500,10 @@
// State needed by MaybeInitializeGL.
GpuChannelHost* host_;
- GURL active_url_;
int32 surface_id_;
+ GURL active_url_;
+ base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client_;
- bool render_directly_to_web_view_;
-
- // If rendering directly to WebView, weak pointer to it.
- // This is only set when the context is bound to the main thread.
- WebKit::WebView* web_view_;
-
-#if defined(OS_MACOSX)
- // "Fake" plugin window handle in browser process for the compositor's output.
- gfx::PluginWindowHandle plugin_handle_;
-#endif
WebGraphicsContext3D::WebGraphicsContextLostCallback* context_lost_callback_;
WGC3Denum context_lost_reason_;
@@ -529,5 +530,4 @@
#endif
};
-#endif // defined(ENABLE_GPU)
#endif // CONTENT_RENDERER_GPU_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 578d6aaf..064f080 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -180,6 +180,8 @@
#endif
lazy_tls.Pointer()->Set(this);
+ GpuChannelHostFactory::set_instance(this);
+
#if defined(OS_WIN)
// If you are running plugins in this thread you need COM active but in
// the normal case you don't.
@@ -267,6 +269,7 @@
if (webkit_platform_support_.get())
WebKit::shutdown();
+ GpuChannelHostFactory::set_instance(NULL);
lazy_tls.Pointer()->Set(NULL);
// TODO(port)
@@ -677,6 +680,50 @@
#endif // OS_WIN
+bool RenderThreadImpl::IsMainThread() {
+ return !!current();
+}
+
+bool RenderThreadImpl::IsIOThread() {
+ return MessageLoop::current() == ChildProcess::current()->io_message_loop();
+}
+
+MessageLoop* RenderThreadImpl::GetMainLoop() {
+ return message_loop();
+}
+base::MessageLoopProxy* RenderThreadImpl::GetIOLoopProxy() {
+ return ChildProcess::current()->io_message_loop_proxy();
+}
+
+base::WaitableEvent* RenderThreadImpl::GetShutDownEvent() {
+ return ChildProcess::current()->GetShutDownEvent();
+}
+
+scoped_ptr<base::SharedMemory> RenderThreadImpl::AllocateSharedMemory(
+ uint32 size) {
+ if (!IsMainThread())
+ return scoped_ptr<base::SharedMemory>();
+ base::SharedMemoryHandle handle;
+ if (!ChildThread::Send(new ChildProcessHostMsg_SyncAllocateSharedMemory(
+ size,
+ &handle))) {
+ return scoped_ptr<base::SharedMemory>();
+ }
+ if (!base::SharedMemory::IsHandleValid(handle))
+ return scoped_ptr<base::SharedMemory>();
+ return scoped_ptr<base::SharedMemory>(new base::SharedMemory(handle, false));
+}
+
+int32 RenderThreadImpl::CreateViewCommandBuffer(
+ int32 surface_id, const GPUCreateCommandBufferConfig& init_params) {
+ int32 route_id = MSG_ROUTING_NONE;
+ ChildThread::Send(new GpuHostMsg_CreateViewCommandBuffer(
+ surface_id,
+ init_params,
+ &route_id));
+ return route_id;
+}
+
int32 RenderThreadImpl::RoutingIDForCurrentContext() {
int32 routing_id = MSG_ROUTING_CONTROL;
if (v8::Context::InContext()) {
@@ -798,7 +845,7 @@
}
if (!gpu_channel_.get())
- gpu_channel_ = new GpuChannelHost;
+ gpu_channel_ = new GpuChannelHost(this);
// Ask the browser for the channel name.
IPC::ChannelHandle channel_handle;
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index b0501bd..b69bea3 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -14,11 +14,13 @@
#include "base/time.h"
#include "base/timer.h"
#include "build/build_config.h"
+#include "content/common/child_process.h"
#include "content/common/child_thread.h"
#include "content/common/content_export.h"
#include "content/common/css_colors.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/renderer/render_thread.h"
+#include "content/renderer/gpu/gpu_channel_host.h"
#include "ipc/ipc_channel_proxy.h"
#include "ui/gfx/native_widget_types.h"
@@ -67,7 +69,8 @@
// routed to the RenderThread according to the routing IDs of the messages.
// The routing IDs correspond to RenderView instances.
class CONTENT_EXPORT RenderThreadImpl : public content::RenderThread,
- public ChildThread {
+ public ChildThread,
+ public GpuChannelHostFactory {
public:
static RenderThreadImpl* current();
@@ -118,6 +121,26 @@
virtual void ReleaseCachedFonts() OVERRIDE;
#endif
+ // GpuChannelHostFactory implementation:
+ virtual bool IsMainThread() OVERRIDE;
+ virtual bool IsIOThread() OVERRIDE;
+ virtual MessageLoop* GetMainLoop() OVERRIDE;
+ virtual base::MessageLoopProxy* GetIOLoopProxy() OVERRIDE;
+ virtual base::WaitableEvent* GetShutDownEvent() OVERRIDE;
+ virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(
+ uint32 size) OVERRIDE;
+ virtual int32 CreateViewCommandBuffer(
+ int32 surface_id,
+ const GPUCreateCommandBufferConfig& init_params) OVERRIDE;
+
+ // Synchronously establish a channel to the GPU plugin if not previously
+ // established or if it has been lost (for example if the GPU plugin crashed).
+ // If there is a pending asynchronous request, it will be completed by the
+ // time this routine returns.
+ virtual GpuChannelHost* EstablishGpuChannelSync(
+ content::CauseForGpuLaunch) OVERRIDE;
+
+
// These methods modify how the next message is sent. Normally, when sending
// a synchronous message that runs a nested message loop, we need to suspend
// callbacks into WebKit. This involves disabling timers and deferring
@@ -149,12 +172,6 @@
bool plugin_refresh_allowed() const { return plugin_refresh_allowed_; }
- // Synchronously establish a channel to the GPU plugin if not previously
- // established or if it has been lost (for example if the GPU plugin crashed).
- // If there is a pending asynchronous request, it will be completed by the
- // time this routine returns.
- GpuChannelHost* EstablishGpuChannelSync(content::CauseForGpuLaunch);
-
// Get the GPU channel. Returns NULL if the channel is not established or
// has been lost.
GpuChannelHost* GetGpuChannel();
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index a23022d..2489449 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1502,9 +1502,21 @@
return webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView(
attributes, webview(), direct);
} else {
- scoped_ptr<WebGraphicsContext3D> context(
- new WebGraphicsContext3DCommandBufferImpl());
- if (!context->initialize(attributes, webview(), direct))
+ int surface = direct ? surface_id() : 0;
+
+ GURL url;
+ if (webview()->mainFrame())
+ url = GURL(webview()->mainFrame()->document().url());
+
+ base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client;
+ if (direct)
+ swap_client = AsWeakPtr();
+
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
+ new WebGraphicsContext3DCommandBufferImpl(
+ surface, url, swap_client));
+
+ if (!context->Initialize(attributes))
return NULL;
return context.release();
}
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 6c60ae3..66e7dde 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -31,6 +31,7 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/stop_find_action.h"
#include "content/public/renderer/render_view.h"
+#include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h"
#include "content/renderer/pepper_plugin_delegate_impl.h"
#include "content/renderer/render_widget.h"
#include "ipc/ipc_platform_file.h"
@@ -164,6 +165,7 @@
public content::RenderView,
public webkit::npapi::WebPluginPageDelegate,
public webkit_media::WebMediaPlayerDelegate,
+ public WebGraphicsContext3DSwapBuffersClient,
public base::SupportsWeakPtr<RenderViewImpl> {
public:
// Creates a new RenderView. The parent_hwnd specifies a HWND to use as the
@@ -190,11 +192,13 @@
// May return NULL when the view is closing.
CONTENT_EXPORT WebKit::WebView* webview() const;
+ // WebGraphicsContext3DSwapBuffersClient implementation.
+
// Called by a GraphicsContext associated with this view when swapbuffers
// is posted, completes or is aborted.
- void OnViewContextSwapBuffersPosted();
- void OnViewContextSwapBuffersComplete();
- void OnViewContextSwapBuffersAborted();
+ virtual void OnViewContextSwapBuffersPosted() OVERRIDE;
+ virtual void OnViewContextSwapBuffersComplete() OVERRIDE;
+ virtual void OnViewContextSwapBuffersAborted() OVERRIDE;
int history_list_offset() const { return history_list_offset_; }
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc
index 5e62910..1c57670 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.cc
+++ b/content/renderer/renderer_webkitplatformsupport_impl.cc
@@ -573,9 +573,10 @@
return webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView(
attributes, NULL, false);
} else {
- scoped_ptr<WebGraphicsContext3D> context;
- context.reset(new WebGraphicsContext3DCommandBufferImpl());
- if (!context->initialize(attributes, NULL, false))
+ base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> null_client;
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
+ new WebGraphicsContext3DCommandBufferImpl(0, GURL(), null_client));
+ if (!context->Initialize(attributes))
return NULL;
return context.release();
}