0

Use float for alpha everywhere in cc/paint

Bug: 1308932
Change-Id: I8a05dedbbf9cbca5e44683bfd8b3af7e91312596
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4177774
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094061}
This commit is contained in:
Xianzhu Wang
2023-01-18 21:06:01 +00:00
committed by Chromium LUCI CQ
parent aa3616dd4d
commit 34d2164afd
16 changed files with 70 additions and 72 deletions

@@ -1028,7 +1028,7 @@ bool TurbulencePaintFilter::EqualsForTesting(
} }
ShaderPaintFilter::ShaderPaintFilter(sk_sp<PaintShader> shader, ShaderPaintFilter::ShaderPaintFilter(sk_sp<PaintShader> shader,
uint8_t alpha, float alpha,
PaintFlags::FilterQuality filter_quality, PaintFlags::FilterQuality filter_quality,
SkImageFilters::Dither dither, SkImageFilters::Dither dither,
const CropRect* crop_rect) const CropRect* crop_rect)
@@ -1039,10 +1039,10 @@ ShaderPaintFilter::ShaderPaintFilter(sk_sp<PaintShader> shader,
dither_(dither) { dither_(dither) {
sk_sp<SkShader> sk_shader = shader_->GetSkShader(filter_quality_); sk_sp<SkShader> sk_shader = shader_->GetSkShader(filter_quality_);
// Combine the alpha multiply into the SkShader if it's not opaque // Combine the alpha multiply into the SkShader if it's not opaque
if (alpha < 255) { if (alpha < 1.0f) {
// The blend effectively produces (shader * alpha), the rgb of the secondary // The blend effectively produces (shader * alpha), the rgb of the secondary
// color are ignored. // color are ignored.
SkColor4f color{1.0f, 1.0f, 1.0f, alpha / 255.0f}; SkColor4f color{1.0f, 1.0f, 1.0f, alpha};
// TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
sk_shader = SkShaders::Blend(SkBlendMode::kDstIn, std::move(sk_shader), sk_shader = SkShaders::Blend(SkBlendMode::kDstIn, std::move(sk_shader),
SkShaders::Color(color.toSkColor())); SkShaders::Color(color.toSkColor()));
@@ -1067,7 +1067,7 @@ sk_sp<PaintFilter> ShaderPaintFilter::SnapshotWithImagesInternal(
ImageProvider* image_provider) const { ImageProvider* image_provider) const {
PaintFlags orig_flags; PaintFlags orig_flags;
orig_flags.setShader(shader_); orig_flags.setShader(shader_);
orig_flags.setAlphaf(alpha_ / 255.0f); orig_flags.setAlphaf(alpha_);
orig_flags.setFilterQuality(filter_quality_); orig_flags.setFilterQuality(filter_quality_);
orig_flags.setDither(dither_ == SkImageFilters::Dither::kYes); orig_flags.setDither(dither_ == SkImageFilters::Dither::kYes);
@@ -1077,7 +1077,7 @@ sk_sp<PaintFilter> ShaderPaintFilter::SnapshotWithImagesInternal(
if (snapshot) { if (snapshot) {
// Ref the updated paint shader so that it can outlive ScopedRasterFlags // Ref the updated paint shader so that it can outlive ScopedRasterFlags
return sk_make_sp<ShaderPaintFilter>( return sk_make_sp<ShaderPaintFilter>(
sk_ref_sp(snapshot->getShader()), snapshot->getAlpha(), sk_ref_sp(snapshot->getShader()), snapshot->getAlphaf(),
snapshot->getFilterQuality(), snapshot->getFilterQuality(),
snapshot->isDither() ? Dither::kYes : Dither::kNo, GetCropRect()); snapshot->isDither() ? Dither::kYes : Dither::kNo, GetCropRect());
} else { } else {

@@ -693,15 +693,21 @@ class CC_PAINT_EXPORT ShaderPaintFilter final : public PaintFilter {
using Dither = SkImageFilters::Dither; using Dither = SkImageFilters::Dither;
ShaderPaintFilter(sk_sp<PaintShader> shader, ShaderPaintFilter(sk_sp<PaintShader> shader,
uint8_t alpha, float alpha,
PaintFlags::FilterQuality filter_quality, PaintFlags::FilterQuality filter_quality,
SkImageFilters::Dither dither, SkImageFilters::Dither dither,
const CropRect* crop_rect = nullptr); const CropRect* crop_rect = nullptr);
// This declaration prevents int alpha from being passed.
ShaderPaintFilter(sk_sp<PaintShader>,
unsigned alpha,
PaintFlags::FilterQuality,
SkImageFilters::Dither,
const CropRect* = nullptr) = delete;
~ShaderPaintFilter() override; ~ShaderPaintFilter() override;
const PaintShader& shader() const { return *shader_; } const PaintShader& shader() const { return *shader_; }
uint8_t alpha() const { return alpha_; } float alpha() const { return alpha_; }
PaintFlags::FilterQuality filter_quality() const { return filter_quality_; } PaintFlags::FilterQuality filter_quality() const { return filter_quality_; }
SkImageFilters::Dither dither() const { return dither_; } SkImageFilters::Dither dither() const { return dither_; }
@@ -714,7 +720,7 @@ class CC_PAINT_EXPORT ShaderPaintFilter final : public PaintFilter {
private: private:
sk_sp<PaintShader> shader_; sk_sp<PaintShader> shader_;
uint8_t alpha_; float alpha_;
PaintFlags::FilterQuality filter_quality_; PaintFlags::FilterQuality filter_quality_;
SkImageFilters::Dither dither_; SkImageFilters::Dither dither_;
}; };

@@ -115,7 +115,7 @@ sk_sp<PaintFilter> CreateTestFilter(PaintFilter::Type filter_type,
return sk_make_sp<ShaderPaintFilter>( return sk_make_sp<ShaderPaintFilter>(
PaintShader::MakeImage(image, SkTileMode::kClamp, SkTileMode::kClamp, PaintShader::MakeImage(image, SkTileMode::kClamp, SkTileMode::kClamp,
nullptr), nullptr),
/*alpha=*/255, PaintFlags::FilterQuality::kNone, /*alpha=*/1.0f, PaintFlags::FilterQuality::kNone,
SkImageFilters::Dither::kNo, &crop_rect); SkImageFilters::Dither::kNo, &crop_rect);
} }
case PaintFilter::Type::kMatrix: case PaintFilter::Type::kMatrix:

@@ -1418,7 +1418,7 @@ void SaveLayerAlphaOp::Raster(const SaveLayerAlphaOp* op,
absl::optional<SkPaint> paint; absl::optional<SkPaint> paint;
if (op->alpha != 1.0f) { if (op->alpha != 1.0f) {
paint.emplace(); paint.emplace();
paint->setAlpha(op->alpha * 255.0f); paint->setAlphaf(op->alpha);
} }
SkCanvas::SaveLayerRec rec(unset ? nullptr : &op->bounds, SkCanvas::SaveLayerRec rec(unset ? nullptr : &op->bounds,
base::OptionalToPtr(paint)); base::OptionalToPtr(paint));

@@ -241,11 +241,11 @@ void PaintOpBuffer::Playback(SkCanvas* canvas,
auto* context = canvas->recordingContext(); auto* context = canvas->recordingContext();
const ScopedRasterFlags scoped_flags( const ScopedRasterFlags scoped_flags(
&flags_op.flags, new_params.image_provider, canvas->getTotalMatrix(), &flags_op.flags, new_params.image_provider, canvas->getTotalMatrix(),
context ? context->maxTextureSize() : 0, iter.alphaf()); context ? context->maxTextureSize() : 0, iter.alpha());
if (const auto* raster_flags = scoped_flags.flags()) if (const auto* raster_flags = scoped_flags.flags())
flags_op.RasterWithFlags(canvas, raster_flags, new_params); flags_op.RasterWithFlags(canvas, raster_flags, new_params);
} else { } else {
DCHECK_EQ(iter.alpha(), 255); DCHECK_EQ(iter.alpha(), 1.0f);
op->Raster(canvas, new_params); op->Raster(canvas, new_params);
} }

@@ -226,12 +226,8 @@ class CC_PAINT_EXPORT PaintOpBuffer::PlaybackFoldingIterator
explicit operator bool() const { return !!current_op_; } explicit operator bool() const { return !!current_op_; }
// Guaranteed to be 255 for all ops without flags. // Guaranteed to be 1.0f for all ops without flags.
uint8_t alpha() const { float alpha() const { return current_alpha_; }
return static_cast<uint8_t>(current_alpha_ * 255.0f);
}
float alphaf() const { return current_alpha_; }
private: private:
void FindNextOp(); void FindNextOp();

@@ -186,7 +186,7 @@ void PaintOpBufferSerializer::SerializePreamble(SkCanvas* canvas,
bool PaintOpBufferSerializer::WillSerializeNextOp(const PaintOp& op, bool PaintOpBufferSerializer::WillSerializeNextOp(const PaintOp& op,
SkCanvas* canvas, SkCanvas* canvas,
const PlaybackParams& params, const PlaybackParams& params,
uint8_t alpha) { float alpha) {
// Skip ops outside the current clip if they have images. This saves // Skip ops outside the current clip if they have images. This saves
// performing an unnecessary expensive decode. // performing an unnecessary expensive decode.
bool skip_op = PaintOp::OpHasDiscardableImages(op) && bool skip_op = PaintOp::OpHasDiscardableImages(op) &&
@@ -273,12 +273,12 @@ bool PaintOpBufferSerializer::SerializeOpWithFlags(
SkCanvas* canvas, SkCanvas* canvas,
const PaintOpWithFlags& flags_op, const PaintOpWithFlags& flags_op,
const PlaybackParams& params, const PlaybackParams& params,
uint8_t alpha) { float alpha) {
// We use a null |image_provider| here because images are decoded during // We use a null |image_provider| here because images are decoded during
// serialization. // serialization.
const ScopedRasterFlags scoped_flags( const ScopedRasterFlags scoped_flags(&flags_op.flags, nullptr,
&flags_op.flags, nullptr, canvas->getTotalMatrix(), canvas->getTotalMatrix(),
options_.max_texture_size, alpha / 255.0f); options_.max_texture_size, alpha);
const PaintFlags* flags_to_serialize = scoped_flags.flags(); const PaintFlags* flags_to_serialize = scoped_flags.flags();
if (!flags_to_serialize) if (!flags_to_serialize)
return true; return true;

@@ -86,11 +86,11 @@ class CC_PAINT_EXPORT PaintOpBufferSerializer {
bool WillSerializeNextOp(const PaintOp& op, bool WillSerializeNextOp(const PaintOp& op,
SkCanvas* canvas, SkCanvas* canvas,
const PlaybackParams& params, const PlaybackParams& params,
uint8_t alpha); float alpha);
bool SerializeOpWithFlags(SkCanvas* canvas, bool SerializeOpWithFlags(SkCanvas* canvas,
const PaintOpWithFlags& flags_op, const PaintOpWithFlags& flags_op,
const PlaybackParams& params, const PlaybackParams& params,
uint8_t alpha); float alpha);
bool SerializeOp(SkCanvas* canvas, bool SerializeOp(SkCanvas* canvas,
const PaintOp& op, const PaintOp& op,
const PaintFlags* flags_to_serialize, const PaintFlags* flags_to_serialize,

@@ -54,6 +54,7 @@ using ::testing::Contains;
using ::testing::Each; using ::testing::Each;
using ::testing::ElementsAre; using ::testing::ElementsAre;
using ::testing::Eq; using ::testing::Eq;
using ::testing::FloatEq;
using ::testing::Key; using ::testing::Key;
using ::testing::Le; using ::testing::Le;
using ::testing::Matcher; using ::testing::Matcher;
@@ -136,7 +137,7 @@ class PaintOpAppendTest : public ::testing::Test {
PaintOpAppendTest() { PaintOpAppendTest() {
rect_ = SkRect::MakeXYWH(2, 3, 4, 5); rect_ = SkRect::MakeXYWH(2, 3, 4, 5);
flags_.setColor(SK_ColorMAGENTA); flags_.setColor(SK_ColorMAGENTA);
flags_.setAlphaf(100.0f / 255.0f); flags_.setAlphaf(0.25f);
} }
void PushOps(PaintOpBuffer* buffer) { void PushOps(PaintOpBuffer* buffer) {
@@ -242,10 +243,10 @@ TEST(PaintOpBufferTest, SaveDrawRestore) {
float alpha = 0.4f; float alpha = 0.4f;
buffer.push<SaveLayerAlphaOp>(alpha); buffer.push<SaveLayerAlphaOp>(alpha);
int paint_flags_alpha = 50; float paint_flags_alpha = 0.25f;
PaintFlags draw_flags; PaintFlags draw_flags;
draw_flags.setColor(SkColors::kMagenta); draw_flags.setColor(SkColors::kMagenta);
draw_flags.setAlphaf(paint_flags_alpha / 255.0f); draw_flags.setAlphaf(paint_flags_alpha);
EXPECT_TRUE(draw_flags.SupportsFoldingAlpha()); EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
buffer.push<DrawRectOp>(rect, draw_flags); buffer.push<DrawRectOp>(rect, draw_flags);
@@ -260,8 +261,8 @@ TEST(PaintOpBufferTest, SaveDrawRestore) {
// Expect the alpha from the draw and the save layer to be folded together. // Expect the alpha from the draw and the save layer to be folded together.
// Since alpha is stored in a uint8_t and gets rounded, so use tolerance. // Since alpha is stored in a uint8_t and gets rounded, so use tolerance.
float expected_alpha = alpha * paint_flags_alpha / 255.0f; float expected_alpha = alpha * paint_flags_alpha;
EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlphaf()), 0.01f); EXPECT_NEAR(expected_alpha, canvas.paint_.getAlphaf(), 0.01f);
} }
// Verify that we don't optimize SaveLayerAlpha / DrawTextBlob / Restore. // Verify that we don't optimize SaveLayerAlpha / DrawTextBlob / Restore.
@@ -295,7 +296,7 @@ TEST(PaintOpBufferTest, SaveDrawRestoreFail_BadFlags) {
PaintFlags draw_flags; PaintFlags draw_flags;
draw_flags.setColor(SkColors::kMagenta); draw_flags.setColor(SkColors::kMagenta);
draw_flags.setAlphaf(50.0f / 255.0f); draw_flags.setAlphaf(0.25f);
draw_flags.setBlendMode(SkBlendMode::kSrc); draw_flags.setBlendMode(SkBlendMode::kSrc);
EXPECT_FALSE(draw_flags.SupportsFoldingAlpha()); EXPECT_FALSE(draw_flags.SupportsFoldingAlpha());
SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
@@ -322,7 +323,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore_BadFlags255Alpha) {
PaintFlags draw_flags; PaintFlags draw_flags;
draw_flags.setColor(SkColors::kMagenta); draw_flags.setColor(SkColors::kMagenta);
draw_flags.setAlphaf(50.0f / 255.0f); draw_flags.setAlphaf(0.25f);
draw_flags.setBlendMode(SkBlendMode::kColorBurn); draw_flags.setBlendMode(SkBlendMode::kColorBurn);
EXPECT_FALSE(draw_flags.SupportsFoldingAlpha()); EXPECT_FALSE(draw_flags.SupportsFoldingAlpha());
SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
@@ -347,7 +348,7 @@ TEST(PaintOpBufferTest, SaveDrawRestoreFail_TooManyOps) {
PaintFlags draw_flags; PaintFlags draw_flags;
draw_flags.setColor(SkColors::kMagenta); draw_flags.setColor(SkColors::kMagenta);
draw_flags.setAlphaf(50.0f / 255.0f); draw_flags.setAlphaf(0.25f);
draw_flags.setBlendMode(SkBlendMode::kSrcOver); draw_flags.setBlendMode(SkBlendMode::kSrcOver);
EXPECT_TRUE(draw_flags.SupportsFoldingAlpha()); EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
@@ -387,10 +388,10 @@ TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpNotADrawOp) {
TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleOp) { TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleOp) {
PaintOpBuffer sub_buffer; PaintOpBuffer sub_buffer;
int paint_flags_alpha = 50; float paint_flags_alpha = 0.25f;
PaintFlags draw_flags; PaintFlags draw_flags;
draw_flags.setColor(SkColors::kMagenta); draw_flags.setColor(SkColors::kMagenta);
draw_flags.setAlphaf(paint_flags_alpha / 255.0f); draw_flags.setAlphaf(paint_flags_alpha);
EXPECT_TRUE(draw_flags.SupportsFoldingAlpha()); EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
sub_buffer.push<DrawRectOp>(rect, draw_flags); sub_buffer.push<DrawRectOp>(rect, draw_flags);
@@ -410,7 +411,7 @@ TEST(PaintOpBufferTest, SaveDrawRestore_SingleOpRecordWithSingleOp) {
EXPECT_EQ(0, canvas.restore_count_); EXPECT_EQ(0, canvas.restore_count_);
EXPECT_EQ(rect, canvas.draw_rect_); EXPECT_EQ(rect, canvas.draw_rect_);
float expected_alpha = alpha * paint_flags_alpha / 255.f; float expected_alpha = alpha * paint_flags_alpha;
EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlphaf()), 0.01f); EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlphaf()), 0.01f);
} }
@@ -1143,7 +1144,7 @@ std::vector<PaintFlags> test_flags = {
[] { [] {
PaintFlags flags; PaintFlags flags;
flags.setColor(SK_ColorCYAN); flags.setColor(SK_ColorCYAN);
flags.setAlphaf(103.0f / 255.0f); flags.setAlphaf(0.25f);
flags.setStrokeWidth(0.32f); flags.setStrokeWidth(0.32f);
flags.setStrokeMiter(7.98f); flags.setStrokeMiter(7.98f);
flags.setBlendMode(SkBlendMode::kSrcOut); flags.setBlendMode(SkBlendMode::kSrcOut);
@@ -2113,7 +2114,7 @@ TEST_P(PaintOpSerializationTest, UsesOverridenFlags) {
written = nullptr; written = nullptr;
PaintFlags override_flags = static_cast<const PaintOpWithFlags&>(op).flags; PaintFlags override_flags = static_cast<const PaintOpWithFlags&>(op).flags;
override_flags.setAlphaf(override_flags.getAlpha() * 0.5f / 255.0f); override_flags.setAlphaf(override_flags.getAlphaf() * 0.5f);
bytes_written = op.Serialize(output_.get(), output_size_, bytes_written = op.Serialize(output_.get(), output_size_,
options_provider.serialize_options(), options_provider.serialize_options(),
&override_flags, SkM44(), SkM44()); &override_flags, SkM44(), SkM44());
@@ -2292,8 +2293,9 @@ TEST(PaintOpBufferSerializationTest, AlphaFoldingDuringSerialization) {
buffer.push<SaveLayerAlphaOp>(alpha); buffer.push<SaveLayerAlphaOp>(alpha);
PaintFlags draw_flags; PaintFlags draw_flags;
float draw_rect_alpha = 0.25f;
draw_flags.setColor(SkColors::kMagenta); draw_flags.setColor(SkColors::kMagenta);
draw_flags.setAlphaf(50.0f / 255.0f); draw_flags.setAlphaf(draw_rect_alpha);
SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4); SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
buffer.push<DrawRectOp>(rect, draw_flags); buffer.push<DrawRectOp>(rect, draw_flags);
buffer.push<RestoreOp>(); buffer.push<RestoreOp>();
@@ -2317,21 +2319,17 @@ TEST(PaintOpBufferSerializationTest, AlphaFoldingDuringSerialization) {
EXPECT_THAT( EXPECT_THAT(
deserialized_buffer, deserialized_buffer,
Pointee(ElementsAre( Pointee(ElementsAre(PaintOpIs<SaveOp>(), PaintOpIs<ClipRectOp>(),
PaintOpIs<SaveOp>(), PaintOpIs<ClipRectOp>(), AllOf(PaintOpIs<DrawRectOp>(),
AllOf(PaintOpIs<DrawRectOp>(), // Expect the alpha from the draw and the save
// Expect the alpha from the draw and the save layer to be // layer to be folded together.
// folded together. Since alpha is stored in a uint8_t and ResultOf(
// gets rounded, so use tolerance. [](const PaintOp& op) {
ResultOf( return static_cast<const DrawRectOp&>(op)
[alpha](const PaintOp& op) { .flags.getAlphaf();
float expected_alpha = alpha * 50; },
return std::abs( FloatEq(alpha * draw_rect_alpha))),
expected_alpha - PaintOpIs<RestoreOp>())));
static_cast<const DrawRectOp&>(op).flags.getAlpha());
},
Le(1.f))),
PaintOpIs<RestoreOp>())));
} }
// Test generic PaintOp deserializing failure cases. // Test generic PaintOp deserializing failure cases.

@@ -294,7 +294,7 @@ TEST(PaintOpHelper, SaveLayerAlphaToString) {
SaveLayerAlphaOp op(SkRect::MakeXYWH(1, 2, 3, 4), 1.0f); SaveLayerAlphaOp op(SkRect::MakeXYWH(1, 2, 3, 4), 1.0f);
std::string str = PaintOpHelper::ToString(op); std::string str = PaintOpHelper::ToString(op);
EXPECT_EQ(str, EXPECT_EQ(str,
"SaveLayerAlphaOp(bounds=[1.000,2.000 3.000x4.000], alpha=255)"); "SaveLayerAlphaOp(bounds=[1.000,2.000 3.000x4.000], alpha=1.000)");
} }
TEST(PaintOpHelper, ScaleToString) { TEST(PaintOpHelper, ScaleToString) {
@@ -523,7 +523,7 @@ TEST(PaintOpHelperFilters, ShaderPaintFilter) {
/*tx=*/SkTileMode::kClamp, /*tx=*/SkTileMode::kClamp,
/*ty=*/SkTileMode::kRepeat, /*ty=*/SkTileMode::kRepeat,
/*local_matrix=*/nullptr), /*local_matrix=*/nullptr),
/*alpha=*/255, PaintFlags::FilterQuality::kMedium, /*alpha=*/1.0f, PaintFlags::FilterQuality::kMedium,
SkImageFilters::Dither::kYes, &crop_rect); SkImageFilters::Dither::kYes, &crop_rect);
EXPECT_EQ( EXPECT_EQ(
PaintOpHelper::ToString(filter), PaintOpHelper::ToString(filter),
@@ -534,7 +534,7 @@ TEST(PaintOpHelperFilters, ShaderPaintFilter) {
"0.000x0.000], start_point=[0.000,0.000], end_point=[0.000,0.000], " "0.000x0.000], start_point=[0.000,0.000], end_point=[0.000,0.000], "
"start_degrees=0, end_degrees=0, image=<paint image>, record=(nil), " "start_degrees=0, end_degrees=0, image=<paint image>, record=(nil), "
"id=4294967295, tile_scale=(nil), colors=(nil), positions=(nil)], " "id=4294967295, tile_scale=(nil), colors=(nil), positions=(nil)], "
"alpha=255, filter_quality=kMedium_SkFilterQuality, dither=kYes, " "alpha=1.000, filter_quality=kMedium_SkFilterQuality, dither=kYes, "
"crop_rect=[0.000,0.000 100.000x100.000])"); "crop_rect=[0.000,0.000 100.000x100.000])");
} }

@@ -1252,7 +1252,7 @@ void PaintOpReader::ReadShaderPaintFilter(
using Dither = SkImageFilters::Dither; using Dither = SkImageFilters::Dither;
sk_sp<PaintShader> shader; sk_sp<PaintShader> shader;
uint8_t alpha = 255; float alpha = 1.0f;
PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kNone; PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kNone;
Dither dither = Dither::kNo; Dither dither = Dither::kNo;

@@ -119,10 +119,8 @@ void ScopedRasterFlags::AdjustStrokeIfNeeded(const SkMatrix& ctm) {
// Use modulated hairline when possible, as it is faster and produces // Use modulated hairline when possible, as it is faster and produces
// results closer to the original intent. // results closer to the original intent.
MutableFlags()->setStrokeWidth(0); MutableFlags()->setStrokeWidth(0);
MutableFlags()->setAlphaf( MutableFlags()->setAlphaf(flags()->getAlphaf() *
std::round(flags()->getAlpha() * std::sqrt(stroke_vec.x() * stroke_vec.y()));
std::sqrt(stroke_vec.x() * stroke_vec.y())) /
255.0f);
return; return;
} }

@@ -567,10 +567,10 @@ TEST(RasterSourceTest, RasterPartialClear) {
recording_source->SetRequiresClear(true); recording_source->SetRequiresClear(true);
// First record everything as white. // First record everything as white.
const unsigned alpha_dark = 10u; const float alpha_dark = 0.04f;
PaintFlags white_flags; PaintFlags white_flags;
white_flags.setColor(SK_ColorWHITE); white_flags.setColor(SK_ColorWHITE);
white_flags.setAlphaf(alpha_dark / 255.0f); white_flags.setAlphaf(alpha_dark);
recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds), recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds),
white_flags); white_flags);
recording_source->Rerecord(); recording_source->Rerecord();
@@ -593,7 +593,7 @@ TEST(RasterSourceTest, RasterPartialClear) {
gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
RasterSource::PlaybackSettings()); RasterSource::PlaybackSettings());
SkColor pixel_dark = SkColorSetARGB(alpha_dark, 255, 255, 255); SkColor pixel_dark = SkColor4f{1, 1, 1, alpha_dark}.toSkColor();
for (int i = 0; i < bitmap.width(); ++i) { for (int i = 0; i < bitmap.width(); ++i) {
for (int j = 0; j < bitmap.height(); ++j) for (int j = 0; j < bitmap.height(); ++j)
EXPECT_COLOR_EQ(pixel_dark, bitmap.getColor(i, j)) << i << "," << j; EXPECT_COLOR_EQ(pixel_dark, bitmap.getColor(i, j)) << i << "," << j;
@@ -605,8 +605,8 @@ TEST(RasterSourceTest, RasterPartialClear) {
recording_source_light->SetRequiresClear(true); recording_source_light->SetRequiresClear(true);
// Record everything as a slightly lighter white. // Record everything as a slightly lighter white.
const unsigned alpha_light = 18u; const float alpha_light = 0.1f;
white_flags.setAlphaf(alpha_light / 255.0f); white_flags.setAlphaf(alpha_light);
recording_source_light->add_draw_rect_with_flags(gfx::Rect(layer_bounds), recording_source_light->add_draw_rect_with_flags(gfx::Rect(layer_bounds),
white_flags); white_flags);
recording_source_light->Rerecord(); recording_source_light->Rerecord();
@@ -625,7 +625,7 @@ TEST(RasterSourceTest, RasterPartialClear) {
RasterSource::PlaybackSettings()); RasterSource::PlaybackSettings());
// Test that the whole playback_rect was cleared and repainted with new alpha. // Test that the whole playback_rect was cleared and repainted with new alpha.
SkColor pixel_light = SkColorSetARGB(alpha_light, 255, 255, 255); SkColor pixel_light = SkColor4f{1, 1, 1, alpha_light}.toSkColor();
for (int i = 0; i < playback_rect.width(); ++i) { for (int i = 0; i < playback_rect.width(); ++i) {
for (int j = 0; j < playback_rect.height(); ++j) for (int j = 0; j < playback_rect.height(); ++j)
EXPECT_COLOR_EQ(pixel_light, bitmap.getColor(i, j)) << i << "," << j; EXPECT_COLOR_EQ(pixel_light, bitmap.getColor(i, j)) << i << "," << j;

@@ -40,7 +40,7 @@ scoped_refptr<FakeRasterSource> FakeRasterSource::CreateFilled(
PaintFlags salmon_pink_flags; PaintFlags salmon_pink_flags;
salmon_pink_flags.setColor(SK_ColorRED); salmon_pink_flags.setColor(SK_ColorRED);
salmon_pink_flags.setBlendMode(SkBlendMode::kMultiply); salmon_pink_flags.setBlendMode(SkBlendMode::kMultiply);
salmon_pink_flags.setAlphaf(128.0f / 255.0f); salmon_pink_flags.setAlphaf(0.5f);
recording_source->add_draw_rect_with_flags(gfx::Rect(size), recording_source->add_draw_rect_with_flags(gfx::Rect(size),
salmon_pink_flags); salmon_pink_flags);

@@ -197,7 +197,7 @@ class PaintOpHelper {
case PaintOpType::SaveLayerAlpha: { case PaintOpType::SaveLayerAlpha: {
const auto& op = static_cast<const SaveLayerAlphaOp&>(base_op); const auto& op = static_cast<const SaveLayerAlphaOp&>(base_op);
str << "SaveLayerAlphaOp(bounds=" << ToString(op.bounds) str << "SaveLayerAlphaOp(bounds=" << ToString(op.bounds)
<< ", alpha=" << static_cast<uint32_t>(op.alpha * 255) << ")"; << ", alpha=" << ToString(op.alpha) << ")";
break; break;
} }
case PaintOpType::Scale: { case PaintOpType::Scale: {

@@ -26,12 +26,12 @@ sk_sp<PaintFilter> PaintFilterEffect::CreateImageFilter() {
: SkImageFilters::Dither::kNo; : SkImageFilters::Dither::kNo;
if (shader) { if (shader) {
// Include the paint's alpha modulation // Include the paint's alpha modulation
return sk_make_sp<ShaderPaintFilter>(sk_ref_sp(shader), flags_.getAlpha(), return sk_make_sp<ShaderPaintFilter>(sk_ref_sp(shader), flags_.getAlphaf(),
flags_.getFilterQuality(), dither); flags_.getFilterQuality(), dither);
} else { } else {
// ShaderPaintFilter requires shader to be non-null // ShaderPaintFilter requires shader to be non-null
return sk_make_sp<ShaderPaintFilter>( return sk_make_sp<ShaderPaintFilter>(
cc::PaintShader::MakeColor(flags_.getColor4f()), 255, cc::PaintShader::MakeColor(flags_.getColor4f()), 1.0f,
flags_.getFilterQuality(), dither); flags_.getFilterQuality(), dither);
} }
} }