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

Side by Side 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: 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/accelerated_widget_mac/io_surface_ns_gl_surface.h" 5 #include "ui/accelerated_widget_mac/io_surface_ns_gl_surface.h"
6 6
7 #include <OpenGL/CGLRenderers.h>
7 #include <OpenGL/GL.h> 8 #include <OpenGL/GL.h>
8 9
9 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/command_line.h"
10 #include "base/mac/bind_objc_block.h" 12 #include "base/mac/bind_objc_block.h"
13 #include "base/mac/mac_util.h"
11 #include "base/mac/sdk_forward_declarations.h" 14 #include "base/mac/sdk_forward_declarations.h"
12 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
13 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
14 #include "ui/base/cocoa/animation_utils.h" 17 #include "ui/base/cocoa/animation_utils.h"
18 #include "ui/base/ui_base_switches.h"
15 #include "ui/gfx/geometry/dip_util.h" 19 #include "ui/gfx/geometry/dip_util.h"
16 #include "ui/gfx/geometry/rect.h" 20 #include "ui/gfx/geometry/rect.h"
17 #include "ui/gl/gpu_switching_manager.h" 21 #include "ui/gl/gpu_switching_manager.h"
18 22
19 namespace ui { 23 namespace ui {
20 24
21 IOSurfaceNSGLSurface* IOSurfaceNSGLSurface::Create( 25 IOSurfaceNSGLSurface* IOSurfaceNSGLSurface::Create(
22 IOSurfaceNSGLSurfaceClient* client, NSView* view) { 26 IOSurfaceNSGLSurfaceClient* client,
23 scoped_refptr<IOSurfaceTexture> iosurface = IOSurfaceTexture::Create(false); 27 NSView* view,
28 bool needs_gl_finish_workaround) {
29 scoped_refptr<IOSurfaceTexture> iosurface =
30 IOSurfaceTexture::Create(needs_gl_finish_workaround, true);
24 if (!iosurface) 31 if (!iosurface)
25 return NULL; 32 return NULL;
26 33
27 std::vector<NSOpenGLPixelFormatAttribute> attribs; 34 std::vector<NSOpenGLPixelFormatAttribute> attribs;
28 attribs.push_back(NSOpenGLPFAColorSize); 35 attribs.push_back(NSOpenGLPFAColorSize);
29 attribs.push_back(24); 36 attribs.push_back(24);
30 attribs.push_back(NSOpenGLPFAAlphaSize); 37 attribs.push_back(NSOpenGLPFAAlphaSize);
31 attribs.push_back(8); 38 attribs.push_back(8);
32 attribs.push_back(NSOpenGLPFAAccelerated); 39 attribs.push_back(NSOpenGLPFAAccelerated);
33 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) 40 if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
34 attribs.push_back(NSOpenGLPFAAllowOfflineRenderers); 41 attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
35 attribs.push_back(0); 42 attribs.push_back(0);
36 base::scoped_nsobject<NSOpenGLPixelFormat> pixel_format( 43 base::scoped_nsobject<NSOpenGLPixelFormat> pixel_format(
37 [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs.front()]); 44 [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs.front()]);
38 if (!pixel_format) { 45 if (!pixel_format) {
39 LOG(ERROR) << "Failed to create pixel format object."; 46 LOG(ERROR) << "Failed to create pixel format object.";
40 return NULL; 47 return NULL;
41 } 48 }
42 49
43 base::scoped_nsobject<NSOpenGLContext> ns_gl_context( 50 base::scoped_nsobject<NSOpenGLContext> ns_gl_context(
44 [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]); 51 [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]);
45 if (!ns_gl_context) { 52 if (!ns_gl_context) {
46 LOG(ERROR) << "Failed to create context object."; 53 LOG(ERROR) << "Failed to create context object.";
47 return NULL; 54 return NULL;
48 } 55 }
49 56
50 return new IOSurfaceNSGLSurface(client, view, ns_gl_context, iosurface); 57 return new IOSurfaceNSGLSurface(
58 client, view, needs_gl_finish_workaround, ns_gl_context, iosurface);
51 } 59 }
52 60
53 IOSurfaceNSGLSurface::IOSurfaceNSGLSurface( 61 IOSurfaceNSGLSurface::IOSurfaceNSGLSurface(
54 IOSurfaceNSGLSurfaceClient* client, 62 IOSurfaceNSGLSurfaceClient* client,
55 NSView* view, 63 NSView* view,
64 bool needs_gl_finish_workaround,
56 base::scoped_nsobject<NSOpenGLContext> ns_gl_context, 65 base::scoped_nsobject<NSOpenGLContext> ns_gl_context,
57 scoped_refptr<ui::IOSurfaceTexture> iosurface) 66 scoped_refptr<ui::IOSurfaceTexture> iosurface)
58 : client_(client), view_(view), iosurface_(iosurface), 67 : client_(client), view_(view), iosurface_(iosurface),
59 ns_gl_context_(ns_gl_context), contents_scale_factor_(1), 68 ns_gl_context_(ns_gl_context), contents_scale_factor_(1),
60 pending_draw_exists_(false) { 69 pending_draw_exists_(false) {
61 [[view_ layer] setContentsGravity:kCAGravityTopLeft]; 70 [[view_ layer] setContentsGravity:kCAGravityTopLeft];
62 } 71 }
63 72
64 IOSurfaceNSGLSurface::~IOSurfaceNSGLSurface() { 73 IOSurfaceNSGLSurface::~IOSurfaceNSGLSurface() {
65 DoPendingDrawIfNeeded(); 74 DoPendingDrawIfNeeded();
66 [ns_gl_context_ makeCurrentContext]; 75 [ns_gl_context_ makeCurrentContext];
67 iosurface_ = NULL; 76 iosurface_ = NULL;
68 [NSOpenGLContext clearCurrentContext]; 77 [NSOpenGLContext clearCurrentContext];
69 [ns_gl_context_ clearDrawable]; 78 [ns_gl_context_ clearDrawable];
70 79
71 ScopedCAActionDisabler disabler; 80 ScopedCAActionDisabler disabler;
72 [[view_ layer] setContents:nil]; 81 [[view_ layer] setContents:nil];
73 } 82 }
74 83
75 bool IOSurfaceNSGLSurface::GotFrame(IOSurfaceID io_surface_id, 84 bool IOSurfaceNSGLSurface::GotFrame(IOSurfaceID io_surface_id,
76 gfx::Size frame_pixel_size, 85 gfx::Size frame_pixel_size,
77 float frame_scale_factor, 86 float frame_scale_factor,
78 gfx::Rect pixel_damage_rect) { 87 gfx::Rect pixel_damage_rect) {
88 TRACE_EVENT0("ui", "IOSurfaceNSGLSurface::GotFrame");
79 pending_draw_exists_ = true; 89 pending_draw_exists_ = true;
80 pending_draw_damage_rect_.Union(pixel_damage_rect); 90 pending_draw_damage_rect_.Union(pixel_damage_rect);
81 91
82 // If the OpenGL framebuffer does not match the frame in scale factor or 92 // If the OpenGL framebuffer does not match the frame in scale factor or
83 // pixel size, then re-latch them. Note that they will latch to the layer's 93 // pixel size, then re-latch them. Note that they will latch to the layer's
84 // bounds, which will not necessarily match the frame's pixel size. 94 // bounds, which will not necessarily match the frame's pixel size.
85 if (!iosurface_->IsUpToDate(io_surface_id, frame_pixel_size) || 95 if (!iosurface_->IsUpToDate(io_surface_id, frame_pixel_size) ||
86 [ns_gl_context_ view] != view_ || 96 [ns_gl_context_ view] != view_ ||
87 frame_pixel_size != contents_pixel_size_ || 97 frame_pixel_size != contents_pixel_size_ ||
88 frame_scale_factor != contents_scale_factor_) { 98 frame_scale_factor != contents_scale_factor_) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 glFlush(); 141 glFlush();
132 [NSOpenGLContext clearCurrentContext]; 142 [NSOpenGLContext clearCurrentContext];
133 } 143 }
134 144
135 pending_draw_exists_ = false; 145 pending_draw_exists_ = false;
136 pending_draw_damage_rect_ = gfx::Rect(); 146 pending_draw_damage_rect_ = gfx::Rect();
137 147
138 client_->IOSurfaceNSGLSurfaceDidDrawFrame(); 148 client_->IOSurfaceNSGLSurfaceDidDrawFrame();
139 } 149 }
140 150
141 }; 151 int IOSurfaceNSGLSurface::GetRendererID() {
152 GLint current_renderer_id = -1;
153 CGLContextObj cgl_context = static_cast<CGLContextObj>(
Andre 2015/06/10 05:23:39 Why do you need this cast?
ccameron 2015/06/10 21:39:51 -[NSOpenGLContext CGLContextObj] returns a void*,
154 [ns_gl_context_ CGLContextObj]);
155 if (CGLGetParameter(cgl_context,
156 kCGLCPCurrentRendererID,
157 &current_renderer_id) == kCGLNoError) {
158 return current_renderer_id & kCGLRendererIDMatchingMask;
159 }
160 return -1;
161 }
162
163 // static
164 bool IOSurfaceNSGLSurface::CanUseNSGLSurfaceForView(NSView* view) {
165 // This must be explicitly enabled at the command line.
166 static bool use_ns_gl_surfaces =
167 base::CommandLine::ForCurrentProcess()->HasSwitch(
168 switches::kEnableNSGLSurfaces);
169 if (!use_ns_gl_surfaces)
170 return false;
171
172 // Do not attempt this before 10.9. The power savings are not worth the
173 // stability risk and testing burden.
174 if (!base::mac::IsOSMavericksOrLater())
175 return false;
176
177 // If the NSView being attached to the NSOpenGLContext is not on the main
178 // monitor, then, due to an OS X bug, the IOSurface will be thrashed,
179 // resulting in hangs of 50 msec or more.
180 CGDirectDisplayID main_display = CGMainDisplayID();
181 NSScreen* screen = [[view window] screen];
182 NSDictionary* screen_description = [screen deviceDescription];
183 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"];
184 CGDirectDisplayID display_id = [screen_number unsignedIntValue];
185 if (display_id != main_display)
186 return false;
187
188 return true;
189 }
190
191 } // namespace ui
OLDNEW
« 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