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

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

Issue 2224163005: Made shadows blurry (thru implementing variance mapping) (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: made req changes Created 4 years, 4 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
OLDNEW
1 /* 1 /*
2 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
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 "SkBitmapDevice.h" 8 #include "SkBitmapDevice.h"
9 #include "SkBitmapProcShader.h"
9 #include "SkCanvas.h" 10 #include "SkCanvas.h"
10 #include "SkCanvasPriv.h" 11 #include "SkCanvasPriv.h"
11 #include "SkClipStack.h" 12 #include "SkClipStack.h"
12 #include "SkColorFilter.h" 13 #include "SkColorFilter.h"
13 #include "SkDraw.h" 14 #include "SkDraw.h"
14 #include "SkDrawable.h" 15 #include "SkDrawable.h"
16 #include "GrDrawContext.h"
15 #include "SkDrawFilter.h" 17 #include "SkDrawFilter.h"
16 #include "SkDrawLooper.h" 18 #include "SkDrawLooper.h"
17 #include "SkErrorInternals.h" 19 #include "SkErrorInternals.h"
18 #include "SkImage.h" 20 #include "SkImage.h"
19 #include "SkImage_Base.h" 21 #include "SkImage_Base.h"
20 #include "SkImageFilter.h" 22 #include "SkImageFilter.h"
21 #include "SkImageFilterCache.h" 23 #include "SkImageFilterCache.h"
22 #include "SkLatticeIter.h" 24 #include "SkLatticeIter.h"
25 #include "SkLights.h"
26 #include "SkMatrix.h"
23 #include "SkMatrixUtils.h" 27 #include "SkMatrixUtils.h"
24 #include "SkMetaData.h" 28 #include "SkMetaData.h"
29 #include "SkNormalSource.h"
30 #include "SkPaintFilterCanvas.h"
25 #include "SkPaintPriv.h" 31 #include "SkPaintPriv.h"
26 #include "SkPatchUtils.h" 32 #include "SkPatchUtils.h"
27 #include "SkPicture.h" 33 #include "SkPicture.h"
34 #include "SkPictureRecorder.h"
28 #include "SkRasterClip.h" 35 #include "SkRasterClip.h"
29 #include "SkReadPixelsRec.h" 36 #include "SkReadPixelsRec.h"
30 #include "SkRRect.h" 37 #include "SkRRect.h"
31 #include "SkShadowPaintFilterCanvas.h" 38 #include "SkShadowPaintFilterCanvas.h"
32 #include "SkShadowShader.h"
33 #include "SkSmallAllocator.h" 39 #include "SkSmallAllocator.h"
34 #include "SkSpecialImage.h" 40 #include "SkSpecialImage.h"
41 #include "SkSurface.h"
35 #include "SkSurface_Base.h" 42 #include "SkSurface_Base.h"
36 #include "SkTextBlob.h" 43 #include "SkTextBlob.h"
37 #include "SkTextFormatParams.h" 44 #include "SkTextFormatParams.h"
38 #include "SkTLazy.h" 45 #include "SkTLazy.h"
39 #include "SkTraceEvent.h" 46 #include "SkTraceEvent.h"
40 47 #include "../../include/effects/SkBlurImageFilter.h"
41 #include <new> 48 #include <new>
42 49
43 #if SK_SUPPORT_GPU 50 #if SK_SUPPORT_GPU
44 #include "GrContext.h" 51 #include "GrContext.h"
45 #include "GrRenderTarget.h" 52 #include "GrRenderTarget.h"
46 #include "SkGrPriv.h" 53 #include "SkGrPriv.h"
54 #include "SkShadowShader.h"
55 #include "SkShadowMapShader.h"
56
47 #endif 57 #endif
48 58
49 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 59 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0)
50 60
51 //#define SK_SUPPORT_PRECHECK_CLIPRECT 61 //#define SK_SUPPORT_PRECHECK_CLIPRECT
52 62
53 /* 63 /*
54 * Return true if the drawing this rect would hit every pixels in the canvas. 64 * Return true if the drawing this rect would hit every pixels in the canvas.
55 * 65 *
56 * Returns false if 66 * Returns false if
(...skipping 2996 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 } 3063 }
3054 } 3064 }
3055 3065
3056 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3066 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
3057 picture->playback(this); 3067 picture->playback(this);
3058 } 3068 }
3059 3069
3060 #ifdef SK_EXPERIMENTAL_SHADOWING 3070 #ifdef SK_EXPERIMENTAL_SHADOWING
3061 void SkCanvas::drawShadowedPicture(const SkPicture* picture, 3071 void SkCanvas::drawShadowedPicture(const SkPicture* picture,
3062 const SkMatrix* matrix, 3072 const SkMatrix* matrix,
3063 const SkPaint* paint) { 3073 const SkPaint* paint,
3074 SkShadowType sType) {
3064 RETURN_ON_NULL(picture); 3075 RETURN_ON_NULL(picture);
3065 3076
3066 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); 3077 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()");
3067 3078
3068 this->onDrawShadowedPicture(picture, matrix, paint); 3079 this->onDrawShadowedPicture(picture, matrix, paint, sType);
3069 } 3080 }
3070 3081
3071 void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, 3082 void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
3072 const SkMatrix* matrix, 3083 const SkMatrix* matrix,
3073 const SkPaint* paint) { 3084 const SkPaint* paint,
3085 SkShadowType sType) {
3074 if (!paint || paint->canComputeFastBounds()) { 3086 if (!paint || paint->canComputeFastBounds()) {
3075 SkRect bounds = picture->cullRect(); 3087 SkRect bounds = picture->cullRect();
3076 if (paint) { 3088 if (paint) {
3077 paint->computeFastBounds(bounds, &bounds); 3089 paint->computeFastBounds(bounds, &bounds);
3078 } 3090 }
3079 if (matrix) { 3091 if (matrix) {
3080 matrix->mapRect(&bounds); 3092 matrix->mapRect(&bounds);
3081 } 3093 }
3082 if (this->quickReject(bounds)) { 3094 if (this->quickReject(bounds)) {
3083 return; 3095 return;
3084 } 3096 }
3085 } 3097 }
3086 3098
3087 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3099 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
3088 3100
3101 sk_sp<SkImage> povDepthMap;
3102 sk_sp<SkImage> diffuseMap;
3103
3104 // TODO: pass the depth to the shader in vertices, or uniforms
3105 // so we don't have to render depth and color separately
3089 for (int i = 0; i < fLights->numLights(); ++i) { 3106 for (int i = 0; i < fLights->numLights(); ++i) {
3090 // skip over ambient lights; they don't cast shadows 3107 // skip over ambient lights; they don't cast shadows
3091 // lights that have shadow maps do not need updating (because lights are immutable) 3108 // lights that have shadow maps do not need updating (because lights are immutable)
3092 3109
3093 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type() || 3110 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type() ||
3094 fLights->light(i).getShadowMap() != nullptr) { 3111 fLights->light(i).getShadowMap() != nullptr) {
3095 continue; 3112 continue;
3096 } 3113 }
3097 3114
3098 // TODO: compute the correct size of the depth map from the light proper ties 3115 // TODO: compute the correct size of the depth map from the light proper ties
3099 // TODO: maybe add a kDepth_8_SkColorType 3116 // TODO: maybe add a kDepth_8_SkColorType
3100 // TODO: find actual max depth of picture 3117 // TODO: find actual max depth of picture
3101 SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( 3118 SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize(
3102 fLights->light(i), 255, 3119 fLights->light(i), 255,
3103 picture->cullRect().width(), 3120 picture->cullRect().width(),
3104 picture->cullRect().height()); 3121 picture->cullRect().height());
3105 3122
3106 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight , 3123 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight ,
3107 kBGRA_8888_SkColorType, 3124 kBGRA_8888_SkColorType,
3108 kOpaque_SkAlphaType); 3125 kOpaque_SkAlphaType);
3109 3126
3110 // Create a new surface (that matches the backend of canvas) 3127 // Create a new surface (that matches the backend of canvas)
3111 // for each shadow map 3128 // for each shadow map
3112 sk_sp<SkSurface> surf(this->makeSurface(info)); 3129 sk_sp<SkSurface> surf(this->makeSurface(info));
3113 3130
3114 // Wrap another SPFCanvas around the surface 3131 // Wrap another SPFCanvas around the surface
3115 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3132 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
3116 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3133 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
3134 depthMapCanvas->setShadowType(sType);
3117 3135
3118 // set the depth map canvas to have the light we're drawing. 3136 // set the depth map canvas to have the light we're drawing.
3119 SkLights::Builder builder; 3137 SkLights::Builder builder;
3120 builder.add(fLights->light(i)); 3138 builder.add(fLights->light(i));
3121 sk_sp<SkLights> curLight = builder.finish(); 3139 sk_sp<SkLights> curLight = builder.finish();
3140 depthMapCanvas->setLights(curLight);
3122 3141
3123 depthMapCanvas->setLights(std::move(curLight));
3124 depthMapCanvas->drawPicture(picture); 3142 depthMapCanvas->drawPicture(picture);
3143 sk_sp<SkImage> depthMap = surf->makeImageSnapshot();
3125 3144
3126 fLights->light(i).setShadowMap(surf->makeImageSnapshot()); 3145 // we blur the variance map
3146 SkPaint paint2;
jvanverth1 2016/08/12 17:39:08 Suggestion: SkPaint blurPaint;
vjiaoblack 2016/08/12 19:07:42 Done.
3147 if (sType.fBlurAlgorithm != SkShadowType::kNoBlur_BlurAlgorithm) {
3148 paint2.setImageFilter(SkBlurImageFilter::Make(sType.fShadowRadius,
3149 sType.fShadowRadius, n ullptr));
3150 }
3151
3152 SkImageInfo info2 = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeigh t,
jvanverth1 2016/08/12 17:39:08 Suggestion: rename to blurInfo, blurSurface, blurr
vjiaoblack 2016/08/12 19:07:42 Done.
3153 kBGRA_8888_SkColorType,
jvanverth1 2016/08/12 17:39:08 Nit: align just past (
vjiaoblack 2016/08/12 19:07:42 Done.
3154 kOpaque_SkAlphaType);
3155
3156 sk_sp<SkSurface> surf2(this->makeSurface(info2));
3157 sk_sp<SkCanvas> depthMapCanvas2 = sk_ref_sp(surf2->getCanvas());
3158
3159 depthMapCanvas2->drawImage(depthMap, 0, 0, &paint2);
3160
3161 fLights->light(i).setShadowMap(surf2->makeImageSnapshot());
3127 } 3162 }
3128 3163
3129 sk_sp<SkImage> povDepthMap;
3130 sk_sp<SkImage> diffuseMap;
3131
3132 // TODO: pass the depth to the shader in vertices, or uniforms
3133 // so we don't have to render depth and color separately
3134
3135 // povDepthMap 3164 // povDepthMap
3136 { 3165 {
3137 SkLights::Builder builder; 3166 SkLights::Builder builder;
3138 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), 3167 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
3139 SkVector3::Make(0.0f, 0.0f, 1.0f))); 3168 SkVector3::Make(0.0f, 0.0f, 1.0f)));
3140 sk_sp<SkLights> povLight = builder.finish(); 3169 sk_sp<SkLights> povLight = builder.finish();
3141 3170
3142 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3171 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(),
3143 picture->cullRect().height(), 3172 picture->cullRect().height(),
3144 kBGRA_8888_SkColorType, 3173 kBGRA_8888_SkColorType,
3145 kOpaque_SkAlphaType); 3174 kOpaque_SkAlphaType);
3146 3175
3147 // Create a new surface (that matches the backend of canvas) 3176 // Create a new surface (that matches the backend of canvas)
3148 // to create the povDepthMap 3177 // to create the povDepthMap
3149 sk_sp<SkSurface> surf(this->makeSurface(info)); 3178 sk_sp<SkSurface> surf(this->makeSurface(info));
3150 3179
3151 // Wrap another SPFCanvas around the surface 3180 // Wrap another SPFCanvas around the surface
3152 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3181 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
3153 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3182 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
3154 3183
3155 // set the depth map canvas to have the light as the user's POV 3184 // set the depth map canvas to have the light as the user's POV
3156 depthMapCanvas->setLights(std::move(povLight)); 3185 depthMapCanvas->setLights(std::move(povLight));
3157 3186
3158 depthMapCanvas->drawPicture(picture); 3187 depthMapCanvas->drawPicture(picture);
3159
3160 povDepthMap = surf->makeImageSnapshot(); 3188 povDepthMap = surf->makeImageSnapshot();
3161 } 3189 }
3162 3190
3163 // diffuseMap 3191 // diffuseMap
3164 { 3192 {
3165 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3193 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(),
3166 picture->cullRect().height(), 3194 picture->cullRect().height(),
3167 kBGRA_8888_SkColorType, 3195 kBGRA_8888_SkColorType,
3168 kOpaque_SkAlphaType); 3196 kOpaque_SkAlphaType);
3169 3197
3170 sk_sp<SkSurface> surf(this->makeSurface(info)); 3198 sk_sp<SkSurface> surf(this->makeSurface(info));
3171 surf->getCanvas()->drawPicture(picture); 3199 surf->getCanvas()->drawPicture(picture);
3172 3200
3173 diffuseMap = surf->makeImageSnapshot(); 3201 diffuseMap = surf->makeImageSnapshot();
3174 } 3202 }
3175
3176 SkPaint shadowPaint; 3203 SkPaint shadowPaint;
3177 3204
3178 sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_Ti leMode, 3205 sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_Ti leMode,
3179 SkShader::kClamp_Ti leMode); 3206 SkShader::kClamp_Ti leMode);
3180
3181 sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_Tile Mode, 3207 sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_Tile Mode,
3182 SkShader::kClamp_Tile Mode); 3208 SkShader::kClamp_Tile Mode);
3183
3184 sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader ), 3209 sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader ),
3185 std::move(diffuseShader) , 3210 std::move(diffuseShader) ,
3186 std::move(fLights), 3211 std::move(fLights),
3187 diffuseMap->width(), 3212 diffuseMap->width(),
3188 diffuseMap->height()); 3213 diffuseMap->height(),
3214 sType);
3189 3215
3190 shadowPaint.setShader(shadowShader); 3216 shadowPaint.setShader(shadowShader);
3191 3217
3192 this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), s hadowPaint); 3218 this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), s hadowPaint);
3193 } 3219 }
3194 #endif 3220 #endif
3195 3221
3196 /////////////////////////////////////////////////////////////////////////////// 3222 ///////////////////////////////////////////////////////////////////////////////
3197 /////////////////////////////////////////////////////////////////////////////// 3223 ///////////////////////////////////////////////////////////////////////////////
3198 3224
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3296 3322
3297 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3323 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3298 fCanvas->restoreToCount(fSaveCount); 3324 fCanvas->restoreToCount(fSaveCount);
3299 } 3325 }
3300 3326
3301 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3327 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API
3302 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 3328 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
3303 return this->makeSurface(info, props).release(); 3329 return this->makeSurface(info, props).release();
3304 } 3330 }
3305 #endif 3331 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698