1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_SURFACE_IMPL_H_ 6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_SURFACE_IMPL_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/macros.h" 12 #include "base/observer_list.h" 13 #include "base/optional.h" 14 #include "base/threading/thread_checker.h" 15 #include "base/util/type_safety/pass_key.h" 16 #include "build/build_config.h" 17 #include "components/viz/common/display/renderer_settings.h" 18 #include "components/viz/common/resources/resource_id.h" 19 #include "components/viz/service/display/skia_output_surface.h" 20 #include "components/viz/service/viz_service_export.h" 21 #include "gpu/command_buffer/common/sync_token.h" 22 #include "gpu/ipc/common/vulkan_ycbcr_info.h" 23 #include "gpu/ipc/in_process_command_buffer.h" 24 #include "third_party/skia/include/core/SkDeferredDisplayListRecorder.h" 25 #include "third_party/skia/include/core/SkOverdrawCanvas.h" 26 #include "third_party/skia/include/core/SkSurfaceCharacterization.h" 27 #include "third_party/skia/include/core/SkYUVAIndex.h" 28 29 namespace base { 30 class WaitableEvent; 31 } 32 33 namespace viz { 34 35 class ImageContextImpl; 36 class SkiaOutputSurfaceDependency; 37 class SkiaOutputSurfaceImplOnGpu; 38 39 // The SkiaOutputSurface implementation. It is the output surface for 40 // SkiaRenderer. It lives on the compositor thread, but it will post tasks 41 // to the GPU thread for initializing. Currently, SkiaOutputSurfaceImpl 42 // create a SkiaOutputSurfaceImplOnGpu on the GPU thread. It will be used 43 // for creating a SkSurface from the default framebuffer and providing the 44 // SkSurfaceCharacterization for the SkSurface. And then SkiaOutputSurfaceImpl 45 // will create SkDeferredDisplayListRecorder and SkCanvas for SkiaRenderer to 46 // render into. In SwapBuffers, it detaches a SkDeferredDisplayList from the 47 // recorder and plays it back on the framebuffer SkSurface on the GPU thread 48 // through SkiaOutputSurfaceImpleOnGpu. 49 class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { 50 public: 51 static std::unique_ptr<SkiaOutputSurface> Create( 52 std::unique_ptr<SkiaOutputSurfaceDependency> deps, 53 const RendererSettings& renderer_settings); 54 55 SkiaOutputSurfaceImpl(util::PassKey<SkiaOutputSurfaceImpl> pass_key, 56 std::unique_ptr<SkiaOutputSurfaceDependency> deps, 57 const RendererSettings& renderer_settings); 58 ~SkiaOutputSurfaceImpl() override; 59 60 // OutputSurface implementation: 61 gpu::SurfaceHandle GetSurfaceHandle() const override; 62 void BindToClient(OutputSurfaceClient* client) override; 63 void BindFramebuffer() override; 64 void SetDrawRectangle(const gfx::Rect& draw_rectangle) override; 65 void EnsureBackbuffer() override; 66 void DiscardBackbuffer() override; 67 void Reshape(const gfx::Size& size, 68 float device_scale_factor, 69 const gfx::ColorSpace& color_space, 70 gfx::BufferFormat format, 71 bool use_stencil) override; 72 void SetUpdateVSyncParametersCallback( 73 UpdateVSyncParametersCallback callback) override; 74 void SetGpuVSyncEnabled(bool enabled) override; 75 void SetGpuVSyncCallback(GpuVSyncCallback callback) override; 76 void SetDisplayTransformHint(gfx::OverlayTransform transform) override; 77 gfx::OverlayTransform GetDisplayTransform() override; 78 void SwapBuffers(OutputSurfaceFrame frame) override; 79 uint32_t GetFramebufferCopyTextureFormat() override; 80 bool IsDisplayedAsOverlayPlane() const override; 81 unsigned GetOverlayTextureId() const override; 82 bool HasExternalStencilTest() const override; 83 void ApplyExternalStencil() override; 84 unsigned UpdateGpuFence() override; 85 void SetNeedsSwapSizeNotifications( 86 bool needs_swap_size_notifications) override; 87 base::ScopedClosureRunner GetCacheBackBufferCb() override; 88 scoped_refptr<gpu::GpuTaskSchedulerHelper> GetGpuTaskSchedulerHelper() 89 override; 90 gfx::Rect GetCurrentFramebufferDamage() const override; 91 92 // SkiaOutputSurface implementation: 93 SkCanvas* BeginPaintCurrentFrame() override; 94 sk_sp<SkImage> MakePromiseSkImageFromYUV( 95 const std::vector<ImageContext*>& contexts, 96 sk_sp<SkColorSpace> image_color_space, 97 bool has_alpha) override; 98 void SwapBuffersSkipped() override; 99 void ScheduleOutputSurfaceAsOverlay( 100 OverlayProcessorInterface::OutputSurfaceOverlayPlane output_surface_plane) 101 override; 102 103 SkCanvas* BeginPaintRenderPass(const RenderPassId& id, 104 const gfx::Size& surface_size, 105 ResourceFormat format, 106 bool mipmap, 107 sk_sp<SkColorSpace> color_space) override; 108 gpu::SyncToken SubmitPaint(base::OnceClosure on_finished) override; 109 void MakePromiseSkImage(ImageContext* image_context) override; 110 sk_sp<SkImage> MakePromiseSkImageFromRenderPass( 111 const RenderPassId& id, 112 const gfx::Size& size, 113 ResourceFormat format, 114 bool mipmap, 115 sk_sp<SkColorSpace> color_space) override; 116 117 void RemoveRenderPassResource(std::vector<RenderPassId> ids) override; 118 void ScheduleOverlays(OverlayList overlays, 119 std::vector<gpu::SyncToken> sync_tokens) override; 120 121 #if defined(OS_WIN) 122 void SetEnableDCLayers(bool enable) override; 123 #endif 124 void CopyOutput(RenderPassId id, 125 const copy_output::RenderPassGeometry& geometry, 126 const gfx::ColorSpace& color_space, 127 std::unique_ptr<CopyOutputRequest> request) override; 128 void AddContextLostObserver(ContextLostObserver* observer) override; 129 void RemoveContextLostObserver(ContextLostObserver* observer) override; 130 131 // ExternalUseClient implementation: 132 void ReleaseImageContexts( 133 std::vector<std::unique_ptr<ImageContext>> image_contexts) override; 134 std::unique_ptr<ExternalUseClient::ImageContext> CreateImageContext( 135 const gpu::MailboxHolder& holder, 136 const gfx::Size& size, 137 ResourceFormat format, 138 const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info, 139 sk_sp<SkColorSpace> color_space) override; 140 141 gpu::MemoryTracker* GetMemoryTracker() override; 142 143 // Set the fields of |capabilities_| and propagates to |impl_on_gpu_|. Should 144 // be called after BindToClient(). 145 void SetCapabilitiesForTesting(gfx::SurfaceOrigin output_surface_origin); 146 147 // Used in unit tests. 148 void ScheduleGpuTaskForTesting( 149 base::OnceClosure callback, 150 std::vector<gpu::SyncToken> sync_tokens) override; 151 152 private: 153 bool Initialize(); 154 void InitializeOnGpuThread(GpuVSyncCallback vsync_callback_runner, 155 base::WaitableEvent* event, 156 bool* result); 157 SkSurfaceCharacterization CreateSkSurfaceCharacterization( 158 const gfx::Size& surface_size, 159 ResourceFormat format, 160 bool mipmap, 161 sk_sp<SkColorSpace> color_space, 162 bool is_root_render_pass); 163 void DidSwapBuffersComplete(gpu::SwapBuffersCompleteParams params, 164 const gfx::Size& pixel_size); 165 void BufferPresented(const gfx::PresentationFeedback& feedback); 166 167 // Provided as a callback for the GPU thread. 168 void OnGpuVSync(base::TimeTicks timebase, base::TimeDelta interval); 169 170 void ScheduleGpuTask(base::OnceClosure callback, 171 std::vector<gpu::SyncToken> sync_tokens); 172 GrBackendFormat GetGrBackendFormatForTexture( 173 ResourceFormat resource_format, 174 uint32_t gl_texture_target, 175 const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info); 176 void PrepareYUVATextureIndices(const std::vector<ImageContext*>& contexts, 177 bool has_alpha, 178 SkYUVAIndex indices[4]); 179 void ContextLost(); 180 181 void RecreateRootRecorder(); 182 183 OutputSurfaceClient* client_ = nullptr; 184 bool needs_swap_size_notifications_ = false; 185 186 // Images for current frame or render pass. 187 std::vector<ImageContextImpl*> images_in_current_paint_; 188 189 THREAD_CHECKER(thread_checker_); 190 191 // Observers for context lost. 192 base::ObserverList<ContextLostObserver>::Unchecked observers_; 193 194 uint64_t sync_fence_release_ = 0; 195 std::unique_ptr<SkiaOutputSurfaceDependency> dependency_; 196 UpdateVSyncParametersCallback update_vsync_parameters_callback_; 197 GpuVSyncCallback gpu_vsync_callback_; 198 bool is_displayed_as_overlay_ = false; 199 200 gfx::Size size_; 201 gfx::ColorSpace color_space_; 202 bool is_hdr_ = false; 203 SkSurfaceCharacterization characterization_; 204 base::Optional<SkDeferredDisplayListRecorder> root_recorder_; 205 206 class ScopedPaint { 207 public: 208 explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder); 209 ScopedPaint(SkSurfaceCharacterization characterization, 210 RenderPassId render_pass_id); 211 ~ScopedPaint(); 212 recorder()213 SkDeferredDisplayListRecorder* recorder() { return recorder_; } render_pass_id()214 RenderPassId render_pass_id() { return render_pass_id_; } 215 216 private: 217 // This is recorder being used for current paint 218 SkDeferredDisplayListRecorder* recorder_; 219 // If we need new recorder for this Paint (i.e it's not root render pass), 220 // it's stored here 221 base::Optional<SkDeferredDisplayListRecorder> recorder_storage_; 222 const RenderPassId render_pass_id_; 223 }; 224 225 // This holds current paint info 226 base::Optional<ScopedPaint> current_paint_; 227 228 // The SkDDL recorder is used for overdraw feedback. It is created by 229 // BeginPaintOverdraw, and FinishPaintCurrentFrame will turn it into a SkDDL 230 // and play the SkDDL back on the GPU thread. 231 base::Optional<SkDeferredDisplayListRecorder> overdraw_surface_recorder_; 232 233 // |overdraw_canvas_| is used to record draw counts. 234 base::Optional<SkOverdrawCanvas> overdraw_canvas_; 235 236 // |nway_canvas_| contains |overdraw_canvas_| and root canvas. 237 base::Optional<SkNWayCanvas> nway_canvas_; 238 239 // The cache for promise image created from render passes. 240 base::flat_map<RenderPassId, std::unique_ptr<ImageContextImpl>> 241 render_pass_image_cache_; 242 243 // Sync tokens for resources which are used for the current frame or render 244 // pass. 245 std::vector<gpu::SyncToken> resource_sync_tokens_; 246 247 const RendererSettings renderer_settings_; 248 249 // The display transform relative to the hardware natural orientation, 250 // applied to the frame content. The transform can be rotations in 90 degree 251 // increments or flips. 252 gfx::OverlayTransform pre_transform_ = gfx::OVERLAY_TRANSFORM_NONE; 253 254 // |gpu_task_scheduler_| holds a gpu::SingleTaskSequence, and helps schedule 255 // tasks on GPU as a single sequence. It is shared with OverlayProcessor so 256 // compositing and overlay processing are in order. A gpu::SingleTaskSequence 257 // in regular Viz is implemented by SchedulerSequence. In Android WebView 258 // gpu::SingleTaskSequence is implemented on top of WebView's task queue. 259 scoped_refptr<gpu::GpuTaskSchedulerHelper> gpu_task_scheduler_; 260 261 // |impl_on_gpu| is created and destroyed on the GPU thread. 262 std::unique_ptr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu_; 263 264 bool has_set_draw_rectangle_for_frame_ = false; 265 base::Optional<gfx::Rect> draw_rectangle_; 266 267 // We defer the draw to the framebuffer until SwapBuffers or CopyOutput 268 // to avoid the expense of posting a task and calling MakeCurrent. 269 base::OnceCallback<bool()> deferred_framebuffer_draw_closure_; 270 271 // Current buffer index. 272 size_t current_buffer_ = 0; 273 // Damage area of the buffer. Differ to the last submit buffer. 274 std::vector<gfx::Rect> damage_of_buffers_; 275 // Track if the current buffer content is changed. 276 bool current_buffer_modified_ = false; 277 278 base::WeakPtr<SkiaOutputSurfaceImpl> weak_ptr_; 279 base::WeakPtrFactory<SkiaOutputSurfaceImpl> weak_ptr_factory_{this}; 280 281 DISALLOW_COPY_AND_ASSIGN(SkiaOutputSurfaceImpl); 282 }; 283 284 } // namespace viz 285 286 #endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_SURFACE_IMPL_H_ 287