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

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

Issue 2132113002: SkLS accepts nullptr for pointer args, handles alpha accurately, has new GM (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-diffuse-api-change
Patch Set: Fixed more windows warnings Created 4 years, 5 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') | src/gpu/GrFragmentProcessor.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 "SkError.h"
9 #include "SkErrorInternals.h" 9 #include "SkErrorInternals.h"
10 #include "SkLightingShader.h" 10 #include "SkLightingShader.h"
11 #include "SkMatrix.h" 11 #include "SkMatrix.h"
12 #include "SkNormalSource.h" 12 #include "SkNormalSource.h"
13 #include "SkPM4f.h"
13 #include "SkReadBuffer.h" 14 #include "SkReadBuffer.h"
14 #include "SkWriteBuffer.h" 15 #include "SkWriteBuffer.h"
15 16
16 // Genretating vtable 17 // Genretating vtable
17 SkNormalSource::~SkNormalSource() {} 18 SkNormalSource::~SkNormalSource() {}
18 19
19 /////////////////////////////////////////////////////////////////////////////// 20 ///////////////////////////////////////////////////////////////////////////////
20 21
21 class NormalMapSourceImpl : public SkNormalSource { 22 class NormalMapSourceImpl : public SkNormalSource {
22 public: 23 public:
(...skipping 16 matching lines...) Expand all
39 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalMapSourceImpl) 40 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalMapSourceImpl)
40 41
41 protected: 42 protected:
42 void flatten(SkWriteBuffer& buf) const override; 43 void flatten(SkWriteBuffer& buf) const override;
43 44
44 bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* norm TotalInverse) const; 45 bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* norm TotalInverse) const;
45 46
46 private: 47 private:
47 class Provider : public SkNormalSource::Provider { 48 class Provider : public SkNormalSource::Provider {
48 public: 49 public:
49 Provider(const NormalMapSourceImpl& source, SkShader::Context* fMapConte xt); 50 Provider(const NormalMapSourceImpl& source, SkShader::Context* mapContex t,
51 SkPaint* overridePaint);
50 52
51 virtual ~Provider() override; 53 virtual ~Provider() override;
52 54
53 void fillScanLine(int x, int y, SkPoint3 output[], int count) const over ride; 55 void fillScanLine(int x, int y, SkPoint3 output[], int count) const over ride;
56
54 private: 57 private:
55 const NormalMapSourceImpl& fSource; 58 const NormalMapSourceImpl& fSource;
56 SkShader::Context* fMapContext; 59 SkShader::Context* fMapContext;
57 60
61 SkPaint* fOverridePaint;
62
58 typedef SkNormalSource::Provider INHERITED; 63 typedef SkNormalSource::Provider INHERITED;
59 }; 64 };
60 65
61 sk_sp<SkShader> fMapShader; 66 sk_sp<SkShader> fMapShader;
62 SkMatrix fInvCTM; // Inverse of the canvas total matrix, used for rot ating normals. 67 SkMatrix fInvCTM; // Inverse of the canvas total matrix, used for rot ating normals.
63 68
64 friend class SkNormalSource; 69 friend class SkNormalSource;
65 70
66 typedef SkNormalSource INHERITED; 71 typedef SkNormalSource INHERITED;
67 }; 72 };
(...skipping 30 matching lines...) Expand all
98 // add uniform 103 // add uniform
99 const char* xformUniName = nullptr; 104 const char* xformUniName = nullptr;
100 fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat2 2f_GrSLType, 105 fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat2 2f_GrSLType,
101 kDefault_GrSLPrecision, "Xfor m", &xformUniName); 106 kDefault_GrSLPrecision, "Xfor m", &xformUniName);
102 107
103 SkString dstNormalColorName("dstNormalColor"); 108 SkString dstNormalColorName("dstNormalColor");
104 this->emitChild(0, nullptr, &dstNormalColorName, args); 109 this->emitChild(0, nullptr, &dstNormalColorName, args);
105 fragBuilder->codeAppendf("vec3 normal = normalize(%s.rgb - vec3(0.5) );", 110 fragBuilder->codeAppendf("vec3 normal = normalize(%s.rgb - vec3(0.5) );",
106 dstNormalColorName.c_str()); 111 dstNormalColorName.c_str());
107 112
108 // TODO: inverse map the light direction vectors in the vertex shade r rather than
109 // transforming all the normals here!
110
111 // If there's no x & y components, return (0, 0, +/- 1) instead to a void division by 0 113 // If there's no x & y components, return (0, 0, +/- 1) instead to a void division by 0
112 fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {"); 114 fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {");
113 fragBuilder->codeAppendf(" %s = normalize(vec4(0.0, 0.0, normal.z , 0.0));", 115 fragBuilder->codeAppendf(" %s = normalize(vec4(0.0, 0.0, normal.z , 0.0));",
114 args.fOutputColor); 116 args.fOutputColor);
115 // Else, Normalizing the transformed X and Y, while keeping constant both Z and the 117 // Else, Normalizing the transformed X and Y, while keeping constant both Z and the
116 // vector's angle in the XY plane. This maintains the "slope" for th e surface while 118 // vector's angle in the XY plane. This maintains the "slope" for th e surface while
117 // appropriately rotating the normal for any anisotropic scaling tha t occurs. 119 // appropriately rotating the normal regardless of any anisotropic s caling that occurs.
118 // Here, we call scaling factor the number that must divide the tran sformed X and Y so 120 // Here, we call 'scaling factor' the number that must divide the tr ansformed X and Y so
119 // that the normal's length remains equal to 1. 121 // that the normal's length remains equal to 1.
120 fragBuilder->codeAppend( "} else {"); 122 fragBuilder->codeAppend( "} else {");
121 fragBuilder->codeAppendf(" vec2 transformed = %s * normal.xy;", 123 fragBuilder->codeAppendf(" vec2 transformed = %s * normal.xy;",
122 xformUniName); 124 xformUniName);
123 fragBuilder->codeAppend( " float scalingFactorSquared = " 125 fragBuilder->codeAppend( " float scalingFactorSquared = "
124 "( (transformed.x * transformed .x) " 126 "( (transformed.x * transformed .x) "
125 "+ (transformed.y * transform ed.y) )" 127 "+ (transformed.y * transform ed.y) )"
126 "/(1.0 - (normal.z * normal.z)) ;"); 128 "/(1.0 - (normal.z * normal.z)) ;");
127 fragBuilder->codeAppendf(" %s = vec4(transformed*inversesqrt(scal ingFactorSquared)," 129 fragBuilder->codeAppendf(" %s = vec4(transformed*inversesqrt(scal ingFactorSquared),"
128 "normal.z, 0.0);", 130 "normal.z, 0.0);",
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 190 }
189 191
190 return sk_make_sp<NormalMapFP>(std::move(mapFP), fInvCTM); 192 return sk_make_sp<NormalMapFP>(std::move(mapFP), fInvCTM);
191 } 193 }
192 194
193 #endif // SK_SUPPORT_GPU 195 #endif // SK_SUPPORT_GPU
194 196
195 //////////////////////////////////////////////////////////////////////////// 197 ////////////////////////////////////////////////////////////////////////////
196 198
197 NormalMapSourceImpl::Provider::Provider(const NormalMapSourceImpl& source, 199 NormalMapSourceImpl::Provider::Provider(const NormalMapSourceImpl& source,
198 SkShader::Context* mapContext) 200 SkShader::Context* mapContext,
201 SkPaint* overridePaint)
199 : fSource(source) 202 : fSource(source)
200 , fMapContext(mapContext) { 203 , fMapContext(mapContext)
201 } 204 , fOverridePaint(overridePaint) {}
202 205
203 NormalMapSourceImpl::Provider::~Provider() { 206 NormalMapSourceImpl::Provider::~Provider() {
204 fMapContext->~Context(); 207 fMapContext->~Context();
208 fOverridePaint->~SkPaint();
205 } 209 }
206 210
207 SkNormalSource::Provider* NormalMapSourceImpl::asProvider( 211 SkNormalSource::Provider* NormalMapSourceImpl::asProvider(
208 const SkShader::ContextRec &rec, void *storage) const { 212 const SkShader::ContextRec &rec, void *storage) const {
209 SkMatrix normTotalInv; 213 SkMatrix normTotalInv;
210 if (!this->computeNormTotalInverse(rec, &normTotalInv)) { 214 if (!this->computeNormTotalInverse(rec, &normTotalInv)) {
211 return nullptr; 215 return nullptr;
212 } 216 }
213 217
214 void* mapContextStorage = (char*)storage + sizeof(Provider); 218 // Overriding paint's alpha because we need the normal map's RGB channels to be unpremul'd
215 SkShader::Context* context = fMapShader->createContext(rec, mapContextStorag e); 219 void* paintStorage = (char*)storage + sizeof(Provider);
220 SkPaint* overridePaint = new (paintStorage) SkPaint(*(rec.fPaint));
221 overridePaint->setAlpha(0xFF);
222 SkShader::ContextRec overrideRec(*overridePaint, *(rec.fMatrix), rec.fLocalM atrix,
223 rec.fPreferredDstType);
224
225 void* mapContextStorage = (char*) paintStorage + sizeof(SkPaint);
226 SkShader::Context* context = fMapShader->createContext(overrideRec, mapConte xtStorage);
216 if (!context) { 227 if (!context) {
217 return nullptr; 228 return nullptr;
218 } 229 }
219 230
220 return new (storage) Provider(*this, context); 231 return new (storage) Provider(*this, context, overridePaint);
221 } 232 }
222 233
223 size_t NormalMapSourceImpl::providerSize(const SkShader::ContextRec& rec) const { 234 size_t NormalMapSourceImpl::providerSize(const SkShader::ContextRec& rec) const {
224 return sizeof(Provider) + fMapShader->contextSize(rec); 235 return sizeof(Provider) + sizeof(SkPaint) + fMapShader->contextSize(rec);
225 } 236 }
226 237
227 bool NormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& re c, 238 bool NormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& re c,
228 SkMatrix* normTotalInverse) co nst { 239 SkMatrix* normTotalInverse) co nst {
229 SkMatrix total; 240 SkMatrix total;
230 total.setConcat(*rec.fMatrix, fMapShader->getLocalMatrix()); 241 total.setConcat(*rec.fMatrix, fMapShader->getLocalMatrix());
231 242
232 const SkMatrix* m = &total; 243 const SkMatrix* m = &total;
233 if (rec.fLocalMatrix) { 244 if (rec.fLocalMatrix) {
234 total.setConcat(*m, *rec.fLocalMatrix); 245 total.setConcat(*m, *rec.fLocalMatrix);
(...skipping 11 matching lines...) Expand all
246 int n = SkTMin(count, BUFFER_MAX); 257 int n = SkTMin(count, BUFFER_MAX);
247 258
248 fMapContext->shadeSpan(x, y, tmpNormalColors, n); 259 fMapContext->shadeSpan(x, y, tmpNormalColors, n);
249 260
250 for (int i = 0; i < n; i++) { 261 for (int i = 0; i < n; i++) {
251 SkPoint3 tempNorm; 262 SkPoint3 tempNorm;
252 263
253 tempNorm.set(SkIntToScalar(SkGetPackedR32(tmpNormalColors[i])) - 127 .0f, 264 tempNorm.set(SkIntToScalar(SkGetPackedR32(tmpNormalColors[i])) - 127 .0f,
254 SkIntToScalar(SkGetPackedG32(tmpNormalColors[i])) - 127 .0f, 265 SkIntToScalar(SkGetPackedG32(tmpNormalColors[i])) - 127 .0f,
255 SkIntToScalar(SkGetPackedB32(tmpNormalColors[i])) - 127 .0f); 266 SkIntToScalar(SkGetPackedB32(tmpNormalColors[i])) - 127 .0f);
267
256 tempNorm.normalize(); 268 tempNorm.normalize();
257 269
270
258 if (!SkScalarNearlyEqual(SkScalarAbs(tempNorm.fZ), 1.0f)) { 271 if (!SkScalarNearlyEqual(SkScalarAbs(tempNorm.fZ), 1.0f)) {
259 SkVector transformed = fSource.fInvCTM.mapVector(tempNorm.fX, te mpNorm.fY); 272 SkVector transformed = fSource.fInvCTM.mapVector(tempNorm.fX, te mpNorm.fY);
260 273
261 // Normalizing the transformed X and Y, while keeping constant b oth Z and the 274 // Normalizing the transformed X and Y, while keeping constant b oth Z and the
262 // vector's angle in the XY plane. This maintains the "slope" fo r the surface while 275 // vector's angle in the XY plane. This maintains the "slope" fo r the surface while
263 // appropriately rotating the normal for any anisotropic scaling that occurs. 276 // appropriately rotating the normal for any anisotropic scaling that occurs.
264 // Here, we call scaling factor the number that must divide the transformed X and Y 277 // Here, we call scaling factor the number that must divide the transformed X and Y
265 // so that the normal's length remains equal to 1. 278 // so that the normal's length remains equal to 1.
266 SkScalar scalingFactorSquared = 279 SkScalar scalingFactorSquared =
267 (SkScalarSquare(transformed.fX) + SkScalarSquare(transfo rmed.fY)) 280 (SkScalarSquare(transformed.fX) + SkScalarSquare(transfo rmed.fY))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 sk_sp<SkNormalSource> SkNormalSource::MakeFromNormalMap(sk_sp<SkShader> map, con st SkMatrix& ctm) { 322 sk_sp<SkNormalSource> SkNormalSource::MakeFromNormalMap(sk_sp<SkShader> map, con st SkMatrix& ctm) {
310 SkMatrix invCTM; 323 SkMatrix invCTM;
311 324
312 if (!ctm.invert(&invCTM) || !map) { 325 if (!ctm.invert(&invCTM) || !map) {
313 return nullptr; 326 return nullptr;
314 } 327 }
315 328
316 return sk_make_sp<NormalMapSourceImpl>(std::move(map), invCTM); 329 return sk_make_sp<NormalMapSourceImpl>(std::move(map), invCTM);
317 } 330 }
318 331
332 ///////////////////////////////////////////////////////////////////////////////
333
334 class SK_API NormalFlatSourceImpl : public SkNormalSource {
335 public:
336 NormalFlatSourceImpl(){}
337
338 #if SK_SUPPORT_GPU
339 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
340 const SkMatrix& viewM,
341 const SkMatrix* localMatrix,
342 SkFilterQuality,
343 SkSourceGammaTreatment) const override;
344 #endif
345
346 SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
347 void* storage) const override;
348 size_t providerSize(const SkShader::ContextRec& rec) const override;
349
350 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalFlatSourceImpl)
351
352 protected:
353 void flatten(SkWriteBuffer& buf) const override;
354
355 private:
356 class Provider : public SkNormalSource::Provider {
357 public:
358 Provider();
359
360 virtual ~Provider();
361
362 void fillScanLine(int x, int y, SkPoint3 output[], int count) const over ride;
363
364 private:
365 typedef SkNormalSource::Provider INHERITED;
366 };
367
368 friend class SkNormalSource;
369
370 typedef SkNormalSource INHERITED;
371 };
372
373 ////////////////////////////////////////////////////////////////////////////
374
375 #if SK_SUPPORT_GPU
376
377 class NormalFlatFP : public GrFragmentProcessor {
378 public:
379 NormalFlatFP() {
380 this->initClassID<NormalFlatFP>();
381 }
382
383 class GLSLNormalFlatFP : public GrGLSLFragmentProcessor {
384 public:
385 GLSLNormalFlatFP() {}
386
387 void emitCode(EmitArgs& args) override {
388 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
389
390 fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor );
391 }
392
393 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
394 GrProcessorKeyBuilder* b) {
395 b->add32(0x0);
396 }
397
398 protected:
399 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {}
400 };
401
402 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
403 GLSLNormalFlatFP::GenKey(*this, caps, b);
404 }
405
406 const char* name() const override { return "NormalFlatFP"; }
407
408 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
409 inout->setToUnknown(GrInvariantOutput::ReadInput::kWillNot_ReadInput);
410 }
411
412 private:
413 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLNormalFlatFP; }
414
415 bool onIsEqual(const GrFragmentProcessor& proc) const override {
416 return true;
417 }
418 };
419
420 sk_sp<GrFragmentProcessor> NormalFlatSourceImpl::asFragmentProcessor(
421 GrContext *context,
422 const SkMatrix &viewM,
423 const SkMatrix *localMatrix ,
424 SkFilterQuality filterQuali ty,
425 SkSourceGammaTreatment gamm aTreatment) const {
426
427 return sk_make_sp<NormalFlatFP>();
428 }
429
430 #endif // SK_SUPPORT_GPU
431
432 ////////////////////////////////////////////////////////////////////////////
433
434 NormalFlatSourceImpl::Provider::Provider() {}
435
436 NormalFlatSourceImpl::Provider::~Provider() {}
437
438 SkNormalSource::Provider* NormalFlatSourceImpl::asProvider(const SkShader::Conte xtRec &rec,
439 void *storage) const {
440 return new (storage) Provider();
441 }
442
443 size_t NormalFlatSourceImpl::providerSize(const SkShader::ContextRec&) const {
444 return sizeof(Provider);
445 }
446
447 void NormalFlatSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[ ],
448 int count) const {
449 for (int i = 0; i < count; i++) {
450 output[i] = {0.0f, 0.0f, 1.0f};
451 }
452 }
453
454 ////////////////////////////////////////////////////////////////////////////////
455
456 sk_sp<SkFlattenable> NormalFlatSourceImpl::CreateProc(SkReadBuffer& buf) {
457 return sk_make_sp<NormalFlatSourceImpl>();
458 }
459
460 void NormalFlatSourceImpl::flatten(SkWriteBuffer& buf) const {
461 this->INHERITED::flatten(buf);
462 }
463
464 ////////////////////////////////////////////////////////////////////////////
465
466 sk_sp<SkNormalSource> SkNormalSource::MakeFlat() {
467 return sk_make_sp<NormalFlatSourceImpl>();
468 }
469
470 ////////////////////////////////////////////////////////////////////////////
471
319 //////////////////////////////////////////////////////////////////////////// 472 ////////////////////////////////////////////////////////////////////////////
320 473
321 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource) 474 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource)
322 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(NormalMapSourceImpl) 475 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(NormalMapSourceImpl)
476 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(NormalFlatSourceImpl)
323 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 477 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
324 478
325 //////////////////////////////////////////////////////////////////////////// 479 ////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « src/core/SkNormalSource.h ('k') | src/gpu/GrFragmentProcessor.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698