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/aggregated_render_pass.h"
14 #include "components/viz/service/display/aggregated_frame.h"
15 #include "components/viz/service/viz_service_export.h"
16 #include "gpu/command_buffer/common/mailbox.h"
17 #include "third_party/skia/include/core/SkColor.h"
18 #include "third_party/skia/include/core/SkMatrix44.h"
19 #include "ui/gfx/geometry/rect_f.h"
20 #include "ui/gfx/hdr_metadata.h"
21 #include "ui/gfx/video_types.h"
22 #include "ui/gl/gpu_switching_observer.h"
23 
24 namespace viz {
25 struct DebugRendererSettings;
26 class DisplayResourceProvider;
27 
28 // TODO(weiliangc): Eventually fold this into OverlayProcessorWin and
29 // OverlayCandidate class.
30 // Holds all information necessary to construct a
31 // DCLayer from a DrawQuad.
32 class VIZ_SERVICE_EXPORT DCLayerOverlay {
33  public:
34   DCLayerOverlay();
35   DCLayerOverlay(const DCLayerOverlay& other);
36   DCLayerOverlay& operator=(const DCLayerOverlay& other);
37   ~DCLayerOverlay();
38 
39   // Resource ids for video Y and UV planes, a single NV12 image, or a swap
40   // chain image. See DirectCompositionSurfaceWin for details.
41   enum : size_t { kNumResources = 2 };
42   ResourceId resources[kNumResources] = {kInvalidResourceId};
43 
44   // Mailboxes corresponding to |resources|. This is populated in SkiaRenderer
45   // for accessing the textures on the GPU thread.
46   gpu::Mailbox mailbox[kNumResources];
47 
48   // Stacking order relative to backbuffer which has z-order 0.
49   int z_order = 1;
50 
51   // What part of the content to display in pixels.
52   gfx::Rect content_rect;
53 
54   // Bounds of the overlay in pre-transform space.
55   gfx::Rect quad_rect;
56 
57   // 2D flattened transform that maps |quad_rect| to root target space,
58   // after applying the |quad_rect.origin()| as an offset.
59   gfx::Transform transform;
60 
61   // If |is_clipped| is true, then clip to |clip_rect| in root target space.
62   bool is_clipped = false;
63   gfx::Rect clip_rect;
64 
65   // This is the color-space the texture should be displayed as. If invalid,
66   // then the default for the texture should be used. For YUV textures, that's
67   // normally BT.709.
68   gfx::ColorSpace color_space;
69 
70   gfx::ProtectedVideoType protected_video_type =
71       gfx::ProtectedVideoType::kClear;
72 
73   gfx::HDRMetadata hdr_metadata;
74 };
75 
76 typedef std::vector<DCLayerOverlay> DCLayerOverlayList;
77 
78 class VIZ_SERVICE_EXPORT DCLayerOverlayProcessor
79     : public ui::GpuSwitchingObserver {
80  public:
81   using FilterOperationsMap =
82       base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>;
83   // When |skip_initialization_for_testing| is true, object will be isolated
84   // for unit tests.
85   // allowed_yuv_overlay_count will be limited to 1 if
86   // |use_overlay_damage_list_| is not supported. This new method produces an
87   // empty root damage rect when the overlay quads are the only damages in the
88   // frames. If |use_overlay_damage_list_| is false, we should not allowed more
89   // than one YUV overlays since non-empty damage rect won't save any power.
90   explicit DCLayerOverlayProcessor(
91       const DebugRendererSettings* debug_settings,
92       int allowed_yuv_overlay_count,
93       bool skip_initialization_for_testing = false);
94   virtual ~DCLayerOverlayProcessor();
95 
96   // Virtual for testing.
97   virtual void Process(DisplayResourceProvider* resource_provider,
98                        const gfx::RectF& display_rect,
99                        const FilterOperationsMap& render_pass_filters,
100                        const FilterOperationsMap& render_pass_backdrop_filters,
101                        AggregatedRenderPassList* render_passes,
102                        gfx::Rect* damage_rect,
103                        SurfaceDamageRectList* surface_damage_rect_list,
104                        DCLayerOverlayList* dc_layer_overlays);
105   void ClearOverlayState();
106   // This is the damage contribution due to previous frame's overlays which can
107   // be empty.
previous_frame_overlay_damage_contribution()108   gfx::Rect previous_frame_overlay_damage_contribution() {
109     return previous_frame_overlay_rect_union_;
110   }
111 
112   // GpuSwitchingObserver implementation.
113   void OnDisplayAdded() override;
114   void OnDisplayRemoved() override;
115   void UpdateHasHwOverlaySupport();
116 
117  private:
118   // UpdateDCLayerOverlays() adds the quad at |it| to the overlay list
119   // |dc_layer_overlays|.
120   void UpdateDCLayerOverlays(const gfx::RectF& display_rect,
121                              AggregatedRenderPass* render_pass,
122                              const QuadList::Iterator& it,
123                              const gfx::Rect& quad_rectangle_in_target_space,
124                              const gfx::Rect& occluding_damage_rect,
125                              bool is_overlay,
126                              QuadList::Iterator* new_it,
127                              size_t* new_index,
128                              gfx::Rect* this_frame_underlay_rect,
129                              gfx::Rect* damage_rect,
130                              DCLayerOverlayList* dc_layer_overlays);
131 
132   // Returns an iterator to the element after |it|.
133   QuadList::Iterator ProcessForOverlay(const gfx::RectF& display_rect,
134                                        AggregatedRenderPass* render_pass,
135                                        const gfx::Rect& quad_rectangle,
136                                        const QuadList::Iterator& it,
137                                        gfx::Rect* damage_rect);
138   void ProcessForUnderlay(const gfx::RectF& display_rect,
139                           AggregatedRenderPass* render_pass,
140                           const gfx::Rect& quad_rectangle,
141                           const gfx::Rect& occluding_damage_rect,
142                           const QuadList::Iterator& it,
143                           gfx::Rect* damage_rect,
144                           gfx::Rect* this_frame_underlay_rect,
145                           DCLayerOverlay* dc_layer);
146 
147   void UpdateRootDamageRect(const gfx::RectF& display_rect,
148                             gfx::Rect* damage_rect);
149 
150   void RemoveOverlayDamageRect(const QuadList::Iterator& it,
151                                const gfx::Rect& quad_rectangle,
152                                const gfx::Rect& occluding_damage_rect,
153                                gfx::Rect* damage_rect);
154 
155   void InsertDebugBorderDrawQuad(const DCLayerOverlayList* dc_layer_overlays,
156                                  AggregatedRenderPass* render_pass,
157                                  const gfx::RectF& display_rect,
158                                  gfx::Rect* damage_rect);
159   bool IsPreviousFrameUnderlayRect(const gfx::Rect& quad_rectangle,
160                                    size_t index);
161 
162   bool has_overlay_support_;
163   const bool use_overlay_damage_list_;
164   // TODO(magchen@): We are going to support more than one YUV overlay.
165   const int allowed_yuv_overlay_count_;
166   int processed_yuv_overlay_count_ = 0;
167 
168   // Reference to the global viz singleton.
169   const DebugRendererSettings* const debug_settings_;
170 
171   gfx::Rect previous_frame_underlay_rect_;
172   gfx::RectF previous_display_rect_;
173   // previous and current overlay_rect_union_ include both overlay and underlay
174   gfx::Rect previous_frame_overlay_rect_union_;
175   gfx::Rect current_frame_overlay_rect_union_;
176   int previous_frame_processed_overlay_count_ = 0;
177   int current_frame_processed_overlay_count_ = 0;
178 
179   struct OverlayRect {
180     gfx::Rect rect;
181     bool is_overlay;  // If false, it's an underlay.
182     bool operator==(const OverlayRect& b) {
183       return rect == b.rect && is_overlay == b.is_overlay;
184     }
185     bool operator!=(const OverlayRect& b) { return !(*this == b); }
186   };
187   std::vector<OverlayRect> previous_frame_overlay_rects_;
188   std::vector<OverlayRect> current_frame_overlay_rects_;
189   SurfaceDamageRectList* surface_damage_rect_list_;
190 
191   scoped_refptr<base::SingleThreadTaskRunner> viz_task_runner_;
192 
193   DISALLOW_COPY_AND_ASSIGN(DCLayerOverlayProcessor);
194 };
195 
196 }  // namespace viz
197 
198 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DC_LAYER_OVERLAY_H_
199