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:

committed by
Chromium LUCI CQ

parent
aa3616dd4d
commit
34d2164afd
cc
paint
paint_filter.ccpaint_filter.hpaint_filter_unittest.ccpaint_op.ccpaint_op_buffer.ccpaint_op_buffer_iterator.hpaint_op_buffer_serializer.ccpaint_op_buffer_serializer.hpaint_op_buffer_unittest.ccpaint_op_helper_unittest.ccpaint_op_reader.ccscoped_raster_flags.cc
raster
test
third_party/blink/renderer/platform/graphics/filters
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user