diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkCanvas.cpp | 49 | ||||
-rw-r--r-- | src/core/SkLiteDL.cpp | 13 | ||||
-rw-r--r-- | src/core/SkLiteDL.h | 3 | ||||
-rw-r--r-- | src/core/SkLiteRecorder.cpp | 5 | ||||
-rw-r--r-- | src/core/SkLiteRecorder.h | 6 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 4 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 10 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 2 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 9 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 6 | ||||
-rw-r--r-- | src/core/SkShadowShader.cpp | 141 | ||||
-rw-r--r-- | src/core/SkShadowShader.h | 3 |
12 files changed, 181 insertions, 70 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 8f77afe78e..0b14368b6e 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -38,13 +38,13 @@ #include "SkTextFormatParams.h" #include "SkTLazy.h" #include "SkTraceEvent.h" - #include <new> #if SK_SUPPORT_GPU #include "GrContext.h" #include "GrRenderTarget.h" #include "SkGrPriv.h" + #endif #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) @@ -3163,17 +3163,19 @@ void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, #ifdef SK_EXPERIMENTAL_SHADOWING void SkCanvas::drawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint) { + const SkPaint* paint, + const SkShadowParams& params) { RETURN_ON_NULL(picture); TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); - this->onDrawShadowedPicture(picture, matrix, paint); + this->onDrawShadowedPicture(picture, matrix, paint, params); } void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint) { + const SkPaint* paint, + const SkShadowParams& params) { if (!paint || paint->canComputeFastBounds()) { SkRect bounds = picture->cullRect(); if (paint) { @@ -3189,6 +3191,11 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); + sk_sp<SkImage> povDepthMap; + sk_sp<SkImage> diffuseMap; + + // TODO: pass the depth to the shader in vertices, or uniforms + // so we don't have to render depth and color separately for (int i = 0; i < fLights->numLights(); ++i) { // skip over ambient lights; they don't cast shadows // lights that have shadow maps do not need updating (because lights are immutable) @@ -3217,23 +3224,36 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, // Wrap another SPFCanvas around the surface sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); + depthMapCanvas->setShadowParams(params); // set the depth map canvas to have the light we're drawing. SkLights::Builder builder; builder.add(fLights->light(i)); sk_sp<SkLights> curLight = builder.finish(); - depthMapCanvas->setLights(std::move(curLight)); + depthMapCanvas->drawPicture(picture); + sk_sp<SkImage> depthMap = surf->makeImageSnapshot(); - fLights->light(i).setShadowMap(surf->makeImageSnapshot()); - } + if (params.fType == SkShadowParams::kNoBlur_ShadowType) { + fLights->light(i).setShadowMap(std::move(depthMap)); + } else if (params.fType == SkShadowParams::kVariance_ShadowType) { + // we blur the variance map + SkPaint blurPaint; + blurPaint.setImageFilter(SkImageFilter::MakeBlur(params.fShadowRadius, + params.fShadowRadius, nullptr)); - sk_sp<SkImage> povDepthMap; - sk_sp<SkImage> diffuseMap; + SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, + kBGRA_8888_SkColorType, + kOpaque_SkAlphaType); - // TODO: pass the depth to the shader in vertices, or uniforms - // so we don't have to render depth and color separately + sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); + + blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); + + fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); + } + } // povDepthMap { @@ -3259,7 +3279,6 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, depthMapCanvas->setLights(std::move(povLight)); depthMapCanvas->drawPicture(picture); - povDepthMap = surf->makeImageSnapshot(); } @@ -3275,20 +3294,18 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, diffuseMap = surf->makeImageSnapshot(); } - SkPaint shadowPaint; sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); - sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); - sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader), std::move(diffuseShader), std::move(fLights), diffuseMap->width(), - diffuseMap->height()); + diffuseMap->height(), + params); shadowPaint.setShader(shadowShader); diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp index f7fe578c4e..d94e1399d6 100644 --- a/src/core/SkLiteDL.cpp +++ b/src/core/SkLiteDL.cpp @@ -270,17 +270,20 @@ namespace { }; struct DrawShadowedPicture final : Op { static const auto kType = Type::DrawShadowedPicture; - DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) + DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, + const SkPaint* paint, const SkShadowParams& params) : picture(sk_ref_sp(picture)) { if (matrix) { this->matrix = *matrix; } if (paint) { this->paint = *paint; } + this->params = params; } sk_sp<const SkPicture> picture; SkMatrix matrix = SkMatrix::I(); SkPaint paint; + SkShadowParams params; void draw(SkCanvas* c, const SkMatrix&) { #ifdef SK_EXPERIMENTAL_SHADOWING - c->drawShadowedPicture(picture.get(), &matrix, &paint); + c->drawShadowedPicture(picture.get(), &matrix, &paint, params); #endif } void makeThreadsafe() { make_threadsafe(nullptr, &matrix); } @@ -615,9 +618,9 @@ void SkLiteDL::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { this->push<DrawPicture>(0, picture, matrix, paint); } -void SkLiteDL::drawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, const SkPaint* paint) { - this->push<DrawShadowedPicture>(0, picture, matrix, paint); +void SkLiteDL::drawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, + const SkPaint* paint, const SkShadowParams& params) { + push<DrawShadowedPicture>(0, picture, matrix, paint, params); } void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) { diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h index 400b242322..4f28486840 100644 --- a/src/core/SkLiteDL.h +++ b/src/core/SkLiteDL.h @@ -48,7 +48,8 @@ public: void drawAnnotation (const SkRect&, const char*, SkData*); void drawDrawable (SkDrawable*, const SkMatrix*); void drawPicture (const SkPicture*, const SkMatrix*, const SkPaint*); - void drawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*); + void drawShadowedPicture(const SkPicture*, const SkMatrix*, + const SkPaint*, const SkShadowParams& params); void drawText (const void*, size_t, SkScalar, SkScalar, const SkPaint&); void drawPosText (const void*, size_t, const SkPoint[], const SkPaint&); diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp index 3b3c24cf5c..42218acd93 100644 --- a/src/core/SkLiteRecorder.cpp +++ b/src/core/SkLiteRecorder.cpp @@ -189,6 +189,7 @@ void SkLiteRecorder::didTranslateZ(SkScalar dz) { } void SkLiteRecorder::onDrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint) { - fDL->drawShadowedPicture(picture, matrix, paint); + const SkPaint* paint, + const SkShadowParams& params) { + fDL->drawShadowedPicture(picture, matrix, paint, params); } diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h index e2d754d30d..c4e80cd246 100644 --- a/src/core/SkLiteRecorder.h +++ b/src/core/SkLiteRecorder.h @@ -76,10 +76,12 @@ public: #ifdef SK_EXPERIMENTAL_SHADOWING void didTranslateZ(SkScalar) override; - void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; + void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, + const SkPaint*, const SkShadowParams& params) override; #else void didTranslateZ(SkScalar); - void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*); + void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, + const SkPaint*, const SkShadowParams& params); #endif private: diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 2140795b3d..c461bfbbac 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -666,11 +666,13 @@ void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* ma void SkPictureRecord::onDrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint) { + const SkPaint* paint, + const SkShadowParams& params) { // op + picture index size_t size = 2 * kUInt32Size; size_t initialOffset; + // TODO: handle recording params. if (nullptr == matrix && nullptr == paint) { initialOffset = this->addDraw(DRAW_PICTURE, &size); this->addPicture(picture); diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index 610e6d1c4c..5601d2ac08 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -212,13 +212,11 @@ protected: void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; #ifdef SK_EXPERIMENTAL_SHADOWING - void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*) override; + void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, + const SkPaint*, const SkShadowParams& params) override; #else - void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*); + void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, + const SkPaint*, const SkShadowParams& params); #endif void onDrawDrawable(SkDrawable*, const SkMatrix*) override; diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 2b7b9726bd..5b4bc6af6c 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -118,7 +118,7 @@ DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.xmode, r.paint)); DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint)); #ifdef SK_EXPERIMENTAL_SHADOWING -DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture.get(), &r.matrix, r.paint)); +DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture.get(), &r.matrix, r.paint, r.params)); #else template <> void Draw::draw(const DrawShadowedPicture& r) { } #endif diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index caa9bb58c3..214b075ce7 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -303,15 +303,16 @@ void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con } } -void SkRecorder::onDrawShadowedPicture(const SkPicture* pic, - const SkMatrix* matrix, - const SkPaint* paint) { +void SkRecorder::onDrawShadowedPicture(const SkPicture* pic, const SkMatrix* matrix, + const SkPaint* paint, const SkShadowParams& params) { if (fDrawPictureMode == Record_DrawPictureMode) { fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic); APPEND(DrawShadowedPicture, this->copy(paint), sk_ref_sp(pic), - matrix ? *matrix : SkMatrix::I()); + matrix ? *matrix : SkMatrix::I(), + params); } else { + // TODO update pic->playback(this) to draw the shadowed pic SkASSERT(fDrawPictureMode == Playback_DrawPictureMode); SkAutoCanvasMatrixPaint acmp(this, matrix, paint, pic->cullRect()); pic->playback(this); diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 9f8824f85a..6892894927 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -141,11 +141,13 @@ public: #ifdef SK_EXPERIMENTAL_SHADOWING void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*) override; + const SkPaint*, + const SkShadowParams& params) override; #else void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*); + const SkPaint*, + const SkShadowParams& params); #endif void onDrawAnnotation(const SkRect&, const char[], SkData*) override; diff --git a/src/core/SkShadowShader.cpp b/src/core/SkShadowShader.cpp index 804258321a..9ad23b7c17 100644 --- a/src/core/SkShadowShader.cpp +++ b/src/core/SkShadowShader.cpp @@ -5,11 +5,9 @@ * found in the LICENSE file. */ - -#include "SkLights.h" +#include "SkCanvas.h" #include "SkReadBuffer.h" #include "SkShadowShader.h" -#include "SkPoint3.h" //////////////////////////////////////////////////////////////////////////// #ifdef SK_EXPERIMENTAL_SHADOWING @@ -26,12 +24,14 @@ public: SkShadowShaderImpl(sk_sp<SkShader> povDepthShader, sk_sp<SkShader> diffuseShader, sk_sp<SkLights> lights, - int diffuseWidth, int diffuseHeight) + int diffuseWidth, int diffuseHeight, + const SkShadowParams& params) : fPovDepthShader(std::move(povDepthShader)) , fDiffuseShader(std::move(diffuseShader)) , fLights(std::move(lights)) , fDiffuseWidth(diffuseWidth) - , fDiffuseHeight(diffuseHeight) { } + , fDiffuseHeight(diffuseHeight) + , fShadowParams(params) { } bool isOpaque() const override; @@ -80,6 +80,8 @@ private: int fDiffuseWidth; int fDiffuseHeight; + SkShadowParams fShadowParams; + friend class SkShadowShader; typedef SkShader INHERITED; @@ -106,6 +108,7 @@ public: sk_sp<GrFragmentProcessor> diffuse, sk_sp<SkLights> lights, int diffuseWidth, int diffuseHeight, + const SkShadowParams& params, GrContext* context) { // fuse all ambient lights into a single one @@ -137,7 +140,9 @@ public: fWidth = diffuseWidth; fHeight = diffuseHeight; - this->registerChildProcessor(std::move(povDepth)); + fShadowParams = params; + + this->registerChildProcessor(std::move(povDepth)); this->registerChildProcessor(std::move(diffuse)); this->initClassID<ShadowFP>(); } @@ -155,6 +160,8 @@ public: int32_t numLights = args.fFp.cast<ShadowFP>().fNumDirLights; SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); + int blurAlgorithm = args.fFp.cast<ShadowFP>().fShadowParams.fType; + const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; @@ -203,6 +210,17 @@ public: &depthMapHeightUniName[i]); } + const char* shBiasUniName = nullptr; + const char* minVarianceUniName = nullptr; + + fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderFlag, + kFloat_GrSLType, + kDefault_GrSLPrecision, + "shadowBias", &shBiasUniName); + fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag, + kFloat_GrSLType, + kDefault_GrSLPrecision, + "minVariance", &minVarianceUniName); const char* widthUniName = nullptr; const char* heightUniName = nullptr; @@ -254,17 +272,17 @@ public: fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n", scaleOffsetVec.c_str(), scaleVec.c_str()); - fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + " - "vec2(%s.x, 0 - %s.y)) " - " * %s + vec2(0,1) * %s;\n", - + "vec2(%s.x, 0 - %s.y)) " + " * %s + vec2(0,1) * %s;\n", povCoord.c_str(), offset.c_str(), offset.c_str(), scaleVec.c_str(), scaleOffsetVec.c_str()); fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSamplers[i], povCoord.c_str(), kVec2f_GrSLType); + + } const char* ambientColorUniName = nullptr; @@ -274,25 +292,58 @@ public: fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseColor.c_str()); - // Essentially, - // diffColor * (ambientLightTot + foreachDirLight(lightColor * (N . L))) SkString totalLightColor("totalLightColor"); - fragBuilder->codeAppendf("vec3 %s = vec3(0);", totalLightColor.c_str()); + fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c_str()); + + fragBuilder->codeAppendf("float lightProbability;"); + fragBuilder->codeAppendf("float variance;"); + fragBuilder->codeAppendf("float d;"); for (int i = 0; i < numLights; i++) { - fragBuilder->codeAppendf("if (%s.b >= %s.b) {", + fragBuilder->codeAppendf("lightProbability = 1;"); + + // 1/512 is less than half a pixel; imperceptible + fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {", povDepth.c_str(), depthMaps[i].c_str()); - // Note that dot(vec3(0,0,1), %s) == %s.z * %s - fragBuilder->codeAppendf("%s += %s.z * %s;", + if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { + fragBuilder->codeAppendf("vec2 moments = vec2(%s.b * 255, %s.g * 255 * 256 );", + depthMaps[i].c_str(), depthMaps[i].c_str()); + + // variance biasing lessens light bleeding + fragBuilder->codeAppendf("variance = max(moments.y - (moments.x * moments.x)," + "%s);", minVarianceUniName); + + fragBuilder->codeAppendf("d = (%s.b * 255) - moments.x;", povDepth.c_str()); + fragBuilder->codeAppendf("lightProbability = " + "(variance / (variance + d * d));"); + + SkString clamp("clamp"); + clamp.appendf("%d", i); + + // choosing between light artifacts or correct shape shadows + // linstep + fragBuilder->codeAppendf("float %s = clamp((lightProbability - %s) /" + "(1 - %s), 0, 1);", + clamp.c_str(), shBiasUniName, shBiasUniName); + + fragBuilder->codeAppendf("lightProbability = %s;", clamp.c_str()); + } else { + fragBuilder->codeAppendf("if (%s.b >= %s.b) {", + povDepth.c_str(), depthMaps[i].c_str()); + fragBuilder->codeAppendf("lightProbability = 1;"); + fragBuilder->codeAppendf("} else { lightProbability = 0; }"); + } + + // VSM: The curved shadows near plane edges are mostly light bleeding. + fragBuilder->codeAppendf("}"); + + fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * lightProbability;", totalLightColor.c_str(), lightDirUniName[i], lightColorUniName[i]); - fragBuilder->codeAppendf("}"); } - fragBuilder->codeAppendf("%s += %s;", - totalLightColor.c_str(), - ambientColorUniName); + fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambientColorUniName); fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", totalLightColor.c_str()); @@ -304,15 +355,14 @@ public: GrProcessorKeyBuilder* b) { const ShadowFP& shadowFP = proc.cast<ShadowFP>(); b->add32(shadowFP.fNumDirLights); + b->add32(shadowFP.fShadowParams.fType); } protected: void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { const ShadowFP &shadowFP = proc.cast<ShadowFP>(); - fNumDirLights = shadowFP.numLights(); - - for (int i = 0; i < fNumDirLights; i++) { + for (int i = 0; i < shadowFP.fNumDirLights; i++) { const SkVector3& lightDir = shadowFP.lightDir(i); if (lightDir != fLightDir[i]) { pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX); @@ -336,6 +386,18 @@ public: } } + SkScalar biasingConstant = shadowFP.shadowParams().fBiasingConstant; + if (biasingConstant != fBiasingConstant) { + pdman.set1f(fBiasingConstantUni, biasingConstant); + fBiasingConstant = biasingConstant; + } + + SkScalar minVariance = shadowFP.shadowParams().fMinVariance; + if (minVariance != fMinVariance) { + pdman.set1f(fMinVarianceUni, minVariance); + fMinVariance = minVariance; + } + int width = shadowFP.width(); if (width != fWidth) { pdman.set1i(fWidthUni, width); @@ -376,10 +438,13 @@ public: int fHeight; GrGLSLProgramDataManager::UniformHandle fHeightUni; + SkScalar fBiasingConstant; + GrGLSLProgramDataManager::UniformHandle fBiasingConstantUni; + SkScalar fMinVariance; + GrGLSLProgramDataManager::UniformHandle fMinVarianceUni; + SkColor3f fAmbientColor; GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; - - int fNumDirLights; }; void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { @@ -413,6 +478,8 @@ public: int width() const {return fWidth; } int height() const {return fHeight; } + const SkShadowParams& shadowParams() const {return fShadowParams; } + private: GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; } @@ -454,6 +521,8 @@ private: int fHeight; int fWidth; + SkShadowParams fShadowParams; + SkColor3f fAmbientColor; }; @@ -469,7 +538,7 @@ sk_sp<GrFragmentProcessor> SkShadowShaderImpl::asFragmentProcessor(const AsFPArg std::move(diffuseFP), std::move(fLights), fDiffuseWidth, fDiffuseHeight, - fpargs.fContext); + fShadowParams, fpargs.fContext); return shadowfp; } @@ -594,6 +663,12 @@ sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) { sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf); + SkShadowParams params; + params.fMinVariance = buf.readScalar(); + params.fBiasingConstant = buf.readScalar(); + params.fType = (SkShadowParams::ShadowType) buf.readInt(); + params.fShadowRadius = buf.readScalar(); + int diffuseWidth = buf.readInt(); int diffuseHeight = buf.readInt(); @@ -603,7 +678,8 @@ sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) { return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader), std::move(diffuseShader), std::move(lights), - diffuseWidth, diffuseHeight); + diffuseWidth, diffuseHeight, + params); } void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const { @@ -611,6 +687,11 @@ void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const { fLights->flatten(buf); + buf.writeScalar(fShadowParams.fMinVariance); + buf.writeScalar(fShadowParams.fBiasingConstant); + buf.writeInt(fShadowParams.fType); + buf.writeScalar(fShadowParams.fShadowRadius); + buf.writeInt(fDiffuseWidth); buf.writeInt(fDiffuseHeight); @@ -656,7 +737,8 @@ SkShader::Context* SkShadowShaderImpl::onCreateContext(const ContextRec& rec, sk_sp<SkShader> SkShadowShader::Make(sk_sp<SkShader> povDepthShader, sk_sp<SkShader> diffuseShader, sk_sp<SkLights> lights, - int diffuseWidth, int diffuseHeight) { + int diffuseWidth, int diffuseHeight, + const SkShadowParams& params) { if (!povDepthShader || !diffuseShader) { // TODO: Use paint's color in absence of a diffuseShader // TODO: Use a default implementation of normalSource instead @@ -666,7 +748,8 @@ sk_sp<SkShader> SkShadowShader::Make(sk_sp<SkShader> povDepthShader, return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader), std::move(diffuseShader), std::move(lights), - diffuseWidth, diffuseHeight); + diffuseWidth, diffuseHeight, + params); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkShadowShader.h b/src/core/SkShadowShader.h index 163d58acd7..3263950a93 100644 --- a/src/core/SkShadowShader.h +++ b/src/core/SkShadowShader.h @@ -23,7 +23,8 @@ public: static sk_sp<SkShader> Make(sk_sp<SkShader> povDepthShader, sk_sp<SkShader> diffuseShader, sk_sp<SkLights> lights, - int diffuseWidth, int diffuseHeight); + int diffuseWidth, int diffuseHeight, + const SkShadowParams& params); // The shadow shader supports any number of ambient lights, but only // 4 non-ambient lights (currently just refers to directional lights). |