| OLD | NEW |
| 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 "SkBitmapProcState.h" | 8 #include "SkBitmapProcState.h" |
| 9 #include "SkColor.h" | 9 #include "SkColor.h" |
| 10 #include "SkEmptyShader.h" | 10 #include "SkEmptyShader.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 | 36 |
| 37 /** \class SkLightingShaderImpl | 37 /** \class SkLightingShaderImpl |
| 38 This subclass of shader applies lighting. | 38 This subclass of shader applies lighting. |
| 39 */ | 39 */ |
| 40 class SK_API SkLightingShaderImpl : public SkShader { | 40 class SK_API SkLightingShaderImpl : public SkShader { |
| 41 public: | 41 public: |
| 42 | 42 |
| 43 /** Create a new lighting shader that uses the provided normal map and | 43 /** Create a new lighting shader that uses the provided normal map and |
| 44 lights to light the diffuse bitmap. | 44 lights to light the diffuse bitmap. |
| 45 @param diffuse the diffuse bitmap | 45 @param diffuse the diffuse bitmap |
| 46 @param normal the normal map | 46 @param normal the normal map |
| 47 @param lights the lights applied to the normal map | 47 @param lights the lights applied to the normal map |
| 48 @param invNormRotation rotation applied to the normal map's normals | 48 @param invNormRotation rotation applied to the normal map's normals |
| 49 @param diffLocalM the local matrix for the diffuse coordinates | 49 @param diffLocalM the local matrix for the diffuse coordinates |
| 50 @param normLocalM the local matrix for the normal coordinates | 50 @param normLocalM the local matrix for the normal coordinates |
| 51 @param normalSource the normal source for GPU computations | |
| 52 */ | 51 */ |
| 53 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, | 52 SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, |
| 54 const sk_sp<SkLights> lights, | 53 const sk_sp<SkLights> lights, |
| 55 const SkVector& invNormRotation, | 54 const SkVector& invNormRotation, |
| 56 const SkMatrix* diffLocalM, const SkMatrix* normLocalM, | 55 const SkMatrix* diffLocalM, const SkMatrix* normLocalM) |
| 57 sk_sp<SkLightingShader::NormalSource> normalSource) | |
| 58 : INHERITED(diffLocalM) | 56 : INHERITED(diffLocalM) |
| 59 , fDiffuseMap(diffuse) | 57 , fDiffuseMap(diffuse) |
| 60 , fNormalMap(normal) | 58 , fNormalMap(normal) |
| 61 , fLights(std::move(lights)) | 59 , fLights(std::move(lights)) |
| 62 , fInvNormRotation(invNormRotation) { | 60 , fInvNormRotation(invNormRotation) { |
| 63 | 61 |
| 64 if (normLocalM) { | 62 if (normLocalM) { |
| 65 fNormLocalMatrix = *normLocalM; | 63 fNormLocalMatrix = *normLocalM; |
| 66 } else { | 64 } else { |
| 67 fNormLocalMatrix.reset(); | 65 fNormLocalMatrix.reset(); |
| 68 } | 66 } |
| 69 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf
e. | 67 // Pre-cache so future calls to fNormLocalMatrix.getType() are threadsaf
e. |
| 70 (void)fNormLocalMatrix.getType(); | 68 (void)fNormLocalMatrix.getType(); |
| 71 | 69 |
| 72 fNormalSource = std::move(normalSource); | |
| 73 } | 70 } |
| 74 | 71 |
| 75 bool isOpaque() const override; | 72 bool isOpaque() const override; |
| 76 | 73 |
| 77 #if SK_SUPPORT_GPU | 74 #if SK_SUPPORT_GPU |
| 78 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, | 75 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, |
| 79 const SkMatrix& viewM, | 76 const SkMatrix& viewM, |
| 80 const SkMatrix* localMatrix, | 77 const SkMatrix* localMatrix, |
| 81 SkFilterQuality, | 78 SkFilterQuality, |
| 82 SkSourceGammaTreatment) const
override; | 79 SkSourceGammaTreatment) const
override; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 113 | 110 |
| 114 private: | 111 private: |
| 115 SkBitmap fDiffuseMap; | 112 SkBitmap fDiffuseMap; |
| 116 SkBitmap fNormalMap; | 113 SkBitmap fNormalMap; |
| 117 | 114 |
| 118 sk_sp<SkLights> fLights; | 115 sk_sp<SkLights> fLights; |
| 119 | 116 |
| 120 SkMatrix fNormLocalMatrix; | 117 SkMatrix fNormLocalMatrix; |
| 121 SkVector fInvNormRotation; | 118 SkVector fInvNormRotation; |
| 122 | 119 |
| 123 sk_sp<SkLightingShader::NormalSource> fNormalSource; | |
| 124 | |
| 125 friend class SkLightingShader; | 120 friend class SkLightingShader; |
| 126 | 121 |
| 127 typedef SkShader INHERITED; | 122 typedef SkShader INHERITED; |
| 128 }; | 123 }; |
| 129 | 124 |
| 130 //////////////////////////////////////////////////////////////////////////// | 125 //////////////////////////////////////////////////////////////////////////// |
| 131 | 126 |
| 132 #if SK_SUPPORT_GPU | 127 #if SK_SUPPORT_GPU |
| 133 | 128 |
| 134 #include "GrCoordTransform.h" | 129 #include "GrCoordTransform.h" |
| 135 #include "GrFragmentProcessor.h" | 130 #include "GrFragmentProcessor.h" |
| 136 #include "GrInvariantOutput.h" | 131 #include "GrInvariantOutput.h" |
| 137 #include "GrTextureAccess.h" | 132 #include "GrTextureAccess.h" |
| 138 #include "glsl/GrGLSLFragmentProcessor.h" | 133 #include "glsl/GrGLSLFragmentProcessor.h" |
| 139 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 134 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
| 140 #include "glsl/GrGLSLProgramDataManager.h" | 135 #include "glsl/GrGLSLProgramDataManager.h" |
| 141 #include "glsl/GrGLSLUniformHandler.h" | 136 #include "glsl/GrGLSLUniformHandler.h" |
| 142 #include "SkBitmapProcShader.h" | |
| 143 #include "SkGr.h" | 137 #include "SkGr.h" |
| 144 #include "SkGrPriv.h" | 138 #include "SkGrPriv.h" |
| 145 | 139 |
| 146 class LightingFP : public GrFragmentProcessor { | 140 class LightingFP : public GrFragmentProcessor { |
| 147 public: | 141 public: |
| 148 LightingFP(GrTexture* diffuse, const SkMatrix& diffMatrix, const GrTexturePa
rams& diffParams, | 142 LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& diffMatrix
, |
| 149 sk_sp<SkLights> lights, sk_sp<GrFragmentProcessor> normalFP) | 143 const SkMatrix& normMatrix, const GrTextureParams& diffParams, |
| 144 const GrTextureParams& normParams, sk_sp<SkLights> lights, |
| 145 const SkVector& invNormRotation) |
| 150 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam
s.filterMode()) | 146 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam
s.filterMode()) |
| 151 , fDiffuseTextureAccess(diffuse, diffParams) { | 147 , fNormDeviceTransform(kLocal_GrCoordSet, normMatrix, normal, normParams
.filterMode()) |
| 148 , fDiffuseTextureAccess(diffuse, diffParams) |
| 149 , fNormalTextureAccess(normal, normParams) |
| 150 , fInvNormRotation(invNormRotation) { |
| 152 this->addCoordTransform(&fDiffDeviceTransform); | 151 this->addCoordTransform(&fDiffDeviceTransform); |
| 152 this->addCoordTransform(&fNormDeviceTransform); |
| 153 this->addTextureAccess(&fDiffuseTextureAccess); | 153 this->addTextureAccess(&fDiffuseTextureAccess); |
| 154 this->addTextureAccess(&fNormalTextureAccess); |
| 154 | 155 |
| 155 // fuse all ambient lights into a single one | 156 // fuse all ambient lights into a single one |
| 156 fAmbientColor.set(0.0f, 0.0f, 0.0f); | 157 fAmbientColor.set(0.0f, 0.0f, 0.0f); |
| 157 for (int i = 0; i < lights->numLights(); ++i) { | 158 for (int i = 0; i < lights->numLights(); ++i) { |
| 158 if (SkLights::Light::kAmbient_LightType == lights->light(i).type())
{ | 159 if (SkLights::Light::kAmbient_LightType == lights->light(i).type())
{ |
| 159 fAmbientColor += lights->light(i).color(); | 160 fAmbientColor += lights->light(i).color(); |
| 160 } else { | 161 } else { |
| 161 // TODO: handle more than one of these | 162 // TODO: handle more than one of these |
| 162 fLightColor = lights->light(i).color(); | 163 fLightColor = lights->light(i).color(); |
| 163 fLightDir = lights->light(i).dir(); | 164 fLightDir = lights->light(i).dir(); |
| 164 } | 165 } |
| 165 } | 166 } |
| 166 | 167 |
| 167 this->registerChildProcessor(std::move(normalFP)); | |
| 168 this->initClassID<LightingFP>(); | 168 this->initClassID<LightingFP>(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 class GLSLLightingFP : public GrGLSLFragmentProcessor { | 171 class LightingGLFP : public GrGLSLFragmentProcessor { |
| 172 public: | 172 public: |
| 173 GLSLLightingFP() { | 173 LightingGLFP() { |
| 174 fLightDir.fX = 10000.0f; | 174 fLightDir.fX = 10000.0f; |
| 175 fLightColor.fX = 0.0f; | 175 fLightColor.fX = 0.0f; |
| 176 fAmbientColor.fX = 0.0f; | 176 fAmbientColor.fX = 0.0f; |
| 177 fInvNormRotation.set(0.0f, 0.0f); |
| 177 } | 178 } |
| 178 | 179 |
| 179 void emitCode(EmitArgs& args) override { | 180 void emitCode(EmitArgs& args) override { |
| 180 | 181 |
| 181 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 182 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 182 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | 183 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| 183 | 184 |
| 184 // add uniforms | 185 // add uniforms |
| 185 const char* lightDirUniName = nullptr; | 186 const char* lightDirUniName = nullptr; |
| 186 fLightDirUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 187 fLightDirUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
| 187 kVec3f_GrSLType, kDefault_
GrSLPrecision, | 188 kVec3f_GrSLType, kDefault_
GrSLPrecision, |
| 188 "LightDir", &lightDirUniNa
me); | 189 "LightDir", &lightDirUniNa
me); |
| 189 | 190 |
| 190 const char* lightColorUniName = nullptr; | 191 const char* lightColorUniName = nullptr; |
| 191 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 192 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
| 192 kVec3f_GrSLType, kDefaul
t_GrSLPrecision, | 193 kVec3f_GrSLType, kDefaul
t_GrSLPrecision, |
| 193 "LightColor", &lightColo
rUniName); | 194 "LightColor", &lightColo
rUniName); |
| 194 | 195 |
| 195 const char* ambientColorUniName = nullptr; | 196 const char* ambientColorUniName = nullptr; |
| 196 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag
, | 197 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag
, |
| 197 kVec3f_GrSLType, kDefa
ult_GrSLPrecision, | 198 kVec3f_GrSLType, kDefa
ult_GrSLPrecision, |
| 198 "AmbientColor", &ambie
ntColorUniName); | 199 "AmbientColor", &ambie
ntColorUniName); |
| 199 | 200 |
| 201 const char* xformUniName = nullptr; |
| 202 fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
| 203 kVec2f_GrSLType, kDefault_GrS
LPrecision, |
| 204 "Xform", &xformUniName); |
| 205 |
| 200 fragBuilder->codeAppend("vec4 diffuseColor = "); | 206 fragBuilder->codeAppend("vec4 diffuseColor = "); |
| 201 fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.f
TexSamplers[0], | 207 fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.f
TexSamplers[0], |
| 202 args.fCoords[0].c_str(), | 208 args.fCoords[0].c_str(), |
| 203 args.fCoords[0].getType()); | 209 args.fCoords[0].getType()); |
| 204 fragBuilder->codeAppend(";"); | 210 fragBuilder->codeAppend(";"); |
| 205 | 211 |
| 206 SkString dstNormalName("dstNormal"); | 212 fragBuilder->codeAppend("vec4 normalColor = "); |
| 207 this->emitChild(0, nullptr, &dstNormalName, args); | 213 fragBuilder->appendTextureLookup(args.fTexSamplers[1], |
| 214 args.fCoords[1].c_str(), |
| 215 args.fCoords[1].getType()); |
| 216 fragBuilder->codeAppend(";"); |
| 208 | 217 |
| 209 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st
r()); | 218 fragBuilder->codeAppend("vec3 normal = normalColor.rgb - vec3(0.5);"
); |
| 219 |
| 220 fragBuilder->codeAppendf( |
| 221 "mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0.
0, 0.0, 0.0, 1.0);", |
| 222 xformUniName, xformUniName, xformUniName, xform
UniName); |
| 223 |
| 224 // TODO: inverse map the light direction vectors in the vertex shade
r rather than |
| 225 // transforming all the normals here! |
| 226 fragBuilder->codeAppend("normal = normalize(m*normal);"); |
| 227 |
| 210 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0,
1.0);", | 228 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0,
1.0);", |
| 211 lightDirUniName); | 229 lightDirUniName); |
| 212 // diffuse light | 230 // diffuse light |
| 213 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;",
lightColorUniName); | 231 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;",
lightColorUniName); |
| 214 // ambient light | 232 // ambient light |
| 215 fragBuilder->codeAppendf("result += %s;", ambientColorUniName); | 233 fragBuilder->codeAppendf("result += %s;", ambientColorUniName); |
| 216 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a
rgs.fOutputColor); | 234 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a
rgs.fOutputColor); |
| 217 } | 235 } |
| 218 | 236 |
| 219 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | 237 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 237 if (lightColor != fLightColor) { | 255 if (lightColor != fLightColor) { |
| 238 pdman.set3fv(fLightColorUni, 1, &lightColor.fX); | 256 pdman.set3fv(fLightColorUni, 1, &lightColor.fX); |
| 239 fLightColor = lightColor; | 257 fLightColor = lightColor; |
| 240 } | 258 } |
| 241 | 259 |
| 242 const SkColor3f& ambientColor = lightingFP.ambientColor(); | 260 const SkColor3f& ambientColor = lightingFP.ambientColor(); |
| 243 if (ambientColor != fAmbientColor) { | 261 if (ambientColor != fAmbientColor) { |
| 244 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); | 262 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); |
| 245 fAmbientColor = ambientColor; | 263 fAmbientColor = ambientColor; |
| 246 } | 264 } |
| 265 |
| 266 const SkVector& invNormRotation = lightingFP.invNormRotation(); |
| 267 if (invNormRotation != fInvNormRotation) { |
| 268 pdman.set2fv(fXformUni, 1, &invNormRotation.fX); |
| 269 fInvNormRotation = invNormRotation; |
| 270 } |
| 247 } | 271 } |
| 248 | 272 |
| 249 private: | 273 private: |
| 250 SkVector3 fLightDir; | 274 SkVector3 fLightDir; |
| 251 GrGLSLProgramDataManager::UniformHandle fLightDirUni; | 275 GrGLSLProgramDataManager::UniformHandle fLightDirUni; |
| 252 | 276 |
| 253 SkColor3f fLightColor; | 277 SkColor3f fLightColor; |
| 254 GrGLSLProgramDataManager::UniformHandle fLightColorUni; | 278 GrGLSLProgramDataManager::UniformHandle fLightColorUni; |
| 255 | 279 |
| 256 SkColor3f fAmbientColor; | 280 SkColor3f fAmbientColor; |
| 257 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; | 281 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; |
| 282 |
| 283 SkVector fInvNormRotation; |
| 284 GrGLSLProgramDataManager::UniformHandle fXformUni; |
| 258 }; | 285 }; |
| 259 | 286 |
| 260 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { | 287 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override { |
| 261 GLSLLightingFP::GenKey(*this, caps, b); | 288 LightingGLFP::GenKey(*this, caps, b); |
| 262 } | 289 } |
| 263 | 290 |
| 264 const char* name() const override { return "LightingFP"; } | 291 const char* name() const override { return "LightingFP"; } |
| 265 | 292 |
| 266 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | 293 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 267 inout->mulByUnknownFourComponents(); | 294 inout->mulByUnknownFourComponents(); |
| 268 } | 295 } |
| 269 | 296 |
| 270 const SkVector3& lightDir() const { return fLightDir; } | 297 const SkVector3& lightDir() const { return fLightDir; } |
| 271 const SkColor3f& lightColor() const { return fLightColor; } | 298 const SkColor3f& lightColor() const { return fLightColor; } |
| 272 const SkColor3f& ambientColor() const { return fAmbientColor; } | 299 const SkColor3f& ambientColor() const { return fAmbientColor; } |
| 300 const SkVector& invNormRotation() const { return fInvNormRotation; } |
| 273 | 301 |
| 274 private: | 302 private: |
| 275 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new
GLSLLightingFP; } | 303 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new
LightingGLFP; } |
| 276 | 304 |
| 277 bool onIsEqual(const GrFragmentProcessor& proc) const override { | 305 bool onIsEqual(const GrFragmentProcessor& proc) const override { |
| 278 const LightingFP& lightingFP = proc.cast<LightingFP>(); | 306 const LightingFP& lightingFP = proc.cast<LightingFP>(); |
| 279 return fDiffDeviceTransform == lightingFP.fDiffDeviceTransform && | 307 return fDiffDeviceTransform == lightingFP.fDiffDeviceTransform && |
| 308 fNormDeviceTransform == lightingFP.fNormDeviceTransform && |
| 280 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess && | 309 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess && |
| 310 fNormalTextureAccess == lightingFP.fNormalTextureAccess && |
| 281 fLightDir == lightingFP.fLightDir && | 311 fLightDir == lightingFP.fLightDir && |
| 282 fLightColor == lightingFP.fLightColor && | 312 fLightColor == lightingFP.fLightColor && |
| 283 fAmbientColor == lightingFP.fAmbientColor; | 313 fAmbientColor == lightingFP.fAmbientColor && |
| 314 fInvNormRotation == lightingFP.fInvNormRotation; |
| 284 } | 315 } |
| 285 | 316 |
| 286 GrCoordTransform fDiffDeviceTransform; | 317 GrCoordTransform fDiffDeviceTransform; |
| 318 GrCoordTransform fNormDeviceTransform; |
| 287 GrTextureAccess fDiffuseTextureAccess; | 319 GrTextureAccess fDiffuseTextureAccess; |
| 320 GrTextureAccess fNormalTextureAccess; |
| 288 SkVector3 fLightDir; | 321 SkVector3 fLightDir; |
| 289 SkColor3f fLightColor; | 322 SkColor3f fLightColor; |
| 290 SkColor3f fAmbientColor; | 323 SkColor3f fAmbientColor; |
| 324 |
| 325 SkVector fInvNormRotation; |
| 291 }; | 326 }; |
| 292 | 327 |
| 293 //////////////////////////////////////////////////////////////////////////// | 328 //////////////////////////////////////////////////////////////////////////// |
| 294 | 329 |
| 295 static bool make_mat(const SkBitmap& bm, | 330 static bool make_mat(const SkBitmap& bm, |
| 296 const SkMatrix& localMatrix1, | 331 const SkMatrix& localMatrix1, |
| 297 const SkMatrix* localMatrix2, | 332 const SkMatrix* localMatrix2, |
| 298 SkMatrix* result) { | 333 SkMatrix* result) { |
| 299 | 334 |
| 300 result->setIDiv(bm.width(), bm.height()); | 335 result->setIDiv(bm.width(), bm.height()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 315 return true; | 350 return true; |
| 316 } | 351 } |
| 317 | 352 |
| 318 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor( | 353 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor( |
| 319 GrContext* context, | 354 GrContext* context, |
| 320 const SkMatrix& viewM, | 355 const SkMatrix& viewM, |
| 321 const SkMatrix* localMatrix
, | 356 const SkMatrix* localMatrix
, |
| 322 SkFilterQuality filterQuali
ty, | 357 SkFilterQuality filterQuali
ty, |
| 323 SkSourceGammaTreatment gamm
aTreatment) const { | 358 SkSourceGammaTreatment gamm
aTreatment) const { |
| 324 // we assume diffuse and normal maps have same width and height | 359 // we assume diffuse and normal maps have same width and height |
| 325 // TODO: support different sizes, will be addressed when diffuse maps are fa
ctored out of | 360 // TODO: support different sizes |
| 326 // SkLightingShader in a future CL | |
| 327 SkASSERT(fDiffuseMap.width() == fNormalMap.width() && | 361 SkASSERT(fDiffuseMap.width() == fNormalMap.width() && |
| 328 fDiffuseMap.height() == fNormalMap.height()); | 362 fDiffuseMap.height() == fNormalMap.height()); |
| 329 SkMatrix diffM; | 363 SkMatrix diffM, normM; |
| 330 | 364 |
| 331 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) { | 365 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) { |
| 332 return nullptr; | 366 return nullptr; |
| 333 } | 367 } |
| 334 | 368 |
| 369 if (!make_mat(fNormalMap, fNormLocalMatrix, localMatrix, &normM)) { |
| 370 return nullptr; |
| 371 } |
| 372 |
| 335 bool doBicubic; | 373 bool doBicubic; |
| 336 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode
( | 374 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode
( |
| 337 SkTMin(filterQuality, kMediu
m_SkFilterQuality), | 375 SkTMin(filterQuality, kMedium_SkFilterQu
ality), |
| 338 viewM, | 376 viewM, |
| 339 this->getLocalMatrix(), | 377 this->getLocalMatrix(), |
| 340 &doBicubic); | 378 &doBicubic); |
| 379 SkASSERT(!doBicubic); |
| 380 |
| 381 GrTextureParams::FilterMode normFilterMode = GrSkFilterQualityToGrFilterMode
( |
| 382 SkTMin(filterQuality, kMedium_SkFilterQu
ality), |
| 383 viewM, |
| 384 fNormLocalMatrix, |
| 385 &doBicubic); |
| 341 SkASSERT(!doBicubic); | 386 SkASSERT(!doBicubic); |
| 342 | 387 |
| 343 // TODO: support other tile modes | 388 // TODO: support other tile modes |
| 344 GrTextureParams diffParams(kClamp_TileMode, diffFilterMode); | 389 GrTextureParams diffParams(kClamp_TileMode, diffFilterMode); |
| 345 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, fDi
ffuseMap, | 390 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, |
| 346 diffParams,
gammaTreatment)); | 391 fDiffuseMap,
diffParams, |
| 392 gammaTreatme
nt)); |
| 347 if (!diffuseTexture) { | 393 if (!diffuseTexture) { |
| 348 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit
map to texture."); | 394 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit
map to texture."); |
| 349 return nullptr; | 395 return nullptr; |
| 350 } | 396 } |
| 351 | 397 |
| 352 sk_sp<GrFragmentProcessor> normalFP( | 398 GrTextureParams normParams(kClamp_TileMode, normFilterMode); |
| 353 fNormalSource->asFragmentProcessor(context, viewM, localMatrix, filt
erQuality, | 399 SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, |
| 354 gammaTreatment)); | 400 fNormalMap, n
ormParams, |
| 401 gammaTreatmen
t)); |
| 402 if (!normalTexture) { |
| 403 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit
map to texture."); |
| 404 return nullptr; |
| 405 } |
| 406 |
| 355 sk_sp<GrFragmentProcessor> inner ( | 407 sk_sp<GrFragmentProcessor> inner ( |
| 356 new LightingFP(diffuseTexture, diffM, diffParams, fLights, std::move
(normalFP))); | 408 new LightingFP(diffuseTexture, normalTexture, diffM, normM, diffParams,
normParams, fLights, |
| 357 | 409 fInvNormRotation)); |
| 358 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); | 410 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); |
| 359 } | 411 } |
| 360 | 412 |
| 361 #endif | 413 #endif |
| 362 | 414 |
| 363 //////////////////////////////////////////////////////////////////////////// | 415 //////////////////////////////////////////////////////////////////////////// |
| 364 | 416 |
| 365 bool SkLightingShaderImpl::isOpaque() const { | 417 bool SkLightingShaderImpl::isOpaque() const { |
| 366 return fDiffuseMap.isOpaque(); | 418 return fDiffuseMap.isOpaque(); |
| 367 } | 419 } |
| 368 | 420 |
| 369 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( | 421 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(const SkLight
ingShaderImpl& shader, |
| 370 const SkLighting
ShaderImpl& shader, | 422 const Context
Rec& rec, |
| 371 const ContextRec
& rec, | 423 SkBitmapProcS
tate* diffuseState, |
| 372 SkBitmapProcStat
e* diffuseState, | 424 SkBitmapProcS
tate* normalState) |
| 373 SkBitmapProcStat
e* normalState) | |
| 374 : INHERITED(shader, rec) | 425 : INHERITED(shader, rec) |
| 375 , fDiffuseState(diffuseState) | 426 , fDiffuseState(diffuseState) |
| 376 , fNormalState(normalState) { | 427 , fNormalState(normalState) |
| 428 { |
| 377 const SkPixmap& pixmap = fDiffuseState->fPixmap; | 429 const SkPixmap& pixmap = fDiffuseState->fPixmap; |
| 378 bool isOpaque = pixmap.isOpaque(); | 430 bool isOpaque = pixmap.isOpaque(); |
| 379 | 431 |
| 380 // update fFlags | 432 // update fFlags |
| 381 uint32_t flags = 0; | 433 uint32_t flags = 0; |
| 382 if (isOpaque && (255 == this->getPaintAlpha())) { | 434 if (isOpaque && (255 == this->getPaintAlpha())) { |
| 383 flags |= kOpaqueAlpha_Flag; | 435 flags |= kOpaqueAlpha_Flag; |
| 384 } | 436 } |
| 385 | 437 |
| 386 fFlags = flags; | 438 fFlags = flags; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 } | 608 } |
| 557 } | 609 } |
| 558 | 610 |
| 559 sk_sp<SkLights> lights(builder.finish()); | 611 sk_sp<SkLights> lights(builder.finish()); |
| 560 | 612 |
| 561 SkVector invNormRotation = {1,0}; | 613 SkVector invNormRotation = {1,0}; |
| 562 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { | 614 if (!buf.isVersionLT(SkReadBuffer::kLightingShaderWritesInvNormRotation)) { |
| 563 invNormRotation = buf.readPoint(); | 615 invNormRotation = buf.readPoint(); |
| 564 } | 616 } |
| 565 | 617 |
| 566 sk_sp<SkLightingShader::NormalSource> normalSource( | |
| 567 buf.readFlattenable<SkLightingShader::NormalSource>()); | |
| 568 | |
| 569 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
invNormRotation, | 618 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
invNormRotation, |
| 570 &diffLocalM, &normLocalM, std::move(
normalSource)); | 619 &diffLocalM, &normLocalM); |
| 571 } | 620 } |
| 572 | 621 |
| 573 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { | 622 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { |
| 574 this->INHERITED::flatten(buf); | 623 this->INHERITED::flatten(buf); |
| 575 | 624 |
| 576 bool hasNormLocalM = !fNormLocalMatrix.isIdentity(); | 625 bool hasNormLocalM = !fNormLocalMatrix.isIdentity(); |
| 577 buf.writeBool(hasNormLocalM); | 626 buf.writeBool(hasNormLocalM); |
| 578 if (hasNormLocalM) { | 627 if (hasNormLocalM) { |
| 579 buf.writeMatrix(fNormLocalMatrix); | 628 buf.writeMatrix(fNormLocalMatrix); |
| 580 } | 629 } |
| 581 | 630 |
| 582 buf.writeBitmap(fDiffuseMap); | 631 buf.writeBitmap(fDiffuseMap); |
| 583 buf.writeBitmap(fNormalMap); | 632 buf.writeBitmap(fNormalMap); |
| 584 | 633 |
| 585 buf.writeInt(fLights->numLights()); | 634 buf.writeInt(fLights->numLights()); |
| 586 for (int l = 0; l < fLights->numLights(); ++l) { | 635 for (int l = 0; l < fLights->numLights(); ++l) { |
| 587 const SkLights::Light& light = fLights->light(l); | 636 const SkLights::Light& light = fLights->light(l); |
| 588 | 637 |
| 589 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); | 638 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); |
| 590 | 639 |
| 591 buf.writeBool(isAmbient); | 640 buf.writeBool(isAmbient); |
| 592 buf.writeScalarArray(&light.color().fX, 3); | 641 buf.writeScalarArray(&light.color().fX, 3); |
| 593 if (!isAmbient) { | 642 if (!isAmbient) { |
| 594 buf.writeScalarArray(&light.dir().fX, 3); | 643 buf.writeScalarArray(&light.dir().fX, 3); |
| 595 } | 644 } |
| 596 } | 645 } |
| 597 buf.writePoint(fInvNormRotation); | 646 buf.writePoint(fInvNormRotation); |
| 598 | |
| 599 buf.writeFlattenable(fNormalSource.get()); | |
| 600 } | 647 } |
| 601 | 648 |
| 602 bool SkLightingShaderImpl::computeNormTotalInverse(const ContextRec& rec, | 649 bool SkLightingShaderImpl::computeNormTotalInverse(const ContextRec& rec, |
| 603 SkMatrix* normTotalInverse) c
onst { | 650 SkMatrix* normTotalInverse) c
onst { |
| 604 SkMatrix total; | 651 SkMatrix total; |
| 605 total.setConcat(*rec.fMatrix, fNormLocalMatrix); | 652 total.setConcat(*rec.fMatrix, fNormLocalMatrix); |
| 606 | 653 |
| 607 const SkMatrix* m = &total; | 654 const SkMatrix* m = &total; |
| 608 if (rec.fLocalMatrix) { | 655 if (rec.fLocalMatrix) { |
| 609 total.setConcat(*m, *rec.fLocalMatrix); | 656 total.setConcat(*m, *rec.fLocalMatrix); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 631 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); | 678 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); |
| 632 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat
e(fDiffuseMap, | 679 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat
e(fDiffuseMap, |
| 633 SkShader::kClamp_TileMode, SkShade
r::kClamp_TileMode, | 680 SkShader::kClamp_TileMode, SkShade
r::kClamp_TileMode, |
| 634 SkMipMap::De
duceTreatment(rec)); | 681 SkMipMap::De
duceTreatment(rec)); |
| 635 SkASSERT(diffuseState); | 682 SkASSERT(diffuseState); |
| 636 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) { | 683 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) { |
| 637 diffuseState->~SkBitmapProcState(); | 684 diffuseState->~SkBitmapProcState(); |
| 638 return nullptr; | 685 return nullptr; |
| 639 } | 686 } |
| 640 | 687 |
| 641 void* normalStateStorage = (char*)storage + | 688 void* normalStateStorage = (char*)storage + sizeof(LightingShaderContext) +
sizeof(SkBitmapProcState); |
| 642 sizeof(LightingShaderContext) + | |
| 643 sizeof(SkBitmapProcState); | |
| 644 SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(
fNormalMap, | 689 SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(
fNormalMap, |
| 645 SkShader::kClamp_TileMode, SkShader:
:kClamp_TileMode, | 690 SkShader::kClamp_TileMode, SkShader:
:kClamp_TileMode, |
| 646 SkMipMap::De
duceTreatment(rec)); | 691 SkMipMap::De
duceTreatment(rec)); |
| 647 SkASSERT(normalState); | 692 SkASSERT(normalState); |
| 648 if (!normalState->setup(normTotalInv, *rec.fPaint)) { | 693 if (!normalState->setup(normTotalInv, *rec.fPaint)) { |
| 649 diffuseState->~SkBitmapProcState(); | 694 diffuseState->~SkBitmapProcState(); |
| 650 normalState->~SkBitmapProcState(); | 695 normalState->~SkBitmapProcState(); |
| 651 return nullptr; | 696 return nullptr; |
| 652 } | 697 } |
| 653 | 698 |
| 654 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalS
tate); | 699 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalS
tate); |
| 655 } | 700 } |
| 656 | 701 |
| 657 /////////////////////////////////////////////////////////////////////////////// | 702 /////////////////////////////////////////////////////////////////////////////// |
| 658 | 703 |
| 704 static bool bitmap_is_too_big(const SkBitmap& bm) { |
| 705 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it |
| 706 // communicates between its matrix-proc and its sampler-proc. Until we can |
| 707 // widen that, we have to reject bitmaps that are larger. |
| 708 // |
| 709 static const int kMaxSize = 65535; |
| 710 |
| 711 return bm.width() > kMaxSize || bm.height() > kMaxSize; |
| 712 } |
| 713 |
| 659 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap&
normal, | 714 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap&
normal, |
| 660 sk_sp<SkLights> lights, | 715 sk_sp<SkLights> lights, |
| 661 const SkVector& invNormRotation, | 716 const SkVector& invNormRotation, |
| 662 const SkMatrix* diffLocalM, const SkMatri
x* normLocalM) { | 717 const SkMatrix* diffLocalM, const SkMatri
x* normLocalM) { |
| 663 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse) || | 718 if (diffuse.isNull() || bitmap_is_too_big(diffuse) || |
| 664 normal.isNull() || SkBitmapProcShader::BitmapIsTooBig(normal) || | 719 normal.isNull() || bitmap_is_too_big(normal) || |
| 665 diffuse.width() != normal.width() || | 720 diffuse.width() != normal.width() || |
| 666 diffuse.height() != normal.height()) { | 721 diffuse.height() != normal.height()) { |
| 667 return nullptr; | 722 return nullptr; |
| 668 } | 723 } |
| 724 |
| 669 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); | 725 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); |
| 670 | 726 |
| 671 sk_sp<SkLightingShader::NormalSource> normalSource = | |
| 672 SkLightingShader::NormalMapSource::Make(normal, invNormRotation, nor
mLocalM); | |
| 673 | |
| 674 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), | 727 return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), |
| 675 invNormRotation, diffLocalM, normLocalM, std::move(normalSource)); | 728 invNormRotation, diffLocalM, normLoc
alM); |
| 676 } | 729 } |
| 677 | 730 |
| 678 /////////////////////////////////////////////////////////////////////////////// | 731 /////////////////////////////////////////////////////////////////////////////// |
| 679 | 732 |
| 680 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) | 733 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) |
| 681 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) | 734 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) |
| 682 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 735 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 683 | 736 |
| 684 /////////////////////////////////////////////////////////////////////////////// | 737 /////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |