chromium/components/viz/service/display/overlay_unittest.cc

// 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include <stddef.h>

#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "base/time/time_override.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/resource_provider_test_utils.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/buildflags.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/quads/aggregated_render_pass_draw_quad.h"
#include "components/viz/common/quads/compositor_render_pass.h"
#include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/service/display/display_resource_provider_skia.h"
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/output_surface_client.h"
#include "components/viz/service/display/output_surface_frame.h"
#include "components/viz/service/display/overlay_candidate.h"
#include "components/viz/service/display/overlay_candidate_factory.h"
#include "components/viz/service/display/overlay_candidate_temporal_tracker.h"
#include "components/viz/service/display/overlay_processor_using_strategy.h"
#include "components/viz/service/display/overlay_proposed_candidate.h"
#include "components/viz/service/display/overlay_strategy_fullscreen.h"
#include "components/viz/service/display/overlay_strategy_single_on_top.h"
#include "components/viz/service/display/overlay_strategy_underlay.h"
#include "components/viz/test/fake_skia_output_surface.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
#include "gpu/config/gpu_finch_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/linear_gradient.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/test/geometry_util.h"
#include "ui/latency/latency_info.h"

#if BUILDFLAG(IS_OZONE)
#include "components/viz/service/display/overlay_processor_delegated.h"
#include "ui/base/ui_base_features.h"
#endif

#if BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)
#include "components/viz/service/display/overlay_strategy_underlay_cast.h"
#endif

#if BUILDFLAG(IS_APPLE)
#include "components/viz/service/display/ca_layer_overlay.h"
#endif

_;
Mock;

