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 
5 #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_
6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_
7 
8 #include <memory>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/callback.h"
13 #include "base/containers/circular_deque.h"
14 #include "base/containers/flat_map.h"
15 #include "base/macros.h"
16 #include "base/optional.h"
17 #include "build/build_config.h"
18 #include "components/viz/common/delegated_ink_metadata.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_base.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/viz_service_export.h"
27 #include "gpu/command_buffer/common/texture_in_use_response.h"
28 #include "ui/gfx/display_color_spaces.h"
29 #include "ui/gfx/geometry/quad_f.h"
30 #include "ui/gfx/geometry/rect.h"
31 #include "ui/latency/latency_info.h"
32 
33 namespace cc {
34 class FilterOperations;
35 }  // namespace cc
36 
37 namespace gfx {
38 class ColorSpace;
39 class RRectF;
40 }  // namespace gfx
41 
42 namespace viz {
43 class BspWalkActionDrawPolygon;
44 class DrawPolygon;
45 class OutputSurface;
46 struct DebugRendererSettings;
47 class RendererSettings;
48 
49 namespace copy_output {
50 struct RenderPassGeometry;
51 }  // namespace copy_output
52 
53 // This is the base class for code shared between the GL and software
54 // renderer implementations. "Direct" refers to the fact that it does not
55 // delegate rendering to another compositor (see historical DelegatingRenderer
56 // for reference).
57 class VIZ_SERVICE_EXPORT DirectRenderer {
58  public:
59   DirectRenderer(const RendererSettings* settings,
60                  const DebugRendererSettings* debug_settings,
61                  OutputSurface* output_surface,
62                  DisplayResourceProvider* resource_provider,
63                  OverlayProcessorInterface* overlay_processor);
64   virtual ~DirectRenderer();
65 
66   void Initialize();
67 
use_partial_swap()68   bool use_partial_swap() const { return use_partial_swap_; }
69 
70   void SetVisible(bool visible);
71   void DecideRenderPassAllocationsForFrame(
72       const AggregatedRenderPassList& render_passes_in_draw_order);
73   void DrawFrame(AggregatedRenderPassList* render_passes_in_draw_order,
74                  float device_scale_factor,
75                  const gfx::Size& device_viewport_size,
76                  const gfx::DisplayColorSpaces& display_color_spaces,
77                  SurfaceDamageRectList* surface_damage_rect_list);
78 
79   // The renderer might expand the damage (e.g: HW overlays were used,
80   // invalidation rects on previous buffers). This function returns a
81   // bounding rect of the area that might need to be recomposited.
82   gfx::Rect GetTargetDamageBoundingRect() const;
83 
84   // Public interface implemented by subclasses.
85   struct SwapFrameData {
86     SwapFrameData();
87     ~SwapFrameData();
88 
89     SwapFrameData& operator=(SwapFrameData&&);
90     SwapFrameData(SwapFrameData&&);
91 
92     SwapFrameData(const SwapFrameData&) = delete;
93     SwapFrameData& operator=(const SwapFrameData&) = delete;
94 
95     std::vector<ui::LatencyInfo> latency_info;
96     bool top_controls_visible_height_changed = false;
97   };
98   virtual void SwapBuffers(SwapFrameData swap_frame_data) = 0;
SwapBuffersSkipped()99   virtual void SwapBuffersSkipped() {}
SwapBuffersComplete()100   virtual void SwapBuffersComplete() {}
DidReceiveTextureInUseResponses(const gpu::TextureInUseResponses & responses)101   virtual void DidReceiveTextureInUseResponses(
102       const gpu::TextureInUseResponses& responses) {}
DidReceiveReleasedOverlays(const std::vector<gpu::Mailbox> & released_overlays)103   virtual void DidReceiveReleasedOverlays(
104       const std::vector<gpu::Mailbox>& released_overlays) {}
105 
106   // Public for tests that poke at internals.
107   struct VIZ_SERVICE_EXPORT DrawingFrame {
108     DrawingFrame();
109     ~DrawingFrame();
110 
111     const AggregatedRenderPassList* render_passes_in_draw_order = nullptr;
112     const AggregatedRenderPass* root_render_pass = nullptr;
113     const AggregatedRenderPass* current_render_pass = nullptr;
114 
115     gfx::Rect root_damage_rect;
116     std::vector<gfx::Rect> root_content_bounds;
117     gfx::Size device_viewport_size;
118     gfx::DisplayColorSpaces display_color_spaces;
119 
120     gfx::Transform projection_matrix;
121     gfx::Transform window_matrix;
122 
123     OverlayProcessorInterface::CandidateList overlay_list;
124     // When we have a buffer queue, the output surface could be treated as an
125     // overlay plane, and the struct to store that information is in
126     // |output_surface_plane|.
127     base::Optional<OverlayProcessorInterface::OutputSurfaceOverlayPlane>
128         output_surface_plane;
129   };
130 
131   void SetCurrentFrameForTesting(const DrawingFrame& frame);
132   bool HasAllocatedResourcesForTesting(
133       const AggregatedRenderPassId& render_pass_id) const;
134   // Allow tests to enlarge the texture size of non-root render passes to
135   // verify cases where the texture doesn't match the render pass size.
SetEnlargePassTextureAmountForTesting(const gfx::Size & amount)136   void SetEnlargePassTextureAmountForTesting(const gfx::Size& amount) {
137     enlarge_pass_texture_amount_ = amount;
138   }
139 
GetLastRootScissorRectForTesting()140   gfx::Rect GetLastRootScissorRectForTesting() const {
141     return last_root_render_pass_scissor_rect_;
142   }
143 
144   virtual DelegatedInkPointRendererBase* GetDelegatedInkPointRenderer();
145   void SetDelegatedInkMetadata(std::unique_ptr<DelegatedInkMetadata> metadata);
146 
147   // Returns true if composite time tracing is enabled. This measures a detailed
148   // trace log for draw time spent per quad.
149   virtual bool CompositeTimeTracingEnabled();
150 
151   // Puts the draw time wall in trace file relative to the |ready_timestamp|.
152   virtual void AddCompositeTimeTraces(base::TimeTicks ready_timestamp);
153 
154   // Return the bounding rect of previously drawn delegated ink trail.
155   gfx::Rect GetDelegatedInkTrailDamageRect();
156 
157  protected:
158   friend class BspWalkActionDrawPolygon;
159   friend class SkiaDelegatedInkRendererTest;
160   friend class DelegatedInkPointPixelTestHelper;
161 
162   enum SurfaceInitializationMode {
163     SURFACE_INITIALIZATION_MODE_PRESERVE,
164     SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR,
165     SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR,
166   };
167 
168   struct RenderPassRequirements {
169     gfx::Size size;
170     bool generate_mipmap = false;
171   };
172 
173   static gfx::RectF QuadVertexRect();
174   static void QuadRectTransform(gfx::Transform* quad_rect_transform,
175                                 const gfx::Transform& quad_transform,
176                                 const gfx::RectF& quad_rect);
177   // This function takes DrawingFrame as an argument because RenderPass drawing
178   // code uses its computations for buffer sizing.
179   void InitializeViewport(DrawingFrame* frame,
180                           const gfx::Rect& draw_rect,
181                           const gfx::Rect& viewport_rect,
182                           const gfx::Size& surface_size);
183   gfx::Rect MoveFromDrawToWindowSpace(const gfx::Rect& draw_rect) const;
184 
185   gfx::Rect DeviceViewportRectInDrawSpace() const;
186   gfx::Rect OutputSurfaceRectInDrawSpace() const;
187   void SetScissorStateForQuad(const DrawQuad& quad,
188                               const gfx::Rect& render_pass_scissor,
189                               bool use_render_pass_scissor);
190   bool ShouldSkipQuad(const DrawQuad& quad,
191                       const gfx::Rect& render_pass_scissor);
192   void SetScissorTestRectInDrawSpace(const gfx::Rect& draw_space_rect);
193 
194   gfx::Size CalculateTextureSizeForRenderPass(
195       const AggregatedRenderPass* render_pass);
196 
197   void FlushPolygons(
198       base::circular_deque<std::unique_ptr<DrawPolygon>>* poly_list,
199       const gfx::Rect& render_pass_scissor,
200       bool use_render_pass_scissor);
201   void DrawRenderPassAndExecuteCopyRequests(AggregatedRenderPass* render_pass);
202   void DrawRenderPass(const AggregatedRenderPass* render_pass);
203   // Returns true if it detects that we do not need to draw the render pass.
204   // This may be because the RenderPass is already cached, or because it is
205   // entirely clipped out, for instance.
206   bool CanSkipRenderPass(const AggregatedRenderPass* render_pass) const;
207   void UseRenderPass(const AggregatedRenderPass* render_pass);
208   gfx::Rect ComputeScissorRectForRenderPass(
209       const AggregatedRenderPass* render_pass) const;
210 
211   void DoDrawPolygon(const DrawPolygon& poly,
212                      const gfx::Rect& render_pass_scissor,
213                      bool use_render_pass_scissor);
214 
215   const cc::FilterOperations* FiltersForPass(
216       AggregatedRenderPassId render_pass_id) const;
217   const cc::FilterOperations* BackdropFiltersForPass(
218       AggregatedRenderPassId render_pass_id) const;
219   const base::Optional<gfx::RRectF> BackdropFilterBoundsForPass(
220       AggregatedRenderPassId render_pass_id) const;
221 
222   // Private interface implemented by subclasses for use by DirectRenderer.
223   virtual bool CanPartialSwap() = 0;
224   virtual void UpdateRenderPassTextures(
225       const AggregatedRenderPassList& render_passes_in_draw_order,
226       const base::flat_map<AggregatedRenderPassId, RenderPassRequirements>&
227           render_passes_in_frame) = 0;
228   virtual void AllocateRenderPassResourceIfNeeded(
229       const AggregatedRenderPassId& render_pass_id,
230       const RenderPassRequirements& requirements) = 0;
231   virtual bool IsRenderPassResourceAllocated(
232       const AggregatedRenderPassId& render_pass_id) const = 0;
233   virtual gfx::Size GetRenderPassBackingPixelSize(
234       const AggregatedRenderPassId& render_pass_id) = 0;
235   virtual void BindFramebufferToOutputSurface() = 0;
236   virtual void BindFramebufferToTexture(
237       const AggregatedRenderPassId render_pass_id) = 0;
238   virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) = 0;
239   virtual void PrepareSurfaceForPass(
240       SurfaceInitializationMode initialization_mode,
241       const gfx::Rect& render_pass_scissor) = 0;
242   // |clip_region| is a (possibly null) pointer to a quad in the same
243   // space as the quad. When non-null only the area of the quad that overlaps
244   // with clip_region will be drawn.
245   virtual void DoDrawQuad(const DrawQuad* quad,
246                           const gfx::QuadF* clip_region) = 0;
247   virtual void BeginDrawingFrame() = 0;
FlushOverdrawFeedback(const gfx::Rect & output_rect)248   virtual void FlushOverdrawFeedback(const gfx::Rect& output_rect) {}
249   virtual void FinishDrawingFrame() = 0;
250   // If a pass contains a single tile draw quad and can be drawn without
251   // a render pass (e.g. applying a filter directly to the tile quad)
252   // return that quad, otherwise return null.
253   virtual const DrawQuad* CanPassBeDrawnDirectly(
254       const AggregatedRenderPass* pass);
FinishDrawingQuadList()255   virtual void FinishDrawingQuadList() {}
256   virtual bool FlippedFramebuffer() const = 0;
257   virtual void EnsureScissorTestEnabled() = 0;
258   virtual void EnsureScissorTestDisabled() = 0;
259   virtual void DidChangeVisibility() = 0;
260   virtual void CopyDrawnRenderPass(
261       const copy_output::RenderPassGeometry& geometry,
262       std::unique_ptr<CopyOutputRequest> request) = 0;
263   virtual void GenerateMipmap() = 0;
264 
surface_size_for_swap_buffers()265   gfx::Size surface_size_for_swap_buffers() const {
266     return reshape_surface_size_;
267   }
268 
269   bool ShouldApplyRoundedCorner(const DrawQuad* quad) const;
270 
271   gfx::ColorSpace RootRenderPassColorSpace() const;
272   gfx::ColorSpace CurrentRenderPassColorSpace() const;
273 
274   const RendererSettings* const settings_;
275   // Points to the viz-global singleton.
276   const DebugRendererSettings* const debug_settings_;
277   OutputSurface* const output_surface_;
278   DisplayResourceProvider* const resource_provider_;
279   // This can be replaced by test implementations.
280   // TODO(weiliangc): For SoftwareRenderer and tests where overlay is not used,
281   // use OverlayProcessorStub so this pointer is never null.
282   OverlayProcessorInterface* overlay_processor_;
283 
284   // Whether it's valid to SwapBuffers with an empty rect. Trivially true when
285   // using partial swap.
286   bool allow_empty_swap_ = false;
287   // Whether partial swap can be used.
288   bool use_partial_swap_ = false;
289   // Whether overdraw feedback is enabled and can be used.
290   bool overdraw_feedback_ = false;
291 
292   // A map from RenderPass id to the single quad present in and replacing the
293   // RenderPass. The DrawQuads are owned by their RenderPasses, which outlive
294   // the drawn frame, so it is safe to store these pointers until the end of
295   // DrawFrame().
296   base::flat_map<AggregatedRenderPassId, const DrawQuad*>
297       render_pass_bypass_quads_;
298 
299   // A map from RenderPass id to the filters used when drawing the RenderPass.
300   base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>
301       render_pass_filters_;
302   base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>
303       render_pass_backdrop_filters_;
304   base::flat_map<AggregatedRenderPassId, base::Optional<gfx::RRectF>>
305       render_pass_backdrop_filter_bounds_;
306   base::flat_map<AggregatedRenderPassId, gfx::Rect>
307       backdrop_filter_output_rects_;
308 
309   bool visible_ = false;
310   bool disable_color_checks_for_testing_ = false;
311 
312   // For use in coordinate conversion, this stores the output rect, viewport
313   // rect (= unflipped version of glViewport rect), the size of target
314   // framebuffer, and the current window space viewport. During a draw, this
315   // stores the values for the current render pass; in between draws, they
316   // retain the values for the root render pass of the last draw.
317   gfx::Rect current_draw_rect_;
318   gfx::Rect current_viewport_rect_;
319   gfx::Size current_surface_size_;
320   gfx::Rect current_window_space_viewport_;
321 
current_frame()322   DrawingFrame* current_frame() {
323     DCHECK(current_frame_valid_);
324     return &current_frame_;
325   }
current_frame()326   const DrawingFrame* current_frame() const {
327     DCHECK(current_frame_valid_);
328     return &current_frame_;
329   }
reshape_buffer_format()330   gfx::BufferFormat reshape_buffer_format() const {
331     DCHECK(reshape_buffer_format_);
332     return reshape_buffer_format_.value();
333   }
reshape_color_space()334   gfx::ColorSpace reshape_color_space() const { return reshape_color_space_; }
335 
336   // Return a bool to inform the caller if the delegated ink renderer was
337   // actually created or not. If the renderer doesn't support drawing delegated
338   // ink trails, then the delegated ink renderer won't be created.
339   virtual bool CreateDelegatedInkPointRenderer();
340 
341  private:
342   virtual void DrawDelegatedInkTrail();
343 
344   bool initialized_ = false;
345 #if DCHECK_IS_ON()
346   bool overdraw_feedback_support_missing_logged_once_ = false;
347   bool overdraw_tracing_support_missing_logged_once_ = false;
348   bool supports_occlusion_query_ = false;
349 #endif
350   gfx::Rect last_root_render_pass_scissor_rect_;
351   gfx::Size enlarge_pass_texture_amount_;
352 
353   // The current drawing frame is valid only during the duration of the
354   // DrawFrame function. Use the accessor current_frame() to ensure that use
355   // is valid;
356   DrawingFrame current_frame_;
357   bool current_frame_valid_ = false;
358 
359   // Cached values given to Reshape(). The |reshape_buffer_format_| is optional
360   // to prevent use of uninitialized values.
361   gfx::Size reshape_surface_size_;
362   float reshape_device_scale_factor_ = 0.f;
363   gfx::ColorSpace reshape_color_space_;
364   base::Optional<gfx::BufferFormat> reshape_buffer_format_;
365   bool reshape_use_stencil_ = false;
366 
367   DISALLOW_COPY_AND_ASSIGN(DirectRenderer);
368 };
369 
370 }  // namespace viz
371 
372 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_
373