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

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

Issue 2062703003: Abstracted diffuse color map out of SkLightingShaderImpl into a generic SkShader (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-normal-api-change
Patch Set: Rebased, now allocates LightingShaderContext deps on the heap Created 4 years, 6 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 | « no previous file | src/core/SkLightingShader_NormalSource.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 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 22 matching lines...) Expand all
33 down & upsampled draws 33 down & upsampled draws
34 */ 34 */
35 35
36 36
37 37
38 /** \class SkLightingShaderImpl 38 /** \class SkLightingShaderImpl
39 This subclass of shader applies lighting. 39 This subclass of shader applies lighting.
40 */ 40 */
41 class SkLightingShaderImpl : public SkShader { 41 class SkLightingShaderImpl : public SkShader {
42 public: 42 public:
43
44 /** 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
45 lights to light the diffuse bitmap. 44 lights to light the diffuse bitmap.
46 @param diffuse the diffuse bitmap 45 @param diffuseShader the shader that provides the diffuse colors
47 @param lights the lights applied to the normal map
48 @param diffLocalM the local matrix for the diffuse coordinates
49 @param normalSource the source of normals for lighting computation 46 @param normalSource the source of normals for lighting computation
47 @param lights the lights applied to the geometry
50 */ 48 */
51 SkLightingShaderImpl(const SkBitmap& diffuse, 49 SkLightingShaderImpl(sk_sp<SkShader> diffuseShader,
52 const sk_sp<SkLights> lights, 50 sk_sp<SkLightingShader::NormalSource> normalSource,
53 const SkMatrix* diffLocalM, 51 const sk_sp<SkLights> lights)
54 sk_sp<SkLightingShader::NormalSource> normalSource) 52 : fDiffuseShader(std::move(diffuseShader))
55 : INHERITED(diffLocalM) 53 , fNormalSource(std::move(normalSource))
56 , fDiffuseMap(diffuse) 54 , fLights(std::move(lights)) {}
57 , fLights(std::move(lights)) {
58
59 fNormalSource = std::move(normalSource);
60 }
61 55
62 bool isOpaque() const override; 56 bool isOpaque() const override;
63 57
64 #if SK_SUPPORT_GPU 58 #if SK_SUPPORT_GPU
65 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, 59 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
66 const SkMatrix& viewM, 60 const SkMatrix& viewM,
67 const SkMatrix* localMatrix, 61 const SkMatrix* localMatrix,
68 SkFilterQuality, 62 SkFilterQuality,
69 SkSourceGammaTreatment) const override; 63 SkSourceGammaTreatment) const override;
70 #endif 64 #endif
71 65
72 class LightingShaderContext : public SkShader::Context { 66 class LightingShaderContext : public SkShader::Context {
73 public: 67 public:
74 // The context takes ownership of the states. It will call their destruc tors 68 // The context takes ownership of the states. It will call their destruc tors
75 // but will NOT free the memory. 69 // but will NOT free the memory.
76 LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&, 70 LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&,
77 SkBitmapProcState* diffuseState, 71 SkShader::Context* diffuseContext,
78 SkLightingShader::NormalSource::Provider*); 72 SkLightingShader::NormalSource::Provider*, void* h eapAllocated);
79 ~LightingShaderContext() override; 73 ~LightingShaderContext() override;
80 74
81 void shadeSpan(int x, int y, SkPMColor[], int count) override; 75 void shadeSpan(int x, int y, SkPMColor[], int count) override;
82 76
83 uint32_t getFlags() const override { return fFlags; } 77 uint32_t getFlags() const override { return fFlags; }
84 78
85 private: 79 private:
86 SkBitmapProcState* fDiffuseState; 80 SkShader::Context* fDiffuseContext;
87 SkLightingShader::NormalSource::Provider* fNormalProvider; 81 SkLightingShader::NormalSource::Provider* fNormalProvider;
88 uint32_t fFlags; 82 uint32_t fFlags;
89 83
84 void* fHeapAllocated;
85
90 typedef SkShader::Context INHERITED; 86 typedef SkShader::Context INHERITED;
91 }; 87 };
92 88
93 SK_TO_STRING_OVERRIDE() 89 SK_TO_STRING_OVERRIDE()
94 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) 90 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
95 91
96 protected: 92 protected:
97 void flatten(SkWriteBuffer&) const override; 93 void flatten(SkWriteBuffer&) const override;
98 size_t onContextSize(const ContextRec&) const override; 94 size_t onContextSize(const ContextRec&) const override;
99 Context* onCreateContext(const ContextRec&, void*) const override; 95 Context* onCreateContext(const ContextRec&, void*) const override;
100 96
101 private: 97 private:
102 SkBitmap fDiffuseMap; 98 sk_sp<SkShader> fDiffuseShader;
99 sk_sp<SkLightingShader::NormalSource> fNormalSource;
103 sk_sp<SkLights> fLights; 100 sk_sp<SkLights> fLights;
104 101
105 sk_sp<SkLightingShader::NormalSource> fNormalSource;
106
107 friend class SkLightingShader; 102 friend class SkLightingShader;
108 103
109 typedef SkShader INHERITED; 104 typedef SkShader INHERITED;
110 }; 105 };
111 106
112 //////////////////////////////////////////////////////////////////////////// 107 ////////////////////////////////////////////////////////////////////////////
113 108
114 #if SK_SUPPORT_GPU 109 #if SK_SUPPORT_GPU
115 110
116 #include "GrCoordTransform.h" 111 #include "GrCoordTransform.h"
117 #include "GrFragmentProcessor.h" 112 #include "GrFragmentProcessor.h"
118 #include "GrInvariantOutput.h" 113 #include "GrInvariantOutput.h"
119 #include "GrTextureAccess.h" 114 #include "GrTextureAccess.h"
120 #include "glsl/GrGLSLFragmentProcessor.h" 115 #include "glsl/GrGLSLFragmentProcessor.h"
121 #include "glsl/GrGLSLFragmentShaderBuilder.h" 116 #include "glsl/GrGLSLFragmentShaderBuilder.h"
122 #include "glsl/GrGLSLProgramDataManager.h" 117 #include "glsl/GrGLSLProgramDataManager.h"
123 #include "glsl/GrGLSLUniformHandler.h" 118 #include "glsl/GrGLSLUniformHandler.h"
124 #include "SkGr.h" 119 #include "SkGr.h"
125 #include "SkGrPriv.h" 120 #include "SkGrPriv.h"
126 121
127 class LightingFP : public GrFragmentProcessor { 122 class LightingFP : public GrFragmentProcessor {
128 public: 123 public:
129 LightingFP(GrTexture* diffuse, const SkMatrix& diffMatrix, const GrTexturePa rams& diffParams, 124 LightingFP(sk_sp<GrFragmentProcessor> diffuseFP, sk_sp<GrFragmentProcessor> normalFP,
130 sk_sp<SkLights> lights, sk_sp<GrFragmentProcessor> normalFP) 125 sk_sp<SkLights> lights) {
131 : fDiffDeviceTransform(kLocal_GrCoordSet, diffMatrix, diffuse, diffParam s.filterMode())
132 , fDiffuseTextureAccess(diffuse, diffParams) {
133 this->addCoordTransform(&fDiffDeviceTransform);
134 this->addTextureAccess(&fDiffuseTextureAccess);
135 126
136 // fuse all ambient lights into a single one 127 // fuse all ambient lights into a single one
137 fAmbientColor.set(0.0f, 0.0f, 0.0f); 128 fAmbientColor.set(0.0f, 0.0f, 0.0f);
138 for (int i = 0; i < lights->numLights(); ++i) { 129 for (int i = 0; i < lights->numLights(); ++i) {
139 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { 130 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) {
140 fAmbientColor += lights->light(i).color(); 131 fAmbientColor += lights->light(i).color();
141 } else { 132 } else {
142 // TODO: handle more than one of these 133 // TODO: handle more than one of these
143 fLightColor = lights->light(i).color(); 134 fLightColor = lights->light(i).color();
144 fLightDir = lights->light(i).dir(); 135 fLightDir = lights->light(i).dir();
145 } 136 }
146 } 137 }
147 138
139 this->registerChildProcessor(std::move(diffuseFP));
148 this->registerChildProcessor(std::move(normalFP)); 140 this->registerChildProcessor(std::move(normalFP));
149 this->initClassID<LightingFP>(); 141 this->initClassID<LightingFP>();
150 } 142 }
151 143
152 class GLSLLightingFP : public GrGLSLFragmentProcessor { 144 class GLSLLightingFP : public GrGLSLFragmentProcessor {
153 public: 145 public:
154 GLSLLightingFP() { 146 GLSLLightingFP() {
155 fLightDir.fX = 10000.0f; 147 fLightDir.fX = 10000.0f;
156 fLightColor.fX = 0.0f; 148 fLightColor.fX = 0.0f;
157 fAmbientColor.fX = 0.0f; 149 fAmbientColor.fX = 0.0f;
(...skipping 13 matching lines...) Expand all
171 const char* lightColorUniName = nullptr; 163 const char* lightColorUniName = nullptr;
172 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 164 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
173 kVec3f_GrSLType, kDefaul t_GrSLPrecision, 165 kVec3f_GrSLType, kDefaul t_GrSLPrecision,
174 "LightColor", &lightColo rUniName); 166 "LightColor", &lightColo rUniName);
175 167
176 const char* ambientColorUniName = nullptr; 168 const char* ambientColorUniName = nullptr;
177 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , 169 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag ,
178 kVec3f_GrSLType, kDefa ult_GrSLPrecision, 170 kVec3f_GrSLType, kDefa ult_GrSLPrecision,
179 "AmbientColor", &ambie ntColorUniName); 171 "AmbientColor", &ambie ntColorUniName);
180 172
181 fragBuilder->codeAppend("vec4 diffuseColor = "); 173 SkString dstDiffuseName("dstDiffuse");
182 fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.f TexSamplers[0], 174 this->emitChild(0, args.fInputColor, &dstDiffuseName, args);
183 args.fCoords[0].c_str(), 175 fragBuilder->codeAppendf("vec4 diffuseColor = %s;", dstDiffuseName.c _str());
184 args.fCoords[0].getType());
185 fragBuilder->codeAppend(";");
186 176
187 SkString dstNormalName("dstNormal"); 177 SkString dstNormalName("dstNormal");
188 this->emitChild(0, nullptr, &dstNormalName, args); 178 this->emitChild(1, nullptr, &dstNormalName, args);
189 179
190 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r()); 180 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r());
191 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);", 181 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);",
192 lightDirUniName); 182 lightDirUniName);
193 // diffuse light 183 // diffuse light
194 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName); 184 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName);
195 // ambient light 185 // ambient light
196 fragBuilder->codeAppendf("result += %s;", ambientColorUniName); 186 fragBuilder->codeAppendf("result += %s;", ambientColorUniName);
197 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a rgs.fOutputColor); 187 fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", a rgs.fOutputColor);
198 } 188 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 240
251 const SkVector3& lightDir() const { return fLightDir; } 241 const SkVector3& lightDir() const { return fLightDir; }
252 const SkColor3f& lightColor() const { return fLightColor; } 242 const SkColor3f& lightColor() const { return fLightColor; }
253 const SkColor3f& ambientColor() const { return fAmbientColor; } 243 const SkColor3f& ambientColor() const { return fAmbientColor; }
254 244
255 private: 245 private:
256 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; } 246 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; }
257 247
258 bool onIsEqual(const GrFragmentProcessor& proc) const override { 248 bool onIsEqual(const GrFragmentProcessor& proc) const override {
259 const LightingFP& lightingFP = proc.cast<LightingFP>(); 249 const LightingFP& lightingFP = proc.cast<LightingFP>();
260 return fDiffDeviceTransform == lightingFP.fDiffDeviceTransform && 250 return fLightDir == lightingFP.fLightDir &&
261 fDiffuseTextureAccess == lightingFP.fDiffuseTextureAccess &&
262 fLightDir == lightingFP.fLightDir &&
263 fLightColor == lightingFP.fLightColor && 251 fLightColor == lightingFP.fLightColor &&
264 fAmbientColor == lightingFP.fAmbientColor; 252 fAmbientColor == lightingFP.fAmbientColor;
265 } 253 }
266 254
267 GrCoordTransform fDiffDeviceTransform;
268 GrTextureAccess fDiffuseTextureAccess;
269 SkVector3 fLightDir; 255 SkVector3 fLightDir;
270 SkColor3f fLightColor; 256 SkColor3f fLightColor;
271 SkColor3f fAmbientColor; 257 SkColor3f fAmbientColor;
272 }; 258 };
273 259
274 //////////////////////////////////////////////////////////////////////////// 260 ////////////////////////////////////////////////////////////////////////////
275 261
276 static bool make_mat(const SkBitmap& bm,
277 const SkMatrix& localMatrix1,
278 const SkMatrix* localMatrix2,
279 SkMatrix* result) {
280
281 result->setIDiv(bm.width(), bm.height());
282
283 SkMatrix lmInverse;
284 if (!localMatrix1.invert(&lmInverse)) {
285 return false;
286 }
287 if (localMatrix2) {
288 SkMatrix inv;
289 if (!localMatrix2->invert(&inv)) {
290 return false;
291 }
292 lmInverse.postConcat(inv);
293 }
294 result->preConcat(lmInverse);
295
296 return true;
297 }
298
299 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor( 262 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(
300 GrContext* context, 263 GrContext* context,
301 const SkMatrix& viewM, 264 const SkMatrix& viewM,
302 const SkMatrix* localMatrix , 265 const SkMatrix* localMatrix ,
303 SkFilterQuality filterQuali ty, 266 SkFilterQuality filterQuali ty,
304 SkSourceGammaTreatment gamm aTreatment) const { 267 SkSourceGammaTreatment gamm aTreatment) const {
305 // we assume diffuse and normal maps have same width and height 268 sk_sp<GrFragmentProcessor> diffuseFP(
306 // TODO: support different sizes, will be addressed when diffuse maps are fa ctored out of 269 fDiffuseShader->asFragmentProcessor(context, viewM, localMatrix, fil terQuality,
307 // SkLightingShader in a future CL 270 gammaTreatment));
308 SkMatrix diffM;
309
310 if (!make_mat(fDiffuseMap, this->getLocalMatrix(), localMatrix, &diffM)) {
311 return nullptr;
312 }
313
314 bool doBicubic;
315 GrTextureParams::FilterMode diffFilterMode = GrSkFilterQualityToGrFilterMode (
316 SkTMin(filterQuality, kMediu m_SkFilterQuality),
317 viewM,
318 this->getLocalMatrix(),
319 &doBicubic);
320 SkASSERT(!doBicubic);
321
322 // TODO: support other tile modes
323 GrTextureParams diffParams(kClamp_TileMode, diffFilterMode);
324 SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, fDi ffuseMap,
325 diffParams, gammaTreatment));
326 if (!diffuseTexture) {
327 SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bit map to texture.");
328 return nullptr;
329 }
330
331 sk_sp<GrFragmentProcessor> normalFP( 271 sk_sp<GrFragmentProcessor> normalFP(
332 fNormalSource->asFragmentProcessor(context, viewM, localMatrix, filt erQuality, 272 fNormalSource->asFragmentProcessor(context, viewM, localMatrix, filt erQuality,
333 gammaTreatment)); 273 gammaTreatment));
334 sk_sp<GrFragmentProcessor> inner ( 274 sk_sp<GrFragmentProcessor> inner (
335 new LightingFP(diffuseTexture, diffM, diffParams, fLights, std::move (normalFP))); 275 new LightingFP(std::move(diffuseFP), std::move(normalFP), fLights));
336 276
337 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); 277 return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner));
338 } 278 }
339 279
340 #endif 280 #endif
341 281
342 //////////////////////////////////////////////////////////////////////////// 282 ////////////////////////////////////////////////////////////////////////////
343 283
344 bool SkLightingShaderImpl::isOpaque() const { 284 bool SkLightingShaderImpl::isOpaque() const {
345 return fDiffuseMap.isOpaque(); 285 return fDiffuseShader->isOpaque();
346 } 286 }
347 287
348 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( 288 SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
349 const SkLightingShaderImpl& shader, const ContextRec& rec, SkBitmapProcS tate* diffuseState, 289 const SkLightingShaderImpl& shader, const ContextRec& rec,
350 SkLightingShader::NormalSource::Provider* normalProvider) 290 SkShader::Context* diffuseContext, SkLightingShader::NormalSource::Provi der* normalProvider,
291 void* heapAllocated)
351 : INHERITED(shader, rec) 292 : INHERITED(shader, rec)
352 , fDiffuseState(diffuseState) 293 , fDiffuseContext(diffuseContext)
353 , fNormalProvider(normalProvider) { 294 , fNormalProvider(normalProvider)
354 const SkPixmap& pixmap = fDiffuseState->fPixmap; 295 , fHeapAllocated(heapAllocated) {
355 bool isOpaque = pixmap.isOpaque(); 296 bool isOpaque = shader.isOpaque();
356 297
357 // update fFlags 298 // update fFlags
358 uint32_t flags = 0; 299 uint32_t flags = 0;
359 if (isOpaque && (255 == this->getPaintAlpha())) { 300 if (isOpaque && (255 == this->getPaintAlpha())) {
360 flags |= kOpaqueAlpha_Flag; 301 flags |= kOpaqueAlpha_Flag;
361 } 302 }
362 303
363 fFlags = flags; 304 fFlags = flags;
364 } 305 }
365 306
366 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { 307 SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() {
367 // The bitmap proc states have been created outside of the context on memory that will be freed 308 // The dependencies have been created outside of the context on memory that was allocated by
368 // elsewhere. Call the destructors but leave the freeing of the memory to th e caller. 309 // the onCreateContext() method. Call the destructors and free the memory.
369 fDiffuseState->~SkBitmapProcState(); 310 fDiffuseContext->~Context();
370 fNormalProvider->~Provider(); 311 fNormalProvider->~Provider();
312
313 free(fHeapAllocated);
371 } 314 }
372 315
373 static inline SkPMColor convert(SkColor3f color, U8CPU a) { 316 static inline SkPMColor convert(SkColor3f color, U8CPU a) {
374 if (color.fX <= 0.0f) { 317 if (color.fX <= 0.0f) {
375 color.fX = 0.0f; 318 color.fX = 0.0f;
376 } else if (color.fX >= 255.0f) { 319 } else if (color.fX >= 255.0f) {
377 color.fX = 255.0f; 320 color.fX = 255.0f;
378 } 321 }
379 322
380 if (color.fY <= 0.0f) { 323 if (color.fY <= 0.0f) {
381 color.fY = 0.0f; 324 color.fY = 0.0f;
382 } else if (color.fY >= 255.0f) { 325 } else if (color.fY >= 255.0f) {
383 color.fY = 255.0f; 326 color.fY = 255.0f;
384 } 327 }
385 328
386 if (color.fZ <= 0.0f) { 329 if (color.fZ <= 0.0f) {
387 color.fZ = 0.0f; 330 color.fZ = 0.0f;
388 } else if (color.fZ >= 255.0f) { 331 } else if (color.fZ >= 255.0f) {
389 color.fZ = 255.0f; 332 color.fZ = 255.0f;
390 } 333 }
391 334
392 return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ) ; 335 return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ) ;
393 } 336 }
394 337
395 // larger is better (fewer times we have to loop), but we shouldn't 338 // larger is better (fewer times we have to loop), but we shouldn't
396 // take up too much stack-space (each one here costs 16 bytes) 339 // take up too much stack-space (each one here costs 16 bytes)
397 #define TMP_COUNT 16 340 #define BUFFER_MAX 16
398 #define BUFFER_MAX ((int)(TMP_COUNT * sizeof(uint32_t)))
399 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, 341 void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y,
400 SkPMColor result[], int count) { 342 SkPMColor result[], int count) {
401 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader); 343 const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShader Impl&>(fShader);
402 344
403 uint32_t tmpColor[TMP_COUNT]; 345 SkPMColor diffuse[BUFFER_MAX];
404 SkPMColor tmpColor2[2*TMP_COUNT];
405
406 SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc();
407 SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32() ;
408
409 int max = fDiffuseState->maxCountForBufferSize(BUFFER_MAX);
410
411 SkASSERT(fDiffuseState->fPixmap.addr());
412
413 SkASSERT(max <= BUFFER_MAX);
414 SkPoint3 normals[BUFFER_MAX]; 346 SkPoint3 normals[BUFFER_MAX];
415 347
416 do { 348 do {
417 int n = count; 349 int n = SkTMin(count, BUFFER_MAX);
418 if (n > max) {
419 n = max;
420 }
421 350
422 diffMProc(*fDiffuseState, tmpColor, n, x, y); 351 fDiffuseContext->shadeSpan(x, y, diffuse, n);
423 diffSProc(*fDiffuseState, tmpColor, n, tmpColor2);
424
425 fNormalProvider->fillScanLine(x, y, normals, n); 352 fNormalProvider->fillScanLine(x, y, normals, n);
426 353
427 for (int i = 0; i < n; ++i) { 354 for (int i = 0; i < n; ++i) {
428 355
429 SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); 356 SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]);
430 357
431 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); 358 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
432 // This is all done in linear unpremul color space (each component 0 ..255.0f though) 359 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
433 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { 360 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
434 const SkLights::Light& light = lightShader.fLights->light(l); 361 const SkLights::Light& light = lightShader.fLights->light(l);
435 362
436 if (SkLights::Light::kAmbient_LightType == light.type()) { 363 if (SkLights::Light::kAmbient_LightType == light.type()) {
437 accum += light.color().makeScale(255.0f); 364 accum += light.color().makeScale(255.0f);
438 } else { 365 } else {
439 SkScalar NdotL = normals[i].dot(light.dir()); 366 SkScalar NdotL = normals[i].dot(light.dir());
(...skipping 18 matching lines...) Expand all
458 385
459 //////////////////////////////////////////////////////////////////////////// 386 ////////////////////////////////////////////////////////////////////////////
460 387
461 #ifndef SK_IGNORE_TO_STRING 388 #ifndef SK_IGNORE_TO_STRING
462 void SkLightingShaderImpl::toString(SkString* str) const { 389 void SkLightingShaderImpl::toString(SkString* str) const {
463 str->appendf("LightingShader: ()"); 390 str->appendf("LightingShader: ()");
464 } 391 }
465 #endif 392 #endif
466 393
467 sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { 394 sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) {
468 SkMatrix diffLocalM;
469 bool hasDiffLocalM = buf.readBool();
470 if (hasDiffLocalM) {
471 buf.readMatrix(&diffLocalM);
472 } else {
473 diffLocalM.reset();
474 }
475 395
476 SkBitmap diffuse; 396 // Discarding SkShader flattenable params
477 if (!buf.readBitmap(&diffuse)) { 397 bool hasLocalMatrix = buf.readBool();
478 return nullptr; 398 SkASSERT(!hasLocalMatrix);
479 }
480 diffuse.setImmutable();
481 399
482 int numLights = buf.readInt(); 400 int numLights = buf.readInt();
483 401
484 SkLights::Builder builder; 402 SkLights::Builder builder;
485 403
486 for (int l = 0; l < numLights; ++l) { 404 for (int l = 0; l < numLights; ++l) {
487 bool isAmbient = buf.readBool(); 405 bool isAmbient = buf.readBool();
488 406
489 SkColor3f color; 407 SkColor3f color;
490 if (!buf.readScalarArray(&color.fX, 3)) { 408 if (!buf.readScalarArray(&color.fX, 3)) {
491 return nullptr; 409 return nullptr;
492 } 410 }
493 411
494 if (isAmbient) { 412 if (isAmbient) {
495 builder.add(SkLights::Light(color)); 413 builder.add(SkLights::Light(color));
496 } else { 414 } else {
497 SkVector3 dir; 415 SkVector3 dir;
498 if (!buf.readScalarArray(&dir.fX, 3)) { 416 if (!buf.readScalarArray(&dir.fX, 3)) {
499 return nullptr; 417 return nullptr;
500 } 418 }
501 builder.add(SkLights::Light(color, dir)); 419 builder.add(SkLights::Light(color, dir));
502 } 420 }
503 } 421 }
504 422
505 sk_sp<SkLights> lights(builder.finish()); 423 sk_sp<SkLights> lights(builder.finish());
506 424
507 sk_sp<SkLightingShader::NormalSource> normalSource( 425 sk_sp<SkLightingShader::NormalSource> normalSource(
508 buf.readFlattenable<SkLightingShader::NormalSource>()); 426 buf.readFlattenable<SkLightingShader::NormalSource>());
427 sk_sp<SkShader> diffuseShader(buf.readFlattenable<SkShader>());
509 428
510 return sk_make_sp<SkLightingShaderImpl>(diffuse, std::move(lights), &diffLoc alM, 429 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource),
511 std::move(normalSource)); 430 std::move(lights));
512 } 431 }
513 432
514 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { 433 void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
515 this->INHERITED::flatten(buf); 434 this->INHERITED::flatten(buf);
516 435
517 buf.writeBitmap(fDiffuseMap);
518
519 buf.writeInt(fLights->numLights()); 436 buf.writeInt(fLights->numLights());
520 for (int l = 0; l < fLights->numLights(); ++l) { 437 for (int l = 0; l < fLights->numLights(); ++l) {
521 const SkLights::Light& light = fLights->light(l); 438 const SkLights::Light& light = fLights->light(l);
522 439
523 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type(); 440 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
524 441
525 buf.writeBool(isAmbient); 442 buf.writeBool(isAmbient);
526 buf.writeScalarArray(&light.color().fX, 3); 443 buf.writeScalarArray(&light.color().fX, 3);
527 if (!isAmbient) { 444 if (!isAmbient) {
528 buf.writeScalarArray(&light.dir().fX, 3); 445 buf.writeScalarArray(&light.dir().fX, 3);
529 } 446 }
530 } 447 }
531 448
532 buf.writeFlattenable(fNormalSource.get()); 449 buf.writeFlattenable(fNormalSource.get());
450 buf.writeFlattenable(fDiffuseShader.get());
533 } 451 }
534 452
535 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const { 453 size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const {
536 return sizeof(LightingShaderContext) + 454 return sizeof(LightingShaderContext);
537 sizeof(SkBitmapProcState) +
538 fNormalSource->providerSize(rec);
539 } 455 }
540 456
541 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, 457 SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
542 void* storage) const { 458 void* storage) const {
543 459
544 SkMatrix diffTotalInv; 460 size_t heapRequired = fDiffuseShader->contextSize(rec) + fNormalSource->prov iderSize(rec);
545 // computeTotalInverse was called in SkShader::createContext so we know it w ill succeed 461 void* heapAllocated = malloc(heapRequired); // Freed on ~LightingShaderConte xt()
dvonbeck 2016/06/17 16:05:51 malloc and free. Should I be using some SkMalloc o
546 SkAssertResult(this->computeTotalInverse(rec, &diffTotalInv));
547 462
548 void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); 463 void* diffuseContextStorage = (char*)heapAllocated;
549 SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcStat e(fDiffuseMap,
550 SkShader::kClamp_TileMode, SkShade r::kClamp_TileMode,
551 SkMipMap::De duceTreatment(rec));
552 SkASSERT(diffuseState);
553 if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) {
554 diffuseState->~SkBitmapProcState();
555 return nullptr;
556 }
557 void* normalProviderStorage = (char*)storage +
558 sizeof(LightingShaderContext) +
559 sizeof(SkBitmapProcState);
560 464
465 SkShader::Context* diffuseContext = fDiffuseShader->createContext(rec, diffu seContextStorage);
466
467 void* normalProviderStorage = (char*)heapAllocated + fDiffuseShader->context Size(rec);
561 SkLightingShader::NormalSource::Provider* normalProvider = 468 SkLightingShader::NormalSource::Provider* normalProvider =
562 fNormalSource->asProvider(rec, normalProviderStorage); 469 fNormalSource->asProvider(rec, normalProviderStorage);
563 if (!normalProvider) { 470 if (!normalProvider) {
564 diffuseState->~SkBitmapProcState(); 471 diffuseContext->~Context();
472 free(heapAllocated);
565 return nullptr; 473 return nullptr;
566 } 474 }
567 475
568 return new (storage) LightingShaderContext(*this, rec, diffuseState, normalP rovider); 476 return new (storage) LightingShaderContext(*this, rec, diffuseContext, norma lProvider,
477 heapAllocated);
569 } 478 }
570 479
571 /////////////////////////////////////////////////////////////////////////////// 480 ///////////////////////////////////////////////////////////////////////////////
572 481
573 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, sk_sp<SkLights> lights, 482 sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, sk_sp<SkLights> lights,
574 const SkMatrix* diffLocalM, sk_sp<NormalSource> normalSource) { 483 const SkMatrix* diffLocalM, sk_sp<NormalSource> normalSource) {
575 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse)) { 484 if (diffuse.isNull() || SkBitmapProcShader::BitmapIsTooBig(diffuse)) {
576 return nullptr; 485 return nullptr;
577 } 486 }
578 487
579 if (!normalSource) { 488 if (!normalSource) {
580 // TODO: Use a default implementation of normalSource instead 489 // TODO: Use a default implementation of normalSource instead
581 return nullptr; 490 return nullptr;
582 } 491 }
583 492
584 return sk_make_sp<SkLightingShaderImpl>(diffuse, std::move(lights), diffLoca lM, 493 // TODO: support other tile modes
585 std::move(normalSource)); 494 sk_sp<SkShader> diffuseShader = SkBitmapProcShader::MakeBitmapShader(diffuse ,
495 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, diffLocalM);
496
497 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource),
498 std::move(lights));
586 } 499 }
587 500
588 /////////////////////////////////////////////////////////////////////////////// 501 ///////////////////////////////////////////////////////////////////////////////
589 502
590 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) 503 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
591 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) 504 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
592 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 505 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
593 506
594 /////////////////////////////////////////////////////////////////////////////// 507 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « no previous file | src/core/SkLightingShader_NormalSource.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698