// 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 #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::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 layer, const IntPoint& offset) { DEFINE_STATIC_LOCAL(LiteralDebugNameClient, client, ("ForeignLayer")); paint_artifact_->GetDisplayItemList() .AllocateAndConstruct( 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( 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 TestPaintArtifact::Build() { return std::move(paint_artifact_); } FakeDisplayItemClient& TestPaintArtifact::NewClient() { clients_.push_back(std::make_unique()); 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