OLD | NEW |
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 20 matching lines...) Expand all Loading... |
31 #include "SkRRect.h" | 31 #include "SkRRect.h" |
32 #include "SkShadowPaintFilterCanvas.h" | 32 #include "SkShadowPaintFilterCanvas.h" |
33 #include "SkShadowShader.h" | 33 #include "SkShadowShader.h" |
34 #include "SkSmallAllocator.h" | 34 #include "SkSmallAllocator.h" |
35 #include "SkSpecialImage.h" | 35 #include "SkSpecialImage.h" |
36 #include "SkSurface_Base.h" | 36 #include "SkSurface_Base.h" |
37 #include "SkTextBlob.h" | 37 #include "SkTextBlob.h" |
38 #include "SkTextFormatParams.h" | 38 #include "SkTextFormatParams.h" |
39 #include "SkTLazy.h" | 39 #include "SkTLazy.h" |
40 #include "SkTraceEvent.h" | 40 #include "SkTraceEvent.h" |
41 | 41 #include "../../include/effects/SkBlurImageFilter.h" |
42 #include <new> | 42 #include <new> |
43 | 43 |
44 #if SK_SUPPORT_GPU | 44 #if SK_SUPPORT_GPU |
45 #include "GrContext.h" | 45 #include "GrContext.h" |
46 #include "GrRenderTarget.h" | 46 #include "GrRenderTarget.h" |
47 #include "SkGrPriv.h" | 47 #include "SkGrPriv.h" |
| 48 |
48 #endif | 49 #endif |
49 | 50 |
50 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) | 51 #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) |
51 | 52 |
52 //#define SK_SUPPORT_PRECHECK_CLIPRECT | 53 //#define SK_SUPPORT_PRECHECK_CLIPRECT |
53 | 54 |
54 /* | 55 /* |
55 * Return true if the drawing this rect would hit every pixels in the canvas. | 56 * Return true if the drawing this rect would hit every pixels in the canvas. |
56 * | 57 * |
57 * Returns false if | 58 * Returns false if |
(...skipping 3091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3149 } | 3150 } |
3150 } | 3151 } |
3151 | 3152 |
3152 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); | 3153 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); |
3153 picture->playback(this); | 3154 picture->playback(this); |
3154 } | 3155 } |
3155 | 3156 |
3156 #ifdef SK_EXPERIMENTAL_SHADOWING | 3157 #ifdef SK_EXPERIMENTAL_SHADOWING |
3157 void SkCanvas::drawShadowedPicture(const SkPicture* picture, | 3158 void SkCanvas::drawShadowedPicture(const SkPicture* picture, |
3158 const SkMatrix* matrix, | 3159 const SkMatrix* matrix, |
3159 const SkPaint* paint) { | 3160 const SkPaint* paint, |
| 3161 const SkShadowParams& params) { |
3160 RETURN_ON_NULL(picture); | 3162 RETURN_ON_NULL(picture); |
3161 | 3163 |
3162 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); | 3164 TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); |
3163 | 3165 |
3164 this->onDrawShadowedPicture(picture, matrix, paint); | 3166 this->onDrawShadowedPicture(picture, matrix, paint, params); |
3165 } | 3167 } |
3166 | 3168 |
3167 void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, | 3169 void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, |
3168 const SkMatrix* matrix, | 3170 const SkMatrix* matrix, |
3169 const SkPaint* paint) { | 3171 const SkPaint* paint, |
| 3172 const SkShadowParams& params) { |
3170 if (!paint || paint->canComputeFastBounds()) { | 3173 if (!paint || paint->canComputeFastBounds()) { |
3171 SkRect bounds = picture->cullRect(); | 3174 SkRect bounds = picture->cullRect(); |
3172 if (paint) { | 3175 if (paint) { |
3173 paint->computeFastBounds(bounds, &bounds); | 3176 paint->computeFastBounds(bounds, &bounds); |
3174 } | 3177 } |
3175 if (matrix) { | 3178 if (matrix) { |
3176 matrix->mapRect(&bounds); | 3179 matrix->mapRect(&bounds); |
3177 } | 3180 } |
3178 if (this->quickReject(bounds)) { | 3181 if (this->quickReject(bounds)) { |
3179 return; | 3182 return; |
3180 } | 3183 } |
3181 } | 3184 } |
3182 | 3185 |
3183 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); | 3186 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); |
3184 | 3187 |
| 3188 sk_sp<SkImage> povDepthMap; |
| 3189 sk_sp<SkImage> diffuseMap; |
| 3190 |
| 3191 // TODO: pass the depth to the shader in vertices, or uniforms |
| 3192 // so we don't have to render depth and color separately |
3185 for (int i = 0; i < fLights->numLights(); ++i) { | 3193 for (int i = 0; i < fLights->numLights(); ++i) { |
3186 // skip over ambient lights; they don't cast shadows | 3194 // skip over ambient lights; they don't cast shadows |
3187 // lights that have shadow maps do not need updating (because lights are
immutable) | 3195 // lights that have shadow maps do not need updating (because lights are
immutable) |
3188 | 3196 |
3189 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type() || | 3197 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type() || |
3190 fLights->light(i).getShadowMap() != nullptr) { | 3198 fLights->light(i).getShadowMap() != nullptr) { |
3191 continue; | 3199 continue; |
3192 } | 3200 } |
3193 | 3201 |
3194 // TODO: compute the correct size of the depth map from the light proper
ties | 3202 // TODO: compute the correct size of the depth map from the light proper
ties |
3195 // TODO: maybe add a kDepth_8_SkColorType | 3203 // TODO: maybe add a kDepth_8_SkColorType |
3196 // TODO: find actual max depth of picture | 3204 // TODO: find actual max depth of picture |
3197 SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( | 3205 SkISize shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( |
3198 fLights->light(i), 255, | 3206 fLights->light(i), 255, |
3199 picture->cullRect().width(), | 3207 picture->cullRect().width(), |
3200 picture->cullRect().height()); | 3208 picture->cullRect().height()); |
3201 | 3209 |
3202 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight
, | 3210 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight
, |
3203 kBGRA_8888_SkColorType, | 3211 kBGRA_8888_SkColorType, |
3204 kOpaque_SkAlphaType); | 3212 kOpaque_SkAlphaType); |
3205 | 3213 |
3206 // Create a new surface (that matches the backend of canvas) | 3214 // Create a new surface (that matches the backend of canvas) |
3207 // for each shadow map | 3215 // for each shadow map |
3208 sk_sp<SkSurface> surf(this->makeSurface(info)); | 3216 sk_sp<SkSurface> surf(this->makeSurface(info)); |
3209 | 3217 |
3210 // Wrap another SPFCanvas around the surface | 3218 // Wrap another SPFCanvas around the surface |
3211 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = | 3219 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = |
3212 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); | 3220 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); |
| 3221 depthMapCanvas->setShadowParams(params); |
3213 | 3222 |
3214 // set the depth map canvas to have the light we're drawing. | 3223 // set the depth map canvas to have the light we're drawing. |
3215 SkLights::Builder builder; | 3224 SkLights::Builder builder; |
3216 builder.add(fLights->light(i)); | 3225 builder.add(fLights->light(i)); |
3217 sk_sp<SkLights> curLight = builder.finish(); | 3226 sk_sp<SkLights> curLight = builder.finish(); |
| 3227 depthMapCanvas->setLights(std::move(curLight)); |
3218 | 3228 |
3219 depthMapCanvas->setLights(std::move(curLight)); | |
3220 depthMapCanvas->drawPicture(picture); | 3229 depthMapCanvas->drawPicture(picture); |
| 3230 sk_sp<SkImage> depthMap = surf->makeImageSnapshot(); |
3221 | 3231 |
3222 fLights->light(i).setShadowMap(surf->makeImageSnapshot()); | 3232 if (params.fType == SkShadowParams::kNoBlur_BlurAlgorithm) { |
| 3233 fLights->light(i).setShadowMap(std::move(depthMap)); |
| 3234 } else if (params.fType == SkShadowParams::kVariance_BlurAlgorithm) { |
| 3235 // we blur the variance map |
| 3236 SkPaint blurPaint; |
| 3237 blurPaint.setImageFilter(SkBlurImageFilter::Make(params.fShadowRadiu
s, |
| 3238 params.fShadowRadiu
s, nullptr)); |
| 3239 |
| 3240 // depthMapCanvas2->drawImage(finalDepthMap, 0, 0, &paint2); |
| 3241 |
| 3242 |
| 3243 sk_sp<SkImage> depthMap2 = surf->makeImageSnapshot(); |
| 3244 |
| 3245 |
| 3246 SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize
.fHeight, |
| 3247 kBGRA_8888_SkColorType, |
| 3248 kOpaque_SkAlphaType); |
| 3249 |
| 3250 sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); |
| 3251 |
| 3252 blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPai
nt); |
| 3253 |
| 3254 fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); |
| 3255 } |
3223 } | 3256 } |
3224 | 3257 |
3225 sk_sp<SkImage> povDepthMap; | |
3226 sk_sp<SkImage> diffuseMap; | |
3227 | |
3228 // TODO: pass the depth to the shader in vertices, or uniforms | |
3229 // so we don't have to render depth and color separately | |
3230 | |
3231 // povDepthMap | 3258 // povDepthMap |
3232 { | 3259 { |
3233 SkLights::Builder builder; | 3260 SkLights::Builder builder; |
3234 builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f,
1.0f), | 3261 builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f,
1.0f), |
3235 SkVector3::Make(0.0f, 0.0f,
1.0f))); | 3262 SkVector3::Make(0.0f, 0.0f,
1.0f))); |
3236 sk_sp<SkLights> povLight = builder.finish(); | 3263 sk_sp<SkLights> povLight = builder.finish(); |
3237 | 3264 |
3238 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), | 3265 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), |
3239 picture->cullRect().height(), | 3266 picture->cullRect().height(), |
3240 kBGRA_8888_SkColorType, | 3267 kBGRA_8888_SkColorType, |
3241 kOpaque_SkAlphaType); | 3268 kOpaque_SkAlphaType); |
3242 | 3269 |
3243 // Create a new surface (that matches the backend of canvas) | 3270 // Create a new surface (that matches the backend of canvas) |
3244 // to create the povDepthMap | 3271 // to create the povDepthMap |
3245 sk_sp<SkSurface> surf(this->makeSurface(info)); | 3272 sk_sp<SkSurface> surf(this->makeSurface(info)); |
3246 | 3273 |
3247 // Wrap another SPFCanvas around the surface | 3274 // Wrap another SPFCanvas around the surface |
3248 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = | 3275 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = |
3249 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); | 3276 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); |
3250 | 3277 |
3251 // set the depth map canvas to have the light as the user's POV | 3278 // set the depth map canvas to have the light as the user's POV |
3252 depthMapCanvas->setLights(std::move(povLight)); | 3279 depthMapCanvas->setLights(std::move(povLight)); |
3253 | 3280 |
3254 depthMapCanvas->drawPicture(picture); | 3281 depthMapCanvas->drawPicture(picture); |
3255 | |
3256 povDepthMap = surf->makeImageSnapshot(); | 3282 povDepthMap = surf->makeImageSnapshot(); |
3257 } | 3283 } |
3258 | 3284 |
3259 // diffuseMap | 3285 // diffuseMap |
3260 { | 3286 { |
3261 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), | 3287 SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), |
3262 picture->cullRect().height(), | 3288 picture->cullRect().height(), |
3263 kBGRA_8888_SkColorType, | 3289 kBGRA_8888_SkColorType, |
3264 kOpaque_SkAlphaType); | 3290 kOpaque_SkAlphaType); |
3265 | 3291 |
3266 sk_sp<SkSurface> surf(this->makeSurface(info)); | 3292 sk_sp<SkSurface> surf(this->makeSurface(info)); |
3267 surf->getCanvas()->drawPicture(picture); | 3293 surf->getCanvas()->drawPicture(picture); |
3268 | 3294 |
3269 diffuseMap = surf->makeImageSnapshot(); | 3295 diffuseMap = surf->makeImageSnapshot(); |
3270 } | 3296 } |
3271 | |
3272 SkPaint shadowPaint; | 3297 SkPaint shadowPaint; |
3273 | 3298 |
3274 sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_Ti
leMode, | 3299 sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_Ti
leMode, |
3275 SkShader::kClamp_Ti
leMode); | 3300 SkShader::kClamp_Ti
leMode); |
3276 | |
3277 sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_Tile
Mode, | 3301 sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_Tile
Mode, |
3278 SkShader::kClamp_Tile
Mode); | 3302 SkShader::kClamp_Tile
Mode); |
3279 | |
3280 sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader
), | 3303 sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader
), |
3281 std::move(diffuseShader)
, | 3304 std::move(diffuseShader)
, |
3282 std::move(fLights), | 3305 std::move(fLights), |
3283 diffuseMap->width(), | 3306 diffuseMap->width(), |
3284 diffuseMap->height()); | 3307 diffuseMap->height(), |
| 3308 params); |
3285 | 3309 |
3286 shadowPaint.setShader(shadowShader); | 3310 shadowPaint.setShader(shadowShader); |
3287 | 3311 |
3288 this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), s
hadowPaint); | 3312 this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), s
hadowPaint); |
3289 } | 3313 } |
3290 #endif | 3314 #endif |
3291 | 3315 |
3292 /////////////////////////////////////////////////////////////////////////////// | 3316 /////////////////////////////////////////////////////////////////////////////// |
3293 /////////////////////////////////////////////////////////////////////////////// | 3317 /////////////////////////////////////////////////////////////////////////////// |
3294 | 3318 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3392 | 3416 |
3393 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 3417 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
3394 fCanvas->restoreToCount(fSaveCount); | 3418 fCanvas->restoreToCount(fSaveCount); |
3395 } | 3419 } |
3396 | 3420 |
3397 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API | 3421 #ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API |
3398 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 3422 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
3399 return this->makeSurface(info, props).release(); | 3423 return this->makeSurface(info, props).release(); |
3400 } | 3424 } |
3401 #endif | 3425 #endif |
OLD | NEW |