diff options
author | ccameron <ccameron@chromium.org> | 2015-08-14 12:36:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-14 19:37:43 +0000 |
commit | 18aef9e80c78e646dac22a19dc88c700589058e0 (patch) | |
tree | 051ef2801f3426a7ea9d771124c9757b059d8d1b | |
parent | da7cdcd7a6b95fd659d552f69d7a4864c10bc8d6 (diff) | |
download | chromium_src-18aef9e80c78e646dac22a19dc88c700589058e0.zip chromium_src-18aef9e80c78e646dac22a19dc88c700589058e0.tar.gz chromium_src-18aef9e80c78e646dac22a19dc88c700589058e0.tar.bz2 |
Mac Overlays: Make ImageTransportSurfaceOverlayMac observe GPU switches
When the GPU switches, create a new OpenGL context, to see which GL
renderer it uses. Whenever a context is made current to the surface,
ensure that the context is using the appropriate renderer.
Ideally, the GpuSwitchingManager should be able to tell the observers
which GL renderer to use, but that is not currently wired up.
BUG=519097
Committed: https://crrev.com/0009e1ea4154c5a20fffa3cf47b0b29c23a6f7e2
Cr-Commit-Position: refs/heads/master@{#343277}
Review URL: https://codereview.chromium.org/1291703002
Cr-Commit-Position: refs/heads/master@{#343459}
-rw-r--r-- | content/common/gpu/image_transport_surface_overlay_mac.h | 12 | ||||
-rw-r--r-- | content/common/gpu/image_transport_surface_overlay_mac.mm | 44 | ||||
-rw-r--r-- | ui/accelerated_widget_mac/io_surface_context.h | 4 |
3 files changed, 56 insertions, 4 deletions
diff --git a/content/common/gpu/image_transport_surface_overlay_mac.h b/content/common/gpu/image_transport_surface_overlay_mac.h index 1265cc4..4c9c006 100644 --- a/content/common/gpu/image_transport_surface_overlay_mac.h +++ b/content/common/gpu/image_transport_surface_overlay_mac.h @@ -13,6 +13,7 @@ #include "content/common/gpu/image_transport_surface.h" #include "ui/accelerated_widget_mac/display_link_mac.h" #include "ui/gl/gl_surface.h" +#include "ui/gl/gpu_switching_observer.h" @class CAContext; @class CALayer; @@ -20,7 +21,8 @@ namespace content { class ImageTransportSurfaceOverlayMac : public gfx::GLSurface, - public ImageTransportSurface { + public ImageTransportSurface, + public ui::GpuSwitchingObserver { public: ImageTransportSurfaceOverlayMac(GpuChannelManager* manager, GpuCommandBufferStub* stub, @@ -35,6 +37,7 @@ class ImageTransportSurfaceOverlayMac : public gfx::GLSurface, bool SupportsPostSubBuffer() override; gfx::Size GetSize() override; void* GetHandle() override; + bool OnMakeCurrent(gfx::GLContext* context) override; bool ScheduleOverlayPlane(int z_order, gfx::OverlayTransform transform, @@ -50,6 +53,9 @@ class ImageTransportSurfaceOverlayMac : public gfx::GLSurface, void SetLatencyInfo(const std::vector<ui::LatencyInfo>&) override; void WakeUpGpu() override; + // ui::GpuSwitchingObserver implementation. + void OnGpuSwitched() override; + private: class PendingSwap; @@ -85,6 +91,10 @@ class ImageTransportSurfaceOverlayMac : public gfx::GLSurface, float scale_factor_; std::vector<ui::LatencyInfo> latency_info_; + // The renderer ID that all contexts made current to this surface should be + // targeting. + GLint gl_renderer_id_; + // Weak pointer to the image provided when ScheduleOverlayPlane is called. Is // consumed and reset when SwapBuffers is called. For now, only one overlay // plane is supported. diff --git a/content/common/gpu/image_transport_surface_overlay_mac.mm b/content/common/gpu/image_transport_surface_overlay_mac.mm index 7f21afd..7d51b79 100644 --- a/content/common/gpu/image_transport_surface_overlay_mac.mm +++ b/content/common/gpu/image_transport_surface_overlay_mac.mm @@ -5,6 +5,8 @@ #include "content/common/gpu/image_transport_surface_overlay_mac.h" #include <IOSurface/IOSurface.h> +#include <OpenGL/CGLRenderers.h> +#include <OpenGL/CGLTypes.h> #include <OpenGL/GL.h> // This type consistently causes problem on Mac, and needs to be dealt with @@ -16,12 +18,15 @@ typedef void* GLeglImageOES; #include "base/mac/scoped_cftyperef.h" #include "content/common/gpu/gpu_messages.h" +#include "ui/accelerated_widget_mac/io_surface_context.h" #include "ui/accelerated_widget_mac/surface_handle_types.h" #include "ui/base/cocoa/animation_utils.h" #include "ui/base/cocoa/remote_layer_api.h" #include "ui/gfx/geometry/dip_util.h" +#include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" #include "ui/gl/gl_image_io_surface.h" +#include "ui/gl/gpu_switching_manager.h" #include "ui/gl/scoped_api.h" #include "ui/gl/scoped_cgl.h" @@ -47,6 +52,9 @@ void CheckGLErrors(const char* msg) { } } +void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { +} + } // namespace @interface CALayer(Private) @@ -88,12 +96,14 @@ ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( GpuChannelManager* manager, GpuCommandBufferStub* stub, gfx::PluginWindowHandle handle) - : scale_factor_(1), pending_overlay_image_(nullptr), + : scale_factor_(1), gl_renderer_id_(0), pending_overlay_image_(nullptr), has_pending_callback_(false), weak_factory_(this) { helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); + ui::GpuSwitchingManager::GetInstance()->AddObserver(this); } ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { + ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); Destroy(); } @@ -251,7 +261,7 @@ bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay( gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context); CheckGLErrors("before testing fence"); - has_completed= swap->gl_fence->HasCompleted(); + has_completed = swap->gl_fence->HasCompleted(); CheckGLErrors("after testing fence"); if (has_completed) { swap->gl_fence.reset(); @@ -407,6 +417,14 @@ void* ImageTransportSurfaceOverlayMac::GetHandle() { return nullptr; } +bool ImageTransportSurfaceOverlayMac::OnMakeCurrent(gfx::GLContext* context) { + // Ensure that the context is on the appropriate GL renderer. The GL renderer + // will generally only change when the GPU changes. + if (gl_renderer_id_ && context) + context->share_group()->SetRendererID(gl_renderer_id_); + return true; +} + bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane( int z_order, gfx::OverlayTransform transform, @@ -454,4 +472,26 @@ void ImageTransportSurfaceOverlayMac::SetLatencyInfo( void ImageTransportSurfaceOverlayMac::WakeUpGpu() {} +void ImageTransportSurfaceOverlayMac::OnGpuSwitched() { + // Create a new context, and use the GL renderer ID that the new context gets. + scoped_refptr<ui::IOSurfaceContext> context_on_new_gpu = + ui::IOSurfaceContext::Get(ui::IOSurfaceContext::kCALayerContext); + if (!context_on_new_gpu) + return; + GLint context_renderer_id = -1; + if (CGLGetParameter(context_on_new_gpu->cgl_context(), + kCGLCPCurrentRendererID, + &context_renderer_id) != kCGLNoError) { + LOG(ERROR) << "Failed to create test context after GPU switch"; + return; + } + gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask; + + // Post a task holding a reference to the new GL context. The reason for + // this is to avoid creating-then-destroying the context for every image + // transport surface that is observing the GPU switch. + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu)); +} + } // namespace content diff --git a/ui/accelerated_widget_mac/io_surface_context.h b/ui/accelerated_widget_mac/io_surface_context.h index 75347b48..bf2b254 100644 --- a/ui/accelerated_widget_mac/io_surface_context.h +++ b/ui/accelerated_widget_mac/io_surface_context.h @@ -13,6 +13,7 @@ #include "base/mac/scoped_nsobject.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h" #include "ui/gl/gpu_switching_observer.h" #include "ui/gl/scoped_cgl.h" @@ -33,7 +34,8 @@ class IOSurfaceContext // Get or create a GL context of the specified type. Share these GL contexts // as much as possible because creating and destroying them can be expensive. // http://crbug.com/180463 - static scoped_refptr<IOSurfaceContext> Get(Type type); + ACCELERATED_WIDGET_MAC_EXPORT static scoped_refptr<IOSurfaceContext> Get( + Type type); // Mark that all the GL contexts in the same sharegroup as this context as // invalid, so they shouldn't be returned anymore by Get, but rather, new |