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

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: 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 "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkCanvasPriv.h" 10 #include "SkCanvasPriv.h"
(...skipping 21 matching lines...) Expand all
32 #include "SkShadowShader.h" 32 #include "SkShadowShader.h"
33 #include "SkSmallAllocator.h" 33 #include "SkSmallAllocator.h"
34 #include "SkSpecialImage.h" 34 #include "SkSpecialImage.h"
35 #include "SkSurface_Base.h" 35 #include "SkSurface_Base.h"
36 #include "SkTextBlob.h" 36 #include "SkTextBlob.h"
37 #include "SkTextFormatParams.h" 37 #include "SkTextFormatParams.h"
38 #include "SkTLazy.h" 38 #include "SkTLazy.h"
39 #include "SkTraceEvent.h" 39 #include "SkTraceEvent.h"
40 40
41 #include <new> 41 #include <new>
42 #include <SkShadowPaintFilterCanvas.h>
43 #include "SkLights.h"
44
45 #include "SkDrawFilter.h"
46 #include "SkLights.h"
47 #include "SkPictureRecorder.h"
48 #include "SkSurface.h"
49 #include "SkPaintFilterCanvas.h"
50 #include "SkMatrix.h"
51 #include "SkShadowShader.h"
52 #include "SkBitmapProcShader.h"
53 #include "SkNormalSource.h"
54
55
42 56
43 #if SK_SUPPORT_GPU 57 #if SK_SUPPORT_GPU
44 #include "GrContext.h" 58 #include "GrContext.h"
45 #include "GrRenderTarget.h" 59 #include "GrRenderTarget.h"
46 #include "SkGrPriv.h" 60 #include "SkGrPriv.h"
61 #include "SkShadowShader.h"
62 #include "SkShadowMapShader.h"
63
47 #endif 64 #endif
48 65
49 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 66 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0)
50 67
51 //#define SK_SUPPORT_PRECHECK_CLIPRECT 68 //#define SK_SUPPORT_PRECHECK_CLIPRECT
52 69
53 /* 70 /*
54 * Return true if the drawing this rect would hit every pixels in the canvas. 71 * Return true if the drawing this rect would hit every pixels in the canvas.
55 * 72 *
56 * Returns false if 73 * Returns false if
(...skipping 3004 matching lines...) Expand 10 before | Expand all | Expand 10 after
3061 void SkCanvas::drawShadowedPicture(const SkPicture* picture, 3078 void SkCanvas::drawShadowedPicture(const SkPicture* picture,
3062 const SkMatrix* matrix, 3079 const SkMatrix* matrix,
3063 const SkPaint* paint) { 3080 const SkPaint* paint) {
3064 RETURN_ON_NULL(picture); 3081 RETURN_ON_NULL(picture);
3065 3082
3066 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); 3083 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()");
3067 3084
3068 this->onDrawShadowedPicture(picture, matrix, paint); 3085 this->onDrawShadowedPicture(picture, matrix, paint);
3069 } 3086 }
3070 3087
3088 #include "GrDrawContext.h"
3089 #include "../../include/effects/SkBlurImageFilter.h"
3090
robertphillips 2016/08/10 14:23:18 Let's parameterize this so we can turn variance sh
vjiaoblack 2016/08/11 18:28:51 Done.
3071 void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, 3091 void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
3072 const SkMatrix* matrix, 3092 const SkMatrix* matrix,
3073 const SkPaint* paint) { 3093 const SkPaint* paint) {
3074 if (!paint || paint->canComputeFastBounds()) { 3094 if (!paint || paint->canComputeFastBounds()) {
3075 SkRect bounds = picture->cullRect(); 3095 SkRect bounds = picture->cullRect();
3076 if (paint) { 3096 if (paint) {
3077 paint->computeFastBounds(bounds, &bounds); 3097 paint->computeFastBounds(bounds, &bounds);
3078 } 3098 }
3079 if (matrix) { 3099 if (matrix) {
3080 matrix->mapRect(&bounds); 3100 matrix->mapRect(&bounds);
3081 } 3101 }
3082 if (this->quickReject(bounds)) { 3102 if (this->quickReject(bounds)) {
3083 return; 3103 return;
3084 } 3104 }
3085 } 3105 }
3086 3106
3087 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3107 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
3088 3108
3089 for (int i = 0; i < fLights->numLights(); ++i) {
3090 // skip over ambient lights; they don't cast shadows
3091 // lights that have shadow maps do not need updating (because lights are immutable)
3092
3093 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type() ||
3094 fLights->light(i).getShadowMap() != nullptr) {
3095 continue;
3096 }
3097
3098 // TODO: compute the correct size of the depth map from the light proper ties
3099 // TODO: maybe add a kDepth_8_SkColorType
3100 // TODO: find actual max depth of picture
3101 SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize(
3102 fLights->light(i), 255,
3103 picture->cullRect().width(),
3104 picture->cullRect().height());
3105
3106 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight ,
3107 kBGRA_8888_SkColorType,
3108 kOpaque_SkAlphaType);
3109
3110 // Create a new surface (that matches the backend of canvas)
3111 // for each shadow map
3112 sk_sp<SkSurface> surf(this->makeSurface(info));
3113
3114 // Wrap another SPFCanvas around the surface
3115 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
3116 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
3117
3118 // set the depth map canvas to have the light we're drawing.
3119 SkLights::Builder builder;
3120 builder.add(fLights->light(i));
3121 sk_sp<SkLights> curLight = builder.finish();
3122
3123 depthMapCanvas->setLights(std::move(curLight));
3124 depthMapCanvas->drawPicture(picture);
3125
3126 fLights->light(i).setShadowMap(surf->makeImageSnapshot());
3127 }
3128
3129 sk_sp<SkImage> povDepthMap; 3109 sk_sp<SkImage> povDepthMap;
3130 sk_sp<SkImage> diffuseMap; 3110 sk_sp<SkImage> diffuseMap;
3131 3111
3132 // TODO: pass the depth to the shader in vertices, or uniforms 3112 // TODO: pass the depth to the shader in vertices, or uniforms
3133 // so we don't have to render depth and color separately 3113 // so we don't have to render depth and color separately
3134 3114
3135 // povDepthMap 3115 // povDepthMap
3136 { 3116 {
3137 SkLights::Builder builder; 3117 SkLights::Builder builder;
3138 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), 3118 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
(...skipping 10 matching lines...) Expand all
3149 sk_sp<SkSurface> surf(this->makeSurface(info)); 3129 sk_sp<SkSurface> surf(this->makeSurface(info));
3150 3130
3151 // Wrap another SPFCanvas around the surface 3131 // Wrap another SPFCanvas around the surface
3152 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3132 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
3153 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3133 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
3154 3134
3155 // set the depth map canvas to have the light as the user's POV 3135 // set the depth map canvas to have the light as the user's POV
3156 depthMapCanvas->setLights(std::move(povLight)); 3136 depthMapCanvas->setLights(std::move(povLight));
3157 3137
3158 depthMapCanvas->drawPicture(picture); 3138 depthMapCanvas->drawPicture(picture);
3159
3160 povDepthMap = surf->makeImageSnapshot(); 3139 povDepthMap = surf->makeImageSnapshot();
3161 } 3140 }
3162 3141
3163 // diffuseMap 3142 // diffuseMap
3164 { 3143 {
3165 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3144 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(),
3166 picture->cullRect().height(), 3145 picture->cullRect().height(),
3167 kBGRA_8888_SkColorType, 3146 kBGRA_8888_SkColorType,
3168 kOpaque_SkAlphaType); 3147 kOpaque_SkAlphaType);
3169 3148
3170 sk_sp<SkSurface> surf(this->makeSurface(info)); 3149 sk_sp<SkSurface> surf(this->makeSurface(info));
3171 surf->getCanvas()->drawPicture(picture); 3150 surf->getCanvas()->drawPicture(picture);
3172 3151
3173 diffuseMap = surf->makeImageSnapshot(); 3152 diffuseMap = surf->makeImageSnapshot();
3174 } 3153 }
3175 3154
robertphillips 2016/08/10 14:23:18 Why was this moved down?
vjiaoblack 2016/08/11 18:28:51 Done.
3155 for (int i = 0; i < fLights->numLights(); ++i) {
3156 // skip over ambient lights; they don't cast shadows
3157 // lights that have shadow maps do not need updating (because lights are immutable)
3158
3159 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type() ||
3160 fLights->light(i).getShadowMap() != nullptr) {
3161 continue;
3162 }
3163
3164 // TODO: compute the correct size of the depth map from the light proper ties
3165 // TODO: maybe add a kDepth_8_SkColorType
3166 // TODO: find actual max depth of picture
3167 SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize(
3168 fLights->light(i), 255,
3169 picture->cullRect().width(),
3170 picture->cullRect().height());
3171
3172 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight ,
3173 kBGRA_8888_SkColorType,
3174 kOpaque_SkAlphaType);
3175
3176 // Create a new surface (that matches the backend of canvas)
3177 // for each shadow map
3178 sk_sp<SkSurface> surf(this->makeSurface(info));
3179
3180 // Wrap another SPFCanvas around the surface
3181 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
3182 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
3183
3184 // set the depth map canvas to have the light we're drawing.
3185 SkLights::Builder builder;
3186 builder.add(fLights->light(i));
3187 sk_sp<SkLights> curLight = builder.finish();
3188 depthMapCanvas->setLights(curLight);
3189
3190 depthMapCanvas->drawPicture(picture);
3191 sk_sp<SkImage> depthMap = surf->makeImageSnapshot();
3192
3193 // we blur the variance map
3194 SkPaint paint2;
3195 paint2.setImageFilter(SkBlurImageFilter::Make(2.0f, 2.0f, nullptr));
3196
3197 SkImageInfo info2 = SkImageInfo::Make(picture->cullRect().width(),
3198 picture->cullRect().height(),
3199 kBGRA_8888_SkColorType,
3200 kOpaque_SkAlphaType);
3201
3202 sk_sp<SkSurface> surf2(this->makeSurface(info2));
3203 sk_sp<SkCanvas> depthMapCanvas2 = sk_ref_sp(surf2->getCanvas());
3204
3205 depthMapCanvas2->drawImage(depthMap, 0, 0, &paint2);
3206
3207 fLights->light(i).setShadowMap(surf2->makeImageSnapshot());
3208 }
3209
3176 SkPaint shadowPaint; 3210 SkPaint shadowPaint;
3177 3211
3178 sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_Ti leMode, 3212 sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_Ti leMode,
3179 SkShader::kClamp_Ti leMode); 3213 SkShader::kClamp_Ti leMode);
3180
3181 sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_Tile Mode, 3214 sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_Tile Mode,
3182 SkShader::kClamp_Tile Mode); 3215 SkShader::kClamp_Tile Mode);
3183
3184 sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader ), 3216 sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader ),
3185 std::move(diffuseShader) , 3217 std::move(diffuseShader) ,
3186 std::move(fLights), 3218 std::move(fLights),
3187 diffuseMap->width(), 3219 diffuseMap->width(),
3188 diffuseMap->height()); 3220 diffuseMap->height());
3189 3221
3190 shadowPaint.setShader(shadowShader); 3222 shadowPaint.setShader(shadowShader);
3191 3223
3192 this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), s hadowPaint); 3224 this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), s hadowPaint);
3193 } 3225 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
3296 3328
3297 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3329 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
3298 fCanvas->restoreToCount(fSaveCount); 3330 fCanvas->restoreToCount(fSaveCount);
3299 } 3331 }
3300 3332
3301 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3333 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API
3302 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) { 3334 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p rops) {
3303 return this->makeSurface(info, props).release(); 3335 return this->makeSurface(info, props).release();
3304 } 3336 }
3305 #endif 3337 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698