namespace viz {
namespace {

RoundedDisplayMasksInfo;

const gfx::Size kDisplaySize(256, 256);
const gfx::Rect kOverlayRect(0, 0, 256, 256);
const gfx::Rect kOverlayTopLeftRect(0, 0, 128, 128);
const gfx::Rect kOverlayTopRightRect(128, 0, 128, 128);
const gfx::Rect kOverlayBottomRightRect(128, 128, 128, 128);
const gfx::Rect kOverlayClipRect(0, 0, 128, 128);
const gfx::PointF kUVTopLeft(0.1f, 0.2f);
const gfx::PointF kUVBottomRight(1.0f, 1.0f);
const SharedImageFormat kDefaultSIFormat =;
const OverlayCandidateFactory::OverlayContext kTestOverlayContext;

class TimeTicksOverride {};

// static
base::TimeTicks TimeTicksOverride::now_ticks_ =;

class TestOverlayProcessor : public OverlayProcessorUsingStrategy {};

class FullscreenOverlayProcessor : public TestOverlayProcessor {};

// Gets the minimum scaling amount used by either dimension for the src relative
// to the dst.
float GetMinScaleFactor(const OverlayCandidate& candidate) {}

class DefaultOverlayProcessor : public TestOverlayProcessor {};

class SingleOverlayProcessor : public DefaultOverlayProcessor {};

class MultiOverlayProcessorBase : public TestOverlayProcessor {};

class MultiOverlayProcessor : public MultiOverlayProcessorBase {};

class MultiSingleOnTopProcessor : public MultiOverlayProcessorBase {};

class SizeSortedMultiSingleOnTopProcessor : public MultiOverlayProcessorBase {};

class MultiUnderlayProcessor : public MultiOverlayProcessorBase {};

class SizeSortedMultiOverlayProcessorBase : public MultiOverlayProcessorBase {};

class SizeSortedMultiOverlayProcessor
    : public SizeSortedMultiOverlayProcessorBase {};

class SizeSortedMultiUnderlayProcessor
    : public SizeSortedMultiOverlayProcessorBase {};

class TypeAndSizeSortedMultiOverlayProcessor
    : public MultiOverlayProcessorBase {};

// This processor only allows only candidates with rounded-display masks after
// sorting them.
class AllowCandidateWithMasksSortedMultiOverlayProcessor
    : public MultiOverlayProcessorBase {};

class SingleOnTopOverlayProcessor : public DefaultOverlayProcessor {};

class UnderlayOverlayProcessor : public DefaultOverlayProcessor {};

class TransitionOverlayProcessor : public DefaultOverlayProcessor {};

class TransparentUnderlayOverlayProcessor : public DefaultOverlayProcessor {};

#if BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)
class UnderlayCastOverlayProcessor : public DefaultOverlayProcessor {
 public:
  UnderlayCastOverlayProcessor() : DefaultOverlayProcessor() {
    strategies_.push_back(std::make_unique<OverlayStrategyUnderlayCast>(this));
  }
};
#endif

class ChangeThresholdOnTopOverlayProcessor : public DefaultOverlayProcessor {};

class FullThresholdUnderlayOverlayProcessor : public DefaultOverlayProcessor {};

std::unique_ptr<AggregatedRenderPass> CreateRenderPass() {}

static ResourceId CreateResourceInLayerTree(
    ClientResourceProvider* child_resource_provider,
    const gfx::Size& size,
    bool is_overlay_candidate,
    SharedImageFormat format) {}

ResourceId CreateResource(DisplayResourceProvider* parent_resource_provider,
                          ClientResourceProvider* child_resource_provider,
                          RasterContextProvider* child_context_provider,
                          const gfx::Size& size,
                          bool is_overlay_candidate,
                          SharedImageFormat format,
                          SurfaceId test_surface_id = SurfaceId()) {}

ResourceId CreateResource(DisplayResourceProvider* parent_resource_provider,
                          ClientResourceProvider* child_resource_provider,
                          RasterContextProvider* child_context_provider,
                          const gfx::Size& size,
                          bool is_overlay_candidate) {}

SolidColorDrawQuad* CreateSolidColorQuadAt(
    const SharedQuadState* shared_quad_state,
    SkColor4f color,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect) {}

TextureDrawQuad* CreateCandidateQuadAt(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect,
    gfx::ProtectedVideoType protected_video_type,
    SharedImageFormat format,
    const gfx::Size& resource_size_in_pixels,
    SurfaceId test_surface_id = SurfaceId()) {}

TextureDrawQuad* CreateCandidateQuadAt(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect,
    gfx::ProtectedVideoType protected_video_type,
    SharedImageFormat format,
    SurfaceId test_surface_id = SurfaceId()) {}

TextureDrawQuad* CreateCandidateQuadAt(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect,
    SurfaceId test_surface_id = SurfaceId()) {}

#if BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)
std::unique_ptr<AggregatedRenderPass> CreateRenderPassWithTransform(
    const gfx::Transform& transform) {
  AggregatedRenderPassId render_pass_id{1};
  gfx::Rect output_rect(0, 0, 256, 256);

  auto pass = std::make_unique<AggregatedRenderPass>();
  pass->SetNew(render_pass_id, output_rect, output_rect, gfx::Transform());

  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
  shared_state->opacity = 1.f;
  shared_state->quad_to_target_transform = transform;
  return pass;
}

// For Cast we use VideoHoleDrawQuad, and that's what overlay_processor_
// expects.
VideoHoleDrawQuad* CreateVideoHoleDrawQuadAt(
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect) {
  base::UnguessableToken overlay_plane_id = base::UnguessableToken::Create();
  auto* overlay_quad =
      render_pass->CreateAndAppendDrawQuad<VideoHoleDrawQuad>();
  overlay_quad->SetNew(shared_quad_state, rect, rect, overlay_plane_id);
  return overlay_quad;
}
#endif

TextureDrawQuad* CreateTransparentCandidateQuadAt(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect) {}

TextureDrawQuad* CreateFullscreenCandidateQuad(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass) {}

TextureDrawQuad* CreateQuadWithRoundedDisplayMasksAt(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    bool is_overlay_candidate,
    const gfx::Rect& rect,
    const RoundedDisplayMasksInfo& rounded_display_masks_info) {}

TextureDrawQuad* CreateFullscreenQuadWithRoundedDisplayMasks(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    bool is_overlay_candidate,
    const RoundedDisplayMasksInfo& rounded_display_masks_info) {}

void CreateOpaqueQuadAt(DisplayResourceProvider* resource_provider,
                        const SharedQuadState* shared_quad_state,
                        AggregatedRenderPass* render_pass,
                        const gfx::Rect& rect) {}

void CreateOpaqueQuadAt(DisplayResourceProvider* resource_provider,
                        const SharedQuadState* shared_quad_state,
                        AggregatedRenderPass* render_pass,
                        const gfx::Rect& rect,
                        SkColor4f color) {}

void CreateFullscreenOpaqueQuad(DisplayResourceProvider* resource_provider,
                                const SharedQuadState* shared_quad_state,
                                AggregatedRenderPass* render_pass) {}

static void CompareRenderPassLists(
    const AggregatedRenderPassList& expected_list,
    const AggregatedRenderPassList& actual_list) {}

SkM44 GetIdentityColorMatrix() {}

SkM44 GetNonIdentityColorMatrix() {}

template <typename OverlayProcessorType>
class OverlayTest : public testing::Test {};

template <typename OverlayProcessorType>
class UseMultipleOverlaysTest : public OverlayTest<OverlayProcessorType> {};

FullscreenOverlayTest;
SingleOverlayOnTopTest;
ChangeSingleOnTopTest;
FullThresholdTest;
TransitionOverlayTypeTest;

UnderlayTest;
TransparentUnderlayTest;
#if BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)
using UnderlayCastTest = OverlayTest<UnderlayCastOverlayProcessor>;
#endif
MultiOverlayTest;
MultiUnderlayTest;
MultiSingleOnTopOverlayTest;
SizeSortedMultiSingeOnTopOverlayTest;

SizeSortedMultiUnderlayOverlayTest;
SizeSortedMultiOverlayTest;
TypeAndSizeSortedMultiOverlayTest;
AllowCandidateWithMasksSortedMultiOverlayTest;

TEST(OverlayTest, OverlaysProcessorHasStrategy) {}

#if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_WIN)

TEST_F(FullscreenOverlayTest, DRMDefaultBlackOptimization) {}

TEST_F(FullscreenOverlayTest,
       DRMDefaultBlackOptimizationWithRoundedDisplayMaskTextures) {}

TEST_F(FullscreenOverlayTest, SuccessfulOverlay) {}

TEST_F(FullscreenOverlayTest, FailIfFullscreenQuadHasRoundedDisplayMasks) {}

TEST_F(FullscreenOverlayTest, FailOnOutputColorMatrix) {}

TEST_F(FullscreenOverlayTest, AlphaFail) {}

TEST_F(FullscreenOverlayTest, SuccessfulResourceSizeInPixels) {}

TEST_F(FullscreenOverlayTest, OnTopFail) {}

TEST_F(FullscreenOverlayTest, NotCoveringFullscreenFail) {}

TEST_F(FullscreenOverlayTest, RemoveFullscreenQuadFromQuadList) {}

TEST_F(SingleOverlayOnTopTest, SuccessfulOverlay) {}

TEST_F(MultiSingleOnTopOverlayTest,
       SuccessfulOverlay_OccludedByOverlayRoundedDisplayMaskCandidate) {}

TEST_F(MultiSingleOnTopOverlayTest, RoundedDisplayMaskCandidateNotDrawnOnTop) {}

DeathMultiSingleOnTopOverlayTest;
TEST_F(DeathMultiSingleOnTopOverlayTest,
       RoundedDisplayMaskCandidatesOverlapsEachOther) {}

TEST_F(DeathMultiSingleOnTopOverlayTest,
       RoundedDisplayMaskCandidateIsNotOverlayCandidate) {}

TEST_F(MultiSingleOnTopOverlayTest,
       PromoteRoundedDisplayMaskCandidateIfOccludeOtherCandidates) {}

TEST_F(
    MultiSingleOnTopOverlayTest,
    FailToPromoteRoundedDisplayMaskCandidatesIfTheyDontOccludeOtherCandidates) {}

TEST_F(MultiSingleOnTopOverlayTest,
       OcclusionOptimizationForRoundedDisplayMaskCandidate) {}

TEST_F(SingleOverlayOnTopTest, PrioritizeBiggerOne) {}

// It is possible (but unlikely) that the candidate tracking ids are not unique.
// This might result in some mis-prioritization but should not result in any
// significant error. Here we test that if we have two candidates with same
// tracking id the first candidate in the root is selected for overlay.
TEST_F(SingleOverlayOnTopTest, CandidateIdCollision) {}

// Tests to make sure that quads from different surfaces have different
// candidate tracking ids.
TEST_F(SingleOverlayOnTopTest, CandidateTrackIdUniqueSurface) {}

// This test makes sure that the prioritization choices remain stable over a
// series of many frames. The example here would be two similar sized unoccluded
// videos running at 30fps. It is possible (observed on android) for these
// frames to get staggered such that each video frame updates on alternating
// frames of the 60fps vsync. Under specific damage conditions this will lead
// prioritization to be very indecisive and flip priorities every frame. The
// root cause for this issue has been resolved.
TEST_F(SingleOverlayOnTopTest, StablePrioritizeIntervalFrame) {}

TEST_F(SingleOverlayOnTopTest, OpaqueOverlayDamageSubtract) {}

TEST_F(SingleOverlayOnTopTest, NonOpaquePureOverlayFirstFrameDamage) {}

TEST_F(SingleOverlayOnTopTest, NonOpaquePureOverlayNonOccludingDamage) {}

TEST_F(SingleOverlayOnTopTest, DamageRect) {}

TEST_F(SingleOverlayOnTopTest, DamageWithMutipleSurfaceDamage) {}

TEST_F(SingleOverlayOnTopTest, NoCandidates) {}

TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {}

// Test with multiple render passes.
TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {}

TEST_F(SingleOverlayOnTopTest, AcceptBlending) {}

TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {}

TEST_F(SingleOverlayOnTopTest, AcceptBlackBackgroundColor) {}

// MaskFilters are only supported by underlay strategy.
TEST_F(UnderlayTest, AcceptBlackBackgroundColorWithRoundedCorners) {}

// MaskFilters are only supported by underlay strategy.
TEST_F(UnderlayTest, RejectBlackBackgroundColorWithGradient) {}

TEST_F(SingleOverlayOnTopTest, RejectBlackBackgroundColorWithBlending) {}

TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {}

TEST_F(SingleOverlayOnTopTest, RejectOpacity) {}

TEST_F(SingleOverlayOnTopTest, RejectNearestNeighbor) {}

TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) {}

TEST_F(SingleOverlayOnTopTest, AllowClipped) {}

TEST_F(UnderlayTest, ReplacementQuad) {}

TEST_F(UnderlayTest, AllowVerticalFlip) {}

TEST_F(UnderlayTest, AllowHorizontalFlip) {}

TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {}

TEST_F(SingleOverlayOnTopTest, AcceptMirrorYTransform) {}

TEST_F(UnderlayTest, Allow90DegreeRotation) {}

TEST_F(UnderlayTest, Allow180DegreeRotation) {}

TEST_F(UnderlayTest, Allow270DegreeRotation) {}

TEST_F(UnderlayTest, AllowsOpaqueCandidates) {}

TEST_F(UnderlayTest, DisallowsQuadsWithRoundedDisplayMasks) {}

TEST_F(UnderlayTest, DisallowsTransparentCandidates) {}

TEST_F(UnderlayTest, DisallowFilteredQuadOnTop) {}

TEST_F(UnderlayTest, AllowFilteredQuadOnTopForProtectedVideo) {}

TEST_F(TransparentUnderlayTest, AllowsOpaqueCandidates) {}

TEST_F(TransparentUnderlayTest, AllowsTransparentCandidates) {}

TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {}

TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {}

TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {}

TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {}

TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {}

// Test makes sure promotion hint (|overlay_priority_hint| in |TextureDrawQuad|)
// feature functions. The (current) expectation is that |kLow| will not promote
// and that |kRequired| will be promoted in preference to |kRegular| candidates.
TEST_F(SingleOverlayOnTopTest, CheckPromotionHintBasic) {}

TEST_F(ChangeSingleOnTopTest, DoNotPromoteIfContentsDontChange) {}

TEST_F(FullThresholdTest, ThresholdTestForPrioritization) {}

TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {}

TEST_F(UnderlayTest, AllowOnTop) {}

// Pure overlays have a very specific optimization that does not produce damage
// on promotion because it is not required. However the same rect overlay
// transitions to an underlay the entire |display_rect| must damage the primary
// plane.This allows for the transparent black window to be drawn allowing the
// underlay to show through.
TEST_F(TransitionOverlayTypeTest, DamageChangeOnTransistionOverlayType) {}

TEST_F(TransitionOverlayTypeTest, DamageWhenOverlayBecomesTransparent) {}

// A candidate with a mask filter must go to underlay, and not single on top.
// Also, the quad must be replaced by a black quad with |SkBlendMode::kDstOut|.
TEST_F(TransitionOverlayTypeTest, MaskFilterBringsUnderlay) {}

// The first time an underlay is scheduled its damage must not be excluded.
TEST_F(UnderlayTest, InitialUnderlayDamageNotExcluded) {}

// An identical underlay for two frames in a row means the damage can be
// excluded the second time. On demotion the frame damage will be the display
// rect of the underlay. After the demotion there will be no exclusion of
// damage.
TEST_F(UnderlayTest, DamageExcludedForConsecutiveIdenticalUnderlays) {}

// Underlay damage can only be excluded if the previous frame's underlay
// was the same rect.
TEST_F(UnderlayTest, DamageNotExcludedForNonIdenticalConsecutiveUnderlays) {}

// Underlay damage can only be excluded if the previous frame's underlay exists.
TEST_F(UnderlayTest, DamageNotExcludedForNonConsecutiveIdenticalUnderlays) {}

// Underlay damage cannot be excluded if the underlay has a mask filter in the
// current frame but did not in the previous frame or vice versa.
TEST_F(
    UnderlayTest,
    DamageNotExcludedForConsecutiveUnderlaysIfOneHasMaskFilterAndOtherDoesNot) {}

TEST_F(UnderlayTest, DamageExcludedForCandidateAndThoseOccluded) {}

TEST_F(UnderlayTest, DamageExtractedWhenQuadsAboveDontOverlap) {}

TEST_F(UnderlayTest, PrimaryPlaneOverlayIsTransparentWithUnderlay) {}

TEST_F(UnderlayTest, UpdateDamageWhenChangingUnderlays) {}

TEST_F(UnderlayTest, OverlayCandidateTemporalTracker) {}

TEST_F(UnderlayTest, UpdateDamageRectWhenNoPromotion) {}

// Tests that no damage occurs when the quad shared state has no occluding
// damage.
TEST_F(UnderlayTest, CandidateNoDamageWhenQuadSharedStateNoOccludingDamage) {}
#endif  // !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_WIN)

#if BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)
TEST_F(UnderlayCastTest, ReplacementQuad) {
  auto pass = CreateRenderPass();
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            kOverlayRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);
  ASSERT_EQ(1U, pass_list.size());
  ASSERT_EQ(1U, pass_list.front()->quad_list.size());
  EXPECT_EQ(SkColors::kTransparent, static_cast<SolidColorDrawQuad*>(
                                        pass_list.front()->quad_list.front())
                                        ->color);
  EXPECT_FALSE(pass_list.front()->quad_list.front()->ShouldDrawWithBlending());
  EXPECT_FALSE(pass_list.front()
                   ->quad_list.front()
                   ->shared_quad_state->are_contents_opaque);
}

