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

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: 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') | no next file » | 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 <OpenGL/gl.h> 7 #include <OpenGL/gl.h>
8 #include <OpenGL/glext.h> 8 #include <OpenGL/glext.h>
9 9
10 #include "content/common/gpu/gpu_messages.h" 10 #include "content/common/gpu/gpu_messages.h"
11 #include "ui/accelerated_widget_mac/surface_handle_types.h" 11 #include "ui/accelerated_widget_mac/surface_handle_types.h"
12 #include "ui/base/cocoa/animation_utils.h" 12 #include "ui/base/cocoa/animation_utils.h"
13 #include "ui/base/cocoa/remote_layer_api.h" 13 #include "ui/base/cocoa/remote_layer_api.h"
14 #include "ui/gfx/geometry/dip_util.h" 14 #include "ui/gfx/geometry/dip_util.h"
15 #include "ui/gl/gl_image_io_surface.h" 15 #include "ui/gl/gl_image_io_surface.h"
16 #include "ui/gl/scoped_api.h" 16 #include "ui/gl/scoped_api.h"
17 #include "ui/gl/scoped_cgl.h" 17 #include "ui/gl/scoped_cgl.h"
18 18
19 #define LOG_GL_ERRORS(msg) \ 19 #define LOG_GL_ERRORS(msg) \
20 do { \ 20 do { \
21 for (GLenum gl_error = glGetError(); gl_error != GL_NO_ERROR; \ 21 for (GLenum gl_error = glGetError(); gl_error != GL_NO_ERROR; \
22 gl_error = glGetError()) { \ 22 gl_error = glGetError()) { \
23 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; \ 23 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; \
24 } \ 24 } \
25 } while (0) 25 } while (0)
26 26
27 @interface CALayer(Private)
28 -(void) setContentsChanged;
Andre 2015/08/05 17:59:30 - (void)set...
ccameron 2015/08/06 18:55:18 Done.
29 @end
30
27 namespace content { 31 namespace content {
28 32
29 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( 33 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
30 GpuChannelManager* manager, 34 GpuChannelManager* manager,
31 GpuCommandBufferStub* stub, 35 GpuCommandBufferStub* stub,
32 gfx::PluginWindowHandle handle) 36 gfx::PluginWindowHandle handle)
33 : scale_factor_(1), pending_overlay_image_(nullptr), weak_factory_(this) { 37 : scale_factor_(1), pending_overlay_image_(nullptr), weak_factory_(this) {
34 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); 38 helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
35 } 39 }
36 40
37 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { 41 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() {
38 } 42 }
39 43
40 bool ImageTransportSurfaceOverlayMac::Initialize() { 44 bool ImageTransportSurfaceOverlayMac::Initialize() {
41 if (!helper_->Initialize()) 45 if (!helper_->Initialize())
42 return false; 46 return false;
43 47
44 // Create the CAContext to send this to the GPU process, and the layer for 48 // Create the CAContext to send this to the GPU process, and the layer for
45 // the context. 49 // the context.
46 CGSConnectionID connection_id = CGSMainConnectionID(); 50 CGSConnectionID connection_id = CGSMainConnectionID();
47 ca_context_.reset( 51 ca_context_.reset(
48 [[CAContext contextWithCGSConnection:connection_id options:@{}] retain]); 52 [[CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
49 layer_.reset([[CALayer alloc] init]); 53 layer_.reset([[CALayer alloc] init]);
50 [layer_ setGeometryFlipped:YES]; 54 [layer_ setGeometryFlipped:YES];
55 partial_damage_layer_.reset([[CALayer alloc] init]);
51 [ca_context_ setLayer:layer_]; 56 [ca_context_ setLayer:layer_];
52 57
53 return true; 58 return true;
54 } 59 }
55 60
56 void ImageTransportSurfaceOverlayMac::Destroy() { 61 void ImageTransportSurfaceOverlayMac::Destroy() {
57 CheckAndDisplayPendingSwaps(true); 62 CheckAndDisplayPendingSwaps(true);
58 } 63 }
59 64
60 bool ImageTransportSurfaceOverlayMac::IsOffscreen() { 65 bool ImageTransportSurfaceOverlayMac::IsOffscreen() {
(...skipping 25 matching lines...) Expand all
86 this_swap.io_surface.get()); 91 this_swap.io_surface.get());
87 LOG_GL_ERRORS("before flushing frame"); 92 LOG_GL_ERRORS("before flushing frame");
88 this_swap.cgl_context.reset(CGLGetCurrentContext(), 93 this_swap.cgl_context.reset(CGLGetCurrentContext(),
89 base::scoped_policy::RETAIN); 94 base::scoped_policy::RETAIN);
90 glGenFencesAPPLE(1, &this_swap.fence); 95 glGenFencesAPPLE(1, &this_swap.fence);
91 glSetFenceAPPLE(this_swap.fence); 96 glSetFenceAPPLE(this_swap.fence);
92 glFlush(); 97 glFlush();
93 LOG_GL_ERRORS("while flushing frame"); 98 LOG_GL_ERRORS("while flushing frame");
94 } 99 }
95 100
96 this_swap.dip_size = gfx::ConvertSizeToDIP(scale_factor_, pixel_size_); 101 // Determine if this will be a full or partial damage, and compute the rects
102 // for the damage.
103 {
104 this_swap.dip_size = gfx::ConvertSizeToDIP(scale_factor_, pixel_size_);
105
106 // Grow the partial damage rect to include the new damage.
107 accumulated_partial_damage_pixel_rect_.Union(pixel_damage_rect);
108 // Compute the fraction of the full layer that has been damaged. If this
109 // fraction is very large (>85%), just damage the full layer, and don't
110 // bother with the partial layer.
111 double kMaximumFractionOfFullDamage = 0.85;
Andre 2015/08/05 17:59:30 nit: const
ccameron 2015/08/06 18:55:18 Done.
112 double fraction_of_full_damage =
Andre 2015/08/05 17:59:30 nit: const
ccameron 2015/08/06 18:55:18 Done.
113 accumulated_partial_damage_pixel_rect_.size().GetArea() /
114 static_cast<double>(pixel_size_.GetArea());
115 // Compute the fraction of the accumulated partial damage rect that has been
116 // damaged. If this gets too small (<75%), just re-damage the full window,
117 // so we can re-create a smaller partial damage layer next frame.
118 double kMinimumFractionOfPartialDamage = 0.75;
119 double fraction_of_partial_damage =
120 pixel_damage_rect.size().GetArea() / static_cast<double>(
121 accumulated_partial_damage_pixel_rect_.size().GetArea());
122 if (fraction_of_full_damage < kMaximumFractionOfFullDamage &&
123 fraction_of_partial_damage > kMinimumFractionOfPartialDamage) {
124 this_swap.use_partial_damage = true;
125 this_swap.dip_partial_damage_rect = gfx::ConvertRectToDIP(
126 scale_factor_, accumulated_partial_damage_pixel_rect_);
127 } else {
128 this_swap.use_partial_damage = false;
129 accumulated_partial_damage_pixel_rect_ = gfx::Rect();
130 }
131 }
132
97 pending_swaps_.push_back(this_swap); 133 pending_swaps_.push_back(this_swap);
98
99 PostCheckAndDisplayPendingSwaps(); 134 PostCheckAndDisplayPendingSwaps();
100 return gfx::SwapResult::SWAP_ACK; 135 return gfx::SwapResult::SWAP_ACK;
101 } 136 }
102 137
103 void ImageTransportSurfaceOverlayMac::CheckAndDisplayPendingSwaps( 138 void ImageTransportSurfaceOverlayMac::CheckAndDisplayPendingSwaps(
104 bool force_immediate_display) { 139 bool force_immediate_display) {
105 TRACE_EVENT0("gpu", 140 TRACE_EVENT0("gpu",
106 "ImageTransportSurfaceOverlayMac::CheckAndDisplayPendingSwaps"); 141 "ImageTransportSurfaceOverlayMac::CheckAndDisplayPendingSwaps");
107 if (pending_swaps_.empty()) 142 if (pending_swaps_.empty())
108 return; 143 return;
(...skipping 15 matching lines...) Expand all
124 } 159 }
125 glDeleteFencesAPPLE(1, &this_swap.fence); 160 glDeleteFencesAPPLE(1, &this_swap.fence);
126 LOG_GL_ERRORS("while deleting fence"); 161 LOG_GL_ERRORS("while deleting fence");
127 } 162 }
128 163
129 // Update the CALayer hierarchy. 164 // Update the CALayer hierarchy.
130 { 165 {
131 TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::setContents", 166 TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::setContents",
132 "surface", this_swap.io_surface.get()); 167 "surface", this_swap.io_surface.get());
133 ScopedCAActionDisabler disabler; 168 ScopedCAActionDisabler disabler;
134 id new_contents = static_cast<id>(this_swap.io_surface.get()); 169 if (this_swap.use_partial_damage) {
135 [layer_ setContents:new_contents]; 170 if (![partial_damage_layer_ superlayer])
136 [layer_ setFrame:gfx::Rect(this_swap.dip_size).ToCGRect()]; 171 [layer_ addSublayer:partial_damage_layer_];
172
173 [partial_damage_layer_
174 setContents:static_cast<id>(this_swap.io_surface.get())];
175 [partial_damage_layer_
176 setFrame:this_swap.dip_partial_damage_rect.ToCGRect()];
177 gfx::RectF content_bounds_rect =
178 gfx::RectF(this_swap.dip_partial_damage_rect);
179 content_bounds_rect.Scale(
180 1. / this_swap.dip_size.width(), 1. / this_swap.dip_size.height());
181 [partial_damage_layer_ setContentsRect:CGRectMake(
182 content_bounds_rect.x(),
183 content_bounds_rect.y(),
184 content_bounds_rect.width(),
185 content_bounds_rect.height())];
Andre 2015/08/05 17:59:30 How about something like: CGRect damage_rect = thi
ccameron 2015/08/06 18:55:18 Actually, gfx::RectF should have a ToCGRect functi
186 } else {
187 if ([partial_damage_layer_ superlayer]) {
188 [partial_damage_layer_ removeFromSuperlayer];
189 [partial_damage_layer_ setContents:nil];
190 }
191
192 // Note that calling setContents with the same IOSurface twice will result
193 // in the screen not being updated, even if the IOSurface's content has
194 // changed. Avoid this by calling setContentsChanged.
195 id new_contents = static_cast<id>(this_swap.io_surface.get());
196 if ([layer_ contents] == new_contents)
197 [layer_ setContentsChanged];
198 else
199 [layer_ setContents:static_cast<id>(this_swap.io_surface.get())];
Andre 2015/08/05 17:59:30 setContents:new_contents
ccameron 2015/08/06 18:55:18 Done.
200 [layer_ setFrame:gfx::Rect(this_swap.dip_size).ToCGRect()];
201 }
137 } 202 }
138 203
139 // Remove this swap from the queue. 204 // Remove this swap from the queue.
140 pending_swaps_.pop_front(); 205 pending_swaps_.pop_front();
141 206
142 // Send acknowledgement to the browser. 207 // Send acknowledgement to the browser.
143 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 208 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
144 params.surface_handle = 209 params.surface_handle =
145 ui::SurfaceHandleFromCAContextID([ca_context_ contextId]); 210 ui::SurfaceHandleFromCAContextID([ca_context_ contextId]);
146 params.size = pixel_size_; 211 params.size = pixel_size_;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 void ImageTransportSurfaceOverlayMac::SetLatencyInfo( 310 void ImageTransportSurfaceOverlayMac::SetLatencyInfo(
246 const std::vector<ui::LatencyInfo>& latency_info) { 311 const std::vector<ui::LatencyInfo>& latency_info) {
247 latency_info_.insert( 312 latency_info_.insert(
248 latency_info_.end(), latency_info.begin(), latency_info.end()); 313 latency_info_.end(), latency_info.begin(), latency_info.end());
249 } 314 }
250 315
251 void ImageTransportSurfaceOverlayMac::WakeUpGpu() {} 316 void ImageTransportSurfaceOverlayMac::WakeUpGpu() {}
252 317
253 318
254 ImageTransportSurfaceOverlayMac::PendingSwap::PendingSwap() 319 ImageTransportSurfaceOverlayMac::PendingSwap::PendingSwap()
255 : fence(0) { 320 : fence(0), use_partial_damage(false) {
256 } 321 }
257 322
258 ImageTransportSurfaceOverlayMac::PendingSwap::~PendingSwap() { 323 ImageTransportSurfaceOverlayMac::PendingSwap::~PendingSwap() {
259 } 324 }
260 325
261 } // namespace content 326 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698