aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkDraw_vertices.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkDraw_vertices.cpp')
-rw-r--r--src/core/SkDraw_vertices.cpp88
1 files changed, 73 insertions, 15 deletions
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),