chromium/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc

// Copyright 2017 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 "components/viz/service/frame_sinks/compositor_frame_sink_support.h"

#include <string>
#include <tuple>
#include <utility>

#include "base/functional/bind.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/with_feature_override.h"
#include "base/time/time.h"
#include "base/token.h"
#include "build/build_config.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/compositor_frame_transition_directive.h"
#include "components/viz/common/quads/shared_element_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/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/subtree_capture_id.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/compositor_frame_helpers.h"
#include "components/viz/test/fake_compositor_frame_sink_client.h"
#include "components/viz/test/fake_external_begin_frame_source.h"
#include "components/viz/test/fake_surface_observer.h"
#include "components/viz/test/mock_compositor_frame_sink_client.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_shared_image_interface_provider.h"
#include "components/viz/test/viz_test_suite.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"

_;
Contains;
Eq;
Invoke;
IsEmpty;
Key;
Ne;
SizeIs;
UnorderedElementsAre;

namespace viz {
namespace {

constexpr bool kIsRoot =;

constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
constexpr FrameSinkId kAnotherArbitraryFrameSinkId(2, 2);

constexpr gfx::Size kDefaultSize(20, 20);
constexpr gfx::Rect kDefaultOutputRect(kDefaultSize);

const base::UnguessableToken kArbitraryToken =;
const base::UnguessableToken kAnotherArbitraryToken =;

const uint64_t kBeginFrameSourceId =;

// Matches a SurfaceInfo for |surface_id|.
MATCHER_P(SurfaceInfoWithId, surface_id, "") {}

void StubResultCallback(std::unique_ptr<CopyOutputResult> result) {}

gpu::SyncToken GenTestSyncToken(int id) {}

bool BeginFrameArgsAreEquivalent(const BeginFrameArgs& first,
                                 const BeginFrameArgs& second) {}

std::string PostTestCaseNameTuple(
    const ::testing::TestParamInfo<std::tuple<bool, bool>>& info) {}

std::string PostTestCaseNameBool(const ::testing::TestParamInfo<bool>& info) {}

}  // namespace

class MockFrameSinkManagerClient : public mojom::FrameSinkManagerClient {};

class CompositorFrameSinkSupportTestBase : public testing::Test {};

class CompositorFrameSinkSupportTest
    : public testing::WithParamInterface<bool>,
      public CompositorFrameSinkSupportTestBase {};

CompositorFrameSinkSupportTest::CompositorFrameSinkSupportTest() {}

// Supports testing features::OnBeginFrameAcks, which changes the expectations
// of what IPCs are sent to the CompositorFrameSinkClient. When enabled
// OnBeginFrame also handles ReturnResources as well as
// DidReceiveCompositorFrameAck.
class OnBeginFrameAcksCompositorFrameSinkSupportTest
    : public CompositorFrameSinkSupportTestBase,
      public testing::WithParamInterface<std::tuple<bool, bool>> {};

OnBeginFrameAcksCompositorFrameSinkSupportTest::
    OnBeginFrameAcksCompositorFrameSinkSupportTest() {}

void OnBeginFrameAcksCompositorFrameSinkSupportTest::
    MaybeSendCompositorFrameAck() {}

void OnBeginFrameAcksCompositorFrameSinkSupportTest::MaybeTestOnBeginFrame(
    uint64_t sequence_number) {}

// Tests submitting a frame with resources followed by one with no resources
// with no resource provider action in between.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest, ResourceLifetimeSimple) {}

// Tests submitting a frame with resources followed by one with no resources
// with the resource provider holding everything alive.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       ResourceLifetimeSimpleWithProviderHoldingAlive) {}

// Tests referencing a resource, unref'ing it to zero, then using it again
// before returning it to the client.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       ResourceReusedBeforeReturn) {}

// Tests having resources referenced multiple times, as if referenced by
// multiple providers.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       ResourceRefMultipleTimes) {}

TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest, ResourceLifetime) {}

TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest, AddDuringEviction) {}

// Verifies that only monotonically increasing LocalSurfaceIds are accepted.
TEST_P(CompositorFrameSinkSupportTest, MonotonicallyIncreasingLocalSurfaceIds) {}

// Verifies that CopyOutputRequests submitted by unprivileged clients are
// rejected.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       ProhibitsUnprivilegedCopyRequests) {}

// Tests doing an EvictLastActivatedSurface before shutting down the factory.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       EvictLastActivatedSurface) {}

// This test checks the case where a client submits a CompositorFrame for a
// SurfaceId that has been evicted. The CompositorFrame must be immediately
// evicted.
TEST_P(CompositorFrameSinkSupportTest, ResurectAndImmediatelyEvict) {}

// Verify that a temporary reference does not block surface eviction.
TEST_P(CompositorFrameSinkSupportTest, EvictSurfaceWithTemporaryReference) {}

// Verifies that evicting a surface destroys all older surfaces as well.
TEST_P(CompositorFrameSinkSupportTest, EvictOlderSurfaces) {}

void CopyRequestTestCallback(bool* called,
                             base::OnceClosure finished,
                             std::unique_ptr<CopyOutputResult> result) {}

TEST_P(CompositorFrameSinkSupportTest, CopyRequestOnSubtree) {}

TEST_P(CompositorFrameSinkSupportTest, DuplicateCopyRequest) {}

