Flutter Engine
The Flutter Engine
SkPerlinNoiseShaderImpl.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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
9
23
24#include <optional>
25
27 SkScalar baseFrequencyX,
28 SkScalar baseFrequencyY,
29 int numOctaves,
30 SkScalar seed,
31 const SkISize* tileSize)
32 : fType(type)
33 , fBaseFrequencyX(baseFrequencyX)
34 , fBaseFrequencyY(baseFrequencyY)
35 , fNumOctaves(numOctaves > kMaxOctaves ? kMaxOctaves
36 : numOctaves) // [0,255] octaves allowed
37 , fSeed(seed)
38 , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize)
39 , fStitchTiles(!fTileSize.isEmpty()) {
41 SkASSERT(fBaseFrequencyX >= 0);
42 SkASSERT(fBaseFrequencyY >= 0);
43
44 // If kBlockSize changes then it must be changed in the SkSL noise_function
45 // implementation and the graphite backend
46 static_assert(SkPerlinNoiseShader::kBlockSize == 256);
47}
48
49sk_sp<SkFlattenable> SkPerlinNoiseShader::CreateProc(SkReadBuffer& buffer) {
51
52 SkScalar freqX = buffer.readScalar();
53 SkScalar freqY = buffer.readScalar();
54 int octaves = buffer.read32LE<int>(kMaxOctaves);
55
56 SkScalar seed = buffer.readScalar();
58 tileSize.fWidth = buffer.readInt();
59 tileSize.fHeight = buffer.readInt();
60
61 switch (type) {
63 return SkShaders::MakeFractalNoise(freqX, freqY, octaves, seed, &tileSize);
65 return SkShaders::MakeTurbulence(freqX, freqY, octaves, seed, &tileSize);
66 default:
67 // Really shouldn't get here b.c. of earlier check on type
68 buffer.validate(false);
69 return nullptr;
70 }
71}
72
74 buffer.writeInt((int)fType);
75 buffer.writeScalar(fBaseFrequencyX);
76 buffer.writeScalar(fBaseFrequencyY);
77 buffer.writeInt(fNumOctaves);
78 buffer.writeScalar(fSeed);
79 buffer.writeInt(fTileSize.fWidth);
80 buffer.writeInt(fTileSize.fHeight);
81}
82
84 const SkShaders::MatrixRec& mRec) const {
85 std::optional<SkShaders::MatrixRec> newMRec = mRec.apply(rec);
86 if (!newMRec.has_value()) {
87 return false;
88 }
89
90 fInitPaintingDataOnce([&] {
91 const_cast<SkPerlinNoiseShader*>(this)->fPaintingData = this->getPaintingData();
92 });
93
95 ctx->noiseType = fType;
96 ctx->baseFrequencyX = fPaintingData->fBaseFrequency.fX;
97 ctx->baseFrequencyY = fPaintingData->fBaseFrequency.fY;
98 ctx->stitchDataInX = fPaintingData->fStitchDataInit.fWidth;
99 ctx->stitchDataInY = fPaintingData->fStitchDataInit.fHeight;
100 ctx->stitching = fStitchTiles;
101 ctx->numOctaves = fNumOctaves;
102 ctx->latticeSelector = fPaintingData->fLatticeSelector;
103 ctx->noiseData = &fPaintingData->fNoise[0][0][0];
104
105 rec.fPipeline->append(SkRasterPipelineOp::perlin_noise, ctx);
106 return true;
107}
108
109///////////////////////////////////////////////////////////////////////////////////////////////////
110
111static bool valid_input(
112 SkScalar baseX, SkScalar baseY, int numOctaves, const SkISize* tileSize, SkScalar seed) {
113 if (!(baseX >= 0 && baseY >= 0)) {
114 return false;
115 }
116 if (!(numOctaves >= 0 && numOctaves <= SkPerlinNoiseShader::kMaxOctaves)) {
117 return false;
118 }
119 if (tileSize && !(tileSize->width() >= 0 && tileSize->height() >= 0)) {
120 return false;
121 }
122 if (!SkIsFinite(seed)) {
123 return false;
124 }
125 return true;
126}
127
130 // Previous name
131 SkFlattenable::Register("SkPerlinNoiseShaderImpl", SkPerlinNoiseShader::CreateProc);
132}
133
134namespace SkShaders {
136 SkScalar baseFrequencyY,
137 int numOctaves,
138 SkScalar seed,
139 const SkISize* tileSize) {
140 if (!valid_input(baseFrequencyX, baseFrequencyY, numOctaves, tileSize, seed)) {
141 return nullptr;
142 }
143
144 if (0 == numOctaves) {
145 // For kFractalNoise, w/o any octaves, the entire shader collapses to:
146 // [0,0,0,0] * 0.5 + 0.5
147 constexpr SkColor4f kTransparentGray = {0.5f, 0.5f, 0.5f, 0.5f};
148
149 return SkShaders::Color(kTransparentGray, /* colorSpace= */ nullptr);
150 }
151
153 baseFrequencyX,
154 baseFrequencyY,
155 numOctaves,
156 seed,
157 tileSize));
158}
159
161 SkScalar baseFrequencyY,
162 int numOctaves,
163 SkScalar seed,
164 const SkISize* tileSize) {
165 if (!valid_input(baseFrequencyX, baseFrequencyY, numOctaves, tileSize, seed)) {
166 return nullptr;
167 }
168
169 if (0 == numOctaves) {
170 // For kTurbulence, w/o any octaves, the entire shader collapses to: [0,0,0,0]
171 return SkShaders::Color(SkColors::kTransparent, /* colorSpace= */ nullptr);
172 }
173
175 baseFrequencyX,
176 baseFrequencyY,
177 numOctaves,
178 seed,
179 tileSize));
180}
181
182} // namespace SkShaders
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SK_REGISTER_FLATTENABLE(type)
static bool SkIsFinite(T x, Pack... values)
static bool valid_input(SkScalar baseX, SkScalar baseY, int numOctaves, const SkISize *tileSize, SkScalar seed)
void SkRegisterPerlinNoiseShaderFlattenable()
SkPerlinNoiseShaderType
GLenum type
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
Definition: SkArenaAlloc.h:120
static void Register(const char name[], Factory)
ShaderType type() const override
SkPerlinNoiseShader(SkPerlinNoiseShaderType type, SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize)
bool appendStages(const SkStageRec &rec, const SkShaders::MatrixRec &mRec) const override
std::unique_ptr< PaintingData > getPaintingData() const
void flatten(SkWriteBuffer &) const override
void append(SkRasterPipelineOp, void *=nullptr)
std::optional< MatrixRec > apply(const SkStageRec &rec, const SkMatrix &postInv={}) const
float SkScalar
Definition: extension.cpp:12
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
SK_API sk_sp< SkShader > Color(SkColor)
SK_API sk_sp< SkShader > MakeTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)
SK_API sk_sp< SkShader > MakeFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)
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
Definition: switches.h:126
Definition: SkSize.h:16
int32_t fHeight
Definition: SkSize.h:18
int32_t fWidth
Definition: SkSize.h:17
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
SkRasterPipeline * fPipeline
Definition: SkEffectPriv.h:21
SkArenaAlloc * fAlloc
Definition: SkEffectPriv.h:22