skia_renderer.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // Copyright 2012 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. #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_
  5. #define COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_
  6. #include <memory>
  7. #include <tuple>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/containers/flat_map.h"
  11. #include "base/containers/flat_set.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "build/build_config.h"
  14. #include "cc/cc_export.h"
  15. #include "components/viz/service/display/direct_renderer.h"
  16. #include "components/viz/service/display/display_resource_provider_skia.h"
  17. #include "components/viz/service/viz_service_export.h"
  18. #include "third_party/skia/include/core/SkCanvas.h"
  19. #include "ui/gfx/color_conversion_sk_filter_cache.h"
  20. #include "ui/gfx/geometry/mask_filter_info.h"
  21. #include "ui/latency/latency_info.h"
  22. class SkColorFilter;
  23. namespace viz {
  24. class AggregatedRenderPassDrawQuad;
  25. class DebugBorderDrawQuad;
  26. class DelegatedInkPointRendererBase;
  27. class DelegatedInkHandler;
  28. class PictureDrawQuad;
  29. class SkiaOutputSurface;
  30. class SolidColorDrawQuad;
  31. class TextureDrawQuad;
  32. class TileDrawQuad;
  33. class YUVVideoDrawQuad;
  34. // TODO(795132): SkColorSpace is only a subset comparing to gfx::ColorSpace.
  35. // Need to figure out support for color space that is not covered by
  36. // SkColorSpace.
  37. class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
  38. public:
  39. // TODO(penghuang): Remove skia_output_surface when DDL is used everywhere.
  40. SkiaRenderer(const RendererSettings* settings,
  41. const DebugRendererSettings* debug_settings,
  42. OutputSurface* output_surface,
  43. DisplayResourceProviderSkia* resource_provider,
  44. OverlayProcessorInterface* overlay_processor,
  45. SkiaOutputSurface* skia_output_surface);
  46. SkiaRenderer(const SkiaRenderer&) = delete;
  47. SkiaRenderer& operator=(const SkiaRenderer&) = delete;
  48. ~SkiaRenderer() override;
  49. void SwapBuffers(SwapFrameData swap_frame_data) override;
  50. void SwapBuffersSkipped() override;
  51. void SwapBuffersComplete(gfx::GpuFenceHandle release_fence) override;
  52. void BuffersPresented() override;
  53. void DidReceiveReleasedOverlays(
  54. const std::vector<gpu::Mailbox>& released_overlays) override;
  55. void SetDisablePictureQuadImageFiltering(bool disable) {
  56. disable_picture_quad_image_filtering_ = disable;
  57. }
  58. DelegatedInkPointRendererBase* GetDelegatedInkPointRenderer(
  59. bool create_if_necessary) override;
  60. void SetDelegatedInkMetadata(
  61. std::unique_ptr<gfx::DelegatedInkMetadata> metadata) override;
  62. protected:
  63. bool CanPartialSwap() override;
  64. void UpdateRenderPassTextures(
  65. const AggregatedRenderPassList& render_passes_in_draw_order,
  66. const base::flat_map<AggregatedRenderPassId, RenderPassRequirements>&
  67. render_passes_in_frame) override;
  68. void AllocateRenderPassResourceIfNeeded(
  69. const AggregatedRenderPassId& render_pass_id,
  70. const RenderPassRequirements& requirements) override;
  71. bool IsRenderPassResourceAllocated(
  72. const AggregatedRenderPassId& render_pass_id) const override;
  73. gfx::Size GetRenderPassBackingPixelSize(
  74. const AggregatedRenderPassId& render_pass_id) override;
  75. void BindFramebufferToOutputSurface() override;
  76. void BindFramebufferToTexture(
  77. const AggregatedRenderPassId render_pass_id) override;
  78. void SetScissorTestRect(const gfx::Rect& scissor_rect) override;
  79. void PrepareSurfaceForPass(SurfaceInitializationMode initialization_mode,
  80. const gfx::Rect& render_pass_scissor) override;
  81. void DoDrawQuad(const DrawQuad* quad, const gfx::QuadF* draw_region) override;
  82. void BeginDrawingFrame() override;
  83. void FinishDrawingFrame() override;
  84. bool FlippedFramebuffer() const override;
  85. void EnsureScissorTestEnabled() override;
  86. void EnsureScissorTestDisabled() override;
  87. void CopyDrawnRenderPass(const copy_output::RenderPassGeometry& geometry,
  88. std::unique_ptr<CopyOutputRequest> request) override;
  89. void DidChangeVisibility() override;
  90. void FinishDrawingQuadList() override;
  91. void GenerateMipmap() override;
  92. void SetDelegatedInkPointRendererSkiaForTest(
  93. std::unique_ptr<DelegatedInkPointRendererSkia> renderer) override;
  94. std::unique_ptr<DelegatedInkHandler> delegated_ink_handler_;
  95. private:
  96. enum class BypassMode;
  97. struct DrawQuadParams;
  98. struct DrawRPDQParams;
  99. class ScopedSkImageBuilder;
  100. class ScopedYUVSkImageBuilder;
  101. void ClearCanvas(SkColor4f color);
  102. void ClearFramebuffer();
  103. // Callers should init an SkAutoCanvasRestore before calling this function.
  104. // |scissor_rect| and |mask_filter_info| should be in device space,
  105. // i.e. same space that |cdt| will transform subsequent draws into.
  106. void PrepareCanvas(
  107. const absl::optional<gfx::Rect>& scissor_rect,
  108. const absl::optional<gfx::MaskFilterInfo>& mask_filter_info,
  109. const gfx::Transform* cdt);
  110. void PrepareGradient(
  111. const absl::optional<gfx::MaskFilterInfo>& mask_filter_info);
  112. // Further modify the canvas as needed to apply the effects represented by
  113. // |rpdq_params|. Call Prepare[Paint|Color]OrCanvasForRPDQ when possible,
  114. // in order apply the RPDQ effects into a more efficient format.
  115. void PrepareCanvasForRPDQ(const DrawRPDQParams& rpdq_params,
  116. DrawQuadParams* params);
  117. // Attempt to apply the effects in |rpdq_params| to the paint used to draw
  118. // the quad; otherwise modify the current canvas instead.
  119. void PreparePaintOrCanvasForRPDQ(const DrawRPDQParams& rpdq_params,
  120. DrawQuadParams* params,
  121. SkPaint* paint);
  122. // Attempt to apply the effects in |rpdq_params| to the color used to draw
  123. // the quad; otherwise modify the current canvas as a fallback.
  124. void PrepareColorOrCanvasForRPDQ(const DrawRPDQParams& rpdq_params,
  125. DrawQuadParams* params,
  126. SkColor4f* color);
  127. // The returned DrawQuadParams can be modified by the DrawX calls that accept
  128. // params so that they can apply explicit data transforms before sending to
  129. // Skia in a consistent manner.
  130. DrawQuadParams CalculateDrawQuadParams(const gfx::Transform& target_to_device,
  131. const gfx::Rect* scissor_rect,
  132. const DrawQuad* quad,
  133. const gfx::QuadF* draw_region) const;
  134. DrawRPDQParams CalculateRPDQParams(const AggregatedRenderPassDrawQuad* quad,
  135. DrawQuadParams* params);
  136. // Modifies |params| and |rpdq_params| to apply correctly when drawing the
  137. // RenderPass directly via |bypass_quad|.
  138. BypassMode CalculateBypassParams(const DrawQuad* bypass_quad,
  139. DrawRPDQParams* rpdq_params,
  140. DrawQuadParams* params) const;
  141. SkCanvas::ImageSetEntry MakeEntry(const SkImage* image,
  142. int matrix_index,
  143. const DrawQuadParams& params) const;
  144. // Returns overall constraint to pass to Skia, and modifies |params| to
  145. // emulate content area clamping different from the provided texture coords.
  146. SkCanvas::SrcRectConstraint ResolveTextureConstraints(
  147. const SkImage* image,
  148. const gfx::RectF& valid_texel_bounds,
  149. DrawQuadParams* params) const;
  150. bool MustFlushBatchedQuads(const DrawQuad* new_quad,
  151. const DrawRPDQParams* rpdq_params,
  152. const DrawQuadParams& params) const;
  153. void AddQuadToBatch(const SkImage* image,
  154. const gfx::RectF& valid_texel_bounds,
  155. DrawQuadParams* params);
  156. void FlushBatchedQuads();
  157. // Utility function that calls appropriate draw function based on quad
  158. // material. If |rpdq_params| is not null, then |quad| is assumed to be the
  159. // bypass quad associated with the RenderPass that defined the |rpdq_params|.
  160. void DrawQuadInternal(const DrawQuad* quad,
  161. const DrawRPDQParams* rpdq_params,
  162. DrawQuadParams* params);
  163. // Utility to draw a single quad as a filled color, and optionally apply the
  164. // effects defined in |rpdq_params| when the quad is bypassing the render pass
  165. void DrawColoredQuad(SkColor4f color,
  166. const DrawRPDQParams* rpdq_params,
  167. DrawQuadParams* params);
  168. // Utility to make a single ImageSetEntry and draw it with the complex paint,
  169. // and optionally apply the effects defined in |rpdq_params| when the quad is
  170. // bypassing the render pass
  171. void DrawSingleImage(const SkImage* image,
  172. const gfx::RectF& valid_texel_bounds,
  173. const DrawRPDQParams* rpdq_params,
  174. SkPaint* paint,
  175. DrawQuadParams* params);
  176. void DrawPaintOpBuffer(const cc::PaintOpBuffer* buffer,
  177. const absl::optional<SkColor4f>& clear_color,
  178. const TileDrawQuad* quad,
  179. const DrawQuadParams* params);
  180. // RPDQ, DebugBorder and picture quads cannot be batched. They
  181. // either are not textures (debug, picture), or it's very likely
  182. // the texture will have advanced paint effects (rpdq). Additionally, they do
  183. // not support being drawn directly for a pass-through RenderPass.
  184. void DrawRenderPassQuad(const AggregatedRenderPassDrawQuad* quad,
  185. DrawQuadParams* params);
  186. void DrawDebugBorderQuad(const DebugBorderDrawQuad* quad,
  187. DrawQuadParams* params);
  188. void DrawPictureQuad(const PictureDrawQuad* quad, DrawQuadParams* params);
  189. // Solid-color quads are not batchable, but can be drawn directly in place of
  190. // a RenderPass (hence it takes the optional DrawRPDQParams).
  191. void DrawSolidColorQuad(const SolidColorDrawQuad* quad,
  192. const DrawRPDQParams* rpdq_params,
  193. DrawQuadParams* params);
  194. void DrawTextureQuad(const TextureDrawQuad* quad,
  195. const DrawRPDQParams* rpdq_params,
  196. DrawQuadParams* params);
  197. void DrawTileDrawQuad(const TileDrawQuad* quad,
  198. const DrawRPDQParams* rpdq_params,
  199. DrawQuadParams* params);
  200. void DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
  201. const DrawRPDQParams* rpdq_params,
  202. DrawQuadParams* params);
  203. void DrawUnsupportedQuad(const DrawQuad* quad,
  204. const DrawRPDQParams* rpdq_params,
  205. DrawQuadParams* params);
  206. // Schedule overlay candidates for presentation at next SwapBuffers().
  207. void ScheduleOverlays();
  208. // skia_renderer can draw most single-quad passes directly, regardless of
  209. // blend mode or image filtering.
  210. const DrawQuad* CanPassBeDrawnDirectly(
  211. const AggregatedRenderPass* pass) override;
  212. void DrawDelegatedInkTrail() override;
  213. // Get a color filter that converts from |src| color space to |dst| color
  214. // space using a shader constructed from gfx::ColorTransform. The color
  215. // filters are cached in |color_filter_cache_|. Resource offset and
  216. // multiplier are used to adjust the RGB output of the shader for YUV video
  217. // quads. The default values perform no adjustment.
  218. sk_sp<SkColorFilter> GetColorSpaceConversionFilter(
  219. const gfx::ColorSpace& src,
  220. absl::optional<gfx::HDRMetadata> src_hdr_metadata,
  221. const gfx::ColorSpace& dst,
  222. float resource_offset = 0.0f,
  223. float resource_multiplier = 1.0f);
  224. // Returns the color filter that should be applied to the current canvas.
  225. sk_sp<SkColorFilter> GetContentColorFilter();
  226. // Flush SkiaOutputSurface, so all pending GPU tasks in SkiaOutputSurface will
  227. // be sent to GPU scheduler.
  228. void FlushOutputSurface();
  229. #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  230. void PrepareRenderPassOverlay(
  231. OverlayProcessorInterface::PlatformOverlayCandidate* overlay);
  232. #endif
  233. // Sets up callbacks for frame resource fences and passes them to
  234. // SkiaOutputSurface by calling EndPaint on that. If |failed|,
  235. // SkiaOutputSurface::EndPaint will be called with null callbacks.
  236. void EndPaint(bool failed);
  237. DisplayResourceProviderSkia* resource_provider() {
  238. return static_cast<DisplayResourceProviderSkia*>(resource_provider_);
  239. }
  240. // A map from RenderPass id to the texture used to draw the RenderPass from.
  241. struct RenderPassBacking {
  242. gfx::Size size;
  243. bool generate_mipmap;
  244. gfx::ColorSpace color_space;
  245. ResourceFormat format;
  246. gpu::Mailbox mailbox;
  247. };
  248. base::flat_map<AggregatedRenderPassId, RenderPassBacking>
  249. render_pass_backings_;
  250. sk_sp<SkColorSpace> RenderPassBackingSkColorSpace(
  251. const RenderPassBacking& backing) {
  252. return backing.color_space.ToSkColorSpace(CurrentFrameSDRWhiteLevel());
  253. }
  254. // Interface used for drawing. Common among different draw modes.
  255. raw_ptr<SkCanvas> current_canvas_ = nullptr;
  256. class FrameResourceGpuCommandsCompletedFence;
  257. scoped_refptr<FrameResourceGpuCommandsCompletedFence>
  258. current_gpu_commands_completed_fence_;
  259. class FrameResourceReleaseFence;
  260. scoped_refptr<FrameResourceReleaseFence> current_release_fence_;
  261. bool disable_picture_quad_image_filtering_ = false;
  262. bool is_scissor_enabled_ = false;
  263. gfx::Rect scissor_rect_;
  264. gfx::Rect swap_buffer_rect_;
  265. // State common to all quads in a batch. Draws that require an SkPaint not
  266. // captured by this state cannot be batched.
  267. struct BatchedQuadState {
  268. absl::optional<gfx::Rect> scissor_rect;
  269. absl::optional<gfx::MaskFilterInfo> mask_filter_info;
  270. SkBlendMode blend_mode;
  271. SkSamplingOptions sampling;
  272. SkCanvas::SrcRectConstraint constraint;
  273. BatchedQuadState();
  274. };
  275. BatchedQuadState batched_quad_state_;
  276. std::vector<SkCanvas::ImageSetEntry> batched_quads_;
  277. // Same order as batched_quads_, but only includes draw regions for the
  278. // entries that have fHasClip == true. Each draw region is 4 consecutive pts
  279. std::vector<SkPoint> batched_draw_regions_;
  280. // Each entry of batched_quads_ will have an index into this vector; multiple
  281. // entries may point to the same matrix.
  282. std::vector<SkMatrix> batched_cdt_matrices_;
  283. // Specific for SkDDL.
  284. const raw_ptr<SkiaOutputSurface> skia_output_surface_;
  285. const bool is_using_raw_draw_;
  286. // Lock set for resources that are used for the current frame. All resources
  287. // in this set will be unlocked with a sync token when the frame is done in
  288. // the compositor thread. And the sync token will be released when the DDL
  289. // for the current frame is replayed on the GPU thread.
  290. // It is only used with DDL.
  291. absl::optional<DisplayResourceProviderSkia::LockSetForExternalUse>
  292. lock_set_for_external_use_;
  293. struct OverlayLock {
  294. OverlayLock(DisplayResourceProvider* resource_provider,
  295. ResourceId resource_id);
  296. #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  297. explicit OverlayLock(gpu::Mailbox mailbox);
  298. #endif // BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  299. ~OverlayLock();
  300. OverlayLock(OverlayLock&& other);
  301. OverlayLock& operator=(OverlayLock&& other);
  302. OverlayLock(const OverlayLock&) = delete;
  303. OverlayLock& operator=(const OverlayLock&) = delete;
  304. const gpu::Mailbox& mailbox() const {
  305. #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  306. if (render_pass_lock.has_value()) {
  307. return *render_pass_lock;
  308. }
  309. #endif // BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  310. DCHECK(resource_lock.has_value());
  311. return resource_lock->mailbox();
  312. }
  313. const gpu::SyncToken& sync_token() const {
  314. DCHECK(resource_lock.has_value());
  315. return resource_lock->sync_token();
  316. }
  317. void SetReleaseFence(gfx::GpuFenceHandle release_fence) {
  318. if (resource_lock.has_value()) {
  319. resource_lock->SetReleaseFence(std::move(release_fence));
  320. }
  321. }
  322. bool HasReadLockFence() {
  323. if (resource_lock.has_value()) {
  324. return resource_lock->HasReadLockFence();
  325. }
  326. return false;
  327. }
  328. // Either resource_lock is set for non render pass overlays (i.e. videos),
  329. // or render_pass_lock is set for render pass overlays.
  330. absl::optional<DisplayResourceProviderSkia::ScopedReadLockSharedImage>
  331. resource_lock;
  332. #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  333. absl::optional<gpu::Mailbox> render_pass_lock;
  334. #endif // BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  335. };
  336. // Locks for overlays that are pending for SwapBuffers().
  337. base::circular_deque<std::vector<OverlayLock>> pending_overlay_locks_;
  338. // Locks for overlays that have been committed. |pending_overlay_locks_| will
  339. // be moved to |committed_overlay_locks_| after SwapBuffers() is completed.
  340. std::vector<OverlayLock> committed_overlay_locks_;
  341. // Locks for overlays that have release fences and read lock fences.
  342. base::circular_deque<std::vector<OverlayLock>>
  343. read_lock_release_fence_overlay_locks_;
  344. #if BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  345. class OverlayLockComparator {
  346. public:
  347. using is_transparent = void;
  348. bool operator()(const OverlayLock& lhs, const OverlayLock& rhs) const;
  349. };
  350. // A set for locks of overlays which are waiting to be released, using
  351. // mailbox() as the unique key.
  352. base::flat_set<OverlayLock, OverlayLockComparator>
  353. awaiting_release_overlay_locks_;
  354. // Tracks render pass overlay backings that are currently in use and available
  355. // for re-using via mailboxes. RenderPassBacking.generate_mipmap is not used.
  356. std::vector<RenderPassBacking> in_flight_render_pass_overlay_backings_;
  357. std::vector<RenderPassBacking> available_render_pass_overlay_backings_;
  358. #endif // BUILDFLAG(IS_APPLE) || defined(USE_OZONE)
  359. gfx::ColorConversionSkFilterCache color_filter_cache_;
  360. bool UsingSkiaForDelegatedInk() const;
  361. uint32_t debug_tint_modulate_count_ = 0;
  362. bool use_real_color_space_for_stream_video_ = false;
  363. };
  364. } // namespace viz
  365. #endif // COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_