OLD | NEW |
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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 base::TimeTicks after_flush_before_commit_time; | 183 base::TimeTicks after_flush_before_commit_time; |
184 | 184 |
185 // If supported, use GLFence to ensure that we haven't gotten more than one | 185 // If supported, use GLFence to ensure that we haven't gotten more than one |
186 // frame ahead of GL. | 186 // frame ahead of GL. |
187 if (gl::GLFence::IsSupported()) { | 187 if (gl::GLFence::IsSupported()) { |
188 CheckGLErrors("Before fence/flush"); | 188 CheckGLErrors("Before fence/flush"); |
189 | 189 |
190 // If we have gotten more than one frame ahead of GL, wait for the previous | 190 // If we have gotten more than one frame ahead of GL, wait for the previous |
191 // frame to complete. | 191 // frame to complete. |
192 if (previous_frame_fence_) { | 192 if (previous_frame_fence_) { |
193 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::ClientWait"); | 193 TRACE_EVENT0("gpu", "ClientWait"); |
194 | 194 |
195 // Ensure we are using the context with which the fence was created. | 195 // Ensure we are using the context with which the fence was created. |
196 gl::ScopedCGLSetCurrentContext scoped_set_current(fence_context_obj_); | 196 gl::ScopedCGLSetCurrentContext scoped_set_current(fence_context_obj_); |
197 | 197 |
198 // While we could call GLFence::ClientWait, this performs a busy wait on | 198 // While we could call GLFence::ClientWait, this performs a busy wait on |
199 // Mac, leading to high CPU usage. Instead we poll with a 1ms delay. This | 199 // Mac, leading to high CPU usage. Instead we poll with a 1ms delay. This |
200 // should have minimal impact, as we will only hit this path when we are | 200 // should have minimal impact, as we will only hit this path when we are |
201 // more than one frame (16ms) behind. | 201 // more than one frame (16ms) behind. |
202 // | 202 // |
203 // Note that on some platforms (10.9), fences appear to sometimes get | 203 // Note that on some platforms (10.9), fences appear to sometimes get |
(...skipping 11 matching lines...) Expand all Loading... |
215 } | 215 } |
216 | 216 |
217 before_flush_time = base::TimeTicks::Now(); | 217 before_flush_time = base::TimeTicks::Now(); |
218 | 218 |
219 // Create a fence for the current frame's work and save the context. | 219 // Create a fence for the current frame's work and save the context. |
220 previous_frame_fence_.reset(gl::GLFence::Create()); | 220 previous_frame_fence_.reset(gl::GLFence::Create()); |
221 fence_context_obj_.reset(CGLGetCurrentContext(), | 221 fence_context_obj_.reset(CGLGetCurrentContext(), |
222 base::scoped_policy::RETAIN); | 222 base::scoped_policy::RETAIN); |
223 | 223 |
224 // A glFlush is necessary to ensure correct content appears. | 224 // A glFlush is necessary to ensure correct content appears. |
225 glFlush(); | 225 { |
226 CheckGLErrors("After fence/flush"); | 226 TRACE_EVENT0("gpu", "glFlush"); |
| 227 glFlush(); |
| 228 CheckGLErrors("After fence/flush"); |
| 229 } |
227 | 230 |
228 after_flush_before_commit_time = base::TimeTicks::Now(); | 231 after_flush_before_commit_time = base::TimeTicks::Now(); |
229 UMA_HISTOGRAM_TIMES("GPU.IOSurface.GLFlushTime", | 232 UMA_HISTOGRAM_TIMES("GPU.IOSurface.GLFlushTime", |
230 after_flush_before_commit_time - before_flush_time); | 233 after_flush_before_commit_time - before_flush_time); |
231 } else { | 234 } else { |
232 // GLFence isn't supported - issue a glFinish on each frame to ensure | 235 // GLFence isn't supported - issue a glFinish on each frame to ensure |
233 // there is backpressure from GL. | 236 // there is backpressure from GL. |
234 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFinish"); | 237 TRACE_EVENT0("gpu", "glFinish"); |
235 CheckGLErrors("Before finish"); | 238 CheckGLErrors("Before finish"); |
236 glFinish(); | 239 glFinish(); |
237 CheckGLErrors("After finish"); | 240 CheckGLErrors("After finish"); |
238 after_flush_before_commit_time = base::TimeTicks::Now(); | 241 after_flush_before_commit_time = base::TimeTicks::Now(); |
239 } | 242 } |
240 | 243 |
241 bool fullscreen_low_power_layer_valid = false; | 244 bool fullscreen_low_power_layer_valid = false; |
242 ca_layer_tree_coordinator_->CommitPendingTreesToCA( | 245 { |
243 pixel_damage_rect, &fullscreen_low_power_layer_valid); | 246 TRACE_EVENT0("gpu", "CommitPendingTreesToCA"); |
| 247 ca_layer_tree_coordinator_->CommitPendingTreesToCA( |
| 248 pixel_damage_rect, &fullscreen_low_power_layer_valid); |
| 249 } |
244 | 250 |
245 base::TimeTicks after_transaction_time = base::TimeTicks::Now(); | 251 base::TimeTicks after_transaction_time = base::TimeTicks::Now(); |
246 UMA_HISTOGRAM_TIMES("GPU.IOSurface.CATransactionTime", | 252 UMA_HISTOGRAM_TIMES("GPU.IOSurface.CATransactionTime", |
247 after_transaction_time - after_flush_before_commit_time); | 253 after_transaction_time - after_flush_before_commit_time); |
248 | 254 |
249 // Update the latency info to reflect the swap time. | 255 // Update the latency info to reflect the swap time. |
250 for (auto& latency_info : latency_info_) { | 256 for (auto& latency_info : latency_info_) { |
251 latency_info.AddLatencyNumberWithTimestamp( | 257 latency_info.AddLatencyNumberWithTimestamp( |
252 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, | 258 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, |
253 after_flush_before_commit_time, 1); | 259 after_flush_before_commit_time, 1); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask; | 405 gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask; |
400 | 406 |
401 // Post a task holding a reference to the new GL context. The reason for | 407 // Post a task holding a reference to the new GL context. The reason for |
402 // this is to avoid creating-then-destroying the context for every image | 408 // this is to avoid creating-then-destroying the context for every image |
403 // transport surface that is observing the GPU switch. | 409 // transport surface that is observing the GPU switch. |
404 base::ThreadTaskRunnerHandle::Get()->PostTask( | 410 base::ThreadTaskRunnerHandle::Get()->PostTask( |
405 FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu)); | 411 FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu)); |
406 } | 412 } |
407 | 413 |
408 } // namespace gpu | 414 } // namespace gpu |
OLD | NEW |