1 // Copyright 2019 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 #include "components/viz/service/display/overlay_processor_win.h"
6 
7 #include <utility>
8 #include <vector>
9 
10 #include "base/trace_event/trace_event.h"
11 #include "build/build_config.h"
12 #include "components/viz/common/quads/solid_color_draw_quad.h"
13 #include "components/viz/service/display/display_resource_provider.h"
14 #include "components/viz/service/display/output_surface.h"
15 #include "ui/gfx/geometry/rect_conversions.h"
16 #include "ui/gl/gl_utils.h"
17 
18 namespace viz {
19 namespace {
20 // Switching between enabling DC layers and not is expensive, so only
21 // switch away after a large number of frames not needing DC layers have
22 // been produced.
23 constexpr int kNumberOfFramesBeforeDisablingDCLayers = 60;
24 }  // anonymous namespace
25 
OverlayProcessorWin(OutputSurface * output_surface,std::unique_ptr<DCLayerOverlayProcessor> dc_layer_overlay_processor)26 OverlayProcessorWin::OverlayProcessorWin(
27     OutputSurface* output_surface,
28     std::unique_ptr<DCLayerOverlayProcessor> dc_layer_overlay_processor)
29     : output_surface_(output_surface),
30       dc_layer_overlay_processor_(std::move(dc_layer_overlay_processor)) {
31   DCHECK(output_surface_->capabilities().supports_dc_layers);
32 }
33 
34 OverlayProcessorWin::~OverlayProcessorWin() = default;
35 
IsOverlaySupported() const36 bool OverlayProcessorWin::IsOverlaySupported() const {
37   return true;
38 }
39 
GetPreviousFrameOverlaysBoundingRect() const40 gfx::Rect OverlayProcessorWin::GetPreviousFrameOverlaysBoundingRect() const {
41   // TODO(dcastagna): Implement me.
42   NOTIMPLEMENTED();
43   return gfx::Rect();
44 }
45 
GetAndResetOverlayDamage()46 gfx::Rect OverlayProcessorWin::GetAndResetOverlayDamage() {
47   return gfx::Rect();
48 }
49 
ProcessForOverlays(DisplayResourceProvider * resource_provider,AggregatedRenderPassList * render_passes,const SkMatrix44 & output_color_matrix,const OverlayProcessorInterface::FilterOperationsMap & render_pass_filters,const OverlayProcessorInterface::FilterOperationsMap & render_pass_backdrop_filters,SurfaceDamageRectList * surface_damage_rect_list,OutputSurfaceOverlayPlane * output_surface_plane,CandidateList * candidates,gfx::Rect * damage_rect,std::vector<gfx::Rect> * content_bounds)50 void OverlayProcessorWin::ProcessForOverlays(
51     DisplayResourceProvider* resource_provider,
52     AggregatedRenderPassList* render_passes,
53     const SkMatrix44& output_color_matrix,
54     const OverlayProcessorInterface::FilterOperationsMap& render_pass_filters,
55     const OverlayProcessorInterface::FilterOperationsMap&
56         render_pass_backdrop_filters,
57     SurfaceDamageRectList* surface_damage_rect_list,
58     OutputSurfaceOverlayPlane* output_surface_plane,
59     CandidateList* candidates,
60     gfx::Rect* damage_rect,
61     std::vector<gfx::Rect>* content_bounds) {
62   TRACE_EVENT0("viz", "OverlayProcessorWin::ProcessForOverlays");
63 
64   auto* root_render_pass = render_passes->back().get();
65   // Skip overlay processing if we have copy request.
66   if (!root_render_pass->copy_requests.empty()) {
67     damage_rect->Union(dc_layer_overlay_processor_
68                            ->previous_frame_overlay_damage_contribution());
69     // Update damage rect before calling ClearOverlayState, otherwise
70     // previous_frame_overlay_rect_union will be empty.
71     dc_layer_overlay_processor_->ClearOverlayState();
72     return;
73   }
74 
75   // Skip overlay processing if output colorspace is HDR.
76   // Since most of overlay only supports NV12 and YUY2 now, HDR content (usually
77   // P010 format) cannot output through overlay without format degrading. In
78   // some Intel's platforms (Icelake or above), Overlay can play HDR content by
79   // supporting RGB10 format. Let overlay deal with HDR content in this
80   // situation.
81   bool supports_rgb10a2_overlay =
82       (gl::GetOverlaySupportFlags(DXGI_FORMAT_R10G10B10A2_UNORM) != 0 ||
83        output_surface_->capabilities().forces_rgb10a2_overlay_support_flags);
84   if (root_render_pass->content_color_usage == gfx::ContentColorUsage::kHDR &&
85       !supports_rgb10a2_overlay) {
86     return;
87   }
88 
89   dc_layer_overlay_processor_->Process(
90       resource_provider, gfx::RectF(root_render_pass->output_rect),
91       render_pass_filters, render_pass_backdrop_filters, render_passes,
92       damage_rect, surface_damage_rect_list, candidates);
93 
94   bool was_using_dc_layers = using_dc_layers_;
95   if (!candidates->empty()) {
96     using_dc_layers_ = true;
97     frames_since_using_dc_layers_ = 0;
98   } else if (++frames_since_using_dc_layers_ >=
99              kNumberOfFramesBeforeDisablingDCLayers) {
100     using_dc_layers_ = false;
101   }
102 
103   if (was_using_dc_layers != using_dc_layers_) {
104     output_surface_->SetEnableDCLayers(using_dc_layers_);
105     // The entire surface has to be redrawn if switching from or to direct
106     // composition layers, because the previous contents are discarded and some
107     // contents would otherwise be undefined.
108     *damage_rect = root_render_pass->output_rect;
109   }
110 }
111 
NeedsSurfaceDamageRectList() const112 bool OverlayProcessorWin::NeedsSurfaceDamageRectList() const {
113   return true;
114 }
115 
116 }  // namespace viz
117