Made shadows blurry (thru implementing variance mapping)
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2224163005 Review-Url: https://codereview.chromium.org/2224163005
This commit is contained in:
parent
199a2ea665
commit
e6f5d56231
@ -76,6 +76,11 @@ public:
|
|||||||
SkVector3::Make(0.1f, 0.2f, 1.0f)));
|
SkVector3::Make(0.1f, 0.2f, 1.0f)));
|
||||||
builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
|
builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
|
||||||
fLights = builder.finish();
|
fLights = builder.finish();
|
||||||
|
|
||||||
|
fShadowParams.fShadowRadius = 4.0f;
|
||||||
|
fShadowParams.fBiasingConstant = 0.3f;
|
||||||
|
fShadowParams.fMinVariance = 1024;
|
||||||
|
fShadowParams.fType = SkShadowParams::kVariance_ShadowType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -95,11 +100,12 @@ protected:
|
|||||||
// It's used to generate the depth maps.
|
// It's used to generate the depth maps.
|
||||||
sk_sp<SkPicture> pic(make_test_picture(kWidth, kHeight));
|
sk_sp<SkPicture> pic(make_test_picture(kWidth, kHeight));
|
||||||
canvas->setLights(fLights);
|
canvas->setLights(fLights);
|
||||||
canvas->drawShadowedPicture(pic, nullptr, nullptr);
|
canvas->drawShadowedPicture(pic, nullptr, nullptr, fShadowParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sk_sp<SkLights> fLights;
|
sk_sp<SkLights> fLights;
|
||||||
|
SkShadowParams fShadowParams;
|
||||||
typedef GM INHERITED;
|
typedef GM INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -443,6 +443,7 @@
|
|||||||
'<(skia_include_path)/private/SkOnce.h',
|
'<(skia_include_path)/private/SkOnce.h',
|
||||||
'<(skia_include_path)/private/SkRecords.h',
|
'<(skia_include_path)/private/SkRecords.h',
|
||||||
'<(skia_include_path)/private/SkSemaphore.h',
|
'<(skia_include_path)/private/SkSemaphore.h',
|
||||||
|
'<(skia_include_path)/private/SkShadowParams.h',
|
||||||
'<(skia_include_path)/private/SkSpinlock.h',
|
'<(skia_include_path)/private/SkSpinlock.h',
|
||||||
'<(skia_include_path)/private/SkTemplates.h',
|
'<(skia_include_path)/private/SkTemplates.h',
|
||||||
'<(skia_include_path)/private/SkTArray.h',
|
'<(skia_include_path)/private/SkTArray.h',
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "SkSurfaceProps.h"
|
#include "SkSurfaceProps.h"
|
||||||
#include "SkXfermode.h"
|
#include "SkXfermode.h"
|
||||||
#include "SkLights.h"
|
#include "SkLights.h"
|
||||||
|
#include "../private/SkShadowParams.h"
|
||||||
|
|
||||||
class GrContext;
|
class GrContext;
|
||||||
class GrDrawContext;
|
class GrDrawContext;
|
||||||
@ -1073,7 +1074,7 @@ public:
|
|||||||
|
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
/**
|
/**
|
||||||
* Draw the picture into this canvas.
|
* Draw the picture into this canvas, with shadows!
|
||||||
*
|
*
|
||||||
* We will use the canvas's lights along with the picture information (draw depths of
|
* We will use the canvas's lights along with the picture information (draw depths of
|
||||||
* objects, etc) to first create a set of shadowmaps for the light-picture pairs, and
|
* objects, etc) to first create a set of shadowmaps for the light-picture pairs, and
|
||||||
@ -1088,14 +1089,33 @@ public:
|
|||||||
* This is logically equivalent to
|
* This is logically equivalent to
|
||||||
* saveLayer(paint)/drawPicture/restore
|
* saveLayer(paint)/drawPicture/restore
|
||||||
*
|
*
|
||||||
|
* We also support using variance shadow maps for blurred shadows; the user can specify
|
||||||
|
* what shadow mapping algorithm to use with params.
|
||||||
|
* - Variance Shadow Mapping works by storing both the depth and depth^2 in the shadow map.
|
||||||
|
* - Then, the shadow map can be blurred, and when reading from it, the fragment shader
|
||||||
|
* can calculate the variance of the depth at a position by doing E(x^2) - E(x)^2.
|
||||||
|
* - We can then use the depth variance and depth at a fragment to arrive at an upper bound
|
||||||
|
* of the probability that the current surface is shadowed by using Chebyshev's
|
||||||
|
* inequality, and then use that to shade the fragment.
|
||||||
|
*
|
||||||
|
* - There are a few problems with VSM.
|
||||||
|
* * Light Bleeding | Areas with high variance, such as near the edges of high up rects,
|
||||||
|
* will cause their shadow penumbras to overwrite otherwise solid
|
||||||
|
* shadows.
|
||||||
|
* * Shape Distortion | We can combat Light Bleeding by biasing the shadow (setting
|
||||||
|
* mostly shaded fragments to completely shaded) and increasing
|
||||||
|
* the minimum allowed variance. However, this warps and rounds
|
||||||
|
* out the shape of the shadow.
|
||||||
*/
|
*/
|
||||||
void drawShadowedPicture(const SkPicture*,
|
void drawShadowedPicture(const SkPicture*,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint);
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params);
|
||||||
void drawShadowedPicture(const sk_sp<SkPicture>& picture,
|
void drawShadowedPicture(const sk_sp<SkPicture>& picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
this->drawShadowedPicture(picture.get(), matrix, paint);
|
const SkShadowParams& params) {
|
||||||
|
this->drawShadowedPicture(picture.get(), matrix, paint, params);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1434,7 +1454,8 @@ protected:
|
|||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
virtual void onDrawShadowedPicture(const SkPicture*,
|
virtual void onDrawShadowedPicture(const SkPicture*,
|
||||||
const SkMatrix*,
|
const SkMatrix*,
|
||||||
const SkPaint*);
|
const SkPaint*,
|
||||||
|
const SkShadowParams& params);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Returns the canvas to be used by DrawIter. Default implementation
|
// Returns the canvas to be used by DrawIter. Default implementation
|
||||||
|
@ -268,7 +268,8 @@ RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag,
|
|||||||
RECORD(DrawShadowedPicture, kDraw_Tag|kHasPaint_Tag,
|
RECORD(DrawShadowedPicture, kDraw_Tag|kHasPaint_Tag,
|
||||||
Optional<SkPaint> paint;
|
Optional<SkPaint> paint;
|
||||||
sk_sp<const SkPicture> picture;
|
sk_sp<const SkPicture> picture;
|
||||||
TypedMatrix matrix);
|
TypedMatrix matrix;
|
||||||
|
const SkShadowParams& params);
|
||||||
RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
|
RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
SkCanvas::PointMode mode;
|
SkCanvas::PointMode mode;
|
||||||
|
48
include/private/SkShadowParams.h
Normal file
48
include/private/SkShadowParams.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
#ifndef SkShadowParams_DEFINED
|
||||||
|
#define SkShadowParams_DEFINED
|
||||||
|
|
||||||
|
/** \struct SkShadowParams
|
||||||
|
|
||||||
|
This struct holds information needed for drawing shadows.
|
||||||
|
|
||||||
|
fShadowRadius - radius of the shadow blur
|
||||||
|
|
||||||
|
fBiasingConstant - A constant used in variance shadow mapping to directly
|
||||||
|
0.0 - 1.0 reduce light bleeding. Essentially sets all shadows
|
||||||
|
~.25 below a certain brightness equal to no light, and does
|
||||||
|
a linear step on the rest. Essentially makes shadows
|
||||||
|
darker and more rounded at higher values.
|
||||||
|
|
||||||
|
fMinVariance - Too low of a variance (near the outer edges of blurry
|
||||||
|
~512, 1024 shadows) will lead to ugly sharp shadow brightness
|
||||||
|
distortions. This enforces a minimum amount of variance
|
||||||
|
in the calculation to smooth out the outside edges of
|
||||||
|
blurry shadows. However, too high of a value for this will
|
||||||
|
cause all shadows to be lighter by visibly different
|
||||||
|
amounts varying on depth.
|
||||||
|
|
||||||
|
fType - Decides which algorithm to use to draw shadows.
|
||||||
|
*/
|
||||||
|
struct SkShadowParams {
|
||||||
|
SkScalar fShadowRadius;
|
||||||
|
SkScalar fBiasingConstant;
|
||||||
|
SkScalar fMinVariance;
|
||||||
|
|
||||||
|
enum ShadowType {
|
||||||
|
kNoBlur_ShadowType,
|
||||||
|
kVariance_ShadowType,
|
||||||
|
|
||||||
|
kLast_ShadowType = kVariance_ShadowType
|
||||||
|
};
|
||||||
|
static const int kShadowTypeCount = kLast_ShadowType + 1;
|
||||||
|
|
||||||
|
ShadowType fType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -38,13 +38,31 @@ public:
|
|||||||
fTestRects[2].fDepth = 240;
|
fTestRects[2].fDepth = 240;
|
||||||
fTestRects[2].fGeometry = SkRect::MakeLTRB(100,100,250,250);
|
fTestRects[2].fGeometry = SkRect::MakeLTRB(100,100,250,250);
|
||||||
|
|
||||||
|
fSliders[0].fGeometry = SkRect::MakeLTRB(20, 400, 30, 420);
|
||||||
|
fSliders[0].fOffset = 0.0f;
|
||||||
|
fSliders[0].fScale = 0.1f;
|
||||||
|
|
||||||
|
fSliders[1].fGeometry = SkRect::MakeLTRB(100, 420, 110, 440);
|
||||||
|
fSliders[1].fOffset = 0.0f;
|
||||||
|
fSliders[1].fScale = 10.0f;
|
||||||
|
|
||||||
|
fSliders[2].fGeometry = SkRect::MakeLTRB(0, 440, 10, 460);
|
||||||
|
fSliders[2].fOffset = 0.0f;
|
||||||
|
fSliders[2].fScale = 0.0025f;
|
||||||
|
|
||||||
fSceneChanged = true;
|
fSceneChanged = true;
|
||||||
fLightsChanged = true;
|
fLightsChanged = true;
|
||||||
|
|
||||||
fSelectedRect = -1;
|
fSelectedRect = -1;
|
||||||
|
fSelectedSlider = -1;
|
||||||
fMoveLight = false;
|
fMoveLight = false;
|
||||||
|
|
||||||
fClearShadowMaps = false;
|
fClearShadowMaps = false;
|
||||||
|
|
||||||
|
fShadowParams.fShadowRadius = 2.0f;
|
||||||
|
fShadowParams.fBiasingConstant = 0.3f;
|
||||||
|
fShadowParams.fMinVariance = 1024;
|
||||||
|
fShadowParams.fType = SkShadowParams::kVariance_ShadowType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -67,6 +85,15 @@ protected:
|
|||||||
// the shadow maps will be re-generated according to the new backend.
|
// the shadow maps will be re-generated according to the new backend.
|
||||||
fClearShadowMaps = true;
|
fClearShadowMaps = true;
|
||||||
break;
|
break;
|
||||||
|
case 'B':
|
||||||
|
if (SkShadowParams::kVariance_ShadowType == fShadowParams.fType) {
|
||||||
|
fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType;
|
||||||
|
} else if (SkShadowParams::kNoBlur_ShadowType ==
|
||||||
|
fShadowParams.fType) {
|
||||||
|
fShadowParams.fType = SkShadowParams::kVariance_ShadowType;
|
||||||
|
}
|
||||||
|
fLightsChanged = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -113,19 +140,46 @@ protected:
|
|||||||
for (int i = 0; i < fLights->numLights(); i++) {
|
for (int i = 0; i < fLights->numLights(); i++) {
|
||||||
fLights->light(i).setShadowMap(nullptr);
|
fLights->light(i).setShadowMap(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fSceneChanged = false;
|
fSceneChanged = false;
|
||||||
fLightsChanged = false;
|
fLightsChanged = false;
|
||||||
fClearShadowMaps = false;
|
fClearShadowMaps = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas->setLights(fLights);
|
canvas->setLights(fLights);
|
||||||
canvas->drawShadowedPicture(fPicture, nullptr, nullptr);
|
canvas->drawShadowedPicture(fPicture, nullptr, nullptr, fShadowParams);
|
||||||
|
|
||||||
|
for (int i = 0; i < kNumSliders; i++) {
|
||||||
|
SkPaint paint;
|
||||||
|
paint.setColor(SK_ColorBLACK);
|
||||||
|
canvas->drawRect(fSliders[i].fGeometry, paint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
|
SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
|
||||||
return new SkView::Click(this);
|
return new SkView::Click(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateFromSelectedSlider() {
|
||||||
|
SkScalar newValue = fSliders[fSelectedSlider].fGeometry.fLeft *
|
||||||
|
fSliders[fSelectedSlider].fScale +
|
||||||
|
fSliders[fSelectedSlider].fOffset;
|
||||||
|
|
||||||
|
switch (fSelectedSlider) {
|
||||||
|
case 0:
|
||||||
|
fShadowParams.fShadowRadius = newValue;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fShadowParams.fMinVariance = newValue;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fShadowParams.fBiasingConstant = newValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool onClick(Click *click) override {
|
bool onClick(Click *click) override {
|
||||||
SkScalar x = click->fCurr.fX;
|
SkScalar x = click->fCurr.fX;
|
||||||
SkScalar y = click->fCurr.fY;
|
SkScalar y = click->fCurr.fY;
|
||||||
@ -161,6 +215,7 @@ protected:
|
|||||||
|
|
||||||
if (click->fState == Click::State::kUp_State) {
|
if (click->fState == Click::State::kUp_State) {
|
||||||
fSelectedRect = -1;
|
fSelectedRect = -1;
|
||||||
|
fSelectedSlider = -1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +227,16 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fSelectedSlider > -1) {
|
||||||
|
fSliders[fSelectedSlider].fGeometry.offset(dx, 0);
|
||||||
|
|
||||||
|
this->updateFromSelectedSlider();
|
||||||
|
|
||||||
|
fLightsChanged = true;
|
||||||
|
this->inval(nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// assume last elements are highest
|
// assume last elements are highest
|
||||||
for (int i = kNumTestRects - 1; i >= 0; i--) {
|
for (int i = kNumTestRects - 1; i >= 0; i--) {
|
||||||
if (fTestRects[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
|
if (fTestRects[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
|
||||||
@ -184,30 +249,51 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= kNumSliders; i++) {
|
||||||
|
if (fSliders[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
|
||||||
|
fSelectedSlider = i;
|
||||||
|
fSliders[i].fGeometry.offset(dx, 0);
|
||||||
|
|
||||||
|
this->updateFromSelectedSlider();
|
||||||
|
|
||||||
|
fLightsChanged = true;
|
||||||
|
|
||||||
|
this->inval(nullptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int kNumTestRects = 3;
|
static constexpr int kNumTestRects = 3;
|
||||||
|
static constexpr int kNumSliders = 3;
|
||||||
|
|
||||||
static const int kWidth = 400;
|
static const int kWidth = 400;
|
||||||
static const int kHeight = 400;
|
static const int kHeight = 400;
|
||||||
bool fClearShadowMaps;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
SkRect fGeometry;
|
SkRect fGeometry;
|
||||||
int fDepth;
|
int fDepth;
|
||||||
SkColor fColor;
|
SkColor fColor;
|
||||||
} fTestRects[kNumTestRects];
|
} fTestRects[kNumTestRects];
|
||||||
|
|
||||||
int fSelectedRect;
|
int fSelectedRect;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
SkRect fGeometry;
|
||||||
|
SkScalar fOffset;
|
||||||
|
SkScalar fScale;
|
||||||
|
} fSliders[kNumSliders];
|
||||||
|
int fSelectedSlider;
|
||||||
|
|
||||||
|
bool fClearShadowMaps;
|
||||||
bool fMoveLight;
|
bool fMoveLight;
|
||||||
|
|
||||||
sk_sp<SkPicture> fPicture;
|
|
||||||
|
|
||||||
bool fSceneChanged;
|
bool fSceneChanged;
|
||||||
bool fLightsChanged;
|
bool fLightsChanged;
|
||||||
|
|
||||||
|
sk_sp<SkPicture> fPicture;
|
||||||
|
SkShadowParams fShadowParams;
|
||||||
sk_sp<SkLights> fLights;
|
sk_sp<SkLights> fLights;
|
||||||
|
|
||||||
typedef SampleView INHERITED;
|
typedef SampleView INHERITED;
|
||||||
|
@ -38,13 +38,13 @@
|
|||||||
#include "SkTextFormatParams.h"
|
#include "SkTextFormatParams.h"
|
||||||
#include "SkTLazy.h"
|
#include "SkTLazy.h"
|
||||||
#include "SkTraceEvent.h"
|
#include "SkTraceEvent.h"
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
#include "GrContext.h"
|
#include "GrContext.h"
|
||||||
#include "GrRenderTarget.h"
|
#include "GrRenderTarget.h"
|
||||||
#include "SkGrPriv.h"
|
#include "SkGrPriv.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0)
|
#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0)
|
||||||
@ -3163,17 +3163,19 @@ void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
|
|||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
void SkCanvas::drawShadowedPicture(const SkPicture* picture,
|
void SkCanvas::drawShadowedPicture(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params) {
|
||||||
RETURN_ON_NULL(picture);
|
RETURN_ON_NULL(picture);
|
||||||
|
|
||||||
TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()");
|
TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()");
|
||||||
|
|
||||||
this->onDrawShadowedPicture(picture, matrix, paint);
|
this->onDrawShadowedPicture(picture, matrix, paint, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params) {
|
||||||
if (!paint || paint->canComputeFastBounds()) {
|
if (!paint || paint->canComputeFastBounds()) {
|
||||||
SkRect bounds = picture->cullRect();
|
SkRect bounds = picture->cullRect();
|
||||||
if (paint) {
|
if (paint) {
|
||||||
@ -3189,6 +3191,11 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
|||||||
|
|
||||||
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
|
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
|
||||||
|
|
||||||
|
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) {
|
for (int i = 0; i < fLights->numLights(); ++i) {
|
||||||
// skip over ambient lights; they don't cast shadows
|
// skip over ambient lights; they don't cast shadows
|
||||||
// lights that have shadow maps do not need updating (because lights are immutable)
|
// lights that have shadow maps do not need updating (because lights are immutable)
|
||||||
@ -3217,23 +3224,36 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
|||||||
// Wrap another SPFCanvas around the surface
|
// Wrap another SPFCanvas around the surface
|
||||||
sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
|
sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas =
|
||||||
sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
|
sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas());
|
||||||
|
depthMapCanvas->setShadowParams(params);
|
||||||
|
|
||||||
// set the depth map canvas to have the light we're drawing.
|
// set the depth map canvas to have the light we're drawing.
|
||||||
SkLights::Builder builder;
|
SkLights::Builder builder;
|
||||||
builder.add(fLights->light(i));
|
builder.add(fLights->light(i));
|
||||||
sk_sp<SkLights> curLight = builder.finish();
|
sk_sp<SkLights> curLight = builder.finish();
|
||||||
|
|
||||||
depthMapCanvas->setLights(std::move(curLight));
|
depthMapCanvas->setLights(std::move(curLight));
|
||||||
|
|
||||||
depthMapCanvas->drawPicture(picture);
|
depthMapCanvas->drawPicture(picture);
|
||||||
|
sk_sp<SkImage> depthMap = surf->makeImageSnapshot();
|
||||||
|
|
||||||
fLights->light(i).setShadowMap(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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
// povDepthMap
|
// povDepthMap
|
||||||
{
|
{
|
||||||
@ -3259,7 +3279,6 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
|||||||
depthMapCanvas->setLights(std::move(povLight));
|
depthMapCanvas->setLights(std::move(povLight));
|
||||||
|
|
||||||
depthMapCanvas->drawPicture(picture);
|
depthMapCanvas->drawPicture(picture);
|
||||||
|
|
||||||
povDepthMap = surf->makeImageSnapshot();
|
povDepthMap = surf->makeImageSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3275,20 +3294,18 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
|||||||
|
|
||||||
diffuseMap = surf->makeImageSnapshot();
|
diffuseMap = surf->makeImageSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPaint shadowPaint;
|
SkPaint shadowPaint;
|
||||||
|
|
||||||
sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode,
|
sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode,
|
||||||
SkShader::kClamp_TileMode);
|
SkShader::kClamp_TileMode);
|
||||||
|
|
||||||
sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode,
|
sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode,
|
||||||
SkShader::kClamp_TileMode);
|
SkShader::kClamp_TileMode);
|
||||||
|
|
||||||
sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader),
|
sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader),
|
||||||
std::move(diffuseShader),
|
std::move(diffuseShader),
|
||||||
std::move(fLights),
|
std::move(fLights),
|
||||||
diffuseMap->width(),
|
diffuseMap->width(),
|
||||||
diffuseMap->height());
|
diffuseMap->height(),
|
||||||
|
params);
|
||||||
|
|
||||||
shadowPaint.setShader(shadowShader);
|
shadowPaint.setShader(shadowShader);
|
||||||
|
|
||||||
|
@ -270,17 +270,20 @@ namespace {
|
|||||||
};
|
};
|
||||||
struct DrawShadowedPicture final : Op {
|
struct DrawShadowedPicture final : Op {
|
||||||
static const auto kType = Type::DrawShadowedPicture;
|
static const auto kType = Type::DrawShadowedPicture;
|
||||||
DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
|
DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix,
|
||||||
|
const SkPaint* paint, const SkShadowParams& params)
|
||||||
: picture(sk_ref_sp(picture)) {
|
: picture(sk_ref_sp(picture)) {
|
||||||
if (matrix) { this->matrix = *matrix; }
|
if (matrix) { this->matrix = *matrix; }
|
||||||
if (paint) { this->paint = *paint; }
|
if (paint) { this->paint = *paint; }
|
||||||
|
this->params = params;
|
||||||
}
|
}
|
||||||
sk_sp<const SkPicture> picture;
|
sk_sp<const SkPicture> picture;
|
||||||
SkMatrix matrix = SkMatrix::I();
|
SkMatrix matrix = SkMatrix::I();
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
|
SkShadowParams params;
|
||||||
void draw(SkCanvas* c, const SkMatrix&) {
|
void draw(SkCanvas* c, const SkMatrix&) {
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
c->drawShadowedPicture(picture.get(), &matrix, &paint);
|
c->drawShadowedPicture(picture.get(), &matrix, &paint, params);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
|
void makeThreadsafe() { make_threadsafe(nullptr, &matrix); }
|
||||||
@ -615,9 +618,9 @@ void SkLiteDL::drawPicture(const SkPicture* picture,
|
|||||||
const SkMatrix* matrix, const SkPaint* paint) {
|
const SkMatrix* matrix, const SkPaint* paint) {
|
||||||
this->push<DrawPicture>(0, picture, matrix, paint);
|
this->push<DrawPicture>(0, picture, matrix, paint);
|
||||||
}
|
}
|
||||||
void SkLiteDL::drawShadowedPicture(const SkPicture* picture,
|
void SkLiteDL::drawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix,
|
||||||
const SkMatrix* matrix, const SkPaint* paint) {
|
const SkPaint* paint, const SkShadowParams& params) {
|
||||||
this->push<DrawShadowedPicture>(0, picture, matrix, paint);
|
push<DrawShadowedPicture>(0, picture, matrix, paint, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) {
|
void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) {
|
||||||
|
@ -48,7 +48,8 @@ public:
|
|||||||
void drawAnnotation (const SkRect&, const char*, SkData*);
|
void drawAnnotation (const SkRect&, const char*, SkData*);
|
||||||
void drawDrawable (SkDrawable*, const SkMatrix*);
|
void drawDrawable (SkDrawable*, const SkMatrix*);
|
||||||
void drawPicture (const SkPicture*, const SkMatrix*, const SkPaint*);
|
void drawPicture (const SkPicture*, const SkMatrix*, const SkPaint*);
|
||||||
void drawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
|
void drawShadowedPicture(const SkPicture*, const SkMatrix*,
|
||||||
|
const SkPaint*, const SkShadowParams& params);
|
||||||
|
|
||||||
void drawText (const void*, size_t, SkScalar, SkScalar, const SkPaint&);
|
void drawText (const void*, size_t, SkScalar, SkScalar, const SkPaint&);
|
||||||
void drawPosText (const void*, size_t, const SkPoint[], const SkPaint&);
|
void drawPosText (const void*, size_t, const SkPoint[], const SkPaint&);
|
||||||
|
@ -189,6 +189,7 @@ void SkLiteRecorder::didTranslateZ(SkScalar dz) {
|
|||||||
}
|
}
|
||||||
void SkLiteRecorder::onDrawShadowedPicture(const SkPicture* picture,
|
void SkLiteRecorder::onDrawShadowedPicture(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
fDL->drawShadowedPicture(picture, matrix, paint);
|
const SkShadowParams& params) {
|
||||||
|
fDL->drawShadowedPicture(picture, matrix, paint, params);
|
||||||
}
|
}
|
||||||
|
@ -76,10 +76,12 @@ public:
|
|||||||
|
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
void didTranslateZ(SkScalar) override;
|
void didTranslateZ(SkScalar) override;
|
||||||
void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
void onDrawShadowedPicture(const SkPicture*, const SkMatrix*,
|
||||||
|
const SkPaint*, const SkShadowParams& params) override;
|
||||||
#else
|
#else
|
||||||
void didTranslateZ(SkScalar);
|
void didTranslateZ(SkScalar);
|
||||||
void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
|
void onDrawShadowedPicture(const SkPicture*, const SkMatrix*,
|
||||||
|
const SkPaint*, const SkShadowParams& params);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -666,11 +666,13 @@ void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* ma
|
|||||||
|
|
||||||
void SkPictureRecord::onDrawShadowedPicture(const SkPicture* picture,
|
void SkPictureRecord::onDrawShadowedPicture(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params) {
|
||||||
// op + picture index
|
// op + picture index
|
||||||
size_t size = 2 * kUInt32Size;
|
size_t size = 2 * kUInt32Size;
|
||||||
size_t initialOffset;
|
size_t initialOffset;
|
||||||
|
|
||||||
|
// TODO: handle recording params.
|
||||||
if (nullptr == matrix && nullptr == paint) {
|
if (nullptr == matrix && nullptr == paint) {
|
||||||
initialOffset = this->addDraw(DRAW_PICTURE, &size);
|
initialOffset = this->addDraw(DRAW_PICTURE, &size);
|
||||||
this->addPicture(picture);
|
this->addPicture(picture);
|
||||||
|
@ -212,13 +212,11 @@ protected:
|
|||||||
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
||||||
|
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
void onDrawShadowedPicture(const SkPicture*,
|
void onDrawShadowedPicture(const SkPicture*, const SkMatrix*,
|
||||||
const SkMatrix*,
|
const SkPaint*, const SkShadowParams& params) override;
|
||||||
const SkPaint*) override;
|
|
||||||
#else
|
#else
|
||||||
void onDrawShadowedPicture(const SkPicture*,
|
void onDrawShadowedPicture(const SkPicture*, const SkMatrix*,
|
||||||
const SkMatrix*,
|
const SkPaint*, const SkShadowParams& params);
|
||||||
const SkPaint*);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
|
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
|
||||||
|
@ -118,7 +118,7 @@ DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.xmode, r.paint));
|
|||||||
DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint));
|
DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint));
|
||||||
|
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture.get(), &r.matrix, r.paint));
|
DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture.get(), &r.matrix, r.paint, r.params));
|
||||||
#else
|
#else
|
||||||
template <> void Draw::draw(const DrawShadowedPicture& r) { }
|
template <> void Draw::draw(const DrawShadowedPicture& r) { }
|
||||||
#endif
|
#endif
|
||||||
|
@ -303,15 +303,16 @@ void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkRecorder::onDrawShadowedPicture(const SkPicture* pic,
|
void SkRecorder::onDrawShadowedPicture(const SkPicture* pic, const SkMatrix* matrix,
|
||||||
const SkMatrix* matrix,
|
const SkPaint* paint, const SkShadowParams& params) {
|
||||||
const SkPaint* paint) {
|
|
||||||
if (fDrawPictureMode == Record_DrawPictureMode) {
|
if (fDrawPictureMode == Record_DrawPictureMode) {
|
||||||
fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic);
|
fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic);
|
||||||
APPEND(DrawShadowedPicture, this->copy(paint),
|
APPEND(DrawShadowedPicture, this->copy(paint),
|
||||||
sk_ref_sp(pic),
|
sk_ref_sp(pic),
|
||||||
matrix ? *matrix : SkMatrix::I());
|
matrix ? *matrix : SkMatrix::I(),
|
||||||
|
params);
|
||||||
} else {
|
} else {
|
||||||
|
// TODO update pic->playback(this) to draw the shadowed pic
|
||||||
SkASSERT(fDrawPictureMode == Playback_DrawPictureMode);
|
SkASSERT(fDrawPictureMode == Playback_DrawPictureMode);
|
||||||
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, pic->cullRect());
|
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, pic->cullRect());
|
||||||
pic->playback(this);
|
pic->playback(this);
|
||||||
|
@ -141,11 +141,13 @@ public:
|
|||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
void onDrawShadowedPicture(const SkPicture*,
|
void onDrawShadowedPicture(const SkPicture*,
|
||||||
const SkMatrix*,
|
const SkMatrix*,
|
||||||
const SkPaint*) override;
|
const SkPaint*,
|
||||||
|
const SkShadowParams& params) override;
|
||||||
#else
|
#else
|
||||||
void onDrawShadowedPicture(const SkPicture*,
|
void onDrawShadowedPicture(const SkPicture*,
|
||||||
const SkMatrix*,
|
const SkMatrix*,
|
||||||
const SkPaint*);
|
const SkPaint*,
|
||||||
|
const SkShadowParams& params);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
|
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
|
||||||
|
@ -5,11 +5,9 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "SkCanvas.h"
|
||||||
#include "SkLights.h"
|
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
#include "SkShadowShader.h"
|
#include "SkShadowShader.h"
|
||||||
#include "SkPoint3.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
@ -26,12 +24,14 @@ public:
|
|||||||
SkShadowShaderImpl(sk_sp<SkShader> povDepthShader,
|
SkShadowShaderImpl(sk_sp<SkShader> povDepthShader,
|
||||||
sk_sp<SkShader> diffuseShader,
|
sk_sp<SkShader> diffuseShader,
|
||||||
sk_sp<SkLights> lights,
|
sk_sp<SkLights> lights,
|
||||||
int diffuseWidth, int diffuseHeight)
|
int diffuseWidth, int diffuseHeight,
|
||||||
|
const SkShadowParams& params)
|
||||||
: fPovDepthShader(std::move(povDepthShader))
|
: fPovDepthShader(std::move(povDepthShader))
|
||||||
, fDiffuseShader(std::move(diffuseShader))
|
, fDiffuseShader(std::move(diffuseShader))
|
||||||
, fLights(std::move(lights))
|
, fLights(std::move(lights))
|
||||||
, fDiffuseWidth(diffuseWidth)
|
, fDiffuseWidth(diffuseWidth)
|
||||||
, fDiffuseHeight(diffuseHeight) { }
|
, fDiffuseHeight(diffuseHeight)
|
||||||
|
, fShadowParams(params) { }
|
||||||
|
|
||||||
bool isOpaque() const override;
|
bool isOpaque() const override;
|
||||||
|
|
||||||
@ -80,6 +80,8 @@ private:
|
|||||||
int fDiffuseWidth;
|
int fDiffuseWidth;
|
||||||
int fDiffuseHeight;
|
int fDiffuseHeight;
|
||||||
|
|
||||||
|
SkShadowParams fShadowParams;
|
||||||
|
|
||||||
friend class SkShadowShader;
|
friend class SkShadowShader;
|
||||||
|
|
||||||
typedef SkShader INHERITED;
|
typedef SkShader INHERITED;
|
||||||
@ -106,6 +108,7 @@ public:
|
|||||||
sk_sp<GrFragmentProcessor> diffuse,
|
sk_sp<GrFragmentProcessor> diffuse,
|
||||||
sk_sp<SkLights> lights,
|
sk_sp<SkLights> lights,
|
||||||
int diffuseWidth, int diffuseHeight,
|
int diffuseWidth, int diffuseHeight,
|
||||||
|
const SkShadowParams& params,
|
||||||
GrContext* context) {
|
GrContext* context) {
|
||||||
|
|
||||||
// fuse all ambient lights into a single one
|
// fuse all ambient lights into a single one
|
||||||
@ -137,6 +140,8 @@ public:
|
|||||||
fWidth = diffuseWidth;
|
fWidth = diffuseWidth;
|
||||||
fHeight = diffuseHeight;
|
fHeight = diffuseHeight;
|
||||||
|
|
||||||
|
fShadowParams = params;
|
||||||
|
|
||||||
this->registerChildProcessor(std::move(povDepth));
|
this->registerChildProcessor(std::move(povDepth));
|
||||||
this->registerChildProcessor(std::move(diffuse));
|
this->registerChildProcessor(std::move(diffuse));
|
||||||
this->initClassID<ShadowFP>();
|
this->initClassID<ShadowFP>();
|
||||||
@ -155,6 +160,8 @@ public:
|
|||||||
int32_t numLights = args.fFp.cast<ShadowFP>().fNumDirLights;
|
int32_t numLights = args.fFp.cast<ShadowFP>().fNumDirLights;
|
||||||
SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights);
|
SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights);
|
||||||
|
|
||||||
|
int blurAlgorithm = args.fFp.cast<ShadowFP>().fShadowParams.fType;
|
||||||
|
|
||||||
const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
|
const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
|
||||||
const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
|
const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
|
||||||
|
|
||||||
@ -203,6 +210,17 @@ public:
|
|||||||
&depthMapHeightUniName[i]);
|
&depthMapHeightUniName[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* shBiasUniName = nullptr;
|
||||||
|
const char* minVarianceUniName = nullptr;
|
||||||
|
|
||||||
|
fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||||
|
kFloat_GrSLType,
|
||||||
|
kDefault_GrSLPrecision,
|
||||||
|
"shadowBias", &shBiasUniName);
|
||||||
|
fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||||
|
kFloat_GrSLType,
|
||||||
|
kDefault_GrSLPrecision,
|
||||||
|
"minVariance", &minVarianceUniName);
|
||||||
|
|
||||||
const char* widthUniName = nullptr;
|
const char* widthUniName = nullptr;
|
||||||
const char* heightUniName = nullptr;
|
const char* heightUniName = nullptr;
|
||||||
@ -254,17 +272,17 @@ public:
|
|||||||
fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n",
|
fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n",
|
||||||
scaleOffsetVec.c_str(), scaleVec.c_str());
|
scaleOffsetVec.c_str(), scaleVec.c_str());
|
||||||
|
|
||||||
|
|
||||||
fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + "
|
fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + "
|
||||||
"vec2(%s.x, 0 - %s.y)) "
|
"vec2(%s.x, 0 - %s.y)) "
|
||||||
" * %s + vec2(0,1) * %s;\n",
|
" * %s + vec2(0,1) * %s;\n",
|
||||||
|
|
||||||
povCoord.c_str(), offset.c_str(), offset.c_str(),
|
povCoord.c_str(), offset.c_str(), offset.c_str(),
|
||||||
scaleVec.c_str(), scaleOffsetVec.c_str());
|
scaleVec.c_str(), scaleOffsetVec.c_str());
|
||||||
|
|
||||||
fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSamplers[i],
|
fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSamplers[i],
|
||||||
povCoord.c_str(),
|
povCoord.c_str(),
|
||||||
kVec2f_GrSLType);
|
kVec2f_GrSLType);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ambientColorUniName = nullptr;
|
const char* ambientColorUniName = nullptr;
|
||||||
@ -274,25 +292,58 @@ public:
|
|||||||
|
|
||||||
fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseColor.c_str());
|
fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseColor.c_str());
|
||||||
|
|
||||||
// Essentially,
|
|
||||||
// diffColor * (ambientLightTot + foreachDirLight(lightColor * (N . L)))
|
|
||||||
SkString totalLightColor("totalLightColor");
|
SkString totalLightColor("totalLightColor");
|
||||||
fragBuilder->codeAppendf("vec3 %s = vec3(0);", totalLightColor.c_str());
|
fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c_str());
|
||||||
|
|
||||||
|
fragBuilder->codeAppendf("float lightProbability;");
|
||||||
|
fragBuilder->codeAppendf("float variance;");
|
||||||
|
fragBuilder->codeAppendf("float d;");
|
||||||
|
|
||||||
for (int i = 0; i < numLights; i++) {
|
for (int i = 0; i < numLights; i++) {
|
||||||
|
fragBuilder->codeAppendf("lightProbability = 1;");
|
||||||
|
|
||||||
|
// 1/512 is less than half a pixel; imperceptible
|
||||||
|
fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {",
|
||||||
|
povDepth.c_str(), depthMaps[i].c_str());
|
||||||
|
if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) {
|
||||||
|
fragBuilder->codeAppendf("vec2 moments = vec2(%s.b * 255, %s.g * 255 * 256 );",
|
||||||
|
depthMaps[i].c_str(), depthMaps[i].c_str());
|
||||||
|
|
||||||
|
// variance biasing lessens light bleeding
|
||||||
|
fragBuilder->codeAppendf("variance = max(moments.y - (moments.x * moments.x),"
|
||||||
|
"%s);", minVarianceUniName);
|
||||||
|
|
||||||
|
fragBuilder->codeAppendf("d = (%s.b * 255) - moments.x;", povDepth.c_str());
|
||||||
|
fragBuilder->codeAppendf("lightProbability = "
|
||||||
|
"(variance / (variance + d * d));");
|
||||||
|
|
||||||
|
SkString clamp("clamp");
|
||||||
|
clamp.appendf("%d", i);
|
||||||
|
|
||||||
|
// choosing between light artifacts or correct shape shadows
|
||||||
|
// linstep
|
||||||
|
fragBuilder->codeAppendf("float %s = clamp((lightProbability - %s) /"
|
||||||
|
"(1 - %s), 0, 1);",
|
||||||
|
clamp.c_str(), shBiasUniName, shBiasUniName);
|
||||||
|
|
||||||
|
fragBuilder->codeAppendf("lightProbability = %s;", clamp.c_str());
|
||||||
|
} else {
|
||||||
fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
|
fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
|
||||||
povDepth.c_str(), depthMaps[i].c_str());
|
povDepth.c_str(), depthMaps[i].c_str());
|
||||||
// Note that dot(vec3(0,0,1), %s) == %s.z * %s
|
fragBuilder->codeAppendf("lightProbability = 1;");
|
||||||
fragBuilder->codeAppendf("%s += %s.z * %s;",
|
fragBuilder->codeAppendf("} else { lightProbability = 0; }");
|
||||||
|
}
|
||||||
|
|
||||||
|
// VSM: The curved shadows near plane edges are mostly light bleeding.
|
||||||
|
fragBuilder->codeAppendf("}");
|
||||||
|
|
||||||
|
fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * lightProbability;",
|
||||||
totalLightColor.c_str(),
|
totalLightColor.c_str(),
|
||||||
lightDirUniName[i],
|
lightDirUniName[i],
|
||||||
lightColorUniName[i]);
|
lightColorUniName[i]);
|
||||||
fragBuilder->codeAppendf("}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fragBuilder->codeAppendf("%s += %s;",
|
fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambientColorUniName);
|
||||||
totalLightColor.c_str(),
|
|
||||||
ambientColorUniName);
|
|
||||||
|
|
||||||
fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);",
|
fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);",
|
||||||
totalLightColor.c_str());
|
totalLightColor.c_str());
|
||||||
@ -304,15 +355,14 @@ public:
|
|||||||
GrProcessorKeyBuilder* b) {
|
GrProcessorKeyBuilder* b) {
|
||||||
const ShadowFP& shadowFP = proc.cast<ShadowFP>();
|
const ShadowFP& shadowFP = proc.cast<ShadowFP>();
|
||||||
b->add32(shadowFP.fNumDirLights);
|
b->add32(shadowFP.fNumDirLights);
|
||||||
|
b->add32(shadowFP.fShadowParams.fType);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
|
void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
|
||||||
const ShadowFP &shadowFP = proc.cast<ShadowFP>();
|
const ShadowFP &shadowFP = proc.cast<ShadowFP>();
|
||||||
|
|
||||||
fNumDirLights = shadowFP.numLights();
|
for (int i = 0; i < shadowFP.fNumDirLights; i++) {
|
||||||
|
|
||||||
for (int i = 0; i < fNumDirLights; i++) {
|
|
||||||
const SkVector3& lightDir = shadowFP.lightDir(i);
|
const SkVector3& lightDir = shadowFP.lightDir(i);
|
||||||
if (lightDir != fLightDir[i]) {
|
if (lightDir != fLightDir[i]) {
|
||||||
pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX);
|
pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX);
|
||||||
@ -336,6 +386,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkScalar biasingConstant = shadowFP.shadowParams().fBiasingConstant;
|
||||||
|
if (biasingConstant != fBiasingConstant) {
|
||||||
|
pdman.set1f(fBiasingConstantUni, biasingConstant);
|
||||||
|
fBiasingConstant = biasingConstant;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkScalar minVariance = shadowFP.shadowParams().fMinVariance;
|
||||||
|
if (minVariance != fMinVariance) {
|
||||||
|
pdman.set1f(fMinVarianceUni, minVariance);
|
||||||
|
fMinVariance = minVariance;
|
||||||
|
}
|
||||||
|
|
||||||
int width = shadowFP.width();
|
int width = shadowFP.width();
|
||||||
if (width != fWidth) {
|
if (width != fWidth) {
|
||||||
pdman.set1i(fWidthUni, width);
|
pdman.set1i(fWidthUni, width);
|
||||||
@ -376,10 +438,13 @@ public:
|
|||||||
int fHeight;
|
int fHeight;
|
||||||
GrGLSLProgramDataManager::UniformHandle fHeightUni;
|
GrGLSLProgramDataManager::UniformHandle fHeightUni;
|
||||||
|
|
||||||
|
SkScalar fBiasingConstant;
|
||||||
|
GrGLSLProgramDataManager::UniformHandle fBiasingConstantUni;
|
||||||
|
SkScalar fMinVariance;
|
||||||
|
GrGLSLProgramDataManager::UniformHandle fMinVarianceUni;
|
||||||
|
|
||||||
SkColor3f fAmbientColor;
|
SkColor3f fAmbientColor;
|
||||||
GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
|
GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
|
||||||
|
|
||||||
int fNumDirLights;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
|
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
|
||||||
@ -413,6 +478,8 @@ public:
|
|||||||
int width() const {return fWidth; }
|
int width() const {return fWidth; }
|
||||||
int height() const {return fHeight; }
|
int height() const {return fHeight; }
|
||||||
|
|
||||||
|
const SkShadowParams& shadowParams() const {return fShadowParams; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; }
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; }
|
||||||
|
|
||||||
@ -454,6 +521,8 @@ private:
|
|||||||
int fHeight;
|
int fHeight;
|
||||||
int fWidth;
|
int fWidth;
|
||||||
|
|
||||||
|
SkShadowParams fShadowParams;
|
||||||
|
|
||||||
SkColor3f fAmbientColor;
|
SkColor3f fAmbientColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -469,7 +538,7 @@ sk_sp<GrFragmentProcessor> SkShadowShaderImpl::asFragmentProcessor(const AsFPArg
|
|||||||
std::move(diffuseFP),
|
std::move(diffuseFP),
|
||||||
std::move(fLights),
|
std::move(fLights),
|
||||||
fDiffuseWidth, fDiffuseHeight,
|
fDiffuseWidth, fDiffuseHeight,
|
||||||
fpargs.fContext);
|
fShadowParams, fpargs.fContext);
|
||||||
return shadowfp;
|
return shadowfp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,6 +663,12 @@ sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) {
|
|||||||
|
|
||||||
sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf);
|
sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf);
|
||||||
|
|
||||||
|
SkShadowParams params;
|
||||||
|
params.fMinVariance = buf.readScalar();
|
||||||
|
params.fBiasingConstant = buf.readScalar();
|
||||||
|
params.fType = (SkShadowParams::ShadowType) buf.readInt();
|
||||||
|
params.fShadowRadius = buf.readScalar();
|
||||||
|
|
||||||
int diffuseWidth = buf.readInt();
|
int diffuseWidth = buf.readInt();
|
||||||
int diffuseHeight = buf.readInt();
|
int diffuseHeight = buf.readInt();
|
||||||
|
|
||||||
@ -603,7 +678,8 @@ sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) {
|
|||||||
return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader),
|
return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader),
|
||||||
std::move(diffuseShader),
|
std::move(diffuseShader),
|
||||||
std::move(lights),
|
std::move(lights),
|
||||||
diffuseWidth, diffuseHeight);
|
diffuseWidth, diffuseHeight,
|
||||||
|
params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const {
|
void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const {
|
||||||
@ -611,6 +687,11 @@ void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const {
|
|||||||
|
|
||||||
fLights->flatten(buf);
|
fLights->flatten(buf);
|
||||||
|
|
||||||
|
buf.writeScalar(fShadowParams.fMinVariance);
|
||||||
|
buf.writeScalar(fShadowParams.fBiasingConstant);
|
||||||
|
buf.writeInt(fShadowParams.fType);
|
||||||
|
buf.writeScalar(fShadowParams.fShadowRadius);
|
||||||
|
|
||||||
buf.writeInt(fDiffuseWidth);
|
buf.writeInt(fDiffuseWidth);
|
||||||
buf.writeInt(fDiffuseHeight);
|
buf.writeInt(fDiffuseHeight);
|
||||||
|
|
||||||
@ -656,7 +737,8 @@ SkShader::Context* SkShadowShaderImpl::onCreateContext(const ContextRec& rec,
|
|||||||
sk_sp<SkShader> SkShadowShader::Make(sk_sp<SkShader> povDepthShader,
|
sk_sp<SkShader> SkShadowShader::Make(sk_sp<SkShader> povDepthShader,
|
||||||
sk_sp<SkShader> diffuseShader,
|
sk_sp<SkShader> diffuseShader,
|
||||||
sk_sp<SkLights> lights,
|
sk_sp<SkLights> lights,
|
||||||
int diffuseWidth, int diffuseHeight) {
|
int diffuseWidth, int diffuseHeight,
|
||||||
|
const SkShadowParams& params) {
|
||||||
if (!povDepthShader || !diffuseShader) {
|
if (!povDepthShader || !diffuseShader) {
|
||||||
// TODO: Use paint's color in absence of a diffuseShader
|
// TODO: Use paint's color in absence of a diffuseShader
|
||||||
// TODO: Use a default implementation of normalSource instead
|
// TODO: Use a default implementation of normalSource instead
|
||||||
@ -666,7 +748,8 @@ sk_sp<SkShader> SkShadowShader::Make(sk_sp<SkShader> povDepthShader,
|
|||||||
return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader),
|
return sk_make_sp<SkShadowShaderImpl>(std::move(povDepthShader),
|
||||||
std::move(diffuseShader),
|
std::move(diffuseShader),
|
||||||
std::move(lights),
|
std::move(lights),
|
||||||
diffuseWidth, diffuseHeight);
|
diffuseWidth, diffuseHeight,
|
||||||
|
params);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -23,7 +23,8 @@ public:
|
|||||||
static sk_sp<SkShader> Make(sk_sp<SkShader> povDepthShader,
|
static sk_sp<SkShader> Make(sk_sp<SkShader> povDepthShader,
|
||||||
sk_sp<SkShader> diffuseShader,
|
sk_sp<SkShader> diffuseShader,
|
||||||
sk_sp<SkLights> lights,
|
sk_sp<SkLights> lights,
|
||||||
int diffuseWidth, int diffuseHeight);
|
int diffuseWidth, int diffuseHeight,
|
||||||
|
const SkShadowParams& params);
|
||||||
|
|
||||||
// The shadow shader supports any number of ambient lights, but only
|
// The shadow shader supports any number of ambient lights, but only
|
||||||
// 4 non-ambient lights (currently just refers to directional lights).
|
// 4 non-ambient lights (currently just refers to directional lights).
|
||||||
|
@ -11,7 +11,12 @@
|
|||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
|
|
||||||
SkShadowPaintFilterCanvas::SkShadowPaintFilterCanvas(SkCanvas *canvas)
|
SkShadowPaintFilterCanvas::SkShadowPaintFilterCanvas(SkCanvas *canvas)
|
||||||
: SkPaintFilterCanvas(canvas) { }
|
: SkPaintFilterCanvas(canvas) {
|
||||||
|
fShadowParams.fShadowRadius = 0.0f;
|
||||||
|
fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType;
|
||||||
|
fShadowParams.fBiasingConstant = 0.0f;
|
||||||
|
fShadowParams.fMinVariance = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO use a shader instead
|
// TODO use a shader instead
|
||||||
bool SkShadowPaintFilterCanvas::onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const {
|
bool SkShadowPaintFilterCanvas::onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const {
|
||||||
@ -24,6 +29,17 @@ bool SkShadowPaintFilterCanvas::onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Ty
|
|||||||
|
|
||||||
SkColor color = 0xFF000000; // init color to opaque black
|
SkColor color = 0xFF000000; // init color to opaque black
|
||||||
color |= z; // Put the index into the blue component
|
color |= z; // Put the index into the blue component
|
||||||
|
|
||||||
|
if (fShadowParams.fType == SkShadowParams::kVariance_ShadowType) {
|
||||||
|
int z2 = z * z;
|
||||||
|
if (z2 > 255 * 256) {
|
||||||
|
color |= 0xff00;
|
||||||
|
} else {
|
||||||
|
// Let's only store the more significant bits of z2 to save space.
|
||||||
|
// In practice, this should barely impact shadow blur quality.
|
||||||
|
color |= z2 & 0x0000ff00;
|
||||||
|
}
|
||||||
|
}
|
||||||
newPaint.setColor(color);
|
newPaint.setColor(color);
|
||||||
|
|
||||||
*paint->writable() = newPaint;
|
*paint->writable() = newPaint;
|
||||||
@ -42,6 +58,9 @@ SkISize SkShadowPaintFilterCanvas::ComputeDepthMapSize(const SkLights::Light& li
|
|||||||
return SkISize::Make(dMapWidth, dMapHeight);
|
return SkISize::Make(dMapWidth, dMapHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkShadowPaintFilterCanvas::setShadowParams(const SkShadowParams ¶ms) {
|
||||||
|
fShadowParams = params;
|
||||||
|
}
|
||||||
|
|
||||||
void SkShadowPaintFilterCanvas::onDrawPicture(const SkPicture *picture, const SkMatrix *matrix,
|
void SkShadowPaintFilterCanvas::onDrawPicture(const SkPicture *picture, const SkMatrix *matrix,
|
||||||
const SkPaint *paint) {
|
const SkPaint *paint) {
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
static SkISize ComputeDepthMapSize(const SkLights::Light& light, int maxDepth,
|
static SkISize ComputeDepthMapSize(const SkLights::Light& light, int maxDepth,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
|
void setShadowParams(const SkShadowParams ¶ms);
|
||||||
protected:
|
protected:
|
||||||
void onDrawPicture(const SkPicture *picture, const SkMatrix *matrix,
|
void onDrawPicture(const SkPicture *picture, const SkMatrix *matrix,
|
||||||
const SkPaint *paint) override;
|
const SkPaint *paint) override;
|
||||||
@ -107,6 +108,7 @@ protected:
|
|||||||
void onDrawTextBlob(const SkTextBlob *blob, SkScalar x,
|
void onDrawTextBlob(const SkTextBlob *blob, SkScalar x,
|
||||||
SkScalar y, const SkPaint &paint) override;
|
SkScalar y, const SkPaint &paint) override;
|
||||||
private:
|
private:
|
||||||
|
SkShadowParams fShadowParams;
|
||||||
typedef SkPaintFilterCanvas INHERITED;
|
typedef SkPaintFilterCanvas INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,9 +60,10 @@ protected:
|
|||||||
|
|
||||||
void onDrawShadowedPicture(const SkPicture* picture,
|
void onDrawShadowedPicture(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params) {
|
||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
this->SkCanvas::onDrawShadowedPicture(picture, matrix, paint);
|
this->SkCanvas::onDrawShadowedPicture(picture, matrix, paint, params);
|
||||||
#else
|
#else
|
||||||
this->SkCanvas::onDrawPicture(picture, matrix, paint);
|
this->SkCanvas::onDrawPicture(picture, matrix, paint);
|
||||||
#endif
|
#endif
|
||||||
@ -620,8 +621,9 @@ void SkDebugCanvas::onDrawPicture(const SkPicture* picture,
|
|||||||
|
|
||||||
void SkDebugCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
void SkDebugCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint,
|
||||||
this->addDrawCommand(new SkBeginDrawShadowedPictureCommand(picture, matrix, paint));
|
const SkShadowParams& params) {
|
||||||
|
this->addDrawCommand(new SkBeginDrawShadowedPictureCommand(picture, matrix, paint, params));
|
||||||
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
|
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
|
||||||
picture->playback(this);
|
picture->playback(this);
|
||||||
this->addDrawCommand(new SkEndDrawShadowedPictureCommand(SkToBool(matrix) || SkToBool(paint)));
|
this->addDrawCommand(new SkEndDrawShadowedPictureCommand(SkToBool(matrix) || SkToBool(paint)));
|
||||||
|
@ -258,11 +258,13 @@ protected:
|
|||||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
void onDrawShadowedPicture(const SkPicture*,
|
void onDrawShadowedPicture(const SkPicture*,
|
||||||
const SkMatrix*,
|
const SkMatrix*,
|
||||||
const SkPaint*) override;
|
const SkPaint*,
|
||||||
|
const SkShadowParams& params) override;
|
||||||
#else
|
#else
|
||||||
void onDrawShadowedPicture(const SkPicture*,
|
void onDrawShadowedPicture(const SkPicture*,
|
||||||
const SkMatrix*,
|
const SkMatrix*,
|
||||||
const SkPaint*);
|
const SkPaint*,
|
||||||
|
const SkShadowParams& params);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void markActiveCommands(int index);
|
void markActiveCommands(int index);
|
||||||
|
@ -2449,14 +2449,35 @@ void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
|
|||||||
|
|
||||||
SkBeginDrawShadowedPictureCommand::SkBeginDrawShadowedPictureCommand(const SkPicture* picture,
|
SkBeginDrawShadowedPictureCommand::SkBeginDrawShadowedPictureCommand(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint)
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params)
|
||||||
: INHERITED(kBeginDrawShadowedPicture_OpType)
|
: INHERITED(kBeginDrawShadowedPicture_OpType)
|
||||||
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
|
, fPicture(SkRef(picture))
|
||||||
|
, fShadowParams(params) {
|
||||||
|
#else
|
||||||
, fPicture(SkRef(picture)) {
|
, fPicture(SkRef(picture)) {
|
||||||
|
#endif
|
||||||
SkString* str = new SkString;
|
SkString* str = new SkString;
|
||||||
str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
|
str->appendf("SkPicture: L: %f T: %f R: %f B: %f\n",
|
||||||
picture->cullRect().fLeft, picture->cullRect().fTop,
|
picture->cullRect().fLeft, picture->cullRect().fTop,
|
||||||
picture->cullRect().fRight, picture->cullRect().fBottom);
|
picture->cullRect().fRight, picture->cullRect().fBottom);
|
||||||
|
str->appendf("SkShadowParams: bias:%f, minVariance:%f, shRadius:%f, shType:",
|
||||||
|
params.fBiasingConstant,
|
||||||
|
params.fMinVariance,
|
||||||
|
params.fShadowRadius);
|
||||||
|
|
||||||
|
SkASSERT(SkShadowParams::kShadowTypeCount == 2);
|
||||||
|
|
||||||
|
switch (params.fType) {
|
||||||
|
case SkShadowParams::ShadowType::kNoBlur_ShadowType:
|
||||||
|
str->append("kNoBlur_ShadowType\n");
|
||||||
|
break;
|
||||||
|
case SkShadowParams::ShadowType::kVariance_ShadowType:
|
||||||
|
str->append("kVariance_ShadowType\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
fInfo.push(str);
|
fInfo.push(str);
|
||||||
|
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
@ -2492,9 +2513,11 @@ bool SkBeginDrawShadowedPictureCommand::render(SkCanvas* canvas) const {
|
|||||||
canvas->save();
|
canvas->save();
|
||||||
|
|
||||||
xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
|
xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
|
||||||
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
canvas->drawPicture(fPicture.get());
|
canvas->drawShadowedPicture(fPicture.get(), fMatrix.get(), fPaint.get(), fShadowParams);
|
||||||
|
#else
|
||||||
|
canvas->drawPicture(fPicture.get(), fMatrix.get(), fPaint.get());
|
||||||
|
#endif
|
||||||
canvas->restore();
|
canvas->restore();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -480,7 +480,8 @@ class SkBeginDrawShadowedPictureCommand : public SkDrawCommand {
|
|||||||
public:
|
public:
|
||||||
SkBeginDrawShadowedPictureCommand(const SkPicture* picture,
|
SkBeginDrawShadowedPictureCommand(const SkPicture* picture,
|
||||||
const SkMatrix* matrix,
|
const SkMatrix* matrix,
|
||||||
const SkPaint* paint);
|
const SkPaint* paint,
|
||||||
|
const SkShadowParams& params);
|
||||||
|
|
||||||
void execute(SkCanvas* canvas) const override;
|
void execute(SkCanvas* canvas) const override;
|
||||||
bool render(SkCanvas* canvas) const override;
|
bool render(SkCanvas* canvas) const override;
|
||||||
@ -489,6 +490,9 @@ private:
|
|||||||
SkAutoTUnref<const SkPicture> fPicture;
|
SkAutoTUnref<const SkPicture> fPicture;
|
||||||
SkTLazy<SkMatrix> fMatrix;
|
SkTLazy<SkMatrix> fMatrix;
|
||||||
SkTLazy<SkPaint> fPaint;
|
SkTLazy<SkPaint> fPaint;
|
||||||
|
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||||
|
SkShadowParams fShadowParams;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef SkDrawCommand INHERITED;
|
typedef SkDrawCommand INHERITED;
|
||||||
};
|
};
|
||||||
@ -796,3 +800,4 @@ private:
|
|||||||
typedef SkDrawCommand INHERITED;
|
typedef SkDrawCommand INHERITED;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user