OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 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 |
| 8 #include "SkError.h" |
| 9 #include "SkErrorInternals.h" |
| 10 #include "SkLightingShader.h" |
| 11 #include "SkNormalSource.h" |
| 12 #include "SkReadBuffer.h" |
| 13 #include "SkWriteBuffer.h" |
| 14 |
| 15 // Genretating vtable |
| 16 SkNormalSource::~SkNormalSource() {} |
| 17 |
| 18 /////////////////////////////////////////////////////////////////////////////// |
| 19 |
| 20 class NormalMapSourceImpl : public SkNormalSource { |
| 21 public: |
| 22 NormalMapSourceImpl(sk_sp<SkShader> mapShader, const SkVector &normRotation) |
| 23 : fMapShader(std::move(mapShader)) |
| 24 , fNormRotation(normRotation) {} |
| 25 |
| 26 #if SK_SUPPORT_GPU |
| 27 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, |
| 28 const SkMatrix& viewM, |
| 29 const SkMatrix* localMatrix, |
| 30 SkFilterQuality, |
| 31 SkSourceGammaTreatment) const
override; |
| 32 #endif |
| 33 |
| 34 SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec, |
| 35 void* storage) const ov
erride; |
| 36 |
| 37 size_t providerSize(const SkShader::ContextRec& rec) const override; |
| 38 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalMapSourceImpl) |
| 39 |
| 40 protected: |
| 41 void flatten(SkWriteBuffer& buf) const override; |
| 42 |
| 43 bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* norm
TotalInverse) const; |
| 44 |
| 45 private: |
| 46 class Provider : public SkNormalSource::Provider { |
| 47 public: |
| 48 Provider(const NormalMapSourceImpl& source, SkShader::Context* fMapConte
xt); |
| 49 |
| 50 virtual ~Provider() override; |
| 51 |
| 52 void fillScanLine(int x, int y, SkPoint3 output[], int count) const over
ride; |
| 53 private: |
| 54 const NormalMapSourceImpl& fSource; |
| 55 SkShader::Context* fMapContext; |
| 56 |
| 57 typedef SkNormalSource::Provider INHERITED; |
| 58 }; |
| 59 |
| 60 sk_sp<SkShader> fMapShader; |
| 61 SkVector fNormRotation; |
| 62 |
| 63 friend class SkNormalSource; |
| 64 |
| 65 typedef SkNormalSource INHERITED; |
| 66 }; |
| 67 |
| 68 //////////////////////////////////////////////////////////////////////////// |
| 69 |
| 70 #if SK_SUPPORT_GPU |
| 71 |
| 72 #include "GrCoordTransform.h" |
| 73 #include "GrInvariantOutput.h" |
| 74 #include "GrTextureParams.h" |
| 75 #include "glsl/GrGLSLFragmentProcessor.h" |
| 76 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
| 77 #include "SkGr.h" |
| 78 |
| 79 class NormalMapFP : public GrFragmentProcessor { |
| 80 public: |
| 81 NormalMapFP(sk_sp<GrFragmentProcessor> mapFP, const SkVector& normRotation) |
| 82 : fNormRotation(normRotation) { |
| 83 this->registerChildProcessor(mapFP); |
| 84 |
| 85 this->initClassID<NormalMapFP>(); |
| 86 } |
| 87 |
| 88 class GLSLNormalMapFP : public GrGLSLFragmentProcessor { |
| 89 public: |
| 90 GLSLNormalMapFP() { |
| 91 fNormRotation.set(0.0f, 0.0f); |
| 92 } |
| 93 |
| 94 void emitCode(EmitArgs& args) override { |
| 95 |
| 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, |
| 102 kVec2f_GrSLType, kDefault_GrS
LPrecision, |
| 103 "Xform", &xformUniName); |
| 104 |
| 105 SkString dstNormalColorName("dstNormalColor"); |
| 106 this->emitChild(0, nullptr, &dstNormalColorName, args); |
| 107 fragBuilder->codeAppendf("vec3 normal = %s.rgb - vec3(0.5);", |
| 108 dstNormalColorName.c_str()); |
| 109 |
| 110 // TODO: inverse map the light direction vectors in the vertex shade
r rather than |
| 111 // transforming all the normals here! |
| 112 fragBuilder->codeAppendf( |
| 113 "mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0.0, 0.0, 0.0,
1.0);", |
| 114 xformUniName, xformUniName, xformUniName, xformUniName); |
| 115 |
| 116 fragBuilder->codeAppend("normal = normalize(m*normal);"); |
| 117 fragBuilder->codeAppendf("%s = vec4(normal, 0);", args.fOutputColor)
; |
| 118 } |
| 119 |
| 120 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
| 121 GrProcessorKeyBuilder* b) { |
| 122 b->add32(0x0); |
| 123 } |
| 124 |
| 125 protected: |
| 126 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor&
proc) override { |
| 127 const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); |
| 128 |
| 129 const SkVector& normRotation = normalMapFP.normRotation(); |
| 130 if (normRotation != fNormRotation) { |
| 131 pdman.set2fv(fXformUni, 1, &normRotation.fX); |
| 132 fNormRotation = normRotation; |
| 133 } |
| 134 } |
| 135 |
| 136 private: |
| 137 SkVector fNormRotation; |
| 138 GrGLSLProgramDataManager::UniformHandle fXformUni; |
| 139 }; |
| 140 |
| 141 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { |
| 142 GLSLNormalMapFP::GenKey(*this, caps, b); |
| 143 } |
| 144 |
| 145 const char* name() const override { return "NormalMapFP"; } |
| 146 |
| 147 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 148 inout->setToUnknown(GrInvariantOutput::ReadInput::kWillNot_ReadInput); |
| 149 } |
| 150 |
| 151 const SkVector& normRotation() const { return fNormRotation; } |
| 152 |
| 153 private: |
| 154 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new
GLSLNormalMapFP; } |
| 155 |
| 156 bool onIsEqual(const GrFragmentProcessor& proc) const override { |
| 157 const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); |
| 158 return fNormRotation == normalMapFP.fNormRotation; |
| 159 } |
| 160 |
| 161 SkVector fNormRotation; |
| 162 }; |
| 163 |
| 164 sk_sp<GrFragmentProcessor> NormalMapSourceImpl::asFragmentProcessor( |
| 165 GrContext *context, |
| 166 const SkMatrix &viewM, |
| 167 const SkMatrix *localMatrix
, |
| 168 SkFilterQuality filterQuali
ty, |
| 169 SkSourceGammaTreatment gamm
aTreatment) const { |
| 170 |
| 171 sk_sp<GrFragmentProcessor> mapFP = fMapShader->asFragmentProcessor(context,
viewM, |
| 172 localMatrix, filterQuality, gammaTreatment); |
| 173 |
| 174 return sk_make_sp<NormalMapFP>(std::move(mapFP), fNormRotation); |
| 175 } |
| 176 |
| 177 #endif // SK_SUPPORT_GPU |
| 178 |
| 179 //////////////////////////////////////////////////////////////////////////// |
| 180 |
| 181 NormalMapSourceImpl::Provider::Provider(const NormalMapSourceImpl& source, |
| 182 SkShader::Context* mapContext) |
| 183 : fSource(source) |
| 184 , fMapContext(mapContext) { |
| 185 } |
| 186 |
| 187 NormalMapSourceImpl::Provider::~Provider() { |
| 188 fMapContext->~Context(); |
| 189 } |
| 190 |
| 191 SkNormalSource::Provider* NormalMapSourceImpl::asProvider( |
| 192 const SkShader::ContextRec &rec, void *storage) const { |
| 193 SkMatrix normTotalInv; |
| 194 if (!this->computeNormTotalInverse(rec, &normTotalInv)) { |
| 195 return nullptr; |
| 196 } |
| 197 |
| 198 void* mapContextStorage = (char*)storage + sizeof(Provider); |
| 199 SkShader::Context* context = fMapShader->createContext(rec, mapContextStorag
e); |
| 200 if (!context) { |
| 201 return nullptr; |
| 202 } |
| 203 |
| 204 return new (storage) Provider(*this, context); |
| 205 } |
| 206 |
| 207 size_t NormalMapSourceImpl::providerSize(const SkShader::ContextRec& rec) const
{ |
| 208 return sizeof(Provider) + fMapShader->contextSize(rec); |
| 209 } |
| 210 |
| 211 bool NormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& re
c, |
| 212 SkMatrix* normTotalInverse) co
nst { |
| 213 SkMatrix total; |
| 214 total.setConcat(*rec.fMatrix, fMapShader->getLocalMatrix()); |
| 215 |
| 216 const SkMatrix* m = &total; |
| 217 if (rec.fLocalMatrix) { |
| 218 total.setConcat(*m, *rec.fLocalMatrix); |
| 219 m = &total; |
| 220 } |
| 221 return m->invert(normTotalInverse); |
| 222 } |
| 223 |
| 224 #define BUFFER_MAX 16 |
| 225 void NormalMapSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[]
, |
| 226 int count) const { |
| 227 SkPMColor tmpNormalColors[BUFFER_MAX]; |
| 228 |
| 229 do { |
| 230 int n = SkTMin(count, BUFFER_MAX); |
| 231 |
| 232 fMapContext->shadeSpan(x, y, tmpNormalColors, n); |
| 233 |
| 234 for (int i = 0; i < n; i++) { |
| 235 SkPoint3 tempNorm; |
| 236 |
| 237 tempNorm.set(SkIntToScalar(SkGetPackedR32(tmpNormalColors[i])) - 127
.0f, |
| 238 SkIntToScalar(SkGetPackedG32(tmpNormalColors[i])) - 127
.0f, |
| 239 SkIntToScalar(SkGetPackedB32(tmpNormalColors[i])) - 127
.0f); |
| 240 tempNorm.normalize(); |
| 241 |
| 242 output[i].fX = fSource.fNormRotation.fX * tempNorm.fX + |
| 243 fSource.fNormRotation.fY * tempNorm.fY; |
| 244 output[i].fY = -fSource.fNormRotation.fY * tempNorm.fX + |
| 245 fSource.fNormRotation.fX * tempNorm.fY; |
| 246 output[i].fZ = tempNorm.fZ; |
| 247 } |
| 248 |
| 249 output += n; |
| 250 x += n; |
| 251 count -= n; |
| 252 } while (count > 0); |
| 253 } |
| 254 |
| 255 //////////////////////////////////////////////////////////////////////////////// |
| 256 |
| 257 sk_sp<SkFlattenable> NormalMapSourceImpl::CreateProc(SkReadBuffer& buf) { |
| 258 |
| 259 sk_sp<SkShader> mapShader = buf.readFlattenable<SkShader>(); |
| 260 |
| 261 SkVector normRotation = {1,0}; |
| 262 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { |
| 263 normRotation = buf.readPoint(); |
| 264 } |
| 265 |
| 266 return sk_make_sp<NormalMapSourceImpl>(std::move(mapShader), normRotation); |
| 267 } |
| 268 |
| 269 void NormalMapSourceImpl::flatten(SkWriteBuffer& buf) const { |
| 270 this->INHERITED::flatten(buf); |
| 271 |
| 272 buf.writeFlattenable(fMapShader.get()); |
| 273 buf.writePoint(fNormRotation); |
| 274 } |
| 275 |
| 276 //////////////////////////////////////////////////////////////////////////// |
| 277 |
| 278 sk_sp<SkNormalSource> SkNormalSource::MakeFromNormalMap(sk_sp<SkShader> map, |
| 279 const SkVector &normRota
tion) { |
| 280 SkASSERT(SkScalarNearlyEqual(normRotation.lengthSqd(), SK_Scalar1)); |
| 281 if (!map) { |
| 282 return nullptr; |
| 283 } |
| 284 |
| 285 return sk_make_sp<NormalMapSourceImpl>(std::move(map), normRotation); |
| 286 } |
| 287 |
| 288 //////////////////////////////////////////////////////////////////////////// |
| 289 |
| 290 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource) |
| 291 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(NormalMapSourceImpl) |
| 292 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 293 |
| 294 //////////////////////////////////////////////////////////////////////////// |
OLD | NEW |