summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorccameron <ccameron@chromium.org>2015-08-14 12:36:28 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-14 19:37:43 +0000
commit18aef9e80c78e646dac22a19dc88c700589058e0 (patch)
tree051ef2801f3426a7ea9d771124c9757b059d8d1b
parentda7cdcd7a6b95fd659d552f69d7a4864c10bc8d6 (diff)
downloadchromium_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.h12
-rw-r--r--content/common/gpu/image_transport_surface_overlay_mac.mm44
-rw-r--r--ui/accelerated_widget_mac/io_surface_context.h4
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