TEST_F(UnderlayCastTest, NoOverlayContentBounds) {
  auto pass = CreateRenderPass();

  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     kOverlayTopLeftRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);
  EXPECT_EQ(0U, content_bounds_.size());
}

TEST_F(UnderlayCastTest, FullScreenOverlayContentBounds) {
  auto pass = CreateRenderPass();
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            kOverlayRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  EXPECT_EQ(1U, content_bounds_.size());
  EXPECT_TRUE(content_bounds_[0].IsEmpty());
}

TEST_F(UnderlayCastTest, BlackOutsideOverlayContentBounds) {
  AddExpectedRectToOverlayProcessor(gfx::RectF(kOverlayBottomRightRect));

  const gfx::Rect kLeftSide(0, 0, 128, 256);
  const gfx::Rect kTopRight(128, 0, 128, 128);

  auto pass = CreateRenderPass();
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            kOverlayBottomRightRect);
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(), kLeftSide,
                     SkColors::kBlack);
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(), kTopRight,
                     SkColors::kBlack);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  EXPECT_EQ(1U, content_bounds_.size());
  EXPECT_TRUE(content_bounds_[0].IsEmpty());
}

TEST_F(UnderlayCastTest, OverlayOccludedContentBounds) {
  auto pass = CreateRenderPass();
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     kOverlayTopLeftRect);
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            kOverlayRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  EXPECT_EQ(1U, content_bounds_.size());
  EXPECT_EQ(kOverlayTopLeftRect, content_bounds_[0]);
}

