aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Ruiqi Mao <ruiqimao@google.com>2018-06-29 14:32:21 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-29 19:34:28 +0000
commitf510149da8d32f60f08d0a809eb037496079af3c (patch)
tree13b3670a481f3bae652968165d04f9ca4890d9bf /src
parent38f118a2e7f986b06d69d0af41ec2d1af53dac39 (diff)
skeletal animation support added to API and software backend
SkCanvas::drawVertices now supports overloads that take an array of bone deformation matrices. SkVertices::MakeCopy and SkVertices::Builder now support two additional optional attributes, boneIndices and boneWeights. Bug: skia: Change-Id: I30a3b11691e7cdb13924907cc1401ff86d127aea Reviewed-on: https://skia-review.googlesource.com/137221 Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Ruiqi Mao <ruiqimao@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmapDevice.cpp9
-rw-r--r--src/core/SkBitmapDevice.h3
-rw-r--r--src/core/SkCanvas.cpp24
-rw-r--r--src/core/SkColorSpaceXformCanvas.cpp7
-rw-r--r--src/core/SkDevice.cpp4
-rw-r--r--src/core/SkDevice.h6
-rw-r--r--src/core/SkDraw.h7
-rw-r--r--src/core/SkDraw_vertices.cpp88
-rw-r--r--src/core/SkLiteDL.cpp20
-rw-r--r--src/core/SkLiteDL.h3
-rw-r--r--src/core/SkLiteRecorder.cpp6
-rw-r--r--src/core/SkLiteRecorder.h3
-rw-r--r--src/core/SkOverdrawCanvas.cpp9
-rw-r--r--src/core/SkPicturePlayback.cpp6
-rw-r--r--src/core/SkPictureRecord.cpp10
-rw-r--r--src/core/SkPictureRecord.h3
-rw-r--r--src/core/SkRecordDraw.cpp2
-rw-r--r--src/core/SkRecorder.cpp10
-rw-r--r--src/core/SkRecorder.h3
-rw-r--r--src/core/SkRecords.h2
-rw-r--r--src/core/SkThreadedBMPDevice.cpp9
-rw-r--r--src/core/SkThreadedBMPDevice.h3
-rw-r--r--src/core/SkVertices.cpp76
-rw-r--r--src/gpu/SkGpuDevice.cpp4
-rw-r--r--src/gpu/SkGpuDevice.h3
-rw-r--r--src/pdf/SkPDFDevice.cpp3
-rw-r--r--src/pdf/SkPDFDevice.h3
-rw-r--r--src/pipe/SkPipeCanvas.cpp6
-rw-r--r--src/pipe/SkPipeCanvas.h3
-rw-r--r--src/pipe/SkPipeReader.cpp9
-rw-r--r--src/svg/SkSVGDevice.cpp3
-rw-r--r--src/svg/SkSVGDevice.h3
-rw-r--r--src/utils/SkLuaCanvas.cpp3
-rw-r--r--src/utils/SkNWayCanvas.cpp6
-rw-r--r--src/utils/SkPaintFilterCanvas.cpp5
-rw-r--r--src/utils/SkShadowUtils.cpp6
-rw-r--r--src/xps/SkXPSDevice.cpp6
-rw-r--r--src/xps/SkXPSDevice.h3
38 files changed, 279 insertions, 100 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 2361468d56..0d1ec8ddc5 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -570,11 +570,12 @@ void SkBitmapDevice::drawPosText(const void* text, size_t len, const SkScalar xp
nullptr)
}
-void SkBitmapDevice::drawVertices(const SkVertices* vertices, SkBlendMode bmode,
- const SkPaint& paint) {
+void SkBitmapDevice::drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
+ SkBlendMode bmode, const SkPaint& paint) {
BDDraw(this).drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
- vertices->texCoords(), vertices->colors(), bmode,
- vertices->indices(), vertices->indexCount(), paint);
+ vertices->texCoords(), vertices->colors(), vertices->boneIndices(),
+ vertices->boneWeights(), bmode, vertices->indices(),
+ vertices->indexCount(), paint, bones, boneCount);
}
void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& origPaint) {
diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h
index ba7846ca43..e2cedaa7e1 100644
--- a/src/core/SkBitmapDevice.h
+++ b/src/core/SkBitmapDevice.h
@@ -113,7 +113,8 @@ protected:
*/
void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint& paint) override;
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
///////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index b297f98156..bf32aafae9 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1702,13 +1702,27 @@ void SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode,
RETURN_ON_NULL(vertices);
// We expect fans to be converted to triangles when building or deserializing SkVertices.
SkASSERT(vertices->mode() != SkVertices::kTriangleFan_VertexMode);
- this->onDrawVerticesObject(vertices.get(), mode, paint);
+ this->onDrawVerticesObject(vertices.get(), nullptr, 0, mode, paint);
}
void SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
TRACE_EVENT0("skia", TRACE_FUNC);
RETURN_ON_NULL(vertices);
- this->onDrawVerticesObject(vertices, mode, paint);
+ this->onDrawVerticesObject(vertices, nullptr, 0, mode, paint);
+}
+
+void SkCanvas::drawVertices(const sk_sp<SkVertices> vertices, const SkMatrix* bones, int boneCount,
+ SkBlendMode mode, const SkPaint& paint) {
+ TRACE_EVENT0("skia", TRACE_FUNC);
+ RETURN_ON_NULL(vertices);
+ this->onDrawVerticesObject(vertices.get(), bones, boneCount, mode, paint);
+}
+
+void SkCanvas::drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
+ SkBlendMode mode, const SkPaint& paint) {
+ TRACE_EVENT0("skia", TRACE_FUNC);
+ RETURN_ON_NULL(vertices);
+ this->onDrawVerticesObject(vertices, bones, boneCount, mode, paint);
}
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
@@ -2597,13 +2611,13 @@ void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
this->onDrawTextBlob(blob, x, y, paint);
}
-void SkCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
- const SkPaint& paint) {
+void SkCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode bmode, const SkPaint& paint) {
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
while (iter.next()) {
// In the common case of one iteration we could std::move vertices here.
- iter.fDevice->drawVertices(vertices, bmode, looper.paint());
+ iter.fDevice->drawVertices(vertices, bones, boneCount, bmode, looper.paint());
}
LOOPER_END
diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp
index 3ef4d6d00d..caf07fb5d9 100644
--- a/src/core/SkColorSpaceXformCanvas.cpp
+++ b/src/core/SkColorSpaceXformCanvas.cpp
@@ -90,8 +90,8 @@ public:
const SkPaint& paint) override {
fTarget->drawPoints(mode, count, pts, fXformer->apply(paint));
}
- void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
- const SkPaint& paint) override {
+ void onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
+ SkBlendMode mode, const SkPaint& paint) override {
sk_sp<SkVertices> copy;
if (vertices->hasColors()) {
int count = vertices->vertexCount();
@@ -99,11 +99,12 @@ public:
fXformer->apply(xformed.begin(), vertices->colors(), count);
copy = SkVertices::MakeCopy(vertices->mode(), count, vertices->positions(),
vertices->texCoords(), xformed.begin(),
+ vertices->boneIndices(), vertices->boneWeights(),
vertices->indexCount(), vertices->indices());
vertices = copy.get();
}
- fTarget->drawVertices(vertices, mode, fXformer->apply(paint));
+ fTarget->drawVertices(vertices, bones, boneCount, mode, fXformer->apply(paint));
}
void onDrawText(const void* ptr, size_t len,
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 46404b2887..08fc3e2b0d 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -137,7 +137,7 @@ void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
auto vertices = SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height(),
interpColorsLinearly);
if (vertices) {
- this->drawVertices(vertices.get(), bmode, paint);
+ this->drawVertices(vertices.get(), nullptr, 0, bmode, paint);
}
}
@@ -311,7 +311,7 @@ void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
}
SkPaint p(paint);
p.setShader(atlas->makeShader());
- this->drawVertices(builder.detach().get(), mode, p);
+ this->drawVertices(builder.detach().get(), nullptr, 0, mode, p);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index f840cf6218..93ed3e184a 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -225,7 +225,8 @@ protected:
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun);
- virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) = 0;
+ virtual void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint&) = 0;
virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
// default implementation unrolls the blob runs.
@@ -434,7 +435,8 @@ protected:
void drawPosText(const void*, size_t, const SkScalar[], int, const SkPoint&,
const SkPaint&) override {}
void drawDevice(SkBaseDevice*, int, int, const SkPaint&) override {}
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override {}
+ void drawVertices(const SkVertices*, const SkMatrix*, int, SkBlendMode,
+ const SkPaint&) override {}
private:
typedef SkBaseDevice INHERITED;
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index 8032ad9d3c..afd50ea229 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -65,11 +65,12 @@ public:
void drawPosText(const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkPaint&, const SkSurfaceProps*) const;
- void drawVertices(SkVertices::VertexMode mode, int count,
+ void drawVertices(SkVertices::VertexMode mode, int vertexCount,
const SkPoint vertices[], const SkPoint textures[],
- const SkColor colors[], SkBlendMode bmode,
+ const SkColor colors[], const SkVertices::BoneIndices boneIndices[],
+ const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
const uint16_t indices[], int ptCount,
- const SkPaint& paint) const;
+ const SkPaint& paint, const SkMatrix* bones, int boneCount) const;
/**
* Overwrite the target with the path's coverage (i.e. its mask).
diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp
index de6eaea5b6..f918269992 100644
--- a/src/core/SkDraw_vertices.cpp
+++ b/src/core/SkDraw_vertices.cpp
@@ -161,15 +161,16 @@ static bool compute_is_opaque(const SkColor colors[], int count) {
return SkColorGetA(c) == 0xFF;
}
-void SkDraw::drawVertices(SkVertices::VertexMode vmode, int count,
+void SkDraw::drawVertices(SkVertices::VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint textures[],
- const SkColor colors[], SkBlendMode bmode,
+ const SkColor colors[], const SkVertices::BoneIndices boneIndices[],
+ const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
const uint16_t indices[], int indexCount,
- const SkPaint& paint) const {
- SkASSERT(0 == count || vertices);
+ const SkPaint& paint, const SkMatrix* bones, int boneCount) const {
+ SkASSERT(0 == vertexCount || vertices);
// abort early if there is nothing to draw
- if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) {
+ if (vertexCount < 3 || (indices && indexCount < 3) || fRC->isEmpty()) {
return;
}
SkMatrix ctmInv;
@@ -204,25 +205,81 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int count,
shader = nullptr;
}
- constexpr size_t defCount = 16;
- constexpr size_t outerSize = sizeof(SkTriColorShader) +
+ constexpr size_t kDefVertexCount = 16;
+ constexpr size_t kDefBoneCount = 8;
+ constexpr size_t kOuterSize = sizeof(SkTriColorShader) +
sizeof(SkComposeShader) +
- (sizeof(SkPoint) + sizeof(SkPM4f)) * defCount;
- SkSTArenaAlloc<outerSize> outerAlloc;
+ (2 * sizeof(SkPoint) + sizeof(SkPM4f)) * kDefVertexCount +
+ sizeof(SkMatrix) * kDefBoneCount;
+ SkSTArenaAlloc<kOuterSize> outerAlloc;
+
+ // deform vertices using the skeleton if it is passed in
+ if (bones && boneCount) {
+ // allocate space for the deformed vertices
+ SkPoint* deformed = outerAlloc.makeArray<SkPoint>(vertexCount);
+
+ // get the bone matrices
+ SkMatrix* transformedBones = outerAlloc.makeArray<SkMatrix>(boneCount);
+
+ // transform the bone matrices by the world transform
+ transformedBones[0] = bones[0];
+ for (int i = 1; i < boneCount; i ++) {
+ transformedBones[i] = SkMatrix::Concat(bones[i], bones[0]);
+ }
+
+ // deform the vertices
+ if (boneIndices && boneWeights) {
+ for (int i = 0; i < vertexCount; i ++) {
+ const SkVertices::BoneIndices& indices = boneIndices[i];
+ const SkVertices::BoneWeights& weights = boneWeights[i];
+
+ // apply bone deformations
+ SkPoint result = SkPoint::Make(0.0f, 0.0f);
+ SkPoint transformed;
+ for (uint32_t j = 0; j < 4; j ++) {
+ // get the attachment data
+ uint32_t index = indices.indices[j];
+ float weight = weights.weights[j];
+
+ // skip the bone if there is no weight
+ if (weight == 0.0f) {
+ continue;
+ }
+ SkASSERT(index != 0);
+
+ // transformed = M * v
+ transformedBones[index].mapPoints(&transformed, &vertices[i], 1);
+
+ // result += transformed * w
+ result += transformed * weight;
+ }
+
+ // set the deformed point
+ deformed[i] = result;
+ }
+ } else {
+ // no bones, so only apply world transform
+ const SkMatrix& worldTransform = bones[0];
+ worldTransform.mapPoints(deformed, vertices, vertexCount);
+ }
+
+ // change the vertices to point to deformed
+ vertices = deformed;
+ }
- SkPoint* devVerts = outerAlloc.makeArray<SkPoint>(count);
- fMatrix->mapPoints(devVerts, vertices, count);
+ SkPoint* devVerts = outerAlloc.makeArray<SkPoint>(vertexCount);
+ fMatrix->mapPoints(devVerts, vertices, vertexCount);
{
SkRect bounds;
// this also sets bounds to empty if we see a non-finite value
- bounds.set(devVerts, count);
+ bounds.set(devVerts, vertexCount);
if (bounds.isEmpty()) {
return;
}
}
- VertState state(count, indices, indexCount);
+ VertState state(vertexCount, indices, indexCount);
VertState::Proc vertProc = state.chooseProc(vmode);
if (colors || textures) {
@@ -230,10 +287,11 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int count,
Matrix43* matrix43 = nullptr;
if (colors) {
- dstColors = convert_colors(colors, count, fDst.colorSpace(), &outerAlloc);
+ dstColors = convert_colors(colors, vertexCount, fDst.colorSpace(), &outerAlloc);
SkTriColorShader* triShader = outerAlloc.make<SkTriColorShader>(
- compute_is_opaque(colors, count));
+ compute_is_opaque(colors,
+ vertexCount));
matrix43 = triShader->getMatrix43();
if (shader) {
shader = outerAlloc.make<SkComposeShader>(sk_ref_sp(triShader), sk_ref_sp(shader),
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index ce6f0d3191..4240055480 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -459,13 +459,17 @@ namespace {
};
struct DrawVertices final : Op {
static const auto kType = Type::DrawVertices;
- DrawVertices(const SkVertices* v, SkBlendMode m, const SkPaint& p)
- : vertices(sk_ref_sp(const_cast<SkVertices*>(v))), mode(m), paint(p) {}
+ DrawVertices(const SkVertices* v, int bc, SkBlendMode m, const SkPaint& p)
+ : vertices(sk_ref_sp(const_cast<SkVertices*>(v)))
+ , boneCount(bc)
+ , mode(m)
+ , paint(p) {}
sk_sp<SkVertices> vertices;
+ int boneCount;
SkBlendMode mode;
SkPaint paint;
void draw(SkCanvas* c, const SkMatrix&) const {
- c->drawVertices(vertices, mode, paint);
+ c->drawVertices(vertices, pod<SkMatrix>(this), boneCount, mode, paint);
}
};
struct DrawAtlas final : Op {
@@ -676,8 +680,14 @@ void SkLiteDL::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint
void* pod = this->push<DrawPoints>(count*sizeof(SkPoint), mode, count, paint);
copy_v(pod, points,count);
}
-void SkLiteDL::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
- this->push<DrawVertices>(0, vertices, mode, paint);
+void SkLiteDL::drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
+ SkBlendMode mode, const SkPaint& paint) {
+ void* pod = this->push<DrawVertices>(boneCount * sizeof(SkMatrix),
+ vertices,
+ boneCount,
+ mode,
+ paint);
+ copy_v(pod, bones, boneCount);
}
void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
const SkColor colors[], int count, SkBlendMode xfermode,
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index 6d63657084..b63ed0d514 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -76,7 +76,8 @@ public:
void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4],
SkBlendMode, const SkPaint&);
void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&);
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&);
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, 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&);
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
index bd41ff3913..0891508c92 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -182,9 +182,9 @@ void SkLiteRecorder::onDrawPoints(SkCanvas::PointMode mode,
const SkPaint& paint) {
fDL->drawPoints(mode, count, pts, paint);
}
-void SkLiteRecorder::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
- const SkPaint& paint) {
- fDL->drawVertices(vertices, mode, paint);
+void SkLiteRecorder::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode mode, const SkPaint& paint) {
+ fDL->drawVertices(vertices, bones, boneCount, mode, paint);
}
void SkLiteRecorder::onDrawAtlas(const SkImage* atlas,
const SkRSXform xforms[],
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
index 6b21c8984b..af538ee3aa 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -77,7 +77,8 @@ public:
void onDrawPatch(const SkPoint[12], const SkColor[4],
const SkPoint[4], SkBlendMode, const SkPaint&) override;
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
- void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, 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;
diff --git a/src/core/SkOverdrawCanvas.cpp b/src/core/SkOverdrawCanvas.cpp
index 25bc7fb160..b86f9a333c 100644
--- a/src/core/SkOverdrawCanvas.cpp
+++ b/src/core/SkOverdrawCanvas.cpp
@@ -219,9 +219,14 @@ void SkOverdrawCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint
fList[0]->onDrawPoints(mode, count, points, this->overdrawPaint(paint));
}
-void SkOverdrawCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode blendMode,
+void SkOverdrawCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode blendMode,
const SkPaint& paint) {
- fList[0]->onDrawVerticesObject(vertices, blendMode, this->overdrawPaint(paint));
+ fList[0]->onDrawVerticesObject(vertices,
+ bones,
+ boneCount,
+ blendMode,
+ this->overdrawPaint(paint));
}
void SkOverdrawCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[],
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 780cb13349..f63abe724c 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -615,11 +615,15 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
case DRAW_VERTICES_OBJECT: {
const SkPaint* paint = fPictureData->getPaint(reader);
const SkVertices* vertices = fPictureData->getVertices(reader);
+ const int boneCount = reader->readInt();
+ const SkMatrix* bones = boneCount ?
+ (const SkMatrix*) reader->skip(boneCount, sizeof(SkMatrix)) :
+ nullptr;
SkBlendMode bmode = reader->read32LE(SkBlendMode::kLastMode);
BREAK_ON_READ_ERROR(reader);
if (paint && vertices) {
- canvas->drawVertices(vertices, bmode, *paint);
+ canvas->drawVertices(vertices, bones, boneCount, bmode, *paint);
}
} break;
case RESTORE:
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 87c8c4d2fb..922fb6a425 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -682,14 +682,16 @@ void SkPictureRecord::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matri
this->validate(initialOffset, size);
}
-void SkPictureRecord::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
- const SkPaint& paint) {
- // op + paint index + vertices index + mode
- size_t size = 4 * kUInt32Size;
+void SkPictureRecord::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode mode, const SkPaint& paint) {
+ // op + paint index + vertices index + number of bones + bone matrices + mode
+ size_t size = 5 * kUInt32Size + boneCount * sizeof(SkMatrix);
size_t initialOffset = this->addDraw(DRAW_VERTICES_OBJECT, &size);
this->addPaint(paint);
this->addVertices(vertices);
+ this->addInt(boneCount);
+ fWriter.write(bones, boneCount * sizeof(SkMatrix));
this->addInt(static_cast<uint32_t>(mode));
this->validate(initialOffset, size);
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index ad2dbdfd24..dc9f4d9bdc 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -196,7 +196,8 @@ protected:
void onDrawImageLattice(const SkImage*, const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint*) override;
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
- void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint&) override;
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index f712c0e436..9c58456295 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -126,7 +126,7 @@ DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, &r.matrix, r.p
DRAW(DrawTextRSXform, drawTextRSXform(r.text, r.byteLength, r.xforms, r.cull, r.paint));
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(DrawVertices, drawVertices(r.vertices, r.bones, r.boneCount, 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
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 65dcd7bb4b..1abd5823af 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -317,9 +317,13 @@ void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con
}
}
-void SkRecorder::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
- const SkPaint& paint) {
- this->append<SkRecords::DrawVertices>(paint, sk_ref_sp(const_cast<SkVertices*>(vertices)), bmode);
+void SkRecorder::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode bmode, const SkPaint& paint) {
+ this->append<SkRecords::DrawVertices>(paint,
+ sk_ref_sp(const_cast<SkVertices*>(vertices)),
+ this->copy(bones, boneCount),
+ boneCount,
+ bmode);
}
void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 6a7a83bdc2..7fed8eaacc 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -121,7 +121,8 @@ public:
const SkPaint*) override;
void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst,
const SkPaint*) override;
- void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, 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;
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 67424aca2a..4ec2ae68c7 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -344,6 +344,8 @@ RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
sk_sp<SkVertices> vertices;
+ PODArray<SkMatrix> bones;
+ int boneCount;
SkBlendMode bmode);
RECORD(DrawShadowRec, kDraw_Tag,
PreCachedPath path;
diff --git a/src/core/SkThreadedBMPDevice.cpp b/src/core/SkThreadedBMPDevice.cpp
index 10cd824205..de2b6c0230 100644
--- a/src/core/SkThreadedBMPDevice.cpp
+++ b/src/core/SkThreadedBMPDevice.cpp
@@ -222,15 +222,16 @@ void SkThreadedBMPDevice::drawPosText(const void* text, size_t len, const SkScal
});
}
-void SkThreadedBMPDevice::drawVertices(const SkVertices* vertices, SkBlendMode bmode,
- const SkPaint& paint) {
+void SkThreadedBMPDevice::drawVertices(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode bmode, const SkPaint& paint) {
const sk_sp<SkVertices> verts = sk_ref_sp(vertices); // retain vertices until flush
SkRect drawBounds = SkRectPriv::MakeLargest(); // TODO tighter drawBounds
fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds){
TileDraw(ds, tileBounds).drawVertices(verts->mode(), verts->vertexCount(),
verts->positions(), verts->texCoords(),
- verts->colors(), bmode, verts->indices(),
- verts->indexCount(), paint);
+ verts->colors(), verts->boneIndices(),
+ verts->boneWeights(), bmode, verts->indices(),
+ verts->indexCount(), paint, bones, boneCount);
});
}
diff --git a/src/core/SkThreadedBMPDevice.h b/src/core/SkThreadedBMPDevice.h
index 13d837424c..0cfb91db07 100644
--- a/src/core/SkThreadedBMPDevice.h
+++ b/src/core/SkThreadedBMPDevice.h
@@ -35,7 +35,8 @@ protected:
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override;
void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint&) override;
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
const SkPaint&) override;
diff --git a/src/core/SkVertices.cpp b/src/core/SkVertices.cpp
index d4c6ed56de..04db0d35fb 100644
--- a/src/core/SkVertices.cpp
+++ b/src/core/SkVertices.cpp
@@ -27,12 +27,14 @@ static int32_t next_id() {
struct SkVertices::Sizes {
Sizes(SkVertices::VertexMode mode, int vertexCount, int indexCount, bool hasTexs,
- bool hasColors) {
+ bool hasColors, bool hasBones) {
SkSafeMath safe;
fVSize = safe.mul(vertexCount, sizeof(SkPoint));
fTSize = hasTexs ? safe.mul(vertexCount, sizeof(SkPoint)) : 0;
fCSize = hasColors ? safe.mul(vertexCount, sizeof(SkColor)) : 0;
+ fBISize = hasBones ? safe.mul(vertexCount, sizeof(BoneIndices)) : 0;
+ fBWSize = hasBones ? safe.mul(vertexCount, sizeof(BoneWeights)) : 0;
fBuilderTriFanISize = 0;
fISize = safe.mul(indexCount, sizeof(uint16_t));
@@ -61,7 +63,9 @@ struct SkVertices::Sizes {
safe.add(fVSize,
safe.add(fTSize,
safe.add(fCSize,
- fISize))));
+ safe.add(fBISize,
+ safe.add(fBWSize,
+ fISize))))));
if (safe.ok()) {
fArrays = fTotal - sizeof(SkVertices); // just the sum of the arrays
@@ -73,10 +77,12 @@ struct SkVertices::Sizes {
bool isValid() const { return fTotal != 0; }
size_t fTotal; // size of entire SkVertices allocation (obj + arrays)
- size_t fArrays; // size of all the arrays (V + T + C + I)
+ size_t fArrays; // size of all the arrays (V + T + C + BI + BW + I)
size_t fVSize;
size_t fTSize;
size_t fCSize;
+ size_t fBISize;
+ size_t fBWSize;
size_t fISize;
// For indexed tri-fans this is the number of amount of space fo indices needed in the builder
@@ -88,8 +94,9 @@ SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount,
uint32_t builderFlags) {
bool hasTexs = SkToBool(builderFlags & SkVertices::kHasTexCoords_BuilderFlag);
bool hasColors = SkToBool(builderFlags & SkVertices::kHasColors_BuilderFlag);
+ bool hasBones = SkToBool(builderFlags & SkVertices::kHasBones_BuilderFlag);
this->init(mode, vertexCount, indexCount,
- SkVertices::Sizes(mode, vertexCount, indexCount, hasTexs, hasColors));
+ SkVertices::Sizes(mode, vertexCount, indexCount, hasTexs, hasColors, hasBones));
}
SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount,
@@ -113,13 +120,16 @@ void SkVertices::Builder::init(VertexMode mode, int vertexCount, int indexCount,
// need to point past the object to store the arrays
char* ptr = (char*)storage + sizeof(SkVertices);
- fVertices->fPositions = (SkPoint*)ptr; ptr += sizes.fVSize;
- fVertices->fTexs = sizes.fTSize ? (SkPoint*)ptr : nullptr; ptr += sizes.fTSize;
- fVertices->fColors = sizes.fCSize ? (SkColor*)ptr : nullptr; ptr += sizes.fCSize;
+ fVertices->fPositions = (SkPoint*)ptr; ptr += sizes.fVSize;
+ fVertices->fTexs = sizes.fTSize ? (SkPoint*)ptr : nullptr; ptr += sizes.fTSize;
+ fVertices->fColors = sizes.fCSize ? (SkColor*)ptr : nullptr; ptr += sizes.fCSize;
+ fVertices->fBoneIndices = sizes.fBISize ? (BoneIndices*) ptr : nullptr; ptr += sizes.fBISize;
+ fVertices->fBoneWeights = sizes.fBWSize ? (BoneWeights*) ptr : nullptr; ptr += sizes.fBWSize;
fVertices->fIndices = sizes.fISize ? (uint16_t*)ptr : nullptr;
fVertices->fVertexCnt = vertexCount;
fVertices->fIndexCnt = indexCount;
fVertices->fMode = mode;
+
// We defer assigning fBounds and fUniqueID until detach() is called
}
@@ -173,6 +183,14 @@ SkColor* SkVertices::Builder::colors() {
return fVertices ? const_cast<SkColor*>(fVertices->colors()) : nullptr;
}
+SkVertices::BoneIndices* SkVertices::Builder::boneIndices() {
+ return fVertices ? const_cast<BoneIndices*>(fVertices->boneIndices()) : nullptr;
+}
+
+SkVertices::BoneWeights* SkVertices::Builder::boneWeights() {
+ return fVertices ? const_cast<BoneWeights*>(fVertices->boneWeights()) : nullptr;
+}
+
uint16_t* SkVertices::Builder::indices() {
if (!fVertices) {
return nullptr;
@@ -187,9 +205,17 @@ uint16_t* SkVertices::Builder::indices() {
sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount,
const SkPoint pos[], const SkPoint texs[],
- const SkColor colors[], int indexCount,
- const uint16_t indices[]) {
- Sizes sizes(mode, vertexCount, indexCount, texs != nullptr, colors != nullptr);
+ const SkColor colors[],
+ const BoneIndices boneIndices[],
+ const BoneWeights boneWeights[],
+ int indexCount, const uint16_t indices[]) {
+ SkASSERT((!boneIndices && !boneWeights) || (boneIndices && boneWeights));
+ Sizes sizes(mode,
+ vertexCount,
+ indexCount,
+ texs != nullptr,
+ colors != nullptr,
+ boneIndices != nullptr);
if (!sizes.isValid()) {
return nullptr;
}
@@ -200,6 +226,8 @@ sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount,
sk_careful_memcpy(builder.positions(), pos, sizes.fVSize);
sk_careful_memcpy(builder.texCoords(), texs, sizes.fTSize);
sk_careful_memcpy(builder.colors(), colors, sizes.fCSize);
+ sk_careful_memcpy(builder.boneIndices(), boneIndices, sizes.fBISize);
+ sk_careful_memcpy(builder.boneWeights(), boneWeights, sizes.fBWSize);
size_t isize = (mode == kTriangleFan_VertexMode) ? sizes.fBuilderTriFanISize : sizes.fISize;
sk_careful_memcpy(builder.indices(), indices, isize);
@@ -207,19 +235,26 @@ sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount,
}
size_t SkVertices::approximateSize() const {
- Sizes sizes(fMode, fVertexCnt, fIndexCnt, this->hasTexCoords(), this->hasColors());
+ Sizes sizes(fMode,
+ fVertexCnt,
+ fIndexCnt,
+ this->hasTexCoords(),
+ this->hasColors(),
+ this->hasBones());
SkASSERT(sizes.isValid());
return sizeof(SkVertices) + sizes.fArrays;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
-// storage = packed | vertex_count | index_count | pos[] | texs[] | colors[] | indices[]
+// storage = packed | vertex_count | index_count | pos[] | texs[] | colors[] | boneIndices[] |
+// boneWeights[] | indices[]
// = header + arrays
#define kMode_Mask 0x0FF
#define kHasTexs_Mask 0x100
#define kHasColors_Mask 0x200
+#define kHasBones_Mask 0x400
#define kHeaderSize (3 * sizeof(uint32_t))
sk_sp<SkData> SkVertices::encode() const {
@@ -232,8 +267,16 @@ sk_sp<SkData> SkVertices::encode() const {
if (this->hasColors()) {
packed |= kHasColors_Mask;
}
+ if (this->hasBones()) {
+ packed |= kHasBones_Mask;
+ }
- Sizes sizes(fMode, fVertexCnt, fIndexCnt, this->hasTexCoords(), this->hasColors());
+ Sizes sizes(fMode,
+ fVertexCnt,
+ fIndexCnt,
+ this->hasTexCoords(),
+ this->hasColors(),
+ this->hasBones());
SkASSERT(sizes.isValid());
SkASSERT(!sizes.fBuilderTriFanISize);
// need to force alignment to 4 for SkWriter32 -- will pad w/ 0s as needed
@@ -248,6 +291,8 @@ sk_sp<SkData> SkVertices::encode() const {
writer.write(fPositions, sizes.fVSize);
writer.write(fTexs, sizes.fTSize);
writer.write(fColors, sizes.fCSize);
+ writer.write(fBoneIndices, sizes.fBISize);
+ writer.write(fBoneWeights, sizes.fBWSize);
// if index-count is odd, we won't be 4-bytes aligned, so we call the pad version
writer.writePad(fIndices, sizes.fISize);
@@ -272,7 +317,8 @@ sk_sp<SkVertices> SkVertices::Decode(const void* data, size_t length) {
}
const bool hasTexs = SkToBool(packed & kHasTexs_Mask);
const bool hasColors = SkToBool(packed & kHasColors_Mask);
- Sizes sizes(mode, vertexCount, indexCount, hasTexs, hasColors);
+ const bool hasBones = SkToBool(packed & kHasBones_Mask);
+ Sizes sizes(mode, vertexCount, indexCount, hasTexs, hasColors, hasBones);
if (!sizes.isValid()) {
return nullptr;
}
@@ -286,6 +332,8 @@ sk_sp<SkVertices> SkVertices::Decode(const void* data, size_t length) {
reader.read(builder.positions(), sizes.fVSize);
reader.read(builder.texCoords(), sizes.fTSize);
reader.read(builder.colors(), sizes.fCSize);
+ reader.read(builder.boneIndices(), sizes.fBISize);
+ reader.read(builder.boneWeights(), sizes.fBWSize);
size_t isize = (mode == kTriangleFan_VertexMode) ? sizes.fBuilderTriFanISize : sizes.fISize;
reader.read(builder.indices(), isize);
if (indexCount > 0) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 819acd2ef8..a665517d4f 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1541,7 +1541,9 @@ void SkGpuDevice::wireframeVertices(SkVertices::VertexMode vmode, int vertexCoun
&primitiveType);
}
-void SkGpuDevice::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
+void SkGpuDevice::drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
+ SkBlendMode mode, const SkPaint& paint) {
+ // TODO: GPU ANIMATION
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVertices", fContext.get());
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 7c7030e1ab..48ba8ac8a1 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -91,7 +91,8 @@ public:
int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
const SkPaint& paint, SkDrawFilter* drawFilter) override;
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, 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;
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 45a9b95915..2d2e27bf1f 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1473,7 +1473,8 @@ void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
}
}
-void SkPDFDevice::drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) {
+void SkPDFDevice::drawVertices(const SkVertices*, const SkMatrix*, int, SkBlendMode,
+ const SkPaint&) {
if (this->hasEmptyClip()) {
return;
}
diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h
index 33d0e70e67..4c9c9c88ac 100644
--- a/src/pdf/SkPDFDevice.h
+++ b/src/pdf/SkPDFDevice.h
@@ -100,7 +100,8 @@ public:
const SkPoint& offset, const SkPaint&) override;
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
const SkPaint &, SkDrawFilter*) override;
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint&) override;
void drawDevice(SkBaseDevice*, int x, int y,
const SkPaint&) override;
diff --git a/src/pipe/SkPipeCanvas.cpp b/src/pipe/SkPipeCanvas.cpp
index d66953c5bd..aabff5bfae 100644
--- a/src/pipe/SkPipeCanvas.cpp
+++ b/src/pipe/SkPipeCanvas.cpp
@@ -728,14 +728,16 @@ void SkPipeCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
write_paint(writer, paint, kGeometry_PaintUsage);
}
-void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
- const SkPaint& paint) {
+void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode bmode, const SkPaint& paint) {
unsigned extra = static_cast<unsigned>(bmode);
SkPipeWriter writer(this);
writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra));
// TODO: dedup vertices?
writer.writeDataAsByteArray(vertices->encode().get());
+ writer.write32(boneCount);
+ writer.write(bones, sizeof(SkMatrix) * boneCount);
write_paint(writer, paint, kVertices_PaintUsage);
}
diff --git a/src/pipe/SkPipeCanvas.h b/src/pipe/SkPipeCanvas.h
index 65bca4dfc4..b39f80920b 100644
--- a/src/pipe/SkPipeCanvas.h
+++ b/src/pipe/SkPipeCanvas.h
@@ -135,7 +135,8 @@ protected:
const SkPaint*) override;
void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst,
const SkPaint*) override;
- void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint&) override;
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
diff --git a/src/pipe/SkPipeReader.cpp b/src/pipe/SkPipeReader.cpp
index ada4a21342..312e3da4e8 100644
--- a/src/pipe/SkPipeReader.cpp
+++ b/src/pipe/SkPipeReader.cpp
@@ -562,9 +562,14 @@ static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb,
static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb));
SkBlendMode bmode = (SkBlendMode)unpack_verb_extra(packedVerb);
+ sk_sp<SkVertices> vertices = nullptr;
if (sk_sp<SkData> data = reader.readByteArrayAsData()) {
- canvas->drawVertices(SkVertices::Decode(data->data(), data->size()), bmode,
- read_paint(reader));
+ vertices = SkVertices::Decode(data->data(), data->size());
+ }
+ int boneCount = reader.read32();
+ const SkMatrix* bones = boneCount ? reader.skipT<SkMatrix>(boneCount) : nullptr;
+ if (vertices) {
+ canvas->drawVertices(vertices, bones, boneCount, bmode, read_paint(reader));
}
}
diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp
index d552803e73..c2a402f695 100644
--- a/src/svg/SkSVGDevice.cpp
+++ b/src/svg/SkSVGDevice.cpp
@@ -988,7 +988,8 @@ void SkSVGDevice::drawTextOnPath(const void* text, size_t len, const SkPath& pat
}
}
-void SkSVGDevice::drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) {
+void SkSVGDevice::drawVertices(const SkVertices*, const SkMatrix*, int, SkBlendMode,
+ const SkPaint&) {
// todo
}
diff --git a/src/svg/SkSVGDevice.h b/src/svg/SkSVGDevice.h
index 4784c7e238..6b8ee4ff44 100644
--- a/src/svg/SkSVGDevice.h
+++ b/src/svg/SkSVGDevice.h
@@ -43,7 +43,8 @@ protected:
void drawTextOnPath(const void* text, size_t len,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint) override;
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) override;
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint& paint) override;
void drawDevice(SkBaseDevice*, int x, int y,
const SkPaint&) override;
diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp
index c7e3064c9b..441857f664 100644
--- a/src/utils/SkLuaCanvas.cpp
+++ b/src/utils/SkLuaCanvas.cpp
@@ -314,7 +314,8 @@ void SkLuaCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
this->INHERITED::onDrawDrawable(drawable, matrix);
}
-void SkLuaCanvas::onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint& paint) {
+void SkLuaCanvas::onDrawVerticesObject(const SkVertices*, const SkMatrix*, int, SkBlendMode,
+ const SkPaint& paint) {
AUTO_LUA("drawVertices");
lua.pushPaint(paint, "paint");
}
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index c9f9768e7c..017ec0551b 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -320,11 +320,11 @@ void SkNWayCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix)
}
}
-void SkNWayCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
- const SkPaint& paint) {
+void SkNWayCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode bmode, const SkPaint& paint) {
Iter iter(fList);
while (iter.next()) {
- iter->drawVertices(vertices, bmode, paint);
+ iter->drawVertices(vertices, bones, boneCount, bmode, paint);
}
}
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index c17990d536..929488caea 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -173,11 +173,12 @@ void SkPaintFilterCanvas::onDrawImageLattice(const SkImage* image, const Lattice
}
}
-void SkPaintFilterCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
+void SkPaintFilterCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
+ int boneCount, SkBlendMode bmode,
const SkPaint& paint) {
AutoPaintFilter apf(this, kVertices_Type, paint);
if (apf.shouldDraw()) {
- this->SkNWayCanvas::onDrawVerticesObject(vertices, bmode, *apf.paint());
+ this->SkNWayCanvas::onDrawVerticesObject(vertices, bones, boneCount, bmode, *apf.paint());
}
}
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 6d5b7e16b4..c6b92ad985 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -545,7 +545,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
if (vertices->vertexCount()) {
SkAutoDeviceCTMRestore adr(this, SkMatrix::Concat(this->ctm(),
SkMatrix::MakeTrans(tx, ty)));
- this->drawVertices(vertices, mode, paint);
+ this->drawVertices(vertices, nullptr, 0, mode, paint);
}
};
@@ -580,7 +580,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
SkColorFilter::MakeModeFilter(rec.fAmbientColor,
SkBlendMode::kModulate)->makeComposed(
SkGaussianColorFilter::Make()));
- this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
+ this->drawVertices(vertices.get(), nullptr, 0, SkBlendMode::kModulate, paint);
success = true;
}
}
@@ -661,7 +661,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
SkColorFilter::MakeModeFilter(rec.fSpotColor,
SkBlendMode::kModulate)->makeComposed(
SkGaussianColorFilter::Make()));
- this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
+ this->drawVertices(vertices.get(), nullptr, 0, SkBlendMode::kModulate, paint);
success = true;
}
}
diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp
index 36d1bd171f..797ff38483 100644
--- a/src/xps/SkXPSDevice.cpp
+++ b/src/xps/SkXPSDevice.cpp
@@ -1156,9 +1156,11 @@ void SkXPSDevice::drawPoints(SkCanvas::PointMode mode,
draw(this, &SkDraw::drawPoints, mode, count, points, paint, this);
}
-void SkXPSDevice::drawVertices(const SkVertices* v, SkBlendMode blendMode, const SkPaint& paint) {
+void SkXPSDevice::drawVertices(const SkVertices* v, const SkMatrix* bones, int boneCount,
+ SkBlendMode blendMode, const SkPaint& paint) {
draw(this, &SkDraw::drawVertices, v->mode(), v->vertexCount(), v->positions(), v->texCoords(),
- v->colors(), blendMode, v->indices(), v->indexCount(), paint);
+ v->colors(), v->boneIndices(), v->boneWeights(), blendMode, v->indices(), v->indexCount(),
+ paint, bones, boneCount);
}
void SkXPSDevice::drawPaint(const SkPaint& origPaint) {
diff --git a/src/xps/SkXPSDevice.h b/src/xps/SkXPSDevice.h
index 81e881ea82..03de5f1dcb 100644
--- a/src/xps/SkXPSDevice.h
+++ b/src/xps/SkXPSDevice.h
@@ -100,7 +100,8 @@ protected:
void drawPosText(const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) override;
- void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
+ void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
+ const SkPaint&) override;
void drawDevice(SkBaseDevice*, int x, int y,
const SkPaint&) override;