1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CONTROLLER_TEST_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CONTROLLER_TEST_H_
#include "base/auto_reset.h"
#include "base/dcheck_is_on.h"
#include "base/functional/function_ref.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/hit_test_data.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/testing/fake_display_item_client.h"
#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
namespace blink {
class GraphicsContext;
class PaintControllerForTest : public PaintController {
public:
explicit PaintControllerForTest()
: PaintController(/*record_debug_info=*/true) {}
explicit PaintControllerForTest(
PaintControllerPersistentData& persistent_data)
: PaintController(/*record_debug_info=*/true, &persistent_data) {}
};
class AutoCommitPaintController : public PaintControllerForTest {
public:
using PaintControllerForTest::PaintControllerForTest;
~AutoCommitPaintController() { CommitNewDisplayItems(); }
};
class PaintControllerTestBase : public testing::Test {
public:
enum DrawResult {
kCached,
kPaintedNew,
kRepaintedCachedItem,
};
static DrawResult Draw(GraphicsContext& context,
const DisplayItemClient& client,
DisplayItem::Type type,
base::FunctionRef<void()> draw_function);
static DrawResult DrawNothing(GraphicsContext& context,
const DisplayItemClient& client,
DisplayItem::Type type) {
return Draw(context, client, type, [&]() {
DrawingRecorder recorder(context, client, type, gfx::Rect());
});
}
static DrawResult DrawRect(GraphicsContext& context,
const DisplayItemClient& client,
DisplayItem::Type type,
const gfx::Rect& bounds) {
return Draw(context, client, type, [&]() {
DrawingRecorder recorder(context, client, type, bounds);
context.FillRect(bounds, AutoDarkMode::Disabled());
});
}
protected:
PaintControllerTestBase()
: root_paint_property_client_(
MakeGarbageCollected<FakeDisplayItemClient>("root")),
root_paint_chunk_id_(root_paint_property_client_->Id(),
DisplayItem::kUninitializedType) {}
void SetUp() override { GTEST_FLAG_SET(death_test_style, "threadsafe"); }
void InitRootChunk(PaintController& paint_controller) const {
paint_controller.UpdateCurrentPaintChunkProperties(
root_paint_chunk_id_, *root_paint_property_client_,
DefaultPaintChunkProperties());
}
const PaintChunk::Id DefaultRootChunkId() const {
return root_paint_chunk_id_;
}
PaintControllerPersistentData& GetPersistentData() {
CHECK(persistent_data_);
return *persistent_data_;
}
static const PaintArtifact& GetNewPaintArtifact(
const PaintController& controller) {
// This can only be called before CommitNewDisplayItems().
DCHECK(controller.new_paint_artifact_);
return *controller.new_paint_artifact_;
}
static wtf_size_t NumCachedNewItems(const PaintController& controller) {
return controller.num_cached_new_items_;
}
static wtf_size_t NumCachedNewSubsequences(
const PaintController& controller) {
return controller.num_cached_new_subsequences_;
}
#if DCHECK_IS_ON()
static wtf_size_t NumIndexedItems(const PaintController& controller) {
return controller.num_indexed_items_;
}
static wtf_size_t NumSequentialMatches(const PaintController& controller) {
return controller.num_sequential_matches_;
}
static wtf_size_t NumOutOfOrderMatches(const PaintController& controller) {
return controller.num_out_of_order_matches_;
}
#endif
void InvalidateAll() { persistent_data_->InvalidateAllForTesting(); }
const SubsequenceMarkers* GetSubsequenceMarkers(
const DisplayItemClient& client) {
return persistent_data_->GetSubsequenceMarkers(client.Id());
}
bool ClientCacheIsValid(const DisplayItemClient& client) const {
return persistent_data_->ClientCacheIsValid(client);
}
static bool ClientCacheIsValid(const PaintController& paint_controller,
const DisplayItemClient& client) {
return paint_controller.ClientCacheIsValid(client);
}
private:
Persistent<FakeDisplayItemClient> root_paint_property_client_;
PaintChunk::Id root_paint_chunk_id_;
Persistent<PaintControllerPersistentData> persistent_data_ =
MakeGarbageCollected<PaintControllerPersistentData>();
};
// Matcher for checking display item list. Sample usage:
// EXPECT_THAT(paint_controller.GetDisplayItemList(),
// ElementsAre(IsSameId(client1, kBackgroundType),
// IsSameId(client2, kForegroundType)));
MATCHER_P(IsSameId, id, "") {
return arg.GetId() == id;
}
MATCHER_P2(IsSameId, client_id, type, "") {
return arg.GetId() == DisplayItem::Id(client_id, type);
}
MATCHER_P3(IsSameId, client_id, type, fragment, "") {
return arg.GetId() == DisplayItem::Id(client_id, type, fragment);
}
// Matcher for checking paint chunks. Sample usage:
// EXPACT_THAT(paint_controller.GetPaintChunks(),
// ELementsAre(IsPaintChunk(0, 1, id1, properties1),
// IsPaintChunk(1, 3, id2, properties2)));
inline bool CheckChunk(const PaintChunk& chunk,
wtf_size_t begin,
wtf_size_t end) {
return chunk.begin_index == begin && chunk.end_index == end;
}
inline bool CheckChunk(const PaintChunk& chunk,
wtf_size_t begin,
wtf_size_t end,
const PaintChunk::Id& id,
const PropertyTreeStateOrAlias& properties,
const HitTestData* hit_test_data = nullptr,
const gfx::Rect* bounds = nullptr) {
return chunk.begin_index == begin && chunk.end_index == end &&
chunk.id == id && chunk.properties == properties &&
((!chunk.hit_test_data && !hit_test_data) ||
(chunk.hit_test_data && hit_test_data &&
*chunk.hit_test_data == *hit_test_data)) &&
(!bounds || chunk.bounds == *bounds);
}
MATCHER_P2(IsPaintChunk, begin, end, "") {
return CheckChunk(arg, begin, end);
}
MATCHER_P4(IsPaintChunk, begin, end, id, properties, "") {
return CheckChunk(arg, begin, end, id, properties);
}
MATCHER_P5(IsPaintChunk, begin, end, id, properties, hit_test_data, "") {
return CheckChunk(arg, begin, end, id, properties, hit_test_data);
}
MATCHER_P6(IsPaintChunk,
begin,
end,
id,
properties,
hit_test_data,
bounds,
"") {
return CheckChunk(arg, begin, end, id, properties, hit_test_data, &bounds);
}
// Shorter names for frequently used display item types in tests.
const DisplayItem::Type kBackgroundType = DisplayItem::kBoxDecorationBackground;
const DisplayItem::Type kForegroundType =
static_cast<DisplayItem::Type>(DisplayItem::kDrawingPaintPhaseFirst + 5);
const DisplayItem::Type kClipType = DisplayItem::kClipPaintPhaseFirst;
#define EXPECT_SUBSEQUENCE(client, expected_start_chunk_index, \
expected_end_chunk_index) \
do { \
auto* subsequence = GetSubsequenceMarkers(client); \
ASSERT_NE(nullptr, subsequence); \
EXPECT_EQ(static_cast<wtf_size_t>(expected_start_chunk_index), \
subsequence->start_chunk_index); \
EXPECT_EQ(static_cast<wtf_size_t>(expected_end_chunk_index), \
subsequence->end_chunk_index); \
} while (false)
#define EXPECT_SUBSEQUENCE_FROM_CHUNK(client, start_chunk_iterator, \
chunk_count) \
EXPECT_SUBSEQUENCE( \
client, (start_chunk_iterator).IndexInPaintArtifact(), \
(start_chunk_iterator).IndexInPaintArtifact() + chunk_count)
#define EXPECT_NO_SUBSEQUENCE(client) \
EXPECT_EQ(nullptr, GetSubsequenceMarkers(client))
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CONTROLLER_TEST_H_
|