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

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

Issue 1271123002: Mac: Enable partial swap (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 4 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
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | ui/gfx/geometry/rect_f.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "content/common/gpu/image_transport_surface_overlay_mac.h" 5 #include "content/common/gpu/image_transport_surface_overlay_mac.h"
6 6
7 #include <IOSurface/IOSurface.h> 7 #include <IOSurface/IOSurface.h>
8 #include <OpenGL/GL.h> 8 #include <OpenGL/GL.h>
9 9
10 // This type consistently causes problem on Mac, and needs to be dealt with 10 // This type consistently causes problem on Mac, and needs to be dealt with
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 57
58 class ImageTransportSurfaceOverlayMac::PendingSwap { 58 class ImageTransportSurfaceOverlayMac::PendingSwap {
59 public: 59 public:
60 PendingSwap() : scale_factor(1) {} 60 PendingSwap() : scale_factor(1) {}
61 ~PendingSwap() { DCHECK(!gl_fence); } 61 ~PendingSwap() { DCHECK(!gl_fence); }
62 62
63 gfx::Size pixel_size; 63 gfx::Size pixel_size;
64 float scale_factor; 64 float scale_factor;
65 std::vector<ui::LatencyInfo> latency_info; 65 std::vector<ui::LatencyInfo> latency_info;
66 66
67 // If true, the partial damage rect for the frame.
68 bool use_partial_damage;
69 gfx::Rect pixel_partial_damage_rect;
70
67 // The IOSurface with new content for this swap. 71 // The IOSurface with new content for this swap.
68 base::ScopedCFTypeRef<IOSurfaceRef> io_surface; 72 base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
69 73
70 // A fence object, and the CGL context it was issued in. 74 // A fence object, and the CGL context it was issued in.
71 base::ScopedTypeRef<CGLContextObj> cgl_context; 75 base::ScopedTypeRef<CGLContextObj> cgl_context;
72 scoped_ptr<gfx::GLFence> gl_fence; 76 scoped_ptr<gfx::GLFence> gl_fence;
73 77
74 // The earliest time that this frame may be drawn. A frame is not allowed 78 // The earliest time that this frame may be drawn. A frame is not allowed
75 // to draw until a fraction of the way through the vsync interval after its 79 // to draw until a fraction of the way through the vsync interval after its
76 // This extra latency is to allow wiggle-room for smoothness. 80 // This extra latency is to allow wiggle-room for smoothness.
(...skipping 21 matching lines...) Expand all
98 102
99 // Create the CAContext to send this to the GPU process, and the layer for 103 // Create the CAContext to send this to the GPU process, and the layer for
100 // the context. 104 // the context.
101 CGSConnectionID connection_id = CGSMainConnectionID(); 105 CGSConnectionID connection_id = CGSMainConnectionID();
102 ca_context_.reset( 106 ca_context_.reset(
103 [[CAContext contextWithCGSConnection:connection_id options:@{}] retain]); 107 [[CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
104 layer_.reset([[CALayer alloc] init]); 108 layer_.reset([[CALayer alloc] init]);
105 [layer_ setGeometryFlipped:YES]; 109 [layer_ setGeometryFlipped:YES];
106 [layer_ setOpaque:YES]; 110 [layer_ setOpaque:YES];
107 [ca_context_ setLayer:layer_]; 111 [ca_context_ setLayer:layer_];
112
113 partial_damage_layer_.reset([[CALayer alloc] init]);
114 [partial_damage_layer_ setOpaque:YES];
108 return true; 115 return true;
109 } 116 }
110 117
111 void ImageTransportSurfaceOverlayMac::Destroy() { 118 void ImageTransportSurfaceOverlayMac::Destroy() {
112 FinishAllPendingSwaps(); 119 FinishAllPendingSwaps();
113 } 120 }
114 121
115 bool ImageTransportSurfaceOverlayMac::IsOffscreen() { 122 bool ImageTransportSurfaceOverlayMac::IsOffscreen() {
116 return false; 123 return false;
117 } 124 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 new_swap->latest_allowed_draw_time = now + 180 new_swap->latest_allowed_draw_time = now +
174 base::TimeDelta::FromSecondsD(kMaximumDelayWaitingForFenceInSeconds); 181 base::TimeDelta::FromSecondsD(kMaximumDelayWaitingForFenceInSeconds);
175 } else { 182 } else {
176 // If we have no display link (because vsync is disabled or because we have 183 // If we have no display link (because vsync is disabled or because we have
177 // not received display parameters yet), immediately attempt to display the 184 // not received display parameters yet), immediately attempt to display the
178 // surface. 185 // surface.
179 new_swap->earliest_allowed_draw_time = now; 186 new_swap->earliest_allowed_draw_time = now;
180 new_swap->latest_allowed_draw_time = now; 187 new_swap->latest_allowed_draw_time = now;
181 } 188 }
182 189
190 // Determine if this will be a full or partial damage, and compute the rects
191 // for the damage.
192 {
193 // Grow the partial damage rect to include the new damage.
194 accumulated_partial_damage_pixel_rect_.Union(pixel_damage_rect);
195 // Compute the fraction of the full layer that has been damaged. If this
196 // fraction is very large (>85%), just damage the full layer, and don't
197 // bother with the partial layer.
198 const double kMaximumFractionOfFullDamage = 0.85;
199 double fraction_of_full_damage =
200 accumulated_partial_damage_pixel_rect_.size().GetArea() /
201 static_cast<double>(pixel_size_.GetArea());
202 // Compute the fraction of the accumulated partial damage rect that has been
203 // damaged. If this gets too small (<75%), just re-damage the full window,
204 // so we can re-create a smaller partial damage layer next frame.
205 const double kMinimumFractionOfPartialDamage = 0.75;
206 double fraction_of_partial_damage =
207 pixel_damage_rect.size().GetArea() / static_cast<double>(
208 accumulated_partial_damage_pixel_rect_.size().GetArea());
209 if (fraction_of_full_damage < kMaximumFractionOfFullDamage &&
210 fraction_of_partial_damage > kMinimumFractionOfPartialDamage) {
211 new_swap->use_partial_damage = true;
212 new_swap->pixel_partial_damage_rect =
213 accumulated_partial_damage_pixel_rect_;
214 } else {
215 new_swap->use_partial_damage = false;
216 accumulated_partial_damage_pixel_rect_ = gfx::Rect();
217 }
218 }
219
183 pending_swaps_.push_back(new_swap); 220 pending_swaps_.push_back(new_swap);
184 PostCheckPendingSwapsCallbackIfNeeded(now); 221 PostCheckPendingSwapsCallbackIfNeeded(now);
185 return gfx::SwapResult::SWAP_ACK; 222 return gfx::SwapResult::SWAP_ACK;
186 } 223 }
187 224
188 bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay( 225 bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay(
189 const base::TimeTicks& now) { 226 const base::TimeTicks& now) {
190 DCHECK(!pending_swaps_.empty()); 227 DCHECK(!pending_swaps_.empty());
191 linked_ptr<PendingSwap> swap = pending_swaps_.front(); 228 linked_ptr<PendingSwap> swap = pending_swaps_.front();
192 229
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 CheckGLErrors("while deleting active fence"); 276 CheckGLErrors("while deleting active fence");
240 } 277 }
241 278
242 // Update the CALayer hierarchy. 279 // Update the CALayer hierarchy.
243 { 280 {
244 TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::setContents", 281 TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::setContents",
245 "surface", swap->io_surface.get()); 282 "surface", swap->io_surface.get());
246 ScopedCAActionDisabler disabler; 283 ScopedCAActionDisabler disabler;
247 284
248 id new_contents = static_cast<id>(swap->io_surface.get()); 285 id new_contents = static_cast<id>(swap->io_surface.get());
249 [layer_ setContents:new_contents]; 286 if (swap->use_partial_damage) {
287 if (![partial_damage_layer_ superlayer])
288 [layer_ addSublayer:partial_damage_layer_];
289 [partial_damage_layer_ setContents:new_contents];
250 290
251 CGRect new_frame = gfx::ConvertRectToDIP( 291 CGRect new_frame = gfx::ConvertRectToDIP(
252 swap->scale_factor, gfx::Rect(swap->pixel_size)).ToCGRect(); 292 swap->scale_factor, swap->pixel_partial_damage_rect).ToCGRect();
253 if (!CGRectEqualToRect([layer_ frame], new_frame)) 293 if (!CGRectEqualToRect([partial_damage_layer_ frame], new_frame))
254 [layer_ setFrame:new_frame]; 294 [partial_damage_layer_ setFrame:new_frame];
295
296 gfx::RectF contents_rect =
297 gfx::RectF(swap->pixel_partial_damage_rect);
298 contents_rect.Scale(
299 1. / swap->pixel_size.width(), 1. / swap->pixel_size.height());
300 CGRect cg_contents_rect = CGRectMake(
301 contents_rect.x(), contents_rect.y(),
302 contents_rect.width(), contents_rect.height());
303 [partial_damage_layer_ setContentsRect:cg_contents_rect];
304 } else {
305 // Remove the partial damage layer.
306 if ([partial_damage_layer_ superlayer]) {
307 [partial_damage_layer_ removeFromSuperlayer];
308 [partial_damage_layer_ setContents:nil];
309 }
310
311 // Note that calling setContents with the same IOSurface twice will result
312 // in the screen not being updated, even if the IOSurface's content has
313 // changed. Avoid this by calling setContentsChanged.
314 if ([layer_ contents] == new_contents)
315 [layer_ setContentsChanged];
316 else
317 [layer_ setContents:new_contents];
318
319 CGRect new_frame = gfx::ConvertRectToDIP(
320 swap->scale_factor, gfx::Rect(swap->pixel_size)).ToCGRect();
321 if (!CGRectEqualToRect([layer_ frame], new_frame))
322 [layer_ setFrame:new_frame];
323 }
255 } 324 }
256 325
257 // Send acknowledgement to the browser. 326 // Send acknowledgement to the browser.
258 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 327 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
259 params.surface_handle = 328 params.surface_handle =
260 ui::SurfaceHandleFromCAContextID([ca_context_ contextId]); 329 ui::SurfaceHandleFromCAContextID([ca_context_ contextId]);
261 params.size = pixel_size_; 330 params.size = pixel_size_;
262 params.scale_factor = scale_factor_; 331 params.scale_factor = scale_factor_;
263 params.latency_info.swap(swap->latency_info); 332 params.latency_info.swap(swap->latency_info);
264 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 333 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 448
380 void ImageTransportSurfaceOverlayMac::SetLatencyInfo( 449 void ImageTransportSurfaceOverlayMac::SetLatencyInfo(
381 const std::vector<ui::LatencyInfo>& latency_info) { 450 const std::vector<ui::LatencyInfo>& latency_info) {
382 latency_info_.insert( 451 latency_info_.insert(
383 latency_info_.end(), latency_info.begin(), latency_info.end()); 452 latency_info_.end(), latency_info.begin(), latency_info.end());
384 } 453 }
385 454
386 void ImageTransportSurfaceOverlayMac::WakeUpGpu() {} 455 void ImageTransportSurfaceOverlayMac::WakeUpGpu() {}
387 456
388 } // namespace content 457 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | ui/gfx/geometry/rect_f.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698