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