diff options
Diffstat (limited to 'chromium/cc/paint')
40 files changed, 499 insertions, 198 deletions
diff --git a/chromium/cc/paint/BUILD.gn b/chromium/cc/paint/BUILD.gn index 4c3776c0411..0a9161d4e66 100644 --- a/chromium/cc/paint/BUILD.gn +++ b/chromium/cc/paint/BUILD.gn @@ -107,6 +107,7 @@ cc_component("paint") { deps = [ "//base", + "//gpu/command_buffer/common:mailbox", "//ui/gfx/animation", "//ui/gfx/ipc/color", ] diff --git a/chromium/cc/paint/decoded_draw_image.cc b/chromium/cc/paint/decoded_draw_image.cc index 2c66554d449..69f195f2bb4 100644 --- a/chromium/cc/paint/decoded_draw_image.cc +++ b/chromium/cc/paint/decoded_draw_image.cc @@ -17,6 +17,14 @@ DecodedDrawImage::DecodedDrawImage(sk_sp<const SkImage> image, filter_quality_(filter_quality), is_budgeted_(is_budgeted) {} +DecodedDrawImage::DecodedDrawImage(const gpu::Mailbox& mailbox, + SkFilterQuality filter_quality) + : mailbox_(mailbox), + src_rect_offset_(SkSize::MakeEmpty()), + scale_adjustment_(SkSize::Make(1.f, 1.f)), + filter_quality_(filter_quality), + is_budgeted_(true) {} + DecodedDrawImage::DecodedDrawImage( base::Optional<uint32_t> transfer_cache_entry_id, const SkSize& src_rect_offset, diff --git a/chromium/cc/paint/decoded_draw_image.h b/chromium/cc/paint/decoded_draw_image.h index 02b3ad1092c..a3e47d30fc0 100644 --- a/chromium/cc/paint/decoded_draw_image.h +++ b/chromium/cc/paint/decoded_draw_image.h @@ -10,6 +10,7 @@ #include "base/optional.h" #include "cc/paint/paint_export.h" +#include "gpu/command_buffer/common/mailbox.h" #include "third_party/skia/include/core/SkFilterQuality.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -29,6 +30,7 @@ class CC_PAINT_EXPORT DecodedDrawImage { const SkSize& scale_adjustment, SkFilterQuality filter_quality, bool is_budgeted); + DecodedDrawImage(const gpu::Mailbox& mailbox, SkFilterQuality filter_quality); DecodedDrawImage(base::Optional<uint32_t> transfer_cache_entry_id, const SkSize& src_rect_offset, const SkSize& scale_adjustment, @@ -62,6 +64,7 @@ class CC_PAINT_EXPORT DecodedDrawImage { private: sk_sp<const SkImage> image_; + gpu::Mailbox mailbox_; base::Optional<uint32_t> transfer_cache_entry_id_; SkSize src_rect_offset_; SkSize scale_adjustment_; diff --git a/chromium/cc/paint/discardable_image_map_unittest.cc b/chromium/cc/paint/discardable_image_map_unittest.cc index fd52a353fcc..380ee6d6ae2 100644 --- a/chromium/cc/paint/discardable_image_map_unittest.cc +++ b/chromium/cc/paint/discardable_image_map_unittest.cc @@ -626,8 +626,8 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInShader) { .set_paint_image_generator( CreatePaintImageGenerator(gfx::Size(500, 500))) .TakePaintImage(); - SkMatrix scale = SkMatrix::MakeScale(std::max(x * 0.5f, kMinScale), - std::max(y * 0.5f, kMinScale)); + SkMatrix scale = SkMatrix::Scale(std::max(x * 0.5f, kMinScale), + std::max(y * 0.5f, kMinScale)); PaintFlags flags; flags.setShader(PaintShader::MakeImage(discardable_image[y][x], SkTileMode::kClamp, diff --git a/chromium/cc/paint/display_item_list.cc b/chromium/cc/paint/display_item_list.cc index 52a3aac9f07..071f57b646f 100644 --- a/chromium/cc/paint/display_item_list.cc +++ b/chromium/cc/paint/display_item_list.cc @@ -296,7 +296,6 @@ void DisplayItemList::Reset() { offsets_.shrink_to_fit(); paired_begin_stack_.clear(); paired_begin_stack_.shrink_to_fit(); - has_draw_ops_ = false; } sk_sp<PaintRecord> DisplayItemList::ReleaseAsRecord() { diff --git a/chromium/cc/paint/display_item_list.h b/chromium/cc/paint/display_item_list.h index b518d67715a..c065c33e60a 100644 --- a/chromium/cc/paint/display_item_list.h +++ b/chromium/cc/paint/display_item_list.h @@ -91,8 +91,6 @@ class CC_PAINT_EXPORT DisplayItemList if (usage_hint_ == kTopLevelDisplayItemList) offsets_.push_back(offset); const T* op = paint_op_buffer_.push<T>(std::forward<Args>(args)...); - if (op->IsDrawOp()) - has_draw_ops_ = true; DCHECK(op->IsValid()); return offset; } @@ -181,11 +179,17 @@ class CC_PAINT_EXPORT DisplayItemList int max_ops_to_analyze = 1); std::string ToString() const; - bool has_draw_ops() const { return has_draw_ops_; } + bool has_draw_ops() const { return paint_op_buffer_.has_draw_ops(); } // Ops with nested paint ops are considered as a single op. size_t num_paint_ops() const { return paint_op_buffer_.size(); } + bool NeedsAdditionalInvalidationForLCDText( + const DisplayItemList& old_list) const { + return paint_op_buffer_.NeedsAdditionalInvalidationForLCDText( + old_list.paint_op_buffer_); + } + private: friend class DisplayItemListTest; friend gpu::raster::RasterImplementation; @@ -238,7 +242,6 @@ class CC_PAINT_EXPORT DisplayItemList #endif UsageHint usage_hint_; - bool has_draw_ops_ = false; friend class base::RefCountedThreadSafe<DisplayItemList>; FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, BytesUsed); diff --git a/chromium/cc/paint/display_item_list_unittest.cc b/chromium/cc/paint/display_item_list_unittest.cc index a4dea57bbfb..a8230788bbb 100644 --- a/chromium/cc/paint/display_item_list_unittest.cc +++ b/chromium/cc/paint/display_item_list_unittest.cc @@ -8,6 +8,7 @@ #include <vector> +#include "base/logging.h" #include "base/trace_event/traced_value.h" #include "base/values.h" #include "cc/paint/filter_operation.h" diff --git a/chromium/cc/paint/element_id.cc b/chromium/cc/paint/element_id.cc index 3465eb1117a..a5b11cb2da2 100644 --- a/chromium/cc/paint/element_id.cc +++ b/chromium/cc/paint/element_id.cc @@ -15,6 +15,11 @@ namespace cc { const ElementIdType ElementId::kInvalidElementId = 0; +// static +bool ElementId::IsValid(ElementIdType id) { + return id != kInvalidElementId; +} + ElementId LayerIdToElementIdForTesting(int layer_id) { return ElementId(std::numeric_limits<int>::max() - layer_id); } diff --git a/chromium/cc/paint/element_id.h b/chromium/cc/paint/element_id.h index a4108a13b37..fcdebf565b7 100644 --- a/chromium/cc/paint/element_id.h +++ b/chromium/cc/paint/element_id.h @@ -63,6 +63,8 @@ struct CC_PAINT_EXPORT ElementId { std::string ToString() const; + static bool IsValid(ElementIdType id); + private: friend struct ElementIdHash; static const ElementIdType kInvalidElementId; diff --git a/chromium/cc/paint/filter_operation.h b/chromium/cc/paint/filter_operation.h index e1c018b9be3..8971192195f 100644 --- a/chromium/cc/paint/filter_operation.h +++ b/chromium/cc/paint/filter_operation.h @@ -8,7 +8,7 @@ #include <memory> #include <vector> -#include "base/logging.h" +#include "base/check_op.h" #include "cc/paint/paint_export.h" #include "cc/paint/paint_filter.h" #include "third_party/skia/include/core/SkColor.h" diff --git a/chromium/cc/paint/filter_operations.h b/chromium/cc/paint/filter_operations.h index 5bc51ad8ec8..1186796cd1a 100644 --- a/chromium/cc/paint/filter_operations.h +++ b/chromium/cc/paint/filter_operations.h @@ -10,7 +10,7 @@ #include <string> #include <vector> -#include "base/logging.h" +#include "base/check_op.h" #include "cc/paint/filter_operation.h" namespace base { diff --git a/chromium/cc/paint/filter_operations_unittest.cc b/chromium/cc/paint/filter_operations_unittest.cc index 93b3dbb0eed..7e4fdc4834d 100644 --- a/chromium/cc/paint/filter_operations_unittest.cc +++ b/chromium/cc/paint/filter_operations_unittest.cc @@ -23,9 +23,9 @@ TEST(FilterOperationsTest, MapRectBlur) { EXPECT_EQ(gfx::Rect(-60, -60, 130, 130), ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); EXPECT_EQ(gfx::Rect(-120, -120, 260, 260), - ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); + ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ(gfx::Rect(-60, -70, 130, 130), - ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::MakeScale(1, -1))); + ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectBlurOverflow) { @@ -43,10 +43,10 @@ TEST(FilterOperationsTest, MapRectReverseBlur) { ops.MapRectReverse(gfx::Rect(0, 0, 150, 150), SkMatrix::I())); EXPECT_EQ( gfx::Rect(120, 120, 60, 60), - ops.MapRectReverse(gfx::Rect(0, 0, 300, 300), SkMatrix::MakeScale(2, 2))); - EXPECT_EQ(gfx::Rect(60, 50, 30, 30), - ops.MapRectReverse(gfx::Rect(0, -10, 150, 150), - SkMatrix::MakeScale(1, -1))); + ops.MapRectReverse(gfx::Rect(0, 0, 300, 300), SkMatrix::Scale(2, 2))); + EXPECT_EQ( + gfx::Rect(60, 50, 30, 30), + ops.MapRectReverse(gfx::Rect(0, -10, 150, 150), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectDropShadowReferenceFilter) { @@ -60,9 +60,9 @@ TEST(FilterOperationsTest, MapRectDropShadowReferenceFilter) { EXPECT_EQ(gfx::Rect(-9, -19, 34, 64), ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); EXPECT_EQ(gfx::Rect(-18, -38, 68, 128), - ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); + ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ(gfx::Rect(-9, -45, 34, 64), - ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::MakeScale(1, -1))); + ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectReverseDropShadowReferenceFilter) { @@ -75,12 +75,11 @@ TEST(FilterOperationsTest, MapRectReverseDropShadowReferenceFilter) { nullptr))); EXPECT_EQ(gfx::Rect(-15, -35, 34, 64), ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); + EXPECT_EQ(gfx::Rect(-30, -70, 68, 128), + ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ( - gfx::Rect(-30, -70, 68, 128), - ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); - EXPECT_EQ(gfx::Rect(-15, -29, 34, 64), - ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), - SkMatrix::MakeScale(1, -1))); + gfx::Rect(-15, -29, 34, 64), + ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectOffsetReferenceFilter) { @@ -90,9 +89,9 @@ TEST(FilterOperationsTest, MapRectOffsetReferenceFilter) { EXPECT_EQ(gfx::Rect(30, 40, 10, 10), ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); EXPECT_EQ(gfx::Rect(60, 80, 20, 20), - ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); + ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ(gfx::Rect(30, -50, 10, 10), - ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::MakeScale(1, -1))); + ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectReverseOffsetReferenceFilter) { @@ -101,12 +100,11 @@ TEST(FilterOperationsTest, MapRectReverseOffsetReferenceFilter) { ops.Append(FilterOperation::CreateReferenceFilter(std::move(filter))); EXPECT_EQ(gfx::Rect(-30, -40, 10, 10), ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); + EXPECT_EQ(gfx::Rect(-60, -80, 20, 20), + ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ( - gfx::Rect(-60, -80, 20, 20), - ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); - EXPECT_EQ(gfx::Rect(-30, 30, 10, 10), - ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), - SkMatrix::MakeScale(1, -1))); + gfx::Rect(-30, 30, 10, 10), + ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectCombineNonCommutative) { @@ -123,9 +121,9 @@ TEST(FilterOperationsTest, MapRectCombineNonCommutative) { EXPECT_EQ(gfx::Rect(200, 200, 20, 20), ops.MapRect(gfx::Rect(10, 10), SkMatrix::I())); EXPECT_EQ(gfx::Rect(400, 400, 40, 40), - ops.MapRect(gfx::Rect(20, 20), SkMatrix::MakeScale(2, 2))); + ops.MapRect(gfx::Rect(20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ(gfx::Rect(200, -220, 20, 20), - ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::MakeScale(1, -1))); + ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectReverseCombineNonCommutative) { @@ -142,10 +140,10 @@ TEST(FilterOperationsTest, MapRectReverseCombineNonCommutative) { EXPECT_EQ(gfx::Rect(10, 10), ops.MapRectReverse(gfx::Rect(200, 200, 20, 20), SkMatrix::I())); EXPECT_EQ(gfx::Rect(20, 20), ops.MapRectReverse(gfx::Rect(400, 400, 40, 40), - SkMatrix::MakeScale(2, 2))); - EXPECT_EQ(gfx::Rect(0, -10, 10, 10), - ops.MapRectReverse(gfx::Rect(200, -220, 20, 20), - SkMatrix::MakeScale(1, -1))); + SkMatrix::Scale(2, 2))); + EXPECT_EQ( + gfx::Rect(0, -10, 10, 10), + ops.MapRectReverse(gfx::Rect(200, -220, 20, 20), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectNullReferenceFilter) { @@ -154,9 +152,9 @@ TEST(FilterOperationsTest, MapRectNullReferenceFilter) { EXPECT_EQ(gfx::Rect(0, 0, 10, 10), ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); EXPECT_EQ(gfx::Rect(0, 0, 20, 20), - ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); + ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ(gfx::Rect(0, -10, 10, 10), - ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::MakeScale(1, -1))); + ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectReverseNullReferenceFilter) { @@ -164,12 +162,11 @@ TEST(FilterOperationsTest, MapRectReverseNullReferenceFilter) { ops.Append(FilterOperation::CreateReferenceFilter(nullptr)); EXPECT_EQ(gfx::Rect(0, 0, 10, 10), ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); + EXPECT_EQ(gfx::Rect(0, 0, 20, 20), + ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ( - gfx::Rect(0, 0, 20, 20), - ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); - EXPECT_EQ(gfx::Rect(0, -10, 10, 10), - ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), - SkMatrix::MakeScale(1, -1))); + gfx::Rect(0, -10, 10, 10), + ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectDropShadow) { @@ -178,9 +175,9 @@ TEST(FilterOperationsTest, MapRectDropShadow) { EXPECT_EQ(gfx::Rect(-57, -52, 130, 130), ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); EXPECT_EQ(gfx::Rect(-114, -104, 260, 260), - ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); + ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ(gfx::Rect(-57, -78, 130, 130), - ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::MakeScale(1, -1))); + ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectReverseDropShadow) { @@ -188,12 +185,11 @@ TEST(FilterOperationsTest, MapRectReverseDropShadow) { ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 20, 0)); EXPECT_EQ(gfx::Rect(-63, -68, 130, 130), ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I())); + EXPECT_EQ(gfx::Rect(-126, -136, 260, 260), + ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2))); EXPECT_EQ( - gfx::Rect(-126, -136, 260, 260), - ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::MakeScale(2, 2))); - EXPECT_EQ(gfx::Rect(-63, -62, 130, 130), - ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), - SkMatrix::MakeScale(1, -1))); + gfx::Rect(-63, -62, 130, 130), + ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1))); } TEST(FilterOperationsTest, MapRectDropShadowDoesNotContract) { diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc index 155d95f1e3b..1f669ebefb4 100644 --- a/chromium/cc/paint/image_transfer_cache_entry.cc +++ b/chromium/cc/paint/image_transfer_cache_entry.cc @@ -24,6 +24,14 @@ namespace cc { namespace { +struct Context { + const std::vector<sk_sp<SkImage>> sk_planes_; +}; + +void ReleaseContext(SkImage::ReleaseContext context) { + auto* texture_context = static_cast<Context*>(context); + delete texture_context; +} // Creates a SkImage backed by the YUV textures corresponding to |plane_images|. // The layout is specified by |plane_images_format|). The backend textures are @@ -81,10 +89,11 @@ sk_sp<SkImage> MakeYUVImageFromUploadedPlanes( return nullptr; } plane_indices[SkYUVAIndex::kA_Index] = {-1, SkColorChannel::kR}; + Context* ctx = new Context{plane_images}; sk_sp<SkImage> image = SkImage::MakeFromYUVATextures( context, yuv_color_space, plane_backend_textures.data(), plane_indices, plane_images[0]->dimensions(), kTopLeft_GrSurfaceOrigin, - std::move(image_color_space)); + std::move(image_color_space), ReleaseContext, ctx); if (!image) { DLOG(ERROR) << "Could not create YUV image"; return nullptr; diff --git a/chromium/cc/paint/image_transfer_cache_entry_unittest.cc b/chromium/cc/paint/image_transfer_cache_entry_unittest.cc index 24a334eedbb..0da5db2f946 100644 --- a/chromium/cc/paint/image_transfer_cache_entry_unittest.cc +++ b/chromium/cc/paint/image_transfer_cache_entry_unittest.cc @@ -144,7 +144,7 @@ class ImageTransferCacheEntryTest if (texture.isValid()) gr_context_->deleteBackendTexture(texture); } - gr_context_->flush(); + gr_context_->flushAndSubmit(); textures_to_free_.clear(); } diff --git a/chromium/cc/paint/oop_pixeltest.cc b/chromium/cc/paint/oop_pixeltest.cc index 6c9f1c1e192..ffc090ebee1 100644 --- a/chromium/cc/paint/oop_pixeltest.cc +++ b/chromium/cc/paint/oop_pixeltest.cc @@ -332,7 +332,7 @@ class OopPixelTest : public testing::Test, raster_source->PlaybackToCanvas( canvas, options.content_size, options.full_raster_rect, options.playback_rect, raster_transform, settings); - surface->flush(); + surface->flushAndSubmit(); EXPECT_EQ(gles2_context_provider_->ContextGL()->GetError(), static_cast<unsigned>(GL_NO_ERROR)); @@ -852,7 +852,7 @@ TEST_P(OopImagePixelTest, DrawImageWithSetMatrix) { display_item_list->StartPaint(); PaintFlags flags; flags.setFilterQuality(FilterQuality()); - display_item_list->push<SetMatrixOp>(SkMatrix::MakeScale(0.5f, 0.5f)); + display_item_list->push<SetMatrixOp>(SkMatrix::Scale(0.5f, 0.5f)); display_item_list->push<DrawImageOp>(paint_image, 0.f, 0.f, &flags); display_item_list->EndPaintOfUnpaired(rect); display_item_list->Finalize(); @@ -1358,6 +1358,39 @@ TEST_F(OopPixelTest, DrawRectScaleTransformOptions) { ExpectEquals(actual, expected); } +TEST_F(OopPixelTest, DrawRectTransformOptionsFullRaster) { + PaintFlags flags; + // Use powers of two here to make floating point blending consistent. + flags.setColor(SkColorSetRGB(64, 128, 32)); + flags.setAntiAlias(true); + gfx::Rect draw_rect(0, 0, 19, 19); + + auto display_item_list = base::MakeRefCounted<DisplayItemList>(); + display_item_list->StartPaint(); + display_item_list->push<DrawRectOp>(gfx::RectToSkRect(draw_rect), flags); + display_item_list->EndPaintOfUnpaired(draw_rect); + display_item_list->Finalize(); + + // The opaque rect above is 1px smaller than the canvas. With the subpixel + // translation, the rect fills the whole canvas, but the pixels at the edges + // are translucent. We should clear the canvas before drawing the rect, so + // the translucent pixels at the edges should not expose the preclear color, + // even if requires_clear is not true. + RasterOptions options; + options.resource_size = {20, 20}; + options.content_size = {25, 25}; + options.full_raster_rect = {5, 5, 20, 20}; + options.playback_rect = {5, 5, 20, 20}; + options.preclear = true; + options.preclear_color = SK_ColorRED; + options.post_translate = {0.5f, 0.25f}; + options.post_scale = 2.f; + + auto actual = Raster(display_item_list, options); + auto expected = RasterExpectedBitmap(display_item_list, options); + ExpectEquals(actual, expected); +} + TEST_F(OopPixelTest, DrawRectQueryMiddleOfDisplayList) { auto display_item_list = base::MakeRefCounted<DisplayItemList>(); std::vector<SkColor> colors = { @@ -1546,12 +1579,12 @@ class OopRecordFilterPixelTest : public OopPixelTest, }; TEST_P(OopRecordFilterPixelTest, FilterWithTextScaled) { - SkMatrix mat = SkMatrix::MakeScale(2.f, 2.f); + SkMatrix mat = SkMatrix::Scale(2.f, 2.f); RunTest(mat); } TEST_P(OopRecordFilterPixelTest, FilterWithTextAndComplexCTM) { - SkMatrix mat = SkMatrix::MakeScale(2.f, 2.f); + SkMatrix mat = SkMatrix::Scale(2.f, 2.f); mat.preSkew(2.f, 2.f); RunTest(mat); } diff --git a/chromium/cc/paint/paint_canvas.h b/chromium/cc/paint/paint_canvas.h index 8a0883b7fc8..2b9c34a2336 100644 --- a/chromium/cc/paint/paint_canvas.h +++ b/chromium/cc/paint/paint_canvas.h @@ -146,16 +146,11 @@ class CC_PAINT_EXPORT PaintCanvas { drawImage(image, left, top, nullptr); } - enum SrcRectConstraint { - kStrict_SrcRectConstraint = SkCanvas::kStrict_SrcRectConstraint, - kFast_SrcRectConstraint = SkCanvas::kFast_SrcRectConstraint, - }; - virtual void drawImageRect(const PaintImage& image, const SkRect& src, const SkRect& dst, const PaintFlags* flags, - SrcRectConstraint constraint) = 0; + SkCanvas::SrcRectConstraint constraint) = 0; // Draws the frame of the |skottie| animation specified by the normalized time // t [0->first frame..1->last frame] at the destination bounds given by |dst| diff --git a/chromium/cc/paint/paint_filter.cc b/chromium/cc/paint/paint_filter.cc index 279258b26b7..cf868e21167 100644 --- a/chromium/cc/paint/paint_filter.cc +++ b/chromium/cc/paint/paint_filter.cc @@ -701,7 +701,7 @@ sk_sp<PaintFilter> ImagePaintFilter::SnapshotWithImagesInternal( PaintImage decoded_paint_image = PaintImageBuilder::WithDefault() .set_id(image_.stable_id()) - .set_image(decoded_sk_image, PaintImage::GetNextContentId()) + .set_texture_image(decoded_sk_image, PaintImage::GetNextContentId()) .TakePaintImage(); return sk_make_sp<ImagePaintFilter>(std::move(decoded_paint_image), src_rect_, diff --git a/chromium/cc/paint/paint_filter.h b/chromium/cc/paint/paint_filter.h index cec36ef7c6a..556ab9a91e8 100644 --- a/chromium/cc/paint/paint_filter.h +++ b/chromium/cc/paint/paint_filter.h @@ -5,8 +5,8 @@ #ifndef CC_PAINT_PAINT_FILTER_H_ #define CC_PAINT_PAINT_FILTER_H_ +#include "base/check_op.h" #include "base/containers/stack_container.h" -#include "base/logging.h" #include "base/optional.h" #include "base/stl_util.h" #include "cc/paint/paint_export.h" diff --git a/chromium/cc/paint/paint_flags.h b/chromium/cc/paint/paint_flags.h index c1f1cb5ce2f..e28e68929c9 100644 --- a/chromium/cc/paint/paint_flags.h +++ b/chromium/cc/paint/paint_flags.h @@ -33,7 +33,6 @@ class CC_PAINT_EXPORT PaintFlags { enum Style { kFill_Style = SkPaint::kFill_Style, kStroke_Style = SkPaint::kStroke_Style, - kStrokeAndFill_Style = SkPaint::kStrokeAndFill_Style, }; bool nothingToDraw() const; ALWAYS_INLINE Style getStyle() const { @@ -141,9 +140,13 @@ class CC_PAINT_EXPORT PaintFlags { draw_looper_ = std::move(looper); } - // Returns true if this just represents an opacity blend when - // used as saveLayer flags. + // Returns true if this just represents an opacity blend when used as + // saveLayer flags, thus the saveLayer can be converted to a saveLayerAlpha. bool IsSimpleOpacity() const; + + // Returns true if this (of a drawOp) allows the sequence + // saveLayerAlpha/drawOp/restore to be folded into a single drawOp by baking + // the alpha in the saveLayerAlpha into the flags of the drawOp. bool SupportsFoldingAlpha() const; // SkPaint does not support loopers, so callers of SkToPaint need diff --git a/chromium/cc/paint/paint_image.cc b/chromium/cc/paint/paint_image.cc index 86deeddd70f..529718556d9 100644 --- a/chromium/cc/paint/paint_image.cc +++ b/chromium/cc/paint/paint_image.cc @@ -5,6 +5,7 @@ #include "cc/paint/paint_image.h" #include <memory> +#include <sstream> #include "base/atomic_sequence_num.h" #include "base/hash/hash.h" @@ -113,6 +114,15 @@ const sk_sp<SkImage>& PaintImage::GetSkImage() const { return cached_sk_image_; } +const sk_sp<SkImage>& PaintImage::GetRasterSkImage() const { + return cached_sk_image_; +} + +gpu::Mailbox PaintImage::GetMailbox() const { + DCHECK(texture_backing_); + return texture_backing_->GetMailbox(); +} + PaintImage PaintImage::MakeSubset(const gfx::Rect& subset) const { DCHECK(!subset.IsEmpty()); @@ -133,7 +143,7 @@ PaintImage PaintImage::MakeSubset(const gfx::Rect& subset) const { // PaintImage is an optimization to allow re-use of the original decode for // image subsets in skia, for cases that rely on skia's image decode cache. result.cached_sk_image_ = - GetSkImage()->makeSubset(gfx::RectToSkIRect(subset)); + GetRasterSkImage()->makeSubset(gfx::RectToSkIRect(subset)); return result; } @@ -288,6 +298,14 @@ SkAlphaType PaintImage::GetAlphaType() const { return kUnknown_SkAlphaType; } +bool PaintImage::IsTextureBacked() const { + if (texture_backing_) + return true; + if (cached_sk_image_) + return cached_sk_image_->isTextureBacked(); + return false; +} + int PaintImage::width() const { return paint_worklet_input_ ? static_cast<int>(paint_worklet_input_->GetSize().width()) @@ -361,18 +379,19 @@ sk_sp<SkImage> PaintImage::GetSkImageForFrame( size_t index, GeneratorClientId client_id) const { DCHECK_LT(index, FrameCount()); + DCHECK(!IsTextureBacked()); // |client_id| and |index| are only relevant for generator backed images which // perform lazy decoding and can be multi-frame. if (!paint_image_generator_) { DCHECK_EQ(index, kDefaultFrameIndex); - return GetSkImage(); + return GetRasterSkImage(); } // The internally cached SkImage is constructed using the default frame index // and GeneratorClientId. Avoid creating a new SkImage. if (index == kDefaultFrameIndex && client_id == kDefaultGeneratorClientId) - return GetSkImage(); + return GetRasterSkImage(); sk_sp<SkImage> image = SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>( diff --git a/chromium/cc/paint/paint_image.h b/chromium/cc/paint/paint_image.h index 95881204e0a..1d7503a2d04 100644 --- a/chromium/cc/paint/paint_image.h +++ b/chromium/cc/paint/paint_image.h @@ -8,12 +8,12 @@ #include <vector> #include "base/gtest_prod_util.h" -#include "base/logging.h" #include "base/memory/scoped_refptr.h" #include "base/optional.h" #include "cc/paint/frame_metadata.h" #include "cc/paint/image_animation_count.h" #include "cc/paint/paint_export.h" +#include "gpu/command_buffer/common/mailbox.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkYUVAIndex.h" #include "third_party/skia/include/core/SkYUVASizeInfo.h" @@ -229,8 +229,16 @@ class CC_PAINT_EXPORT PaintImage { const SkYUVASizeInfo& yuva_size_info, SkYUVAIndex* plane_indices) const; + // Returns the SkImage associated with this PaintImage. If PaintImage is + // texture backed, this API may do a readback from GPU to CPU memory. + // Avoid using this API unless actual pixels are needed. + // For other cases, prefer using PaintImage APIs directly or use + // GetSkImageInfo() for metadata about the SkImage. + const sk_sp<SkImage>& GetRasterSkImage() const; + Id stable_id() const { return id_; } const sk_sp<SkImage>& GetSkImage() const; + gpu::Mailbox GetMailbox() const; AnimationType animation_type() const { return animation_type_; } CompletionState completion_state() const { return completion_state_; } bool is_multipart() const { return is_multipart_; } @@ -253,9 +261,7 @@ class CC_PAINT_EXPORT PaintImage { return paint_worklet_input_ ? false : GetSkImage()->isLazyGenerated(); } bool IsPaintWorklet() const { return !!paint_worklet_input_; } - bool IsTextureBacked() const { - return paint_worklet_input_ ? false : GetSkImage()->isTextureBacked(); - } + bool IsTextureBacked() const; int width() const; int height() const; SkColorSpace* color_space() const { diff --git a/chromium/cc/paint/paint_image_builder.h b/chromium/cc/paint/paint_image_builder.h index 25a20bf1a9c..8820b078f5e 100644 --- a/chromium/cc/paint/paint_image_builder.h +++ b/chromium/cc/paint/paint_image_builder.h @@ -43,10 +43,17 @@ class CC_PAINT_EXPORT PaintImageBuilder { PaintImageBuilder&& set_image(sk_sp<SkImage> sk_image, PaintImage::ContentId content_id) { + DCHECK(!sk_image->isTextureBacked()); paint_image_.sk_image_ = std::move(sk_image); paint_image_.content_id_ = content_id; return std::move(*this); } + PaintImageBuilder&& set_texture_backing(sk_sp<TextureBacking> texture_backing, + PaintImage::ContentId content_id) { + paint_image_.texture_backing_ = std::move(texture_backing); + paint_image_.content_id_ = content_id; + return std::move(*this); + } PaintImageBuilder&& set_paint_record(sk_sp<PaintRecord> paint_record, const gfx::Rect& rect, PaintImage::ContentId content_id) { @@ -62,7 +69,6 @@ class CC_PAINT_EXPORT PaintImageBuilder { paint_image_.paint_image_generator_ = std::move(generator); return std::move(*this); } - PaintImageBuilder&& set_animation_type(PaintImage::AnimationType type) { paint_image_.animation_type_ = type; return std::move(*this); @@ -105,19 +111,26 @@ class CC_PAINT_EXPORT PaintImageBuilder { paint_image_.paint_worklet_input_ = std::move(input); return std::move(*this); } - PaintImageBuilder&& set_texture_backing(sk_sp<TextureBacking> texture_backing, - PaintImage::ContentId content_id) { - paint_image_.texture_backing_ = std::move(texture_backing); - paint_image_.content_id_ = content_id; - return std::move(*this); - } PaintImage TakePaintImage(); private: + friend class PaintOpReader; + friend class PaintShader; + friend class ImagePaintFilter; + friend PaintImage CreateNonDiscardablePaintImage(const gfx::Size& size); + PaintImageBuilder(); PaintImageBuilder(PaintImage starting_image, bool clear_contents); + // For GPU process callers using a texture backed SkImage. + PaintImageBuilder&& set_texture_image(sk_sp<SkImage> sk_image, + PaintImage::ContentId content_id) { + paint_image_.sk_image_ = std::move(sk_image); + paint_image_.content_id_ = content_id; + return std::move(*this); + } + PaintImage paint_image_; #if DCHECK_IS_ON() bool id_set_ = false; diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc index 51955bcf32f..04963e4d4b4 100644 --- a/chromium/cc/paint/paint_op_buffer.cc +++ b/chromium/cc/paint/paint_op_buffer.cc @@ -315,10 +315,7 @@ size_t SimpleSerialize(const PaintOp* op, void* memory, size_t size) { } PlaybackParams::PlaybackParams(ImageProvider* image_provider) - : image_provider(image_provider), - original_ctm(SkMatrix::I()), - custom_callback(CustomDataRasterCallback()), - did_draw_op_callback(DidDrawOpCallback()) {} + : PlaybackParams(image_provider, SkMatrix::I()) {} PlaybackParams::PlaybackParams(ImageProvider* image_provider, const SkMatrix& original_ctm, @@ -1275,7 +1272,8 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op, canvas->scale(1.f / op->scale_adjustment.width(), 1.f / op->scale_adjustment.height()); } - canvas->drawImage(op->image.GetSkImage().get(), op->left, op->top, &paint); + canvas->drawImage(op->image.GetRasterSkImage().get(), op->left, op->top, + &paint); return; } @@ -1342,16 +1340,11 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op, return; } - // TODO(enne): Probably PaintCanvas should just use the skia enum directly. - SkCanvas::SrcRectConstraint skconstraint = - static_cast<SkCanvas::SrcRectConstraint>(op->constraint); - if (!params.image_provider) { SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment); - flags->DrawToSk(canvas, [op, adjusted_src, skconstraint](SkCanvas* c, - const SkPaint& p) { - c->drawImageRect(op->image.GetSkImage().get(), adjusted_src, op->dst, &p, - skconstraint); + flags->DrawToSk(canvas, [op, adjusted_src](SkCanvas* c, const SkPaint& p) { + c->drawImageRect(op->image.GetRasterSkImage().get(), adjusted_src, + op->dst, &p, op->constraint); }); return; } @@ -1381,12 +1374,12 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op, op->src.makeOffset(decoded_image.src_rect_offset().width(), decoded_image.src_rect_offset().height()); adjusted_src = AdjustSrcRectForScale(adjusted_src, scale_adjustment); - flags->DrawToSk(canvas, [op, &decoded_image, adjusted_src, skconstraint]( - SkCanvas* c, const SkPaint& p) { + flags->DrawToSk(canvas, [op, &decoded_image, adjusted_src](SkCanvas* c, + const SkPaint& p) { SkPaint paint_with_filter_quality(p); paint_with_filter_quality.setFilterQuality(decoded_image.filter_quality()); c->drawImageRect(decoded_image.image().get(), adjusted_src, op->dst, - &paint_with_filter_quality, skconstraint); + &paint_with_filter_quality, op->constraint); }); } @@ -1506,7 +1499,19 @@ void SaveLayerAlphaOp::Raster(const SaveLayerAlphaOp* op, const PlaybackParams& params) { // See PaintOp::kUnsetRect bool unset = op->bounds.left() == SK_ScalarInfinity; - canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha); + base::Optional<SkPaint> paint; + if (op->alpha != 0xFF) { + paint.emplace(); + paint->setAlpha(op->alpha); + } + SkCanvas::SaveLayerRec rec(unset ? nullptr : &op->bounds, + base::OptionalOrNullptr(paint)); + if (params.save_layer_alpha_should_preserve_lcd_text.has_value() && + *params.save_layer_alpha_should_preserve_lcd_text) { + rec.fSaveLayerFlags = SkCanvas::kPreserveLCDText_SaveLayerFlag | + SkCanvas::kInitWithPrevious_SaveLayerFlag; + } + canvas->saveLayer(rec); } void ScaleOp::Raster(const ScaleOp* op, @@ -2278,6 +2283,18 @@ bool DrawRecordOp::HasNonAAPaint() const { return record->HasNonAAPaint(); } +bool DrawRecordOp::HasDrawTextOps() const { + return record->has_draw_text_ops(); +} + +bool DrawRecordOp::HasSaveLayerAlphaOps() const { + return record->has_save_layer_alpha_ops(); +} + +bool DrawRecordOp::HasEffectsPreventingLCDTextForSaveLayerAlpha() const { + return record->has_effects_preventing_lcd_text_for_save_layer_alpha(); +} + AnnotateOp::AnnotateOp() : PaintOp(kType) {} AnnotateOp::AnnotateOp(PaintCanvas::AnnotationType annotation_type, @@ -2313,7 +2330,7 @@ DrawImageRectOp::DrawImageRectOp(const PaintImage& image, const SkRect& src, const SkRect& dst, const PaintFlags* flags, - PaintCanvas::SrcRectConstraint constraint) + SkCanvas::SrcRectConstraint constraint) : PaintOpWithFlags(kType, flags ? *flags : PaintFlags()), image(image), src(src), @@ -2389,7 +2406,12 @@ PaintOpBuffer::CompositeIterator::CompositeIterator(CompositeIterator&& other) = default; PaintOpBuffer::PaintOpBuffer() - : has_non_aa_paint_(false), has_discardable_images_(false) {} + : has_non_aa_paint_(false), + has_discardable_images_(false), + has_draw_ops_(false), + has_draw_text_ops_(false), + has_save_layer_alpha_ops_(false), + has_effects_preventing_lcd_text_for_save_layer_alpha_(false) {} PaintOpBuffer::PaintOpBuffer(PaintOpBuffer&& other) { *this = std::move(other); @@ -2409,6 +2431,11 @@ PaintOpBuffer& PaintOpBuffer::operator=(PaintOpBuffer&& other) { subrecord_op_count_ = other.subrecord_op_count_; has_non_aa_paint_ = other.has_non_aa_paint_; has_discardable_images_ = other.has_discardable_images_; + has_draw_ops_ = other.has_draw_ops_; + has_draw_text_ops_ = other.has_draw_text_ops_; + has_save_layer_alpha_ops_ = other.has_save_layer_alpha_ops_; + has_effects_preventing_lcd_text_for_save_layer_alpha_ = + other.has_effects_preventing_lcd_text_for_save_layer_alpha_; // Make sure the other pob can destruct safely. other.used_ = 0; @@ -2430,6 +2457,10 @@ void PaintOpBuffer::Reset() { subrecord_bytes_used_ = 0; subrecord_op_count_ = 0; has_discardable_images_ = false; + has_draw_ops_ = false; + has_draw_text_ops_ = false; + has_save_layer_alpha_ops_ = false; + has_effects_preventing_lcd_text_for_save_layer_alpha_ = false; } // When |op| is a nested PaintOpBuffer, this returns the PaintOp inside @@ -2556,10 +2587,22 @@ void PaintOpBuffer::Playback(SkCanvas* canvas, return; if (offsets && offsets->empty()) return; - // Prevent PaintOpBuffers from having side effects back into the canvas. SkAutoCanvasRestore save_restore(canvas, true); + bool save_layer_alpha_should_preserve_lcd_text = + (!params.save_layer_alpha_should_preserve_lcd_text.has_value() || + *params.save_layer_alpha_should_preserve_lcd_text) && + has_draw_text_ops_ && + !has_effects_preventing_lcd_text_for_save_layer_alpha_; + if (save_layer_alpha_should_preserve_lcd_text) { + // Check if the canvas supports LCD text. + SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); + canvas->getProps(&props); + if (props.pixelGeometry() == kUnknown_SkPixelGeometry) + save_layer_alpha_should_preserve_lcd_text = false; + } + // TODO(enne): a PaintRecord that contains a SetMatrix assumes that the // SetMatrix is local to that PaintRecord itself. Said differently, if you // translate(x, y), then draw a paint record with a SetMatrix(identity), @@ -2568,6 +2611,8 @@ void PaintOpBuffer::Playback(SkCanvas* canvas, PlaybackParams new_params(params.image_provider, canvas->getTotalMatrix(), params.custom_callback, params.did_draw_op_callback); + new_params.save_layer_alpha_should_preserve_lcd_text = + save_layer_alpha_should_preserve_lcd_text; for (PlaybackFoldingIterator iter(this, offsets); iter; ++iter) { const PaintOp* op = *iter; @@ -2591,10 +2636,6 @@ void PaintOpBuffer::Playback(SkCanvas* canvas, if (const auto* raster_flags = scoped_flags.flags()) flags_op->RasterWithFlags(canvas, raster_flags, new_params); } else { - // TODO(enne): skip SaveLayer followed by restore with nothing in - // between, however SaveLayer with image filters on it (or maybe - // other PaintFlags options) are not a noop. Figure out what these - // are so we can skip them correctly. DCHECK_EQ(iter.alpha(), 255); op->Raster(canvas, new_params); } @@ -2719,4 +2760,18 @@ bool PaintOpBuffer::operator==(const PaintOpBuffer& other) const { return true; } +bool PaintOpBuffer::NeedsAdditionalInvalidationForLCDText( + const PaintOpBuffer& old_buffer) const { + // We need this in addition to blink's raster invalidation because change of + // has_effects_preventing_lcd_text_for_save_layer_alpha() can affect + // all SaveLayerAlphaOps of the PaintOpBuffer, not just the area that the + // changed effects affected. + if (!has_draw_text_ops() || !has_save_layer_alpha_ops()) + return false; + if (!old_buffer.has_draw_text_ops() || !old_buffer.has_save_layer_alpha_ops()) + return false; + return has_effects_preventing_lcd_text_for_save_layer_alpha() != + old_buffer.has_effects_preventing_lcd_text_for_save_layer_alpha(); +} + } // namespace cc diff --git a/chromium/cc/paint/paint_op_buffer.h b/chromium/cc/paint/paint_op_buffer.h index ef564407da9..24459b52dd3 100644 --- a/chromium/cc/paint/paint_op_buffer.h +++ b/chromium/cc/paint/paint_op_buffer.h @@ -12,10 +12,11 @@ #include <type_traits> #include "base/callback.h" +#include "base/check_op.h" #include "base/containers/stack_container.h" #include "base/debug/alias.h" -#include "base/logging.h" #include "base/memory/aligned_memory.h" +#include "base/notreached.h" #include "base/optional.h" #include "cc/base/math_util.h" #include "cc/paint/node_id.h" @@ -124,6 +125,7 @@ struct CC_PAINT_EXPORT PlaybackParams { SkMatrix original_ctm; CustomDataRasterCallback custom_callback; DidDrawOpCallback did_draw_op_callback; + base::Optional<bool> save_layer_alpha_should_preserve_lcd_text; }; class CC_PAINT_EXPORT PaintOp { @@ -252,6 +254,11 @@ class CC_PAINT_EXPORT PaintOp { int CountSlowPathsFromFlags() const { return 0; } bool HasNonAAPaint() const { return false; } + bool HasDrawTextOps() const { return false; } + bool HasSaveLayerAlphaOps() const { return false; } + // Returns true if effects are present that would break LCD text or be broken + // by the flags for SaveLayerAlpha to preserving LCD text. + bool HasEffectsPreventingLCDTextForSaveLayerAlpha() const { return false; } bool HasDiscardableImages() const { return false; } bool HasDiscardableImagesFromFlags() const { return false; } @@ -534,7 +541,7 @@ class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags { const SkRect& src, const SkRect& dst, const PaintFlags* flags, - PaintCanvas::SrcRectConstraint constraint); + SkCanvas::SrcRectConstraint constraint); ~DrawImageRectOp(); static void RasterWithFlags(const DrawImageRectOp* op, const PaintFlags* flags, @@ -552,7 +559,7 @@ class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags { PaintImage image; SkRect src; SkRect dst; - PaintCanvas::SrcRectConstraint constraint; + SkCanvas::SrcRectConstraint constraint; private: DrawImageRectOp(); @@ -672,6 +679,9 @@ class CC_PAINT_EXPORT DrawRecordOp final : public PaintOp { bool HasDiscardableImages() const; int CountSlowPaths() const; bool HasNonAAPaint() const; + bool HasDrawTextOps() const; + bool HasSaveLayerAlphaOps() const; + bool HasEffectsPreventingLCDTextForSaveLayerAlpha() const; HAS_SERIALIZATION_FUNCTIONS(); sk_sp<const PaintRecord> record; @@ -759,6 +769,7 @@ class CC_PAINT_EXPORT DrawTextBlobOp final : public PaintOpWithFlags { SkCanvas* canvas, const PlaybackParams& params); bool IsValid() const { return flags.IsValid(); } + bool HasDrawTextOps() const { return true; } static bool AreEqual(const PaintOp* left, const PaintOp* right); HAS_SERIALIZATION_FUNCTIONS(); @@ -835,6 +846,10 @@ class CC_PAINT_EXPORT SaveLayerOp final : public PaintOpWithFlags { bool IsValid() const { return flags.IsValid() && IsValidOrUnsetRect(bounds); } static bool AreEqual(const PaintOp* left, const PaintOp* right); bool HasNonAAPaint() const { return false; } + // We simply assume any effects (or even no effects -- just starting an empty + // transparent layer) would break LCD text or be broken by the flags for + // SaveLayerAlpha to preserve LCD text. + bool HasEffectsPreventingLCDTextForSaveLayerAlpha() const { return true; } HAS_SERIALIZATION_FUNCTIONS(); SkRect bounds; @@ -853,6 +868,7 @@ class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOp { const PlaybackParams& params); bool IsValid() const { return IsValidOrUnsetRect(bounds); } static bool AreEqual(const PaintOp* left, const PaintOp* right); + bool HasSaveLayerAlphaOps() const { return true; } HAS_SERIALIZATION_FUNCTIONS(); SkRect bounds; @@ -985,6 +1001,16 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { bool HasNonAAPaint() const { return has_non_aa_paint_; } bool HasDiscardableImages() const { return has_discardable_images_; } + bool has_draw_ops() const { return has_draw_ops_; } + bool has_draw_text_ops() const { return has_draw_text_ops_; } + bool has_save_layer_alpha_ops() const { return has_save_layer_alpha_ops_; } + bool has_effects_preventing_lcd_text_for_save_layer_alpha() const { + return has_effects_preventing_lcd_text_for_save_layer_alpha_; + } + + bool NeedsAdditionalInvalidationForLCDText( + const PaintOpBuffer& old_buffer) const; + bool operator==(const PaintOpBuffer& other) const; bool operator!=(const PaintOpBuffer& other) const { return !(*this == other); @@ -1047,6 +1073,12 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { subrecord_bytes_used_ += op->AdditionalBytesUsed(); subrecord_op_count_ += op->AdditionalOpCount(); + + has_draw_ops_ |= op->IsDrawOp(); + has_draw_text_ops_ |= op->HasDrawTextOps(); + has_save_layer_alpha_ops_ |= op->HasSaveLayerAlphaOps(); + has_effects_preventing_lcd_text_for_save_layer_alpha_ |= + op->HasEffectsPreventingLCDTextForSaveLayerAlpha(); } template <typename T> @@ -1263,15 +1295,19 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { size_t reserved_ = 0; size_t op_count_ = 0; - // Record paths for veto-to-msaa for gpu raster. - int num_slow_paths_ = 0; // Record additional bytes used by referenced sub-records and display lists. size_t subrecord_bytes_used_ = 0; // Record total op count of referenced sub-record and display lists. size_t subrecord_op_count_ = 0; + // Record paths for veto-to-msaa for gpu raster. + int num_slow_paths_ = 0; bool has_non_aa_paint_ : 1; bool has_discardable_images_ : 1; + bool has_draw_ops_ : 1; + bool has_draw_text_ops_ : 1; + bool has_save_layer_alpha_ops_ : 1; + bool has_effects_preventing_lcd_text_for_save_layer_alpha_ : 1; }; } // namespace cc diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc index 48c7b99140d..3f28f0e8d29 100644 --- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc +++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc @@ -6,6 +6,7 @@ #include <stdint.h> #include "base/command_line.h" +#include "base/logging.h" #include "base/process/memory.h" #include "base/test/test_discardable_memory_allocator.h" #include "cc/paint/paint_cache.h" diff --git a/chromium/cc/paint/paint_op_buffer_serializer.cc b/chromium/cc/paint/paint_op_buffer_serializer.cc index 7601f978325..3f59290175c 100644 --- a/chromium/cc/paint/paint_op_buffer_serializer.cc +++ b/chromium/cc/paint/paint_op_buffer_serializer.cc @@ -4,13 +4,16 @@ #include "cc/paint/paint_op_buffer_serializer.h" +#include <limits> +#include <memory> +#include <utility> +#include <vector> + #include "base/bind.h" #include "base/trace_event/trace_event.h" #include "cc/paint/scoped_raster_flags.h" #include "ui/gfx/skia_util.h" -#include <utility> - namespace cc { namespace { @@ -72,12 +75,16 @@ PaintOpBufferSerializer::PaintOpBufferSerializer( context_supports_distance_field_text_( context_supports_distance_field_text), max_texture_size_(max_texture_size), - text_blob_canvas_(kMaxExtent, - kMaxExtent, - ComputeSurfaceProps(can_use_lcd_text), - strike_server, - std::move(color_space), - context_supports_distance_field_text) { + text_blob_canvas_( + strike_server + ? std::make_unique<SkTextBlobCacheDiffCanvas>( + kMaxExtent, + kMaxExtent, + ComputeSurfaceProps(can_use_lcd_text), + strike_server, + std::move(color_space), + context_supports_distance_field_text) + : std::make_unique<SkNoDrawCanvas>(kMaxExtent, kMaxExtent)) { DCHECK(serialize_cb_); } @@ -86,16 +93,16 @@ PaintOpBufferSerializer::~PaintOpBufferSerializer() = default; void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer, const std::vector<size_t>* offsets, const Preamble& preamble) { - DCHECK(text_blob_canvas_.getTotalMatrix().isIdentity()); + DCHECK(text_blob_canvas_->getTotalMatrix().isIdentity()); static const int kInitialSaveCount = 1; - DCHECK_EQ(kInitialSaveCount, text_blob_canvas_.getSaveCount()); + DCHECK_EQ(kInitialSaveCount, text_blob_canvas_->getSaveCount()); // These SerializeOptions and PlaybackParams use the initial (identity) canvas // matrix, as they are only used for serializing the preamble and the initial // save / final restore. SerializeBuffer will create its own SerializeOptions // and PlaybackParams based on the post-preamble canvas. PaintOp::SerializeOptions options = MakeSerializeOptions(); - PlaybackParams params = MakeParams(&text_blob_canvas_); + PlaybackParams params = MakeParams(text_blob_canvas_.get()); Save(options, params); SerializePreamble(preamble, options, params); @@ -104,7 +111,7 @@ void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer, } void PaintOpBufferSerializer::Serialize(const PaintOpBuffer* buffer) { - DCHECK(text_blob_canvas_.getTotalMatrix().isIdentity()); + DCHECK(text_blob_canvas_->getTotalMatrix().isIdentity()); SerializeBuffer(buffer, nullptr); } @@ -114,10 +121,10 @@ void PaintOpBufferSerializer::Serialize( const gfx::Rect& playback_rect, const gfx::SizeF& post_scale, const SkMatrix& post_matrix_for_analysis) { - DCHECK(text_blob_canvas_.getTotalMatrix().isIdentity()); + DCHECK(text_blob_canvas_->getTotalMatrix().isIdentity()); PaintOp::SerializeOptions options = MakeSerializeOptions(); - PlaybackParams params = MakeParams(&text_blob_canvas_); + PlaybackParams params = MakeParams(text_blob_canvas_.get()); // TODO(khushalsagar): remove this clip rect if it's not needed. if (!playback_rect.IsEmpty()) { @@ -131,7 +138,7 @@ void PaintOpBufferSerializer::Serialize( SerializeOp(&scale_op, options, params); } - text_blob_canvas_.concat(post_matrix_for_analysis); + text_blob_canvas_->concat(post_matrix_for_analysis); SerializeBuffer(buffer, nullptr); } @@ -208,8 +215,10 @@ void PaintOpBufferSerializer::SerializePreamble( << "full: " << preamble.full_raster_rect.ToString() << ", playback: " << preamble.playback_rect.ToString(); + // NOTE: The following code should be kept consistent with + // RasterSource::PlaybackToCanvas(). bool is_partial_raster = preamble.full_raster_rect != preamble.playback_rect; - if (!preamble.requires_clear) { + if (!preamble.requires_clear && preamble.post_translation.IsZero()) { ClearForOpaqueRaster(preamble, options, params); } else if (!is_partial_raster) { // If rastering the entire tile, clear to transparent pre-clip. This is so @@ -259,7 +268,7 @@ void PaintOpBufferSerializer::SerializeBuffer( const std::vector<size_t>* offsets) { DCHECK(buffer); PaintOp::SerializeOptions options = MakeSerializeOptions(); - PlaybackParams params = MakeParams(&text_blob_canvas_); + PlaybackParams params = MakeParams(text_blob_canvas_.get()); for (PaintOpBuffer::PlaybackFoldingIterator iter(buffer, offsets); iter; ++iter) { @@ -267,13 +276,16 @@ void PaintOpBufferSerializer::SerializeBuffer( // Skip ops outside the current clip if they have images. This saves // performing an unnecessary expensive decode. - const bool skip_op = PaintOp::OpHasDiscardableImages(op) && - PaintOp::QuickRejectDraw(op, &text_blob_canvas_); + bool skip_op = PaintOp::OpHasDiscardableImages(op) && + PaintOp::QuickRejectDraw(op, text_blob_canvas_.get()); + // Skip text ops if there is no SkStrikeServer. + skip_op |= + op->GetType() == PaintOpType::DrawTextBlob && !options.strike_server; if (skip_op) continue; if (op->GetType() == PaintOpType::DrawRecord) { - int save_count = text_blob_canvas_.getSaveCount(); + int save_count = text_blob_canvas_->getSaveCount(); Save(options, params); SerializeBuffer(static_cast<const DrawRecordOp*>(op)->record.get(), nullptr); @@ -290,7 +302,7 @@ void PaintOpBufferSerializer::SerializeBuffer( if (!result || !result.paint_record()) continue; - int save_count = text_blob_canvas_.getSaveCount(); + int save_count = text_blob_canvas_->getSaveCount(); Save(options, params); // The following ops are copying the canvas's ops from // DrawImageRectOp::RasterWithFlags. @@ -387,9 +399,9 @@ void PaintOpBufferSerializer::PlaybackOnAnalysisCanvas( if (op->IsPaintOpWithFlags() && options.flags_to_serialize) { static_cast<const PaintOpWithFlags*>(op)->RasterWithFlags( - &text_blob_canvas_, options.flags_to_serialize, params); + text_blob_canvas_.get(), options.flags_to_serialize, params); } else { - op->Raster(&text_blob_canvas_, params); + op->Raster(text_blob_canvas_.get(), params); } } @@ -404,7 +416,7 @@ void PaintOpBufferSerializer::RestoreToCount( const PaintOp::SerializeOptions& options, const PlaybackParams& params) { RestoreOp restore_op; - while (text_blob_canvas_.getSaveCount() > count) { + while (text_blob_canvas_->getSaveCount() > count) { if (!SerializeOp(&restore_op, options, params)) return; } @@ -412,10 +424,10 @@ void PaintOpBufferSerializer::RestoreToCount( PaintOp::SerializeOptions PaintOpBufferSerializer::MakeSerializeOptions() { return PaintOp::SerializeOptions( - image_provider_, transfer_cache_, paint_cache_, &text_blob_canvas_, + image_provider_, transfer_cache_, paint_cache_, text_blob_canvas_.get(), strike_server_, color_space_, can_use_lcd_text_, context_supports_distance_field_text_, max_texture_size_, - text_blob_canvas_.getTotalMatrix()); + text_blob_canvas_->getTotalMatrix()); } SimpleBufferSerializer::SimpleBufferSerializer( diff --git a/chromium/cc/paint/paint_op_buffer_serializer.h b/chromium/cc/paint/paint_op_buffer_serializer.h index 88eb914af4f..3a57a8039cb 100644 --- a/chromium/cc/paint/paint_op_buffer_serializer.h +++ b/chromium/cc/paint/paint_op_buffer_serializer.h @@ -114,7 +114,7 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer { bool context_supports_distance_field_text_; int max_texture_size_; - SkTextBlobCacheDiffCanvas text_blob_canvas_; + std::unique_ptr<SkNoDrawCanvas> text_blob_canvas_; bool valid_ = true; }; diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc index 7a2861e76a7..fe73fe73b6b 100644 --- a/chromium/cc/paint/paint_op_buffer_unittest.cc +++ b/chromium/cc/paint/paint_op_buffer_unittest.cc @@ -503,16 +503,16 @@ TEST(PaintOpBufferTest, DiscardableImagesTracking_PaintWorkletImageRect) { SkRect src = SkRect::MakeEmpty(); SkRect dst = SkRect::MakeEmpty(); buffer.push<DrawImageRectOp>(image, src, dst, nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); EXPECT_TRUE(buffer.HasDiscardableImages()); } TEST(PaintOpBufferTest, DiscardableImagesTracking_DrawImageRect) { PaintOpBuffer buffer; PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100)); - buffer.push<DrawImageRectOp>( - image, SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 100), nullptr, - PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint); + buffer.push<DrawImageRectOp>(image, SkRect::MakeWH(100, 100), + SkRect::MakeWH(100, 100), nullptr, + SkCanvas::kFast_SrcRectConstraint); EXPECT_TRUE(buffer.HasDiscardableImages()); } @@ -1081,8 +1081,8 @@ std::vector<uint32_t> test_ids = {0, 1, 56, 0xFFFFFFFF, 0xFFFFFFFE, 0x10001}; std::vector<SkMatrix> test_matrices = { SkMatrix::I(), - SkMatrix::MakeScale(3.91f, 4.31f), - SkMatrix::MakeTrans(-5.2f, 8.7f), + SkMatrix::Scale(3.91f, 4.31f), + SkMatrix::Translate(-5.2f, 8.7f), [] { SkMatrix matrix; SkScalar buffer[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -1126,7 +1126,7 @@ std::vector<PaintFlags> test_flags = { flags.setBlendMode(SkBlendMode::kDst); flags.setStrokeCap(PaintFlags::kSquare_Cap); flags.setStrokeJoin(PaintFlags::kBevel_Join); - flags.setStyle(PaintFlags::kStrokeAndFill_Style); + flags.setStyle(PaintFlags::kStroke_Style); flags.setFilterQuality(SkFilterQuality::kMedium_SkFilterQuality); flags.setShader(PaintShader::MakeColor(SkColorSetARGB(1, 2, 3, 4))); return flags; @@ -1467,9 +1467,9 @@ void PushDrawImageRectOps(PaintOpBuffer* buffer) { size_t len = std::min({test_images.size(), test_flags.size(), test_rects.size() - 1}); for (size_t i = 0; i < len; ++i) { - PaintCanvas::SrcRectConstraint constraint = - i % 2 ? PaintCanvas::kStrict_SrcRectConstraint - : PaintCanvas::kFast_SrcRectConstraint; + SkCanvas::SrcRectConstraint constraint = + i % 2 ? SkCanvas::kStrict_SrcRectConstraint + : SkCanvas::kFast_SrcRectConstraint; buffer->push<DrawImageRectOp>(test_images[i], test_rects[i], test_rects[i + 1], &test_flags[i], constraint); @@ -1477,8 +1477,7 @@ void PushDrawImageRectOps(PaintOpBuffer* buffer) { // Test optional flags. buffer->push<DrawImageRectOp>(test_images[0], test_rects[0], test_rects[1], - nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + nullptr, SkCanvas::kStrict_SrcRectConstraint); ValidateOps<DrawImageRectOp>(buffer); } @@ -2602,9 +2601,9 @@ TEST(PaintOpBufferTest, ValidateRects) { buffer.push<ClipRectOp>(bad_rect, SkClipOp::kDifference, true); buffer.push<DrawImageRectOp>(test_images[0], bad_rect, test_rects[1], nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); buffer.push<DrawImageRectOp>(test_images[0], test_rects[0], bad_rect, nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); buffer.push<DrawOvalOp>(bad_rect, test_flags[0]); buffer.push<DrawRectOp>(bad_rect, test_flags[0]); buffer.push<SaveLayerOp>(&bad_rect, nullptr); @@ -2925,7 +2924,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImageRectBasicCase) { SkRect src = SkRect::MakeXYWH(0, 0, 100, 100); SkRect dst = SkRect::MakeXYWH(0, 0, 100, 100); blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); testing::StrictMock<MockCanvas> canvas; testing::Sequence s; @@ -2967,7 +2966,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImageRectTranslated) { SkRect src = SkRect::MakeXYWH(0, 0, 100, 100); SkRect dst = SkRect::MakeXYWH(5, 7, 100, 100); blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); testing::StrictMock<MockCanvas> canvas; testing::Sequence s; @@ -2975,7 +2974,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImageRectTranslated) { EXPECT_CALL(canvas, willSave()).InSequence(s); EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); - EXPECT_CALL(canvas, didConcat(SkMatrix::MakeTrans(5.0f, 7.0f))); + EXPECT_CALL(canvas, didConcat(SkMatrix::Translate(5.0f, 7.0f))); EXPECT_CALL(canvas, willSave()).InSequence(s); EXPECT_CALL(canvas, didScale(1.0f / scale_adjustment[0].width(), 1.0f / scale_adjustment[0].height())); @@ -3012,7 +3011,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImageRectScaled) { SkRect src = SkRect::MakeXYWH(0, 0, 100, 100); SkRect dst = SkRect::MakeXYWH(0, 0, 200, 150); blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); testing::StrictMock<MockCanvas> canvas; testing::Sequence s; @@ -3020,7 +3019,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImageRectScaled) { EXPECT_CALL(canvas, willSave()).InSequence(s); EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); - EXPECT_CALL(canvas, didConcat(SkMatrix::MakeScale(2.f, 1.5f))); + EXPECT_CALL(canvas, didConcat(SkMatrix::Scale(2.f, 1.5f))); EXPECT_CALL(canvas, willSave()).InSequence(s); EXPECT_CALL(canvas, didScale(1.0f / scale_adjustment[0].width(), 1.0f / scale_adjustment[0].height())); @@ -3060,7 +3059,7 @@ TEST(PaintOpBufferTest, RasterPaintWorkletImageRectClipped) { SkRect src = SkRect::MakeXYWH(0, 0, 20, 20); SkRect dst = SkRect::MakeXYWH(0, 0, 20, 20); blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); testing::StrictMock<MockCanvas> canvas; testing::Sequence s; @@ -3098,9 +3097,8 @@ TEST(PaintOpBufferTest, ReplacesImagesFromProvider) { flags.setFilterQuality(kLow_SkFilterQuality); PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10)); buffer.push<DrawImageOp>(paint_image, 0.0f, 0.0f, &flags); - buffer.push<DrawImageRectOp>( - paint_image, rect, rect, &flags, - PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint); + buffer.push<DrawImageRectOp>(paint_image, rect, rect, &flags, + SkCanvas::kFast_SrcRectConstraint); flags.setShader(PaintShader::MakeImage(paint_image, SkTileMode::kRepeat, SkTileMode::kRepeat, nullptr)); buffer.push<DrawOvalOp>(SkRect::MakeWH(10, 10), flags); @@ -3142,9 +3140,9 @@ TEST(PaintOpBufferTest, DrawImageRectOpWithLooperNoImageProvider) { PaintFlags paint_flags; paint_flags.setLooper(sk_draw_looper_builder.detach()); - buffer.push<DrawImageRectOp>( - image, SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 100), &paint_flags, - PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint); + buffer.push<DrawImageRectOp>(image, SkRect::MakeWH(100, 100), + SkRect::MakeWH(100, 100), &paint_flags, + SkCanvas::kFast_SrcRectConstraint); testing::StrictMock<MockCanvas> canvas; EXPECT_CALL(canvas, willSave); @@ -3165,9 +3163,9 @@ TEST(PaintOpBufferTest, DrawImageRectOpWithLooperWithImageProvider) { PaintFlags paint_flags; paint_flags.setLooper(sk_draw_looper_builder.detach()); - buffer.push<DrawImageRectOp>( - image, SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 100), &paint_flags, - PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint); + buffer.push<DrawImageRectOp>(image, SkRect::MakeWH(100, 100), + SkRect::MakeWH(100, 100), &paint_flags, + SkCanvas::kFast_SrcRectConstraint); testing::StrictMock<MockCanvas> canvas; EXPECT_CALL(canvas, willSave); @@ -3192,9 +3190,8 @@ TEST(PaintOpBufferTest, ReplacesImagesFromProviderOOP) { PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10)); buffer.push<ScaleOp>(expected_scale.width(), expected_scale.height()); buffer.push<DrawImageOp>(paint_image, 0.0f, 0.0f, &flags); - buffer.push<DrawImageRectOp>( - paint_image, rect, rect, &flags, - PaintCanvas::SrcRectConstraint::kFast_SrcRectConstraint); + buffer.push<DrawImageRectOp>(paint_image, rect, rect, &flags, + SkCanvas::kFast_SrcRectConstraint); flags.setShader(PaintShader::MakeImage(paint_image, SkTileMode::kRepeat, SkTileMode::kRepeat, nullptr)); buffer.push<DrawOvalOp>(SkRect::MakeWH(10, 10), flags); @@ -3558,9 +3555,9 @@ TEST(PaintOpBufferTest, DrawImageRectSerializeScaledImages) { // translations here are arbitrary SkRect src = SkRect::MakeXYWH(3, 4, 20, 6); SkRect dst = SkRect::MakeXYWH(20, 38, 5, 30); - buffer->push<DrawImageRectOp>( - CreateDiscardablePaintImage(gfx::Size(32, 16)), src, dst, nullptr, - PaintCanvas::SrcRectConstraint::kStrict_SrcRectConstraint); + buffer->push<DrawImageRectOp>(CreateDiscardablePaintImage(gfx::Size(32, 16)), + src, dst, nullptr, + SkCanvas::kStrict_SrcRectConstraint); std::unique_ptr<char, base::AlignedFreeDeleter> memory( static_cast<char*>(base::AlignedAlloc(PaintOpBuffer::kInitialBufferSize, @@ -3829,4 +3826,108 @@ TEST(PaintOpBufferTest, NullImages) { PaintOpType::DrawImage); } +TEST(PaintOpBufferTest, HasDrawOpsAndHasDrawTextOps) { + auto buffer1 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer1->has_draw_ops()); + EXPECT_FALSE(buffer1->has_draw_text_ops()); + buffer1->push<DrawRectOp>(SkRect::MakeWH(3, 4), PaintFlags()); + PushDrawRectOps(buffer1.get()); + EXPECT_TRUE(buffer1->has_draw_ops()); + EXPECT_FALSE(buffer1->has_draw_text_ops()); + + auto buffer2 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer2->has_draw_ops()); + EXPECT_FALSE(buffer2->has_draw_text_ops()); + buffer2->push<DrawRecordOp>(std::move(buffer1)); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_FALSE(buffer2->has_draw_text_ops()); + buffer2->push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), 0, + 0, PaintFlags()); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_TRUE(buffer2->has_draw_text_ops()); + buffer2->push<DrawRectOp>(SkRect::MakeWH(4, 5), PaintFlags()); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_TRUE(buffer2->has_draw_text_ops()); + + auto buffer3 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer3->has_draw_text_ops()); + EXPECT_FALSE(buffer3->has_draw_ops()); + buffer3->push<DrawRecordOp>(std::move(buffer2)); + EXPECT_TRUE(buffer3->has_draw_ops()); + EXPECT_TRUE(buffer3->has_draw_text_ops()); +} + +TEST(PaintOpBufferTest, HasEffectsPreventingLCDTextForSaveLayerAlpha) { + auto buffer1 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer1->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer1->push<DrawRectOp>(SkRect::MakeWH(3, 4), PaintFlags()); + EXPECT_FALSE(buffer1->has_effects_preventing_lcd_text_for_save_layer_alpha()); + + auto buffer2 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer2->push<DrawRecordOp>(std::move(buffer1)); + EXPECT_FALSE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer2->push<SaveLayerOp>(nullptr, nullptr); + EXPECT_TRUE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer2->push<DrawRectOp>(SkRect::MakeWH(4, 5), PaintFlags()); + EXPECT_TRUE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + + auto buffer3 = sk_make_sp<PaintOpBuffer>(); + EXPECT_FALSE(buffer3->has_effects_preventing_lcd_text_for_save_layer_alpha()); + buffer3->push<DrawRecordOp>(std::move(buffer2)); + EXPECT_TRUE(buffer3->has_effects_preventing_lcd_text_for_save_layer_alpha()); +} + +TEST(PaintOpBufferTest, NeedsAdditionalInvalidationForLCDText) { + auto buffer1 = sk_make_sp<PaintOpBuffer>(); + buffer1->push<SaveLayerAlphaOp>(nullptr, 100); + EXPECT_FALSE(buffer1->has_draw_text_ops()); + EXPECT_TRUE(buffer1->has_save_layer_alpha_ops()); + EXPECT_FALSE(buffer1->has_effects_preventing_lcd_text_for_save_layer_alpha()); + + auto buffer2 = sk_make_sp<PaintOpBuffer>(); + buffer2->push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), 0, + 0, PaintFlags()); + buffer2->push<SaveLayerOp>(nullptr, nullptr); + EXPECT_TRUE(buffer2->has_draw_ops()); + EXPECT_FALSE(buffer2->has_save_layer_alpha_ops()); + EXPECT_TRUE(buffer2->has_effects_preventing_lcd_text_for_save_layer_alpha()); + + // Neither buffer has effects preventing lcd text for SaveLayerAlpha. + EXPECT_FALSE(buffer1->NeedsAdditionalInvalidationForLCDText(*buffer2)); + EXPECT_FALSE(buffer2->NeedsAdditionalInvalidationForLCDText(*buffer1)); + + { + auto buffer3 = sk_make_sp<PaintOpBuffer>(); + buffer3->push<DrawRecordOp>(buffer2); + EXPECT_TRUE( + buffer3->has_effects_preventing_lcd_text_for_save_layer_alpha()); + // Neither buffer has both DrawText and SaveLayerAlpha. + EXPECT_FALSE(buffer1->NeedsAdditionalInvalidationForLCDText(*buffer3)); + EXPECT_FALSE(buffer3->NeedsAdditionalInvalidationForLCDText(*buffer1)); + EXPECT_FALSE(buffer2->NeedsAdditionalInvalidationForLCDText(*buffer3)); + EXPECT_FALSE(buffer3->NeedsAdditionalInvalidationForLCDText(*buffer2)); + } + { + buffer1->push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), + 0, 0, PaintFlags()); + EXPECT_TRUE(buffer1->has_draw_text_ops()); + EXPECT_TRUE(buffer1->has_save_layer_alpha_ops()); + EXPECT_FALSE( + buffer1->has_effects_preventing_lcd_text_for_save_layer_alpha()); + auto buffer3 = sk_make_sp<PaintOpBuffer>(); + buffer3->push<DrawRecordOp>(buffer1); + buffer3->push<DrawRecordOp>(buffer2); + EXPECT_TRUE(buffer3->has_draw_text_ops()); + EXPECT_TRUE(buffer3->has_save_layer_alpha_ops()); + EXPECT_TRUE( + buffer3->has_effects_preventing_lcd_text_for_save_layer_alpha()); + // Both have DrawText and SaveLayerAlpha, and have different + // has_effects_preventing_lcd_text_for_save_layer_alpha(). + EXPECT_TRUE(buffer1->NeedsAdditionalInvalidationForLCDText(*buffer3)); + EXPECT_TRUE(buffer3->NeedsAdditionalInvalidationForLCDText(*buffer1)); + EXPECT_FALSE(buffer3->NeedsAdditionalInvalidationForLCDText(*buffer3)); + } +} + } // namespace cc diff --git a/chromium/cc/paint/paint_op_helper_unittest.cc b/chromium/cc/paint/paint_op_helper_unittest.cc index c2682d039b4..3d5db9a8710 100644 --- a/chromium/cc/paint/paint_op_helper_unittest.cc +++ b/chromium/cc/paint/paint_op_helper_unittest.cc @@ -93,7 +93,7 @@ TEST(PaintOpHelper, DrawImageToString) { TEST(PaintOpHelper, DrawImageRectToString) { DrawImageRectOp op(PaintImage(), SkRect::MakeXYWH(1, 2, 3, 4), SkRect::MakeXYWH(5, 6, 7, 8), nullptr, - PaintCanvas::kStrict_SrcRectConstraint); + SkCanvas::kStrict_SrcRectConstraint); std::string str = PaintOpHelper::ToString(&op); EXPECT_EQ( str, diff --git a/chromium/cc/paint/paint_op_reader.cc b/chromium/cc/paint/paint_op_reader.cc index 5118c0f814a..20a06327cb2 100644 --- a/chromium/cc/paint/paint_op_reader.cc +++ b/chromium/cc/paint/paint_op_reader.cc @@ -326,8 +326,8 @@ void PaintOpReader::Read(PaintImage* image) { *image = PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) - .set_image(SkImage::MakeRasterCopy(pixmap), - PaintImage::kNonLazyStableId) + .set_texture_image(SkImage::MakeRasterCopy(pixmap), + PaintImage::kNonLazyStableId) .TakePaintImage(); } return; @@ -366,10 +366,11 @@ void PaintOpReader::Read(PaintImage* image) { transfer_cache_entry_id)) { if (needs_mips) entry->EnsureMips(); - *image = PaintImageBuilder::WithDefault() - .set_id(PaintImage::GetNextId()) - .set_image(entry->image(), PaintImage::kNonLazyStableId) - .TakePaintImage(); + *image = + PaintImageBuilder::WithDefault() + .set_id(PaintImage::GetNextId()) + .set_texture_image(entry->image(), PaintImage::kNonLazyStableId) + .TakePaintImage(); } } diff --git a/chromium/cc/paint/paint_op_reader.h b/chromium/cc/paint/paint_op_reader.h index 9de213ec7f0..03d9a241c0f 100644 --- a/chromium/cc/paint/paint_op_reader.h +++ b/chromium/cc/paint/paint_op_reader.h @@ -85,10 +85,10 @@ class CC_PAINT_EXPORT PaintOpReader { Read(&value); *type = static_cast<PaintCanvas::AnnotationType>(value); } - void Read(PaintCanvas::SrcRectConstraint* constraint) { + void Read(SkCanvas::SrcRectConstraint* constraint) { uint8_t value = 0u; Read(&value); - *constraint = static_cast<PaintCanvas::SrcRectConstraint>(value); + *constraint = static_cast<SkCanvas::SrcRectConstraint>(value); } void Read(SkFilterQuality* quality) { uint8_t value = 0u; diff --git a/chromium/cc/paint/paint_op_writer.cc b/chromium/cc/paint/paint_op_writer.cc index a24b5c9ffb5..bb59e6feaff 100644 --- a/chromium/cc/paint/paint_op_writer.cc +++ b/chromium/cc/paint/paint_op_writer.cc @@ -243,7 +243,7 @@ void PaintOpWriter::Write(const DrawImage& draw_image, // Security constrained serialization inlines the image bitmap. if (enable_security_constraints_) { SkBitmap bm; - if (!draw_image.paint_image().GetSkImage()->asLegacyBitmap(&bm)) { + if (!draw_image.paint_image().GetRasterSkImage()->asLegacyBitmap(&bm)) { Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage)); return; } @@ -741,7 +741,7 @@ void PaintOpWriter::Write(const RecordPaintFilter& filter) { SkMatrix mat = options_.canvas->getTotalMatrix(); SkSize scale; if (!mat.isScaleTranslate() && mat.decomposeScale(&scale)) - mat = SkMatrix::MakeScale(scale.width(), scale.height()); + mat = SkMatrix::Scale(scale.width(), scale.height()); Write(filter.record().get(), gfx::Rect(), gfx::SizeF(1.f, 1.f), mat); } diff --git a/chromium/cc/paint/paint_op_writer.h b/chromium/cc/paint/paint_op_writer.h index 187d697796b..cddf8752d2c 100644 --- a/chromium/cc/paint/paint_op_writer.h +++ b/chromium/cc/paint/paint_op_writer.h @@ -69,7 +69,7 @@ class CC_PAINT_EXPORT PaintOpWriter { void Write(PaintCanvas::AnnotationType type) { Write(static_cast<uint8_t>(type)); } - void Write(PaintCanvas::SrcRectConstraint constraint) { + void Write(SkCanvas::SrcRectConstraint constraint) { Write(static_cast<uint8_t>(constraint)); } void Write(SkFilterQuality filter_quality) { diff --git a/chromium/cc/paint/paint_shader.cc b/chromium/cc/paint/paint_shader.cc index 26761e78266..7b55359a9ab 100644 --- a/chromium/cc/paint/paint_shader.cc +++ b/chromium/cc/paint/paint_shader.cc @@ -395,7 +395,8 @@ sk_sp<PaintShader> PaintShader::CreateDecodedImage( decoded_paint_image = PaintImageBuilder::WithDefault() .set_id(image_.stable_id()) - .set_image(std::move(sk_image), image_.GetContentIdForFrame(0u)) + .set_texture_image(std::move(sk_image), + image_.GetContentIdForFrame(0u)) .TakePaintImage(); } diff --git a/chromium/cc/paint/paint_shader_unittest.cc b/chromium/cc/paint/paint_shader_unittest.cc index f18200efb32..66e8768a083 100644 --- a/chromium/cc/paint/paint_shader_unittest.cc +++ b/chromium/cc/paint/paint_shader_unittest.cc @@ -60,13 +60,13 @@ class MockImageProvider : public ImageProvider { } // namespace TEST(PaintShaderTest, RasterizationRectForRecordShaders) { - SkMatrix local_matrix = SkMatrix::MakeScale(0.5f, 0.5f); + SkMatrix local_matrix = SkMatrix::Scale(0.5f, 0.5f); auto record_shader = PaintShader::MakePaintRecord( sk_make_sp<PaintOpBuffer>(), SkRect::MakeWH(100, 100), SkTileMode::kClamp, SkTileMode::kClamp, &local_matrix); SkRect tile_rect; - SkMatrix ctm = SkMatrix::MakeScale(0.5f, 0.5f); + SkMatrix ctm = SkMatrix::Scale(0.5f, 0.5f); EXPECT_TRUE(record_shader->GetRasterizationTileRect(ctm, &tile_rect)); EXPECT_EQ(tile_rect, SkRect::MakeWH(25, 25)); } @@ -85,7 +85,7 @@ TEST(PaintShaderTest, DecodePaintRecord) { .TakePaintImage(); record->push<DrawImageOp>(paint_image, 0.f, 0.f, nullptr); - SkMatrix local_matrix = SkMatrix::MakeScale(0.5f, 0.5f); + SkMatrix local_matrix = SkMatrix::Scale(0.5f, 0.5f); auto record_shader = PaintShader::MakePaintRecord( record, SkRect::MakeWH(100, 100), SkTileMode::kClamp, SkTileMode::kClamp, &local_matrix); @@ -111,7 +111,7 @@ TEST(PaintShaderTest, DecodePaintRecord) { EXPECT_TRUE(skia_image->isLazyGenerated()); EXPECT_EQ(xy[0], record_shader->tx()); EXPECT_EQ(xy[1], record_shader->ty()); - EXPECT_EQ(decoded_local_matrix, SkMatrix::MakeScale(2.f, 2.f)); + EXPECT_EQ(decoded_local_matrix, SkMatrix::Scale(2.f, 2.f)); // The rasterization of the shader is internal to skia, so use a raster canvas // to verify that the decoded paint does not have the encoded image. diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc index 09728c8d7de..e8758c76972 100644 --- a/chromium/cc/paint/record_paint_canvas.cc +++ b/chromium/cc/paint/record_paint_canvas.cc @@ -261,7 +261,7 @@ void RecordPaintCanvas::drawImageRect(const PaintImage& image, const SkRect& src, const SkRect& dst, const PaintFlags* flags, - SrcRectConstraint constraint) { + SkCanvas::SrcRectConstraint constraint) { list_->push<DrawImageRectOp>(image, src, dst, flags, constraint); } diff --git a/chromium/cc/paint/record_paint_canvas.h b/chromium/cc/paint/record_paint_canvas.h index cb1396b3b74..4917088a76e 100644 --- a/chromium/cc/paint/record_paint_canvas.h +++ b/chromium/cc/paint/record_paint_canvas.h @@ -8,7 +8,6 @@ #include <memory> #include "base/compiler_specific.h" -#include "base/logging.h" #include "base/optional.h" #include "build/build_config.h" #include "cc/paint/paint_canvas.h" @@ -85,7 +84,7 @@ class CC_PAINT_EXPORT RecordPaintCanvas : public PaintCanvas { const SkRect& src, const SkRect& dst, const PaintFlags* flags, - SrcRectConstraint constraint) override; + SkCanvas::SrcRectConstraint constraint) override; void drawSkottie(scoped_refptr<SkottieWrapper> skottie, const SkRect& dst, float t) override; diff --git a/chromium/cc/paint/scoped_raster_flags_unittest.cc b/chromium/cc/paint/scoped_raster_flags_unittest.cc index 2a4ac36c6e1..1bef28bc3ac 100644 --- a/chromium/cc/paint/scoped_raster_flags_unittest.cc +++ b/chromium/cc/paint/scoped_raster_flags_unittest.cc @@ -131,13 +131,13 @@ TEST(ScopedRasterFlagsTest, ThinAliasedStroke) { uint8_t expect_alpha; } tests[] = { // No downscaling => no stroke change. - {SkMatrix::MakeScale(1.0f, 1.0f), 255, true, false, 1.0f, 0xFF}, + {SkMatrix::Scale(1.0f, 1.0f), 255, true, false, 1.0f, 0xFF}, // Symmetric downscaling => modulated hairline stroke. - {SkMatrix::MakeScale(0.5f, 0.5f), 255, false, false, 0.0f, 0x80}, + {SkMatrix::Scale(0.5f, 0.5f), 255, false, false, 0.0f, 0x80}, // Symmetric downscaling w/ alpha => modulated hairline stroke. - {SkMatrix::MakeScale(0.5f, 0.5f), 127, false, false, 0.0f, 0x40}, + {SkMatrix::Scale(0.5f, 0.5f), 127, false, false, 0.0f, 0x40}, // Anisotropic scaling => AA stroke. - {SkMatrix::MakeScale(0.5f, 1.5f), 255, false, true, 1.0f, 0xFF}, + {SkMatrix::Scale(0.5f, 1.5f), 255, false, true, 1.0f, 0xFF}, }; for (const auto& test : tests) { diff --git a/chromium/cc/paint/skia_paint_canvas.cc b/chromium/cc/paint/skia_paint_canvas.cc index 91d8acc1d52..3e40ebe88cd 100644 --- a/chromium/cc/paint/skia_paint_canvas.cc +++ b/chromium/cc/paint/skia_paint_canvas.cc @@ -274,7 +274,7 @@ void SkiaPaintCanvas::drawImageRect(const PaintImage& image, const SkRect& src, const SkRect& dst, const PaintFlags* flags, - SrcRectConstraint constraint) { + SkCanvas::SrcRectConstraint constraint) { base::Optional<ScopedRasterFlags> scoped_flags; if (flags) { scoped_flags.emplace(flags, image_provider_, canvas_->getTotalMatrix(), diff --git a/chromium/cc/paint/skia_paint_canvas.h b/chromium/cc/paint/skia_paint_canvas.h index 312433f5d77..77870695946 100644 --- a/chromium/cc/paint/skia_paint_canvas.h +++ b/chromium/cc/paint/skia_paint_canvas.h @@ -8,7 +8,6 @@ #include <memory> #include "base/compiler_specific.h" -#include "base/logging.h" #include "build/build_config.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" @@ -109,7 +108,7 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas { const SkRect& src, const SkRect& dst, const PaintFlags* flags, - SrcRectConstraint constraint) override; + SkCanvas::SrcRectConstraint constraint) override; void drawSkottie(scoped_refptr<SkottieWrapper> skottie, const SkRect& dst, float t) override; |