Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(471)

Unified Diff: ui/accelerated_widget_mac/io_surface_ns_gl_surface.mm

Issue 1164363005: Mac: Only allow NSOpenGLContext displaying on the main display (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add GPU switch Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/accelerated_widget_mac/io_surface_ns_gl_surface.mm
diff --git a/ui/accelerated_widget_mac/io_surface_ns_gl_surface.mm b/ui/accelerated_widget_mac/io_surface_ns_gl_surface.mm
index 46132a1eac2720c0f24d7628839a4800aca1ee16..9d1c26cd8f7578d8b53f9162e8e7cf69370dd0e5 100644
--- a/ui/accelerated_widget_mac/io_surface_ns_gl_surface.mm
+++ b/ui/accelerated_widget_mac/io_surface_ns_gl_surface.mm
@@ -4,14 +4,18 @@
#include "ui/accelerated_widget_mac/io_surface_ns_gl_surface.h"
+#include <OpenGL/CGLRenderers.h>
#include <OpenGL/GL.h>
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/mac/bind_objc_block.h"
+#include "base/mac/mac_util.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/message_loop/message_loop.h"
#include "base/trace_event/trace_event.h"
#include "ui/base/cocoa/animation_utils.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gl/gpu_switching_manager.h"
@@ -19,8 +23,11 @@
namespace ui {
IOSurfaceNSGLSurface* IOSurfaceNSGLSurface::Create(
- IOSurfaceNSGLSurfaceClient* client, NSView* view) {
- scoped_refptr<IOSurfaceTexture> iosurface = IOSurfaceTexture::Create(false);
+ IOSurfaceNSGLSurfaceClient* client,
+ NSView* view,
+ bool needs_gl_finish_workaround) {
+ scoped_refptr<IOSurfaceTexture> iosurface =
+ IOSurfaceTexture::Create(needs_gl_finish_workaround, true);
if (!iosurface)
return NULL;
@@ -47,21 +54,25 @@ IOSurfaceNSGLSurface* IOSurfaceNSGLSurface::Create(
return NULL;
}
- return new IOSurfaceNSGLSurface(client, view, ns_gl_context, iosurface);
+ return new IOSurfaceNSGLSurface(
+ client, view, needs_gl_finish_workaround, ns_gl_context, iosurface);
}
IOSurfaceNSGLSurface::IOSurfaceNSGLSurface(
IOSurfaceNSGLSurfaceClient* client,
NSView* view,
+ bool needs_gl_finish_workaround,
base::scoped_nsobject<NSOpenGLContext> ns_gl_context,
scoped_refptr<ui::IOSurfaceTexture> iosurface)
: client_(client), view_(view), iosurface_(iosurface),
ns_gl_context_(ns_gl_context), contents_scale_factor_(1),
- pending_draw_exists_(false) {
+ pending_draw_exists_(false), needs_to_be_recreated_(false) {
[[view_ layer] setContentsGravity:kCAGravityTopLeft];
+ ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
}
IOSurfaceNSGLSurface::~IOSurfaceNSGLSurface() {
+ ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
DoPendingDrawIfNeeded();
[ns_gl_context_ makeCurrentContext];
iosurface_ = NULL;
@@ -76,6 +87,7 @@ bool IOSurfaceNSGLSurface::GotFrame(IOSurfaceID io_surface_id,
gfx::Size frame_pixel_size,
float frame_scale_factor,
gfx::Rect pixel_damage_rect) {
+ TRACE_EVENT0("ui", "IOSurfaceNSGLSurface::GotFrame");
pending_draw_exists_ = true;
pending_draw_damage_rect_.Union(pixel_damage_rect);
@@ -109,8 +121,11 @@ bool IOSurfaceNSGLSurface::GotFrame(IOSurfaceID io_surface_id,
bool result = iosurface_->SetIOSurface(io_surface_id, frame_pixel_size);
[NSOpenGLContext clearCurrentContext];
- if (!result)
+ if (!result) {
+ LOG(ERROR) << "Failed to set IOSurface, poisoning NSOpenGLContext.";
+ needs_to_be_recreated_ = true;
return false;
+ }
pending_draw_damage_rect_ = gfx::Rect(frame_pixel_size);
}
@@ -126,8 +141,12 @@ void IOSurfaceNSGLSurface::DoPendingDrawIfNeeded() {
{
TRACE_EVENT0("ui", "IOSurfaceNSGLSurface::Draw");
[ns_gl_context_ makeCurrentContext];
- ignore_result(iosurface_->DrawIOSurfaceWithDamageRect(
- pending_draw_damage_rect_));
+ bool result = iosurface_->DrawIOSurfaceWithDamageRect(
+ pending_draw_damage_rect_);
+ if (!result) {
+ LOG(ERROR) << "Failed to draw IOSurface, poisoning NSOpenGLContext.";
+ needs_to_be_recreated_ = true;
+ }
glFlush();
[NSOpenGLContext clearCurrentContext];
}
@@ -138,4 +157,48 @@ void IOSurfaceNSGLSurface::DoPendingDrawIfNeeded() {
client_->IOSurfaceNSGLSurfaceDidDrawFrame();
}
-};
+int IOSurfaceNSGLSurface::GetRendererID() {
+ GLint current_renderer_id = -1;
+ CGLContextObj cgl_context = static_cast<CGLContextObj>(
+ [ns_gl_context_ CGLContextObj]);
+ if (CGLGetParameter(cgl_context,
+ kCGLCPCurrentRendererID,
+ &current_renderer_id) == kCGLNoError) {
+ return current_renderer_id & kCGLRendererIDMatchingMask;
+ }
+ return -1;
+}
+
+void IOSurfaceNSGLSurface::OnGpuSwitched() {
+ needs_to_be_recreated_ = true;
+}
+
+// static
+bool IOSurfaceNSGLSurface::CanUseNSGLSurfaceForView(NSView* view) {
+ // This must be explicitly enabled at the command line.
+ static bool use_ns_gl_surfaces =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableNSGLSurfaces);
+ if (!use_ns_gl_surfaces)
+ return false;
+
+ // Do not attempt this before 10.9. The power savings are not worth the
+ // stability risk and testing burden.
+ if (!base::mac::IsOSMavericksOrLater())
+ return false;
+
+ // If the NSView being attached to the NSOpenGLContext is not on the main
+ // monitor, then, due to an OS X bug, the IOSurface will be thrashed,
+ // resulting in hangs of 50 msec or more.
+ CGDirectDisplayID main_display = CGMainDisplayID();
+ NSScreen* screen = [[view window] screen];
+ NSDictionary* screen_description = [screen deviceDescription];
+ NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"];
+ CGDirectDisplayID display_id = [screen_number unsignedIntValue];
+ if (display_id != main_display)
+ return false;
+
+ return true;
+}
+
+} // namespace ui
« no previous file with comments | « ui/accelerated_widget_mac/io_surface_ns_gl_surface.h ('k') | ui/accelerated_widget_mac/io_surface_texture.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698