#include "components/viz/service/display_embedder/skia_output_device_buffer_queue.h"
#include <stddef.h>
#include <stdint.h>
#include <set>
#include <string>
#include <utility>
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "build/build_config.h"
#include "components/viz/common/features.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "components/viz/service/display_embedder/output_presenter_gl.h"
#include "components/viz/service/display_embedder/skia_output_device.h"
#include "components/viz/service/display_embedder/skia_output_surface_dependency_impl.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "components/viz/test/test_gpu_service_holder.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/shared_image/shared_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
#include "gpu/command_buffer/service/shared_image/test_image_backing.h"
#include "gpu/config/gpu_finch_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/presenter.h"
#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif
_;
Expectation;
Ne;
Return;
namespace viz {
namespace {
#define GTEST_TEST_GPU_(test_suite_name, test_name, parent_class, parent_id) …
#define TEST_F_GPU(test_fixture, test_name) …
const gfx::Size kScreenSize = …;
const SkColorType kDefaultColorType = …;
class TestOnGpu : public ::testing::Test { … };
class TestImageBackingFactory : public gpu::SharedImageBackingFactory { … };
class MockPresenter : public gl::Presenter { … };
class MemoryTrackerStub : public gpu::MemoryTracker { … };
}
DidSwapBufferCompleteCallback;
BufferPresentedCallback;
class SkiaOutputDeviceBufferQueueTest : public TestOnGpu { … };
namespace {
SkiaOutputSurface::OverlayList MakeOverlayList(
std::vector<gpu::Mailbox> mailboxes) { … }
TEST_F_GPU(SkiaOutputDeviceBufferQueueTest, ScheduleOverlaysNoPrimaryPlane) { … }
#if BUILDFLAG(IS_APPLE)
TEST_F_GPU(SkiaOutputDeviceBufferQueueTest, ScheduleOverlaysStillInUse) {
FirstReshape();
std::unique_ptr<gpu::OverlayImageRepresentation> overlay_1 = MakeOverlay();
std::unique_ptr<gpu::OverlayImageRepresentation> overlay_2 = MakeOverlay();
output_device_->ScheduleOverlays(MakeOverlayList({overlay_1->mailbox()}));
EXPECT_THAT(pending_overlay_mailboxes(),
testing::ElementsAre(overlay_1->mailbox()));
Present();
EXPECT_THAT(pending_overlay_mailboxes(), testing::IsEmpty());
EXPECT_THAT(committed_overlay_mailboxes(),
testing::ElementsAre(overlay_1->mailbox()));
PageFlipComplete();
EXPECT_EQ(1u, params_.size());
EXPECT_EQ(0u, params_[0].released_overlays.size());
auto* overlay2 =
static_cast<gpu::TestOverlayImageRepresentation*>(overlay_2.get());
overlay2->MarkBackingInUse(true);
output_device_->ScheduleOverlays(MakeOverlayList({overlay_2->mailbox()}));
Present();
PageFlipComplete();
EXPECT_EQ(2u, params_.size());
EXPECT_THAT(params_[1].released_overlays,
testing::ElementsAre(overlay_1->mailbox()));
output_device_->ScheduleOverlays(MakeOverlayList({overlay_1->mailbox()}));
Present();
PageFlipComplete();
EXPECT_EQ(3u, params_.size());
EXPECT_TRUE(params_[2].released_overlays.empty());
overlay2->MarkBackingInUse(false);
output_device_->ScheduleOverlays(MakeOverlayList({overlay_1->mailbox()}));
Present();
PageFlipComplete();
EXPECT_EQ(4u, params_.size());
EXPECT_THAT(params_[3].released_overlays,
testing::ElementsAre(overlay_2->mailbox()));
}
TEST_F_GPU(SkiaOutputDeviceBufferQueueTest, InUseOverlaysAreCollected) {
output_device_->SetSwapTimeClockForTesting(&test_tick_clock_);
FirstReshape();
std::unique_ptr<gpu::OverlayImageRepresentation> overlay_1 = MakeOverlay();
std::unique_ptr<gpu::OverlayImageRepresentation> overlay_2 = MakeOverlay();
output_device_->ScheduleOverlays(MakeOverlayList({overlay_1->mailbox()}));
EXPECT_THAT(pending_overlay_mailboxes(),
testing::ElementsAre(overlay_1->mailbox()));
Present();
EXPECT_THAT(pending_overlay_mailboxes(), testing::IsEmpty());
EXPECT_THAT(committed_overlay_mailboxes(),
testing::ElementsAre(overlay_1->mailbox()));
PageFlipComplete();
EXPECT_EQ(1u, params_.size());
EXPECT_EQ(0u, params_[0].released_overlays.size());
auto* overlay2 =
static_cast<gpu::TestOverlayImageRepresentation*>(overlay_2.get());
overlay2->MarkBackingInUse(true);
output_device_->ScheduleOverlays(MakeOverlayList({overlay_2->mailbox()}));
Present();
PageFlipComplete();
EXPECT_EQ(2u, params_.size());
EXPECT_THAT(params_[1].released_overlays,
testing::ElementsAre(overlay_1->mailbox()));
EXPECT_FALSE(output_device_->OverlaysReclaimTimerForTesting().IsRunning());
output_device_->ScheduleOverlays(MakeOverlayList({overlay_1->mailbox()}));
Present();
PageFlipComplete();
EXPECT_EQ(3u, params_.size());
EXPECT_TRUE(params_[2].released_overlays.empty());
EXPECT_TRUE(output_device_->OverlaysReclaimTimerForTesting().IsRunning());
overlay2->MarkBackingInUse(false);
test_tick_clock_.Advance(base::Milliseconds(1));
output_device_->OverlaysReclaimTimerForTesting().FireNow();
EXPECT_TRUE(output_device_->OverlaysReclaimTimerForTesting().IsRunning());
test_tick_clock_.Advance(base::Seconds(1));
output_device_->OverlaysReclaimTimerForTesting().FireNow();
EXPECT_FALSE(output_device_->OverlaysReclaimTimerForTesting().IsRunning());
EXPECT_EQ(1u, released_overlays_params_.size());
EXPECT_THAT(released_overlays_params_[0],
testing::ElementsAre(overlay_2->mailbox()));
}
#endif
}
}