Flutter Engine
The Flutter Engine
PaintOption.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2024 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
22
23namespace skgpu::graphite {
24
25void PaintOption::toKey(const KeyContext& keyContext,
26 PaintParamsKeyBuilder* keyBuilder,
27 PipelineDataGatherer* gatherer) const {
28 this->handleDstRead(keyContext, keyBuilder, gatherer);
29
30 std::optional<SkBlendMode> finalBlendMode = this->finalBlender()
31 ? this->finalBlender()->priv().asBlendMode()
33 if (fDstReadReq != DstReadRequirement::kNone) {
34 // In this case the blend will have been handled by shader-based blending with the dstRead.
35 finalBlendMode = SkBlendMode::kSrc;
36 }
37
38 if (fClipShader.first) {
39 ClipShaderBlock::BeginBlock(keyContext, keyBuilder, gatherer);
40 fClipShader.first->priv().addToKey(keyContext, keyBuilder, gatherer,
41 fClipShader.second);
42 keyBuilder->endBlock();
43 }
44
45 // Set the hardware blend mode.
46 SkASSERT(finalBlendMode);
47 BuiltInCodeSnippetID fixedFuncBlendModeID = static_cast<BuiltInCodeSnippetID>(
48 kFixedFunctionBlendModeIDOffset + static_cast<int>(*finalBlendMode));
49
50 keyBuilder->addBlock(fixedFuncBlendModeID);
51}
52
53void PaintOption::addPaintColorToKey(const KeyContext& keyContext,
55 PipelineDataGatherer* gatherer) const {
56 if (fShader.first) {
57 fShader.first->priv().addToKey(keyContext, builder, gatherer, fShader.second);
58 } else {
59 RGBPaintColorBlock::AddBlock(keyContext, builder, gatherer);
60 }
61}
62
63void PaintOption::handlePrimitiveColor(const KeyContext& keyContext,
64 PaintParamsKeyBuilder* keyBuilder,
65 PipelineDataGatherer* gatherer) const {
66 if (fHasPrimitiveBlender) {
67 Blend(keyContext, keyBuilder, gatherer,
68 /* addBlendToKey= */ [&] () -> void {
69 // TODO: Support runtime blenders for primitive blending in the precompile API.
70 // In the meantime, assume for now that we're using kSrcOver here.
71 AddToKey(keyContext, keyBuilder, gatherer,
73 },
74 /* addSrcToKey= */ [&]() -> void {
75 this->addPaintColorToKey(keyContext, keyBuilder, gatherer);
76 },
77 /* addDstToKey= */ [&]() -> void {
78 keyBuilder->addBlock(BuiltInCodeSnippetID::kPrimitiveColor);
79 });
80 } else {
81 this->addPaintColorToKey(keyContext, keyBuilder, gatherer);
82 }
83}
84
85void PaintOption::handlePaintAlpha(const KeyContext& keyContext,
86 PaintParamsKeyBuilder* keyBuilder,
87 PipelineDataGatherer* gatherer) const {
88
89 if (!fShader.first && !fHasPrimitiveBlender) {
90 // If there is no shader and no primitive blending the input to the colorFilter stage
91 // is just the premultiplied paint color.
92 SolidColorShaderBlock::AddBlock(keyContext, keyBuilder, gatherer, SK_PMColor4fWHITE);
93 return;
94 }
95
96 if (!fOpaquePaintColor) {
97 Blend(keyContext, keyBuilder, gatherer,
98 /* addBlendToKey= */ [&] () -> void {
99 AddKnownModeBlend(keyContext, keyBuilder, gatherer, SkBlendMode::kSrcIn);
100 },
101 /* addSrcToKey= */ [&]() -> void {
102 this->handlePrimitiveColor(keyContext, keyBuilder, gatherer);
103 },
104 /* addDstToKey= */ [&]() -> void {
105 AlphaOnlyPaintColorBlock::AddBlock(keyContext, keyBuilder, gatherer);
106 });
107 } else {
108 this->handlePrimitiveColor(keyContext, keyBuilder, gatherer);
109 }
110}
111
112void PaintOption::handleColorFilter(const KeyContext& keyContext,
113 PaintParamsKeyBuilder* builder,
114 PipelineDataGatherer* gatherer) const {
115 if (fColorFilter.first) {
116 Compose(keyContext, builder, gatherer,
117 /* addInnerToKey= */ [&]() -> void {
118 this->handlePaintAlpha(keyContext, builder, gatherer);
119 },
120 /* addOuterToKey= */ [&]() -> void {
121 fColorFilter.first->priv().addToKey(keyContext, builder, gatherer,
122 fColorFilter.second);
123 });
124 } else {
125 this->handlePaintAlpha(keyContext, builder, gatherer);
126 }
127}
128
129// This should be kept in sync w/ SkPaintPriv::ShouldDither and PaintParams::should_dither
130bool PaintOption::shouldDither(SkColorType dstCT) const {
131 // The paint dither flag can veto.
132 if (!fDither) {
133 return false;
134 }
135
136 if (dstCT == kUnknown_SkColorType) {
137 return false;
138 }
139
140 // We always dither 565 or 4444 when requested.
141 if (dstCT == kRGB_565_SkColorType || dstCT == kARGB_4444_SkColorType) {
142 return true;
143 }
144
145 // Otherwise, dither is only needed for non-const paints.
146 return fShader.first && !fShader.first->priv().isConstant(fShader.second);
147}
148
149void PaintOption::handleDithering(const KeyContext& keyContext,
150 PaintParamsKeyBuilder* builder,
151 PipelineDataGatherer* gatherer) const {
152
153#ifndef SK_IGNORE_GPU_DITHER
154 SkColorType ct = keyContext.dstColorInfo().colorType();
155 if (this->shouldDither(ct)) {
156 Compose(keyContext, builder, gatherer,
157 /* addInnerToKey= */ [&]() -> void {
158 this->handleColorFilter(keyContext, builder, gatherer);
159 },
160 /* addOuterToKey= */ [&]() -> void {
161 AddDitherBlock(keyContext, builder, gatherer, ct);
162 });
163 } else
164#endif
165 {
166 this->handleColorFilter(keyContext, builder, gatherer);
167 }
168}
169
170void PaintOption::handleDstRead(const KeyContext& keyContext,
171 PaintParamsKeyBuilder* builder,
172 PipelineDataGatherer* gatherer) const {
173 if (fDstReadReq != DstReadRequirement::kNone) {
174 Blend(keyContext, builder, gatherer,
175 /* addBlendToKey= */ [&] () -> void {
176 if (fFinalBlender.first) {
177 fFinalBlender.first->priv().addToKey(keyContext, builder, gatherer,
178 fFinalBlender.second);
179 } else {
180 AddKnownModeBlend(keyContext, builder, gatherer, SkBlendMode::kSrcOver);
181 }
182 },
183 /* addSrcToKey= */ [&]() -> void {
184 this->handleDithering(keyContext, builder, gatherer);
185 },
186 /* addDstToKey= */ [&]() -> void {
187 AddDstReadBlock(keyContext, builder, gatherer, fDstReadReq);
188 });
189 } else {
190 this->handleDithering(keyContext, builder, gatherer);
191 }
192}
193
194} // namespace skgpu::graphite
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kSrcOver
r = s + (1-sa)*d
@ kSrcIn
r = s * da
constexpr SkPMColor4f SK_PMColor4fWHITE
Definition: SkColorData.h:380
SkColorType
Definition: SkColorType.h:19
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition: SkColorType.h:23
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
static sk_sp< SkBlender > Mode(SkBlendMode mode)
const PrecompileBlender * finalBlender() const
Definition: PaintOption.h:45
void toKey(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *) const
Definition: PaintOption.cpp:25
void addBlock(BuiltInCodeSnippetID id)
std::optional< SkBlendMode > asBlendMode() const
const myers::Point & get(const myers::Segment &)
static constexpr int kFixedFunctionBlendModeIDOffset
void AddToKey(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, const SkBlender *blender)
void AddKnownModeBlend(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, SkBlendMode bm)
void Compose(const KeyContext &keyContext, PaintParamsKeyBuilder *keyBuilder, PipelineDataGatherer *gatherer, AddToKeyFn addInnerToKey, AddToKeyFn addOuterToKey)
void AddDitherBlock(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, SkColorType ct)
void AddDstReadBlock(const KeyContext &keyContext, PaintParamsKeyBuilder *builder, PipelineDataGatherer *gatherer, DstReadRequirement dstReadReq)
void Blend(const KeyContext &keyContext, PaintParamsKeyBuilder *keyBuilder, PipelineDataGatherer *gatherer, AddToKeyFn addBlendToKey, AddToKeyFn addSrcToKey, AddToKeyFn addDstToKey)
Definition: PaintParams.cpp:95
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *)
Definition: KeyHelpers.cpp:139
static void BeginBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *)
Definition: KeyHelpers.cpp:961
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *)
Definition: KeyHelpers.cpp:131
static void AddBlock(const KeyContext &, PaintParamsKeyBuilder *, PipelineDataGatherer *, const SkPMColor4f &)
Definition: KeyHelpers.cpp:102