TEST_F(UnderlayCastTest, OverlayOccludedUnionContentBounds) {
  auto pass = CreateRenderPass();
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     kOverlayTopLeftRect);
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     kOverlayBottomRightRect);
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            kOverlayRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  EXPECT_EQ(1U, content_bounds_.size());
  EXPECT_EQ(kOverlayRect, content_bounds_[0]);
}

TEST_F(UnderlayCastTest, RoundOverlayContentBounds) {
  // Check rounding behaviour on overlay quads.  Be conservative (content
  // potentially visible on boundary).
  const gfx::Rect overlay_rect(1, 1, 8, 8);
  AddExpectedRectToOverlayProcessor(gfx::RectF(1.5f, 1.5f, 8, 8));

  gfx::Transform transform;
  transform.Translate(0.5f, 0.5f);

  auto pass = CreateRenderPassWithTransform(transform);
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            overlay_rect);
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     gfx::Rect(0, 0, 10, 10), SkColors::kWhite);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  EXPECT_EQ(1U, content_bounds_.size());
  EXPECT_EQ(gfx::Rect(0, 0, 11, 11), content_bounds_[0]);
}

TEST_F(UnderlayCastTest, RoundContentBounds) {
  // Check rounding behaviour on content quads (bounds should be enclosing
  // rect).
  gfx::Rect overlay_rect = kOverlayRect;
  overlay_rect.Inset(gfx::Insets::TLBR(0, 0, 1, 1));
  AddExpectedRectToOverlayProcessor(gfx::RectF(0.5f, 0.5f, 255, 255));

  gfx::Transform transform;
  transform.Translate(0.5f, 0.5f);

  auto pass = CreateRenderPassWithTransform(transform);
  CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
                            overlay_rect);
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     gfx::Rect(0, 0, 255, 255), SkColors::kWhite);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  EXPECT_EQ(1U, content_bounds_.size());
  EXPECT_EQ(kOverlayRect, content_bounds_[0]);
}

