summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-16 01:40:24 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-16 01:40:24 +0000
commit58b4b6dac3eeb9af7a3e46482552679ba3db6ed7 (patch)
tree2f11456c5cdc2dd81fadd2af7497378e99659682
parent4eec71c33f6469fdec8ba5494842c1c16ab22cd5 (diff)
downloadchromium_src-58b4b6dac3eeb9af7a3e46482552679ba3db6ed7.zip
chromium_src-58b4b6dac3eeb9af7a3e46482552679ba3db6ed7.tar.gz
chromium_src-58b4b6dac3eeb9af7a3e46482552679ba3db6ed7.tar.bz2
aura: Use GPU process for UI
This is behind a flag (--ui-use-gpu-process). Currently problems occur when the GPU process crash, this will be handled in a follow-up CL. BUG=99516 TEST=chrome --ui-use-gpu-process (with an aura build) Review URL: http://codereview.chromium.org/9348117 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122213 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_browser_main_extra_parts_aura.cc4
-rw-r--r--chrome/common/chrome_switches.cc5
-rw-r--r--chrome/common/chrome_switches.h4
-rw-r--r--content/browser/browser_main_loop.cc10
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.cc7
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.h3
-rw-r--r--content/browser/gpu/gpu_process_host.cc3
-rw-r--r--content/browser/gpu/gpu_process_host.h5
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.cc10
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.h4
-rw-r--r--content/browser/renderer_host/gpu_message_filter.cc15
-rw-r--r--content/browser/renderer_host/gpu_message_filter.h1
-rw-r--r--content/browser/renderer_host/image_transport_client.cc72
-rw-r--r--content/browser/renderer_host/image_transport_client.h7
-rw-r--r--content/browser/renderer_host/image_transport_factory.cc349
-rw-r--r--content/browser/renderer_host/image_transport_factory.h67
-rw-r--r--content/browser/renderer_host/render_widget_host_view.h2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc58
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h19
-rw-r--r--content/common/gpu/client/command_buffer_proxy.h2
-rw-r--r--content/common/gpu/client/content_gl_context.cc8
-rw-r--r--content/common/gpu/client/content_gl_context.h6
-rw-r--r--content/common/gpu/client/gpu_channel_host.cc3
-rw-r--r--content/common/gpu/client/gpu_channel_host.h4
-rw-r--r--content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h2
-rw-r--r--content/common/gpu/gpu_messages.h3
-rw-r--r--content/content_browser.gypi4
-rw-r--r--content/public/common/content_switches.cc8
-rw-r--r--content/public/common/content_switches.h5
-rw-r--r--content/renderer/render_thread_impl.cc9
-rw-r--r--ui/aura/root_window.cc22
-rw-r--r--ui/aura/root_window.h7
-rw-r--r--ui/gfx/compositor/compositor.cc174
-rw-r--r--ui/gfx/compositor/compositor.h96
-rw-r--r--ui/gfx/compositor/compositor_observer.h6
-rw-r--r--ui/gfx/compositor/compositor_setup.h1
-rw-r--r--ui/gfx/compositor/layer.h2
37 files changed, 774 insertions, 233 deletions
diff --git a/chrome/browser/chrome_browser_main_extra_parts_aura.cc b/chrome/browser/chrome_browser_main_extra_parts_aura.cc
index 18ead25..54eac8b 100644
--- a/chrome/browser/chrome_browser_main_extra_parts_aura.cc
+++ b/chrome/browser/chrome_browser_main_extra_parts_aura.cc
@@ -29,10 +29,6 @@ ChromeBrowserMainExtraPartsAura::ChromeBrowserMainExtraPartsAura()
}
void ChromeBrowserMainExtraPartsAura::PreProfileInit() {
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestCompositor)) {
- ui::SetupTestCompositor();
- }
-
#if defined(OS_CHROMEOS)
if (chromeos::system::runtime_environment::IsRunningOnChromeOS()) {
aura::RootWindow::set_use_fullscreen_host_window(true);
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 24262eb..c961834 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -1295,11 +1295,6 @@ const char kDisablePrintPreview[] = "disable-print-preview";
const char kEnablePrintPreview[] = "enable-print-preview";
#endif
-#if defined(USE_AURA)
-// Forces usage of the test compositor. Needed to run ui tests on bots.
-extern const char kTestCompositor[] = "test-compositor";
-#endif
-
// -----------------------------------------------------------------------------
// DO NOT ADD YOUR CRAP TO THE BOTTOM OF THIS FILE.
//
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 3830cbd..1c7f2fd 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -379,10 +379,6 @@ extern const char kDisablePrintPreview[];
extern const char kEnablePrintPreview[];
#endif
-#if defined(USE_AURA)
-extern const char kTestCompositor[];
-#endif
-
// DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
// alphabetical order, or in one of the ifdefs (also in order in each section).
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 4096821..41b3dd2 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -37,6 +37,10 @@
#include "net/socket/client_socket_factory.h"
#include "net/socket/tcp_client_socket.h"
+#if defined(USE_AURA)
+#include "content/browser/renderer_host/image_transport_factory.h"
+#endif
+
#if defined(OS_WIN)
#include <windows.h>
#include <commctrl.h>
@@ -409,6 +413,9 @@ void BrowserMainLoop::CreateThreads() {
}
BrowserGpuChannelHostFactory::Initialize();
+#if defined(USE_AURA)
+ ImageTransportFactory::Initialize();
+#endif
BrowserThreadsStarted();
@@ -455,6 +462,9 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
if (resource_dispatcher_host_.get())
resource_dispatcher_host_.get()->Shutdown();
+#if defined(USE_AURA)
+ ImageTransportFactory::Terminate();
+#endif
BrowserGpuChannelHostFactory::Terminate();
// Must be size_t so we can subtract from it.
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index a706fb3..7caccb7 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -39,6 +39,10 @@ void BrowserGpuChannelHostFactory::Terminate() {
delete instance();
}
+BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::Get() {
+ return static_cast<BrowserGpuChannelHostFactory*>(instance());
+}
+
BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
: gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
shutdown_event_(new base::WaitableEvent(true, false)),
@@ -142,6 +146,7 @@ void BrowserGpuChannelHostFactory::EstablishGpuChannelOnIO(
host->EstablishGpuChannel(
gpu_client_id_,
+ 0,
base::Bind(&BrowserGpuChannelHostFactory::GpuChannelEstablishedOnIO,
request));
}
@@ -202,7 +207,7 @@ GpuChannelHost* BrowserGpuChannelHostFactory::EstablishGpuChannelSync(
browser_process_for_gpu = base::GetCurrentProcessHandle();
#endif
- gpu_channel_ = new GpuChannelHost(this);
+ gpu_channel_ = new GpuChannelHost(this, gpu_client_id_);
gpu_channel_->set_gpu_info(request.gpu_info);
content::GetContentClient()->SetGpuInfo(request.gpu_info);
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index cecb3c4..f9a7bd6 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -19,6 +19,7 @@ class BrowserGpuChannelHostFactory : public GpuChannelHostFactory {
public:
static void Initialize();
static void Terminate();
+ static BrowserGpuChannelHostFactory* Get();
// GpuChannelHostFactory implementation.
virtual bool IsMainThread() OVERRIDE;
@@ -34,6 +35,8 @@ class BrowserGpuChannelHostFactory : public GpuChannelHostFactory {
virtual GpuChannelHost* EstablishGpuChannelSync(
CauseForGpuLaunch cause_for_gpu_launch) OVERRIDE;
+ int gpu_client_id() { return gpu_client_id_; }
+
private:
struct CreateRequest {
CreateRequest();
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index e6f5d93..e3eae00 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -417,6 +417,7 @@ void GpuProcessHost::OnChannelConnected(int32 peer_pid) {
void GpuProcessHost::EstablishGpuChannel(
int client_id,
+ int share_client_id,
const EstablishChannelCallback& callback) {
DCHECK(CalledOnValidThread());
TRACE_EVENT0("gpu", "GpuProcessHostUIShim::EstablishGpuChannel");
@@ -429,7 +430,7 @@ void GpuProcessHost::EstablishGpuChannel(
return;
}
- if (Send(new GpuMsg_EstablishChannel(client_id, 0))) {
+ if (Send(new GpuMsg_EstablishChannel(client_id, share_client_id))) {
channel_requests_.push(callback);
} else {
EstablishChannelError(
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index c0c8b73..854268b 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -64,8 +64,9 @@ class GpuProcessHost : public content::BrowserChildProcessHostDelegate,
// Tells the GPU process to create a new channel for communication with a
// client. Once the GPU process responds asynchronously with the IPC handle
// and GPUInfo, we call the callback.
- void EstablishGpuChannel(
- int client_id, const EstablishChannelCallback& callback);
+ void EstablishGpuChannel(int client_id,
+ int share_client_id,
+ const EstablishChannelCallback& callback);
typedef base::Callback<void(int32)> CreateCommandBufferCallback;
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index ef3f310..3ded9e3 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -197,12 +197,12 @@ bool GpuProcessHostUIShim::OnControlMessageReceived(
IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView)
#endif
-#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(OS_MACOSX) || defined(USE_AURA)
IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceNew,
OnAcceleratedSurfaceNew)
#endif
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(USE_AURA)
IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease,
OnAcceleratedSurfaceRelease)
#endif
@@ -278,7 +278,7 @@ void GpuProcessHostUIShim::OnResizeView(int32 surface_id,
#endif
-#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(OS_MACOSX) || defined(USE_AURA)
void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
const GpuHostMsg_AcceleratedSurfaceNew_Params& params) {
@@ -324,7 +324,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
params.height,
surface_handle);
}
-#else // defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#else // defined(USE_AURA)
view->AcceleratedSurfaceNew(
params.width, params.height, &surface_handle, &shm_handle);
#endif
@@ -387,7 +387,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend(int32 surface_id) {
view->AcceleratedSurfaceSuspend();
}
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(USE_AURA)
void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h
index 2ce9866..c5da9ef 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.h
+++ b/content/browser/gpu/gpu_process_host_ui_shim.h
@@ -96,12 +96,12 @@ class GpuProcessHostUIShim
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params);
void OnAcceleratedSurfaceSuspend(int32 surface_id);
-#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(OS_MACOSX) || defined(USE_AURA)
void OnAcceleratedSurfaceNew(
const GpuHostMsg_AcceleratedSurfaceNew_Params& params);
#endif
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(USE_AURA)
void OnAcceleratedSurfaceRelease(
const GpuHostMsg_AcceleratedSurfaceRelease_Params& params);
#endif
diff --git a/content/browser/renderer_host/gpu_message_filter.cc b/content/browser/renderer_host/gpu_message_filter.cc
index 7ec5083..b19f640 100644
--- a/content/browser/renderer_host/gpu_message_filter.cc
+++ b/content/browser/renderer_host/gpu_message_filter.cc
@@ -9,11 +9,14 @@
#include "content/browser/renderer_host/gpu_message_filter.h"
#include "base/bind.h"
+#include "base/command_line.h"
#include "base/process_util.h"
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/public/common/content_switches.h"
using content::BrowserThread;
@@ -21,8 +24,17 @@ GpuMessageFilter::GpuMessageFilter(int render_process_id,
RenderWidgetHelper* render_widget_helper)
: gpu_host_id_(0),
render_process_id_(render_process_id),
+ share_client_id_(0),
render_widget_helper_(render_widget_helper) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kUIUseGPUProcess)) {
+ // When using the GPU process for UI, we need to share renderer GL contexts
+ // with the compositor context.
+ share_client_id_ =
+ content::BrowserGpuChannelHostFactory::Get()->gpu_client_id();
+ }
}
GpuMessageFilter::~GpuMessageFilter() {
@@ -70,6 +82,7 @@ void GpuMessageFilter::OnEstablishGpuChannel(
host->EstablishGpuChannel(
render_process_id_,
+ share_client_id_,
base::Bind(&GpuMessageFilter::EstablishChannelCallback,
AsWeakPtr(),
reply));
@@ -142,7 +155,7 @@ void GpuMessageFilter::EstablishChannelCallback(
}
GpuHostMsg_EstablishGpuChannel::WriteReplyParams(
- reply, channel, renderer_process_for_gpu, gpu_info);
+ reply, render_process_id_, channel, renderer_process_for_gpu, gpu_info);
Send(reply);
}
diff --git a/content/browser/renderer_host/gpu_message_filter.h b/content/browser/renderer_host/gpu_message_filter.h
index afd5b4e..b286797 100644
--- a/content/browser/renderer_host/gpu_message_filter.h
+++ b/content/browser/renderer_host/gpu_message_filter.h
@@ -55,6 +55,7 @@ class GpuMessageFilter : public content::BrowserMessageFilter,
int gpu_host_id_;
int render_process_id_;
+ int share_client_id_;
scoped_refptr<RenderWidgetHelper> render_widget_helper_;
diff --git a/content/browser/renderer_host/image_transport_client.cc b/content/browser/renderer_host/image_transport_client.cc
index 96c2ff1..f2a893b 100644
--- a/content/browser/renderer_host/image_transport_client.cc
+++ b/content/browser/renderer_host/image_transport_client.cc
@@ -11,6 +11,7 @@
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
+#include "content/browser/renderer_host/image_transport_factory.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gfx/gl/gl_bindings.h"
@@ -42,30 +43,31 @@ GLuint CreateTexture() {
class ImageTransportClientEGL : public ImageTransportClient {
public:
- ImageTransportClientEGL(ui::SharedResources* resources, const gfx::Size& size)
+ ImageTransportClientEGL(ImageTransportFactory* factory, const gfx::Size& size)
: ImageTransportClient(true, size),
- resources_(resources),
+ factory_(factory),
image_(NULL) {
}
virtual ~ImageTransportClientEGL() {
- scoped_ptr<gfx::ScopedMakeCurrent> bind(resources_->GetScopedMakeCurrent());
+ scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent());
if (image_)
eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_);
- if (texture_id_)
- glDeleteTextures(1, &texture_id_);
+ unsigned int texture = texture_id();
+ if (texture)
+ glDeleteTextures(1, &texture);
glFlush();
}
virtual bool Initialize(uint64* surface_handle) {
- scoped_ptr<gfx::ScopedMakeCurrent> bind(resources_->GetScopedMakeCurrent());
+ scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent());
image_ = eglCreateImageKHR(
gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT,
EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_handle), NULL);
if (!image_)
return false;
- texture_id_ = CreateTexture();
- glBindTexture(GL_TEXTURE_2D, texture_id_);
+ set_texture_id(CreateTexture());
+ glBindTexture(GL_TEXTURE_2D, texture_id());
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_);
glFlush();
return true;
@@ -77,7 +79,7 @@ class ImageTransportClientEGL : public ImageTransportClient {
}
private:
- ui::SharedResources* resources_;
+ ImageTransportFactory* factory_;
EGLImageKHR image_;
};
@@ -85,16 +87,16 @@ class ImageTransportClientEGL : public ImageTransportClient {
class ImageTransportClientGLX : public ImageTransportClient {
public:
- ImageTransportClientGLX(ui::SharedResources* resources, const gfx::Size& size)
+ ImageTransportClientGLX(ImageTransportFactory* factory, const gfx::Size& size)
: ImageTransportClient(false, size),
- resources_(resources),
+ factory_(factory),
pixmap_(0),
glx_pixmap_(0),
acquired_(false) {
}
virtual ~ImageTransportClientGLX() {
- scoped_ptr<gfx::ScopedMakeCurrent> bind(resources_->GetScopedMakeCurrent());
+ scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent());
Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay();
if (glx_pixmap_) {
if (acquired_)
@@ -103,8 +105,9 @@ class ImageTransportClientGLX : public ImageTransportClient {
}
if (pixmap_)
XFreePixmap(dpy, pixmap_);
- if (texture_id_)
- glDeleteTextures(1, &texture_id_);
+ unsigned int texture = texture_id();
+ if (texture)
+ glDeleteTextures(1, &texture);
glFlush();
}
@@ -112,7 +115,7 @@ class ImageTransportClientGLX : public ImageTransportClient {
TRACE_EVENT0("renderer_host", "ImageTransportClientGLX::Initialize");
Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay();
- scoped_ptr<gfx::ScopedMakeCurrent> bind(resources_->GetScopedMakeCurrent());
+ scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent());
if (!InitializeOneOff(dpy))
return false;
@@ -130,7 +133,7 @@ class ImageTransportClientGLX : public ImageTransportClient {
glx_pixmap_ = glXCreatePixmap(dpy, fbconfig_.Get(), pixmap_, pixmapAttribs);
- texture_id_ = CreateTexture();
+ set_texture_id(CreateTexture());
glFlush();
return true;
}
@@ -138,8 +141,8 @@ class ImageTransportClientGLX : public ImageTransportClient {
virtual void Update() {
TRACE_EVENT0("renderer_host", "ImageTransportClientGLX::Update");
Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay();
- scoped_ptr<gfx::ScopedMakeCurrent> bind(resources_->GetScopedMakeCurrent());
- glBindTexture(GL_TEXTURE_2D, texture_id_);
+ scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent());
+ glBindTexture(GL_TEXTURE_2D, texture_id());
if (acquired_)
glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT);
glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
@@ -218,7 +221,7 @@ class ImageTransportClientGLX : public ImageTransportClient {
return initialized;
}
- ui::SharedResources* resources_;
+ ImageTransportFactory* factory_;
XID pixmap_;
XID glx_pixmap_;
bool acquired_;
@@ -230,17 +233,18 @@ base::LazyInstance<GLXFBConfig> ImageTransportClientGLX::fbconfig_ =
class ImageTransportClientOSMesa : public ImageTransportClient {
public:
- ImageTransportClientOSMesa(ui::SharedResources* resources,
+ ImageTransportClientOSMesa(ImageTransportFactory* factory,
const gfx::Size& size)
: ImageTransportClient(false, size),
- resources_(resources) {
+ factory_(factory) {
}
virtual ~ImageTransportClientOSMesa() {
- if (texture_id_) {
+ unsigned int texture = texture_id();
+ if (texture) {
scoped_ptr<gfx::ScopedMakeCurrent> bind(
- resources_->GetScopedMakeCurrent());
- glDeleteTextures(1, &texture_id_);
+ factory_->GetScopedMakeCurrent());
+ glDeleteTextures(1, &texture);
glFlush();
}
}
@@ -257,21 +261,21 @@ class ImageTransportClientOSMesa : public ImageTransportClient {
*surface_handle = next_handle_++;
shared_mem_.reset(
- TransportDIB::Create(size_.GetArea() * 4, // GL_RGBA=4 B/px
+ TransportDIB::Create(size().GetArea() * 4, // GL_RGBA=4 B/px
*surface_handle));
if (!shared_mem_.get())
return false;
- scoped_ptr<gfx::ScopedMakeCurrent> bind(resources_->GetScopedMakeCurrent());
- texture_id_ = CreateTexture();
+ scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent());
+ set_texture_id(CreateTexture());
glFlush();
return true;
}
virtual void Update() {
- glBindTexture(GL_TEXTURE_2D, texture_id_);
+ glBindTexture(GL_TEXTURE_2D, texture_id());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- size_.width(), size_.height(), 0,
+ size().width(), size().height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory());
glFlush();
}
@@ -279,7 +283,7 @@ class ImageTransportClientOSMesa : public ImageTransportClient {
virtual TransportDIB::Handle Handle() const { return shared_mem_->handle(); }
private:
- ui::SharedResources* resources_;
+ ImageTransportFactory* factory_;
scoped_ptr<TransportDIB> shared_mem_;
static uint32 next_handle_;
};
@@ -294,17 +298,17 @@ ImageTransportClient::ImageTransportClient(bool flipped, const gfx::Size& size)
}
ImageTransportClient* ImageTransportClient::Create(
- ui::SharedResources* resources,
+ ImageTransportFactory* factory,
const gfx::Size& size) {
switch (gfx::GetGLImplementation()) {
#if !defined(USE_WAYLAND)
case gfx::kGLImplementationOSMesaGL:
- return new ImageTransportClientOSMesa(resources, size);
+ return new ImageTransportClientOSMesa(factory, size);
case gfx::kGLImplementationDesktopGL:
- return new ImageTransportClientGLX(resources, size);
+ return new ImageTransportClientGLX(factory, size);
#endif
case gfx::kGLImplementationEGLGLES2:
- return new ImageTransportClientEGL(resources, size);
+ return new ImageTransportClientEGL(factory, size);
default:
NOTREACHED();
return NULL;
diff --git a/content/browser/renderer_host/image_transport_client.h b/content/browser/renderer_host/image_transport_client.h
index e11e9ae..a3b40c7 100644
--- a/content/browser/renderer_host/image_transport_client.h
+++ b/content/browser/renderer_host/image_transport_client.h
@@ -13,11 +13,12 @@
namespace gfx {
class Size;
}
+class ImageTransportFactory;
// This is a client for ImageTransportSurface, that handles the
// platform-specific task of binding the transport surface to a GL texture.
-// The GL texture is allocated in the SharedResources context, and the data is
-// only valid after the first Update().
+// The GL texture is allocated in the ImageTransportFactory context, and the
+// data is only valid after the first Update().
class ImageTransportClient : public ui::Texture {
public:
virtual ~ImageTransportClient() {}
@@ -33,7 +34,7 @@ class ImageTransportClient : public ui::Texture {
virtual TransportDIB::Handle Handle() const = 0;
// Creates a platform-specific client.
- static ImageTransportClient* Create(ui::SharedResources* resources,
+ static ImageTransportClient* Create(ImageTransportFactory* factory,
const gfx::Size& size);
protected:
diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc
new file mode 100644
index 0000000..59ee6d9
--- /dev/null
+++ b/content/browser/renderer_host/image_transport_factory.cc
@@ -0,0 +1,349 @@
+// Copyright (c) 2012 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 "content/browser/renderer_host/image_transport_factory.h"
+
+#include <map>
+
+#include "base/command_line.h"
+#include "base/memory/ref_counted.h"
+#include "content/browser/gpu/gpu_surface_tracker.h"
+#include "content/browser/renderer_host/image_transport_client.h"
+#include "content/common/gpu/client/command_buffer_proxy.h"
+#include "content/common/gpu/client/gpu_channel_host.h"
+#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/public/common/content_switches.h"
+#include "ui/gfx/compositor/compositor.h"
+#include "ui/gfx/compositor/compositor_setup.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_surface.h"
+#include "ui/gfx/gl/scoped_make_current.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/size.h"
+#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
+
+namespace {
+
+ImageTransportFactory* g_factory;
+
+class TestTransportFactory
+ : public ui::TestContextFactory,
+ public ImageTransportFactory {
+ public:
+ TestTransportFactory() {}
+
+ virtual ui::ContextFactory* AsContextFactory() OVERRIDE {
+ return this;
+ }
+
+ virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle(
+ ui::Compositor* compositor) OVERRIDE {
+ return gfx::GLSurfaceHandle();
+ }
+
+ virtual void DestroySharedSurfaceHandle(
+ gfx::GLSurfaceHandle surface) OVERRIDE {
+ }
+
+ virtual scoped_refptr<ImageTransportClient> CreateTransportClient(
+ const gfx::Size& size,
+ uint64* transport_handle) OVERRIDE {
+ return NULL;
+ }
+
+ virtual gfx::ScopedMakeCurrent* GetScopedMakeCurrent() OVERRIDE {
+ return NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestTransportFactory);
+};
+
+class DefaultTransportFactory
+ : public ui::DefaultContextFactory,
+ public ImageTransportFactory {
+ public:
+ DefaultTransportFactory() {
+ ui::DefaultContextFactory::Initialize();
+ }
+
+ virtual ui::ContextFactory* AsContextFactory() OVERRIDE {
+ return this;
+ }
+
+ virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle(
+ ui::Compositor* compositor) OVERRIDE {
+ return gfx::GLSurfaceHandle();
+ }
+
+ virtual void DestroySharedSurfaceHandle(
+ gfx::GLSurfaceHandle surface) OVERRIDE {
+ }
+
+ virtual scoped_refptr<ImageTransportClient> CreateTransportClient(
+ const gfx::Size& size,
+ uint64* transport_handle) OVERRIDE {
+ return NULL;
+ }
+
+ virtual gfx::ScopedMakeCurrent* GetScopedMakeCurrent() OVERRIDE {
+ return NULL;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultTransportFactory);
+};
+
+#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+class InProcessTransportFactory : public DefaultTransportFactory {
+ public:
+ InProcessTransportFactory() {
+ surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
+ CHECK(surface_.get()) << "Unable to create compositor GL surface.";
+
+ context_ = gfx::GLContext::CreateGLContext(
+ NULL, surface_.get(), gfx::PreferIntegratedGpu);
+ CHECK(context_.get()) <<"Unable to create compositor GL context.";
+
+ set_share_group(context_->share_group());
+ }
+
+ virtual ~InProcessTransportFactory() {}
+
+ virtual gfx::ScopedMakeCurrent* GetScopedMakeCurrent() OVERRIDE {
+ return new gfx::ScopedMakeCurrent(context_.get(), surface_.get());
+ }
+
+ virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle(
+ ui::Compositor* compositor) OVERRIDE {
+ return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, true);
+ }
+
+ virtual scoped_refptr<ImageTransportClient> CreateTransportClient(
+ const gfx::Size& size,
+ uint64* transport_handle) OVERRIDE {
+ scoped_refptr<ImageTransportClient> surface(
+ ImageTransportClient::Create(this, size));
+ if (!surface || !surface->Initialize(transport_handle)) {
+ LOG(ERROR) << "Failed to create ImageTransportClient";
+ return NULL;
+ }
+ return surface;
+ }
+
+ private:
+ scoped_refptr<gfx::GLContext> context_;
+ scoped_refptr<gfx::GLSurface> surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(InProcessTransportFactory);
+};
+#endif
+
+class ImageTransportClientTexture : public ImageTransportClient {
+ public:
+ explicit ImageTransportClientTexture(const gfx::Size& size)
+ : ImageTransportClient(true, size) {
+ }
+
+ virtual bool Initialize(uint64* surface_id) OVERRIDE {
+ set_texture_id(*surface_id);
+ return true;
+ }
+
+ virtual ~ImageTransportClientTexture() {}
+ virtual void Update() OVERRIDE {}
+ virtual TransportDIB::Handle Handle() const OVERRIDE {
+ return TransportDIB::DefaultHandleValue();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ImageTransportClientTexture);
+};
+
+class CompositorSwapClient : public base::SupportsWeakPtr<CompositorSwapClient>,
+ public WebGraphicsContext3DSwapBuffersClient {
+ public:
+ explicit CompositorSwapClient(ui::Compositor* compositor)
+ : compositor_(compositor) {
+ }
+
+ ~CompositorSwapClient() {
+ }
+
+ virtual void OnViewContextSwapBuffersPosted() OVERRIDE {
+ compositor_->OnSwapBuffersPosted();
+ }
+
+ virtual void OnViewContextSwapBuffersComplete() OVERRIDE {
+ compositor_->OnSwapBuffersComplete();
+ }
+
+ virtual void OnViewContextSwapBuffersAborted() OVERRIDE {
+ compositor_->OnSwapBuffersAborted();
+ }
+
+ private:
+ ui::Compositor* compositor_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient);
+};
+
+class GpuProcessTransportFactory : public ui::ContextFactory,
+ public ImageTransportFactory {
+ public:
+ GpuProcessTransportFactory() {}
+ virtual ~GpuProcessTransportFactory() {
+ DCHECK(per_compositor_data_.empty());
+ }
+
+ virtual WebKit::WebGraphicsContext3D* CreateContext(
+ ui::Compositor* compositor) OVERRIDE {
+ PerCompositorData* data = per_compositor_data_[compositor];
+ if (!data)
+ data = CreatePerCompositorData(compositor);
+
+ WebKit::WebGraphicsContext3D::Attributes attrs;
+ attrs.shareResources = true;
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
+ new WebGraphicsContext3DCommandBufferImpl(
+ data->surface_id, GURL(), data->swap_client->AsWeakPtr()));
+ if (!context->Initialize(attrs))
+ return NULL;
+ return context.release();
+ }
+
+ virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE {
+ PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ if (it == per_compositor_data_.end())
+ return;
+ PerCompositorData* data = it->second;
+ DCHECK(data);
+ GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id);
+ delete data;
+ per_compositor_data_.erase(it);
+ }
+
+ virtual ui::ContextFactory* AsContextFactory() OVERRIDE {
+ return this;
+ }
+
+ virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle(
+ ui::Compositor* compositor) OVERRIDE {
+ PerCompositorData* data = per_compositor_data_[compositor];
+ if (!data)
+ data = CreatePerCompositorData(compositor);
+ gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle(
+ gfx::kNullPluginWindow, true);
+ ContentGLContext* context = data->shared_context->content_gl_context();
+ handle.parent_client_id = context->GetChannelID();
+ handle.parent_context_id = context->GetContextID();
+ handle.parent_texture_id[0] = data->shared_context->createTexture();
+ handle.parent_texture_id[1] = data->shared_context->createTexture();
+ data->shared_context->flush();
+
+ // This handle will not be correct after a GPU process crash / context lost.
+ // TODO(piman): Fix this.
+ return handle;
+ }
+
+ virtual void DestroySharedSurfaceHandle(
+ gfx::GLSurfaceHandle surface) OVERRIDE {
+ for (PerCompositorDataMap::iterator it = per_compositor_data_.begin();
+ it != per_compositor_data_.end(); ++it) {
+ PerCompositorData* data = it->second;
+ DCHECK(data);
+ ContentGLContext* context = data->shared_context->content_gl_context();
+ uint32 client_id = context->GetChannelID();
+ uint32 context_id = context->GetContextID();
+ if (surface.parent_client_id == client_id &&
+ surface.parent_context_id == context_id) {
+ data->shared_context->deleteTexture(surface.parent_texture_id[0]);
+ data->shared_context->deleteTexture(surface.parent_texture_id[1]);
+ data->shared_context->flush();
+ break;
+ }
+ }
+ }
+
+ virtual scoped_refptr<ImageTransportClient> CreateTransportClient(
+ const gfx::Size& size,
+ uint64* transport_handle) {
+ scoped_refptr<ImageTransportClientTexture> image(
+ new ImageTransportClientTexture(size));
+ image->Initialize(transport_handle);
+ return image;
+ }
+
+ virtual gfx::ScopedMakeCurrent* GetScopedMakeCurrent() { return NULL; }
+
+ private:
+ struct PerCompositorData {
+ int surface_id;
+ scoped_ptr<CompositorSwapClient> swap_client;
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context;
+ };
+
+ PerCompositorData* CreatePerCompositorData(ui::Compositor* compositor) {
+ DCHECK(!per_compositor_data_[compositor]);
+
+ gfx::AcceleratedWidget widget = compositor->widget();
+ GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
+
+ PerCompositorData* data = new PerCompositorData;
+ data->surface_id = tracker->AddSurfaceForNativeWidget(widget);
+ tracker->SetSurfaceHandle(
+ data->surface_id,
+ gfx::GLSurfaceHandle(widget, false));
+ data->swap_client.reset(new CompositorSwapClient(compositor));
+
+ WebKit::WebGraphicsContext3D::Attributes attrs;
+ attrs.shareResources = true;
+ data->shared_context.reset(new WebGraphicsContext3DCommandBufferImpl(
+ data->surface_id, GURL(), data->swap_client->AsWeakPtr()));
+ data->shared_context->Initialize(attrs);
+ data->shared_context->makeContextCurrent();
+
+ per_compositor_data_[compositor] = data;
+ return data;
+ }
+
+ typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap;
+ PerCompositorDataMap per_compositor_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory);
+};
+
+} // anonymous namespace
+
+// static
+void ImageTransportFactory::Initialize() {
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kTestCompositor)) {
+ ui::SetupTestCompositor();
+ }
+ if (ui::IsTestCompositorEnabled()) {
+ g_factory = new TestTransportFactory();
+ } else if (command_line->HasSwitch(switches::kUIUseGPUProcess)) {
+ g_factory = new GpuProcessTransportFactory();
+ } else {
+#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+ g_factory = new InProcessTransportFactory();
+#else
+ g_factory = new DefaultTransportFactory();
+#endif
+ }
+ ui::ContextFactory::SetInstance(g_factory->AsContextFactory());
+}
+
+// static
+void ImageTransportFactory::Terminate() {
+ ui::ContextFactory::SetInstance(NULL);
+ delete g_factory;
+ g_factory = NULL;
+}
+
+// static
+ImageTransportFactory* ImageTransportFactory::GetInstance() {
+ return g_factory;
+}
diff --git a/content/browser/renderer_host/image_transport_factory.h b/content/browser/renderer_host/image_transport_factory.h
new file mode 100644
index 0000000..b650a68
--- /dev/null
+++ b/content/browser/renderer_host/image_transport_factory.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_IMAGE_TRANSPORT_FACTORY_H_
+#define CONTENT_BROWSER_RENDERER_HOST_IMAGE_TRANSPORT_FACTORY_H_
+#pragma once
+
+#include "base/memory/ref_counted.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace gfx {
+class Size;
+class ScopedMakeCurrent;
+}
+
+namespace ui {
+class Compositor;
+class ContextFactory;
+class Texture;
+}
+
+class ImageTransportClient;
+
+// This class provides the interface for creating the support for the
+// cross-process image transport, both for creating the shared surface handle
+// (destination surface for the GPU process) and the transport client (logic for
+// using that surface as a texture). The factory is a process-wide singleton.
+// As this is intimately linked to the type of 3D context we use (in-process or
+// command-buffer), implementations of this also implement ui::ContextFactory.
+class ImageTransportFactory {
+ public:
+ virtual ~ImageTransportFactory() { }
+
+ // Initialize the global transport factory.
+ static void Initialize();
+
+ // Terminates the global transport factory.
+ static void Terminate();
+
+ // Gets the factory instance.
+ static ImageTransportFactory* GetInstance();
+
+ // Gets the image transport factory as a context factory for the compositor.
+ virtual ui::ContextFactory* AsContextFactory() = 0;
+
+ // Creates a shared surface handle, associated with the compositor.
+ virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle(
+ ui::Compositor* compositor) = 0;
+
+ // Destroys a shared surface handle.
+ virtual void DestroySharedSurfaceHandle(gfx::GLSurfaceHandle surface) = 0;
+
+ // Creates a transport client of a given size, and using the opaque handle
+ // sent by the GPU process.
+ virtual scoped_refptr<ImageTransportClient> CreateTransportClient(
+ const gfx::Size& size,
+ uint64* transport_handle) = 0;
+
+ // Returns a ScopedMakeCurrent that can be used to make current a context that
+ // is shared with the compositor context, e.g. to create a texture in its
+ // namespace. The caller gets ownership of the object.
+ // This will return NULL when using out-of-process (command buffer) contexts.
+ virtual gfx::ScopedMakeCurrent* GetScopedMakeCurrent() = 0;
+};
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_IMAGE_TRANSPORT_FACTORY_H_
diff --git a/content/browser/renderer_host/render_widget_host_view.h b/content/browser/renderer_host/render_widget_host_view.h
index 99a7c91..d5942d1 100644
--- a/content/browser/renderer_host/render_widget_host_view.h
+++ b/content/browser/renderer_host/render_widget_host_view.h
@@ -349,7 +349,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView {
TransportDIB::Handle transport_dib) = 0;
#endif
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
+#if defined(USE_AURA)
virtual void AcceleratedSurfaceNew(
int32 width,
int32 height,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index d7bc0cf..9626243 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -4,8 +4,11 @@
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "content/browser/renderer_host/backing_store_skia.h"
+#include "content/browser/renderer_host/image_transport_factory.h"
+#include "content/browser/renderer_host/image_transport_client.h"
#include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/renderer_host/web_input_event_aura.h"
#include "content/common/gpu/gpu_messages.h"
@@ -25,15 +28,11 @@
#include "ui/base/ui_base_types.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/compositor/compositor.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
-#include "base/bind.h"
-#include "content/browser/renderer_host/image_transport_client.h"
-#endif
-
using WebKit::WebTouchEvent;
namespace {
@@ -102,12 +101,10 @@ class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
// Overridden from aura::WindowObserver:
virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE {
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
// TODO: It would be better to not use aura::RootWindow here
ui::Compositor* compositor = view_->GetCompositor();
if (compositor && compositor->HasObserver(view_))
compositor->RemoveObserver(view_);
-#endif
}
private:
@@ -129,9 +126,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
can_compose_inline_(true),
has_composition_text_(false),
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
current_surface_(gfx::kNullPluginWindow),
-#endif
paint_canvas_(NULL),
synthetic_move_sent_(false) {
host_->SetView(this);
@@ -331,6 +326,10 @@ void RenderWidgetHostViewAura::RenderViewGone(base::TerminationStatus status,
}
void RenderWidgetHostViewAura::Destroy() {
+ if (!shared_surface_handle_.is_null()) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ factory->DestroySharedSurfaceHandle(shared_surface_handle_);
+ }
delete window_;
}
@@ -362,7 +361,6 @@ void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
}
void RenderWidgetHostViewAura::UpdateExternalTexture() {
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
if (current_surface_ != gfx::kNullPluginWindow &&
host_->is_accelerated_compositing_active()) {
ImageTransportClient* container =
@@ -373,13 +371,11 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
} else {
window_->SetExternalTexture(NULL);
}
-#endif
}
void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
current_surface_ = params.surface_handle;
UpdateExternalTexture();
@@ -400,15 +396,11 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
if (!compositor->HasObserver(this))
compositor->AddObserver(this);
}
-#else
- NOTREACHED();
-#endif
}
void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) {
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
current_surface_ = params.surface_handle;
UpdateExternalTexture();
@@ -436,25 +428,20 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
if (!compositor->HasObserver(this))
compositor->AddObserver(this);
}
-#else
- NOTREACHED();
-#endif
}
void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
}
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
int32 width,
int32 height,
uint64* surface_handle,
TransportDIB::Handle* shm_handle) {
- ui::SharedResources* instance = ui::SharedResources::GetInstance();
- DCHECK(instance);
- scoped_refptr<ImageTransportClient> surface(
- ImageTransportClient::Create(instance, gfx::Size(width, height)));
- if (!surface || !surface->Initialize(surface_handle)) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ scoped_refptr<ImageTransportClient> surface(factory->CreateTransportClient(
+ gfx::Size(width, height), surface_handle));
+ if (!surface) {
LOG(ERROR) << "Failed to create ImageTransportClient";
return;
}
@@ -474,14 +461,11 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
}
image_transport_clients_.erase(surface_handle);
}
-#endif
void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
RenderWidgetHostViewBase::SetBackground(background);
host_->SetBackground(background);
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
window_->layer()->SetFillsBoundsOpaquely(background.isOpaque());
-#endif
}
void RenderWidgetHostViewAura::GetScreenInfo(WebKit::WebScreenInfo* results) {
@@ -519,20 +503,14 @@ void RenderWidgetHostViewAura::SetScrollOffsetPinning(
// Not needed. Mac-only.
}
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
-gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
- return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, true);
-}
-#else
gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
- // TODO(oshima): The original implementation was broken as
- // GtkNativeViewManager doesn't know about NativeWidgetGtk. Figure
- // out if this makes sense without compositor. If it does, then find
- // out the right way to handle.
- NOTIMPLEMENTED();
- return gfx::GLSurfaceHandle();
+ ui::Compositor* compositor = GetCompositor();
+ if (shared_surface_handle_.is_null() && compositor) {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ shared_surface_handle_ = factory->CreateSharedSurfaceHandle(compositor);
+ }
+ return shared_surface_handle_;
}
-#endif
bool RenderWidgetHostViewAura::LockMouse() {
aura::RootWindow* root_window = window_->GetRootWindow();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index aea4688..88de55a 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -8,6 +8,8 @@
#include <map>
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/common/content_export.h"
#include "ui/aura/client/activation_delegate.h"
@@ -17,11 +19,6 @@
#include "ui/gfx/compositor/compositor_observer.h"
#include "webkit/glue/webcursor.h"
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#endif
-
namespace gfx {
class Canvas;
}
@@ -34,15 +31,11 @@ namespace WebKit {
class WebTouchEvent;
}
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
class ImageTransportClient;
-#endif
class RenderWidgetHostViewAura
: public RenderWidgetHostViewBase,
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
public ui::CompositorObserver,
-#endif
public ui::TextInputClient,
public aura::WindowDelegate,
public aura::client::ActivationDelegate {
@@ -100,14 +93,12 @@ class RenderWidgetHostViewAura
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceSuspend() OVERRIDE;
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
virtual void AcceleratedSurfaceNew(
int32 width,
int32 height,
uint64* surface_id,
TransportDIB::Handle* surface_handle) OVERRIDE;
virtual void AcceleratedSurfaceRelease(uint64 surface_id) OVERRIDE;
-#endif
virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE;
virtual gfx::Rect GetRootWindowBounds() OVERRIDE;
virtual void ProcessTouchAck(bool processed) OVERRIDE;
@@ -175,10 +166,8 @@ class RenderWidgetHostViewAura
class WindowObserver;
friend class WindowObserver;
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
// Overridden from ui::CompositorObserver:
virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE;
-#endif
void UpdateCursorIfOverSelf();
void UpdateExternalTexture();
@@ -246,14 +235,14 @@ class RenderWidgetHostViewAura
// Current tooltip text.
string16 tooltip_;
-#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
std::vector< base::Callback<void(void)> > on_compositing_ended_callbacks_;
std::map<uint64, scoped_refptr<ImageTransportClient> >
image_transport_clients_;
gfx::PluginWindowHandle current_surface_;
-#endif
+
+ gfx::GLSurfaceHandle shared_surface_handle_;
// If non-NULL we're in OnPaint() and this is the supplied canvas.
gfx::Canvas* paint_canvas_;
diff --git a/content/common/gpu/client/command_buffer_proxy.h b/content/common/gpu/client/command_buffer_proxy.h
index 398f794..994d4e1 100644
--- a/content/common/gpu/client/command_buffer_proxy.h
+++ b/content/common/gpu/client/command_buffer_proxy.h
@@ -103,6 +103,8 @@ class CommandBufferProxy : public gpu::CommandBuffer,
void SetOnConsoleMessageCallback(const GpuConsoleMessageCallback& callback);
+ GpuChannelHost* channel() const { return channel_; }
+
private:
// Send an IPC message over the GPU channel. This is private to fully
// encapsulate the channel; all callers of this function must explicitly
diff --git a/content/common/gpu/client/content_gl_context.cc b/content/common/gpu/client/content_gl_context.cc
index 86a89f5..f184293 100644
--- a/content/common/gpu/client/content_gl_context.cc
+++ b/content/common/gpu/client/content_gl_context.cc
@@ -263,6 +263,14 @@ CommandBufferProxy* ContentGLContext::GetCommandBufferProxy() {
return command_buffer_;
}
+int ContentGLContext::GetChannelID() {
+ return channel_->client_id();
+}
+
+int ContentGLContext::GetContextID() {
+ return command_buffer_->route_id();
+}
+
bool ContentGLContext::SetSurfaceVisible(bool visible) {
return GetCommandBufferProxy()->SetSurfaceVisible(visible);
}
diff --git a/content/common/gpu/client/content_gl_context.h b/content/common/gpu/client/content_gl_context.h
index e704aa1..95a6cf8 100644
--- a/content/common/gpu/client/content_gl_context.h
+++ b/content/common/gpu/client/content_gl_context.h
@@ -177,6 +177,12 @@ class ContentGLContext : public base::SupportsWeakPtr<ContentGLContext>,
CommandBufferProxy* GetCommandBufferProxy();
+ // The following 2 IDs let one uniquely identify this context.
+ // Gets the channel ID for this context.
+ int GetChannelID();
+ // Gets the context ID (relative to the channel).
+ int GetContextID();
+
private:
explicit ContentGLContext(GpuChannelHost* channel);
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc
index 16fee44..19e1500 100644
--- a/content/common/gpu/client/gpu_channel_host.cc
+++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -99,8 +99,9 @@ void GpuChannelHost::MessageFilter::OnChannelError() {
base::Bind(&GpuChannelHost::OnChannelError, parent_));
}
-GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory)
+GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory, int client_id)
: factory_(factory),
+ client_id_(client_id),
state_(kUnconnected) {
}
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index 38d0403..888451b 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -90,7 +90,7 @@ class GpuChannelHost : public IPC::Message::Sender,
};
// Called on the render thread
- explicit GpuChannelHost(GpuChannelHostFactory* factory);
+ GpuChannelHost(GpuChannelHostFactory* factory, int client_id);
virtual ~GpuChannelHost();
// Connect to GPU process channel.
@@ -158,6 +158,7 @@ class GpuChannelHost : public IPC::Message::Sender,
void ForciblyCloseChannel();
GpuChannelHostFactory* factory() const { return factory_; }
+ int client_id() const { return client_id_; }
private:
// A filter used internally to route incoming messages from the IO thread
@@ -184,6 +185,7 @@ class GpuChannelHost : public IPC::Message::Sender,
};
GpuChannelHostFactory* factory_;
+ int client_id_;
State state_;
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
index 2eda115..c11e6b7 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
@@ -478,6 +478,8 @@ class WebGraphicsContext3DCommandBufferImpl
WGC3Denum target, WGC3Dint levels, WGC3Duint internalformat,
WGC3Dint width, WGC3Dint height);
+ ContentGLContext* content_gl_context() const { return context_; }
+
protected:
#if WEBKIT_USING_SKIA
virtual GrGLInterface* onCreateGrGLInterface();
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index c33b60e..338e4ae 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -195,8 +195,9 @@ IPC_MESSAGE_CONTROL0(GpuMsg_Hang)
// A renderer sends this when it wants to create a connection to the GPU
// process. The browser will create the GPU process if necessary, and will
// return a handle to the channel via a GpuChannelEstablished message.
-IPC_SYNC_MESSAGE_CONTROL1_3(GpuHostMsg_EstablishGpuChannel,
+IPC_SYNC_MESSAGE_CONTROL1_4(GpuHostMsg_EstablishGpuChannel,
content::CauseForGpuLaunch,
+ int /* client id */,
IPC::ChannelHandle /* handle to channel */,
base::ProcessHandle /* renderer_process_for_gpu */,
content::GPUInfo /* stats about GPU process*/)
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index d792939..dd09dd1 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -454,6 +454,8 @@
'browser/renderer_host/gtk_window_utils.h',
'browser/renderer_host/image_transport_client.cc',
'browser/renderer_host/image_transport_client.h',
+ 'browser/renderer_host/image_transport_factory.cc',
+ 'browser/renderer_host/image_transport_factory.h',
'browser/renderer_host/java/java_bound_object.cc',
'browser/renderer_host/java/java_bound_object.h',
'browser/renderer_host/java/java_bridge_channel_host.cc',
@@ -816,6 +818,8 @@
],
}, {
'sources/': [
+ ['exclude', '^browser/renderer_host/image_transport_factory.cc'],
+ ['exclude', '^browser/renderer_host/image_transport_factory.h'],
['exclude', '^browser/renderer_host/render_widget_host_view_aura.cc'],
['exclude', '^browser/renderer_host/render_widget_host_view_aura.h'],
],
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 708fdd6..1e28e57 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -556,6 +556,9 @@ const char kTraceStartupFile[] = "trace-startup-file";
// --startup-trace-file=none was supplied.
const char kTraceStartupDuration[] = "trace-startup-duration";
+// Enables the use of the GPU process for UI. Only meaningful for Aura.
+const char kUIUseGPUProcess[] = "ui-use-gpu-process";
+
// A string used to override the default user agent with a custom one.
const char kUserAgent[] = "user-agent";
@@ -621,4 +624,9 @@ const char kEnablePerTilePainting[] = "enable-per-tile-painting";
// Disables the use of a 3D software rasterizer.
const char kDisableSoftwareRasterizer[] = "disable-software-rasterizer";
+#if defined(USE_AURA)
+// Forces usage of the test compositor. Needed to run ui tests on bots.
+extern const char kTestCompositor[] = "test-compositor";
+#endif
+
} // namespace switches
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 1c05a199..7f56348 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -165,6 +165,7 @@ extern const char kTouchOptimizedUI[];
extern const char kTraceStartup[];
extern const char kTraceStartupFile[];
extern const char kTraceStartupDuration[];
+extern const char kUIUseGPUProcess[];
CONTENT_EXPORT extern const char kUserAgent[];
extern const char kUtilityCmdPrefix[];
CONTENT_EXPORT extern const char kUtilityProcess[];
@@ -194,6 +195,10 @@ CONTENT_EXPORT extern const char kRendererCheckFalseTest[];
extern const char kEnablePerTilePainting[];
+#if defined(USE_AURA)
+CONTENT_EXPORT extern const char kTestCompositor[];
+#endif
+
} // namespace switches
#endif // CONTENT_PUBLIC_COMMON_CONTENT_SWITCHES_H_
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index bb50ee5..ee709ee 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -853,18 +853,16 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
return GetGpuChannel();
// Recreate the channel if it has been lost.
- if (gpu_channel_->state() == GpuChannelHost::kLost)
- gpu_channel_ = NULL;
+ gpu_channel_ = NULL;
}
- if (!gpu_channel_.get())
- gpu_channel_ = new GpuChannelHost(this);
-
// Ask the browser for the channel name.
+ int client_id = 0;
IPC::ChannelHandle channel_handle;
base::ProcessHandle renderer_process_for_gpu;
content::GPUInfo gpu_info;
if (!Send(new GpuHostMsg_EstablishGpuChannel(cause_for_gpu_launch,
+ &client_id,
&channel_handle,
&renderer_process_for_gpu,
&gpu_info)) ||
@@ -878,6 +876,7 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
return NULL;
}
+ gpu_channel_ = new GpuChannelHost(this, client_id);
gpu_channel_->set_gpu_info(gpu_info);
content::GetContentClient()->SetGpuInfo(gpu_info);
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 5182e4c..4428c53 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -132,6 +132,11 @@ void RootWindow::Run() {
}
void RootWindow::Draw() {
+ if (waiting_on_compositing_end_) {
+ draw_on_compositing_end_ = true;
+ return;
+ }
+ waiting_on_compositing_end_ = true;
compositor_->Draw(false);
}
@@ -449,6 +454,17 @@ void RootWindow::ScheduleDraw() {
}
////////////////////////////////////////////////////////////////////////////////
+// RootWindow, ui::CompositorObserver implementation:
+
+void RootWindow::OnCompositingEnded(ui::Compositor*) {
+ waiting_on_compositing_end_ = false;
+ if (draw_on_compositing_end_) {
+ draw_on_compositing_end_ = false;
+ Draw();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
// RootWindow, private:
RootWindow::RootWindow()
@@ -467,7 +483,9 @@ RootWindow::RootWindow()
touch_event_handler_(NULL),
gesture_handler_(NULL),
gesture_recognizer_(GestureRecognizer::Create()),
- synthesize_mouse_move_(false) {
+ synthesize_mouse_move_(false),
+ waiting_on_compositing_end_(false),
+ draw_on_compositing_end_(false) {
SetName("RootWindow");
gfx::Screen::SetInstance(screen_);
last_mouse_location_ = host_->QueryMouseLocation();
@@ -476,9 +494,11 @@ RootWindow::RootWindow()
compositor_.reset(new ui::Compositor(this, host_->GetAcceleratedWidget(),
host_->GetSize()));
DCHECK(compositor_.get());
+ compositor_->AddObserver(this);
}
RootWindow::~RootWindow() {
+ compositor_->RemoveObserver(this);
// Make sure to destroy the compositor before terminating so that state is
// cleared and we don't hit asserts.
compositor_.reset();
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 7396059..207896a 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -17,6 +17,7 @@
#include "ui/aura/window.h"
#include "ui/base/events.h"
#include "ui/gfx/compositor/compositor.h"
+#include "ui/gfx/compositor/compositor_observer.h"
#include "ui/gfx/compositor/layer_animation_observer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
@@ -44,6 +45,7 @@ class GestureEvent;
// RootWindow is responsible for hosting a set of windows.
class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
+ public ui::CompositorObserver,
public Window,
public internal::FocusManager,
public ui::LayerAnimationObserver {
@@ -203,6 +205,9 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// Overridden from ui::CompositorDelegate:
virtual void ScheduleDraw() OVERRIDE;
+ // Overridden from ui::CompositorObserver:
+ virtual void OnCompositingEnded(ui::Compositor*) OVERRIDE;
+
private:
friend class Window;
@@ -312,6 +317,8 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
scoped_ptr<GestureRecognizer> gesture_recognizer_;
bool synthesize_mouse_move_;
+ bool waiting_on_compositing_end_;
+ bool draw_on_compositing_end_;
DISALLOW_COPY_AND_ASSIGN(RootWindow);
};
diff --git a/ui/gfx/compositor/compositor.cc b/ui/gfx/compositor/compositor.cc
index 9d290e2..8c8f2ee 100644
--- a/ui/gfx/compositor/compositor.cc
+++ b/ui/gfx/compositor/compositor.cc
@@ -5,6 +5,7 @@
#include "ui/gfx/compositor/compositor.h"
#include "base/command_line.h"
+#include "base/threading/thread_restrictions.h"
#include "third_party/skia/include/images/SkImageEncoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h"
@@ -18,7 +19,6 @@
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_surface.h"
#include "ui/gfx/gl/gl_implementation.h"
-#include "ui/gfx/gl/scoped_make_current.h"
#include "webkit/glue/webthread_impl.h"
#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
@@ -31,82 +31,90 @@ webkit_glue::WebThreadImpl* g_compositor_thread = NULL;
bool test_compositor_enabled = false;
+ui::ContextFactory* g_context_factory = NULL;
+
} // anonymous namespace
namespace ui {
-SharedResources::SharedResources() : initialized_(false) {
+// static
+ContextFactory* ContextFactory::GetInstance() {
+ // We leak the shared resources so that we don't race with
+ // the tear down of the gl_bindings.
+ if (!g_context_factory) {
+ if (test_compositor_enabled) {
+ VLOG(1) << "Using TestSharedResource";
+ g_context_factory = new TestContextFactory();
+ } else {
+ VLOG(1) << "Using DefaultSharedResource";
+ scoped_ptr<DefaultContextFactory> instance(
+ new DefaultContextFactory());
+ if (instance->Initialize())
+ g_context_factory = instance.release();
+ }
+ }
+ return g_context_factory;
}
+// static
+void ContextFactory::SetInstance(ContextFactory* instance) {
+ DCHECK(!g_context_factory);
+ g_context_factory = instance;
+}
-SharedResources::~SharedResources() {
+TestContextFactory::TestContextFactory() {
}
-// static
-SharedResources* SharedResources::GetInstance() {
- // We use LeakySingletonTraits so that we don't race with
- // the tear down of the gl_bindings.
- SharedResources* instance = Singleton<SharedResources,
- LeakySingletonTraits<SharedResources> >::get();
- if (instance->Initialize()) {
- return instance;
- } else {
- instance->Destroy();
- return NULL;
- }
+TestContextFactory::~TestContextFactory() {
}
-bool SharedResources::Initialize() {
- if (initialized_)
- return true;
+WebKit::WebGraphicsContext3D* TestContextFactory::CreateContext(
+ ui::Compositor* compositor) {
+ ui::TestWebGraphicsContext3D* test_context =
+ new ui::TestWebGraphicsContext3D();
+ test_context->Initialize();
+ return test_context;
+}
+void TestContextFactory::RemoveCompositor(ui::Compositor* compositor) {
+}
- {
- // The following line of code exists soley to disable IO restrictions
- // on this thread long enough to perform the GL bindings.
- // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- if (!gfx::GLSurface::InitializeOneOff() ||
- gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
- LOG(ERROR) << "Could not load the GL bindings";
- return false;
- }
- }
+DefaultContextFactory::DefaultContextFactory() {
+}
- surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
- if (!surface_.get()) {
- LOG(ERROR) << "Unable to create offscreen GL surface.";
- return false;
- }
+DefaultContextFactory::~DefaultContextFactory() {
+}
- context_ = gfx::GLContext::CreateGLContext(
- NULL, surface_.get(), gfx::PreferIntegratedGpu);
- if (!context_.get()) {
- LOG(ERROR) << "Unable to create GL context.";
+bool DefaultContextFactory::Initialize() {
+ // The following line of code exists soley to disable IO restrictions
+ // on this thread long enough to perform the GL bindings.
+ // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ if (!gfx::GLSurface::InitializeOneOff() ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
+ LOG(ERROR) << "Could not load the GL bindings";
return false;
}
-
- initialized_ = true;
return true;
}
-void SharedResources::Destroy() {
- context_ = NULL;
- surface_ = NULL;
-
- initialized_ = false;
-}
-
-gfx::ScopedMakeCurrent* SharedResources::GetScopedMakeCurrent() {
- DCHECK(initialized_);
- if (initialized_)
- return new gfx::ScopedMakeCurrent(context_.get(), surface_.get());
- else
- return NULL;
+WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContext(
+ Compositor* compositor) {
+ WebKit::WebGraphicsContext3D::Attributes attrs;
+ attrs.shareResources = true;
+ WebKit::WebGraphicsContext3D* context =
+ webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow(
+ attrs, compositor->widget(), share_group_.get());
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (!command_line->HasSwitch(switches::kDisableUIVsync)) {
+ context->makeContextCurrent();
+ gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
+ gl_context->SetSwapInterval(1);
+ gl_context->ReleaseCurrent(NULL);
+ }
+ return context;
}
-gfx::GLShareGroup* SharedResources::GetShareGroup() {
- DCHECK(initialized_);
- return context_->share_group();
+void DefaultContextFactory::RemoveCompositor(Compositor* compositor) {
}
Texture::Texture(bool flipped, const gfx::Size& size)
@@ -125,7 +133,8 @@ Compositor::Compositor(CompositorDelegate* delegate,
size_(size),
root_layer_(NULL),
widget_(widget),
- root_web_layer_(WebKit::WebLayer::create()) {
+ root_web_layer_(WebKit::WebLayer::create()),
+ swap_posted_(false) {
WebKit::WebLayerTreeView::Settings settings;
CommandLine* command_line = CommandLine::ForCurrentProcess();
settings.showFPSCounter =
@@ -153,6 +162,7 @@ Compositor::~Compositor() {
host_.setRootLayer(NULL);
if (root_layer_)
root_layer_->SetCompositor(NULL);
+ ContextFactory::GetInstance()->RemoveCompositor(this);
}
void Compositor::Initialize(bool use_thread) {
@@ -194,7 +204,7 @@ void Compositor::Draw(bool force_clear) {
return;
host_.composite();
- if (!g_compositor_thread)
+ if (!g_compositor_thread && !swap_posted_)
NotifyEnd();
}
@@ -242,6 +252,22 @@ bool Compositor::HasObserver(CompositorObserver* observer) {
return observer_list_.HasObserver(observer);
}
+void Compositor::OnSwapBuffersPosted() {
+ swap_posted_ = true;
+}
+
+void Compositor::OnSwapBuffersComplete() {
+ DCHECK(swap_posted_);
+ swap_posted_ = false;
+ NotifyEnd();
+}
+
+void Compositor::OnSwapBuffersAborted() {
+ if (swap_posted_) {
+ swap_posted_ = false;
+ NotifyEnd();
+ }
+}
void Compositor::updateAnimations(double frameBeginTime) {
}
@@ -254,29 +280,7 @@ void Compositor::applyScrollAndScale(const WebKit::WebSize& scrollDelta,
}
WebKit::WebGraphicsContext3D* Compositor::createContext3D() {
- WebKit::WebGraphicsContext3D* context;
- if (test_compositor_enabled) {
- // Use context that results in no rendering to the screen.
- TestWebGraphicsContext3D* test_context = new TestWebGraphicsContext3D();
- test_context->Initialize();
- context = test_context;
- } else {
- gfx::GLShareGroup* share_group =
- SharedResources::GetInstance()->GetShareGroup();
- WebKit::WebGraphicsContext3D::Attributes attrs;
- context = webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow(
- attrs, widget_, share_group);
- }
-
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (!command_line->HasSwitch(switches::kDisableUIVsync)) {
- context->makeContextCurrent();
- gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
- gl_context->SetSwapInterval(1);
- gl_context->ReleaseCurrent(NULL);
- }
-
- return context;
+ return ContextFactory::GetInstance()->CreateContext(this);
}
void Compositor::didCompleteSwapBuffers() {
@@ -328,6 +332,14 @@ COMPOSITOR_EXPORT void SetupTestCompositor() {
COMPOSITOR_EXPORT void DisableTestCompositor() {
test_compositor_enabled = false;
+ if (g_context_factory) {
+ delete g_context_factory;
+ g_context_factory = NULL;
+ }
+}
+
+COMPOSITOR_EXPORT bool IsTestCompositorEnabled() {
+ return test_compositor_enabled;
}
} // namespace ui
diff --git a/ui/gfx/compositor/compositor.h b/ui/gfx/compositor/compositor.h
index 04fcddf..ebbc3ad 100644
--- a/ui/gfx/compositor/compositor.h
+++ b/ui/gfx/compositor/compositor.h
@@ -6,59 +6,94 @@
#define UI_GFX_COMPOSITOR_COMPOSITOR_H_
#pragma once
+#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebLayer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebLayerTreeView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebLayerTreeViewClient.h"
#include "ui/gfx/compositor/compositor_export.h"
-#include "ui/gfx/transform.h"
+#include "ui/gfx/gl/gl_share_group.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
+#include "ui/gfx/transform.h"
class SkBitmap;
-class SkCanvas;
namespace gfx {
class GLContext;
class GLSurface;
class GLShareGroup;
class Point;
class Rect;
-class ScopedMakeCurrent;
}
namespace ui {
+class Compositor;
class CompositorObserver;
class Layer;
-class COMPOSITOR_EXPORT SharedResources {
+// This class abstracts the creation of the 3D context for the compositor. It is
+// a global object.
+class COMPOSITOR_EXPORT ContextFactory {
public:
- static SharedResources* GetInstance();
+ virtual ~ContextFactory() { }
+
+ // Gets the global instance.
+ static ContextFactory* GetInstance();
- // Creates an instance of ScopedMakeCurrent.
- // Note: Caller is responsible for managing lifetime of returned pointer.
- gfx::ScopedMakeCurrent* GetScopedMakeCurrent();
+ // Sets the global instance. Caller keeps ownership.
+ // If this function isn't called (for tests), a "default" factory will be
+ // created on the first call of GetInstance.
+ static void SetInstance(ContextFactory* instance);
- gfx::GLShareGroup* GetShareGroup();
+ // Creates a context for given compositor. The factory may keep per-compositor
+ // data (e.g. a shared context), that needs to be cleaned up by calling
+ // RemoveCompositor when the compositor gets destroyed.
+ virtual WebKit::WebGraphicsContext3D* CreateContext(
+ Compositor* compositor) = 0;
+
+ // Destroys per-compositor data.
+ virtual void RemoveCompositor(Compositor* compositor) = 0;
+};
+
+// A factory that creates test contexts (that don't draw anything).
+class TestContextFactory : public ui::ContextFactory {
+ public:
+ TestContextFactory();
+ virtual ~TestContextFactory();
+
+ // ContextFactory implementation
+ virtual WebKit::WebGraphicsContext3D* CreateContext(
+ ui::Compositor* compositor) OVERRIDE;
+ virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE;
private:
- friend struct DefaultSingletonTraits<SharedResources>;
+ DISALLOW_COPY_AND_ASSIGN(TestContextFactory);
+};
+
+// The default factory that creates in-process contexts.
+class COMPOSITOR_EXPORT DefaultContextFactory : public ContextFactory {
+ public:
+ DefaultContextFactory();
+ virtual ~DefaultContextFactory();
- SharedResources();
- ~SharedResources();
+ // ContextFactory implementation
+ virtual WebKit::WebGraphicsContext3D* CreateContext(
+ Compositor* compositor) OVERRIDE;
+ virtual void RemoveCompositor(Compositor* compositor) OVERRIDE;
bool Initialize();
- void Destroy();
- bool initialized_;
+ void set_share_group(gfx::GLShareGroup* share_group) {
+ share_group_ = share_group;
+ }
- scoped_refptr<gfx::GLContext> context_;
- scoped_refptr<gfx::GLSurface> surface_;
+ private:
+ scoped_refptr<gfx::GLShareGroup> share_group_;
- DISALLOW_COPY_AND_ASSIGN(SharedResources);
+ DISALLOW_COPY_AND_ASSIGN(DefaultContextFactory);
};
// Texture provide an abstraction over the external texture that can be passed
@@ -69,15 +104,15 @@ class COMPOSITOR_EXPORT Texture : public base::RefCounted<Texture> {
virtual ~Texture();
unsigned int texture_id() const { return texture_id_; }
+ void set_texture_id(unsigned int id) { texture_id_ = id; }
bool flipped() const { return flipped_; }
gfx::Size size() const { return size_; }
- protected:
+ private:
unsigned int texture_id_;
bool flipped_;
gfx::Size size_;
- private:
DISALLOW_COPY_AND_ASSIGN(Texture);
};
@@ -139,7 +174,10 @@ class COMPOSITOR_EXPORT Compositor
void WidgetSizeChanged(const gfx::Size& size);
// Returns the size of the widget that is being drawn to.
- const gfx::Size& size() { return size_; }
+ const gfx::Size& size() const { return size_; }
+
+ // Returns the widget for this compositor.
+ gfx::AcceleratedWidget widget() const { return widget_; }
// Compositor does not own observers. It is the responsibility of the
// observer to remove itself when it is done observing.
@@ -147,6 +185,18 @@ class COMPOSITOR_EXPORT Compositor
void RemoveObserver(CompositorObserver* observer);
bool HasObserver(CompositorObserver* observer);
+ // Internal functions, called back by command-buffer contexts on swap buffer
+ // events.
+
+ // Signals swap has been posted.
+ void OnSwapBuffersPosted();
+
+ // Signals swap has completed.
+ void OnSwapBuffersComplete();
+
+ // Signals swap has aborted (e.g. lost context).
+ void OnSwapBuffersAborted();
+
// WebLayerTreeViewClient implementation.
virtual void updateAnimations(double frameBeginTime);
virtual void layout();
@@ -178,6 +228,10 @@ class COMPOSITOR_EXPORT Compositor
WebKit::WebLayer root_web_layer_;
WebKit::WebLayerTreeView host_;
+ // This is set to true when the swap buffers has been posted and we're waiting
+ // for completion.
+ bool swap_posted_;
+
friend class base::RefCounted<Compositor>;
};
diff --git a/ui/gfx/compositor/compositor_observer.h b/ui/gfx/compositor/compositor_observer.h
index 5012f0c..0025799 100644
--- a/ui/gfx/compositor/compositor_observer.h
+++ b/ui/gfx/compositor/compositor_observer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,12 +6,14 @@
#define UI_GFX_COMPOSITOR_COMPOSITOR_OBSERVER_H_
#pragma once
+#include "ui/gfx/compositor/compositor_export.h"
+
namespace ui {
class Compositor;
// A compositor observer is notified when compositing completes.
-class CompositorObserver {
+class COMPOSITOR_EXPORT CompositorObserver {
public:
// Called when compositing completes.
virtual void OnCompositingEnded(Compositor* compositor) = 0;
diff --git a/ui/gfx/compositor/compositor_setup.h b/ui/gfx/compositor/compositor_setup.h
index 9978e7f..1f59d86 100644
--- a/ui/gfx/compositor/compositor_setup.h
+++ b/ui/gfx/compositor/compositor_setup.h
@@ -22,6 +22,7 @@ COMPOSITOR_EXPORT void SetupTestCompositor();
// Disables the test compositor so that the normal compositor is used.
COMPOSITOR_EXPORT void DisableTestCompositor();
+COMPOSITOR_EXPORT bool IsTestCompositorEnabled();
#endif
} // namespace ui
diff --git a/ui/gfx/compositor/layer.h b/ui/gfx/compositor/layer.h
index ee2b429..f7b6e3d 100644
--- a/ui/gfx/compositor/layer.h
+++ b/ui/gfx/compositor/layer.h
@@ -171,8 +171,6 @@ class COMPOSITOR_EXPORT Layer :
// Assigns a new external texture. |texture| can be NULL to disable external
// updates.
- // TODO(beng): This can be removed from the API when we are in a
- // single-compositor world.
void SetExternalTexture(ui::Texture* texture);
// Sets the layer's fill color. May only be called for LAYER_SOLID_COLOR.