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

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

Issue 2118553002: adding new GM to demostrate new shadows (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Forgot to commit files. 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
« src/core/SkShadowShader.h ('K') | « src/core/SkShadowShader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
robertphillips 2016/07/26 16:15:05 2016
vjiaoblack 2016/07/27 15:26:27 Done.
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBitmapProcShader.h"
9 #include "SkBitmapProcState.h"
10 #include "SkColor.h"
11 #include "SkEmptyShader.h"
12 #include "SkErrorInternals.h"
13 #include "SkShadowShader.h"
14 #include "SkMathPriv.h"
robertphillips 2016/07/26 16:15:05 Do we need SkNormalSource.h ?
vjiaoblack 2016/07/27 15:26:27 Done.
15 #include "SkNormalSource.h"
16 #include "SkPoint3.h"
17 #include "SkReadBuffer.h"
18 #include "SkWriteBuffer.h"
19
20 ////////////////////////////////////////////////////////////////////////////
21
22 /** \class SkShadowShaderImpl
23 This subclass of shader applies shadowing
24 */
25 class SkShadowShaderImpl : public SkShader {
26 public:
27 /** Create a new shadowing shader that shadows
28 @param to do to do
29 */
30 SkShadowShaderImpl(sk_sp<SkShader> povDepthShader,
31 sk_sp<SkShader> diffuseShader,
32 sk_sp<SkLights> lights)
33 : povDepthShader(std::move(povDepthShader))
34 , diffuseShader(std::move(diffuseShader))
35 , fLights(std::move(lights)) { }
36
37 bool isOpaque() const override;
38
39 #if SK_SUPPORT_GPU
40 sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
41 const SkMatrix& viewM,
42 const SkMatrix* localMatrix,
43 SkFilterQuality,
44 SkSourceGammaTreatment) const override;
45 #endif
46
47 class ShadowShaderContext : public SkShader::Context {
48 public:
49 // The context takes ownership of the states. It will call their destruc tors
50 // but will NOT free the memory.
51 ShadowShaderContext(const SkShadowShaderImpl&, const ContextRec&,
52 SkShader::Context* povDepthContext,
53 SkShader::Context* diffuseContext,
54 void* heapAllocated);
55
56 ~ShadowShaderContext() override;
57
58 void shadeSpan(int x, int y, SkPMColor[], int count) override;
59
60 uint32_t getFlags() const override { return fFlags; }
61
62 private:
63 SkShader::Context* fDiffuseContext1;
64 SkShader::Context* fDiffuseContext2;
65 uint32_t fFlags;
66
67 void* fHeapAllocated;
68
69 typedef SkShader::Context INHERITED;
70 };
71
72 SK_TO_STRING_OVERRIDE()
robertphillips 2016/07/26 16:15:05 Tab this over ?
vjiaoblack 2016/07/27 15:26:27 Done.
73 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShadowShaderImpl)
74
75 protected:
76 void flatten(SkWriteBuffer&) const override;
77 size_t onContextSize(const ContextRec&) const override;
78 Context* onCreateContext(const ContextRec&, void*) const override;
79
80 private:
81 sk_sp<SkShader> povDepthShader;
82 sk_sp<SkShader> diffuseShader;
83 sk_sp<SkLights> fLights;
84
85 friend class SkShadowShader;
86
87 typedef SkShader INHERITED;
88 };
89
90 ////////////////////////////////////////////////////////////////////////////
91
92 #if SK_SUPPORT_GPU
93
94 #include "GrCoordTransform.h"
95 #include "GrFragmentProcessor.h"
96 #include "GrInvariantOutput.h"
97 #include "GrTextureAccess.h"
98 #include "glsl/GrGLSLFragmentProcessor.h"
99 #include "glsl/GrGLSLFragmentShaderBuilder.h"
100 #include "glsl/GrGLSLProgramDataManager.h"
101 #include "glsl/GrGLSLUniformHandler.h"
102 #include "SkGr.h"
103 #include "SkGrPriv.h"
104 #include "SkSpecialImage.h"
105 #include "SkImage_Base.h"
106 #include "SkImageInfo.h"
107 #include "GrContext.h"
108 #include "GrContextOptions.h"
109
110 class ShadowFP : public GrFragmentProcessor {
111 public:
112 ShadowFP(sk_sp<GrFragmentProcessor> povDepth,
113 sk_sp<GrFragmentProcessor> diffuse,
114 sk_sp<SkLights> lights) {
115
116 // fuse all ambient lights into a single one
117 // TODO do we support 4 directional lights, or just 4 lights?
robertphillips 2016/07/26 16:15:05 Probably any number of ambient + 4 "real" ones. M
vjiaoblack 2016/07/27 15:26:27 Done.
118 fAmbientColor.set(0.0f, 0.0f, 0.0f);
119
robertphillips 2016/07/26 16:15:05 This doesn't seem quite right. fNumLights needs to
vjiaoblack 2016/07/27 15:26:28 I'll change fNumLights to fNumDirLights.
120 fNumLights = lights->numLights(); // refers to directional lights.
robertphillips 2016/07/26 16:15:05 You probably can't have this assert but keep a sep
vjiaoblack 2016/07/27 15:26:27 Done.
121 SkASSERT(fNumLights <= 4 && fNumLights >= 0);
122 for (int i = 0; i < lights->numLights(); ++i) {
123 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) {
124 fAmbientColor += lights->light(i).color();
125 } else {
126 fLightColor[i] = lights->light(i).color();
127 fLightDir[i] = lights->light(i).dir();
128 fDepthMapAccess[i].reset(((SkImage_Base*)lights->light(i).getSha dowMap().get())->
jvanverth1 2016/07/26 15:01:25 You might want to break this line up -- it's a lit
vjiaoblack 2016/07/27 15:26:28 Done.
129 asTextureRef(GrContext::Create(kOpenGL_GrBackend, (GrBac kendContext) nullptr, GrContextOptions()),
jvanverth1 2016/07/26 15:01:24 Lines too long (must be <= 100 chars)
vjiaoblack 2016/07/27 15:26:28 Done.
130 GrTextureParams::ClampNoFilter(), SkSourceG ammaTreatment::kIgnore));
131 this->addTextureAccess(&fDepthMapAccess[i]);
132 // // TODO: Call unref on the GrTexture somewhere.
jvanverth1 2016/07/26 15:01:25 Is this still needed? Otherwise you have a memory
vjiaoblack 2016/07/27 15:26:28 Hm. I'm trying to fix this (and it seems like a pr
133 }
134 }
135
136 this->registerChildProcessor(std::move(povDepth));
137 this->registerChildProcessor(std::move(diffuse));
138 this->initClassID<ShadowFP>();
139 }
140
141 class GLSLShadowFP : public GrGLSLFragmentProcessor {
142 public:
143 GLSLShadowFP() { }
144
145 void emitCode(EmitArgs& args) override {
146
147 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
148 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
149
150 // add uniforms
151 int32_t numLights = args.fFp.cast<ShadowFP>().fNumLights;
152
153 const char* lightDirUniName[4] = {nullptr};
154 const char* lightColorUniName[4] = {nullptr};
155
156 for (int i = 0; i < numLights; i++) {
157 lightDirUniName[i] = nullptr;
158 fLightDirUni[i] = uniformHandler->addUniform(kFragment_GrShaderF lag,
159 kVec3f_GrSLType, kDef ault_GrSLPrecision,
jvanverth1 2016/07/26 15:01:25 Line up indents next to parens.
vjiaoblack 2016/07/27 15:26:28 Done.
160 "LightDir" + (i+1), & lightDirUniName[i]);
161
162 lightColorUniName[i] = nullptr;
163 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag,
164 kVec3f_GrSLType, kD efault_GrSLPrecision,
jvanverth1 2016/07/26 15:01:24 Lines too long.
vjiaoblack 2016/07/27 15:26:28 Done.
165 "LightColor" + (i+1 ), &lightColorUniName[i]);
166 }
167
168 SkString povDepth("povDepth");
169 this->emitChild(0, nullptr, &povDepth, args);
170
171 SkString diffuseColor("inDiffuseColor");
172 this->emitChild(1, nullptr, &diffuseColor, args);
173
174 SkString depthMaps[4];
175
176 for (int i = 0; i < numLights; i++) {
177 const char* povCoord = "povCoord" + i;
178
179 fragBuilder->codeAppendf("vec2 %s = vMatrixCoord_0_1_Stage0 + (v ec2(%s) * povDepth.b * 255 / 400);",
jvanverth1 2016/07/26 15:01:25 Line too long. Also, it's not clear to me what thi
vjiaoblack 2016/07/27 15:26:28 Done.
180 povCoord, lightDirUniName[i]);
181
182 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i],
183 povCoord,
184 kVec2f_GrSLType);
185 }
186
187 const char* ambientColorUniName = nullptr;
188 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag ,
189 kVec3f_GrSLType, kDefa ult_GrSLPrecision,
190 "AmbientColor", &ambie ntColorUniName);
191
192 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str());
193
194 // all the normal vectors point straight up
195 SkString totalLightColor("totalLightColor");
196 fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c _str());
197
198 for (int i = 0; i < numLights; i++) {
199 fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
200 povDepth.c_str(), depthMaps[i].c_str()) ;
201 fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s;", tot alLightColor.c_str(),
jvanverth1 2016/07/26 15:01:24 Line too long.
vjiaoblack 2016/07/27 15:26:28 Done.
202 lightDirUniName[i], lightColorUniName[i ]);
203 fragBuilder->codeAppendf("}");
204 }
205
206
207 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie ntColorUniName);
208 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", total LightColor.c_str());
209
210 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or);
211 }
212
213 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
214 GrProcessorKeyBuilder* b) {
215 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
216 b->add32(shadowFP.fNumLights);
217 }
218
219 protected:
220 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
221 const ShadowFP &shadowFP = proc.cast<ShadowFP>();
222
robertphillips 2016/07/26 16:15:05 We set fNumLights in the ctor. Is it correct to re
vjiaoblack 2016/07/27 15:26:28 We set fNumLights in the ShadowFP constructor. We
223 fNumLights = shadowFP.numLights();
224
225 SkASSERT(fNumLights <= 4);
226
227 for (int i = 0; i < fNumLights; i++) {
robertphillips 2016/07/26 16:15:05 Do we need the "1" suffixes?
vjiaoblack 2016/07/27 15:26:28 Done.
228 const SkVector3 &lightDir1 = shadowFP.lightDir(i);
229 if (lightDir1 != fLightDir[i]) {
230 pdman.set3fv(fLightDirUni[i], 1, &lightDir1.fX);
231 fLightDir[i] = lightDir1;
232 }
233 const SkColor3f &lightColor1 = shadowFP.lightColor(i);
234 if (lightColor1 != fLightColor[i]) {
235 pdman.set3fv(fLightColorUni[i], 1, &lightColor1.fX);
236 fLightColor[i] = lightColor1;
237 }
238 }
239
240 const SkColor3f& ambientColor = shadowFP.ambientColor();
241 if (ambientColor != fAmbientColor) {
242 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
243 fAmbientColor = ambientColor;
244 }
245 }
246
247 private:
248 SkVector3 fLightDir[4];
249 GrGLSLProgramDataManager::UniformHandle fLightDirUni[4];
250 SkColor3f fLightColor[4];
251 GrGLSLProgramDataManager::UniformHandle fLightColorUni[4];
252
253 SkColor3f fAmbientColor;
254 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
255
robertphillips 2016/07/26 16:15:05 can this just be an int?
vjiaoblack 2016/07/27 15:26:27 Done.
256 int32_t fNumLights;
257 };
258
259 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
260 GLSLShadowFP::GenKey(*this, caps, b);
261 }
262
263 const char* name() const override { return "shadowFP"; }
264
265 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
266 inout->mulByUnknownFourComponents();
267 }
268 int32_t numLights() const { return fNumLights; }
269 const SkColor3f& ambientColor() const { return fAmbientColor; }
270 const SkVector3& lightDir(int i) const {
271 SkASSERT(i < fNumLights);
272 return fLightDir[i];
273 }
274 const SkVector3& lightColor(int i) const {
275 SkASSERT(i < fNumLights);
276 return fLightColor[i];
277 }
278
279 private:
280 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; }
281
282 bool onIsEqual(const GrFragmentProcessor& proc) const override {
283 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
robertphillips 2016/07/26 16:15:05 Shouldn't we check if the number of lights is the
vjiaoblack 2016/07/27 15:26:27 Done.
284 return fLightDir[0] == shadowFP.fLightDir[0] &&
285 fLightColor[0] == shadowFP.fLightColor[0] &&
286 fLightDir[1] == shadowFP.fLightDir[1] &&
287 fLightColor[1] == shadowFP.fLightColor[1] &&
288 fLightDir[2] == shadowFP.fLightDir[2] &&
289 fLightColor[2] == shadowFP.fLightColor[2] &&
290 fLightDir[3] == shadowFP.fLightDir[3] &&
291 fLightColor[3] == shadowFP.fLightColor[3] &&
292 fAmbientColor == shadowFP.fAmbientColor;
293 }
294
robertphillips 2016/07/26 16:15:05 line this guy up with the rest ?
vjiaoblack 2016/07/27 15:26:27 Done.
295 int fNumLights;
296
297 SkVector3 fLightDir[4];
298 SkColor3f fLightColor[4];
299 GrTextureAccess fDepthMapAccess[4];
300
301 SkColor3f fAmbientColor;
302 };
303
304 ////////////////////////////////////////////////////////////////////////////
305
306 sk_sp<GrFragmentProcessor> SkShadowShaderImpl::asFragmentProcessor(
307 GrContext* context,
308 const SkMatrix& viewM,
309 const SkMatrix* localMatrix,
310 SkFilterQuality filterQuality,
311 SkSourceGammaTreatment gammaTreatment) const {
312
robertphillips 2016/07/26 16:15:05 I'm not in love with the D_FP* names
vjiaoblack 2016/07/27 15:26:28 Done.
313 sk_sp<GrFragmentProcessor> D_FP1 = povDepthShader->asFragmentProcessor(conte xt, viewM,
314 localMatrix, filterQuality,
315 gammaTreatme nt);
316
317 sk_sp<GrFragmentProcessor> D_FP2 = diffuseShader->asFragmentProcessor(contex t, viewM,
318 loca lMatrix, filterQuality,
jvanverth1 2016/07/26 15:01:25 Line too long.
vjiaoblack 2016/07/27 15:26:27 Done.
319 gamm aTreatment);
320
321 sk_sp<GrFragmentProcessor> shadowfp = sk_make_sp<ShadowFP>(D_FP1, D_FP2, fLi ghts);
322 return shadowfp;
323 }
324
325
326 #endif
327
328 ////////////////////////////////////////////////////////////////////////////
329
330 bool SkShadowShaderImpl::isOpaque() const {
331 return povDepthShader->isOpaque() || diffuseShader->isOpaque();
332 }
333
334 SkShadowShaderImpl::ShadowShaderContext::ShadowShaderContext(
335 const SkShadowShaderImpl& shader, const ContextRec& rec,
336 SkShader::Context* povDepthContext,
337 SkShader::Context* diffuseContext,
338 void* heapAllocated)
339 : INHERITED(shader, rec)
340 , fDiffuseContext1(povDepthContext)
341 , fDiffuseContext2(diffuseContext)
342 , fHeapAllocated(heapAllocated) {
343 bool isOpaque = shader.isOpaque();
344
345 // update fFlags
346 uint32_t flags = 0;
347 if (isOpaque && (255 == this->getPaintAlpha())) {
348 flags |= kOpaqueAlpha_Flag;
349 }
350
351 fFlags = flags;
352 }
353
354 SkShadowShaderImpl::ShadowShaderContext::~ShadowShaderContext() {
355 // The dependencies have been created outside of the context on memory that was allocated by
356 // the onCreateContext() method. Call the destructors and free the memory.
357 fDiffuseContext1->~Context();
358 fDiffuseContext2->~Context();
359
360 sk_free(fHeapAllocated);
361 }
362
363 static inline SkPMColor convert(SkColor3f color, U8CPU a) {
364 if (color.fX <= 0.0f) {
365 color.fX = 0.0f;
366 } else if (color.fX >= 255.0f) {
367 color.fX = 255.0f;
368 }
369
370 if (color.fY <= 0.0f) {
371 color.fY = 0.0f;
372 } else if (color.fY >= 255.0f) {
373 color.fY = 255.0f;
374 }
375
376 if (color.fZ <= 0.0f) {
377 color.fZ = 0.0f;
378 } else if (color.fZ >= 255.0f) {
379 color.fZ = 255.0f;
380 }
381 // printf();
382 return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ) ;
383 }
384
385 // larger is better (fewer times we have to loop), but we shouldn't
386 // take up too much stack-space (each one here costs 16 bytes)
387 #define BUFFER_MAX 16
388 void SkShadowShaderImpl::ShadowShaderContext::shadeSpan(int x, int y,
389 SkPMColor result[], int count) {
390 const SkShadowShaderImpl& lightShader = static_cast<const SkShadowShaderImpl &>(fShader);
391
392 SkPMColor diffuse[BUFFER_MAX];
393 SkPoint3 normals[BUFFER_MAX];
394
395 do {
396 int n = SkTMin(count, BUFFER_MAX);
397
398 fDiffuseContext1->shadeSpan(x, y, diffuse, n);
399 fDiffuseContext2->shadeSpan(x, y, diffuse, n);
400
401 for (int i = 0; i < n; ++i) {
402
403 SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]);
404
405 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
406 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
407 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
408 const SkLights::Light& light = lightShader.fLights->light(l);
409
410 if (SkLights::Light::kAmbient_LightType == light.type()) {
411 accum += light.color().makeScale(255.0f);
412 } else {
413 SkScalar NdotL = normals[i].dot(light.dir());
414 if (NdotL < 0.0f) {
415 NdotL = 0.0f;
416 }
417
418 NdotL = 1.0f;
419
420 accum.fX += light.color().fX * SkColorGetR(diffColor) * Ndot L;
421 accum.fY += light.color().fY * SkColorGetG(diffColor) * Ndot L;
422 accum.fZ += light.color().fZ * SkColorGetB(diffColor) * Ndot L;
423 }
424 }
425
426 result[i] = convert(accum, SkColorGetA(diffColor));
427 }
428
429 result += n;
430 x += n;
431 count -= n;
432 } while (count > 0);
433 }
434
435 ////////////////////////////////////////////////////////////////////////////
436
437 #ifndef SK_IGNORE_TO_STRING
438 void SkShadowShaderImpl::toString(SkString* str) const {
439 str->appendf("ShadowShader: ()");
440 }
441 #endif
442
443 sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) {
444
445 // Discarding SkShader flattenable params
446 bool hasLocalMatrix = buf.readBool();
447 SkAssertResult(!hasLocalMatrix);
448
449 int numLights = buf.readInt();
450
451 SkLights::Builder builder;
452
453 for (int l = 0; l < numLights; ++l) {
454 bool isAmbient = buf.readBool();
455
456 SkColor3f color;
457 if (!buf.readScalarArray(&color.fX, 3)) {
458 return nullptr;
459 }
460
461 if (isAmbient) {
462 builder.add(SkLights::Light(color));
463 } else {
464 SkVector3 dir;
465 if (!buf.readScalarArray(&dir.fX, 3)) {
466 return nullptr;
467 }
468 builder.add(SkLights::Light(color, dir));
469 }
470 }
471
472 sk_sp<SkLights> lights(builder.finish());
473
474 sk_sp<SkShader> povDepthShader(buf.readFlattenable<SkShader>());
475 sk_sp<SkShader> diffuseShader(buf.readFlattenable<SkShader>());
476
477 return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader),
478 std::move(diffuseShader),
479 std::move(lights));
480 }
481
482 void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const {
483 this->INHERITED::flatten(buf);
484
485 buf.writeInt(fLights->numLights());
486 for (int l = 0; l < fLights->numLights(); ++l) {
487 const SkLights::Light& light = fLights->light(l);
488
489 bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
490
491 buf.writeBool(isAmbient);
492 buf.writeScalarArray(&light.color().fX, 3);
493 if (!isAmbient) {
494 buf.writeScalarArray(&light.dir().fX, 3);
495 }
496 }
497
498 buf.writeFlattenable(povDepthShader.get());
499 buf.writeFlattenable(diffuseShader.get());
500 }
501
502 size_t SkShadowShaderImpl::onContextSize(const ContextRec& rec) const {
503 return sizeof(ShadowShaderContext);
504 }
505
506 SkShader::Context* SkShadowShaderImpl::onCreateContext(const ContextRec& rec,
507 void* storage) const {
508 size_t heapRequired = povDepthShader->contextSize(rec) +
509 diffuseShader->contextSize(rec);
510
511 void* heapAllocated = sk_malloc_throw(heapRequired);
512
513 void* povDepthContextStorage = heapAllocated;
514
515 SkShader::Context* povDepthContext = povDepthShader->createContext(rec, povD epthContextStorage);
516 if (!povDepthContext) {
517 sk_free(heapAllocated);
518 return nullptr;
519 }
520
521 void* diffuseContextStorage = (char*)heapAllocated + povDepthShader->context Size(rec);
522
523 SkShader::Context* diffuseContext2 = diffuseShader->createContext(rec, diffu seContextStorage);
524 if (!diffuseContext2) {
525 sk_free(heapAllocated);
526 return nullptr;
527 }
528
529
530 return new (storage) ShadowShaderContext(*this, rec, povDepthContext, diffus eContext2,
531 heapAllocated);
532 }
533
534 ///////////////////////////////////////////////////////////////////////////////
535
536 sk_sp<SkShader> SkShadowShader::Make(sk_sp<SkShader> povDepthShader,
537 sk_sp<SkShader> diffuseShader,
538 sk_sp<SkLights> lights) {
539 if (!povDepthShader || !diffuseShader) {
540 // TODO: Use paint's color in absence of a diffuseShader
541 // TODO: Use a default implementation of normalSource instead
542 return nullptr;
543 }
544
545 SkASSERT(lights->numLights() <= 4);
546
547 return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader),
548 std::move(diffuseShader),
549 std::move(lights));
550 }
551
552 ///////////////////////////////////////////////////////////////////////////////
553
554 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader)
555 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl)
556 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
557
558 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« src/core/SkShadowShader.h ('K') | « src/core/SkShadowShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698