TEST_F(UnderlayCastTest, NoOverlayPromotionWithoutProtectedContent) {
  auto pass = CreateRenderPass();
  CreateCandidateQuadAt(resource_provider_.get(),
                        child_resource_provider_.get(), child_provider_.get(),
                        pass->shared_quad_state_list.back(), pass.get(),
                        kOverlayRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  SurfaceDamageRectList surface_damage_rect_list;

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  ASSERT_TRUE(candidate_list.empty());
  EXPECT_TRUE(content_bounds_.empty());
}

TEST_F(UnderlayCastTest, OverlayPromotionWithMaskFilter) {
  auto pass = CreateRenderPass();

  SurfaceDamageRectList surface_damage_rect_list;
  auto* sqs = pass->shared_quad_state_list.front();
  sqs->overlay_damage_index = 0;
  surface_damage_rect_list.emplace_back(damage_rect_);
  sqs->mask_filter_info =
      gfx::MaskFilterInfo(gfx::RectF(kOverlayRect), gfx::RoundedCornersF(1.f),
                          gfx::LinearGradient::GetEmpty());
  CreateVideoHoleDrawQuadAt(sqs, pass.get(), kOverlayRect);

  OverlayCandidateList candidate_list;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));

  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), nullptr, &candidate_list,
      &damage_rect_, &content_bounds_);

  ASSERT_EQ(1U, content_bounds_.size());
  EXPECT_TRUE(content_bounds_.front().IsEmpty());

  ASSERT_EQ(1U, pass_list.size());
  ASSERT_EQ(1U, pass_list.front()->quad_list.size());
  EXPECT_EQ(SkColors::kBlack, static_cast<SolidColorDrawQuad*>(
                                  pass_list.front()->quad_list.front())
                                  ->color);
  EXPECT_FALSE(pass_list.front()
                   ->quad_list.front()
                   ->shared_quad_state->are_contents_opaque);
  EXPECT_EQ(
      SkBlendMode::kDstOut,
      pass_list.front()->quad_list.front()->shared_quad_state->blend_mode);
}
#endif  // BUILDFLAG(ENABLE_CAST_OVERLAY_STRATEGY)

