Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: src/core/SkNormalSource.cpp

Issue 2080993002: Added API for Bevel NormalSource. (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-diffuse-api-change
Patch Set: fixed unused field Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkNormalSource.h ('k') | tests/SerializationTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 ////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « src/core/SkNormalSource.h ('k') | tests/SerializationTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698