1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_
6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_
12 #include "base/containers/circular_deque.h"
13 #include "base/containers/flat_map.h"
14 #include "base/functional/callback.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/raw_ptr_exclusion.h"
17 #include "base/time/time.h"
18 #include "build/build_config.h"
19 #include "components/viz/common/quads/aggregated_render_pass.h"
20 #include "components/viz/common/quads/tile_draw_quad.h"
21 #include "components/viz/service/display/aggregated_frame.h"
22 #include "components/viz/service/display/delegated_ink_point_renderer_skia.h"
23 #include "components/viz/service/display/display_resource_provider.h"
24 #include "components/viz/service/display/overlay_candidate.h"
25 #include "components/viz/service/display/overlay_processor_interface.h"
26 #include "components/viz/service/display/render_pass_alpha_type.h"
27 #include "components/viz/service/viz_service_export.h"
28 #include "third_party/abseil-cpp/absl/types/optional.h"
29 #include "ui/gfx/ca_layer_result.h"
30 #include "ui/gfx/delegated_ink_metadata.h"
31 #include "ui/gfx/display_color_spaces.h"
32 #include "ui/gfx/geometry/axis_transform2d.h"
33 #include "ui/gfx/geometry/quad_f.h"
34 #include "ui/gfx/geometry/rect.h"
35 #include "ui/gfx/gpu_fence_handle.h"
36 #include "ui/latency/latency_info.h"
39 class FilterOperations;
48 struct SwapBuffersCompleteParams;
52 class BspWalkActionDrawPolygon;
55 struct DebugRendererSettings;
56 class RendererSettings;
58 namespace copy_output {
59 struct RenderPassGeometry;
60 } // namespace copy_output
62 // This is the base class for code shared between the GL and software
63 // renderer implementations. "Direct" refers to the fact that it does not
64 // delegate rendering to another compositor (see historical DelegatingRenderer
66 class VIZ_SERVICE_EXPORT DirectRenderer {
68 DirectRenderer(const RendererSettings* settings,
69 const DebugRendererSettings* debug_settings,
70 OutputSurface* output_surface,
71 DisplayResourceProvider* resource_provider,
72 OverlayProcessorInterface* overlay_processor);
74 DirectRenderer(const DirectRenderer&) = delete;
75 DirectRenderer& operator=(const DirectRenderer&) = delete;
77 virtual ~DirectRenderer();
81 bool use_partial_swap() const { return use_partial_swap_; }
83 void SetOutputSurfaceClipRect(const gfx::Rect& clip_rect);
84 void SetVisible(bool visible);
85 void ReallocatedFrameBuffers();
86 void DecideRenderPassAllocationsForFrame(
87 const AggregatedRenderPassList& render_passes_in_draw_order);
88 void DrawFrame(AggregatedRenderPassList* render_passes_in_draw_order,
89 float device_scale_factor,
90 const gfx::Size& device_viewport_size,
91 const gfx::DisplayColorSpaces& display_color_spaces,
92 SurfaceDamageRectList surface_damage_rect_list);
94 // The renderer might expand the damage (e.g: HW overlays were used,
95 // invalidation rects on previous buffers). This function returns a
96 // bounding rect of the area that might need to be recomposited.
97 gfx::Rect GetTargetDamageBoundingRect() const;
99 // Public interface implemented by subclasses.
100 struct SwapFrameData {
104 SwapFrameData& operator=(SwapFrameData&&);
105 SwapFrameData(SwapFrameData&&);
107 SwapFrameData(const SwapFrameData&) = delete;
108 SwapFrameData& operator=(const SwapFrameData&) = delete;
110 std::vector<ui::LatencyInfo> latency_info;
112 bool top_controls_visible_height_changed = false;
114 #if BUILDFLAG(IS_EFL)
115 bool can_skip_flush = false;
118 #if BUILDFLAG(IS_APPLE)
119 gfx::CALayerResult ca_layer_error_code = gfx::kCALayerSuccess;
121 absl::optional<int64_t> choreographer_vsync_id;
122 int64_t swap_trace_id = -1;
124 virtual void SwapBuffers(SwapFrameData swap_frame_data) = 0;
125 virtual void SwapBuffersSkipped() {}
126 virtual void SwapBuffersComplete(const gpu::SwapBuffersCompleteParams& params,
127 gfx::GpuFenceHandle release_fence) {}
128 virtual void BuffersPresented() {}
129 virtual void DidReceiveReleasedOverlays(
130 const std::vector<gpu::Mailbox>& released_overlays) {}
132 // Public for tests that poke at internals.
133 struct VIZ_SERVICE_EXPORT DrawingFrame {
137 raw_ptr<const AggregatedRenderPassList> render_passes_in_draw_order =
139 raw_ptr<const AggregatedRenderPass> root_render_pass = nullptr;
140 // This field is not a raw_ptr<> because of a reference to raw_ptr in
141 // not-rewritten platform specific code and #addr-of.
142 RAW_PTR_EXCLUSION const AggregatedRenderPass* current_render_pass = nullptr;
144 gfx::Rect root_damage_rect;
145 std::vector<gfx::Rect> root_content_bounds;
146 gfx::Size device_viewport_size;
147 gfx::DisplayColorSpaces display_color_spaces;
149 gfx::AxisTransform2d target_to_device_transform;
151 OverlayProcessorInterface::CandidateList overlay_list;
153 #if defined(TIZEN_VIDEO_HOLE)
154 bool has_video_hole = false;
157 // When we have a buffer queue, the output surface could be treated as an
158 // overlay plane, and the struct to store that information is in
159 // |output_surface_plane|.
160 absl::optional<OverlayProcessorInterface::OutputSurfaceOverlayPlane>
161 output_surface_plane;
164 void SetCurrentFrameForTesting(const DrawingFrame& frame);
165 bool HasAllocatedResourcesForTesting(
166 const AggregatedRenderPassId& render_pass_id) const;
167 // Allow tests to enlarge the texture size of non-root render passes to
168 // verify cases where the texture doesn't match the render pass size.
169 void SetEnlargePassTextureAmountForTesting(const gfx::Size& amount) {
170 enlarge_pass_texture_amount_ = amount;
173 gfx::Rect GetLastRootScissorRectForTesting() const {
174 return last_root_render_pass_scissor_rect_;
177 base::flat_set<AggregatedRenderPassId>*
178 GetLastSkippedRenderPassIdsForTesting() {
179 return &skipped_render_pass_ids_;
182 virtual DelegatedInkPointRendererBase* GetDelegatedInkPointRenderer(
183 bool create_if_necessary);
184 virtual void SetDelegatedInkMetadata(
185 std::unique_ptr<gfx::DelegatedInkMetadata> metadata) {}
187 // Returns true if composite time tracing is enabled. This measures a detailed
188 // trace log for draw time spent per quad.
189 virtual bool CompositeTimeTracingEnabled();
191 // Puts the draw time wall in trace file relative to the |ready_timestamp|.
192 virtual void AddCompositeTimeTraces(base::TimeTicks ready_timestamp);
194 // Returns the current frame buffer damage.
195 virtual gfx::Rect GetCurrentFramebufferDamage() const;
197 // Reshapes the output surface.
198 virtual void Reshape(const OutputSurface::ReshapeParams& reshape_params);
200 // Set the number of frame buffers to use when
201 // `supports_dynamic_frame_buffer_allocation` is true. `n` must satisfy
202 // 0 < n <= capabilities_.number_of_buffers.
203 virtual void EnsureMinNumberOfBuffers(int n) {}
205 // Gets a mailbox that can be used for overlay testing the primary plane. This
206 // does not need to be the next mailbox that will be swapped.
207 virtual gpu::Mailbox GetPrimaryPlaneOverlayTestingMailbox();
209 // Return the bounding rect of previously drawn delegated ink trail.
210 gfx::Rect GetDelegatedInkTrailDamageRect();
213 friend class BspWalkActionDrawPolygon;
214 friend class SkiaDelegatedInkRendererTest;
215 friend class DelegatedInkPointPixelTestHelper;
216 friend class DelegatedInkDisplayTest;
218 struct RenderPassRequirements {
220 bool generate_mipmap = false;
221 SharedImageFormat format;
222 gfx::ColorSpace color_space;
223 RenderPassAlphaType alpha_type = RenderPassAlphaType::kPremul;
224 // Render pass wants scanout
225 bool is_scanout = false;
226 // Render pass wants to synchronize updates with other overlays, on Windows
227 // this means a DComp surface.
228 bool scanout_dcomp_surface = false;
231 static gfx::RectF QuadVertexRect();
232 static void QuadRectTransform(gfx::Transform* quad_rect_transform,
233 const gfx::Transform& quad_transform,
234 const gfx::RectF& quad_rect);
235 // This function takes DrawingFrame as an argument because RenderPass drawing
236 // code uses its computations for buffer sizing.
237 void InitializeViewport(DrawingFrame* frame,
238 const gfx::Rect& draw_rect,
239 const gfx::Rect& viewport_rect,
240 const gfx::Size& surface_size);
241 gfx::Rect MoveFromDrawToWindowSpace(const gfx::Rect& draw_rect) const;
243 gfx::Rect DeviceViewportRectInDrawSpace() const;
244 gfx::Rect OutputSurfaceRectInDrawSpace() const;
245 void SetScissorStateForQuad(const DrawQuad& quad,
246 const gfx::Rect& render_pass_scissor,
247 bool use_render_pass_scissor);
248 bool ShouldSkipQuad(const DrawQuad& quad,
249 const gfx::Rect& render_pass_scissor);
250 void SetScissorTestRectInDrawSpace(const gfx::Rect& draw_space_rect);
252 gfx::Size CalculateTextureSizeForRenderPass(
253 const AggregatedRenderPass* render_pass) const;
254 gfx::Size CalculateSizeForOutputSurface(
255 const gfx::Size& device_viewport_size);
256 RenderPassRequirements CalculateRenderPassRequirements(
257 const AggregatedRenderPass* render_pass) const;
260 base::circular_deque<std::unique_ptr<DrawPolygon>>* poly_list,
261 const gfx::Rect& render_pass_scissor,
262 bool use_render_pass_scissor);
263 void DrawRenderPassAndExecuteCopyRequests(AggregatedRenderPass* render_pass);
264 void DrawRenderPass(const AggregatedRenderPass* render_pass);
265 // Returns true if it detects that we do not need to draw the render pass.
266 // This may be because the RenderPass is already cached, or because it is
267 // entirely clipped out, for instance.
268 bool CanSkipRenderPass(const AggregatedRenderPass* render_pass) const;
269 void UseRenderPass(const AggregatedRenderPass* render_pass);
270 gfx::Rect ComputeScissorRectForRenderPass(
271 const AggregatedRenderPass* render_pass) const;
273 void DoDrawPolygon(const DrawPolygon& poly,
274 const gfx::Rect& render_pass_scissor,
275 bool use_render_pass_scissor);
277 const cc::FilterOperations* FiltersForPass(
278 AggregatedRenderPassId render_pass_id) const;
279 const cc::FilterOperations* BackdropFiltersForPass(
280 AggregatedRenderPassId render_pass_id) const;
281 const absl::optional<gfx::RRectF> BackdropFilterBoundsForPass(
282 AggregatedRenderPassId render_pass_id) const;
284 // Private interface implemented by subclasses for use by DirectRenderer.
285 virtual bool CanPartialSwap() = 0;
286 virtual void UpdateRenderPassTextures(
287 const AggregatedRenderPassList& render_passes_in_draw_order,
288 const base::flat_map<AggregatedRenderPassId, RenderPassRequirements>&
289 render_passes_in_frame) = 0;
290 virtual void AllocateRenderPassResourceIfNeeded(
291 const AggregatedRenderPassId& render_pass_id,
292 const RenderPassRequirements& requirements) = 0;
293 virtual bool IsRenderPassResourceAllocated(
294 const AggregatedRenderPassId& render_pass_id) const = 0;
295 virtual gfx::Size GetRenderPassBackingPixelSize(
296 const AggregatedRenderPassId& render_pass_id) = 0;
297 virtual void BindFramebufferToOutputSurface() = 0;
298 virtual void BindFramebufferToTexture(
299 const AggregatedRenderPassId render_pass_id) = 0;
300 virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) = 0;
301 // |render_pass_update_rect| is in render pass backing buffer space.
302 virtual void BeginDrawingRenderPass(
304 const gfx::Rect& render_pass_update_rect) = 0;
305 // |clip_region| is a (possibly null) pointer to a quad in the same
306 // space as the quad. When non-null only the area of the quad that overlaps
307 // with clip_region will be drawn.
308 virtual void DoDrawQuad(const DrawQuad* quad,
309 const gfx::QuadF* clip_region) = 0;
310 virtual void FinishDrawingRenderPass() {}
311 virtual void BeginDrawingFrame() = 0;
312 virtual void FinishDrawingFrame() = 0;
313 // If a pass contains a single tile draw quad and can be drawn without
314 // a render pass (e.g. applying a filter directly to the tile quad)
315 // return that quad, otherwise return null.
316 virtual const DrawQuad* CanPassBeDrawnDirectly(
317 const AggregatedRenderPass* pass);
318 virtual bool FlippedFramebuffer() const = 0;
319 virtual void EnsureScissorTestDisabled() = 0;
320 virtual void DidChangeVisibility() = 0;
321 virtual void CopyDrawnRenderPass(
322 const copy_output::RenderPassGeometry& geometry,
323 std::unique_ptr<CopyOutputRequest> request) = 0;
324 virtual void GenerateMipmap() = 0;
325 virtual bool SupportsBGRA() const;
327 gfx::Size surface_size_for_swap_buffers() const {
328 return reshape_params_ ? reshape_params_->size : gfx::Size();
330 gfx::Size viewport_size_for_swap_buffers() const {
331 return device_viewport_size_;
334 bool ShouldApplyRoundedCorner(const DrawQuad* quad) const;
335 bool ShouldApplyGradientMask(const DrawQuad* quad) const;
337 float CurrentFrameSDRWhiteLevel() const;
338 gfx::ColorSpace RootRenderPassColorSpace() const;
339 gfx::ColorSpace CurrentRenderPassColorSpace() const;
340 gfx::ColorSpace RenderPassColorSpace(
341 const AggregatedRenderPass* render_pass) const;
342 SharedImageFormat GetColorSpaceSharedImageFormat(
343 gfx::ColorSpace color_space) const;
344 // Return the SkColorSpace for rendering to the current render pass. Unlike
345 // CurrentRenderPassColorSpace, this color space has the value of
346 // CurrentFrameSDRWhiteLevel incorporated into it.
347 sk_sp<SkColorSpace> CurrentRenderPassSkColorSpace() const {
348 return CurrentRenderPassColorSpace().ToSkColorSpace(
349 CurrentFrameSDRWhiteLevel());
352 const raw_ptr<const RendererSettings> settings_;
353 // Points to the viz-global singleton.
354 const raw_ptr<const DebugRendererSettings> debug_settings_;
355 const raw_ptr<OutputSurface> output_surface_;
356 const raw_ptr<DisplayResourceProvider> resource_provider_;
357 // This can be replaced by test implementations.
358 // TODO(weiliangc): For SoftwareRenderer and tests where overlay is not used,
359 // use OverlayProcessorStub so this pointer is never null.
360 raw_ptr<OverlayProcessorInterface> overlay_processor_;
362 // If the non-root render pass and its embedded child render passes are not
363 // damaged, skip the rendering.
364 const bool allow_undamaged_nonroot_render_pass_to_skip_;
366 // Whether partial swap can be used.
367 bool use_partial_swap_ = false;
369 // A map from RenderPass id to the single quad present in and replacing the
370 // RenderPass. The DrawQuads are owned by their RenderPasses, which outlive
371 // the drawn frame, so it is safe to store these pointers until the end of
373 base::flat_map<AggregatedRenderPassId, const DrawQuad*>
374 render_pass_bypass_quads_;
376 // A map from RenderPass id to the filters used when drawing the RenderPass.
377 base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>
378 render_pass_filters_;
379 base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>
380 render_pass_backdrop_filters_;
381 base::flat_map<AggregatedRenderPassId, absl::optional<gfx::RRectF>>
382 render_pass_backdrop_filter_bounds_;
383 base::flat_map<AggregatedRenderPassId, gfx::Rect>
384 backdrop_filter_output_rects_;
386 // Whether a render pass with foreground filters that move pixels is found in
388 bool has_pixel_moving_foreground_filters_ = false;
390 // Track skipped non-root render passes in DrawRenderPass.
391 base::flat_set<AggregatedRenderPassId> skipped_render_pass_ids_;
393 bool visible_ = false;
394 bool disable_color_checks_for_testing_ = false;
396 // For use in coordinate conversion, this stores the output rect, viewport
397 // rect (= unflipped version of glViewport rect), the size of target
398 // framebuffer, and the current window space viewport. During a draw, this
399 // stores the values for the current render pass; in between draws, they
400 // retain the values for the root render pass of the last draw.
401 gfx::Rect current_draw_rect_;
402 gfx::Rect current_viewport_rect_;
403 gfx::Size current_surface_size_;
404 gfx::Rect current_window_space_viewport_;
406 DrawingFrame* current_frame() {
407 DCHECK(current_frame_valid_);
408 return ¤t_frame_;
410 const DrawingFrame* current_frame() const {
411 DCHECK(current_frame_valid_);
412 return ¤t_frame_;
414 gfx::BufferFormat reshape_buffer_format() const {
415 DCHECK(reshape_params_);
416 return reshape_params_->format;
418 gfx::ColorSpace reshape_color_space() const {
419 DCHECK(reshape_params_);
420 return reshape_params_->color_space;
422 RenderPassAlphaType reshape_alpha_type() const {
423 DCHECK(reshape_params_);
424 return reshape_params_->alpha_type;
427 // Sets a DelegatedInkPointRendererSkiaForTest to be used for testing only, in
428 // order to save delegated ink metadata values that would otherwise be reset.
429 virtual void SetDelegatedInkPointRendererSkiaForTest(
430 std::unique_ptr<DelegatedInkPointRendererSkia> renderer) {}
433 virtual void DrawDelegatedInkTrail();
435 bool initialized_ = false;
437 gfx::Rect last_root_render_pass_scissor_rect_;
438 gfx::Size enlarge_pass_texture_amount_;
440 // The current drawing frame is valid only during the duration of the
441 // DrawFrame function. Use the accessor current_frame() to ensure that use
443 DrawingFrame current_frame_;
444 bool current_frame_valid_ = false;
446 // Time of most recent reshape that ended up with |device_viewport_size_| !=
447 // |reshape_params->size|.
448 base::TimeTicks last_viewport_resize_time_;
450 bool next_frame_needs_full_frame_redraw_ = false;
452 // Cached values given to Reshape(). The `reshape_params_` is optional
453 // to prevent use of uninitialized values. The size in these parameters
454 // may be larger than the `device_viewport_size_` that users see.
455 absl::optional<OutputSurface::ReshapeParams> reshape_params_;
457 // If present additionally restricts drawing to the OutputSurface. WebView
458 // gets this rect from the HWUI.
459 absl::optional<gfx::Rect> output_surface_clip_rect_;
460 gfx::Size device_viewport_size_;
461 gfx::OverlayTransform reshape_display_transform_ =
462 gfx::OVERLAY_TRANSFORM_INVALID;
467 #endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_