46 const std::optional<SkV4>& coefficients,
50 , fBlender(
std::move(blender))
51 , fArithmeticCoefficients(coefficients)
52 , fEnforcePremul(enforcePremul) {
75 (!fArithmeticCoefficients.has_value() || (*fArithmeticCoefficients)[3] != 0.f);
95 std::optional<SkV4> fArithmeticCoefficients;
103 std::optional<SkV4> coefficients = {},
104 bool enforcePremul =
false) {
116 if (
auto bm =
as_BB(blender)->asBlendMode()) {
118 return cropped(std::move(foreground));
120 return cropped(std::move(background));
129 return cropped(std::move(filter));
139 std::move(background),
140 std::move(foreground),
148 return make_blend(std::move(blender), std::move(background), std::move(foreground), cropRect);
164 return make_blend(std::move(blender),
165 std::move(background),
166 std::move(foreground),
170 SkV4{k1, k2, k3, k4},
180 SkBlendImageFilter::LegacyArithmeticCreateProc);
182 SkBlendImageFilter::LegacyArithmeticCreateProc);
194 for (
int i = 0;
i < 4; ++
i) {
197 const bool enforcePremul =
buffer.readBool();
206 std::optional<SkV4> coefficients;
207 bool enforcePremul =
false;
210 if (
mode == kArithmetic_SkBlendMode) {
214 for (
int i = 0;
i < 4; ++
i) {
218 enforcePremul =
buffer.readBool();
225 blender =
buffer.readBlender();
233 return make_blend(std::move(blender),
243 if (fArithmeticCoefficients.has_value()) {
244 buffer.write32(kArithmetic_SkBlendMode);
246 const SkV4& k = *fArithmeticCoefficients;
251 buffer.writeBool(fEnforcePremul);
252 }
else if (
auto bm =
as_BB(fBlender)->asBlendMode()) {
253 buffer.write32((
unsigned)bm.value());
256 buffer.writeFlattenable(fBlender.get());
268 if (!this->onAffectsTransparentBlack() && !bg && !fg) {
272 if (
auto bm =
as_BB(fBlender)->asBlendMode()) {
326 std::optional<skif::LayerSpace<SkIRect>> maxOutput;
327 if (contentBounds && (maxOutput = this->onGetOutputLayerBounds(mapping, *contentBounds))) {
329 requiredInput = *maxOutput;
330 if (!requiredInput.
intersect(desiredOutput)) {
337 requiredInput = desiredOutput;
342 this->getChildInputLayerBounds(
kBackground, mapping, requiredInput, contentBounds);
344 this->getChildInputLayerBounds(
kForeground, mapping, requiredInput, contentBounds);
346 bgInput.
join(fgInput);
350std::optional<skif::LayerSpace<SkIRect>> SkBlendImageFilter::onGetOutputLayerBounds(
365 bool transparentOutsideFG =
false;
366 bool transparentOutsideBG =
false;
367 if (
auto bm =
as_BB(fBlender)->asBlendMode()) {
381 }
else if (fArithmeticCoefficients.has_value()) {
382 [[maybe_unused]]
static constexpr SkV4 kClearCoeff = {0.f, 0.f, 0.f, 0.f};
383 const SkV4& k = *fArithmeticCoefficients;
393 transparentOutsideFG = k[2] == 0.f;
394 transparentOutsideBG = k[1] == 0.f;
402 auto foregroundBounds = this->getChildOutputLayerBounds(
kForeground, mapping, contentBounds);
403 auto backgroundBounds = this->getChildOutputLayerBounds(
kBackground, mapping, contentBounds);
404 if (transparentOutsideFG) {
405 if (transparentOutsideBG) {
407 if (!foregroundBounds && backgroundBounds) {
408 foregroundBounds = *backgroundBounds;
409 }
else if (backgroundBounds && !foregroundBounds->intersect(*backgroundBounds)) {
415 return foregroundBounds;
417 if (!transparentOutsideBG) {
419 if (foregroundBounds && backgroundBounds) {
420 backgroundBounds->join(*foregroundBounds);
423 backgroundBounds.reset();
426 return backgroundBounds;
433 bool transparentOutsideFG =
false;
434 bool transparentOutsideBG =
false;
435 if (
auto bm =
as_BB(fBlender)->asBlendMode()) {
445 }
else if (fArithmeticCoefficients.has_value()) {
446 [[maybe_unused]]
static constexpr SkV4 kClearCoeff = {0.f, 0.f, 0.f, 0.f};
447 const SkV4& k = *fArithmeticCoefficients;
457 transparentOutsideFG = k[2] == 0.f;
458 transparentOutsideBG = k[1] == 0.f;
470 if (transparentOutsideFG) {
471 if (transparentOutsideBG) {
473 if (!foregroundBounds.
intersect(backgroundBounds)) {
477 return foregroundBounds;
479 if (!transparentOutsideBG) {
481 backgroundBounds.
join(foregroundBounds);
483 return backgroundBounds;
void SkRegisterBlendImageFilterFlattenable()
constexpr uint8_t kCustom_SkBlendMode
SK_API bool SkBlendMode_AsCoeff(SkBlendMode mode, SkBlendModeCoeff *src, SkBlendModeCoeff *dst)
@ kSrcOver
r = s + (1-sa)*d
@ kLastMode
last valid value
SkBlenderBase * as_BB(SkBlender *blend)
constexpr SkColor SK_ColorTRANSPARENT
#define SK_FLATTENABLE_HOOKS(type)
#define SK_REGISTER_FLATTENABLE(type)
#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount)
static constexpr bool SkToBool(const T &x)
virtual std::optional< SkBlendMode > asBlendMode() const
static sk_sp< SkBlender > Mode(SkBlendMode mode)
static sk_sp< SkBlender > Arithmetic(float k1, float k2, float k3, float k4, bool enforcePremul)
static void Register(const char name[], Factory)
virtual skif::LayerSpace< SkIRect > onGetInputLayerBounds(const skif::Mapping &mapping, const skif::LayerSpace< SkIRect > &desiredOutput, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const =0
virtual bool onAffectsTransparentBlack() const
void flatten(SkWriteBuffer &) const override
virtual std::optional< skif::LayerSpace< SkIRect > > onGetOutputLayerBounds(const skif::Mapping &mapping, std::optional< skif::LayerSpace< SkIRect > > contentBounds) const =0
virtual skif::FilterResult onFilterImage(const skif::Context &context) const =0
virtual MatrixCapability onGetCTMCapability() const
virtual SkRect computeFastBounds(const SkRect &bounds) const
static sk_sp< SkImageFilter > Arithmetic(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool enforcePMColor, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Empty()
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
@ kCombineBlendArithmeticFilters
static SkRect MakeLargeS32()
const LayerSpace< SkIRect > & desiredOutput() const
const FilterResult & source() const
Context withNewDesiredOutput(const LayerSpace< SkIRect > &desiredOutput) const
const Mapping & mapping() const
LayerSpace< SkIRect > layerBounds() const
bool intersect(const LayerSpace< SkIRect > &r)
void join(const LayerSpace< SkIRect > &r)
@ kBackground
Suitable for threads that shouldn't disrupt high priority work.
Optional< SkRect > bounds
SK_API sk_sp< SkShader > Blend(SkBlendMode mode, sk_sp< SkShader > dst, sk_sp< SkShader > src)
SK_API sk_sp< SkShader > Color(SkColor)
SK_API sk_sp< SkShader > Empty()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
static constexpr SkRect MakeEmpty()
bool intersect(const SkRect &r)
void join(const SkRect &r)