blob: 96d156064bf9f8b50680f35d664b2e2429912469 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <limits>
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "components/viz/common/quads/compositor_frame_transition_directive.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/surfaces/surface_saved_frame.h"
#include "components/viz/service/transitions/transferable_resource_tracker.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace viz {
namespace {
std::unique_ptr<SurfaceSavedFrame> CreateFrameWithResult() {
auto directive = CompositorFrameTransitionDirective::CreateSave(
NavigationID::Null(), 1, {});
auto frame = std::make_unique<SurfaceSavedFrame>(
std::move(directive),
base::BindRepeating([](const CompositorFrameTransitionDirective&) {}));
frame->CompleteSavedFrameForTesting();
return frame;
}
} // namespace
class TransferableResourceTrackerTest : public testing::Test {
public:
void SetNextId(TransferableResourceTracker* tracker, uint32_t id) {
tracker->next_id_ = id;
}
// Returns if there is a SharedBitmap in SharedBitmapManager for |resource|.
bool HasBitmapResource(const TransferableResource& resource) {
DCHECK(resource.is_software);
SharedBitmapId id = resource.mailbox_holder.mailbox;
return !!shared_bitmap_manager_.GetSharedBitmapFromId(
gfx::Size(1, 1), SinglePlaneFormat::kRGBA_8888, id);
}
protected:
ServerSharedBitmapManager shared_bitmap_manager_;
};
TEST_F(TransferableResourceTrackerTest, IdInRange) {
TransferableResourceTracker tracker(&shared_bitmap_manager_);
auto frame1 = tracker.ImportResources(CreateFrameWithResult());
EXPECT_TRUE(HasBitmapResource(frame1.root.resource));
EXPECT_GE(frame1.root.resource.id, kVizReservedRangeStartId);
auto frame2 = tracker.ImportResources(CreateFrameWithResult());
EXPECT_TRUE(HasBitmapResource(frame2.root.resource));
EXPECT_GE(frame2.root.resource.id, frame1.root.resource.id);
tracker.ReturnFrame(frame1);
EXPECT_FALSE(HasBitmapResource(frame1.root.resource));
tracker.RefResource(frame2.root.resource.id);
tracker.ReturnFrame(frame2);
EXPECT_TRUE(HasBitmapResource(frame2.root.resource));
tracker.UnrefResource(frame2.root.resource.id, 1);
EXPECT_FALSE(HasBitmapResource(frame2.root.resource));
}
TEST_F(TransferableResourceTrackerTest, ExhaustedIdLoops) {
static_assert(std::is_same<decltype(kInvalidResourceId.GetUnsafeValue()),
uint32_t>::value,
"The test only makes sense if ResourceId is uint32_t");
uint32_t next_id = std::numeric_limits<uint32_t>::max() - 3u;
TransferableResourceTracker tracker(&shared_bitmap_manager_);
SetNextId(&tracker, next_id);
ResourceId last_id = kInvalidResourceId;
for (int i = 0; i < 10; ++i) {
auto frame = tracker.ImportResources(CreateFrameWithResult());
EXPECT_TRUE(HasBitmapResource(frame.root.resource));
EXPECT_GE(frame.root.resource.id, kVizReservedRangeStartId);
EXPECT_NE(frame.root.resource.id, last_id);
last_id = frame.root.resource.id;
tracker.ReturnFrame(frame);
EXPECT_FALSE(HasBitmapResource(frame.root.resource));
}
}
TEST_F(TransferableResourceTrackerTest, UnrefWithCount) {
TransferableResourceTracker tracker(&shared_bitmap_manager_);
auto frame = tracker.ImportResources(CreateFrameWithResult());
for (int i = 0; i < 1000; ++i)
tracker.RefResource(frame.root.resource.id);
ASSERT_FALSE(tracker.is_empty());
tracker.UnrefResource(frame.root.resource.id, 1);
EXPECT_FALSE(tracker.is_empty());
tracker.UnrefResource(frame.root.resource.id, 1);
EXPECT_FALSE(tracker.is_empty());
tracker.UnrefResource(frame.root.resource.id, 999);
EXPECT_TRUE(tracker.is_empty());
}
TEST_F(TransferableResourceTrackerTest,
ExhaustedIdLoopsButSkipsUnavailableIds) {
static_assert(std::is_same<decltype(kInvalidResourceId.GetUnsafeValue()),
uint32_t>::value,
"The test only makes sense if ResourceId is uint32_t");
TransferableResourceTracker tracker(&shared_bitmap_manager_);
auto reserved = tracker.ImportResources(CreateFrameWithResult());
EXPECT_GE(reserved.root.resource.id, kVizReservedRangeStartId);
uint32_t next_id = std::numeric_limits<uint32_t>::max() - 3u;
SetNextId(&tracker, next_id);
ResourceId last_id = kInvalidResourceId;
for (int i = 0; i < 10; ++i) {
auto frame = tracker.ImportResources(CreateFrameWithResult());
EXPECT_TRUE(HasBitmapResource(frame.root.resource));
EXPECT_GE(frame.root.resource.id, kVizReservedRangeStartId);
EXPECT_NE(frame.root.resource.id, last_id);
EXPECT_NE(frame.root.resource.id, reserved.root.resource.id);
last_id = frame.root.resource.id;
tracker.ReturnFrame(frame);
EXPECT_FALSE(HasBitmapResource(frame.root.resource));
}
}
} // namespace viz