// Check whether the SurfaceInfo object is created and populated correctly
// after the frame submission.
TEST_P(CompositorFrameSinkSupportTest, SurfaceInfo) {}

// Check that if the size of a CompositorFrame doesn't match the size of the
// Surface it's being submitted to, we skip the frame.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest, FrameSizeMismatch) {}

// Check that if the device scale factor of a CompositorFrame doesn't match the
// device scale factor of the Surface it's being submitted to, the frame is
// rejected and the surface is destroyed.
TEST_P(CompositorFrameSinkSupportTest, DeviceScaleFactorMismatch) {}

TEST_P(CompositorFrameSinkSupportTest, PassesOnBeginFrameAcks) {}

// Validates that if a client asked to stop receiving begin-frames, then it
// stops receiving begin-frames after receiving the presentation-feedback from
// the last submitted frame.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       NeedsBeginFrameResetAfterPresentationFeedback) {}

// Validates that if the client wants AutoNeedsBeginFrame, an unsolicited frame
// starts subsequent BeginFrames, as if SetNeedsBeginFrame(true) is called.
TEST_P(OnBeginFrameAcksCompositorFrameSinkSupportTest,
       AutoNeedsBeginFrameOnUnsolicitedFrame) {}

TEST_P(CompositorFrameSinkSupportTest, FrameIndexCarriedOverToNewSurface) {}

// Verifies that CopyOutputRequests made at frame sink level are sent to the
// surface that takes them first. In this test this surface is not the last
// activated surface.
TEST_P(CompositorFrameSinkSupportTest,
       OldSurfaceTakesCopyOutputRequestsFromClient) {}

TEST_P(CompositorFrameSinkSupportTest,
       OldSurfaceDoesNotTakeCopyOutputRequestsFromNewLocalId) {}

// Verifies that CopyOutputRequests made at frame sink level are sent to the
// surface that takes them first. In this test this surface is the last
// activated surface.
TEST_P(CompositorFrameSinkSupportTest,
       LastSurfaceTakesCopyOutputRequestsFromClient) {}

// Verifies that OnFrameTokenUpdate is issued after OnFirstSurfaceActivation.
TEST_P(CompositorFrameSinkSupportTest,
       OnFrameTokenUpdateAfterFirstSurfaceActivation) {}

// Test that `PendingCopyOutputRequest` with `capture_exact_surface_id` set to
// true can only be taken by the `Surface` with the exact same `SurfaceId`
// requested.
TEST_P(CompositorFrameSinkSupportTest,
       OnlyExactSurfaceCanTakeExactOutputRequest) {}

// Verify that FrameToken is sent to the client if and only if the frame is
// active.
TEST_P(CompositorFrameSinkSupportTest, OnFrameTokenUpdate) {}

// This test verifies that it is not possible to reuse the same embed token in
// two different frame sinks.
TEST_P(CompositorFrameSinkSupportTest,
       DisallowEmbedTokenReuseAcrossFrameSinks) {}

// This test verifies that the parent sequence number of the submitted
// CompositorFrames can decrease as long as the embed token changes as well.
TEST_P(CompositorFrameSinkSupportTest, SubmitAfterReparenting) {}

// This test verifies that surfaces created with a new embed token are not
// compared against the evicted parent sequence number of the previous embed
// token.
TEST_P(CompositorFrameSinkSupportTest, EvictThenReparent) {}

// Verifies that invalid hit test region does not get submitted.
TEST_P(CompositorFrameSinkSupportTest, HitTestRegionValidation) {}

// Verifies that an unresponsive client has OnBeginFrame() messages throttled
// and then stopped until it becomes responsive again.
TEST_P(CompositorFrameSinkSupportTest, ThrottleUnresponsiveClient) {}

// Verifies that when CompositorFrameSinkSupport has its
// |begin_frame_interval_| set, any BeginFrame would be sent only after this
// interval has passed from the time when the last BeginFrame was sent.
TEST_P(CompositorFrameSinkSupportTest, BeginFrameInterval) {}

TEST_P(CompositorFrameSinkSupportTest, HandlesSmallErrorInBeginFrameTimes) {}

TEST_P(CompositorFrameSinkSupportTest,
       UsesThrottledIntervalInPresentationFeedback) {}

TEST_P(CompositorFrameSinkSupportTest, ForceFullFrameToActivateSurface) {}

TEST_P(CompositorFrameSinkSupportTest,
       ReleaseTransitionDirectiveClearsFrameSinkManagerEntry) {}

TEST_P(CompositorFrameSinkSupportTest, ViewTransitionBlitRequestTextureQuad) {}

TEST_P(CompositorFrameSinkSupportTest,
       GetRequestRegionProperties_NoSurfaceWithActiveFrame) {}

TEST_P(CompositorFrameSinkSupportTest,
       GetRequestRegionProperties_SurfaceWithNoCaptureIdentifier) {}

TEST_P(CompositorFrameSinkSupportTest,
       GetRequestRegionProperties_RenderPassWithSubtreeSize) {}

TEST_P(CompositorFrameSinkSupportTest,
       GetRequestRegionProperties_RenderPassWithNoSubtreeSize) {}

TEST_P(
    CompositorFrameSinkSupportTest,
    GetRequestRegionProperties_RenderPassWithNoSubtreeSizeShouldClipToViewport) {}

TEST_P(CompositorFrameSinkSupportTest,
       GetRequestRegionProperties_RenderPassWithCaptureBounds) {}

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();
}  // namespace viz