Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkShaderImageFilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
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
12#include "include/core/SkRect.h"
21#include "src/core/SkRectPriv.h"
23
24#include <optional>
25#include <utility>
26
27namespace {
28
29class SkShaderImageFilter final : public SkImageFilter_Base {
30public:
31 SkShaderImageFilter(sk_sp<SkShader> shader, SkImageFilters::Dither dither)
32 : SkImageFilter_Base(nullptr, 0)
33 , fShader(std::move(shader))
34 , fDither(dither) {
35 SkASSERT(fShader);
36 }
37
38 SkRect computeFastBounds(const SkRect& /*bounds*/) const override {
40 }
41
42protected:
43 void flatten(SkWriteBuffer&) const override;
44
45private:
46 friend void ::SkRegisterShaderImageFilterFlattenable();
47 SK_FLATTENABLE_HOOKS(SkShaderImageFilter)
48
49 bool onAffectsTransparentBlack() const override { return true; }
50
51 MatrixCapability onGetCTMCapability() const override { return MatrixCapability::kComplex; }
52
53 skif::FilterResult onFilterImage(const skif::Context&) const override;
54
56 const skif::Mapping& mapping,
57 const skif::LayerSpace<SkIRect>& desiredOutput,
58 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override;
59
60 std::optional<skif::LayerSpace<SkIRect>> onGetOutputLayerBounds(
61 const skif::Mapping& mapping,
62 std::optional<skif::LayerSpace<SkIRect>> contentBounds) const override;
63
64 sk_sp<SkShader> fShader;
66};
67
68} // end namespace
69
71 Dither dither,
72 const CropRect& cropRect) {
73 if (!shader) {
74 return SkImageFilters::Empty();
75 }
76
77 sk_sp<SkImageFilter> filter{new SkShaderImageFilter(std::move(shader), dither)};
78 if (cropRect) {
79 filter = SkImageFilters::Crop(*cropRect, std::move(filter));
80 }
81 return filter;
82}
83
85 SK_REGISTER_FLATTENABLE(SkShaderImageFilter);
86 // TODO (michaelludwig) - Remove after grace period for SKPs to stop using old name
87 SkFlattenable::Register("SkPaintImageFilter", SkShaderImageFilter::CreateProc);
88 SkFlattenable::Register("SkPaintImageFilterImpl", SkShaderImageFilter::CreateProc);
89}
90
91sk_sp<SkFlattenable> SkShaderImageFilter::CreateProc(SkReadBuffer& buffer) {
93 sk_sp<SkShader> shader;
94 bool dither;
96 // The old implementation stored an entire SkPaint, but we only need the SkShader and dither
97 // boolean. We could fail if the paint stores more effects than that, but this is simpler.
98 SkPaint paint = buffer.readPaint();
99 shader = paint.getShader() ? paint.refShader()
100 : SkShaders::Color(paint.getColor4f(), nullptr);
101 dither = paint.isDither();
102 } else {
103 shader = buffer.readShader();
104 dither = buffer.readBool();
105 }
106 return SkImageFilters::Shader(std::move(shader),
108 common.cropRect());
109}
110
111void SkShaderImageFilter::flatten(SkWriteBuffer& buffer) const {
112 this->SkImageFilter_Base::flatten(buffer);
113 buffer.writeFlattenable(fShader.get());
114 buffer.writeBool(fDither == SkImageFilters::Dither::kYes);
115}
116
117///////////////////////////////////////////////////////////////////////////////////////////////////
118
119skif::FilterResult SkShaderImageFilter::onFilterImage(const skif::Context& ctx) const {
120 const bool dither = fDither == SkImageFilters::Dither::kYes;
121 return skif::FilterResult::MakeFromShader(ctx, fShader, dither);
122}
123
124skif::LayerSpace<SkIRect> SkShaderImageFilter::onGetInputLayerBounds(
125 const skif::Mapping&,
127 std::optional<skif::LayerSpace<SkIRect>>) const {
128 // This is a leaf filter, it requires no input and no further recursion
130}
131
132std::optional<skif::LayerSpace<SkIRect>> SkShaderImageFilter::onGetOutputLayerBounds(
133 const skif::Mapping&,
134 std::optional<skif::LayerSpace<SkIRect>>) const {
135 // The output of a shader is infinite, unless we were to inspect the shader for a decal
136 // tile mode around a gradient or image.
138}
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SK_FLATTENABLE_HOOKS(type)
#define SK_REGISTER_FLATTENABLE(type)
#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount)
void SkRegisterShaderImageFilterFlattenable()
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 > Empty()
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > Shader(sk_sp< SkShader > shader, const CropRect &cropRect={})
@ kShaderImageFilterSerializeShader
static SkRect MakeLargeS32()
Definition SkRectPriv.h:33
static FilterResult MakeFromShader(const Context &ctx, sk_sp< SkShader > shader, bool dither)
const Paint & paint
static const uint8_t buffer[]
Definition ref_ptr.h:256