1 // Copyright 2017 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_DC_LAYER_OVERLAY_H_
6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_DC_LAYER_OVERLAY_H_
7 
8 #include <vector>
9 
10 #include "base/containers/flat_map.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/single_thread_task_runner.h"
13 #include "components/viz/common/quads/render_pass.h"
14 #include "components/viz/service/viz_service_export.h"
15 #include "gpu/command_buffer/common/mailbox.h"
16 #include "third_party/skia/include/core/SkColor.h"
17 #include "third_party/skia/include/core/SkMatrix44.h"
18 #include "ui/gfx/geometry/rect_f.h"
19 #include "ui/gfx/video_types.h"
20 #include "ui/gl/gpu_switching_observer.h"
21 
22 namespace viz {
23 class DisplayResourceProvider;
24 class RendererSettings;
25 
26 // TODO(weiliangc): Eventually fold this into OverlayProcessorWin and
27 // OverlayCandidate class.
28 // Holds all information necessary to construct a
29 // DCLayer from a DrawQuad.
30 class VIZ_SERVICE_EXPORT DCLayerOverlay {
31  public:
32   DCLayerOverlay();
33   DCLayerOverlay(const DCLayerOverlay& other);
34   DCLayerOverlay& operator=(const DCLayerOverlay& other);
35   ~DCLayerOverlay();
36 
37   // TODO(magchen): Once software protected video is enabled for all GPUs and
38   // all configurations, RequiresOverlay() will be true for all protected video.
39   // Currently, we only force the overlay swap chain path (RequiresOverlay) for
40   // hardware protected video and soon for Finch experiment on software
41   // protected video.
RequiresOverlay()42   bool RequiresOverlay() const {
43     return (protected_video_type ==
44             gfx::ProtectedVideoType::kHardwareProtected);
45   }
46 
47   // Resource ids for video Y and UV planes, a single NV12 image, or a swap
48   // chain image. See DirectCompositionSurfaceWin for details.
49   enum : size_t { kNumResources = 2 };
50   ResourceId resources[kNumResources] = {kInvalidResourceId};
51 
52   // Mailboxes corresponding to |resources|. This is populated in SkiaRenderer
53   // for accessing the textures on the GPU thread.
54   gpu::Mailbox mailbox[kNumResources];
55 
56   // Stacking order relative to backbuffer which has z-order 0.
57   int z_order = 1;
58 
59   // What part of the content to display in pixels.
60   gfx::Rect content_rect;
61 
62   // Bounds of the overlay in pre-transform space.
63   gfx::Rect quad_rect;
64 
65   // 2D flattened transform that maps |quad_rect| to root target space,
66   // after applying the |quad_rect.origin()| as an offset.
67   gfx::Transform transform;
68 
69   // If |is_clipped| is true, then clip to |clip_rect| in root target space.
70   bool is_clipped = false;
71   gfx::Rect clip_rect;
72 
73   // This is the color-space the texture should be displayed as. If invalid,
74   // then the default for the texture should be used. For YUV textures, that's
75   // normally BT.709.
76   gfx::ColorSpace color_space;
77 
78   gfx::ProtectedVideoType protected_video_type =
79       gfx::ProtectedVideoType::kClear;
80 };
81 
82 typedef std::vector<DCLayerOverlay> DCLayerOverlayList;
83 
84 class VIZ_SERVICE_EXPORT DCLayerOverlayProcessor
85     : public ui::GpuSwitchingObserver {
86  public:
87   explicit DCLayerOverlayProcessor(const RendererSettings& settings);
88   // For testing.
89   DCLayerOverlayProcessor();
90   virtual ~DCLayerOverlayProcessor();
91 
92   // Virtual for testing.
93   virtual void Process(DisplayResourceProvider* resource_provider,
94                        const gfx::RectF& display_rect,
95                        RenderPassList* render_passes,
96                        gfx::Rect* damage_rect,
97                        DCLayerOverlayList* dc_layer_overlays);
98   void ClearOverlayState();
99   // This is the damage contribution due to previous frame's overlays which can
100   // be empty.
previous_frame_overlay_damage_contribution()101   gfx::Rect previous_frame_overlay_damage_contribution() {
102     return previous_frame_overlay_rect_union_;
103   }
104 
105   // GpuSwitchingObserver implementation.
106   void OnDisplayAdded() override;
107   void OnDisplayRemoved() override;
108   void UpdateHasHwOverlaySupport();
109 
110  private:
111   // Returns an iterator to the element after |it|.
112   QuadList::Iterator ProcessRenderPassDrawQuad(RenderPass* render_pass,
113                                                gfx::Rect* damage_rect,
114                                                QuadList::Iterator it);
115   void ProcessRenderPass(DisplayResourceProvider* resource_provider,
116                          const gfx::RectF& display_rect,
117                          RenderPass* render_pass,
118                          bool is_root,
119                          gfx::Rect* damage_rect,
120                          DCLayerOverlayList* dc_layer_overlays);
121   // Returns an iterator to the element after |it|.
122   QuadList::Iterator ProcessForOverlay(const gfx::RectF& display_rect,
123                                        RenderPass* render_pass,
124                                        const gfx::Rect& quad_rectangle,
125                                        const QuadList::Iterator& it,
126                                        gfx::Rect* damage_rect);
127   void ProcessForUnderlay(const gfx::RectF& display_rect,
128                           RenderPass* render_pass,
129                           const gfx::Rect& quad_rectangle,
130                           const QuadList::Iterator& it,
131                           bool is_root,
132                           gfx::Rect* damage_rect,
133                           gfx::Rect* this_frame_underlay_rect,
134                           DCLayerOverlay* dc_layer);
135 
136   void InsertDebugBorderDrawQuads(const gfx::RectF& display_rect,
137                                   const gfx::Rect& overlay_rect,
138                                   RenderPass* root_render_pass,
139                                   gfx::Rect* damage_rect);
140 
141   bool has_hw_overlay_support_;
142   const bool show_debug_borders_;
143 
144   gfx::Rect previous_frame_underlay_rect_;
145   gfx::RectF previous_display_rect_;
146   // previous and current overlay_rect_union_ include both overlay and underlay
147   gfx::Rect previous_frame_overlay_rect_union_;
148   gfx::Rect current_frame_overlay_rect_union_;
149   int previous_frame_processed_overlay_count_ = 0;
150   int current_frame_processed_overlay_count_ = 0;
151 
152   struct RenderPassData {
153     RenderPassData();
154     RenderPassData(const RenderPassData& other);
155     ~RenderPassData();
156 
157     // Store information about clipped punch-through rects in target space for
158     // non-root render passes. These rects are used to clear the corresponding
159     // areas in parent render passes.
160     std::vector<gfx::Rect> punch_through_rects;
161 
162     // Output rects of child render passes that have backdrop filters in target
163     // space. These rects are used to determine if the overlay rect could be
164     // read by backdrop filters.
165     std::vector<gfx::Rect> backdrop_filter_rects;
166 
167     // Whether this render pass has backdrop filters.
168     bool has_backdrop_filters = false;
169   };
170   base::flat_map<RenderPassId, RenderPassData> render_pass_data_;
171 
172   scoped_refptr<base::SingleThreadTaskRunner> viz_task_runner_;
173 
174   DISALLOW_COPY_AND_ASSIGN(DCLayerOverlayProcessor);
175 };
176 
177 }  // namespace viz
178 
179 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DC_LAYER_OVERLAY_H_
180