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

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

Issue 511923004: Simplify IOSurface CoreAnimation code: Part 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use accessors 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/gl.h>
9 9
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
11 #include "base/mac/sdk_forward_declarations.h" 11 #include "base/mac/sdk_forward_declarations.h"
12 #include "content/browser/renderer_host/render_widget_host_impl.h" 12 #include "content/browser/renderer_host/render_widget_host_impl.h"
13 #include "content/browser/renderer_host/render_widget_host_view_mac.h" 13 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
14 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" 14 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
15 #include "content/browser/renderer_host/compositing_iosurface_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 //////////////////////////////////////////////////////////////////////////////// 20 ////////////////////////////////////////////////////////////////////////////////
21 // CompositingIOSurfaceLayerHelper 21 // IOSurfaceLayerHelper
22 22
23 namespace content { 23 namespace content {
24 24
25 CompositingIOSurfaceLayerHelper::CompositingIOSurfaceLayerHelper( 25 IOSurfaceLayerHelper::IOSurfaceLayerHelper(
26 CompositingIOSurfaceLayerClient* client, 26 IOSurfaceLayerClient* client,
27 CompositingIOSurfaceLayer* layer) 27 IOSurfaceLayer* layer)
28 : client_(client), 28 : client_(client),
29 layer_(layer), 29 layer_(layer),
30 needs_display_(false), 30 needs_display_(false),
31 has_pending_frame_(false), 31 has_pending_frame_(false),
32 did_not_draw_counter_(0), 32 did_not_draw_counter_(0),
33 is_pumping_frames_(false), 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 // Any acks that were waiting on this layer to draw will not occur, so ack 41 // Any acks that were waiting on this layer to draw will not occur, so ack
42 // them now to prevent blocking the renderer. 42 // them now to prevent blocking the renderer.
43 AckPendingFrame(true); 43 AckPendingFrame(true);
44 } 44 }
45 45
46 void CompositingIOSurfaceLayerHelper::GotNewFrame() { 46 void IOSurfaceLayerHelper::GotNewFrame() {
47 // A trace value of 2 indicates that there is a pending swap ack. See 47 // A trace value of 2 indicates that there is a pending swap ack. See
48 // canDrawInCGLContext for other value meanings. 48 // canDrawInCGLContext for other value meanings.
49 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 2); 49 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 2);
50 50
51 has_pending_frame_ = true; 51 has_pending_frame_ = true;
52 needs_display_ = true; 52 needs_display_ = true;
53 timer_.Reset(); 53 timer_.Reset();
54 54
55 // If reqested, draw immediately and don't bother trying to use the 55 // If reqested, draw immediately and don't bother trying to use the
56 // isAsynchronous property to ensure smooth animation. If this is while 56 // isAsynchronous property to ensure smooth animation. If this is while
57 // frames are being pumped then ack and display immediately to get a 57 // frames are being pumped then ack and display immediately to get a
58 // correct-sized frame displayed as soon as possible. 58 // correct-sized frame displayed as soon as possible.
59 if (is_pumping_frames_ || client_->AcceleratedLayerShouldAckImmediately()) { 59 if (is_pumping_frames_ || client_->IOSurfaceLayerShouldAckImmediately()) {
60 SetNeedsDisplayAndDisplayAndAck(); 60 SetNeedsDisplayAndDisplayAndAck();
61 } else { 61 } else {
62 if (![layer_ isAsynchronous]) 62 if (![layer_ isAsynchronous])
63 [layer_ setAsynchronous:YES]; 63 [layer_ setAsynchronous:YES];
64 } 64 }
65 } 65 }
66 66
67 void CompositingIOSurfaceLayerHelper::SetNeedsDisplay() { 67 void IOSurfaceLayerHelper::SetNeedsDisplay() {
68 needs_display_ = true; 68 needs_display_ = true;
69 } 69 }
70 70
71 bool CompositingIOSurfaceLayerHelper::CanDraw() { 71 bool IOSurfaceLayerHelper::CanDraw() {
72 // If we return NO 30 times in a row, switch to being synchronous to avoid 72 // If we return NO 30 times in a row, switch to being synchronous to avoid
73 // burning CPU cycles on this callback. 73 // burning CPU cycles on this callback.
74 if (needs_display_) { 74 if (needs_display_) {
75 did_not_draw_counter_ = 0; 75 did_not_draw_counter_ = 0;
76 } else { 76 } else {
77 did_not_draw_counter_ += 1; 77 did_not_draw_counter_ += 1;
78 if (did_not_draw_counter_ == 30) 78 if (did_not_draw_counter_ == 30)
79 [layer_ setAsynchronous:NO]; 79 [layer_ setAsynchronous:NO];
80 } 80 }
81 81
82 // Add an instantaneous blip to the PendingSwapAck state to indicate 82 // 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 83 // 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 84 // 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 85 // 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 86 // pending swap ack) indicates that we did not request a draw. This would
87 // be more natural to do with a tracing pseudo-thread 87 // be more natural to do with a tracing pseudo-thread
88 // http://crbug.com/366300 88 // http://crbug.com/366300
89 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, needs_display_ ? 3 : 1); 89 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, needs_display_ ? 3 : 1);
90 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 90 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this,
91 has_pending_frame_ ? 2 : 0); 91 has_pending_frame_ ? 2 : 0);
92 92
93 return needs_display_; 93 return needs_display_;
94 } 94 }
95 95
96 void CompositingIOSurfaceLayerHelper::DidDraw(bool success) { 96 void IOSurfaceLayerHelper::DidDraw(bool success) {
97 needs_display_ = false; 97 needs_display_ = false;
98 AckPendingFrame(success); 98 AckPendingFrame(success);
99 } 99 }
100 100
101 void CompositingIOSurfaceLayerHelper::AckPendingFrame(bool success) { 101 void IOSurfaceLayerHelper::AckPendingFrame(bool success) {
102 if (!has_pending_frame_) 102 if (!has_pending_frame_)
103 return; 103 return;
104 has_pending_frame_ = false; 104 has_pending_frame_ = false;
105 if (success) 105 if (success)
106 client_->AcceleratedLayerDidDrawFrame(); 106 client_->IOSurfaceLayerDidDrawFrame();
107 else 107 else
108 client_->AcceleratedLayerHitError(); 108 client_->IOSurfaceLayerHitError();
109 // A trace value of 0 indicates that there is no longer a pending swap ack. 109 // A trace value of 0 indicates that there is no longer a pending swap ack.
110 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 0); 110 TRACE_COUNTER_ID1("browser", "PendingSwapAck", this, 0);
111 } 111 }
112 112
113 void CompositingIOSurfaceLayerHelper::SetNeedsDisplayAndDisplayAndAck() { 113 void IOSurfaceLayerHelper::SetNeedsDisplayAndDisplayAndAck() {
114 // Drawing using setNeedsDisplay and displayIfNeeded will result in 114 // Drawing using setNeedsDisplay and displayIfNeeded will result in
115 // subsequent canDrawInCGLContext callbacks getting dropped, and jerky 115 // subsequent canDrawInCGLContext callbacks getting dropped, and jerky
116 // animation. Disable asynchronous drawing before issuing these calls as a 116 // animation. Disable asynchronous drawing before issuing these calls as a
117 // workaround. 117 // workaround.
118 // http://crbug.com/395827 118 // http://crbug.com/395827
119 if ([layer_ isAsynchronous]) 119 if ([layer_ isAsynchronous])
120 [layer_ setAsynchronous:NO]; 120 [layer_ setAsynchronous:NO];
121 121
122 [layer_ setNeedsDisplay]; 122 [layer_ setNeedsDisplay];
123 DisplayIfNeededAndAck(); 123 DisplayIfNeededAndAck();
124 } 124 }
125 125
126 void CompositingIOSurfaceLayerHelper::DisplayIfNeededAndAck() { 126 void IOSurfaceLayerHelper::DisplayIfNeededAndAck() {
127 if (!needs_display_) 127 if (!needs_display_)
128 return; 128 return;
129 129
130 // As in SetNeedsDisplayAndDisplayAndAck, disable asynchronous drawing before 130 // As in SetNeedsDisplayAndDisplayAndAck, disable asynchronous drawing before
131 // issuing displayIfNeeded. 131 // issuing displayIfNeeded.
132 // http://crbug.com/395827 132 // http://crbug.com/395827
133 if ([layer_ isAsynchronous]) 133 if ([layer_ isAsynchronous])
134 [layer_ setAsynchronous:NO]; 134 [layer_ setAsynchronous:NO];
135 135
136 // Do not bother drawing while pumping new frames -- wait until the waiting 136 // Do not bother drawing while pumping new frames -- wait until the waiting
137 // block ends to draw any of the new frames. 137 // block ends to draw any of the new frames.
138 if (!is_pumping_frames_) 138 if (!is_pumping_frames_)
139 [layer_ displayIfNeeded]; 139 [layer_ displayIfNeeded];
140 140
141 // Calls to setNeedsDisplay can sometimes be ignored, especially if issued 141 // Calls to setNeedsDisplay can sometimes be ignored, especially if issued
142 // rapidly (e.g, with vsync off). This is unacceptable because the failure 142 // 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 143 // 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. 144 // not be blocked by lying and claiming that we drew the frame.
145 AckPendingFrame(true); 145 AckPendingFrame(true);
146 } 146 }
147 147
148 void CompositingIOSurfaceLayerHelper::TimerFired() { 148 void IOSurfaceLayerHelper::TimerFired() {
149 SetNeedsDisplayAndDisplayAndAck(); 149 SetNeedsDisplayAndDisplayAndAck();
150 } 150 }
151 151
152 void CompositingIOSurfaceLayerHelper::BeginPumpingFrames() { 152 void IOSurfaceLayerHelper::BeginPumpingFrames() {
153 is_pumping_frames_ = true; 153 is_pumping_frames_ = true;
154 } 154 }
155 155
156 void CompositingIOSurfaceLayerHelper::EndPumpingFrames() { 156 void IOSurfaceLayerHelper::EndPumpingFrames() {
157 is_pumping_frames_ = false; 157 is_pumping_frames_ = false;
158 DisplayIfNeededAndAck(); 158 DisplayIfNeededAndAck();
159 } 159 }
160 160
161 } // namespace content 161 } // namespace content
162 162
163 //////////////////////////////////////////////////////////////////////////////// 163 ////////////////////////////////////////////////////////////////////////////////
164 // CompositingIOSurfaceLayer 164 // IOSurfaceLayer
165 165
166 @implementation CompositingIOSurfaceLayer 166 @implementation IOSurfaceLayer
167 167
168 - (content::CompositingIOSurfaceMac*)iosurface { 168 - (content::CompositingIOSurfaceMac*)iosurface {
169 return iosurface_.get(); 169 return iosurface_.get();
170 } 170 }
171 171
172 - (content::CompositingIOSurfaceContext*)context { 172 - (content::CompositingIOSurfaceContext*)context {
173 return context_.get(); 173 return context_.get();
174 } 174 }
175 175
176 - (id)initWithIOSurface:(scoped_refptr<content::CompositingIOSurfaceMac>) 176 - (id)initWithClient:(content::IOSurfaceLayerClient*)client
177 iosurface 177 withScaleFactor:(float)scale_factor {
178 withScaleFactor:(float)scale_factor
179 withClient:(content::CompositingIOSurfaceLayerClient*)client {
180 DCHECK(iosurface);
181 if (self = [super init]) { 178 if (self = [super init]) {
182 helper_.reset(new content::CompositingIOSurfaceLayerHelper(client, self)); 179 helper_.reset(new content::IOSurfaceLayerHelper(client, self));
183 180
184 iosurface_ = iosurface; 181 iosurface_ = content::CompositingIOSurfaceMac::Create();
185 context_ = content::CompositingIOSurfaceContext::Get( 182 context_ = content::CompositingIOSurfaceContext::Get(
186 content::CompositingIOSurfaceContext::kCALayerContextWindowNumber); 183 content::CompositingIOSurfaceContext::kCALayerContextWindowNumber);
187 if (!context_) { 184 if (!iosurface_ || !context_) {
188 LOG(ERROR) << "Failed create CompositingIOSurfaceContext"; 185 LOG(ERROR) << "Failed create CompositingIOSurface or context";
189 [self resetClient]; 186 [self resetClient];
190 [self release]; 187 [self release];
191 return nil; 188 return nil;
192 } 189 }
193 190
194 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; 191 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
195 [self setAnchorPoint:CGPointMake(0, 0)]; 192 [self setAnchorPoint:CGPointMake(0, 0)];
196 // Setting contents gravity is necessary to prevent the layer from being 193 // Setting contents gravity is necessary to prevent the layer from being
197 // scaled during dyanmic resizes (especially with devtools open). 194 // scaled during dyanmic resizes (especially with devtools open).
198 [self setContentsGravity:kCAGravityTopLeft]; 195 [self setContentsGravity:kCAGravityTopLeft];
199 if ([self respondsToSelector:(@selector(setContentsScale:))]) { 196 if ([self respondsToSelector:(@selector(setContentsScale:))]) {
200 [self setContentsScale:scale_factor]; 197 [self setContentsScale:scale_factor];
201 } 198 }
202 } 199 }
203 return self; 200 return self;
204 } 201 }
205 202
206 - (void)dealloc { 203 - (void)dealloc {
207 DCHECK(!helper_); 204 DCHECK(!helper_);
208 [super dealloc]; 205 [super dealloc];
209 } 206 }
210 207
208 - (bool)gotFrameWithIOSurface:(IOSurfaceID)io_surface_id
209 withPixelSize:(gfx::Size)pixel_size
210 withScaleFactor:(float)scale_factor {
211 bool result = true;
212 gfx::ScopedCGLSetCurrentContext scoped_set_current_context(
213 context_->cgl_context());
214 result = iosurface_->SetIOSurfaceWithContextCurrent(
215 context_, io_surface_id, pixel_size, scale_factor);
216 return result;
217 }
218
219 - (void)poisonContextAndSharegroup {
220 context_->PoisonContextAndSharegroup();
221 }
222
223 - (bool)hasBeenPoisoned {
224 return context_->HasBeenPoisoned();
225 }
226
227 - (float)scaleFactor {
228 return iosurface_->scale_factor();
229 }
230
231 - (int)rendererID {
232 return iosurface_->GetRendererID();
233 }
234
211 - (void)resetClient { 235 - (void)resetClient {
212 helper_.reset(); 236 helper_.reset();
213 } 237 }
214 238
215 - (void)gotNewFrame { 239 - (void)gotNewFrame {
216 helper_->GotNewFrame(); 240 helper_->GotNewFrame();
217 } 241 }
218 242
219 - (void)setNeedsDisplayAndDisplayAndAck { 243 - (void)setNeedsDisplayAndDisplayAndAck {
220 helper_->SetNeedsDisplayAndDisplayAndAck(); 244 helper_->SetNeedsDisplayAndDisplayAndAck();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 displayTime:(const CVTimeStamp*)timeStamp { 282 displayTime:(const CVTimeStamp*)timeStamp {
259 if (helper_) 283 if (helper_)
260 return helper_->CanDraw(); 284 return helper_->CanDraw();
261 return NO; 285 return NO;
262 } 286 }
263 287
264 - (void)drawInCGLContext:(CGLContextObj)glContext 288 - (void)drawInCGLContext:(CGLContextObj)glContext
265 pixelFormat:(CGLPixelFormatObj)pixelFormat 289 pixelFormat:(CGLPixelFormatObj)pixelFormat
266 forLayerTime:(CFTimeInterval)timeInterval 290 forLayerTime:(CFTimeInterval)timeInterval
267 displayTime:(const CVTimeStamp*)timeStamp { 291 displayTime:(const CVTimeStamp*)timeStamp {
268 TRACE_EVENT0("browser", "CompositingIOSurfaceLayer::drawInCGLContext"); 292 TRACE_EVENT0("browser", "IOSurfaceLayer::drawInCGLContext");
269 293
270 if (!iosurface_->HasIOSurface() || context_->cgl_context() != glContext) { 294 if (!iosurface_->HasIOSurface() || context_->cgl_context() != glContext) {
271 glClearColor(1, 1, 1, 1); 295 glClearColor(1, 1, 1, 1);
272 glClear(GL_COLOR_BUFFER_BIT); 296 glClear(GL_COLOR_BUFFER_BIT);
273 return; 297 return;
274 } 298 }
275 299
276 // The correct viewport to cover the layer will be set up by the caller. 300 // The correct viewport to cover the layer will be set up by the caller.
277 // Transform this into a window size for DrawIOSurface, where it will be 301 // Transform this into a window size for DrawIOSurface, where it will be
278 // transformed back into this viewport. 302 // transformed back into this viewport.
(...skipping 12 matching lines...) Expand all
291 if (helper_) 315 if (helper_)
292 helper_->DidDraw(draw_succeeded); 316 helper_->DidDraw(draw_succeeded);
293 317
294 [super drawInCGLContext:glContext 318 [super drawInCGLContext:glContext
295 pixelFormat:pixelFormat 319 pixelFormat:pixelFormat
296 forLayerTime:timeInterval 320 forLayerTime:timeInterval
297 displayTime:timeStamp]; 321 displayTime:timeStamp];
298 } 322 }
299 323
300 @end 324 @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