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

Side by Side Diff: gpu/ipc/service/image_transport_surface_overlay_mac.mm

Issue 1867163002: Mac: Clean up ImageTransportSurfaceOverlayMac timing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 8 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 | « gpu/ipc/service/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 "gpu/ipc/service/image_transport_surface_overlay_mac.h" 5 #include "gpu/ipc/service/image_transport_surface_overlay_mac.h"
6 6
7 #include <CoreGraphics/CoreGraphics.h> 7 #include <CoreGraphics/CoreGraphics.h>
8 #include <IOSurface/IOSurface.h> 8 #include <IOSurface/IOSurface.h>
9 #include <OpenGL/CGLRenderers.h> 9 #include <OpenGL/CGLRenderers.h>
10 #include <OpenGL/CGLTypes.h> 10 #include <OpenGL/CGLTypes.h>
(...skipping 24 matching lines...) Expand all
35 #include "ui/gfx/transform.h" 35 #include "ui/gfx/transform.h"
36 #include "ui/gl/gl_context.h" 36 #include "ui/gl/gl_context.h"
37 #include "ui/gl/gl_fence.h" 37 #include "ui/gl/gl_fence.h"
38 #include "ui/gl/gl_image_io_surface.h" 38 #include "ui/gl/gl_image_io_surface.h"
39 #include "ui/gl/gpu_switching_manager.h" 39 #include "ui/gl/gpu_switching_manager.h"
40 #include "ui/gl/scoped_api.h" 40 #include "ui/gl/scoped_api.h"
41 #include "ui/gl/scoped_cgl.h" 41 #include "ui/gl/scoped_cgl.h"
42 42
43 namespace { 43 namespace {
44 44
45 // Don't let a frame draw until 5% of the way through the next vsync interval
46 // after the call to SwapBuffers. This slight offset is to ensure that skew
47 // doesn't result in the frame being presented to the previous vsync interval.
48 const double kVSyncIntervalFractionForEarliestDisplay = 0.05;
49
50 // After doing a glFlush and putting in a fence in SwapBuffers, post a task to
51 // query the fence 50% of the way through the next vsync interval. If we are
52 // trying to animate smoothly, then want to query the fence at the next
53 // SwapBuffers. For this reason we schedule the callback for a long way into
54 // the next frame.
55 const double kVSyncIntervalFractionForDisplayCallback = 0.5;
56
57 // If swaps arrive regularly and nearly at the vsync rate, then attempt to
58 // make animation smooth (each frame is shown for one vsync interval) by sending
59 // them to the window server only when their GL work completes. If frames are
60 // not coming in with each vsync, then just throw them at the window server as
61 // they come.
62 const double kMaximumVSyncsBetweenSwapsForSmoothAnimation = 1.5;
63
64 void CheckGLErrors(const char* msg) { 45 void CheckGLErrors(const char* msg) {
65 GLenum gl_error; 46 GLenum gl_error;
66 while ((gl_error = glGetError()) != GL_NO_ERROR) { 47 while ((gl_error = glGetError()) != GL_NO_ERROR) {
67 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; 48 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error;
68 } 49 }
69 } 50 }
70 51
71 void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { 52 void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) {
72 } 53 }
73 54
74 } // namespace 55 } // namespace
75 56
76 @interface CALayer(Private)
77 -(void)setContentsChanged;
78 @end
79
80 namespace gpu { 57 namespace gpu {
81 58
82 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface( 59 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
83 GpuChannelManager* manager, 60 GpuChannelManager* manager,
84 GpuCommandBufferStub* stub, 61 GpuCommandBufferStub* stub,
85 SurfaceHandle handle) { 62 SurfaceHandle handle) {
86 return new ImageTransportSurfaceOverlayMac(manager, stub, handle); 63 return new ImageTransportSurfaceOverlayMac(manager, stub, handle);
87 } 64 }
88 65
89 class ImageTransportSurfaceOverlayMac::PendingSwap {
90 public:
91 PendingSwap() {}
92 ~PendingSwap() { DCHECK(!gl_fence); }
93
94 gfx::Size pixel_size;
95 float scale_factor;
96 gfx::Rect pixel_damage_rect;
97
98 scoped_ptr<CALayerPartialDamageTree> partial_damage_tree;
99 scoped_ptr<CALayerTree> ca_layer_tree;
100 std::vector<ui::LatencyInfo> latency_info;
101
102 // A fence object, and the CGL context it was issued in.
103 base::ScopedTypeRef<CGLContextObj> cgl_context;
104 scoped_ptr<gfx::GLFence> gl_fence;
105
106 // The earliest time that this frame may be drawn. A frame is not allowed
107 // to draw until a fraction of the way through the vsync interval after its
108 // This extra latency is to allow wiggle-room for smoothness.
109 base::TimeTicks earliest_display_time_allowed;
110
111 // The time that this will wake up and draw, if a following swap does not
112 // cause it to draw earlier.
113 base::TimeTicks target_display_time;
114 };
115
116 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( 66 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
117 GpuChannelManager* manager, 67 GpuChannelManager* manager,
118 GpuCommandBufferStub* stub, 68 GpuCommandBufferStub* stub,
119 SurfaceHandle handle) 69 SurfaceHandle handle)
120 : manager_(manager), 70 : manager_(manager),
121 stub_(stub->AsWeakPtr()), 71 stub_(stub->AsWeakPtr()),
122 handle_(handle), 72 handle_(handle),
123 use_remote_layer_api_(ui::RemoteLayerAPISupported()), 73 use_remote_layer_api_(ui::RemoteLayerAPISupported()),
124 scale_factor_(1), 74 scale_factor_(1),
125 gl_renderer_id_(0), 75 gl_renderer_id_(0),
126 vsync_parameters_valid_(false), 76 vsync_parameters_valid_(false) {
127 display_pending_swap_timer_(true, false),
128 weak_factory_(this) {
129 manager_->AddBufferPresentedCallback( 77 manager_->AddBufferPresentedCallback(
130 handle_, base::Bind(&ImageTransportSurfaceOverlayMac::BufferPresented, 78 handle_, base::Bind(&ImageTransportSurfaceOverlayMac::BufferPresented,
131 base::Unretained(this))); 79 base::Unretained(this)));
132 ui::GpuSwitchingManager::GetInstance()->AddObserver(this); 80 ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
133 } 81 }
134 82
135 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { 83 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() {
136 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); 84 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
137 if (stub_.get()) { 85 if (stub_.get()) {
138 stub_->SetLatencyInfoCallback( 86 stub_->SetLatencyInfoCallback(
(...skipping 20 matching lines...) Expand all
159 [CAContext contextWithCGSConnection:connection_id options:@{}] retain]); 107 [CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
160 ca_root_layer_.reset([[CALayer alloc] init]); 108 ca_root_layer_.reset([[CALayer alloc] init]);
161 [ca_root_layer_ setGeometryFlipped:YES]; 109 [ca_root_layer_ setGeometryFlipped:YES];
162 [ca_root_layer_ setOpaque:YES]; 110 [ca_root_layer_ setOpaque:YES];
163 [ca_context_ setLayer:ca_root_layer_]; 111 [ca_context_ setLayer:ca_root_layer_];
164 } 112 }
165 return true; 113 return true;
166 } 114 }
167 115
168 void ImageTransportSurfaceOverlayMac::Destroy() { 116 void ImageTransportSurfaceOverlayMac::Destroy() {
169 DisplayAndClearAllPendingSwaps();
170
171 current_partial_damage_tree_.reset(); 117 current_partial_damage_tree_.reset();
172 current_ca_layer_tree_.reset(); 118 current_ca_layer_tree_.reset();
173 } 119 }
174 120
175 bool ImageTransportSurfaceOverlayMac::IsOffscreen() { 121 bool ImageTransportSurfaceOverlayMac::IsOffscreen() {
176 return false; 122 return false;
177 } 123 }
178 124
179 void ImageTransportSurfaceOverlayMac::SetLatencyInfo( 125 void ImageTransportSurfaceOverlayMac::SetLatencyInfo(
180 const std::vector<ui::LatencyInfo>& latency_info) { 126 const std::vector<ui::LatencyInfo>& latency_info) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // GpuProcessTransportFactory::CreatePerCompositorData 159 // GpuProcessTransportFactory::CreatePerCompositorData
214 manager_->delegate()->SendAcceleratedSurfaceBuffersSwapped( 160 manager_->delegate()->SendAcceleratedSurfaceBuffersSwapped(
215 surface_id, ca_context_id, io_surface, size, scale_factor, 161 surface_id, ca_context_id, io_surface, size, scale_factor,
216 std::move(latency_info)); 162 std::move(latency_info));
217 } 163 }
218 164
219 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal( 165 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal(
220 const gfx::Rect& pixel_damage_rect) { 166 const gfx::Rect& pixel_damage_rect) {
221 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal"); 167 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal");
222 168
223 // Use the same concept of 'now' for the entire function. The duration of 169 // A glFlush is necessary to ensure correct content appears. A glFinish
224 // this function only affect the result if this function lasts across a vsync 170 // appears empirically to be the best way to get maximum performance when
225 // boundary, in which case smooth animation is out the window anyway. 171 // GPU bound.
226 const base::TimeTicks now = base::TimeTicks::Now(); 172 {
227 173 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
228 // Decide if the frame should be drawn immediately, or if we should wait until 174 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFinish");
229 // its work finishes before drawing immediately. 175 CheckGLErrors("Before finish");
230 bool display_immediately = false; 176 glFinish();
231 if (vsync_parameters_valid_ && 177 CheckGLErrors("After finish");
232 now - last_swap_time_ >
233 kMaximumVSyncsBetweenSwapsForSmoothAnimation * vsync_interval_) {
234 display_immediately = true;
235 }
236 last_swap_time_ = now;
237
238 // If the previous swap is ready to display, do it before flushing the
239 // new swap. It is desirable to always be hitting this path when trying to
240 // animate smoothly with vsync.
241 if (!pending_swaps_.empty()) {
242 if (IsFirstPendingSwapReadyToDisplay(now))
243 DisplayFirstPendingSwapImmediately();
244 } 178 }
245 179
246 // The remainder of the function will populate the PendingSwap structure and 180 base::TimeTicks finish_time = base::TimeTicks::Now();
247 // then enqueue it.
248 linked_ptr<PendingSwap> new_swap(new PendingSwap);
249 new_swap->pixel_size = pixel_size_;
250 new_swap->scale_factor = scale_factor_;
251 new_swap->pixel_damage_rect = pixel_damage_rect;
252 new_swap->partial_damage_tree.swap(pending_partial_damage_tree_);
253 new_swap->ca_layer_tree.swap(pending_ca_layer_tree_);
254 new_swap->latency_info.swap(latency_info_);
255
256 // A flush is required to ensure that all content appears in the layer.
257 {
258 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
259 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFlush");
260 CheckGLErrors("before flushing frame");
261 new_swap->cgl_context.reset(CGLGetCurrentContext(),
262 base::scoped_policy::RETAIN);
263 if (gfx::GLFence::IsSupported() && !display_immediately)
264 new_swap->gl_fence.reset(gfx::GLFence::Create());
265 else
266 glFlush();
267 CheckGLErrors("while flushing frame");
268 }
269
270 // Compute the deadlines for drawing this frame.
271 if (display_immediately) {
272 new_swap->earliest_display_time_allowed = now;
273 new_swap->target_display_time = now;
274 } else {
275 new_swap->earliest_display_time_allowed =
276 GetNextVSyncTimeAfter(now, kVSyncIntervalFractionForEarliestDisplay);
277 new_swap->target_display_time =
278 GetNextVSyncTimeAfter(now, kVSyncIntervalFractionForDisplayCallback);
279 }
280
281 pending_swaps_.push_back(new_swap);
282 if (display_immediately)
283 DisplayFirstPendingSwapImmediately();
284 else
285 PostCheckPendingSwapsCallbackIfNeeded(now);
286 return gfx::SwapResult::SWAP_ACK;
287 }
288
289 bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay(
290 const base::TimeTicks& now) {
291 DCHECK(!pending_swaps_.empty());
292 linked_ptr<PendingSwap> swap = pending_swaps_.front();
293
294 // Frames are disallowed from drawing until the vsync interval after their
295 // swap is issued.
296 if (now < swap->earliest_display_time_allowed)
297 return false;
298
299 // If we've passed that marker, then wait for the work behind the fence to
300 // complete.
301 if (swap->gl_fence) {
302 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
303 gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
304
305 CheckGLErrors("before waiting on fence");
306 if (!swap->gl_fence->HasCompleted()) {
307 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::ClientWait");
308 swap->gl_fence->ClientWait();
309 }
310 swap->gl_fence.reset();
311 CheckGLErrors("after waiting on fence");
312 }
313 return true;
314 }
315
316 void ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately() {
317 TRACE_EVENT0("gpu",
318 "ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately");
319 DCHECK(!pending_swaps_.empty());
320 linked_ptr<PendingSwap> swap = pending_swaps_.front();
321
322 // If there is a fence for this object, delete it.
323 if (swap->gl_fence) {
324 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
325 gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
326
327 CheckGLErrors("before deleting active fence");
328 swap->gl_fence.reset();
329 CheckGLErrors("while deleting active fence");
330 }
331 181
332 // Update the CALayer hierarchy. 182 // Update the CALayer hierarchy.
333 { 183 {
334 gfx::RectF pixel_damage_rect = gfx::RectF(swap->pixel_damage_rect);
335 ScopedCAActionDisabler disabler; 184 ScopedCAActionDisabler disabler;
336 if (swap->ca_layer_tree) { 185 if (pending_ca_layer_tree_) {
337 swap->ca_layer_tree->CommitScheduledCALayers( 186 pending_ca_layer_tree_->CommitScheduledCALayers(
338 ca_root_layer_.get(), std::move(current_ca_layer_tree_), 187 ca_root_layer_.get(), std::move(current_ca_layer_tree_),
339 swap->scale_factor); 188 scale_factor_);
340 current_ca_layer_tree_.swap(swap->ca_layer_tree); 189 current_ca_layer_tree_.swap(pending_ca_layer_tree_);
341 current_partial_damage_tree_.reset(); 190 current_partial_damage_tree_.reset();
342 } else if (swap->partial_damage_tree) { 191 } else if (pending_partial_damage_tree_) {
343 swap->partial_damage_tree->CommitCALayers( 192 pending_partial_damage_tree_->CommitCALayers(
344 ca_root_layer_.get(), std::move(current_partial_damage_tree_), 193 ca_root_layer_.get(), std::move(current_partial_damage_tree_),
345 swap->scale_factor, swap->pixel_damage_rect); 194 scale_factor_, pixel_damage_rect);
346 current_partial_damage_tree_.swap(swap->partial_damage_tree); 195 current_partial_damage_tree_.swap(pending_partial_damage_tree_);
347 current_ca_layer_tree_.reset(); 196 current_ca_layer_tree_.reset();
348 } else { 197 } else {
349 TRACE_EVENT0("gpu", "Blank frame: No overlays or CALayers"); 198 TRACE_EVENT0("gpu", "Blank frame: No overlays or CALayers");
350 [ca_root_layer_ setSublayers:nil]; 199 [ca_root_layer_ setSublayers:nil];
351 current_partial_damage_tree_.reset(); 200 current_partial_damage_tree_.reset();
352 current_ca_layer_tree_.reset(); 201 current_ca_layer_tree_.reset();
353 } 202 }
354 swap->ca_layer_tree.reset();
355 swap->partial_damage_tree.reset();
356 } 203 }
357 204
358 // Update the latency info to reflect the swap time. 205 // Update the latency info to reflect the swap time.
359 base::TimeTicks swap_time = base::TimeTicks::Now(); 206 for (auto latency_info : latency_info_) {
360 for (auto latency_info : swap->latency_info) {
361 latency_info.AddLatencyNumberWithTimestamp( 207 latency_info.AddLatencyNumberWithTimestamp(
362 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); 208 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, finish_time, 1);
363 latency_info.AddLatencyNumberWithTimestamp( 209 latency_info.AddLatencyNumberWithTimestamp(
364 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, 210 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0,
365 swap_time, 1); 211 finish_time, 1);
366 } 212 }
367 213
368 // Send acknowledgement to the browser. 214 // Send acknowledgement to the browser.
369 CAContextID ca_context_id = 0; 215 CAContextID ca_context_id = 0;
370 gfx::ScopedRefCountedIOSurfaceMachPort io_surface; 216 gfx::ScopedRefCountedIOSurfaceMachPort io_surface;
371 if (use_remote_layer_api_) { 217 if (use_remote_layer_api_) {
372 ca_context_id = [ca_context_ contextId]; 218 ca_context_id = [ca_context_ contextId];
373 } else if (current_partial_damage_tree_) { 219 } else if (current_partial_damage_tree_) {
374 io_surface.reset(IOSurfaceCreateMachPort( 220 io_surface.reset(IOSurfaceCreateMachPort(
375 current_partial_damage_tree_->RootLayerIOSurface())); 221 current_partial_damage_tree_->RootLayerIOSurface()));
376 } 222 }
377 gfx::Size size = swap->pixel_size; 223 SendAcceleratedSurfaceBuffersSwapped(handle_, ca_context_id, io_surface,
378 float scale_factor = swap->scale_factor; 224 pixel_size_, scale_factor_,
379 std::vector<ui::LatencyInfo> latency_info; 225 std::move(latency_info_));
380 latency_info.swap(swap->latency_info);
381 SendAcceleratedSurfaceBuffersSwapped(handle_, ca_context_id, io_surface, size,
382 scale_factor, std::move(latency_info));
383 226
384 // Remove this from the queue, and reset any callback timers. 227 // Reset all state for the next frame.
385 pending_swaps_.pop_front(); 228 latency_info_.clear();
386 } 229 pending_ca_layer_tree_.reset();
387 230 pending_partial_damage_tree_.reset();
388 void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() { 231 return gfx::SwapResult::SWAP_ACK;
389 TRACE_EVENT0("gpu",
390 "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps");
391 while (!pending_swaps_.empty())
392 DisplayFirstPendingSwapImmediately();
393 }
394
395 void ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback() {
396 TRACE_EVENT0("gpu",
397 "ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback");
398
399 if (pending_swaps_.empty())
400 return;
401
402 const base::TimeTicks now = base::TimeTicks::Now();
403 if (IsFirstPendingSwapReadyToDisplay(now))
404 DisplayFirstPendingSwapImmediately();
405 PostCheckPendingSwapsCallbackIfNeeded(now);
406 }
407
408 void ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded(
409 const base::TimeTicks& now) {
410 TRACE_EVENT0("gpu",
411 "ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded");
412
413 if (pending_swaps_.empty()) {
414 display_pending_swap_timer_.Stop();
415 } else {
416 display_pending_swap_timer_.Start(
417 FROM_HERE,
418 pending_swaps_.front()->target_display_time - now,
419 base::Bind(&ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback,
420 weak_factory_.GetWeakPtr()));
421 }
422 } 232 }
423 233
424 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffers() { 234 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffers() {
425 return SwapBuffersInternal( 235 return SwapBuffersInternal(
426 gfx::Rect(0, 0, pixel_size_.width(), pixel_size_.height())); 236 gfx::Rect(0, 0, pixel_size_.width(), pixel_size_.height()));
427 } 237 }
428 238
429 gfx::SwapResult ImageTransportSurfaceOverlayMac::PostSubBuffer(int x, 239 gfx::SwapResult ImageTransportSurfaceOverlayMac::PostSubBuffer(int x,
430 int y, 240 int y,
431 int width, 241 int width,
(...skipping 14 matching lines...) Expand all
446 } 256 }
447 257
448 bool ImageTransportSurfaceOverlayMac::OnMakeCurrent(gfx::GLContext* context) { 258 bool ImageTransportSurfaceOverlayMac::OnMakeCurrent(gfx::GLContext* context) {
449 // Ensure that the context is on the appropriate GL renderer. The GL renderer 259 // Ensure that the context is on the appropriate GL renderer. The GL renderer
450 // will generally only change when the GPU changes. 260 // will generally only change when the GPU changes.
451 if (gl_renderer_id_ && context) 261 if (gl_renderer_id_ && context)
452 context->share_group()->SetRendererID(gl_renderer_id_); 262 context->share_group()->SetRendererID(gl_renderer_id_);
453 return true; 263 return true;
454 } 264 }
455 265
456 bool ImageTransportSurfaceOverlayMac::SetBackbufferAllocation(bool allocated) {
457 if (!allocated) {
458 DisplayAndClearAllPendingSwaps();
459 last_swap_time_ = base::TimeTicks();
460 }
461 return true;
462 }
463
464 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane( 266 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane(
465 int z_order, 267 int z_order,
466 gfx::OverlayTransform transform, 268 gfx::OverlayTransform transform,
467 gl::GLImage* image, 269 gl::GLImage* image,
468 const gfx::Rect& pixel_frame_rect, 270 const gfx::Rect& pixel_frame_rect,
469 const gfx::RectF& crop_rect) { 271 const gfx::RectF& crop_rect) {
470 if (transform != gfx::OVERLAY_TRANSFORM_NONE) { 272 if (transform != gfx::OVERLAY_TRANSFORM_NONE) {
471 DLOG(ERROR) << "Invalid overlay plane transform."; 273 DLOG(ERROR) << "Invalid overlay plane transform.";
472 return false; 274 return false;
473 } 275 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 } 313 }
512 314
513 bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const { 315 bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const {
514 return true; 316 return true;
515 } 317 }
516 318
517 bool ImageTransportSurfaceOverlayMac::Resize(const gfx::Size& pixel_size, 319 bool ImageTransportSurfaceOverlayMac::Resize(const gfx::Size& pixel_size,
518 float scale_factor, 320 float scale_factor,
519 bool has_alpha) { 321 bool has_alpha) {
520 // Flush through any pending frames. 322 // Flush through any pending frames.
521 DisplayAndClearAllPendingSwaps();
522 pixel_size_ = pixel_size; 323 pixel_size_ = pixel_size;
523 scale_factor_ = scale_factor; 324 scale_factor_ = scale_factor;
524 return true; 325 return true;
525 } 326 }
526 327
527 void ImageTransportSurfaceOverlayMac::OnGpuSwitched() { 328 void ImageTransportSurfaceOverlayMac::OnGpuSwitched() {
528 // Create a new context, and use the GL renderer ID that the new context gets. 329 // Create a new context, and use the GL renderer ID that the new context gets.
529 scoped_refptr<ui::IOSurfaceContext> context_on_new_gpu = 330 scoped_refptr<ui::IOSurfaceContext> context_on_new_gpu =
530 ui::IOSurfaceContext::Get(ui::IOSurfaceContext::kCALayerContext); 331 ui::IOSurfaceContext::Get(ui::IOSurfaceContext::kCALayerContext);
531 if (!context_on_new_gpu) 332 if (!context_on_new_gpu)
532 return; 333 return;
533 GLint context_renderer_id = -1; 334 GLint context_renderer_id = -1;
534 if (CGLGetParameter(context_on_new_gpu->cgl_context(), 335 if (CGLGetParameter(context_on_new_gpu->cgl_context(),
535 kCGLCPCurrentRendererID, 336 kCGLCPCurrentRendererID,
536 &context_renderer_id) != kCGLNoError) { 337 &context_renderer_id) != kCGLNoError) {
537 LOG(ERROR) << "Failed to create test context after GPU switch"; 338 LOG(ERROR) << "Failed to create test context after GPU switch";
538 return; 339 return;
539 } 340 }
540 gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask; 341 gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask;
541 342
542 // Post a task holding a reference to the new GL context. The reason for 343 // Post a task holding a reference to the new GL context. The reason for
543 // this is to avoid creating-then-destroying the context for every image 344 // this is to avoid creating-then-destroying the context for every image
544 // transport surface that is observing the GPU switch. 345 // transport surface that is observing the GPU switch.
545 base::MessageLoop::current()->PostTask( 346 base::MessageLoop::current()->PostTask(
546 FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu)); 347 FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu));
547 } 348 }
548 349
549 base::TimeTicks ImageTransportSurfaceOverlayMac::GetNextVSyncTimeAfter(
550 const base::TimeTicks& from, double interval_fraction) {
551 if (!vsync_parameters_valid_)
552 return from;
553
554 // Compute the previous vsync time.
555 base::TimeTicks previous_vsync =
556 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) +
557 vsync_timebase_;
558
559 // Return |interval_fraction| through the next vsync.
560 return previous_vsync + (1 + interval_fraction) * vsync_interval_;
561 }
562
563 } // namespace gpu 350 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/ipc/service/image_transport_surface_overlay_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698