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

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

Issue 2063793002: API change to allow for NormalSource selection at the user level. (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-normal-factor-out
Patch Set: Fixed CPU behavior when normal.Z=-1 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 "SkBitmapProcShader.h" 8 #include "SkBitmapProcShader.h"
9 #include "SkBitmapProcState.h" 9 #include "SkBitmapProcState.h"
10 #include "SkColor.h" 10 #include "SkColor.h"
(...skipping 27 matching lines...) Expand all
38 38
39 /** \class SkLightingShaderImpl 39 /** \class SkLightingShaderImpl
40 This subclass of shader applies lighting. 40 This subclass of shader applies lighting.
41 */ 41 */
42 class SkLightingShaderImpl : public SkShader { 42 class SkLightingShaderImpl : public SkShader {
43 public: 43 public:
44 44
45 /** Create a new lighting shader that uses the provided normal map and 45 /** Create a new lighting shader that uses the provided normal map and
46 lights to light the diffuse bitmap. 46 lights to light the diffuse bitmap.
47 @param diffuse the diffuse bitmap 47 @param diffuse the diffuse bitmap
48 @param normal the normal map
49 @param lights the lights applied to the normal map 48 @param lights the lights applied to the normal map
50 @param invNormRotation rotation applied to the normal map's normals
51 @param diffLocalM the local matrix for the diffuse coordinates 49 @param diffLocalM the local matrix for the diffuse coordinates
52 @param normLocalM the local matrix for the normal coordinates 50 @param normalSource the source of normals for lighting computation
53 @param normalSource the normal source for GPU computations
54 */ 51 */
55 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, 52 SkLightingShaderImpl(const SkBitmap& diffuse,
56 const sk_sp<SkLights> lights, 53 const sk_sp<SkLights> lights,
57 const SkVector& invNormRotation, 54 const SkMatrix* diffLocalM,
58 const SkMatrix* diffLocalM, const SkMatrix* normLocalM,
59 sk_sp<SkNormalSource> normalSource) 55 sk_sp<SkNormalSource> normalSource)
60 : INHERITED(diffLocalM) 56 : INHERITED(diffLocalM)
61 , fDiffuseMap(diffuse) 57 , fDiffuseMap(diffuse)
62 , fNormalMap(normal) 58 , fLights(std::move(lights)) {
63 , fLights(std::move(lights))
64 , fInvNormRotation(invNormRotation) {
65
66 if (normLocalM) {
67 fNormLocalMatrix = *normLocalM;
68 } else {
69 fNormLocalMatrix.reset();
70 }
71 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf e.
72 (void)fNormLocalMatrix.getType();
73 59
robertphillips 2016/07/06 16:36:33 Can we not do this in the ctor list with the other
dvonbeck 2016/07/06 18:07:48 Done. I seem to have realized it in a future CL an
74 fNormalSource = std::move(normalSource); 60 fNormalSource = std::move(normalSource);
75 } 61 }
76 62
77 bool isOpaque() const override; 63 bool isOpaque() const override;
78 64
79 #if SK_SUPPORT_GPU 65 #if SK_SUPPORT_GPU
80 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, 66 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
81 const SkMatrix& viewM, 67 const SkMatrix& viewM,
82 const SkMatrix* localMatrix, 68 const SkMatrix* localMatrix,
83 SkFilterQuality, 69 SkFilterQuality,
(...skipping 23 matching lines...) Expand all
107 SK_TO_STRING_OVERRIDE() 93 SK_TO_STRING_OVERRIDE()
108 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) 94 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
109 95
110 protected: 96 protected:
111 void flatten(SkWriteBuffer&) const override; 97 void flatten(SkWriteBuffer&) const override;
112 size_t onContextSize(const ContextRec&) const override; 98 size_t onContextSize(const ContextRec&) const override;
113 Context* onCreateContext(const ContextRec&, void*) const override; 99 Context* onCreateContext(const ContextRec&, void*) const override;
114 100
115 private: 101 private:
116 SkBitmap fDiffuseMap; 102 SkBitmap fDiffuseMap;
117 SkBitmap fNormalMap;
118
119 sk_sp<SkLights> fLights; 103 sk_sp<SkLights> fLights;
120 104
121 SkMatrix fNormLocalMatrix;
122 SkVector fInvNormRotation;
123
124 sk_sp<SkNormalSource> fNormalSource; 105 sk_sp<SkNormalSource> fNormalSource;
125 106
126 friend class SkLightingShader; 107 friend class SkLightingShader;
127 108
128 typedef SkShader INHERITED; 109 typedef SkShader INHERITED;
129 }; 110 };
130 111
131 //////////////////////////////////////////////////////////////////////////// 112 ////////////////////////////////////////////////////////////////////////////
132 113
133 #if SK_SUPPORT_GPU 114 #if SK_SUPPORT_GPU
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 295
315 return true; 296 return true;
316 } 297 }
317 298
318 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor( 299 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(
319 GrContext* context, 300 GrContext* context,
320 const SkMatrix& viewM, 301 const SkMatrix& viewM,
321 const SkMatrix* localMatrix , 302 const SkMatrix* localMatrix ,
322 SkFilterQuality filterQuali ty, 303 SkFilterQuality filterQuali ty,
323 SkSourceGammaTreatment gamm aTreatment) const { 304 SkSourceGammaTreatment gamm aTreatment) const {
324 // we assume diffuse and normal maps have same width and height 305 // we assume diffuse and normal maps have same width and height
robertphillips 2016/07/06 16:36:33 Do we test different sized diffuse maps & light ma
dvonbeck 2016/07/06 18:07:48 This assumption disappears once both normals and d
robertphillips 2016/07/06 19:11:14 Do you have a task list (or something) to add it t
dvonbeck 2016/07/06 19:34:36 Yes, I added it
325 // TODO: support different sizes, will be addressed when diffuse maps are fa ctored out of 306 // TODO: support different sizes, will be addressed when diffuse maps are fa ctored out of
326 // SkLightingShader in a future CL 307 // SkLightingShader in a future CL
327 SkASSERT(fDiffuseMap.width() == fNormalMap.width() &&
328 fDiffuseMap.height() == fNormalMap.height());
329 SkMatrix diffM; 308 SkMatrix diffM;
330 309
331 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) { 310 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) {
332 return nullptr; 311 return nullptr;
333 } 312 }
334 313
335 bool doBicubic; 314 bool doBicubic;
336 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode ( 315 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode (
337 SkTMin(filterQuality, kMediu m_SkFilterQuality), 316 SkTMin(filterQuality, kMediu m_SkFilterQuality),
338 viewM, 317 viewM,
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 466
488 sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { 467 sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) {
489 SkMatrix diffLocalM; 468 SkMatrix diffLocalM;
490 bool hasDiffLocalM = buf.readBool(); 469 bool hasDiffLocalM = buf.readBool();
491 if (hasDiffLocalM) { 470 if (hasDiffLocalM) {
492 buf.readMatrix(&diffLocalM); 471 buf.readMatrix(&diffLocalM);
493 } else { 472 } else {
494 diffLocalM.reset(); 473 diffLocalM.reset();
495 } 474 }
496 475
497 SkMatrix normLocalM;
498 bool hasNormLocalM = buf.readBool();
499 if (hasNormLocalM) {
500 buf.readMatrix(&normLocalM);
501 } else {
502 normLocalM.reset();
503 }
504
505 SkBitmap diffuse; 476 SkBitmap diffuse;
506 if (!buf.readBitmap(&diffuse)) { 477 if (!buf.readBitmap(&diffuse)) {
507 return nullptr; 478 return nullptr;
508 } 479 }
509 diffuse.setImmutable(); 480 diffuse.setImmutable();
510 481
511 SkBitmap normal;
512 if (!buf.readBitmap(&normal)) {
513 return nullptr;
514 }
515 normal.setImmutable();
516
517 int numLights = buf.readInt(); 482 int numLights = buf.readInt();
518 483
519 SkLights::Builder builder; 484 SkLights::Builder builder;
520 485
521 for (int l = 0; l < numLights; ++l) { 486 for (int l = 0; l < numLights; ++l) {
522 bool isAmbient = buf.readBool(); 487 bool isAmbient = buf.readBool();
523 488
524 SkColor3f color; 489 SkColor3f color;
525 if (!buf.readScalarArray(&color.fX, 3)) { 490 if (!buf.readScalarArray(&color.fX, 3)) {
526 return nullptr; 491 return nullptr;
527 } 492 }
528 493
529 if (isAmbient) { 494 if (isAmbient) {
530 builder.add(SkLights::Light(color)); 495 builder.add(SkLights::Light(color));
531 } else { 496 } else {
532 SkVector3 dir; 497 SkVector3 dir;
533 if (!buf.readScalarArray(&dir.fX, 3)) { 498 if (!buf.readScalarArray(&dir.fX, 3)) {
534 return nullptr; 499 return nullptr;
535 } 500 }
536 builder.add(SkLights::Light(color, dir)); 501 builder.add(SkLights::Light(color, dir));
537 } 502 }
538 } 503 }
539 504
540 sk_sp<SkLights> lights(builder.finish()); 505 sk_sp<SkLights> lights(builder.finish());
541 506
542 SkVector invNormRotation = {1,0};
543 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) {
544 invNormRotation = buf.readPoint();
545 }
546
547 sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>()); 507 sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>());
548 508
549 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation, 509 return sk_make_sp<SkLightingShaderImpl>(diffuse, std::move(lights), &diffLoc alM,
550 &diffLocalM, &normLocalM, std::move( normalSource)); 510 std::move(normalSource));
551 } 511 }
552 512
553 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 513 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
554 this->INHERITED::flatten(buf); 514 this->INHERITED::flatten(buf);
555 515
556 bool hasNormLocalM = !fNormLocalMatrix.isIdentity();
557 buf.writeBool(hasNormLocalM);
558 if (hasNormLocalM) {
559 buf.writeMatrix(fNormLocalMatrix);
560 }
561
562 buf.writeBitmap(fDiffuseMap); 516 buf.writeBitmap(fDiffuseMap);
563 buf.writeBitmap(fNormalMap);
564 517
565 buf.writeInt(fLights->numLights()); 518 buf.writeInt(fLights->numLights());
566 for (int l = 0; l < fLights->numLights(); ++l) { 519 for (int l = 0; l < fLights->numLights(); ++l) {
567 const SkLights::Light& light = fLights->light(l); 520 const SkLights::Light& light = fLights->light(l);
568 521
569 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); 522 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
570 523
571 buf.writeBool(isAmbient); 524 buf.writeBool(isAmbient);
572 buf.writeScalarArray(&light.color().fX, 3); 525 buf.writeScalarArray(&light.color().fX, 3);
573 if (!isAmbient) { 526 if (!isAmbient) {
574 buf.writeScalarArray(&light.dir().fX, 3); 527 buf.writeScalarArray(&light.dir().fX, 3);
575 } 528 }
576 } 529 }
577 buf.writePoint(fInvNormRotation);
578 530
579 buf.writeFlattenable(fNormalSource.get()); 531 buf.writeFlattenable(fNormalSource.get());
580 } 532 }
581 533
582 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const { 534 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const {
583 return sizeof(LightingShaderContext) + 535 return sizeof(LightingShaderContext) +
584 sizeof(SkBitmapProcState) + 536 sizeof(SkBitmapProcState) +
585 fNormalSource->providerSize(rec); 537 fNormalSource->providerSize(rec);
586 } 538 }
587 539
(...skipping 22 matching lines...) Expand all
610 if (!normalProvider) { 562 if (!normalProvider) {
611 diffuseState->~SkBitmapProcState(); 563 diffuseState->~SkBitmapProcState();
612 return nullptr; 564 return nullptr;
613 } 565 }
614 566
615 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalP rovider); 567 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalP rovider);
616 } 568 }
617 569
618 /////////////////////////////////////////////////////////////////////////////// 570 ///////////////////////////////////////////////////////////////////////////////
619 571
620 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap& normal, 572 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, sk_sp<SkLights> lights,
robertphillips 2016/07/06 16:36:33 tab the following line over to match up with the '
dvonbeck 2016/07/06 18:07:48 If I do, then the line is over 100 columns. Is thi
robertphillips 2016/07/06 19:11:14 Right, tab it over and add newlines as necessary.
dvonbeck 2016/07/06 19:34:36 Done.
621 sk_sp<SkLights> lights, 573 const SkMatrix* diffLocalM, sk_sp<SkNormalSource> normalSource) {
622 const SkVector& invNormRotation, 574 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse)) {
623 const SkMatrix* diffLocalM, const SkMatri x* normLocalM) {
624 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse) ||
625 normal.isNull() || SkBitmapProcShader::BitmapIsTooBig(normal) ||
626 diffuse.width() != normal.width() ||
627 diffuse.height() != normal.height()) {
628 return nullptr; 575 return nullptr;
629 } 576 }
630 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1));
631 577
632 // TODO: support other tile modes 578 if (!normalSource) {
633 sk_sp<SkShader> mapShader = SkMakeBitmapShader(normal, SkShader::kClamp_Tile Mode, 579 // TODO: Use a default implementation of normalSource instead
634 SkShader::kClamp_TileMode, no rmLocalM, nullptr); 580 return nullptr;
581 }
635 582
636 sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(mapSh ader, 583 return sk_make_sp<SkLightingShaderImpl>(diffuse, std::move(lights), diffLoca lM,
637 invNo rmRotation); 584 std::move(normalSource));
638
639 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
640 invNormRotation, diffLocalM, normLocalM, std::move(normalSource));
641 } 585 }
642 586
643 /////////////////////////////////////////////////////////////////////////////// 587 ///////////////////////////////////////////////////////////////////////////////
644 588
645 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 589 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
646 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 590 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
647 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 591 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
648 592
649 /////////////////////////////////////////////////////////////////////////////// 593 ///////////////////////////////////////////////////////////////////////////////
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698