#if BUILDFLAG(ALWAYS_ENABLE_BLENDING_FOR_PRIMARY)
TEST_F(UnderlayCastTest, PrimaryPlaneOverlayIsAlwaysTransparent) {
  auto pass = CreateRenderPass();
  gfx::Rect output_rect = pass->output_rect;
  CreateOpaqueQuadAt(resource_provider_.get(),
                     pass->shared_quad_state_list.back(), pass.get(),
                     output_rect, SkColors::kWhite);

  OverlayCandidateList candidate_list;

  OverlayProcessorInterface::FilterOperationsMap render_pass_filters;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters;
  AggregatedRenderPassList pass_list;
  pass_list.push_back(std::move(pass));
  auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay(
      kDisplaySize, kDisplaySize, kDefaultSIFormat, gfx::ColorSpace(),
      false /* has_alpha */, 1.0f /* opacity */, gpu::Mailbox());

  SurfaceDamageRectList surface_damage_rect_list;
  overlay_processor_->ProcessForOverlays(
      resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
      render_pass_filters, render_pass_backdrop_filters,
      std::move(surface_damage_rect_list), &output_surface_plane,
      &candidate_list, &damage_rect_, &content_bounds_);

  ASSERT_EQ(true, output_surface_plane.enable_blending);
  EXPECT_EQ(0U, content_bounds_.size());
}
#endif  // BUILDFLAG(ALWAYS_ENABLE_BLENDING_FOR_PRIMARY)

#if BUILDFLAG(IS_APPLE)
class CALayerOverlayRPDQTest : public CALayerOverlayTest {
 protected:
  void SetUp() override {
    CALayerOverlayTest::SetUp();
    pass_list_.push_back(CreateRenderPass());
    pass_ = pass_list_.back().get();
    quad_ = pass_->CreateAndAppendDrawQuad<AggregatedRenderPassDrawQuad>();
    render_pass_id_ = 3;
  }

