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 "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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |