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

Side by Side Diff: content/common/gpu/image_transport_surface_calayer_mac.mm

Issue 636003002: Clean up GPU back-pressure with remote CALayers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: O(1) more compile issue Created 6 years, 2 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/common/gpu/image_transport_surface_calayer_mac.h" 5 #include "content/common/gpu/image_transport_surface_calayer_mac.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/mac/sdk_forward_declarations.h" 8 #include "base/mac/sdk_forward_declarations.h"
9 #include "content/common/gpu/surface_handle_types_mac.h" 9 #include "content/common/gpu/surface_handle_types_mac.h"
10 #include "ui/base/cocoa/animation_utils.h" 10 #include "ui/base/cocoa/animation_utils.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 @end 84 @end
85 85
86 namespace content { 86 namespace content {
87 87
88 CALayerStorageProvider::CALayerStorageProvider( 88 CALayerStorageProvider::CALayerStorageProvider(
89 ImageTransportSurfaceFBO* transport_surface) 89 ImageTransportSurfaceFBO* transport_surface)
90 : transport_surface_(transport_surface), 90 : transport_surface_(transport_surface),
91 gpu_vsync_disabled_(CommandLine::ForCurrentProcess()->HasSwitch( 91 gpu_vsync_disabled_(CommandLine::ForCurrentProcess()->HasSwitch(
92 switches::kDisableGpuVsync)), 92 switches::kDisableGpuVsync)),
93 throttling_disabled_(false),
93 has_pending_draw_(false), 94 has_pending_draw_(false),
94 can_draw_returned_false_count_(0), 95 can_draw_returned_false_count_(0),
95 fbo_texture_(0), 96 fbo_texture_(0),
96 fbo_scale_factor_(1), 97 fbo_scale_factor_(1),
97 weak_factory_(this) {} 98 pending_draw_weak_factory_(this) {}
98 99
99 CALayerStorageProvider::~CALayerStorageProvider() { 100 CALayerStorageProvider::~CALayerStorageProvider() {
100 } 101 }
101 102
102 gfx::Size CALayerStorageProvider::GetRoundedSize(gfx::Size size) { 103 gfx::Size CALayerStorageProvider::GetRoundedSize(gfx::Size size) {
103 return size; 104 return size;
104 } 105 }
105 106
106 bool CALayerStorageProvider::AllocateColorBufferStorage( 107 bool CALayerStorageProvider::AllocateColorBufferStorage(
107 CGLContextObj context, GLuint texture, 108 CGLContextObj context, GLuint texture,
(...skipping 26 matching lines...) Expand all
134 // Set the parameters that will be used to allocate the CALayer to draw the 135 // Set the parameters that will be used to allocate the CALayer to draw the
135 // texture into. 136 // texture into.
136 share_group_context_.reset(CGLRetainContext(context)); 137 share_group_context_.reset(CGLRetainContext(context));
137 fbo_texture_ = texture; 138 fbo_texture_ = texture;
138 fbo_pixel_size_ = pixel_size; 139 fbo_pixel_size_ = pixel_size;
139 fbo_scale_factor_ = scale_factor; 140 fbo_scale_factor_ = scale_factor;
140 return true; 141 return true;
141 } 142 }
142 143
143 void CALayerStorageProvider::FreeColorBufferStorage() { 144 void CALayerStorageProvider::FreeColorBufferStorage() {
144 // We shouldn't be asked to free a texture when we still have yet to draw it.
145 DCHECK(!has_pending_draw_);
146 has_pending_draw_ = false;
147 can_draw_returned_false_count_ = 0;
148
149 // Note that |context_| still holds a reference to |layer_|, and will until 145 // Note that |context_| still holds a reference to |layer_|, and will until
150 // a new frame is swapped in. 146 // a new frame is swapped in.
151 [layer_ displayIfNeeded];
152 [layer_ resetStorageProvider]; 147 [layer_ resetStorageProvider];
153 layer_.reset(); 148 layer_.reset();
154 149
155 share_group_context_.reset(); 150 share_group_context_.reset();
156 fbo_texture_ = 0; 151 fbo_texture_ = 0;
157 fbo_pixel_size_ = gfx::Size(); 152 fbo_pixel_size_ = gfx::Size();
153 can_draw_returned_false_count_ = 0;
158 } 154 }
159 155
160 void CALayerStorageProvider::SwapBuffers( 156 void CALayerStorageProvider::SwapBuffers(
161 const gfx::Size& size, float scale_factor) { 157 const gfx::Size& size, float scale_factor) {
162 DCHECK(!has_pending_draw_); 158 DCHECK(!has_pending_draw_);
163 has_pending_draw_ = true; 159 has_pending_draw_ = true;
164 160
165 // Allocate a CAContext to use to transport the CALayer to the browser 161 // Allocate a CAContext to use to transport the CALayer to the browser
166 // process. 162 // process.
167 if (!context_) { 163 if (!context_) {
(...skipping 10 matching lines...) Expand all
178 gfx::Size dip_size(gfx::ToFlooredSize(gfx::ScaleSize( 174 gfx::Size dip_size(gfx::ToFlooredSize(gfx::ScaleSize(
179 fbo_pixel_size_, 1.0f / fbo_scale_factor_))); 175 fbo_pixel_size_, 1.0f / fbo_scale_factor_)));
180 [layer_ setContentsScale:fbo_scale_factor_]; 176 [layer_ setContentsScale:fbo_scale_factor_];
181 [layer_ setFrame:CGRectMake(0, 0, dip_size.width(), dip_size.height())]; 177 [layer_ setFrame:CGRectMake(0, 0, dip_size.width(), dip_size.height())];
182 178
183 // Make the CALayer current to the CAContext and display its contents 179 // Make the CALayer current to the CAContext and display its contents
184 // immediately. 180 // immediately.
185 [context_ setLayer:layer_]; 181 [context_ setLayer:layer_];
186 } 182 }
187 183
188 // Tell CoreAnimation to draw our frame. We will send the IPC to the browser 184 // Tell CoreAnimation to draw our frame.
189 // when CoreAnimation has drawn our frame. 185 if (gpu_vsync_disabled_ || throttling_disabled_) {
190 if (gpu_vsync_disabled_) { 186 DrawImmediatelyAndUnblockBrowser();
191 DrawWithVsyncDisabled();
192 } else { 187 } else {
193 if (![layer_ isAsynchronous]) 188 if (![layer_ isAsynchronous])
194 [layer_ setAsynchronous:YES]; 189 [layer_ setAsynchronous:YES];
190
191 // If CoreAnimation doesn't end up drawing our frame, un-block the browser
192 // after a timeout of 1/6th of a second has passed.
193 base::MessageLoop::current()->PostDelayedTask(
194 FROM_HERE,
195 base::Bind(&CALayerStorageProvider::DrawImmediatelyAndUnblockBrowser,
196 pending_draw_weak_factory_.GetWeakPtr()),
197 base::TimeDelta::FromSeconds(1) / 6);
195 } 198 }
196 } 199 }
197 200
198 void CALayerStorageProvider::DrawWithVsyncDisabled() { 201 void CALayerStorageProvider::DrawImmediatelyAndUnblockBrowser() {
199 DCHECK(has_pending_draw_); 202 CHECK(has_pending_draw_);
203 if ([layer_ isAsynchronous])
204 [layer_ setAsynchronous:NO];
200 [layer_ setNeedsDisplay]; 205 [layer_ setNeedsDisplay];
206 [layer_ displayIfNeeded];
201 207
202 // Sometimes, setNeedsDisplay calls are dropped on the floor. Make this not 208 // Sometimes, the setNeedsDisplay+displayIfNeeded pairs have no effect. This
203 // hang the renderer by re-issuing the call if the draw has not yet 209 // can happen if the NSView that this layer is attached to isn't in the
204 // happened. 210 // window hierarchy (e.g, tab capture of a backgrounded tab). In this case,
205 if (has_pending_draw_) { 211 // the frame will never be seen, so drop it.
206 // Delay sending another draw immediately to avoid starving the run loop. 212 UnblockBrowserIfNeeded();
207 base::MessageLoop::current()->PostDelayedTask(
208 FROM_HERE,
209 base::Bind(&CALayerStorageProvider::DrawWithVsyncDisabled,
210 weak_factory_.GetWeakPtr()),
211 base::TimeDelta::FromMilliseconds(5));
212 }
213 } 213 }
214 214
215 void CALayerStorageProvider::WillWriteToBackbuffer() { 215 void CALayerStorageProvider::WillWriteToBackbuffer() {
216 // TODO(ccameron): The browser may need to continue issuing swaps even when 216 // The browser will always throttle itself so that there is no pending draw
217 // they do not draw. In these cases it is necessary to either double-buffer 217 // when this output surface is written to.
218 // the resulting texture, or to drop frames. 218 DCHECK(!has_pending_draw_);
219 } 219 }
220 220
221 void CALayerStorageProvider::DiscardBackbuffer() { 221 void CALayerStorageProvider::DiscardBackbuffer() {
222 // If this surface's backbuffer is discarded, it is because this surface has 222 // If this surface's backbuffer is discarded, it is because this surface has
223 // been made non-visible. Ensure that the previous contents are not briefly 223 // been made non-visible. Ensure that the previous contents are not briefly
224 // flashed when this is made visible by creating a new CALayer and CAContext 224 // flashed when this is made visible by creating a new CALayer and CAContext
225 // at the next swap. 225 // at the next swap.
226 [layer_ resetStorageProvider]; 226 [layer_ resetStorageProvider];
227 layer_.reset(); 227 layer_.reset();
228 context_.reset(); 228 context_.reset();
229 } 229 }
230 230
231 void CALayerStorageProvider::SwapBuffersAckedByBrowser() { 231 void CALayerStorageProvider::SwapBuffersAckedByBrowser(
232 bool disable_throttling) {
233 throttling_disabled_ = disable_throttling;
232 } 234 }
233 235
234 CGLContextObj CALayerStorageProvider::LayerShareGroupContext() { 236 CGLContextObj CALayerStorageProvider::LayerShareGroupContext() {
235 return share_group_context_; 237 return share_group_context_;
236 } 238 }
237 239
238 bool CALayerStorageProvider::LayerCanDraw() { 240 bool CALayerStorageProvider::LayerCanDraw() {
239 if (has_pending_draw_) { 241 if (has_pending_draw_) {
240 can_draw_returned_false_count_ = 0; 242 can_draw_returned_false_count_ = 0;
241 return true; 243 return true;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 glVertex2f(fbo_pixel_size_.width(), fbo_pixel_size_.height()); 285 glVertex2f(fbo_pixel_size_.width(), fbo_pixel_size_.height());
284 286
285 glTexCoord2f(fbo_pixel_size_.width(), 0); 287 glTexCoord2f(fbo_pixel_size_.width(), 0);
286 glVertex2f(fbo_pixel_size_.width(), 0); 288 glVertex2f(fbo_pixel_size_.width(), 0);
287 } 289 }
288 glEnd(); 290 glEnd();
289 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); 291 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
290 glDisable(GL_TEXTURE_RECTANGLE_ARB); 292 glDisable(GL_TEXTURE_RECTANGLE_ARB);
291 293
292 // Allow forward progress in the context now that the swap is complete. 294 // Allow forward progress in the context now that the swap is complete.
293 DCHECK(has_pending_draw_); 295 UnblockBrowserIfNeeded();
294 SendPendingSwapToBrowserAfterFrameDrawn();
295 } 296 }
296 297
297 void CALayerStorageProvider::LayerResetStorageProvider() { 298 void CALayerStorageProvider::LayerResetStorageProvider() {
298 // If we are providing back-pressure by waiting for a draw, that draw will 299 // If we are providing back-pressure by waiting for a draw, that draw will
299 // now never come, so release the pressure now. 300 // now never come, so release the pressure now.
300 SendPendingSwapToBrowserAfterFrameDrawn(); 301 UnblockBrowserIfNeeded();
301 } 302 }
302 303
303 void CALayerStorageProvider::SendPendingSwapToBrowserAfterFrameDrawn() { 304 void CALayerStorageProvider::UnblockBrowserIfNeeded() {
304 if (!has_pending_draw_) 305 if (!has_pending_draw_)
305 return; 306 return;
306 weak_factory_.InvalidateWeakPtrs(); 307 pending_draw_weak_factory_.InvalidateWeakPtrs();
307 has_pending_draw_ = false; 308 has_pending_draw_ = false;
308 transport_surface_->SendSwapBuffers( 309 transport_surface_->SendSwapBuffers(
309 SurfaceHandleFromCAContextID([context_ contextId]), 310 SurfaceHandleFromCAContextID([context_ contextId]),
310 fbo_pixel_size_, 311 fbo_pixel_size_,
311 fbo_scale_factor_); 312 fbo_scale_factor_);
312 } 313 }
313 314
314 } // namespace content 315 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/image_transport_surface_calayer_mac.h ('k') | content/common/gpu/image_transport_surface_fbo_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698