  void ProcessForOverlays() {
    overlay_processor_->ProcessForOverlays(
        resource_provider_.get(), &pass_list_, GetIdentityColorMatrix(),
        render_pass_filters_, render_pass_backdrop_filters_,
        std::move(surface_damage_rect_list_), nullity, &ca_layer_list_,
        &damage_rect_, &content_bounds_);
  }
  AggregatedRenderPassList pass_list_;
  AggregatedRenderPass* pass_;
  AggregatedRenderPassDrawQuad* quad_;
  int render_pass_id_;
  cc::FilterOperations filters_;
  cc::FilterOperations backdrop_filters_;
  OverlayProcessorInterface::FilterOperationsMap render_pass_filters_;
  OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters_;
  CALayerOverlayList ca_layer_list_;
  SurfaceDamageRectList surface_damage_rect_list_;
};

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadNoFilters) {
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();

  EXPECT_EQ(1U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadAllValidFilters) {
  filters_.Append(cc::FilterOperation::CreateGrayscaleFilter(0.1f));
  filters_.Append(cc::FilterOperation::CreateSepiaFilter(0.2f));
  filters_.Append(cc::FilterOperation::CreateSaturateFilter(0.3f));
  filters_.Append(cc::FilterOperation::CreateHueRotateFilter(0.4f));
  filters_.Append(cc::FilterOperation::CreateInvertFilter(0.5f));
  filters_.Append(cc::FilterOperation::CreateBrightnessFilter(0.6f));
  filters_.Append(cc::FilterOperation::CreateContrastFilter(0.7f));
  filters_.Append(cc::FilterOperation::CreateOpacityFilter(0.8f));
  filters_.Append(cc::FilterOperation::CreateBlurFilter(0.9f));
  filters_.Append(cc::FilterOperation::CreateDropShadowFilter(
      gfx::Point(10, 20), 1.0f, SK_ColorGREEN));
  render_pass_filters_[render_pass_id_] = &filters_;
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();

  EXPECT_EQ(1U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadOpacityFilterScale) {
  filters_.Append(cc::FilterOperation::CreateOpacityFilter(0.8f));
  render_pass_filters_[render_pass_id_] = &filters_;
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();
  EXPECT_EQ(1U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadBlurFilterScale) {
  filters_.Append(cc::FilterOperation::CreateBlurFilter(0.8f));
  render_pass_filters_[render_pass_id_] = &filters_;
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();
  EXPECT_EQ(1U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest,
       AggregatedRenderPassDrawQuadDropShadowFilterScale) {
  filters_.Append(cc::FilterOperation::CreateDropShadowFilter(
      gfx::Point(10, 20), 1.0f, SK_ColorGREEN));
  render_pass_filters_[render_pass_id_] = &filters_;
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();
  EXPECT_EQ(1U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadBackgroundFilter) {
  backdrop_filters_.Append(cc::FilterOperation::CreateGrayscaleFilter(0.1f));
  render_pass_backdrop_filters_[render_pass_id_] = &backdrop_filters_;
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();
  EXPECT_EQ(0U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadMask) {
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, ResourceId(2), gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();
  EXPECT_EQ(1U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, AggregatedRenderPassDrawQuadUnsupportedFilter) {
  filters_.Append(cc::FilterOperation::CreateZoomFilter(0.9f, 1));
  render_pass_filters_[render_pass_id_] = &filters_;
  quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(),
                gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(),
                false, 1.0f);
  ProcessForOverlays();
  EXPECT_EQ(0U, ca_layer_list_.size());
}

TEST_F(CALayerOverlayRPDQTest, TooManyRenderPassDrawQuads) {
  filters_.Append(cc::FilterOperation::CreateBlurFilter(0.8f));
  int count = 35;

  for (int i = 0; i < count; ++i) {
    auto* quad = pass_->CreateAndAppendDrawQuad<AggregatedRenderPassDrawQuad>();
    quad->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect,
                 kOverlayRect, render_pass_id_, ResourceId(2), gfx::RectF(),
                 gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(),
                 false, 1.0f);
  }

  ProcessForOverlays();
  EXPECT_EQ(0U, ca_layer_list_.size());
}
#endif

void AddQuad(gfx::Rect quad_rect,
             const gfx::Transform& quad_to_target_transform,
             AggregatedRenderPass* render_pass) {}

TEST_F(SingleOverlayOnTopTest, IsOverlayRequiredBasic) {}

TEST_F(SingleOverlayOnTopTest, IsOverlayRequiredHwProtectedVideo) {}

TEST_F(SingleOverlayOnTopTest, RequiredOverlayClippingAndSubsampling) {}

TEST_F(SingleOverlayOnTopTest,
       RequiredOverlayClippingAndSubsamplingWithPrimary) {}

TEST_F(UnderlayTest, EstimateOccludedDamage) {}

TEST_F(UnderlayTest, ProtectedVideoOverlayScaling) {}

#if BUILDFLAG(IS_OZONE)

TileDrawQuad* CreateTileCandidateQuadAt(
    DisplayResourceProvider* parent_resource_provider,
    ClientResourceProvider* child_resource_provider,
    RasterContextProvider* child_context_provider,
    const SharedQuadState* shared_quad_state,
    AggregatedRenderPass* render_pass,
    const gfx::Rect& rect) {}

class TestDelegatedOverlayProcessor : public OverlayProcessorDelegated {};

class DelegatedTest : public OverlayTest<TestDelegatedOverlayProcessor> {};

gfx::Transform MakePerspectiveTransform() {}

gfx::Transform MakeShearTransform() {}

gfx::Transform MakeRotationTransform() {}

TEST_F(DelegatedTest, ForwardMultipleBasic) {}

// Transparent colors are important for delegating overlays. Overlays that have
// an alpha channel but are required to be drawn as opaque will have solid black
// placed behind them. This solid black can interfer with overlay
// promotion/blend optimizations.
TEST_F(DelegatedTest, ForwardBackgroundColor) {}

TEST_F(DelegatedTest, DoNotDelegateCopyRequest) {}

TEST_F(DelegatedTest, BlockDelegationWithNonRootCopies) {}

TEST_F(DelegatedTest, TestClipHandCrafted) {}

TEST_F(DelegatedTest, TestVisibleRectClip) {}

TEST_F(DelegatedTest, TestClipComputed) {}

TEST_F(DelegatedTest, TestClipAggregateRenderPass) {}

TEST_F(DelegatedTest, TestClipWithPrimary) {}

TEST_F(DelegatedTest, ScaledBufferDamage) {}

TEST_F(DelegatedTest, QuadTypes) {}

TEST_F(DelegatedTest, NonAxisAlignedCandidateStatus) {}

// These tests check to make sure that candidate quads that should fail (aka
// non-delegatable) do fail. These tests might need to be changed if we have
// improved delegation support.
class DelegatedTestNonDelegated : public DelegatedTest {};

TEST_F(DelegatedTestNonDelegated, TextureQuadNearest) {}

TEST_F(DelegatedTestNonDelegated, TileQuadNearest) {}

#endif  // BUILDFLAG(IS_OZONE)

TEST_F(MultiUnderlayTest, DamageWhenDemotingTwoUnderlays) {}

TEST_F(MultiUnderlayTest, DamageWhenDemotingOneUnderlay) {}

TEST_F(MultiOverlayTest, DamageOnlyForNewUnderlays) {}

TEST_F(MultiOverlayTest, DamageMaskFilterChange) {}

TEST_F(MultiOverlayTest, DamageOccluded) {}

TEST_F(MultiOverlayTest, FullscreenOnly) {}

TEST_F(MultiOverlayTest, RequiredOverlayOnly) {}

TEST_F(MultiOverlayTest, CappedAtMaxOverlays) {}

TEST_F(MultiOverlayTest, RoundedDisplayMaskCandidateFailsToPromote) {}

TEST_F(MultiOverlayTest,
       DontPromoteCandidatesWithMasksIfAreOnlyOverlayCandidatesNotRejected) {}

// Since AllowCandidateWithMasksSortedMultiOverlayProcessor will only allow
// candidates with masks after sorting in `SortProposedOverlayCandidates()`.
TEST_F(AllowCandidateWithMasksSortedMultiOverlayTest,
       DontPromoteCandidatesWithMasksIfAreOnlySingleOnTopCandidates) {}

TEST_F(TypeAndSizeSortedMultiOverlayTest,
       PrioritizationWithRoundedDisplayMasks) {}

// Test that we favor fullscreen even if other strategies have a higher damage
// rate were previously active.
TEST_F(TransitionOverlayTypeTest, FullscreenFavored) {}

TEST_F(SizeSortedMultiOverlayTest, OverlaysAreSorted) {}

TEST_F(SizeSortedMultiUnderlayOverlayTest, UnderlaysAreSorted) {}

class MultiUnderlayPromotedTest : public MultiUnderlayTest,
                                  public testing::WithParamInterface<bool> {};

TEST_P(MultiUnderlayPromotedTest, UnderlaysBlendPrimaryPlane) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace
}  // namespace viz