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