blob: 998abad19e49c4fd8aa8412fd3860325f3d408dd [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/testing/test_paint_artifact.h"
#include <memory>
#include "cc/layers/layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
static DisplayItemClient& StaticDummyClient() {
DEFINE_STATIC_LOCAL(FakeDisplayItemClient, client, ());
client.Validate();
return client;
}
TestPaintArtifact& TestPaintArtifact::Chunk(int id) {
Chunk(StaticDummyClient(),
static_cast<DisplayItem::Type>(DisplayItem::kDrawingFirst + id));
// The default bounds with magic numbers make the chunks have different bounds
// from each other, for e.g. RasterInvalidatorTest to check the tracked raster
// invalidation rects of chunks. The actual values don't matter. If the chunk
// has display items, we will recalculate the bounds from the display items
// when constructing the PaintArtifact.
Bounds(IntRect(id * 110, id * 220, id * 220 + 200, id * 110 + 200));
return *this;
}
TestPaintArtifact& TestPaintArtifact::Chunk(DisplayItemClient& client,
DisplayItem::Type type) {
auto& display_item_list = paint_artifact_->GetDisplayItemList();
paint_artifact_->PaintChunks().emplace_back(
display_item_list.size(), display_item_list.size(),
PaintChunk::Id(client, type), PropertyTreeState::Root());
// Assume PaintController has processed this chunk.
paint_artifact_->PaintChunks().back().client_is_just_created = false;
return *this;
}
TestPaintArtifact& TestPaintArtifact::Properties(
const PropertyTreeStateOrAlias& properties) {
paint_artifact_->PaintChunks().back().properties = properties;
return *this;
}
TestPaintArtifact& TestPaintArtifact::RectDrawing(const IntRect& bounds,
Color color) {
return RectDrawing(NewClient(), bounds, color);
}
TestPaintArtifact& TestPaintArtifact::ScrollHitTest(
const IntRect& rect,
const TransformPaintPropertyNode* scroll_translation) {
return ScrollHitTest(NewClient(), rect, scroll_translation);
}
TestPaintArtifact& TestPaintArtifact::ForeignLayer(
scoped_refptr<cc::Layer> layer,
const IntPoint& offset) {
DEFINE_STATIC_LOCAL(LiteralDebugNameClient, client, ("ForeignLayer"));
paint_artifact_->GetDisplayItemList()
.AllocateAndConstruct<ForeignLayerDisplayItem>(
client, DisplayItem::kForeignLayerFirst, std::move(layer), offset);
DidAddDisplayItem();
return *this;
}
TestPaintArtifact& TestPaintArtifact::RectDrawing(DisplayItemClient& client,
const IntRect& bounds,
Color color) {
PaintRecorder recorder;
cc::PaintCanvas* canvas = recorder.beginRecording(bounds);
if (!bounds.IsEmpty()) {
PaintFlags flags;
flags.setColor(color.Rgb());
canvas->drawRect(bounds, flags);
}
paint_artifact_->GetDisplayItemList()
.AllocateAndConstruct<DrawingDisplayItem>(
client, DisplayItem::kDrawingFirst, bounds,
recorder.finishRecordingAsPicture());
DidAddDisplayItem();
return *this;
}
TestPaintArtifact& TestPaintArtifact::ScrollHitTest(
DisplayItemClient& client,
const IntRect& rect,
const TransformPaintPropertyNode* scroll_translation) {
auto& hit_test_data =
paint_artifact_->PaintChunks().back().EnsureHitTestData();
hit_test_data.scroll_hit_test_rect = rect;
hit_test_data.scroll_translation = scroll_translation;
return *this;
}
TestPaintArtifact& TestPaintArtifact::SetRasterEffectOutset(
RasterEffectOutset outset) {
paint_artifact_->PaintChunks().back().raster_effect_outset = outset;
return *this;
}
TestPaintArtifact& TestPaintArtifact::KnownToBeOpaque() {
paint_artifact_->PaintChunks().back().known_to_be_opaque = true;
return *this;
}
TestPaintArtifact& TestPaintArtifact::Bounds(const IntRect& bounds) {
auto& chunk = paint_artifact_->PaintChunks().back();
chunk.bounds = bounds;
chunk.drawable_bounds = bounds;
return *this;
}
TestPaintArtifact& TestPaintArtifact::DrawableBounds(
const IntRect& drawable_bounds) {
auto& chunk = paint_artifact_->PaintChunks().back();
chunk.drawable_bounds = drawable_bounds;
DCHECK(chunk.bounds.Contains(drawable_bounds));
return *this;
}
TestPaintArtifact& TestPaintArtifact::Uncacheable() {
paint_artifact_->PaintChunks().back().is_cacheable = false;
return *this;
}
scoped_refptr<PaintArtifact> TestPaintArtifact::Build() {
return std::move(paint_artifact_);
}
FakeDisplayItemClient& TestPaintArtifact::NewClient() {
clients_.push_back(std::make_unique<FakeDisplayItemClient>());
return *clients_.back();
}
FakeDisplayItemClient& TestPaintArtifact::Client(wtf_size_t i) const {
return *clients_[i];
}
void TestPaintArtifact::DidAddDisplayItem() {
auto& chunk = paint_artifact_->PaintChunks().back();
DCHECK_EQ(chunk.end_index, paint_artifact_->GetDisplayItemList().size() - 1);
const auto& item = paint_artifact_->GetDisplayItemList().back();
chunk.bounds.Unite(item.VisualRect());
if (item.DrawsContent())
chunk.drawable_bounds.Unite(item.VisualRect());
chunk.end_index++;
}
} // namespace blink