OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkError.h" | 8 #include "SkNormalBevelSource.h" |
9 #include "SkErrorInternals.h" | 9 #include "SkNormalFlatSource.h" |
10 #include "SkLightingShader.h" | 10 #include "SkNormalMapSource.h" |
11 #include "SkMatrix.h" | |
12 #include "SkNormalSource.h" | 11 #include "SkNormalSource.h" |
13 #include "SkPM4f.h" | |
14 #include "SkReadBuffer.h" | |
15 #include "SkWriteBuffer.h" | |
16 | 12 |
17 // Genretating vtable | 13 // Generating vtable |
18 SkNormalSource::~SkNormalSource() {} | 14 SkNormalSource::~SkNormalSource() {} |
19 | 15 |
20 /////////////////////////////////////////////////////////////////////////////// | |
21 | |
22 class NormalMapSourceImpl : public SkNormalSource { | |
23 public: | |
24 NormalMapSourceImpl(sk_sp<SkShader> mapShader, const SkMatrix& invCTM) | |
25 : fMapShader(std::move(mapShader)) | |
26 , fInvCTM(invCTM) {} | |
27 | |
28 #if SK_SUPPORT_GPU | |
29 sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) co
nst override; | |
30 #endif | |
31 | |
32 SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec, | |
33 void* storage) const ov
erride; | |
34 | |
35 size_t providerSize(const SkShader::ContextRec& rec) const override; | |
36 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalMapSourceImpl) | |
37 | |
38 protected: | |
39 void flatten(SkWriteBuffer& buf) const override; | |
40 | |
41 bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* norm
TotalInverse) const; | |
42 | |
43 private: | |
44 class Provider : public SkNormalSource::Provider { | |
45 public: | |
46 Provider(const NormalMapSourceImpl& source, SkShader::Context* mapContex
t, | |
47 SkPaint* overridePaint); | |
48 | |
49 virtual ~Provider() override; | |
50 | |
51 void fillScanLine(int x, int y, SkPoint3 output[], int count) const over
ride; | |
52 | |
53 private: | |
54 const NormalMapSourceImpl& fSource; | |
55 SkShader::Context* fMapContext; | |
56 | |
57 SkPaint* fOverridePaint; | |
58 | |
59 typedef SkNormalSource::Provider INHERITED; | |
60 }; | |
61 | |
62 sk_sp<SkShader> fMapShader; | |
63 SkMatrix fInvCTM; // Inverse of the canvas total matrix, used for rot
ating normals. | |
64 | |
65 friend class SkNormalSource; | |
66 | |
67 typedef SkNormalSource INHERITED; | |
68 }; | |
69 | |
70 //////////////////////////////////////////////////////////////////////////// | |
71 | |
72 #if SK_SUPPORT_GPU | |
73 | |
74 #include "GrCoordTransform.h" | |
75 #include "GrInvariantOutput.h" | |
76 #include "GrTextureParams.h" | |
77 #include "glsl/GrGLSLFragmentProcessor.h" | |
78 #include "glsl/GrGLSLFragmentShaderBuilder.h" | |
79 #include "SkGr.h" | |
80 | |
81 class NormalMapFP : public GrFragmentProcessor { | |
82 public: | |
83 NormalMapFP(sk_sp<GrFragmentProcessor> mapFP, const SkMatrix& invCTM) | |
84 : fInvCTM(invCTM) { | |
85 this->registerChildProcessor(mapFP); | |
86 | |
87 this->initClassID<NormalMapFP>(); | |
88 } | |
89 | |
90 class GLSLNormalMapFP : public GrGLSLFragmentProcessor { | |
91 public: | |
92 GLSLNormalMapFP() | |
93 : fColumnMajorInvCTM22{0.0f} {} | |
94 | |
95 void emitCode(EmitArgs& args) override { | |
96 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | |
97 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | |
98 | |
99 // add uniform | |
100 const char* xformUniName = nullptr; | |
101 fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat2
2f_GrSLType, | |
102 kDefault_GrSLPrecision, "Xfor
m", &xformUniName); | |
103 | |
104 SkString dstNormalColorName("dstNormalColor"); | |
105 this->emitChild(0, nullptr, &dstNormalColorName, args); | |
106 fragBuilder->codeAppendf("vec3 normal = normalize(%s.rgb - vec3(0.5)
);", | |
107 dstNormalColorName.c_str()); | |
108 | |
109 // If there's no x & y components, return (0, 0, +/- 1) instead to a
void division by 0 | |
110 fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {"); | |
111 fragBuilder->codeAppendf(" %s = normalize(vec4(0.0, 0.0, normal.z
, 0.0));", | |
112 args.fOutputColor); | |
113 // Else, Normalizing the transformed X and Y, while keeping constant
both Z and the | |
114 // vector's angle in the XY plane. This maintains the "slope" for th
e surface while | |
115 // appropriately rotating the normal regardless of any anisotropic s
caling that occurs. | |
116 // Here, we call 'scaling factor' the number that must divide the tr
ansformed X and Y so | |
117 // that the normal's length remains equal to 1. | |
118 fragBuilder->codeAppend( "} else {"); | |
119 fragBuilder->codeAppendf(" vec2 transformed = %s * normal.xy;", | |
120 xformUniName); | |
121 fragBuilder->codeAppend( " float scalingFactorSquared = " | |
122 "( (transformed.x * transformed
.x) " | |
123 "+ (transformed.y * transform
ed.y) )" | |
124 "/(1.0 - (normal.z * normal.z))
;"); | |
125 fragBuilder->codeAppendf(" %s = vec4(transformed*inversesqrt(scal
ingFactorSquared)," | |
126 "normal.z, 0.0);", | |
127 args.fOutputColor); | |
128 fragBuilder->codeAppend( "}"); | |
129 } | |
130 | |
131 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | |
132 GrProcessorKeyBuilder* b) { | |
133 b->add32(0x0); | |
134 } | |
135 | |
136 protected: | |
137 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor&
proc) override { | |
138 const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); | |
139 | |
140 const SkMatrix& invCTM = normalMapFP.invCTM(); | |
141 fColumnMajorInvCTM22[0] = invCTM.get(SkMatrix::kMScaleX); | |
142 fColumnMajorInvCTM22[1] = invCTM.get(SkMatrix::kMSkewY); | |
143 fColumnMajorInvCTM22[2] = invCTM.get(SkMatrix::kMSkewX); | |
144 fColumnMajorInvCTM22[3] = invCTM.get(SkMatrix::kMScaleY); | |
145 pdman.setMatrix2f(fXformUni, fColumnMajorInvCTM22); | |
146 } | |
147 | |
148 private: | |
149 float fColumnMajorInvCTM22[4]; | |
150 GrGLSLProgramDataManager::UniformHandle fXformUni; | |
151 }; | |
152 | |
153 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { | |
154 GLSLNormalMapFP::GenKey(*this, caps, b); | |
155 } | |
156 | |
157 const char* name() const override { return "NormalMapFP"; } | |
158 | |
159 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | |
160 inout->setToUnknown(GrInvariantOutput::ReadInput::kWillNot_ReadInput); | |
161 } | |
162 | |
163 const SkMatrix& invCTM() const { return fInvCTM; } | |
164 | |
165 private: | |
166 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new
GLSLNormalMapFP; } | |
167 | |
168 bool onIsEqual(const GrFragmentProcessor& proc) const override { | |
169 const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); | |
170 return fInvCTM == normalMapFP.fInvCTM; | |
171 } | |
172 | |
173 SkMatrix fInvCTM; | |
174 }; | |
175 | |
176 sk_sp<GrFragmentProcessor> NormalMapSourceImpl::asFragmentProcessor( | |
177 const SkShader::AsFPArgs& args) const { | |
178 sk_sp<GrFragmentProcessor> mapFP = fMapShader->asFragmentProcessor(args); | |
179 if (!mapFP) { | |
180 return nullptr; | |
181 } | |
182 | |
183 return sk_make_sp<NormalMapFP>(std::move(mapFP), fInvCTM); | |
184 } | |
185 | |
186 #endif // SK_SUPPORT_GPU | |
187 | |
188 //////////////////////////////////////////////////////////////////////////// | |
189 | |
190 NormalMapSourceImpl::Provider::Provider(const NormalMapSourceImpl& source, | |
191 SkShader::Context* mapContext, | |
192 SkPaint* overridePaint) | |
193 : fSource(source) | |
194 , fMapContext(mapContext) | |
195 , fOverridePaint(overridePaint) {} | |
196 | |
197 NormalMapSourceImpl::Provider::~Provider() { | |
198 fMapContext->~Context(); | |
199 fOverridePaint->~SkPaint(); | |
200 } | |
201 | |
202 SkNormalSource::Provider* NormalMapSourceImpl::asProvider( | |
203 const SkShader::ContextRec &rec, void *storage) const { | |
204 SkMatrix normTotalInv; | |
205 if (!this->computeNormTotalInverse(rec, &normTotalInv)) { | |
206 return nullptr; | |
207 } | |
208 | |
209 // Overriding paint's alpha because we need the normal map's RGB channels to
be unpremul'd | |
210 void* paintStorage = (char*)storage + sizeof(Provider); | |
211 SkPaint* overridePaint = new (paintStorage) SkPaint(*(rec.fPaint)); | |
212 overridePaint->setAlpha(0xFF); | |
213 SkShader::ContextRec overrideRec(*overridePaint, *(rec.fMatrix), rec.fLocalM
atrix, | |
214 rec.fPreferredDstType); | |
215 | |
216 void* mapContextStorage = (char*) paintStorage + sizeof(SkPaint); | |
217 SkShader::Context* context = fMapShader->createContext(overrideRec, mapConte
xtStorage); | |
218 if (!context) { | |
219 return nullptr; | |
220 } | |
221 | |
222 return new (storage) Provider(*this, context, overridePaint); | |
223 } | |
224 | |
225 size_t NormalMapSourceImpl::providerSize(const SkShader::ContextRec& rec) const
{ | |
226 return sizeof(Provider) + sizeof(SkPaint) + fMapShader->contextSize(rec); | |
227 } | |
228 | |
229 bool NormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& re
c, | |
230 SkMatrix* normTotalInverse) co
nst { | |
231 SkMatrix total; | |
232 total.setConcat(*rec.fMatrix, fMapShader->getLocalMatrix()); | |
233 | |
234 const SkMatrix* m = &total; | |
235 if (rec.fLocalMatrix) { | |
236 total.setConcat(*m, *rec.fLocalMatrix); | |
237 m = &total; | |
238 } | |
239 return m->invert(normTotalInverse); | |
240 } | |
241 | |
242 #define BUFFER_MAX 16 | |
243 void NormalMapSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[]
, | |
244 int count) const { | |
245 SkPMColor tmpNormalColors[BUFFER_MAX]; | |
246 | |
247 do { | |
248 int n = SkTMin(count, BUFFER_MAX); | |
249 | |
250 fMapContext->shadeSpan(x, y, tmpNormalColors, n); | |
251 | |
252 for (int i = 0; i < n; i++) { | |
253 SkPoint3 tempNorm; | |
254 | |
255 tempNorm.set(SkIntToScalar(SkGetPackedR32(tmpNormalColors[i])) - 127
.0f, | |
256 SkIntToScalar(SkGetPackedG32(tmpNormalColors[i])) - 127
.0f, | |
257 SkIntToScalar(SkGetPackedB32(tmpNormalColors[i])) - 127
.0f); | |
258 | |
259 tempNorm.normalize(); | |
260 | |
261 | |
262 if (!SkScalarNearlyEqual(SkScalarAbs(tempNorm.fZ), 1.0f)) { | |
263 SkVector transformed = fSource.fInvCTM.mapVector(tempNorm.fX, te
mpNorm.fY); | |
264 | |
265 // Normalizing the transformed X and Y, while keeping constant b
oth Z and the | |
266 // vector's angle in the XY plane. This maintains the "slope" fo
r the surface while | |
267 // appropriately rotating the normal for any anisotropic scaling
that occurs. | |
268 // Here, we call scaling factor the number that must divide the
transformed X and Y | |
269 // so that the normal's length remains equal to 1. | |
270 SkScalar scalingFactorSquared = | |
271 (SkScalarSquare(transformed.fX) + SkScalarSquare(transfo
rmed.fY)) | |
272 / (1.0f - SkScalarSquare(tempNorm.fZ)); | |
273 SkScalar invScalingFactor = SkScalarInvert(SkScalarSqrt(scalingF
actorSquared)); | |
274 | |
275 output[i].fX = transformed.fX * invScalingFactor; | |
276 output[i].fY = transformed.fY * invScalingFactor; | |
277 output[i].fZ = tempNorm.fZ; | |
278 } else { | |
279 output[i] = {0.0f, 0.0f, tempNorm.fZ}; | |
280 output[i].normalize(); | |
281 } | |
282 | |
283 SkASSERT(SkScalarNearlyEqual(output[i].length(), 1.0f)); | |
284 } | |
285 | |
286 output += n; | |
287 x += n; | |
288 count -= n; | |
289 } while (count > 0); | |
290 } | |
291 | |
292 //////////////////////////////////////////////////////////////////////////////// | |
293 | |
294 sk_sp<SkFlattenable> NormalMapSourceImpl::CreateProc(SkReadBuffer& buf) { | |
295 | |
296 sk_sp<SkShader> mapShader = buf.readFlattenable<SkShader>(); | |
297 | |
298 SkMatrix invCTM; | |
299 buf.readMatrix(&invCTM); | |
300 | |
301 return sk_make_sp<NormalMapSourceImpl>(std::move(mapShader), invCTM); | |
302 } | |
303 | |
304 void NormalMapSourceImpl::flatten(SkWriteBuffer& buf) const { | |
305 this->INHERITED::flatten(buf); | |
306 | |
307 buf.writeFlattenable(fMapShader.get()); | |
308 buf.writeMatrix(fInvCTM); | |
309 } | |
310 | |
311 //////////////////////////////////////////////////////////////////////////// | |
312 | |
313 sk_sp<SkNormalSource> SkNormalSource::MakeFromNormalMap(sk_sp<SkShader> map, con
st SkMatrix& ctm) { | |
314 SkMatrix invCTM; | |
315 | |
316 if (!ctm.invert(&invCTM) || !map) { | |
317 return nullptr; | |
318 } | |
319 | |
320 return sk_make_sp<NormalMapSourceImpl>(std::move(map), invCTM); | |
321 } | |
322 | |
323 /////////////////////////////////////////////////////////////////////////////// | |
324 | |
325 class SK_API NormalFlatSourceImpl : public SkNormalSource { | |
326 public: | |
327 NormalFlatSourceImpl(){} | |
328 | |
329 #if SK_SUPPORT_GPU | |
330 sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) co
nst override; | |
331 #endif | |
332 | |
333 SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec, | |
334 void* storage) const override; | |
335 size_t providerSize(const SkShader::ContextRec& rec) const override; | |
336 | |
337 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalFlatSourceImpl) | |
338 | |
339 protected: | |
340 void flatten(SkWriteBuffer& buf) const override; | |
341 | |
342 private: | |
343 class Provider : public SkNormalSource::Provider { | |
344 public: | |
345 Provider(); | |
346 | |
347 virtual ~Provider(); | |
348 | |
349 void fillScanLine(int x, int y, SkPoint3 output[], int count) const over
ride; | |
350 | |
351 private: | |
352 typedef SkNormalSource::Provider INHERITED; | |
353 }; | |
354 | |
355 friend class SkNormalSource; | |
356 | |
357 typedef SkNormalSource INHERITED; | |
358 }; | |
359 | |
360 //////////////////////////////////////////////////////////////////////////// | |
361 | |
362 #if SK_SUPPORT_GPU | |
363 | |
364 class NormalFlatFP : public GrFragmentProcessor { | |
365 public: | |
366 NormalFlatFP() { | |
367 this->initClassID<NormalFlatFP>(); | |
368 } | |
369 | |
370 class GLSLNormalFlatFP : public GrGLSLFragmentProcessor { | |
371 public: | |
372 GLSLNormalFlatFP() {} | |
373 | |
374 void emitCode(EmitArgs& args) override { | |
375 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | |
376 | |
377 fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor
); | |
378 } | |
379 | |
380 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | |
381 GrProcessorKeyBuilder* b) { | |
382 b->add32(0x0); | |
383 } | |
384 | |
385 protected: | |
386 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor&
proc) override {} | |
387 }; | |
388 | |
389 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { | |
390 GLSLNormalFlatFP::GenKey(*this, caps, b); | |
391 } | |
392 | |
393 const char* name() const override { return "NormalFlatFP"; } | |
394 | |
395 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | |
396 inout->setToUnknown(GrInvariantOutput::ReadInput::kWillNot_ReadInput); | |
397 } | |
398 | |
399 private: | |
400 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new
GLSLNormalFlatFP; } | |
401 | |
402 bool onIsEqual(const GrFragmentProcessor& proc) const override { | |
403 return true; | |
404 } | |
405 }; | |
406 | |
407 sk_sp<GrFragmentProcessor> NormalFlatSourceImpl::asFragmentProcessor( | |
408 const SkShader::AsFPArgs&) const { | |
409 | |
410 return sk_make_sp<NormalFlatFP>(); | |
411 } | |
412 | |
413 #endif // SK_SUPPORT_GPU | |
414 | |
415 //////////////////////////////////////////////////////////////////////////// | |
416 | |
417 NormalFlatSourceImpl::Provider::Provider() {} | |
418 | |
419 NormalFlatSourceImpl::Provider::~Provider() {} | |
420 | |
421 SkNormalSource::Provider* NormalFlatSourceImpl::asProvider(const SkShader::Conte
xtRec &rec, | |
422 void *storage) const
{ | |
423 return new (storage) Provider(); | |
424 } | |
425 | |
426 size_t NormalFlatSourceImpl::providerSize(const SkShader::ContextRec&) const { | |
427 return sizeof(Provider); | |
428 } | |
429 | |
430 void NormalFlatSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[
], | |
431 int count) const { | |
432 for (int i = 0; i < count; i++) { | |
433 output[i] = {0.0f, 0.0f, 1.0f}; | |
434 } | |
435 } | |
436 | |
437 //////////////////////////////////////////////////////////////////////////////// | |
438 | |
439 sk_sp<SkFlattenable> NormalFlatSourceImpl::CreateProc(SkReadBuffer& buf) { | |
440 return sk_make_sp<NormalFlatSourceImpl>(); | |
441 } | |
442 | |
443 void NormalFlatSourceImpl::flatten(SkWriteBuffer& buf) const { | |
444 this->INHERITED::flatten(buf); | |
445 } | |
446 | |
447 //////////////////////////////////////////////////////////////////////////// | |
448 | |
449 sk_sp<SkNormalSource> SkNormalSource::MakeFlat() { | |
450 return sk_make_sp<NormalFlatSourceImpl>(); | |
451 } | |
452 | |
453 //////////////////////////////////////////////////////////////////////////// | |
454 | |
455 //////////////////////////////////////////////////////////////////////////// | 16 //////////////////////////////////////////////////////////////////////////// |
456 | 17 |
457 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource) | 18 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource) |
458 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(NormalMapSourceImpl) | 19 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalMapSourceImpl) |
459 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(NormalFlatSourceImpl) | 20 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalFlatSourceImpl) |
| 21 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalBevelSourceImpl) |
460 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 22 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
461 | 23 |
462 //////////////////////////////////////////////////////////////////////////// | 24 //////////////////////////////////////////////////////////////////////////// |
OLD | NEW |