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

Side by Side Diff: content/browser/compositor/io_surface_layer_mac.mm

Issue 490393002: Simplify IOSurface CoreAnimation code: Part 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Missed colon Created 6 years, 3 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/browser/renderer_host/compositing_iosurface_layer_mac.h" 5 #include "content/browser/compositor/io_surface_layer_mac.h"
6 6
7 #include <CoreFoundation/CoreFoundation.h> 7 #include <CoreFoundation/CoreFoundation.h>
8 #include <OpenGL/gl.h> 8 #include <OpenGL/CGLIOSurface.h>
9 #include <OpenGL/CGLRenderers.h>
10 #include <OpenGL/OpenGL.h>
9 11
10 #include "base/mac/mac_util.h" 12 #include "base/mac/mac_util.h"
11 #include "base/mac/sdk_forward_declarations.h" 13 #include "base/mac/sdk_forward_declarations.h"
12 #include "content/browser/renderer_host/render_widget_host_impl.h" 14 #include "content/browser/renderer_host/render_widget_host_impl.h"
13 #include "content/browser/renderer_host/render_widget_host_view_mac.h" 15 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
14 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
15 #include "content/browser/renderer_host/compositing_iosurface_mac.h"
16 #include "ui/base/cocoa/animation_utils.h" 16 #include "ui/base/cocoa/animation_utils.h"
17 #include "ui/gfx/size_conversions.h" 17 #include "ui/gfx/size_conversions.h"
18 #include "ui/gl/gpu_switching_manager.h" 18 #include "ui/gl/gpu_switching_manager.h"
19 19
20 // Convenience macro for checking errors in the below code.
21 #define CHECK_GL_ERROR() do { \
22 GLenum gl_error = glGetError(); \
23 LOG_IF(ERROR, gl_error != GL_NO_ERROR) << "GL Error: " << gl_error; \
24 } while (0)
25
20 //////////////////////////////////////////////////////////////////////////////// 26 ////////////////////////////////////////////////////////////////////////////////
21 // CompositingIOSurfaceLayerHelper 27 // IOSurfaceLayerHelper
22 28
23 namespace content { 29 namespace content {
24 30
25 CompositingIOSurfaceLayerHelper::CompositingIOSurfaceLayerHelper( 31 IOSurfaceLayerHelper::IOSurfaceLayerHelper(
26 CompositingIOSurfaceLayerClient* client, 32 IOSurfaceLayer* layer)
27 CompositingIOSurfaceLayer* layer) 33 : layer_(layer),
28 : client_(client),
29 layer_(layer),
30 needs_display_(false),
31 has_pending_frame_(false),
32 did_not_draw_counter_(0),
33 is_pumping_frames_(false),
34 timer_( 34 timer_(
35 FROM_HERE, 35 FROM_HERE,
36 base::TimeDelta::FromSeconds(1) / 6, 36 base::TimeDelta::FromSeconds(1) / 6,
37 this, 37 this,
38 &CompositingIOSurfaceLayerHelper::TimerFired) {} 38 &IOSurfaceLayerHelper::TimerFired) {}
39 39
40 CompositingIOSurfaceLayerHelper::~CompositingIOSurfaceLayerHelper() { 40 IOSurfaceLayerHelper::~IOSurfaceLayerHelper() {
41 }
42
43 void IOSurfaceLayerHelper::ResetTimer() {
44 timer_.Reset();
45 }
46
47 void IOSurfaceLayerHelper::TimerFired() {
48 [layer_ timerFired];
49 }
50
51 } // namespace content
52
53 ////////////////////////////////////////////////////////////////////////////////
54 // IOSurfaceLayer
55
56 @implementation IOSurfaceLayer
57
58 - (id)initWithClient:(content::IOSurfaceLayerClient*)client
59 withScaleFactor:(float)scale_factor {
60 if (self = [super init]) {
61 client_ = client;
62 helper_.reset(new content::IOSurfaceLayerHelper(self));
63 needs_display_ = false;
64 has_pending_frame_ = false;
65 did_not_draw_counter_ = 0;
66 is_pumping_frames_ = false;
67 io_surface_texture_ = 0;
68 io_surface_texture_dirty_ = false;
69 cgl_renderer_id_ = 0;
70
71 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
72 [self setAnchorPoint:CGPointMake(0, 0)];
73 // Setting contents gravity is necessary to prevent the layer from being
74 // scaled during dyanmic resizes (especially with devtools open).
75 [self setContentsGravity:kCAGravityTopLeft];
76 if ([self respondsToSelector:(@selector(setContentsScale:))])
77 [self setContentsScale:scale_factor];
78 }
79 return self;
80 }
81
82 - (void)dealloc {
83 DCHECK(!helper_ && !client_);
84 [super dealloc];
85 }
86
87 - (float)scaleFactor {
88 if ([self respondsToSelector:(@selector(contentsScale))])
ccameron 2014/08/27 02:26:26 The case of the extraneous colon.
89 return [self contentsScale];
90 return 1;
91 }
92
93 - (int)rendererID {
94 return cgl_renderer_id_;
95 }
96
97 - (void)timerFired {
98 [self displayIfNeededAndAck];
99 }
100
101 - (void)resetClient {
41 // Any acks that were waiting on this layer to draw will not occur, so ack 102 // Any acks that were waiting on this layer to draw will not occur, so ack
42 // them now to prevent blocking the renderer. 103 // them now to prevent blocking the renderer.
43 AckPendingFrame(true); 104 [self ackPendingFrame];
105 helper_.reset();
106 client_ = NULL;
44 } 107 }
45 108
46 void CompositingIOSurfaceLayerHelper::GotNewFrame() { 109 - (void)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id
110 withPixelSize:(gfx::Size)pixel_size
111 withScaleFactor:(float)scale_factor {
47 // A trace value of 2 indicates that there is a pending swap ack. See 112 // A trace value of 2 indicates that there is a pending swap ack. See
48 // canDrawInCGLContext for other value meanings. 113 // canDrawInCGLContext for other value meanings.
49 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 2); 114 TRACE_COUNTER_ID1("browser", "PendingSwapAck", self, 2);
50
51 has_pending_frame_ = true; 115 has_pending_frame_ = true;
52 needs_display_ = true; 116 needs_display_ = true;
53 timer_.Reset(); 117 helper_->ResetTimer();
118
119 // If this is a new IOSurface, open the IOSurface and mark that the
120 // GL texture needs to bind to the new surface.
121 if (!io_surface_ || io_surface_id != IOSurfaceGetID(io_surface_)) {
122 io_surface_.reset(IOSurfaceLookup(io_surface_id));
123 io_surface_texture_dirty_ = true;
124 if (!io_surface_) {
125 LOG(ERROR) << "Failed to open IOSurface for frame";
126 if (client_)
127 client_->IOSurfaceLayerHitError();
128 }
129 }
54 130
55 // If reqested, draw immediately and don't bother trying to use the 131 // If reqested, draw immediately and don't bother trying to use the
56 // isAsynchronous property to ensure smooth animation. If this is while 132 // isAsynchronous property to ensure smooth animation. If this is while
57 // frames are being pumped then ack and display immediately to get a 133 // frames are being pumped then ack and display immediately to get a
58 // correct-sized frame displayed as soon as possible. 134 // correct-sized frame displayed as soon as possible.
59 if (is_pumping_frames_ || client_->AcceleratedLayerShouldAckImmediately()) { 135 if (is_pumping_frames_ ||
60 SetNeedsDisplayAndDisplayAndAck(); 136 (client_ && client_->IOSurfaceLayerShouldAckImmediately())) {
137 [self setNeedsDisplayAndDisplayAndAck];
61 } else { 138 } else {
62 if (![layer_ isAsynchronous]) 139 if (![self isAsynchronous])
63 [layer_ setAsynchronous:YES]; 140 [self setAsynchronous:YES];
64 } 141 }
65 } 142 }
66 143
67 void CompositingIOSurfaceLayerHelper::SetNeedsDisplay() { 144 - (BOOL)canDrawInCGLContext:(CGLContextObj)glContext
68 needs_display_ = true; 145 pixelFormat:(CGLPixelFormatObj)pixelFormat
69 } 146 forLayerTime:(CFTimeInterval)timeInterval
70 147 displayTime:(const CVTimeStamp*)timeStamp {
71 bool CompositingIOSurfaceLayerHelper::CanDraw() {
72 // If we return NO 30 times in a row, switch to being synchronous to avoid 148 // If we return NO 30 times in a row, switch to being synchronous to avoid
73 // burning CPU cycles on this callback. 149 // burning CPU cycles on this callback.
74 if (needs_display_) { 150 if (needs_display_) {
75 did_not_draw_counter_ = 0; 151 did_not_draw_counter_ = 0;
76 } else { 152 } else {
77 did_not_draw_counter_ += 1; 153 did_not_draw_counter_ += 1;
78 if (did_not_draw_counter_ == 30) 154 if (did_not_draw_counter_ == 30)
79 [layer_ setAsynchronous:NO]; 155 [self setAsynchronous:NO];
80 } 156 }
81 157
82 // Add an instantaneous blip to the PendingSwapAck state to indicate 158 // Add an instantaneous blip to the PendingSwapAck state to indicate
83 // that CoreAnimation asked if a frame is ready. A blip up to to 3 (usually 159 // that CoreAnimation asked if a frame is ready. A blip up to to 3 (usually
84 // from 2, indicating that a swap ack is pending) indicates that we 160 // from 2, indicating that a swap ack is pending) indicates that we
85 // requested a draw. A blip up to 1 (usually from 0, indicating there is no 161 // requested a draw. A blip up to 1 (usually from 0, indicating there is no
86 // pending swap ack) indicates that we did not request a draw. This would 162 // pending swap ack) indicates that we did not request a draw. This would
87 // be more natural to do with a tracing pseudo-thread 163 // be more natural to do with a tracing pseudo-thread
88 // http://crbug.com/366300 164 // http://crbug.com/366300
89 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, needs_display_ ? 3 : 1); 165 TRACE_COUNTER_ID1("browser", "PendingSwapAck", self, needs_display_ ? 3 : 1);
90 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 166 TRACE_COUNTER_ID1("browser", "PendingSwapAck", self,
91 has_pending_frame_ ? 2 : 0); 167 has_pending_frame_ ? 2 : 0);
92 168
93 return needs_display_; 169 return needs_display_;
94 } 170 }
95 171
96 void CompositingIOSurfaceLayerHelper::DidDraw(bool success) { 172 - (void)ackPendingFrame {
97 needs_display_ = false;
98 AckPendingFrame(success);
99 }
100
101 void CompositingIOSurfaceLayerHelper::AckPendingFrame(bool success) {
102 if (!has_pending_frame_) 173 if (!has_pending_frame_)
103 return; 174 return;
104 has_pending_frame_ = false; 175 has_pending_frame_ = false;
105 if (success) 176 if (client_)
106 client_->AcceleratedLayerDidDrawFrame(); 177 client_->IOSurfaceLayerDidDrawFrame();
107 else
108 client_->AcceleratedLayerHitError();
109 // A trace value of 0 indicates that there is no longer a pending swap ack. 178 // A trace value of 0 indicates that there is no longer a pending swap ack.
110 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 0); 179 TRACE_COUNTER_ID1("browser", "PendingSwapAck", self, 0);
111 } 180 }
112 181
113 void CompositingIOSurfaceLayerHelper::SetNeedsDisplayAndDisplayAndAck() { 182 - (void)setNeedsDisplayAndDisplayAndAck {
114 // Drawing using setNeedsDisplay and displayIfNeeded will result in 183 // Drawing using setNeedsDisplay and displayIfNeeded will result in
115 // subsequent canDrawInCGLContext callbacks getting dropped, and jerky 184 // subsequent canDrawInCGLContext callbacks getting dropped, and jerky
116 // animation. Disable asynchronous drawing before issuing these calls as a 185 // animation. Disable asynchronous drawing before issuing these calls as a
117 // workaround. 186 // workaround.
118 // http://crbug.com/395827 187 // http://crbug.com/395827
119 if ([layer_ isAsynchronous]) 188 if ([self isAsynchronous])
120 [layer_ setAsynchronous:NO]; 189 [self setAsynchronous:NO];
121 190
122 [layer_ setNeedsDisplay]; 191 [self setNeedsDisplay];
123 DisplayIfNeededAndAck(); 192 [self displayIfNeededAndAck];
124 } 193 }
125 194
126 void CompositingIOSurfaceLayerHelper::DisplayIfNeededAndAck() { 195 - (void)displayIfNeededAndAck {
127 if (!needs_display_) 196 if (!needs_display_)
128 return; 197 return;
129 198
130 // As in SetNeedsDisplayAndDisplayAndAck, disable asynchronous drawing before 199 // As in SetNeedsDisplayAndDisplayAndAck, disable asynchronous drawing before
131 // issuing displayIfNeeded. 200 // issuing displayIfNeeded.
132 // http://crbug.com/395827 201 // http://crbug.com/395827
133 if ([layer_ isAsynchronous]) 202 if ([self isAsynchronous])
134 [layer_ setAsynchronous:NO]; 203 [self setAsynchronous:NO];
135 204
136 // Do not bother drawing while pumping new frames -- wait until the waiting 205 // Do not bother drawing while pumping new frames -- wait until the waiting
137 // block ends to draw any of the new frames. 206 // block ends to draw any of the new frames.
138 if (!is_pumping_frames_) 207 if (!is_pumping_frames_)
139 [layer_ displayIfNeeded]; 208 [self displayIfNeeded];
140 209
141 // Calls to setNeedsDisplay can sometimes be ignored, especially if issued 210 // Calls to setNeedsDisplay can sometimes be ignored, especially if issued
142 // rapidly (e.g, with vsync off). This is unacceptable because the failure 211 // rapidly (e.g, with vsync off). This is unacceptable because the failure
143 // to ack a single frame will hang the renderer. Ensure that the renderer 212 // to ack a single frame will hang the renderer. Ensure that the renderer
144 // not be blocked by lying and claiming that we drew the frame. 213 // not be blocked by lying and claiming that we drew the frame.
145 AckPendingFrame(true); 214 [self ackPendingFrame];
146 } 215 }
147 216
148 void CompositingIOSurfaceLayerHelper::TimerFired() { 217 - (void)beginPumpingFrames {
149 SetNeedsDisplayAndDisplayAndAck();
150 }
151
152 void CompositingIOSurfaceLayerHelper::BeginPumpingFrames() {
153 is_pumping_frames_ = true; 218 is_pumping_frames_ = true;
154 } 219 }
155 220
156 void CompositingIOSurfaceLayerHelper::EndPumpingFrames() { 221 - (void)endPumpingFrames {
157 is_pumping_frames_ = false; 222 is_pumping_frames_ = false;
158 DisplayIfNeededAndAck(); 223 [self displayIfNeededAndAck];
159 }
160
161 } // namespace content
162
163 ////////////////////////////////////////////////////////////////////////////////
164 // CompositingIOSurfaceLayer
165
166 @implementation CompositingIOSurfaceLayer
167
168 - (content::CompositingIOSurfaceMac*)iosurface {
169 return iosurface_.get();
170 }
171
172 - (content::CompositingIOSurfaceContext*)context {
173 return context_.get();
174 }
175
176 - (id)initWithIOSurface:(scoped_refptr<content::CompositingIOSurfaceMac>)
177 iosurface
178 withScaleFactor:(float)scale_factor
179 withClient:(content::CompositingIOSurfaceLayerClient*)client {
180 DCHECK(iosurface);
181 if (self = [super init]) {
182 helper_.reset(new content::CompositingIOSurfaceLayerHelper(client, self));
183
184 iosurface_ = iosurface;
185 context_ = content::CompositingIOSurfaceContext::Get(
186 content::CompositingIOSurfaceContext::kCALayerContextWindowNumber);
187 if (!context_) {
188 LOG(ERROR) << "Failed create CompositingIOSurfaceContext";
189 [self resetClient];
190 [self release];
191 return nil;
192 }
193
194 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
195 [self setAnchorPoint:CGPointMake(0, 0)];
196 // Setting contents gravity is necessary to prevent the layer from being
197 // scaled during dyanmic resizes (especially with devtools open).
198 [self setContentsGravity:kCAGravityTopLeft];
199 if ([self respondsToSelector:(@selector(setContentsScale:))]) {
200 [self setContentsScale:scale_factor];
201 }
202 }
203 return self;
204 }
205
206 - (void)dealloc {
207 DCHECK(!helper_);
208 [super dealloc];
209 }
210
211 - (void)resetClient {
212 helper_.reset();
213 }
214
215 - (void)gotNewFrame {
216 helper_->GotNewFrame();
217 }
218
219 - (void)setNeedsDisplayAndDisplayAndAck {
220 helper_->SetNeedsDisplayAndDisplayAndAck();
221 }
222
223 - (void)displayIfNeededAndAck {
224 helper_->DisplayIfNeededAndAck();
225 }
226
227 - (void)beginPumpingFrames {
228 helper_->BeginPumpingFrames();
229 }
230
231 - (void)endPumpingFrames {
232 helper_->EndPumpingFrames();
233 } 224 }
234 225
235 // The remaining methods implement the CAOpenGLLayer interface. 226 // The remaining methods implement the CAOpenGLLayer interface.
236 227
237 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { 228 - (void)releaseCGLContext:(CGLContextObj)glContext {
238 if (!context_) 229 io_surface_texture_ = 0;
239 return [super copyCGLPixelFormatForDisplayMask:mask]; 230 cgl_renderer_id_ = 0;
240 return CGLRetainPixelFormat(CGLGetPixelFormat(context_->cgl_context()));
241 }
242
243 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
244 if (!context_)
245 return [super copyCGLContextForPixelFormat:pixelFormat];
246 return CGLRetainContext(context_->cgl_context());
247 } 231 }
248 232
249 - (void)setNeedsDisplay { 233 - (void)setNeedsDisplay {
250 if (helper_) 234 needs_display_ = true;
251 helper_->SetNeedsDisplay();
252 [super setNeedsDisplay]; 235 [super setNeedsDisplay];
253 } 236 }
254 237
255 - (BOOL)canDrawInCGLContext:(CGLContextObj)glContext
256 pixelFormat:(CGLPixelFormatObj)pixelFormat
257 forLayerTime:(CFTimeInterval)timeInterval
258 displayTime:(const CVTimeStamp*)timeStamp {
259 if (helper_)
260 return helper_->CanDraw();
261 return NO;
262 }
263
264 - (void)drawInCGLContext:(CGLContextObj)glContext 238 - (void)drawInCGLContext:(CGLContextObj)glContext
265 pixelFormat:(CGLPixelFormatObj)pixelFormat 239 pixelFormat:(CGLPixelFormatObj)pixelFormat
266 forLayerTime:(CFTimeInterval)timeInterval 240 forLayerTime:(CFTimeInterval)timeInterval
267 displayTime:(const CVTimeStamp*)timeStamp { 241 displayTime:(const CVTimeStamp*)timeStamp {
268 TRACE_EVENT0("browser", "CompositingIOSurfaceLayer::drawInCGLContext"); 242 TRACE_EVENT0("browser", "IOSurfaceLayer::drawInCGLContext");
269 243
270 if (!iosurface_->HasIOSurface() || context_->cgl_context() != glContext) { 244 // Create the texture if it has not been created in this context yet.
245 if (!io_surface_texture_) {
246 glGenTextures(1, &io_surface_texture_);
247 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, io_surface_texture_);
248 glTexParameteri(
249 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
250 glTexParameteri(
251 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
252 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
253 io_surface_texture_dirty_ = true;
254 }
255
256 // Associate the IOSurface with this texture, if the underlying IOSurface has
257 // been changed.
258 if (io_surface_texture_dirty_ && io_surface_) {
259 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, io_surface_texture_);
260 CGLError cgl_error = CGLTexImageIOSurface2D(
261 glContext,
262 GL_TEXTURE_RECTANGLE_ARB,
263 GL_RGBA,
264 IOSurfaceGetWidth(io_surface_),
265 IOSurfaceGetHeight(io_surface_),
266 GL_BGRA,
267 GL_UNSIGNED_INT_8_8_8_8_REV,
268 io_surface_.get(),
269 0 /* plane */);
270 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
271 if (cgl_error != kCGLNoError) {
272 LOG(ERROR) << "CGLTexImageIOSurface2D failed with " << cgl_error;
273 glDeleteTextures(1, &io_surface_texture_);
274 io_surface_texture_ = 0;
275 if (client_)
276 client_->IOSurfaceLayerHitError();
277 }
278 } else if (io_surface_texture_) {
279 glDeleteTextures(1, &io_surface_texture_);
280 io_surface_texture_ = 0;
281 }
282
283 // Fill the viewport with the texture. The viewport must be smaller or equal
284 // than the texture, because it is resized as frames arrive.
285 if (io_surface_texture_) {
286 GLint viewport[4];
287 glGetIntegerv(GL_VIEWPORT, viewport);
288 DCHECK_LE(viewport[2], static_cast<GLint>(IOSurfaceGetWidth(io_surface_)));
289 DCHECK_LE(viewport[3], static_cast<GLint>(IOSurfaceGetHeight(io_surface_)));
290
291 glMatrixMode(GL_PROJECTION);
292 glLoadIdentity();
293 glOrtho(0, 1, 0, 1, -1, 1);
294 glMatrixMode(GL_MODELVIEW);
295 glLoadIdentity();
296
297 glEnable(GL_TEXTURE_RECTANGLE_ARB);
298 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, io_surface_texture_);
299 glBegin(GL_QUADS);
300 glTexCoord2f(0, 0);
301 glVertex2f(0, 0);
302 glTexCoord2f(viewport[2], 0);
303 glVertex2f(1, 0);
304 glTexCoord2f(viewport[2], viewport[3]);
305 glVertex2f(1, 1);
306 glTexCoord2f(0, viewport[3]);
307 glVertex2f(0, 1);
308 glEnd();
309 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
310 glDisable(GL_TEXTURE_RECTANGLE_ARB);
311
312 // Workaround for issue 158469. Issue a dummy draw call with
313 // io_surface_texture_ not bound to a texture, in order to shake all
314 // references to the IOSurface out of the driver.
315 glBegin(GL_TRIANGLES);
316 glEnd();
317 } else {
271 glClearColor(1, 1, 1, 1); 318 glClearColor(1, 1, 1, 1);
272 glClear(GL_COLOR_BUFFER_BIT); 319 glClear(GL_COLOR_BUFFER_BIT);
273 return;
274 } 320 }
275 321
276 // The correct viewport to cover the layer will be set up by the caller. 322 // Query the current GL renderer to send back to the GPU process.
277 // Transform this into a window size for DrawIOSurface, where it will be 323 {
278 // transformed back into this viewport. 324 CGLError cgl_error = CGLGetParameter(
279 GLint viewport[4]; 325 glContext, kCGLCPCurrentRendererID, &cgl_renderer_id_);
280 glGetIntegerv(GL_VIEWPORT, viewport); 326 if (cgl_error == kCGLNoError) {
281 gfx::Rect window_rect(viewport[0], viewport[1], viewport[2], viewport[3]); 327 cgl_renderer_id_ &= kCGLRendererIDMatchingMask;
282 float window_scale_factor = 1.f; 328 } else {
283 if ([self respondsToSelector:(@selector(contentsScale))]) 329 LOG(ERROR) << "CGLGetParameter for kCGLCPCurrentRendererID failed with "
284 window_scale_factor = [self contentsScale]; 330 << cgl_error;
285 window_rect = ToNearestRect( 331 cgl_renderer_id_ = 0;
286 gfx::ScaleRect(window_rect, 1.f/window_scale_factor)); 332 }
333 }
287 334
288 bool draw_succeeded = iosurface_->DrawIOSurface( 335 // If we hit any errors, tell the client.
289 context_, window_rect, window_scale_factor); 336 while (GLenum gl_error = glGetError()) {
337 LOG(ERROR) << "Hit GL error " << gl_error;
338 if (client_)
339 client_->IOSurfaceLayerHitError();
340 }
290 341
291 if (helper_) 342 needs_display_ = false;
292 helper_->DidDraw(draw_succeeded);
293
294 [super drawInCGLContext:glContext 343 [super drawInCGLContext:glContext
295 pixelFormat:pixelFormat 344 pixelFormat:pixelFormat
296 forLayerTime:timeInterval 345 forLayerTime:timeInterval
297 displayTime:timeStamp]; 346 displayTime:timeStamp];
347
348 [self ackPendingFrame];
298 } 349 }
299 350
300 @end 351 @end
OLDNEW
« no previous file with comments | « content/browser/compositor/io_surface_layer_mac.h ('k') | content/browser/compositor/software_layer_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698