Creating framework for drawShadowedPicture
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2146073003 Committed: https://skia.googlesource.com/skia/+/0ae097d116f4332be02a135ffc99c162473dee6a Review-Url: https://codereview.chromium.org/2146073003
This commit is contained in:
parent
b5dc4051f7
commit
95302da19d
@ -112,6 +112,13 @@
|
||||
},
|
||||
},
|
||||
}],
|
||||
[ 'skia_experimental_shadowing',
|
||||
{
|
||||
'defines': [
|
||||
'SK_EXPERIMENTAL_SHADOWING',
|
||||
],
|
||||
},
|
||||
],
|
||||
],
|
||||
}, # end 'target_defaults'
|
||||
}
|
||||
|
@ -251,6 +251,7 @@
|
||||
#'-ffast-math', # Optimize float math even when it breaks IEEE compliance.
|
||||
#'-flto' # Enable link-time optimization.
|
||||
],
|
||||
'skia_experimental_shadowing': 0, # for experimental shadow-drawing
|
||||
|
||||
# These are referenced by our .gypi files that list files (e.g. core.gypi)
|
||||
#
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "SkRegion.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
#include "SkXfermode.h"
|
||||
#include "SkLights.h"
|
||||
|
||||
class GrContext;
|
||||
class GrDrawContext;
|
||||
@ -451,6 +452,7 @@ public:
|
||||
*/
|
||||
void resetMatrix();
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
/** Add the specified translation to the current draw depth of the canvas.
|
||||
@param z The distance to translate in Z.
|
||||
Negative into screen, positive out of screen.
|
||||
@ -458,6 +460,16 @@ public:
|
||||
*/
|
||||
void translateZ(SkScalar z);
|
||||
|
||||
/** Set the current set of lights in the canvas.
|
||||
@param lights The lights that we want the canvas to have.
|
||||
*/
|
||||
void setLights(sk_sp<SkLights> lights);
|
||||
|
||||
/** Returns the current set of lights the canvas uses
|
||||
*/
|
||||
sk_sp<SkLights> getLights() const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Modify the current clip with the specified rectangle.
|
||||
* @param rect The rect to combine with the current clip
|
||||
@ -1049,6 +1061,34 @@ public:
|
||||
this->drawPicture(picture.get(), matrix, paint);
|
||||
}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
/**
|
||||
* Draw the picture into this canvas.
|
||||
*
|
||||
* 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
|
||||
* then use that set of shadowmaps to render the scene with shadows.
|
||||
*
|
||||
* If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
|
||||
* logically equivalent to
|
||||
* save/concat/drawPicture/restore
|
||||
*
|
||||
* If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
|
||||
* alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
|
||||
* This is logically equivalent to
|
||||
* saveLayer(paint)/drawPicture/restore
|
||||
*
|
||||
*/
|
||||
void drawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint);
|
||||
void drawShadowedPicture(const sk_sp<SkPicture>& picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
this->drawShadowedPicture(picture.get(), matrix, paint);
|
||||
}
|
||||
#endif
|
||||
|
||||
enum VertexMode {
|
||||
kTriangles_VertexMode,
|
||||
kTriangleStrip_VertexMode,
|
||||
@ -1267,10 +1307,14 @@ public:
|
||||
void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds);
|
||||
|
||||
protected:
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
/** Returns the current (cumulative) draw depth of the canvas.
|
||||
*/
|
||||
SkScalar getZ() const;
|
||||
|
||||
sk_sp<SkLights> fLights;
|
||||
#endif
|
||||
|
||||
/** After calling saveLayer(), there can be any number of devices that make
|
||||
up the top-most drawing area. LayerIter can be used to iterate through
|
||||
those devices. Note that the iterator is only valid until the next API
|
||||
@ -1336,7 +1380,10 @@ protected:
|
||||
virtual void didRestore() {}
|
||||
virtual void didConcat(const SkMatrix&) {}
|
||||
virtual void didSetMatrix(const SkMatrix&) {}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
virtual void didTranslateZ(SkScalar) {}
|
||||
#endif
|
||||
|
||||
virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value);
|
||||
virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
|
||||
@ -1403,6 +1450,12 @@ protected:
|
||||
|
||||
virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
virtual void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*);
|
||||
#endif
|
||||
|
||||
// Returns the canvas to be used by DrawIter. Default implementation
|
||||
// returns this. Subclasses that encapsulate an indirect canvas may
|
||||
// need to overload this method. The impl must keep track of this, as it
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "SkPoint3.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "../private/SkTDArray.h"
|
||||
#include "SkImage.h"
|
||||
|
||||
class SK_API SkLights : public SkRefCnt {
|
||||
public:
|
||||
@ -26,6 +27,7 @@ public:
|
||||
: fType(kAmbient_LightType)
|
||||
, fColor(color) {
|
||||
fDirection.set(0.0f, 0.0f, 1.0f);
|
||||
fShadowMap.reset(nullptr);
|
||||
}
|
||||
|
||||
Light(const SkColor3f& color, const SkVector3& dir)
|
||||
@ -35,6 +37,7 @@ public:
|
||||
if (!fDirection.normalize()) {
|
||||
fDirection.set(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
fShadowMap.reset(nullptr);
|
||||
}
|
||||
|
||||
LightType type() const { return fType; }
|
||||
@ -44,11 +47,35 @@ public:
|
||||
return fDirection;
|
||||
}
|
||||
|
||||
void setShadowMap(sk_sp<SkImage> shadowMap) {
|
||||
fShadowMap = std::move(shadowMap);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> getShadowMap() const {
|
||||
return fShadowMap;
|
||||
}
|
||||
|
||||
Light& operator= (const Light& b) {
|
||||
if (this == &b)
|
||||
return *this;
|
||||
|
||||
this->fColor = b.fColor;
|
||||
this->fType = b.fType;
|
||||
this->fDirection = b.fDirection;
|
||||
|
||||
if (b.fShadowMap) {
|
||||
this->fShadowMap = b.fShadowMap;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
LightType fType;
|
||||
SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel.
|
||||
SkVector3 fDirection; // direction towards the light (+Z is out of the screen).
|
||||
// If degenerate, it will be replaced with (0, 0, 1).
|
||||
sk_sp<SkImage> fShadowMap;
|
||||
};
|
||||
|
||||
class Builder {
|
||||
@ -57,7 +84,7 @@ public:
|
||||
|
||||
void add(const Light& light) {
|
||||
if (fLights) {
|
||||
*fLights->fLights.push() = light;
|
||||
(void) fLights->fLights.append(1, &light);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +104,10 @@ public:
|
||||
return fLights[index];
|
||||
}
|
||||
|
||||
Light& light(int index) {
|
||||
return fLights[index];
|
||||
}
|
||||
|
||||
private:
|
||||
SkLights() {}
|
||||
|
||||
|
@ -68,6 +68,7 @@ namespace SkRecords {
|
||||
M(DrawPath) \
|
||||
M(DrawPatch) \
|
||||
M(DrawPicture) \
|
||||
M(DrawShadowedPicture) \
|
||||
M(DrawPoints) \
|
||||
M(DrawPosText) \
|
||||
M(DrawPosTextH) \
|
||||
@ -309,6 +310,10 @@ RECORD(DrawPicture, kDraw_Tag,
|
||||
Optional<SkPaint> paint;
|
||||
RefBox<const SkPicture> picture;
|
||||
TypedMatrix matrix);
|
||||
RECORD(DrawShadowedPicture, kDraw_Tag,
|
||||
Optional<SkPaint> paint;
|
||||
RefBox<const SkPicture> picture;
|
||||
TypedMatrix matrix);
|
||||
RECORD(DrawPoints, kDraw_Tag,
|
||||
SkPaint paint;
|
||||
SkCanvas::PointMode mode;
|
||||
|
@ -663,6 +663,9 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
|
||||
fDeviceCMDirty = true;
|
||||
fSaveCount = 1;
|
||||
fMetaData = nullptr;
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
fLights = nullptr;
|
||||
#endif
|
||||
|
||||
fClipStack.reset(new SkClipStack);
|
||||
|
||||
@ -1519,6 +1522,7 @@ void SkCanvas::resetMatrix() {
|
||||
this->setMatrix(SkMatrix::I());
|
||||
}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void SkCanvas::translateZ(SkScalar z) {
|
||||
this->checkForDeferredSave();
|
||||
this->fMCRec->fCurDrawDepth += z;
|
||||
@ -1529,6 +1533,15 @@ SkScalar SkCanvas::getZ() const {
|
||||
return this->fMCRec->fCurDrawDepth;
|
||||
}
|
||||
|
||||
void SkCanvas::setLights(sk_sp<SkLights> lights) {
|
||||
this->fLights = lights;
|
||||
}
|
||||
|
||||
sk_sp<SkLights> SkCanvas::getLights() const {
|
||||
return this->fLights;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
|
||||
@ -3000,6 +3013,24 @@ void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
|
||||
picture->playback(this);
|
||||
}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void SkCanvas::drawShadowedPicture(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
RETURN_ON_NULL(picture);
|
||||
|
||||
TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()");
|
||||
|
||||
this->onDrawShadowedPicture(picture, matrix, paint);
|
||||
}
|
||||
|
||||
void SkCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
this->onDrawPicture(picture, matrix, paint);
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
*/
|
||||
SkLightingShaderImpl(sk_sp<SkShader> diffuseShader,
|
||||
sk_sp<SkNormalSource> normalSource,
|
||||
const sk_sp<SkLights> lights)
|
||||
sk_sp<SkLights> lights)
|
||||
: fDiffuseShader(std::move(diffuseShader))
|
||||
, fNormalSource(std::move(normalSource))
|
||||
, fLights(std::move(lights)) {}
|
||||
@ -134,6 +134,7 @@ public:
|
||||
// TODO: handle more than one of these
|
||||
fLightColor = lights->light(i).color();
|
||||
fLightDir = lights->light(i).dir();
|
||||
// TODO get the handle to the shadow map if there is one
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,6 +177,9 @@ public:
|
||||
this->emitChild(0, nullptr, &dstNormalName, args);
|
||||
|
||||
fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_str());
|
||||
|
||||
// TODO: make this a loop and modulate the contribution from each light
|
||||
// based on the shadow map
|
||||
fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);",
|
||||
lightDirUniName);
|
||||
// diffuse light
|
||||
|
@ -17,6 +17,13 @@
|
||||
#include "SkPtrRecorder.h"
|
||||
#include "SkTDynamicHash.h"
|
||||
|
||||
/*
|
||||
* Note: While adding new DrawTypes, it is necessary to add to the end of this list
|
||||
* and update LAST_DRAWTYPE_ENUM to avoid having the code read older skps wrong.
|
||||
* (which can cause segfaults)
|
||||
*
|
||||
* Reordering can be done during version updates.
|
||||
*/
|
||||
enum DrawType {
|
||||
UNUSED,
|
||||
CLIP_PATH,
|
||||
@ -83,7 +90,9 @@ enum DrawType {
|
||||
|
||||
TRANSLATE_Z,
|
||||
|
||||
LAST_DRAWTYPE_ENUM = TRANSLATE_Z
|
||||
DRAW_SHADOWED_PICTURE_LIGHTS,
|
||||
|
||||
LAST_DRAWTYPE_ENUM = DRAW_SHADOWED_PICTURE_LIGHTS
|
||||
};
|
||||
|
||||
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
|
||||
|
@ -617,9 +617,11 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
||||
canvas->translate(dx, dy);
|
||||
} break;
|
||||
case TRANSLATE_Z: {
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
SkScalar dz = reader->readScalar();
|
||||
canvas->translateZ(dz);
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
default:
|
||||
SkASSERTF(false, "Unknown draw type: %d", op);
|
||||
}
|
||||
|
@ -219,6 +219,7 @@ void SkPictureRecord::didSetMatrix(const SkMatrix& matrix) {
|
||||
}
|
||||
|
||||
void SkPictureRecord::didTranslateZ(SkScalar z) {
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
this->validate(fWriter.bytesWritten(), 0);
|
||||
// op + scalar
|
||||
size_t size = 1 * kUInt32Size + 1 * sizeof(SkScalar);
|
||||
@ -226,6 +227,7 @@ void SkPictureRecord::didTranslateZ(SkScalar z) {
|
||||
this->addScalar(z);
|
||||
this->validate(initialOffset, size);
|
||||
this->INHERITED::didTranslateZ(z);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool regionOpExpands(SkRegion::Op op) {
|
||||
@ -672,6 +674,27 @@ void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* ma
|
||||
this->validate(initialOffset, size);
|
||||
}
|
||||
|
||||
void SkPictureRecord::onDrawShadowedPicture(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
// op + picture index
|
||||
size_t size = 2 * kUInt32Size;
|
||||
size_t initialOffset;
|
||||
|
||||
if (nullptr == matrix && nullptr == paint) {
|
||||
initialOffset = this->addDraw(DRAW_PICTURE, &size);
|
||||
this->addPicture(picture);
|
||||
} else {
|
||||
const SkMatrix& m = matrix ? *matrix : SkMatrix::I();
|
||||
size += m.writeToMemory(nullptr) + kUInt32Size; // matrix + paint
|
||||
initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size);
|
||||
this->addPaintPtr(paint);
|
||||
this->addMatrix(m);
|
||||
this->addPicture(picture);
|
||||
}
|
||||
this->validate(initialOffset, size);
|
||||
}
|
||||
|
||||
void SkPictureRecord::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
|
||||
// op + drawable index
|
||||
size_t size = 2 * kUInt32Size;
|
||||
|
@ -159,7 +159,11 @@ protected:
|
||||
void didConcat(const SkMatrix&) override;
|
||||
void didSetMatrix(const SkMatrix&) override;
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void didTranslateZ(SkScalar) override;
|
||||
#endif
|
||||
void didTranslateZ(SkScalar);
|
||||
#endif
|
||||
|
||||
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
|
||||
|
||||
@ -208,6 +212,17 @@ protected:
|
||||
void onClipRegion(const SkRegion&, SkRegion::Op) override;
|
||||
|
||||
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*) override;
|
||||
#else
|
||||
void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*);
|
||||
#endif
|
||||
|
||||
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
|
||||
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
|
||||
|
||||
@ -253,5 +268,3 @@ private:
|
||||
|
||||
typedef SkCanvas INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -86,7 +86,11 @@ DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op, r.opAA.aa));
|
||||
DRAW(ClipRect, clipRect(r.rect, r.opAA.op, r.opAA.aa));
|
||||
DRAW(ClipRegion, clipRegion(r.region, r.op));
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
DRAW(TranslateZ, SkCanvas::translateZ(r.z));
|
||||
#else
|
||||
template <> void Draw::draw(const TranslateZ& r) { }
|
||||
#endif
|
||||
|
||||
DRAW(DrawBitmap, drawBitmap(r.bitmap.shallowCopy(), r.left, r.top, r.paint));
|
||||
DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap.shallowCopy(), r.center, r.dst, r.paint));
|
||||
@ -107,6 +111,13 @@ DRAW(DrawPaint, drawPaint(r.paint));
|
||||
DRAW(DrawPath, drawPath(r.path, r.paint));
|
||||
DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.xmode, r.paint));
|
||||
DRAW(DrawPicture, drawPicture(r.picture, &r.matrix, r.paint));
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture, &r.matrix, r.paint));
|
||||
#else
|
||||
template <> void Draw::draw(const DrawShadowedPicture& r) { }
|
||||
#endif
|
||||
|
||||
DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint));
|
||||
DRAW(DrawPosText, drawPosText(r.text, r.byteLength, r.pos, r.paint));
|
||||
DRAW(DrawPosTextH, drawPosTextH(r.text, r.byteLength, r.xpos, r.y, r.paint));
|
||||
@ -472,6 +483,12 @@ private:
|
||||
return this->adjustAndMap(dst, op.paint);
|
||||
}
|
||||
|
||||
Bounds bounds(const DrawShadowedPicture& op) const {
|
||||
SkRect dst = op.picture->cullRect();
|
||||
op.matrix.mapRect(&dst);
|
||||
return this->adjustAndMap(dst, op.paint);
|
||||
}
|
||||
|
||||
Bounds bounds(const DrawPosText& op) const {
|
||||
const int N = op.paint.countText(op.text, op.byteLength);
|
||||
if (N == 0) {
|
||||
|
@ -305,6 +305,20 @@ void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con
|
||||
}
|
||||
}
|
||||
|
||||
void SkRecorder::onDrawShadowedPicture(const SkPicture* pic,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
if (fDrawPictureMode == Record_DrawPictureMode) {
|
||||
fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic);
|
||||
APPEND(DrawShadowedPicture, this->copy(paint), pic, matrix ? *matrix : SkMatrix::I());
|
||||
} else {
|
||||
SkASSERT(fDrawPictureMode == Playback_DrawPictureMode);
|
||||
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, pic->cullRect());
|
||||
pic->playback(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SkRecorder::onDrawVertices(VertexMode vmode,
|
||||
int vertexCount, const SkPoint vertices[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
@ -369,8 +383,10 @@ void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
|
||||
APPEND(SetMatrix, matrix);
|
||||
}
|
||||
|
||||
void SkRecorder::didTranslateZ(SkScalar z) {
|
||||
void SkRecorder::didTranslateZ(SkScalar z) {
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
APPEND(TranslateZ, z);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkRecorder::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
|
||||
|
@ -60,7 +60,12 @@ public:
|
||||
|
||||
void didConcat(const SkMatrix&) override;
|
||||
void didSetMatrix(const SkMatrix&) override;
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void didTranslateZ(SkScalar) override;
|
||||
#else
|
||||
void didTranslateZ(SkScalar);
|
||||
#endif
|
||||
|
||||
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
|
||||
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
|
||||
@ -126,6 +131,17 @@ public:
|
||||
void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) override;
|
||||
|
||||
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*) override;
|
||||
#else
|
||||
void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*);
|
||||
#endif
|
||||
|
||||
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
|
||||
|
||||
sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
|
||||
|
@ -780,7 +780,7 @@ DEF_TEST(Canvas_ClipEmptyPath, reporter) {
|
||||
}
|
||||
|
||||
#define SHADOW_TEST_CANVAS_CONST 10
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
class SkShadowTestCanvas : public SkPaintFilterCanvas {
|
||||
public:
|
||||
|
||||
@ -817,6 +817,7 @@ private:
|
||||
|
||||
typedef SkPaintFilterCanvas INHERITED;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
@ -852,6 +853,7 @@ DEF_TEST(PaintFilterCanvas_ConsistentState, reporter) {
|
||||
REPORTER_ASSERT(reporter, canvas.getClipBounds(&clip1) == filterCanvas.getClipBounds(&clip2));
|
||||
REPORTER_ASSERT(reporter, clip1 == clip2);
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
SkShadowTestCanvas* tCanvas = new SkShadowTestCanvas(100,100, reporter);
|
||||
tCanvas->testUpdateDepth(reporter);
|
||||
delete(tCanvas);
|
||||
@ -865,6 +867,7 @@ DEF_TEST(PaintFilterCanvas_ConsistentState, reporter) {
|
||||
tSCanvas->drawPicture(pic);
|
||||
|
||||
delete(tSCanvas);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -58,6 +58,16 @@ protected:
|
||||
this->SkCanvas::onDrawPicture(picture, matrix, paint);
|
||||
}
|
||||
|
||||
void onDrawShadowedPicture(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
this->SkCanvas::onDrawShadowedPicture(picture, matrix, paint);
|
||||
#else
|
||||
this->SkCanvas::onDrawPicture(picture, matrix, paint);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
sk_sp<SkXfermode> fOverdrawXfermode;
|
||||
|
||||
@ -603,6 +613,15 @@ void SkDebugCanvas::onDrawPicture(const SkPicture* picture,
|
||||
this->addDrawCommand(new SkEndDrawPictureCommand(SkToBool(matrix) || SkToBool(paint)));
|
||||
}
|
||||
|
||||
void SkDebugCanvas::onDrawShadowedPicture(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint) {
|
||||
this->addDrawCommand(new SkBeginDrawShadowedPictureCommand(picture, matrix, paint));
|
||||
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
|
||||
picture->playback(this);
|
||||
this->addDrawCommand(new SkEndDrawShadowedPictureCommand(SkToBool(matrix) || SkToBool(paint)));
|
||||
}
|
||||
|
||||
void SkDebugCanvas::onDrawPoints(PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint) {
|
||||
this->addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint));
|
||||
@ -691,8 +710,10 @@ void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) {
|
||||
}
|
||||
|
||||
void SkDebugCanvas::didTranslateZ(SkScalar z) {
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
this->addDrawCommand(new SkTranslateZCommand(z));
|
||||
this->INHERITED::didTranslateZ(z);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkDebugCanvas::toggleCommand(int index, bool toggle) {
|
||||
|
@ -24,23 +24,27 @@ class SkNWayCanvas;
|
||||
class SK_API SkDebugCanvas : public SkCanvas {
|
||||
public:
|
||||
SkDebugCanvas(int width, int height);
|
||||
|
||||
virtual ~SkDebugCanvas();
|
||||
|
||||
void toggleFilter(bool toggle) { fFilter = toggle; }
|
||||
|
||||
void setMegaVizMode(bool megaVizMode) { fMegaVizMode = megaVizMode; }
|
||||
|
||||
bool getMegaVizMode() const { return fMegaVizMode; }
|
||||
|
||||
/**
|
||||
* Enable or disable overdraw visualization
|
||||
*/
|
||||
void setOverdrawViz(bool overdrawViz);
|
||||
|
||||
bool getOverdrawViz() const { return fOverdrawViz; }
|
||||
|
||||
/**
|
||||
* Set the color of the clip visualization. An alpha of zero renders the clip invisible.
|
||||
*/
|
||||
void setClipVizColor(SkColor clipVizColor) { this->fClipVizColor = clipVizColor; }
|
||||
|
||||
SkColor getClipVizColor() const { return fClipVizColor; }
|
||||
|
||||
void setDrawGpuBatchBounds(bool drawGpuBatchBounds) {
|
||||
@ -51,7 +55,7 @@ public:
|
||||
|
||||
bool getAllowSimplifyClip() const { return fAllowSimplifyClip; }
|
||||
|
||||
void setPicture(SkPicture* picture) { fPicture = picture; }
|
||||
void setPicture(SkPicture *picture) { fPicture = picture; }
|
||||
|
||||
/**
|
||||
* Enable or disable texure filtering override
|
||||
@ -62,7 +66,7 @@ public:
|
||||
Executes all draw calls to the canvas.
|
||||
@param canvas The canvas being drawn to
|
||||
*/
|
||||
void draw(SkCanvas* canvas);
|
||||
void draw(SkCanvas *canvas);
|
||||
|
||||
/**
|
||||
Executes the draw calls up to the specified index.
|
||||
@ -70,19 +74,19 @@ public:
|
||||
@param index The index of the final command being executed
|
||||
@param m an optional Mth gpu batch to highlight, or -1
|
||||
*/
|
||||
void drawTo(SkCanvas* canvas, int index, int m = -1);
|
||||
void drawTo(SkCanvas *canvas, int index, int m = -1);
|
||||
|
||||
/**
|
||||
Returns the most recently calculated transformation matrix
|
||||
*/
|
||||
const SkMatrix& getCurrentMatrix() {
|
||||
const SkMatrix &getCurrentMatrix() {
|
||||
return fMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the most recently calculated clip
|
||||
*/
|
||||
const SkIRect& getCurrentClip() {
|
||||
const SkIRect &getCurrentClip() {
|
||||
return fClip;
|
||||
}
|
||||
|
||||
@ -101,20 +105,20 @@ public:
|
||||
Returns the draw command at the given index.
|
||||
@param index The index of the command
|
||||
*/
|
||||
SkDrawCommand* getDrawCommandAt(int index);
|
||||
SkDrawCommand *getDrawCommandAt(int index);
|
||||
|
||||
/**
|
||||
Sets the draw command for a given index.
|
||||
@param index The index to overwrite
|
||||
@param command The new command
|
||||
*/
|
||||
void setDrawCommandAt(int index, SkDrawCommand* command);
|
||||
void setDrawCommandAt(int index, SkDrawCommand *command);
|
||||
|
||||
/**
|
||||
Returns information about the command at the given index.
|
||||
@param index The index of the command
|
||||
*/
|
||||
const SkTDArray<SkString*>* getCommandInfo(int index) const;
|
||||
const SkTDArray<SkString *> *getCommandInfo(int index) const;
|
||||
|
||||
/**
|
||||
Returns the visibility of the command at the given index.
|
||||
@ -126,13 +130,13 @@ public:
|
||||
Returns the vector of draw commands
|
||||
*/
|
||||
SK_ATTR_DEPRECATED("please use getDrawCommandAt and getSize instead")
|
||||
const SkTDArray<SkDrawCommand*>& getDrawCommands() const;
|
||||
const SkTDArray<SkDrawCommand *> &getDrawCommands() const;
|
||||
|
||||
/**
|
||||
Returns the vector of draw commands. Do not use this entry
|
||||
point - it is going away!
|
||||
*/
|
||||
SkTDArray<SkDrawCommand*>& getDrawCommands();
|
||||
SkTDArray<SkDrawCommand *> &getDrawCommands();
|
||||
|
||||
/**
|
||||
Returns length of draw command vector.
|
||||
@ -158,9 +162,9 @@ public:
|
||||
SkDebugCanvas::getSize(). The encoder may use the UrlDataManager to store binary data such
|
||||
as images, referring to them via URLs embedded in the JSON.
|
||||
*/
|
||||
Json::Value toJSON(UrlDataManager& urlDataManager, int n, SkCanvas*);
|
||||
Json::Value toJSON(UrlDataManager &urlDataManager, int n, SkCanvas *);
|
||||
|
||||
Json::Value toJSONBatchList(int n, SkCanvas*);
|
||||
Json::Value toJSONBatchList(int n, SkCanvas *);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Inherited from SkCanvas
|
||||
@ -170,8 +174,10 @@ public:
|
||||
static const int kVizImageWidth = 256;
|
||||
|
||||
bool isClipEmpty() const override { return false; }
|
||||
|
||||
bool isClipRect() const override { return true; }
|
||||
bool getClipBounds(SkRect* bounds) const override {
|
||||
|
||||
bool getClipBounds(SkRect *bounds) const override {
|
||||
if (bounds) {
|
||||
bounds->setXYWH(0, 0,
|
||||
SkIntToScalar(this->imageInfo().width()),
|
||||
@ -179,7 +185,8 @@ public:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool getClipDeviceBounds(SkIRect* bounds) const override {
|
||||
|
||||
bool getClipDeviceBounds(SkIRect *bounds) const override {
|
||||
if (bounds) {
|
||||
bounds->setLargest();
|
||||
}
|
||||
@ -188,13 +195,20 @@ public:
|
||||
|
||||
protected:
|
||||
void willSave() override;
|
||||
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
|
||||
|
||||
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec &) override;
|
||||
|
||||
void willRestore() override;
|
||||
|
||||
void didConcat(const SkMatrix&) override;
|
||||
void didSetMatrix(const SkMatrix&) override;
|
||||
void didConcat(const SkMatrix &) override;
|
||||
|
||||
void didSetMatrix(const SkMatrix &) override;
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void didTranslateZ(SkScalar) override;
|
||||
#else
|
||||
void didTranslateZ(SkScalar);
|
||||
#endif
|
||||
|
||||
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
|
||||
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
|
||||
@ -240,6 +254,16 @@ protected:
|
||||
|
||||
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*) override;
|
||||
#else
|
||||
void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*);
|
||||
#endif
|
||||
|
||||
void markActiveCommands(int index);
|
||||
|
||||
private:
|
||||
|
@ -180,6 +180,7 @@ SkDrawCommand::~SkDrawCommand() {
|
||||
const char* SkDrawCommand::GetCommandString(OpType type) {
|
||||
switch (type) {
|
||||
case kBeginDrawPicture_OpType: return "BeginDrawPicture";
|
||||
case kBeginDrawShadowedPicture_OpType: return "BeginDrawShadowedPicture";
|
||||
case kClipPath_OpType: return "ClipPath";
|
||||
case kClipRegion_OpType: return "ClipRegion";
|
||||
case kClipRect_OpType: return "ClipRect";
|
||||
@ -208,6 +209,7 @@ const char* SkDrawCommand::GetCommandString(OpType type) {
|
||||
case kDrawTextRSXform_OpType: return "DrawTextRSXform";
|
||||
case kDrawVertices_OpType: return "DrawVertices";
|
||||
case kEndDrawPicture_OpType: return "EndDrawPicture";
|
||||
case kEndDrawShadowedPicture_OpType: return "EndDrawShadowedPicture";
|
||||
case kRestore_OpType: return "Restore";
|
||||
case kSave_OpType: return "Save";
|
||||
case kSaveLayer_OpType: return "SaveLayer";
|
||||
@ -270,8 +272,9 @@ SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& url
|
||||
INSTALL_FACTORY(Save);
|
||||
INSTALL_FACTORY(SaveLayer);
|
||||
INSTALL_FACTORY(SetMatrix);
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
INSTALL_FACTORY(TranslateZ);
|
||||
#endif
|
||||
}
|
||||
SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
|
||||
FROM_JSON* factory = factories.find(name);
|
||||
@ -1491,10 +1494,13 @@ static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
|
||||
result->set9(values);
|
||||
}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
// somehow this is only used in shadows...
|
||||
static void extract_json_scalar(Json::Value& scalar, SkScalar* result) {
|
||||
SkScalar value = scalar.asFloat();
|
||||
*result = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void extract_json_path(Json::Value& path, SkPath* result) {
|
||||
const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
|
||||
@ -2381,6 +2387,68 @@ void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
|
||||
}
|
||||
}
|
||||
|
||||
SkBeginDrawShadowedPictureCommand::SkBeginDrawShadowedPictureCommand(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint)
|
||||
: INHERITED(kBeginDrawShadowedPicture_OpType)
|
||||
, fPicture(SkRef(picture)) {
|
||||
|
||||
SkString* str = new SkString;
|
||||
str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
|
||||
picture->cullRect().fLeft, picture->cullRect().fTop,
|
||||
picture->cullRect().fRight, picture->cullRect().fBottom);
|
||||
fInfo.push(str);
|
||||
|
||||
if (matrix) {
|
||||
fMatrix.set(*matrix);
|
||||
fInfo.push(SkObjectParser::MatrixToString(*matrix));
|
||||
}
|
||||
|
||||
if (paint) {
|
||||
fPaint.set(*paint);
|
||||
fInfo.push(SkObjectParser::PaintToString(*paint));
|
||||
}
|
||||
}
|
||||
|
||||
void SkBeginDrawShadowedPictureCommand::execute(SkCanvas* canvas) const {
|
||||
if (fPaint.isValid()) {
|
||||
SkRect bounds = fPicture->cullRect();
|
||||
if (fMatrix.isValid()) {
|
||||
fMatrix.get()->mapRect(&bounds);
|
||||
}
|
||||
canvas->saveLayer(&bounds, fPaint.get());
|
||||
}
|
||||
|
||||
if (fMatrix.isValid()) {
|
||||
if (!fPaint.isValid()) {
|
||||
canvas->save();
|
||||
}
|
||||
canvas->concat(*fMatrix.get());
|
||||
}
|
||||
}
|
||||
|
||||
bool SkBeginDrawShadowedPictureCommand::render(SkCanvas* canvas) const {
|
||||
canvas->clear(0xFFFFFFFF);
|
||||
canvas->save();
|
||||
|
||||
xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
|
||||
|
||||
canvas->drawPicture(fPicture.get());
|
||||
|
||||
canvas->restore();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SkEndDrawShadowedPictureCommand::SkEndDrawShadowedPictureCommand(bool restore)
|
||||
: INHERITED(kEndDrawShadowedPicture_OpType) , fRestore(restore) { }
|
||||
|
||||
void SkEndDrawShadowedPictureCommand::execute(SkCanvas* canvas) const {
|
||||
if (fRestore) {
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
|
||||
SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint)
|
||||
: INHERITED(kDrawPoints_OpType) {
|
||||
@ -3317,7 +3385,9 @@ SkTranslateZCommand::SkTranslateZCommand(SkScalar z)
|
||||
}
|
||||
|
||||
void SkTranslateZCommand::execute(SkCanvas* canvas) const {
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
canvas->translateZ(fZTranslate);
|
||||
#endif
|
||||
}
|
||||
|
||||
Json::Value SkTranslateZCommand::toJSON(UrlDataManager& urlDataManager) const {
|
||||
@ -3329,6 +3399,10 @@ Json::Value SkTranslateZCommand::toJSON(UrlDataManager& urlDataManager) const {
|
||||
SkTranslateZCommand* SkTranslateZCommand::fromJSON(Json::Value& command,
|
||||
UrlDataManager& urlDataManager) {
|
||||
SkScalar z;
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
extract_json_scalar(command[SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS], &z);
|
||||
#else
|
||||
z = 0;
|
||||
#endif
|
||||
return new SkTranslateZCommand(z);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class SK_API SkDrawCommand {
|
||||
public:
|
||||
enum OpType {
|
||||
kBeginDrawPicture_OpType,
|
||||
kBeginDrawShadowedPicture_OpType,
|
||||
kClipPath_OpType,
|
||||
kClipRegion_OpType,
|
||||
kClipRect_OpType,
|
||||
@ -52,6 +53,7 @@ public:
|
||||
kDrawTextRSXform_OpType,
|
||||
kDrawVertices_OpType,
|
||||
kEndDrawPicture_OpType,
|
||||
kEndDrawShadowedPicture_OpType,
|
||||
kRestore_OpType,
|
||||
kSave_OpType,
|
||||
kSaveLayer_OpType,
|
||||
@ -455,6 +457,35 @@ private:
|
||||
typedef SkDrawCommand INHERITED;
|
||||
};
|
||||
|
||||
class SkBeginDrawShadowedPictureCommand : public SkDrawCommand {
|
||||
public:
|
||||
SkBeginDrawShadowedPictureCommand(const SkPicture* picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint);
|
||||
|
||||
void execute(SkCanvas* canvas) const override;
|
||||
bool render(SkCanvas* canvas) const override;
|
||||
|
||||
private:
|
||||
SkAutoTUnref<const SkPicture> fPicture;
|
||||
SkTLazy<SkMatrix> fMatrix;
|
||||
SkTLazy<SkPaint> fPaint;
|
||||
|
||||
typedef SkDrawCommand INHERITED;
|
||||
};
|
||||
|
||||
class SkEndDrawShadowedPictureCommand : public SkDrawCommand {
|
||||
public:
|
||||
SkEndDrawShadowedPictureCommand(bool restore);
|
||||
|
||||
void execute(SkCanvas* canvas) const override;
|
||||
|
||||
private:
|
||||
bool fRestore;
|
||||
|
||||
typedef SkDrawCommand INHERITED;
|
||||
};
|
||||
|
||||
class SkDrawPointsCommand : public SkDrawCommand {
|
||||
public:
|
||||
SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
|
||||
|
Loading…
Reference in New Issue
Block a user