blob: 3e7235539b25fd0b46935de491dfc626beea64b0 [file] [log] [blame]
// 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_