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

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

Powered by Google App Engine
This is Rietveld 408576698