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 ¤t_frame_; 325 } current_frame()326 const DrawingFrame* current_frame() const { 327 DCHECK(current_frame_valid_); 328 return ¤t_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