| /* |
| * Copyright 2022 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/graphite/PaintParams.h" |
| |
| #include "include/core/SkColorSpace.h" |
| #include "include/core/SkShader.h" |
| #include "src/core/SkBlenderBase.h" |
| #include "src/core/SkColorFilterBase.h" |
| #include "src/core/SkColorSpacePriv.h" |
| #include "src/gpu/graphite/KeyContext.h" |
| #include "src/gpu/graphite/KeyHelpers.h" |
| #include "src/gpu/graphite/PaintParamsKey.h" |
| #include "src/gpu/graphite/PipelineData.h" |
| #include "src/gpu/graphite/Uniform.h" |
| #include "src/shaders/SkShaderBase.h" |
| |
| namespace skgpu::graphite { |
| |
| PaintParams::PaintParams(const SkColor4f& color, |
| sk_sp<SkBlender> finalBlender, |
| sk_sp<SkShader> shader, |
| sk_sp<SkColorFilter> colorFilter, |
| sk_sp<SkBlender> primitiveBlender, |
| bool skipColorXform) |
| : fColor(color) |
| , fFinalBlender(std::move(finalBlender)) |
| , fShader(std::move(shader)) |
| , fColorFilter(std::move(colorFilter)) |
| , fPrimitiveBlender(std::move(primitiveBlender)) |
| , fSkipColorXform(skipColorXform) {} |
| |
| PaintParams::PaintParams(const SkPaint& paint, |
| sk_sp<SkBlender> primitiveBlender, |
| bool skipColorXform) |
| : fColor(paint.getColor4f()) |
| , fFinalBlender(paint.refBlender()) |
| , fShader(paint.refShader()) |
| , fColorFilter(paint.refColorFilter()) |
| , fPrimitiveBlender(std::move(primitiveBlender)) |
| , fSkipColorXform(skipColorXform) {} |
| |
| PaintParams::PaintParams(const PaintParams& other) = default; |
| PaintParams::~PaintParams() = default; |
| PaintParams& PaintParams::operator=(const PaintParams& other) = default; |
| |
| std::optional<SkBlendMode> PaintParams::asFinalBlendMode() const { |
| return fFinalBlender ? as_BB(fFinalBlender)->asBlendMode() |
| : SkBlendMode::kSrcOver; |
| } |
| |
| sk_sp<SkBlender> PaintParams::refFinalBlender() const { return fFinalBlender; } |
| |
| sk_sp<SkShader> PaintParams::refShader() const { return fShader; } |
| |
| sk_sp<SkColorFilter> PaintParams::refColorFilter() const { return fColorFilter; } |
| |
| sk_sp<SkBlender> PaintParams::refPrimitiveBlender() const { return fPrimitiveBlender; } |
| |
| SkColor4f PaintParams::Color4fPrepForDst(SkColor4f srcColor, const SkColorInfo& dstColorInfo) { |
| // xform from sRGB to the destination colorspace |
| SkColorSpaceXformSteps steps(sk_srgb_singleton(), kUnpremul_SkAlphaType, |
| dstColorInfo.colorSpace(), kUnpremul_SkAlphaType); |
| |
| SkColor4f result = srcColor; |
| steps.apply(result.vec()); |
| return result; |
| } |
| |
| void PaintParams::toKey(const KeyContext& keyContext, |
| PaintParamsKeyBuilder* builder, |
| PipelineDataGatherer* gatherer) const { |
| |
| SkColor4f dstPaintColor = Color4fPrepForDst(fColor, keyContext.dstColorInfo()); |
| |
| // TODO: figure out how we can omit this block when the Paint's color isn't used. |
| SolidColorShaderBlock::BeginBlock(keyContext, builder, gatherer, |
| dstPaintColor.makeOpaque().premul()); |
| builder->endBlock(); |
| |
| if (fShader) { |
| as_SB(fShader)->addToKey(keyContext, builder, gatherer); |
| } |
| |
| if (fPrimitiveBlender) { |
| as_BB(fPrimitiveBlender)->addToKey(keyContext, builder, gatherer, |
| /* primitiveColorBlender= */ true); |
| } |
| |
| // Apply the paint's alpha value. |
| auto alphaColorFilter = SkColorFilters::Blend({0, 0, 0, fColor.fA}, |
| /* colorSpace= */ nullptr, |
| SkBlendMode::kDstIn); |
| if (alphaColorFilter) { |
| as_CFB(alphaColorFilter)->addToKey(keyContext, builder, gatherer); |
| } |
| |
| if (fColorFilter) { |
| as_CFB(fColorFilter)->addToKey(keyContext, builder, gatherer); |
| } |
| |
| if (fFinalBlender) { |
| as_BB(fFinalBlender)->addToKey(keyContext, builder, gatherer, |
| /* primitiveColorBlender= */ false); |
| } else { |
| BlendModeBlock::BeginBlock(keyContext, builder, gatherer, SkBlendMode::kSrcOver); |
| builder->endBlock(); |
| } |
| |
| SkASSERT(builder->sizeInBytes() > 0); |
| } |
| |
| } // namespace skgpu::graphite |