summaryrefslogtreecommitdiffstats
path: root/webkit/gpu
diff options
context:
space:
mode:
authorkbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-13 22:55:50 +0000
committerkbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-13 22:55:50 +0000
commit276f89060fa4b38582dcd76ebdf9454bb7d42c8e (patch)
tree0ff1c47fed812c196ae491a6c7295164d557e813 /webkit/gpu
parent91701aec11f289e96ce92b588b858b26179cb89c (diff)
downloadchromium_src-276f89060fa4b38582dcd76ebdf9454bb7d42c8e.zip
chromium_src-276f89060fa4b38582dcd76ebdf9454bb7d42c8e.tar.gz
chromium_src-276f89060fa4b38582dcd76ebdf9454bb7d42c8e.tar.bz2
Support dynamic switching between integrated and discrete GPUs on Mac OS X.
Change Chrome to allocate most OpenGL contexts with the kCGLPFAAllowOfflineRenderers flag, and specify NSSupportsAutomaticGraphicsSwitching in the Info.plist for the main executable and helper apps. This keeps Chrome on the integrated GPU except when using WebGL, accelerated 2D Canvas, Pepper 3D, and Core Animation-based plugins (except Flash). Chrome shares resources between OpenGL contexts in order to display WebGL and other content in the compositor, and resource sharing doesn't work between contexts allocated on different GPUs. Therefore, when the first context for a given renderer requests the discrete GPU, the channel is dropped and all contexts are reallocated on the discrete GPU. Similarly, when the last context requesting the discrete GPU for a given renderer is shut down, all contexts are dropped and reallocated on the integrated GPU. Currently dynamic GPU switching is only supported on the latest Mac OS X 10.7 update and MacBook Pros with dual AMD / Intel GPUs, though this will improve in future OS updates. Tested with WebGL, CSS 3D, Flash and Unity3D content and observed desired GPU switching behavior. Also added a layout test to WebKit under https://bugs.webkit.org/show_bug.cgi?id=69776 which when run in Chrome catches an assertion failure related to the destruction of contexts. The intent is to add it as a UI layout test on the GPU bots. BUG=88788 TEST=none Review URL: http://codereview.chromium.org/8233027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105399 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/gpu')
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc38
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_impl.cc10
2 files changed, 36 insertions, 12 deletions
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 6e14dad..ec03290 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -103,7 +103,8 @@ class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> {
GLInProcessContext* context_group,
const char* allowed_extensions,
const int32* attrib_list,
- const GURL& active_arl);
+ const GURL& active_url,
+ gfx::GpuPreference gpu_preference);
// Create a GLInProcessContext that renders to an offscreen frame buffer. If
// parent is not NULL, that GLInProcessContext can access a copy of the
@@ -119,7 +120,8 @@ class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> {
GLInProcessContext* context_group,
const char* allowed_extensions,
const int32* attrib_list,
- const GURL& active_url);
+ const GURL& active_url,
+ gfx::GpuPreference gpu_preference);
// For an offscreen frame buffer GLInProcessContext, return the texture ID
// with respect to the parent GLInProcessContext. Returns zero if
@@ -173,7 +175,8 @@ class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> {
GLInProcessContext* context_group,
const char* allowed_extensions,
const int32* attrib_list,
- const GURL& active_url);
+ const GURL& active_url,
+ gfx::GpuPreference gpu_preference);
void Destroy();
void OnSwapBuffers();
@@ -240,7 +243,8 @@ GLInProcessContext* GLInProcessContext::CreateViewContext(
GLInProcessContext* context_group,
const char* allowed_extensions,
const int32* attrib_list,
- const GURL& active_url) {
+ const GURL& active_url,
+ gfx::GpuPreference gpu_preference) {
#if defined(ENABLE_GPU)
scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL));
if (!context->Initialize(
@@ -250,7 +254,8 @@ GLInProcessContext* GLInProcessContext::CreateViewContext(
context_group,
allowed_extensions,
attrib_list,
- active_url))
+ active_url,
+ gpu_preference))
return NULL;
return context.release();
@@ -265,7 +270,8 @@ GLInProcessContext* GLInProcessContext::CreateOffscreenContext(
GLInProcessContext* context_group,
const char* allowed_extensions,
const int32* attrib_list,
- const GURL& active_url) {
+ const GURL& active_url,
+ gfx::GpuPreference gpu_preference) {
#if defined(ENABLE_GPU)
scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent));
if (!context->Initialize(
@@ -275,7 +281,8 @@ GLInProcessContext* GLInProcessContext::CreateOffscreenContext(
context_group,
allowed_extensions,
attrib_list,
- active_url))
+ active_url,
+ gpu_preference))
return NULL;
return context.release();
@@ -397,7 +404,8 @@ bool GLInProcessContext::Initialize(bool onscreen,
GLInProcessContext* context_group,
const char* allowed_extensions,
const int32* attrib_list,
- const GURL& active_url) {
+ const GURL& active_url,
+ gfx::GpuPreference gpu_preference) {
// Use one share group for all contexts.
static scoped_refptr<gfx::GLShareGroup> share_group(new gfx::GLShareGroup);
@@ -480,7 +488,9 @@ bool GLInProcessContext::Initialize(bool onscreen,
return false;
}
- context_ = gfx::GLContext::CreateGLContext(share_group.get(), surface_.get());
+ context_ = gfx::GLContext::CreateGLContext(share_group.get(),
+ surface_.get(),
+ gpu_preference);
if (!context_.get()) {
LOG(ERROR) << "Could not create GLContext.";
Destroy();
@@ -625,6 +635,13 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize(
const char* preferred_extensions = "*";
+ // TODO(kbr): More work will be needed in this implementation to
+ // properly support GPU switching. Like in the out-of-process
+ // command buffer implementation, all previously created contexts
+ // will need to be lost either when the first context requesting the
+ // discrete GPU is created, or the last one is destroyed.
+ gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+
GURL active_url;
if (web_view && web_view->mainFrame())
active_url = GURL(web_view->mainFrame()->document().url());
@@ -653,7 +670,8 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize(
context_group ? context_group->context_ : NULL,
preferred_extensions,
attribs,
- active_url);
+ active_url,
+ gpu_preference);
web_view_ = NULL;
if (!context_)
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
index 4506289..c56e222 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_impl.cc
@@ -164,8 +164,13 @@ bool WebGraphicsContext3DInProcessImpl::initialize(
return false;
}
+ // TODO(kbr): This implementation doesn't yet support lost contexts
+ // and therefore can't yet properly support GPU switching.
+ gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+
gl_context_ = gfx::GLContext::CreateGLContext(share_group,
- gl_surface_.get());
+ gl_surface_.get(),
+ gpu_preference);
if (!gl_context_.get()) {
if (!is_gles2_)
return false;
@@ -180,7 +185,8 @@ bool WebGraphicsContext3DInProcessImpl::initialize(
if (webView) webView->mainFrame()->collectGarbage();
gl_context_ = gfx::GLContext::CreateGLContext(share_group,
- gl_surface_.get());
+ gl_surface_.get(),
+ gpu_preference);
if (!gl_context_.get())
return false;
}