Commit a0586590 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Don't fold SaveAlphaLayer into DrawTextBlob

SkPaint::drawTextBlob applies alpha on each individual glyph, so
we should keep SaveAlphaLayer to ensure the alpha is applied atomically
on the whole text blob.

Bug: 1006140
Change-Id: I8b1d1868a3423ed4f0ef6541cc8db354773dfb24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1821944
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699621}
parent 132debad
...@@ -2373,7 +2373,11 @@ void PaintOpBuffer::PlaybackFoldingIterator::FindNextOp() { ...@@ -2373,7 +2373,11 @@ void PaintOpBuffer::PlaybackFoldingIterator::FindNextOp() {
third = NextUnfoldedOp(); third = NextUnfoldedOp();
if (third && third->GetType() == PaintOpType::Restore) { if (third && third->GetType() == PaintOpType::Restore) {
auto* save_op = static_cast<const SaveLayerAlphaOp*>(current_op_); auto* save_op = static_cast<const SaveLayerAlphaOp*>(current_op_);
if (draw_op->IsPaintOpWithFlags()) { if (draw_op->IsPaintOpWithFlags() &&
// SkPaint::drawTextBlob() applies alpha on each glyph so we don't
// fold SaveLayerAlpha into DrwaTextBlob to ensure correct alpha
// even if some glyphs overlap.
draw_op->GetType() != PaintOpType::DrawTextBlob) {
auto* flags_op = static_cast<const PaintOpWithFlags*>(draw_op); auto* flags_op = static_cast<const PaintOpWithFlags*>(draw_op);
if (flags_op->flags.SupportsFoldingAlpha()) { if (flags_op->flags.SupportsFoldingAlpha()) {
current_alpha_ = save_op->alpha; current_alpha_ = save_op->alpha;
......
...@@ -48,7 +48,6 @@ void ValidateOps(PaintOpBuffer* buffer) { ...@@ -48,7 +48,6 @@ void ValidateOps(PaintOpBuffer* buffer) {
for (auto* op : PaintOpBuffer::Iterator(buffer)) for (auto* op : PaintOpBuffer::Iterator(buffer))
EXPECT_TRUE(static_cast<T*>(op)->IsValid()); EXPECT_TRUE(static_cast<T*>(op)->IsValid());
} }
} // namespace } // namespace
class PaintOpSerializationTestUtils { class PaintOpSerializationTestUtils {
...@@ -240,6 +239,26 @@ TEST(PaintOpBufferTest, SaveDrawRestore) { ...@@ -240,6 +239,26 @@ TEST(PaintOpBufferTest, SaveDrawRestore) {
EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f); EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f);
} }
// Verify that we don't optimize SaveLayerAlpha / DrawTextBlob / Restore.
TEST(PaintOpBufferTest, SaveDrawTextBlobRestore) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags paint_flags;
EXPECT_TRUE(paint_flags.SupportsFoldingAlpha());
buffer.push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), 0, 0,
paint_flags);
buffer.push<RestoreOp>();
SaveCountingCanvas canvas;
buffer.Playback(&canvas);
EXPECT_EQ(1, canvas.save_count_);
EXPECT_EQ(1, canvas.restore_count_);
}
// The same as SaveDrawRestore, but test that the optimization doesn't apply // The same as SaveDrawRestore, but test that the optimization doesn't apply
// when the drawing op's flags are not compatible with being folded into the // when the drawing op's flags are not compatible with being folded into the
// save layer with opacity. // save layer with opacity.
......
<meta name="flags" content="ahem">
<div style="opacity: 0.5; letter-spacing: -0.6em; font: 100px/1 Ahem; white-space: pre">X X X</div>
<link rel="help" href="http://www.w3.org/TR/css3-color/#transparency">
<link rel="match" href="opacity-overlapping-letters-ref.html">
<meta name="flags" content="ahem">
<meta name="assert" content="Opacity should be apply on the whole text content atomically.">
<div style="opacity: 0.5; letter-spacing: -0.6em; font: 100px/1 Ahem">XXXXX</div>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment