move shadows to device virtual
This CL keeps the impl for each device backend in the utils file for simplicity (shared helpers). Future CLs may move into their respective impl as they become more specialized. Bug: skia: Change-Id: I97ce6cdcc5106ebf4c84778f943cc32d0b7613c1 Reviewed-on: https://skia-review.googlesource.com/15893 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
63e7973d1f
commit
4204da25aa
@ -24,6 +24,7 @@ class SkData;
|
||||
class SkDraw;
|
||||
class SkDrawable;
|
||||
class SkDrawFilter;
|
||||
struct SkDrawShadowRec;
|
||||
class SkImage;
|
||||
class SkImageFilter;
|
||||
class SkLights;
|
||||
@ -1237,6 +1238,8 @@ public:
|
||||
*/
|
||||
void temporary_internal_getRgnClip(SkRegion* region);
|
||||
|
||||
void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
|
||||
|
||||
protected:
|
||||
// default impl defers to getDevice()->newSurface(info)
|
||||
virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
|
||||
@ -1331,6 +1334,7 @@ protected:
|
||||
const SkPaint* paint);
|
||||
virtual void onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
|
||||
const SkRect& dst, const SkPaint* paint);
|
||||
virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
|
||||
|
||||
enum ClipEdgeStyle {
|
||||
kHard_ClipEdgeStyle,
|
||||
|
@ -71,6 +71,7 @@ protected:
|
||||
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*) override;
|
||||
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
|
||||
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
|
||||
|
||||
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
|
@ -1909,6 +1909,21 @@ void SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
}
|
||||
}
|
||||
|
||||
void SkCanvas::private_draw_shadow_rec(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
this->onDrawShadowRec(path, rec);
|
||||
}
|
||||
|
||||
void SkCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
SkPaint paint;
|
||||
const SkRect& pathBounds = path.getBounds();
|
||||
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds)
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawShadow(path, rec);
|
||||
}
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// These are the virtual drawing methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkColorSpaceXformCanvas.h"
|
||||
#include "SkColorSpaceXformer.h"
|
||||
#include "SkDrawShadowRec.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkImagePriv.h"
|
||||
@ -217,7 +218,11 @@ public:
|
||||
fTarget->drawImageLattice(fXformer->apply(bitmap).get(), lattice, dst,
|
||||
MaybePaint(paint, fXformer.get()));
|
||||
}
|
||||
|
||||
void onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) override {
|
||||
SkDrawShadowRec newRec(rec);
|
||||
newRec.fColor = fXformer->apply(rec.fColor);
|
||||
fTarget->private_draw_shadow_rec(path, newRec);
|
||||
}
|
||||
void onDrawPicture(const SkPicture* pic,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) override {
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
class SkBitmap;
|
||||
class SkDrawFilter;
|
||||
struct SkDrawShadowRec;
|
||||
class SkImageFilterCache;
|
||||
struct SkIRect;
|
||||
class SkMatrix;
|
||||
@ -234,6 +235,8 @@ protected:
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) = 0;
|
||||
virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) = 0;
|
||||
virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
|
||||
|
||||
// default implementation unrolls the blob runs.
|
||||
virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter);
|
||||
|
23
src/core/SkDrawShadowRec.h
Normal file
23
src/core/SkDrawShadowRec.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDrawShadowRec_DEFINED
|
||||
#define SkDrawShadowRec_DEFINED
|
||||
|
||||
#include "SkPath.h"
|
||||
|
||||
struct SkDrawShadowRec {
|
||||
SkPoint3 fZPlaneParams;
|
||||
SkPoint3 fLightPos;
|
||||
SkScalar fLightRadius;
|
||||
float fAmbientAlpha;
|
||||
float fSpotAlpha;
|
||||
SkColor fColor;
|
||||
uint32_t fFlags;
|
||||
};
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkData.h"
|
||||
#include "SkDrawFilter.h"
|
||||
#include "SkDrawShadowRec.h"
|
||||
#include "SkImage.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkLiteDL.h"
|
||||
@ -55,7 +56,7 @@ namespace {
|
||||
M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) \
|
||||
M(DrawText) M(DrawPosText) M(DrawPosTextH) \
|
||||
M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob) \
|
||||
M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas)
|
||||
M(DrawPatch) M(DrawPoints) M(DrawVertices) M(DrawAtlas) M(DrawShadowRec)
|
||||
|
||||
#define M(T) T,
|
||||
enum class Type : uint8_t { TYPES(M) };
|
||||
@ -477,6 +478,17 @@ namespace {
|
||||
maybe_unset(cull), &paint);
|
||||
}
|
||||
};
|
||||
struct DrawShadowRec final : Op {
|
||||
static const auto kType = Type::DrawShadowRec;
|
||||
DrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec)
|
||||
: fPath(path), fRec(rec)
|
||||
{}
|
||||
SkPath fPath;
|
||||
SkDrawShadowRec fRec;
|
||||
void draw(SkCanvas* c, const SkMatrix&) const {
|
||||
c->private_draw_shadow_rec(fPath, fRec);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
@ -662,6 +674,9 @@ void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const S
|
||||
texs, count,
|
||||
colors, colors ? count : 0);
|
||||
}
|
||||
void SkLiteDL::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
this->push<DrawShadowRec>(0, path, rec);
|
||||
}
|
||||
|
||||
typedef void(*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
|
||||
typedef void(*void_fn)(const void*);
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&);
|
||||
void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
|
||||
SkBlendMode, const SkRect*, const SkPaint*);
|
||||
void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
|
||||
|
||||
private:
|
||||
template <typename T, typename... Args>
|
||||
|
@ -194,3 +194,6 @@ void SkLiteRecorder::onDrawAtlas(const SkImage* atlas,
|
||||
const SkPaint* paint) {
|
||||
fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, cull, paint);
|
||||
}
|
||||
void SkLiteRecorder::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
fDL->drawShadowRec(path, rec);
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int, SkBlendMode, const SkRect*, const SkPaint*) override;
|
||||
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
|
||||
|
||||
private:
|
||||
typedef SkNoDrawCanvas INHERITED;
|
||||
|
@ -125,6 +125,7 @@ DRAW(DrawTextRSXform, drawTextRSXform(r.text, r.byteLength, r.xforms, r.cull, r.
|
||||
DRAW(DrawAtlas, drawAtlas(r.atlas.get(),
|
||||
r.xforms, r.texs, r.colors, r.count, r.mode, r.cull, r.paint));
|
||||
DRAW(DrawVertices, drawVertices(r.vertices, r.bmode, r.paint));
|
||||
DRAW(DrawShadowRec, private_draw_shadow_rec(r.path, r.rec));
|
||||
DRAW(DrawAnnotation, drawAnnotation(r.rect, r.key.c_str(), r.value.get()));
|
||||
#undef DRAW
|
||||
|
||||
@ -455,6 +456,10 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
Bounds bounds(const DrawShadowRec& op) const {
|
||||
return this->adjustAndMap(op.path.getBounds(), nullptr);
|
||||
}
|
||||
|
||||
Bounds bounds(const DrawPicture& op) const {
|
||||
SkRect dst = op.picture->cullRect();
|
||||
op.matrix.mapRect(&dst);
|
||||
|
@ -338,6 +338,10 @@ void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], cons
|
||||
this->copy(cull));
|
||||
}
|
||||
|
||||
void SkRecorder::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
APPEND(DrawShadowRec, path, rec);
|
||||
}
|
||||
|
||||
void SkRecorder::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
|
||||
APPEND(DrawAnnotation, rect, SkString(key), sk_ref_sp(value));
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ public:
|
||||
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int count, SkBlendMode, const SkRect* cull, const SkPaint*) override;
|
||||
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
|
||||
|
||||
void onClipRect(const SkRect& rect, SkClipOp, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect& rrect, SkClipOp, ClipEdgeStyle) override;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "SkData.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDrawable.h"
|
||||
#include "SkDrawShadowRec.h"
|
||||
#include "SkImage.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkMatrix.h"
|
||||
@ -80,6 +81,7 @@ namespace SkRecords {
|
||||
M(DrawTextBlob) \
|
||||
M(DrawAtlas) \
|
||||
M(DrawVertices) \
|
||||
M(DrawShadowRec) \
|
||||
M(DrawAnnotation)
|
||||
|
||||
// Defines SkRecords::Type, an enum of all record types.
|
||||
@ -345,6 +347,9 @@ RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
|
||||
SkPaint paint;
|
||||
sk_sp<SkVertices> vertices;
|
||||
SkBlendMode bmode);
|
||||
RECORD(DrawShadowRec, kDraw_Tag,
|
||||
SkPath path;
|
||||
SkDrawShadowRec rec);
|
||||
RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548
|
||||
SkRect rect;
|
||||
SkString key;
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter) override;
|
||||
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
|
||||
void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkBlendMode, const SkPaint&) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
@ -299,6 +299,13 @@ void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4]
|
||||
}
|
||||
}
|
||||
|
||||
void SkNWayCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
Iter iter(fList);
|
||||
while (iter.next()) {
|
||||
iter->private_draw_shadow_rec(path, rec);
|
||||
}
|
||||
}
|
||||
|
||||
void SkNWayCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
|
||||
Iter iter(fList);
|
||||
while (iter.next()) {
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkDrawShadowRec.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPM4f.h"
|
||||
#include "SkRandom.h"
|
||||
@ -20,9 +22,9 @@
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrShape.h"
|
||||
#include "effects/GrBlurredEdgeFragmentProcessor.h"
|
||||
#endif
|
||||
#include "../../src/effects/shadows/SkAmbientShadowMaskFilter.h"
|
||||
#include "../../src/effects/shadows/SkSpotShadowMaskFilter.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gaussian color filter -- produces a Gaussian ramp based on the color's B value,
|
||||
@ -444,7 +446,9 @@ static void* kNamespace;
|
||||
* they are first found in SkResourceCache.
|
||||
*/
|
||||
template <typename FACTORY>
|
||||
void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, SkColor color) {
|
||||
void draw_shadow(const FACTORY& factory,
|
||||
std::function<void(const SkVertices*, SkBlendMode, const SkPaint&,
|
||||
SkScalar tx, SkScalar ty)> drawProc, ShadowedPath& path, SkColor color) {
|
||||
FindContext<FACTORY> context(&path.viewMatrix(), &factory);
|
||||
|
||||
SkResourceCache::Key* key = nullptr;
|
||||
@ -496,82 +500,83 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
|
||||
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
|
||||
SkColorFilter::MakeModeFilter(color, SkBlendMode::kModulate),
|
||||
SkGaussianColorFilter::Make()));
|
||||
if (translate->fX || translate->fY) {
|
||||
canvas->save();
|
||||
canvas->translate(translate->fX, translate->fY);
|
||||
}
|
||||
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
||||
if (translate->fX || translate->fY) {
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
drawProc(vertices.get(), SkBlendMode::kModulate, paint, translate->fX, translate->fY);
|
||||
}
|
||||
}
|
||||
|
||||
static bool draw_analytic_shadows(SkCanvas* canvas, const SkPath& path, SkScalar occluderZ,
|
||||
const SkPoint3& devLightPos, SkScalar lightRadius,
|
||||
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
|
||||
uint32_t flags) {
|
||||
// only supported in GPU code
|
||||
if (!canvas->getGrContext()) {
|
||||
return false;
|
||||
}
|
||||
static bool tilted(const SkPoint3& zPlaneParams) {
|
||||
return !SkScalarNearlyZero(zPlaneParams.fX) || !SkScalarNearlyZero(zPlaneParams.fY);
|
||||
}
|
||||
|
||||
SkRect rect;
|
||||
SkRRect rrect;
|
||||
const SkMatrix& ctm = canvas->getTotalMatrix();
|
||||
if (ctm.rectStaysRect() && ctm.isSimilarity()) {
|
||||
static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
|
||||
SkPoint3 result;
|
||||
m.mapXY(pt.fX, pt.fY, (SkPoint*)&result.fX);
|
||||
result.fZ = pt.fZ;
|
||||
return result;
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "SkGpuDevice.h"
|
||||
void SkGpuDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
// check z plane
|
||||
bool tiltZPlane = tilted(rec.fZPlaneParams);
|
||||
bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
|
||||
|
||||
const SkMatrix& ctm = this->ctm();
|
||||
|
||||
if (!tiltZPlane && !skipAnalytic && ctm.rectStaysRect() && ctm.isSimilarity()) {
|
||||
SkPoint3 devLightPos = map(ctm, rec.fLightPos);
|
||||
|
||||
const SkScalar occluderZ = rec.fZPlaneParams.fZ;
|
||||
SkPaint ambientPaint, spotPaint;
|
||||
ambientPaint.setColor(rec.fColor);
|
||||
spotPaint.setColor(rec.fColor);
|
||||
if (rec.fAmbientAlpha > 0) {
|
||||
ambientPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ, rec.fAmbientAlpha,
|
||||
rec.fFlags));
|
||||
}
|
||||
if (rec.fSpotAlpha > 0) {
|
||||
spotPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
|
||||
rec.fLightRadius, rec.fSpotAlpha,
|
||||
rec.fFlags));
|
||||
}
|
||||
|
||||
SkRect rect;
|
||||
SkRRect rrect;
|
||||
if (path.isRect(&rect)) {
|
||||
SkPaint newPaint;
|
||||
newPaint.setColor(color);
|
||||
if (ambientAlpha > 0) {
|
||||
newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
|
||||
ambientAlpha, flags));
|
||||
canvas->drawRect(rect, newPaint);
|
||||
if (rec.fAmbientAlpha > 0) {
|
||||
this->drawRect(rect, ambientPaint);
|
||||
}
|
||||
if (spotAlpha > 0) {
|
||||
newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
|
||||
lightRadius, spotAlpha,
|
||||
flags));
|
||||
canvas->drawRect(rect, newPaint);
|
||||
if (rec.fSpotAlpha > 0) {
|
||||
this->drawRect(rect, spotPaint);
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
} else if (path.isRRect(&rrect) && rrect.isSimpleCircular() &&
|
||||
rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero) {
|
||||
SkPaint newPaint;
|
||||
newPaint.setColor(color);
|
||||
if (ambientAlpha > 0) {
|
||||
newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
|
||||
ambientAlpha, flags));
|
||||
canvas->drawRRect(rrect, newPaint);
|
||||
if (rec.fAmbientAlpha > 0) {
|
||||
this->drawRRect(rrect, ambientPaint);
|
||||
}
|
||||
if (spotAlpha > 0) {
|
||||
newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
|
||||
lightRadius, spotAlpha,
|
||||
flags));
|
||||
canvas->drawRRect(rrect, newPaint);
|
||||
if (rec.fSpotAlpha > 0) {
|
||||
this->drawRRect(rrect, spotPaint);
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
} else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
|
||||
rect.width() > SK_ScalarNearlyZero) {
|
||||
SkPaint newPaint;
|
||||
newPaint.setColor(color);
|
||||
if (ambientAlpha > 0) {
|
||||
newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
|
||||
ambientAlpha, flags));
|
||||
canvas->drawOval(rect, newPaint);
|
||||
if (rec.fAmbientAlpha > 0) {
|
||||
this->drawOval(rect, ambientPaint);
|
||||
}
|
||||
if (spotAlpha > 0) {
|
||||
newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
|
||||
lightRadius, spotAlpha,
|
||||
flags));
|
||||
canvas->drawOval(rect, newPaint);
|
||||
if (rec.fSpotAlpha > 0) {
|
||||
this->drawOval(rect, spotPaint);
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
// failed to find an accelerated case
|
||||
this->INHERITED::drawShadow(path, rec);
|
||||
}
|
||||
#endif
|
||||
|
||||
static SkColor compute_render_color(SkColor color, float alpha) {
|
||||
return SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
|
||||
@ -583,26 +588,47 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
|
||||
const SkPoint3& devLightPos, SkScalar lightRadius,
|
||||
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
|
||||
uint32_t flags) {
|
||||
// check z plane
|
||||
bool tiltZPlane = !SkScalarNearlyZero(zPlaneParams.fX) || !SkScalarNearlyZero(zPlaneParams.fY);
|
||||
|
||||
// try fast paths
|
||||
bool skipAnalytic = SkToBool(flags & SkShadowFlags::kGeometricOnly_ShadowFlag) || tiltZPlane;
|
||||
if (!skipAnalytic && draw_analytic_shadows(canvas, path, zPlaneParams.fZ, devLightPos,
|
||||
lightRadius, ambientAlpha, spotAlpha, color,
|
||||
flags)) {
|
||||
SkMatrix inverse;
|
||||
if (!canvas->getTotalMatrix().invert(&inverse)) {
|
||||
return;
|
||||
}
|
||||
SkPoint pt = inverse.mapXY(devLightPos.fX, devLightPos.fY);
|
||||
|
||||
SkAutoCanvasRestore acr(canvas, true);
|
||||
SkMatrix viewMatrix = canvas->getTotalMatrix();
|
||||
canvas->resetMatrix();
|
||||
SkDrawShadowRec rec;
|
||||
rec.fZPlaneParams = zPlaneParams;
|
||||
rec.fLightPos = { pt.fX, pt.fY, devLightPos.fZ };
|
||||
rec.fLightRadius = lightRadius;
|
||||
rec.fAmbientAlpha = SkScalarToFloat(ambientAlpha);
|
||||
rec.fSpotAlpha = SkScalarToFloat(spotAlpha);
|
||||
rec.fColor = color;
|
||||
rec.fFlags = flags;
|
||||
|
||||
canvas->private_draw_shadow_rec(path, rec);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
auto drawVertsProc = [this](const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint,
|
||||
SkScalar tx, SkScalar ty) {
|
||||
SkAutoDeviceCTMRestore adr(this, SkMatrix::Concat(this->ctm(),
|
||||
SkMatrix::MakeTrans(tx, ty)));
|
||||
this->drawVertices(vertices, mode, paint);
|
||||
};
|
||||
|
||||
SkMatrix viewMatrix = this->ctm();
|
||||
SkAutoDeviceCTMRestore adr(this, SkMatrix::I());
|
||||
|
||||
ShadowedPath shadowedPath(&path, &viewMatrix);
|
||||
|
||||
bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
|
||||
bool tiltZPlane = tilted(rec.fZPlaneParams);
|
||||
bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
|
||||
bool uncached = tiltZPlane || path.isVolatile();
|
||||
|
||||
SkColor color = rec.fColor;
|
||||
SkPoint3 zPlaneParams = rec.fZPlaneParams;
|
||||
SkPoint3 devLightPos = map(viewMatrix, rec.fLightPos);
|
||||
float lightRadius = rec.fLightRadius;
|
||||
|
||||
float ambientAlpha = rec.fAmbientAlpha;
|
||||
if (ambientAlpha > 0) {
|
||||
ambientAlpha = SkTMin(ambientAlpha, 1.f);
|
||||
if (uncached) {
|
||||
@ -614,19 +640,20 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
|
||||
// Run the vertex color through a GaussianColorFilter and then modulate the grayscale
|
||||
// result of that against our 'color' param.
|
||||
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
|
||||
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
|
||||
SkGaussianColorFilter::Make()));
|
||||
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
||||
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
|
||||
SkGaussianColorFilter::Make()));
|
||||
this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
|
||||
} else {
|
||||
AmbientVerticesFactory factory;
|
||||
factory.fOccluderHeight = zPlaneParams.fZ;
|
||||
factory.fTransparent = transparent;
|
||||
|
||||
SkColor renderColor = compute_render_color(color, ambientAlpha);
|
||||
draw_shadow(factory, canvas, shadowedPath, renderColor);
|
||||
draw_shadow(factory, drawVertsProc, shadowedPath, renderColor);
|
||||
}
|
||||
}
|
||||
|
||||
float spotAlpha = rec.fSpotAlpha;
|
||||
if (spotAlpha > 0) {
|
||||
spotAlpha = SkTMin(spotAlpha, 1.f);
|
||||
if (uncached) {
|
||||
@ -641,7 +668,7 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
|
||||
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
|
||||
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
|
||||
SkGaussianColorFilter::Make()));
|
||||
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
||||
this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
|
||||
} else {
|
||||
SpotVerticesFactory factory;
|
||||
SkScalar occluderHeight = zPlaneParams.fZ;
|
||||
@ -690,7 +717,7 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
|
||||
}
|
||||
#endif
|
||||
SkColor renderColor = compute_render_color(color, spotAlpha);
|
||||
draw_shadow(factory, canvas, shadowedPath, renderColor);
|
||||
draw_shadow(factory, drawVertsProc, shadowedPath, renderColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user