Index: src/core/SkCanvas.cpp |
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
index a543a5cc5b667ada6e2241e58d49dead7b97ca51..6e898fa1bbb73fdae8b73e7b4241979cf6376b3c 100644 |
--- a/src/core/SkCanvas.cpp |
+++ b/src/core/SkCanvas.cpp |
@@ -26,6 +26,7 @@ |
#include "SkPaintPriv.h" |
#include "SkPatchUtils.h" |
#include "SkPicture.h" |
+#include "SkRadialShadowMapShader.h" |
#include "SkRasterClip.h" |
#include "SkReadPixelsRec.h" |
#include "SkRRect.h" |
@@ -3239,66 +3240,6 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, |
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) |
- |
- if (fLights->light(i).getShadowMap() != nullptr) { |
- continue; |
- } |
- |
- // TODO: compute the correct size of the depth map from the light properties |
- // TODO: maybe add a kDepth_8_SkColorType |
- // TODO: find actual max depth of picture |
- SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( |
- fLights->light(i), 255, |
- picture->cullRect().width(), |
- picture->cullRect().height()); |
- |
- SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, |
- kBGRA_8888_SkColorType, |
- kOpaque_SkAlphaType); |
- |
- // Create a new surface (that matches the backend of canvas) |
- // for each shadow map |
- sk_sp<SkSurface> surf(this->makeSurface(info)); |
- |
- // 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(); |
- |
- 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)); |
- |
- SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, |
- kBGRA_8888_SkColorType, |
- kOpaque_SkAlphaType); |
- |
- sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); |
- |
- blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); |
- |
- fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); |
- } |
- } |
- |
// povDepthMap |
{ |
SkLights::Builder builder; |
@@ -3338,15 +3279,116 @@ 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); |
+ |
+ // 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) |
+ sk_sp<SkImage> depthMap; |
+ SkISize shMapSize; |
+ |
+ if (fLights->light(i).getShadowMap() != nullptr) { |
+ continue; |
+ } |
+ |
+ if (fLights->light(i).isRadial()) { |
+ shMapSize.fHeight = 1; |
+ shMapSize.fWidth = (int) picture->cullRect().width(); |
+ |
+ SkImageInfo info = SkImageInfo::Make(diffuseMap->width(), 1, |
+ kBGRA_8888_SkColorType, |
+ kOpaque_SkAlphaType); |
+ |
+ // Create new surface (that matches the backend of canvas) |
+ // for each shadow map |
+ sk_sp<SkSurface> surf(this->makeSurface(info)); |
+ |
+ // Wrap another SPFCanvas around the surface |
+ SkCanvas* depthMapCanvas = surf->getCanvas(); |
+ |
+ SkLights::Builder builder; |
+ builder.add(fLights->light(i)); |
+ sk_sp<SkLights> curLight = builder.finish(); |
+ |
+ sk_sp<SkShader> shadowMapShader; |
+ shadowMapShader = SkRadialShadowMapShader::Make( |
+ povDepthShader, curLight, |
+ (int) picture->cullRect().width(), |
+ (int) picture->cullRect().height()); |
+ |
+ SkPaint shadowMapPaint; |
+ shadowMapPaint.setShader(std::move(shadowMapShader)); |
+ |
+ depthMapCanvas->setLights(curLight); |
+ |
+ depthMapCanvas->drawRect(SkRect::MakeIWH(diffuseMap->width(), |
+ diffuseMap->height()), |
+ shadowMapPaint); |
+ |
+ depthMap = surf->makeImageSnapshot(); |
+ |
+ } else { |
+ // TODO: compute the correct size of the depth map from the light properties |
+ // TODO: maybe add a kDepth_8_SkColorType |
+ // TODO: find actual max depth of picture |
+ shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( |
+ fLights->light(i), 255, |
+ (int) picture->cullRect().width(), |
+ (int) picture->cullRect().height()); |
+ |
+ SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, |
+ kBGRA_8888_SkColorType, |
+ kOpaque_SkAlphaType); |
+ |
+ // Create a new surface (that matches the backend of canvas) |
+ // for each shadow map |
+ sk_sp<SkSurface> surf(this->makeSurface(info)); |
+ |
+ // 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); |
+ depthMap = 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)); |
+ |
+ SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, |
+ kBGRA_8888_SkColorType, |
+ kOpaque_SkAlphaType); |
+ |
+ sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); |
+ |
+ blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); |
+ |
+ fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); |
+ } |
+ } |
+ |
+ SkPaint shadowPaint; |
sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader), |
std::move(diffuseShader), |
- std::move(fLights), |
+ fLights, |
diffuseMap->width(), |
diffuseMap->height(), |
params); |