| OLD | NEW |
| 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/browser/compositor/gpu_surfaceless_browser_compositor_output_s
urface.h" | 5 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_s
urface.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/barrier_closure.h" |
| 10 #include "base/base64.h" |
| 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/trace_event/trace_event.h" |
| 9 #include "cc/output/output_surface_client.h" | 14 #include "cc/output/output_surface_client.h" |
| 10 #include "cc/output/output_surface_frame.h" | 15 #include "cc/output/output_surface_frame.h" |
| 11 #include "components/display_compositor/buffer_queue.h" | 16 #include "components/display_compositor/buffer_queue.h" |
| 12 #include "components/display_compositor/compositor_overlay_candidate_validator.h
" | 17 #include "components/display_compositor/compositor_overlay_candidate_validator.h
" |
| 13 #include "components/display_compositor/gl_helper.h" | 18 #include "components/display_compositor/gl_helper.h" |
| 14 #include "content/browser/compositor/reflector_impl.h" | 19 #include "content/browser/compositor/reflector_impl.h" |
| 15 #include "gpu/GLES2/gl2extchromium.h" | 20 #include "gpu/GLES2/gl2extchromium.h" |
| 16 #include "gpu/command_buffer/client/gles2_interface.h" | 21 #include "gpu/command_buffer/client/gles2_interface.h" |
| 17 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" | 22 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" |
| 23 #include "third_party/skia/include/core/SkBitmap.h" |
| 24 #include "ui/gfx/codec/png_codec.h" |
| 25 #include "ui/gfx/skia_util.h" |
| 18 | 26 |
| 19 namespace content { | 27 namespace content { |
| 28 namespace { |
| 29 |
| 30 // How frequently to do a readback of the framebuffer and overlay textures |
| 31 // when tracing is turned on. |
| 32 const size_t kSnapshotInterval = 60; |
| 33 |
| 34 class Snapshot : public base::trace_event::ConvertableToTraceFormat { |
| 35 public: |
| 36 explicit Snapshot(base::TimeTicks vsync_time) : vsync_time_(vsync_time) {} |
| 37 |
| 38 // base::trace_event::ConvertableToTraceFormat implementation. |
| 39 void AppendAsTraceFormat(std::string* out) const override { |
| 40 *out += "{"; |
| 41 // Add framebuffer or the first overlay texture as screenshot if available. |
| 42 const SkBitmap& bitmap = overlay_texture_bitmaps_.empty() |
| 43 ? framebuffer_bitmap_ |
| 44 : overlay_texture_bitmaps_.front(); |
| 45 if (!bitmap.isNull()) { |
| 46 std::vector<unsigned char> png_data; |
| 47 bool png_ok = gfx::PNGCodec::Encode( |
| 48 static_cast<unsigned char*>(bitmap.getPixels()), |
| 49 gfx::PNGCodec::FORMAT_RGBA, gfx::SkISizeToSize(bitmap.dimensions()), |
| 50 bitmap.rowBytes(), false, std::vector<gfx::PNGCodec::Comment>(), |
| 51 &png_data); |
| 52 DCHECK(png_ok); |
| 53 |
| 54 base::StringPiece base64_input( |
| 55 reinterpret_cast<const char*>(&png_data[0]), png_data.size()); |
| 56 std::string base64_output; |
| 57 Base64Encode(base64_input, &base64_output); |
| 58 |
| 59 *out += "\"screenshot\":\"" + base64_output + "\","; |
| 60 } |
| 61 *out += "\"vsyncTime\":" + |
| 62 base::Uint64ToString(vsync_time_.ToInternalValue()) + ","; |
| 63 uint64_t elapsed_time = |
| 64 (base::TimeTicks::Now() - vsync_time_).ToInternalValue(); |
| 65 *out += "\"vsyncJsTime\":" + |
| 66 base::Uint64ToString( |
| 67 static_cast<uint64_t>(base::Time::Now().ToJsTime() * |
| 68 base::Time::kMicrosecondsPerMillisecond) - |
| 69 elapsed_time) + |
| 70 ","; |
| 71 *out += "\"overlayTextures\":\"" + |
| 72 base::SizeTToString(overlay_texture_bitmaps_.size()) + "\""; |
| 73 *out += "}"; |
| 74 } |
| 75 |
| 76 SkBitmap& framebuffer_bitmap() { return framebuffer_bitmap_; } |
| 77 std::vector<SkBitmap>& overlay_texture_bitmaps() { |
| 78 return overlay_texture_bitmaps_; |
| 79 } |
| 80 |
| 81 private: |
| 82 const base::TimeTicks vsync_time_; |
| 83 SkBitmap framebuffer_bitmap_; |
| 84 std::vector<SkBitmap> overlay_texture_bitmaps_; |
| 85 |
| 86 DISALLOW_COPY_AND_ASSIGN(Snapshot); |
| 87 }; |
| 88 |
| 89 void CallbackForwader(const base::Closure& callback, bool result) { |
| 90 callback.Run(); |
| 91 } |
| 92 |
| 93 void SaveSnapshot( |
| 94 void* id, |
| 95 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> snapshot, |
| 96 base::TimeTicks page_flip_time) { |
| 97 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), |
| 98 "SaveSnapshot"); |
| 99 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP( |
| 100 TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), "cc::OutputSurface", |
| 101 id, page_flip_time, std::move(snapshot)); |
| 102 } |
| 103 |
| 104 } // namespace |
| 20 | 105 |
| 21 GpuSurfacelessBrowserCompositorOutputSurface:: | 106 GpuSurfacelessBrowserCompositorOutputSurface:: |
| 22 GpuSurfacelessBrowserCompositorOutputSurface( | 107 GpuSurfacelessBrowserCompositorOutputSurface( |
| 23 scoped_refptr<ui::ContextProviderCommandBuffer> context, | 108 scoped_refptr<ui::ContextProviderCommandBuffer> context, |
| 24 gpu::SurfaceHandle surface_handle, | 109 gpu::SurfaceHandle surface_handle, |
| 25 const UpdateVSyncParametersCallback& update_vsync_parameters_callback, | 110 const UpdateVSyncParametersCallback& update_vsync_parameters_callback, |
| 26 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> | 111 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> |
| 27 overlay_candidate_validator, | 112 overlay_candidate_validator, |
| 28 unsigned int target, | 113 unsigned int target, |
| 29 unsigned int internalformat, | 114 unsigned int internalformat, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 44 // shifts the start of the new frame forward relative to the old | 129 // shifts the start of the new frame forward relative to the old |
| 45 // implementation. | 130 // implementation. |
| 46 capabilities_.max_frames_pending = 2; | 131 capabilities_.max_frames_pending = 2; |
| 47 | 132 |
| 48 gl_helper_.reset(new display_compositor::GLHelper( | 133 gl_helper_.reset(new display_compositor::GLHelper( |
| 49 context_provider_->ContextGL(), context_provider_->ContextSupport())); | 134 context_provider_->ContextGL(), context_provider_->ContextSupport())); |
| 50 buffer_queue_.reset(new display_compositor::BufferQueue( | 135 buffer_queue_.reset(new display_compositor::BufferQueue( |
| 51 context_provider_->ContextGL(), target, internalformat, format, | 136 context_provider_->ContextGL(), target, internalformat, format, |
| 52 gl_helper_.get(), gpu_memory_buffer_manager_, surface_handle)); | 137 gl_helper_.get(), gpu_memory_buffer_manager_, surface_handle)); |
| 53 buffer_queue_->Initialize(); | 138 buffer_queue_->Initialize(); |
| 139 |
| 140 TRACE_EVENT_OBJECT_CREATED_WITH_ID( |
| 141 TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), "cc::OutputSurface", |
| 142 this); |
| 54 } | 143 } |
| 55 | 144 |
| 56 GpuSurfacelessBrowserCompositorOutputSurface:: | 145 GpuSurfacelessBrowserCompositorOutputSurface:: |
| 57 ~GpuSurfacelessBrowserCompositorOutputSurface() { | 146 ~GpuSurfacelessBrowserCompositorOutputSurface() { |
| 147 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
| 148 TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), "cc::OutputSurface", |
| 149 this); |
| 58 } | 150 } |
| 59 | 151 |
| 60 bool GpuSurfacelessBrowserCompositorOutputSurface::IsDisplayedAsOverlayPlane() | 152 bool GpuSurfacelessBrowserCompositorOutputSurface::IsDisplayedAsOverlayPlane() |
| 61 const { | 153 const { |
| 62 return true; | 154 return true; |
| 63 } | 155 } |
| 64 | 156 |
| 65 unsigned GpuSurfacelessBrowserCompositorOutputSurface::GetOverlayTextureId() | 157 unsigned GpuSurfacelessBrowserCompositorOutputSurface::GetOverlayTextureId() |
| 66 const { | 158 const { |
| 67 return buffer_queue_->current_texture_id(); | 159 return buffer_queue_->current_texture_id(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 gfx::SwapResult result, | 198 gfx::SwapResult result, |
| 107 const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) { | 199 const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) { |
| 108 bool force_swap = false; | 200 bool force_swap = false; |
| 109 if (result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) { | 201 if (result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) { |
| 110 // Even through the swap failed, this is a fixable error so we can pretend | 202 // Even through the swap failed, this is a fixable error so we can pretend |
| 111 // it succeeded to the rest of the system. | 203 // it succeeded to the rest of the system. |
| 112 result = gfx::SwapResult::SWAP_ACK; | 204 result = gfx::SwapResult::SWAP_ACK; |
| 113 buffer_queue_->RecreateBuffers(); | 205 buffer_queue_->RecreateBuffers(); |
| 114 force_swap = true; | 206 force_swap = true; |
| 115 } | 207 } |
| 208 bool is_tracing; |
| 209 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
| 210 TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), &is_tracing); |
| 211 // Create a snapshot of the previous frame now that we've received an ack |
| 212 // for the new frame. |last_timebase_| is the page flip time for the |
| 213 // previous frame. |
| 214 if (is_tracing && !(++swap_count_ % kSnapshotInterval)) { |
| 215 // |last_vsync_timebase_| should contain an accurate vsync time stamp for |
| 216 // the previous frame at this time. |
| 217 Snapshot* snapshot = new Snapshot(last_vsync_timebase_); |
| 218 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
| 219 scoped_snapshot(snapshot); |
| 220 base::Closure save_snaphost_callback = |
| 221 base::Bind(&SaveSnapshot, this, base::Passed(&scoped_snapshot), |
| 222 last_vsync_timebase_); |
| 223 base::Closure barrier_closure = |
| 224 base::BarrierClosure(2, save_snaphost_callback); |
| 225 buffer_queue_->ReadbackDisplayedFramebuffer( |
| 226 &snapshot->framebuffer_bitmap(), |
| 227 base::Bind(&CallbackForwader, barrier_closure)); |
| 228 client_->ReadbackSwappedOverlayTextures( |
| 229 &snapshot->overlay_texture_bitmaps(), |
| 230 base::Bind(&CallbackForwader, barrier_closure)); |
| 231 } |
| 116 buffer_queue_->PageFlipComplete(); | 232 buffer_queue_->PageFlipComplete(); |
| 117 GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted( | 233 GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted( |
| 118 latency_info, result, params_mac); | 234 latency_info, result, params_mac); |
| 119 if (force_swap) | 235 if (force_swap) |
| 120 client_->SetNeedsRedrawRect(gfx::Rect(swap_size_)); | 236 client_->SetNeedsRedrawRect(gfx::Rect(swap_size_)); |
| 121 } | 237 } |
| 122 | 238 |
| 123 } // namespace content | 239 } // namespace content |
| OLD | NEW |