1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_H_
#include <optional>
#include <variant>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "components/viz/common/quads/aggregated_render_pass.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "third_party/skia/include/private/chromium/GrDeferredDisplayList.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/gfx/hdr_metadata.h"
#include "ui/gfx/overlay_layer_id.h"
#include "ui/gfx/overlay_priority_hint.h"
#include "ui/gfx/overlay_transform.h"
#include "ui/gfx/overlay_type.h"
#include "ui/gfx/video_types.h"
namespace gfx {
class Rect;
} // namespace gfx
namespace viz {
class AggregatedRenderPassDrawQuad;
class DrawQuad;
class DisplayResourceProvider;
class VIZ_SERVICE_EXPORT OverlayCandidate {
public:
// When adding or changing these return status' check how the callee uses
// these failure codes. Currently, these feed into the logging via the enum
// |OverlayProcessorDelegated::DelegationStatus|.
enum class CandidateStatus {
kSuccess,
kFailNotOverlay,
kFailNotAxisAligned,
kFailNotAxisAligned3dTransform,
kFailNotAxisAligned2dShear,
kFailNotAxisAligned2dRotation,
kFailColorMatrix,
kFailOpacity,
kFailBlending,
kFailQuadNotSupported,
kFailVisible,
kFailBufferFormat,
kFailNearFilter,
kFailPriority,
kFailRoundedDisplayMasksNotSupported,
kFailMaskFilterNotSupported,
kFailHasTransformButCantClip,
kFailRpdqWithTransform,
};
using TrackingId = uint32_t;
static constexpr TrackingId kDefaultTrackingId{0};
// Returns true if |quad| will not block quads underneath from becoming
// an overlay.
static bool IsInvisibleQuad(const DrawQuad* quad);
// Returns true if `quad` contains rounded display masks textures.
static bool QuadHasRoundedDisplayMasks(const DrawQuad* quad);
// Modifies the |candidate|'s |display_rect| to be clipped within |clip_rect|.
// This function will also update the |uv_rect| based on what clipping was
// applied to |display_rect|.
// |clip_rect| should be in the same space as |candidate|'s |display_rect|,
// and |candidate| should not have an arbitrary transform.
static void ApplyClip(OverlayCandidate& candidate,
const gfx::RectF& clip_rect);
// Returns true if the |quad| cannot be displayed on the main plane. This is
// used in conjuction with protected content that can't be GPU composited and
// will be shown via an overlay.
static bool RequiresOverlay(const DrawQuad* quad);
// Returns |candidate|'s |display_rect| transformed to its target space.
// If |candidate| holds an arbitrary transform, this will be the smallest axis
// aligned bounding rect containing |transform| applied to |display_rect|.
// If |candidate| holds an overlay transform, this will just be
// |display_rect|, which is already in its target space.
static gfx::RectF DisplayRectInTargetSpace(const OverlayCandidate& candidate);
OverlayCandidate();
OverlayCandidate(const OverlayCandidate& other);
~OverlayCandidate();
// If the quad doesn't require blending.
bool is_opaque : 1 = false;
// If the quad has a mask filter.
bool has_mask_filter : 1 = false;
// To be modified by the implementer if this candidate can go into
// an overlay.
bool overlay_handled : 1 = false;
// Is true if an HW overlay is required for the quad content.
bool requires_overlay = false;
// Helps to identify whether this is a solid color quad or not.
bool is_solid_color : 1 = false;
// Helps to identify whether this candidate has rounded-display masks or not.
bool has_rounded_display_masks : 1 = false;
// Whether this overlay candidate represents the root render pass.
bool is_root_render_pass : 1 = false;
// Whether this overlay candidate is a render pass draw quad.
bool is_render_pass_draw_quad : 1 = false;
// If we need nearest neighbor filter for displaying this overlay.
bool nearest_neighbor_filter : 1 = false;
// If true, we need to run a detiling image processor on the quad before we
// can scan it out.
bool needs_detiling : 1 = false;
// If true, this candidate uses low latency rendering and we need
// to increase its overlay priority.
bool low_latency_rendering : 1 = false;
// Rect in content space that, when combined with |transform|, is the bounds
// to position the overlay to. When |transform| is a |gx::OverlayTransform|,
// this is the bounds of the quad rect with its transform applied, so that
// content and target space for this overlay are the same.
//
// Implementer must convert to integer coordinates if setting
// |overlay_handled| to true.
gfx::RectF display_rect;
// Format of the buffer to scanout.
SharedImageFormat format = SinglePlaneFormat::kRGBA_8888;
gfx::ProtectedVideoType protected_video_type =
gfx::ProtectedVideoType::kClear;
// Hints for overlay prioritization when delegated composition is used.
gfx::OverlayPriorityHint priority_hint = gfx::OverlayPriorityHint::kNone;
// ColorSpace of the buffer for scanout.
gfx::ColorSpace color_space;
// Optional HDR Metadata for the buffer.
gfx::HDRMetadata hdr_metadata;
// Size of the resource, in pixels.
gfx::Size resource_size_in_pixels;
// Crop within the buffer to be placed inside |display_rect|.
gfx::RectF uv_rect = gfx::RectF(0.f, 0.f, 1.f, 1.f);
// Clip rect in the target space after composition, or nullopt if the quad is
// not clipped.
std::optional<gfx::Rect> clip_rect;
// Texture resource to present in an overlay.
ResourceId resource_id = kInvalidResourceId;
// Mailbox from resource_id. It is used by SkiaRenderer.
gpu::Mailbox mailbox;
#if BUILDFLAG(IS_WIN)
// Indication of the overlay to be detected as possible full screen
// letterboxing.
// During video display, sometimes the video image does not have the same
// shape or Picture Aspect Ratio as the display area. Letterboxing is the
// process of scaling a widescreen image to fit a specific display, like 4:3.
// The reverse case, scaling a 4:3 image to fit a widescreen display, is
// sometimes called pillarboxing. However here letterboxing is also used in a
// general sense, to mean scaling a video image to fit any given display area.
// Check out more information from
// https://learn.microsoft.com/en-us/windows/win32/medfound/picture-aspect-ratio#letterboxing.
// Two conditions to make possible_video_fullscreen_letterboxing be true:
// 1. Current page is in full screen mode which is decided by
// AggregatedFrame::page_fullscreen_mode.
// 2. IsPossibleFullScreenLetterboxing helper from
// DCLayerOverlayProcessor returns true, which basically means the draw
// quad beneath the overlay quad touches two sides of the screen while
// starting at display origin (0, 0). Then before swap chain presentation and
// with possible_video_fullscreen_letterboxing be true, some necessary
// adjustment is done in order to make the video be equidistant from the sides
// off the screen. That is, it needs to be CENTERED for the sides that are not
// touching the screen. At this point, Desktop Window Manager(DWM) considers
// the video as full screen letterboxing.
bool possible_video_fullscreen_letterboxing = false;
#endif
#if BUILDFLAG(IS_ANDROID)
// Is video using SurfaceView-like architecture. It's currently actually uses
// `DialogOverlay` in browser instead of actual SurfaceView. But "SurfaceView"
// is used throughout the code so is used here as well for consistency.
bool is_video_in_surface_view = false;
// Crop within the buffer to be placed inside |display_rect| before
// |clip_rect| was applied. Valid only for surface control.
gfx::RectF unclipped_uv_rect = gfx::RectF(0.f, 0.f, 1.f, 1.f);
// |display_rect| before |clip_rect| was applied. Valid only for surface
// control.
gfx::RectF unclipped_display_rect = gfx::RectF(0.f, 0.f, 1.f, 1.f);
#endif
// Stacking order of the overlay plane relative to the main surface,
// which is 0. Signed to allow for "underlays".
int plane_z_order = 0;
// The total area in square pixels of damage for this candidate's quad. This
// is an estimate when 'EstimateOccludedDamage' function is used.
float damage_area_estimate = 0.f;
// Damage in viz Display space, the same space as |display_rect|;
gfx::RectF damage_rect;
static constexpr uint32_t kInvalidDamageIndex = UINT_MAX;
// Damage index for |SurfaceDamageRectList|.
uint32_t overlay_damage_index = kInvalidDamageIndex;
// Represents either a background of this overlay candidate or a color of a
// solid color quad, which can be checked via the |is_solid_color|.
std::optional<SkColor4f> color;
// If |rpdq| is present, then the renderer must draw the filter effects and
// copy the result into the buffer backing of a render pass.
raw_ptr<const AggregatedRenderPassDrawQuad, DanglingUntriaged> rpdq = nullptr;
// Quad |shared_quad_state| opacity is ubiquitous for quad types
// AggregateRenderPassDrawQuad, TileDrawQuad, SolidColorDrawQuad. A delegate
// context must support non opaque opacity for these types.
float opacity = 1.0f;
// Specifies the rounded corners of overlay candidate, in target space.
gfx::RRectF rounded_corners;
#if BUILDFLAG(IS_APPLE)
// Layers in a non-zero sorting context exist in the same 3D space and should
// intersect.
unsigned sorting_context_id = 0;
// The edge anti-aliasing mask property for the CALayer.
unsigned edge_aa_mask = 0;
#endif // BUILDFLAG(IS_APPLE)
// A (ideally) unique key used to temporally identify a specific overlay
// candidate. This key can have collisions more that would be expected by the
// birthday paradox of 32 bits. If two or more candidates come from the same
// surface and have the same |DrawQuad::rect| they will have the same
// |tracking_id|.
TrackingId tracking_id = kDefaultTrackingId;
#if BUILDFLAG(IS_WIN)
// Used to identify overlays that originate from the same cc layer.
gfx::OverlayLayerId layer_id;
#endif
// Transformation to apply to layer during composition.
// Note: A |gfx::OverlayTransform| transforms the buffer within its bounds and
// does not affect |display_rect|.
std::variant<gfx::OverlayTransform, gfx::Transform> transform =
gfx::OVERLAY_TRANSFORM_NONE;
// Default overlay type.
gfx::OverlayType overlay_type = gfx::OverlayType::kSimple;
};
using OverlayCandidateList = std::vector<OverlayCandidate>;
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_CANDIDATE_H_
|