added optimizations to speed up skinning
Docs-Preview: https://skia.org/?cl=145148 Bug: skia: Change-Id: If27722105a1e8999f6440b6fd4044cc1f327827e Reviewed-on: https://skia-review.googlesource.com/145148 Commit-Queue: Ruiqi Mao <ruiqimao@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
137ca523a3
commit
c97a339cd6
@ -5749,8 +5749,8 @@ void draw(SkCanvas* canvas) {
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#Method void drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint)
|
||||
#Method void drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint)
|
||||
|
||||
Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
|
||||
deform vertices with bone weights.
|
||||
@ -5759,7 +5759,7 @@ contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
|
||||
The first element of bones should be an object to world space transformation matrix that
|
||||
will be applied before performing mesh deformations. If no such transformation is needed,
|
||||
it should be the identity matrix.
|
||||
boneCount must be at most 100, and thus the size of bones should be at most 100.
|
||||
boneCount must be at most 80, and thus the size of bones should be at most 80.
|
||||
|
||||
#Param vertices triangle mesh to draw ##
|
||||
#Param bones bone matrix data ##
|
||||
@ -5767,7 +5767,7 @@ boneCount must be at most 100, and thus the size of bones should be at most 100.
|
||||
#Param mode combines Vertices_Colors with Shader, if both are present ##
|
||||
#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
|
||||
|
||||
#Example
|
||||
#NoExample
|
||||
void draw(SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
|
||||
@ -5781,10 +5781,10 @@ void draw(SkCanvas* canvas) {
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f } };
|
||||
SkMatrix bones[] = { SkMatrix::I(),
|
||||
SkMatrix::MakeTrans(0, 20),
|
||||
SkMatrix::MakeTrans(50, 50),
|
||||
SkMatrix::MakeTrans(20, 0) };
|
||||
SkVertices::Bone bones[] = { {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }},
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 20.0f }},
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 50.0f, 50.0f }},
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f }} };
|
||||
paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
|
||||
SkShader::kClamp_TileMode));
|
||||
auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
|
||||
@ -5799,8 +5799,8 @@ void draw(SkCanvas* canvas) {
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#Method void drawVertices(const sk_sp<SkVertices>& vertices, const SkMatrix* bones, int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint)
|
||||
#Method void drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint)
|
||||
|
||||
Draws Vertices vertices, a triangle mesh, using Clip and Matrix. Bone data is used to
|
||||
deform vertices with bone weights.
|
||||
@ -5809,7 +5809,7 @@ contains Shader, Blend_Mode mode combines Vertices_Colors with Shader.
|
||||
The first element of bones should be an object to world space transformation matrix that
|
||||
will be applied before performing mesh deformations. If no such transformation is needed,
|
||||
it should be the identity matrix.
|
||||
boneCount must be at most 100, and thus the size of bones should be at most 100.
|
||||
boneCount must be at most 80, and thus the size of bones should be at most 80.
|
||||
|
||||
#Param vertices triangle mesh to draw ##
|
||||
#Param bones bone matrix data ##
|
||||
@ -5817,7 +5817,7 @@ boneCount must be at most 100, and thus the size of bones should be at most 100.
|
||||
#Param mode combines Vertices_Colors with Shader, if both are present ##
|
||||
#Param paint specifies the Shader, used as Vertices texture, may be nullptr ##
|
||||
|
||||
#Example
|
||||
#NoExample
|
||||
void draw(SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };
|
||||
@ -5831,10 +5831,10 @@ void draw(SkCanvas* canvas) {
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f } };
|
||||
SkMatrix bones[] = { SkMatrix::I(),
|
||||
SkMatrix::MakeTrans(0, 20),
|
||||
SkMatrix::MakeTrans(50, 50),
|
||||
SkMatrix::MakeTrans(20, 0) };
|
||||
SkVertices::Bone bones[] = { {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }},
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 20.0f }},
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 50.0f, 50.0f }},
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f }} };
|
||||
paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,
|
||||
SkShader::kClamp_TileMode));
|
||||
auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,
|
||||
|
@ -7,7 +7,7 @@
|
||||
API
|
||||
BMP GIF HEIF ICO JPEG PNG WBMP WebP
|
||||
CPU
|
||||
GPU GPU-backed OpenGL Vulkan I/O MSAA
|
||||
GPU GPU-backed OpenGL Vulkan I/O MSAA
|
||||
PDF XPS
|
||||
RFC
|
||||
NaN NaNs
|
||||
@ -81,8 +81,8 @@ FT_Load_Glyph
|
||||
#Substitute unhinted
|
||||
##
|
||||
|
||||
# this jargon requires a substitute to space the phrase.
|
||||
#Topic Little_Endian
|
||||
# this jargon requires a substitute to space the phrase.
|
||||
#Topic Little_Endian
|
||||
#Substitute little endian
|
||||
##
|
||||
|
||||
@ -90,11 +90,11 @@ FT_Load_Glyph
|
||||
#Substitute big endian
|
||||
##
|
||||
|
||||
#Topic YUV_Component_Y
|
||||
#Topic YUV_Component_Y
|
||||
#Substitute YUV component y
|
||||
##
|
||||
|
||||
#Topic YUV_Component_U
|
||||
#Topic YUV_Component_U
|
||||
#Substitute YUV component u
|
||||
##
|
||||
|
||||
@ -106,7 +106,7 @@ FT_Load_Glyph
|
||||
#Substitute UV mapping
|
||||
##
|
||||
|
||||
#Topic Multi_Sample_Anti_Aliasing
|
||||
#Topic Multi_Sample_Anti_Aliasing
|
||||
#Substitute multi-sample anti-aliasing
|
||||
##
|
||||
|
||||
@ -114,43 +114,43 @@ FT_Load_Glyph
|
||||
#Substitute GPU share group
|
||||
##
|
||||
|
||||
#Topic Bezier_Curve
|
||||
#Topic Bezier_Curve
|
||||
#Substitute Bezier cruve
|
||||
##
|
||||
|
||||
#Topic Coons_Patch
|
||||
#Topic Coons_Patch
|
||||
#Substitute Coons patch
|
||||
##
|
||||
|
||||
#Topic Cartesian_Coordinate
|
||||
#Topic Cartesian_Coordinate
|
||||
#Substitute Cartesian coordinate
|
||||
##
|
||||
|
||||
#Topic Euclidean_Distance
|
||||
#Topic Euclidean_Distance
|
||||
#Substitute Euclidean distance
|
||||
##
|
||||
|
||||
#Topic Euclidean_Space
|
||||
#Topic Euclidean_Space
|
||||
#Substitute Euclidean space
|
||||
##
|
||||
|
||||
#Topic HTML_Gray
|
||||
#Topic HTML_Gray
|
||||
#Substitute HTML gray
|
||||
##
|
||||
|
||||
#Topic HTML_Silver
|
||||
#Topic HTML_Silver
|
||||
#Substitute HTML silver
|
||||
##
|
||||
|
||||
#Topic HTML_Lime
|
||||
#Topic HTML_Lime
|
||||
#Substitute HTML lime
|
||||
##
|
||||
|
||||
#Topic HTML_Green
|
||||
#Topic HTML_Green
|
||||
#Substitute HTML green
|
||||
##
|
||||
|
||||
#Topic HTML_Aqua
|
||||
#Topic HTML_Aqua
|
||||
#Substitute HTML aqua
|
||||
##
|
||||
|
||||
@ -158,7 +158,7 @@ FT_Load_Glyph
|
||||
#Substitute HTML fuchsia
|
||||
##
|
||||
|
||||
#Topic SVG_lightgray
|
||||
#Topic SVG_lightgray
|
||||
#Substitute SVG light gray
|
||||
##
|
||||
|
||||
@ -787,6 +787,8 @@ FT_Load_Glyph
|
||||
|
||||
#Topic Vertices
|
||||
#Class SkVertices
|
||||
#Class Bone
|
||||
##
|
||||
##
|
||||
#Subtopic Colors
|
||||
##
|
||||
|
@ -147,6 +147,7 @@ Complete rebuilding of all bookmaker output looks like:
|
||||
$ ./out/skia/bookmaker -a docs/status.json -e fiddle.json
|
||||
$ ~/go/bin/fiddlecli --input fiddle.json --output fiddleout.json
|
||||
$ ./out/skia/bookmaker -a docs/status.json -f fiddleout.json -r site/user/api -c
|
||||
$ ./out/skia/bookmaker -a docs/status.json -f fiddleout.json -r site/user/api
|
||||
$ ./out/skia/bookmaker -a docs/status.json -x
|
||||
$ ./out/skia/bookmaker -a docs/status.json -p
|
||||
##
|
||||
|
@ -18,14 +18,14 @@ static const int kCellSize = 60;
|
||||
static const int kColumnSize = 36;
|
||||
|
||||
static const int kBoneCount = 7;
|
||||
static const SkMatrix kBones[] = {
|
||||
SkMatrix::I(),
|
||||
SkMatrix::MakeTrans(10, 0),
|
||||
SkMatrix::MakeTrans(0, 10),
|
||||
SkMatrix::MakeTrans(-10, 0),
|
||||
SkMatrix::MakeTrans(0, -10),
|
||||
SkMatrix::MakeScale(0.5f),
|
||||
SkMatrix::MakeScale(1.5f),
|
||||
static const SkVertices::Bone kBones[] = {
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}, // SkMatrix::I()
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f }}, // SkMatrix::MakeTrans(10, 0)
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f }}, // SkMatrix::MakeTrans(0, 10)
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, -10.0f, 0.0f }}, // SkMatrix::MakeTrans(-10, 0)
|
||||
{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -10.0f }}, // SkMatrix::MakeTrans(0, -10)
|
||||
{{ 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f }}, // SkMatrix::MakeScale(0.5)
|
||||
{{ 1.5f, 0.0f, 0.0f, 1.5f, 0.0f, 0.0f }}, // SkMatrix::MakeScale(1.5)
|
||||
};
|
||||
|
||||
static const int kVertexCount = 4;
|
||||
@ -60,9 +60,9 @@ static const uint16_t kIndices[] = {
|
||||
2, 3, 0,
|
||||
};
|
||||
|
||||
// Swap two SkMatrix pointers in place.
|
||||
static void swap(const SkMatrix** x, const SkMatrix** y) {
|
||||
const SkMatrix* temp = *x;
|
||||
// Swap two SkVertices::Bone pointers in place.
|
||||
static void swap(const SkVertices::Bone** x, const SkVertices::Bone** y) {
|
||||
const SkVertices::Bone* temp = *x;
|
||||
*x = *y;
|
||||
*y = temp;
|
||||
}
|
||||
@ -116,7 +116,7 @@ protected:
|
||||
int ypos = kCellSize;
|
||||
|
||||
// Create the mutable set of bones.
|
||||
const SkMatrix* bones[kBoneCount];
|
||||
const SkVertices::Bone* bones[kBoneCount];
|
||||
for (int i = 0; i < kBoneCount; i ++) {
|
||||
bones[i] = &kBones[i];
|
||||
}
|
||||
@ -129,14 +129,14 @@ private:
|
||||
void drawPermutations(SkCanvas* canvas,
|
||||
int& xpos,
|
||||
int& ypos,
|
||||
const SkMatrix** bones,
|
||||
const SkVertices::Bone** bones,
|
||||
int start) {
|
||||
if (start == kBoneCount) {
|
||||
// Reached the end of the permutations, so draw.
|
||||
canvas->save();
|
||||
|
||||
// Copy the bones.
|
||||
SkMatrix copiedBones[kBoneCount];
|
||||
SkVertices::Bone copiedBones[kBoneCount];
|
||||
for (int i = 0; i < kBoneCount; i ++) {
|
||||
copiedBones[i] = *bones[i];
|
||||
}
|
||||
@ -146,42 +146,11 @@ private:
|
||||
|
||||
// Draw the vertices.
|
||||
if (fDeformUsingCPU) {
|
||||
// Apply the bones.
|
||||
sk_sp<SkVertices> vertices = fVertices->applyBones(copiedBones,
|
||||
kBoneCount);
|
||||
|
||||
// Deform with CPU.
|
||||
std::vector<SkPoint> positions(kVertexCount);
|
||||
for (int i = 0; i < kVertexCount; i ++) {
|
||||
const SkVertices::BoneIndices& indices = kBoneIndices[i];
|
||||
const SkVertices::BoneWeights& weights = kBoneWeights[i];
|
||||
|
||||
// Apply deformations.
|
||||
SkPoint& result = positions[i];
|
||||
SkPoint transformed;
|
||||
for (uint32_t j = 0; j < 4; j ++) {
|
||||
// Get the bone attachment data.
|
||||
uint32_t index = indices.indices[j];
|
||||
float weight = weights.weights[j];
|
||||
|
||||
// Skip the bone is there is no weight.
|
||||
if (weight == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
SkASSERT(index != 0);
|
||||
|
||||
// transformed = M * v
|
||||
copiedBones[index].mapPoints(&transformed, &kPositions[i], 1);
|
||||
|
||||
// result += transformed * w
|
||||
result += transformed * weight;
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
|
||||
kVertexCount,
|
||||
positions.data(),
|
||||
nullptr,
|
||||
kColors,
|
||||
kIndexCount,
|
||||
kIndices,
|
||||
!fCache);
|
||||
canvas->drawVertices(vertices.get(),
|
||||
SkBlendMode::kSrc,
|
||||
fPaint);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "SkPaint.h"
|
||||
#include "SkRasterHandleAllocator.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
#include "SkVertices.h"
|
||||
|
||||
class GrContext;
|
||||
class GrRenderTargetContext;
|
||||
@ -50,7 +51,6 @@ struct SkRSXform;
|
||||
class SkSurface;
|
||||
class SkSurface_Base;
|
||||
class SkTextBlob;
|
||||
class SkVertices;
|
||||
|
||||
/** \class SkCanvas
|
||||
SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
|
||||
@ -2149,7 +2149,7 @@ public:
|
||||
The first element of bones should be an object to world space transformation matrix that
|
||||
will be applied before performing mesh deformations. If no such transformation is needed,
|
||||
it should be the identity matrix.
|
||||
boneCount must be at most 100, and thus the size of bones should be at most 100.
|
||||
boneCount must be at most 80, and thus the size of bones should be at most 80.
|
||||
|
||||
@param vertices triangle mesh to draw
|
||||
@param bones bone matrix data
|
||||
@ -2157,7 +2157,7 @@ public:
|
||||
@param mode combines vertices colors with SkShader, if both are present
|
||||
@param paint specifies the SkShader, used as SkVertices texture, may be nullptr
|
||||
*/
|
||||
void drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
|
||||
void drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint);
|
||||
|
||||
/** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix. Bone data is used to
|
||||
@ -2167,7 +2167,7 @@ public:
|
||||
The first element of bones should be an object to world space transformation matrix that
|
||||
will be applied before performing mesh deformations. If no such transformation is needed,
|
||||
it should be the identity matrix.
|
||||
boneCount must be at most 100, and thus the size of bones should be at most 100.
|
||||
boneCount must be at most 80, and thus the size of bones should be at most 80.
|
||||
|
||||
@param vertices triangle mesh to draw
|
||||
@param bones bone matrix data
|
||||
@ -2175,8 +2175,8 @@ public:
|
||||
@param mode combines vertices colors with SkShader, if both are present
|
||||
@param paint specifies the SkShader, used as SkVertices texture, may be nullptr
|
||||
*/
|
||||
void drawVertices(const sk_sp<SkVertices>& vertices, const SkMatrix* bones, int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint);
|
||||
void drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint);
|
||||
|
||||
/** Draws a Coons patch: the interpolation of four cubics with shared corners,
|
||||
associating a color, and optionally a texture SkPoint, with each corner.
|
||||
@ -2496,7 +2496,7 @@ protected:
|
||||
const SkPaint& paint) {
|
||||
this->onDrawVerticesObject(vertices, nullptr, 0, mode, paint);
|
||||
}
|
||||
virtual void onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
virtual void onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint);
|
||||
|
||||
virtual void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, const SkPaint* paint);
|
||||
|
@ -48,8 +48,8 @@ protected:
|
||||
const SkPaint& paint) override = 0;
|
||||
void onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
|
||||
const SkPaint& paint) override = 0;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override = 0;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) override = 0;
|
||||
|
||||
void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy,
|
||||
const SkPaint* paint) override = 0;
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
|
||||
void onDrawRRect(const SkRRect&, const SkPaint&) override;
|
||||
void onDrawPoints(PointMode, size_t, const SkPoint[], const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone 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 onDrawPath(const SkPath&, const SkPaint&) override;
|
||||
|
@ -24,6 +24,18 @@ public:
|
||||
// to 0.
|
||||
struct BoneIndices {
|
||||
uint32_t indices[4];
|
||||
|
||||
uint32_t& operator[] (int i) {
|
||||
SkASSERT(i >= 0);
|
||||
SkASSERT(i < 4);
|
||||
return indices[i];
|
||||
}
|
||||
|
||||
const uint32_t& operator[] (int i) const {
|
||||
SkASSERT(i >= 0);
|
||||
SkASSERT(i < 4);
|
||||
return indices[i];
|
||||
}
|
||||
};
|
||||
|
||||
// BoneWeights stores the interpolation weight for each of the (maximum of 4) bones a given
|
||||
@ -31,6 +43,55 @@ public:
|
||||
// slot should be 0.
|
||||
struct BoneWeights {
|
||||
float weights[4];
|
||||
|
||||
float& operator[] (int i) {
|
||||
SkASSERT(i >= 0);
|
||||
SkASSERT(i < 4);
|
||||
return weights[i];
|
||||
}
|
||||
|
||||
const float& operator[] (int i) const {
|
||||
SkASSERT(i >= 0);
|
||||
SkASSERT(i < 4);
|
||||
return weights[i];
|
||||
}
|
||||
};
|
||||
|
||||
// Bone stores a 3x2 transformation matrix in column major order:
|
||||
// | scaleX skewX transX |
|
||||
// | skewY scaleY transY |
|
||||
// SkRSXform is insufficient because bones can have non uniform scale.
|
||||
struct Bone {
|
||||
float values[6];
|
||||
|
||||
float& operator[] (int i) {
|
||||
SkASSERT(i >= 0);
|
||||
SkASSERT(i < 6);
|
||||
return values[i];
|
||||
}
|
||||
|
||||
const float& operator[] (int i) const {
|
||||
SkASSERT(i >= 0);
|
||||
SkASSERT(i < 6);
|
||||
return values[i];
|
||||
}
|
||||
|
||||
SkPoint mapPoint(const SkPoint& point) const {
|
||||
float x = values[0] * point.x() + values[2] * point.y() + values[4];
|
||||
float y = values[1] * point.x() + values[3] * point.y() + values[5];
|
||||
return SkPoint::Make(x, y);
|
||||
}
|
||||
|
||||
SkRect mapRect(const SkRect& rect) const {
|
||||
SkRect dst = SkRect::MakeEmpty();
|
||||
SkPoint quad[4];
|
||||
rect.toQuad(quad);
|
||||
for (int i = 0; i < 4; i ++) {
|
||||
quad[i] = mapPoint(quad[i]);
|
||||
}
|
||||
dst.setBoundsNoCheck(quad, 4);
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
enum VertexMode {
|
||||
@ -168,6 +229,8 @@ public:
|
||||
|
||||
bool isVolatile() const { return fIsVolatile; }
|
||||
|
||||
sk_sp<SkVertices> applyBones(const Bone bones[], int boneCount) const;
|
||||
|
||||
// returns approximate byte size of the vertices object
|
||||
size_t approximateSize() const;
|
||||
|
||||
|
@ -58,8 +58,8 @@ protected:
|
||||
const SkPaint*, SrcRectConstraint) override;
|
||||
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) override;
|
||||
|
||||
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
|
@ -71,8 +71,8 @@ protected:
|
||||
const SkPaint*) override;
|
||||
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone 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;
|
||||
|
@ -75,7 +75,7 @@ protected:
|
||||
const SkPaint*) override {}
|
||||
void onDrawBitmapLattice(const SkBitmap&, const Lattice&, const SkRect&,
|
||||
const SkPaint*) override {}
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix*, int, SkBlendMode,
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone[], int, SkBlendMode,
|
||||
const SkPaint&) override {}
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int, SkBlendMode, const SkRect*, const SkPaint*) override {}
|
||||
|
@ -88,8 +88,8 @@ protected:
|
||||
const SkPaint*) override;
|
||||
void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&,
|
||||
const SkPaint*) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) override;
|
||||
void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkBlendMode,
|
||||
const SkPaint& paint) override;
|
||||
|
@ -3808,11 +3808,11 @@ device bounds empty = true
|
||||
</tr>
|
||||
<tr style='background-color: #f0f0f0; '>
|
||||
<td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '></td>
|
||||
<td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a href='#SkCanvas_drawVertices_3'>drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount, SkBlendMode mode, const SkPaint& paint)</a></td>
|
||||
<td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a href='#SkCanvas_drawVertices_3'>drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[], int boneCount, SkBlendMode mode, const SkPaint& paint)</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '></td>
|
||||
<td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a href='#SkCanvas_drawVertices_4'>drawVertices(const sk sp<SkVertices>& vertices, const SkMatrix* bones, int boneCount, SkBlendMode mode, const SkPaint& paint)</a></td>
|
||||
<td style='text-align: left; border: 2px solid #dddddd; padding: 8px; '><a href='#SkCanvas_drawVertices_4'>drawVertices(const sk sp<SkVertices>& vertices, const SkVertices::Bone bones[], int boneCount, SkBlendMode mode, const SkPaint& paint)</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -6534,8 +6534,8 @@ contains <a href='undocumented#Shader'>Shader</a>, <a href='SkBlendMode_Referenc
|
||||
<a name='SkCanvas_drawVertices_3'></a>
|
||||
|
||||
<pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
|
||||
void <a href='#SkCanvas_drawVertices'>drawVertices</a>(const <a href='undocumented#SkVertices'>SkVertices</a>* vertices, const <a href='SkMatrix_Reference#SkMatrix'>SkMatrix</a>* bones, int boneCount, <a href='SkBlendMode_Reference#SkBlendMode'>SkBlendMode</a> mode,
|
||||
const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint)
|
||||
void <a href='#SkCanvas_drawVertices'>drawVertices</a>(const <a href='undocumented#SkVertices'>SkVertices</a>* vertices, const <a href='undocumented#SkVertices_Bone'>SkVertices::Bone</a> bones[], int boneCount,
|
||||
<a href='SkBlendMode_Reference#SkBlendMode'>SkBlendMode</a> mode, const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint)
|
||||
</pre>
|
||||
|
||||
Draws <a href='undocumented#Vertices'>Vertices</a> <a href='#SkCanvas_drawVertices_3_vertices'>vertices</a>, a triangle mesh, using <a href='#Clip'>Clip</a> and <a href='#Matrix'>Matrix</a>. Bone data is used to
|
||||
@ -6545,7 +6545,7 @@ contains <a href='undocumented#Shader'>Shader</a>, <a href='SkBlendMode_Referenc
|
||||
The first element of <a href='#SkCanvas_drawVertices_3_bones'>bones</a> should be an object to world space transformation matrix that
|
||||
will be applied before performing mesh deformations. If no such transformation is needed,
|
||||
it should be the identity matrix.
|
||||
<a href='#SkCanvas_drawVertices_3_boneCount'>boneCount</a> must be at most 100, and thus the size of <a href='#SkCanvas_drawVertices_3_bones'>bones</a> should be at most 100.
|
||||
<a href='#SkCanvas_drawVertices_3_boneCount'>boneCount</a> must be at most 80, and thus the size of <a href='#SkCanvas_drawVertices_3_bones'>bones</a> should be at most 80.
|
||||
|
||||
### Parameters
|
||||
|
||||
@ -6566,10 +6566,6 @@ it should be the identity matrix.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
<div><fiddle-embed name="7db6ad6b01931d713d7390736239001b"></fiddle-embed></div>
|
||||
|
||||
### See Also
|
||||
|
||||
<a href='#SkCanvas_drawPatch'>drawPatch</a><sup><a href='#SkCanvas_drawPatch_2'>[2]</a></sup> <a href='#SkCanvas_drawPicture'>drawPicture</a><sup><a href='#SkCanvas_drawPicture_2'>[2]</a></sup><sup><a href='#SkCanvas_drawPicture_3'>[3]</a></sup><sup><a href='#SkCanvas_drawPicture_4'>[4]</a></sup>
|
||||
@ -6579,7 +6575,7 @@ it should be the identity matrix.
|
||||
<a name='SkCanvas_drawVertices_4'></a>
|
||||
|
||||
<pre style="padding: 1em 1em 1em 1em; width: 62.5em;background-color: #f0f0f0">
|
||||
void <a href='#SkCanvas_drawVertices'>drawVertices</a>(const <a href='undocumented#sk_sp'>sk sp</a><<a href='undocumented#SkVertices'>SkVertices</a>>& vertices, const <a href='SkMatrix_Reference#SkMatrix'>SkMatrix</a>* bones, int boneCount,
|
||||
void <a href='#SkCanvas_drawVertices'>drawVertices</a>(const <a href='undocumented#sk_sp'>sk sp</a><<a href='undocumented#SkVertices'>SkVertices</a>>& vertices, const <a href='undocumented#SkVertices_Bone'>SkVertices::Bone</a> bones[], int boneCount,
|
||||
<a href='SkBlendMode_Reference#SkBlendMode'>SkBlendMode</a> mode, const <a href='SkPaint_Reference#SkPaint'>SkPaint</a>& paint)
|
||||
</pre>
|
||||
|
||||
@ -6590,7 +6586,7 @@ contains <a href='undocumented#Shader'>Shader</a>, <a href='SkBlendMode_Referenc
|
||||
The first element of <a href='#SkCanvas_drawVertices_4_bones'>bones</a> should be an object to world space transformation matrix that
|
||||
will be applied before performing mesh deformations. If no such transformation is needed,
|
||||
it should be the identity matrix.
|
||||
<a href='#SkCanvas_drawVertices_4_boneCount'>boneCount</a> must be at most 100, and thus the size of <a href='#SkCanvas_drawVertices_4_bones'>bones</a> should be at most 100.
|
||||
<a href='#SkCanvas_drawVertices_4_boneCount'>boneCount</a> must be at most 80, and thus the size of <a href='#SkCanvas_drawVertices_4_bones'>bones</a> should be at most 80.
|
||||
|
||||
### Parameters
|
||||
|
||||
@ -6611,10 +6607,6 @@ it should be the identity matrix.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
<div><fiddle-embed name="cc1fc7f3462abc79ec6dec3405e2812d"></fiddle-embed></div>
|
||||
|
||||
### See Also
|
||||
|
||||
<a href='#SkCanvas_drawPatch'>drawPatch</a><sup><a href='#SkCanvas_drawPatch_2'>[2]</a></sup> <a href='#SkCanvas_drawPicture'>drawPicture</a><sup><a href='#SkCanvas_drawPicture_2'>[2]</a></sup><sup><a href='#SkCanvas_drawPicture_3'>[3]</a></sup><sup><a href='#SkCanvas_drawPicture_4'>[4]</a></sup>
|
||||
|
@ -5353,22 +5353,6 @@
|
||||
"hash": "e8bdae9bea3227758989028424fcac3d",
|
||||
"file": "SkCanvas_Reference",
|
||||
"name": "SkCanvas::drawVertices_2"
|
||||
},
|
||||
"SkCanvas_drawVertices_3": {
|
||||
"code": "void draw(SkCanvas* canvas) {\n SkPaint paint;\n SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };\n SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };\n SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };\n SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },\n { 1, 0, 0, 0 },\n { 2, 0, 0, 0 },\n { 3, 0, 0, 0 } };\n SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },\n { 1.0f, 0.0f, 0.0f, 0.0f },\n { 1.0f, 0.0f, 0.0f, 0.0f },\n { 1.0f, 0.0f, 0.0f, 0.0f } };\n SkMatrix bones[] = { SkMatrix::I(),\n SkMatrix::MakeTrans(0, 20),\n SkMatrix::MakeTrans(50, 50),\n SkMatrix::MakeTrans(20, 0) };\n paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,\n SkShader::kClamp_TileMode));\n auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,\n SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);\n canvas->drawVertices(vertices.get(), bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);\n}\n",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"hash": "7db6ad6b01931d713d7390736239001b",
|
||||
"file": "SkCanvas_Reference",
|
||||
"name": "SkCanvas::drawVertices_3"
|
||||
},
|
||||
"SkCanvas_drawVertices_4": {
|
||||
"code": "void draw(SkCanvas* canvas) {\n SkPaint paint;\n SkPoint points[] = { { 0, 0 }, { 250, 0 }, { 100, 100 }, { 0, 250 } };\n SkPoint texs[] = { { 0, 0 }, { 0, 250 }, { 250, 250 }, { 250, 0 } };\n SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN };\n SkVertices::BoneIndices boneIndices[] = { { 0, 0, 0, 0 },\n { 1, 0, 0, 0 },\n { 2, 0, 0, 0 },\n { 3, 0, 0, 0 } };\n SkVertices::BoneWeights boneWeights[] = { { 0.0f, 0.0f, 0.0f, 0.0f },\n { 1.0f, 0.0f, 0.0f, 0.0f },\n { 1.0f, 0.0f, 0.0f, 0.0f },\n { 1.0f, 0.0f, 0.0f, 0.0f } };\n SkMatrix bones[] = { SkMatrix::I(),\n SkMatrix::MakeTrans(0, 20),\n SkMatrix::MakeTrans(50, 50),\n SkMatrix::MakeTrans(20, 0) };\n paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 4,\n SkShader::kClamp_TileMode));\n auto vertices = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode,\n SK_ARRAY_COUNT(points), points, texs, colors, boneIndices, boneWeights);\n canvas->drawVertices(vertices, bones, SK_ARRAY_COUNT(bones), SkBlendMode::kDarken, paint);\n}\n",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"hash": "cc1fc7f3462abc79ec6dec3405e2812d",
|
||||
"file": "SkCanvas_Reference",
|
||||
"name": "SkCanvas::drawVertices_4"
|
||||
},
|
||||
"SkCanvas_getGrContext": {
|
||||
"code": "void draw(SkCanvas* canvas) {\n if (canvas->getGrContext()) {\n canvas->clear(SK_ColorRED);\n } else {\n canvas->clear(SK_ColorBLUE);\n }\n}\n",
|
||||
|
@ -645,6 +645,8 @@ bool <a href='#GrBackendTexture_isValid'>isValid</a>() const
|
||||
|
||||
# <a name='SkVertices'>Class SkVertices</a>
|
||||
|
||||
# <a name='SkVertices_Bone'>Class SkVertices::Bone</a>
|
||||
|
||||
## <a name='Colors'>Colors</a>
|
||||
|
||||
## <a name='Texs'>Texs</a>
|
||||
|
@ -127,6 +127,7 @@ Complete rebuilding of all bookmaker output looks like:
|
||||
$ ./out/skia/bookmaker -a docs/status.json -e fiddle.json
|
||||
$ ~/go/bin/fiddlecli --input fiddle.json --output fiddleout.json
|
||||
$ ./out/skia/bookmaker -a docs/status.json -f fiddleout.json -r site/user/api -c
|
||||
$ ./out/skia/bookmaker -a docs/status.json -f fiddleout.json -r site/user/api
|
||||
$ ./out/skia/bookmaker -a docs/status.json -x
|
||||
$ ./out/skia/bookmaker -a docs/status.json -p
|
||||
</pre>
|
||||
|
@ -593,8 +593,8 @@ void SkBitmapDevice::drawGlyphRunList(const SkGlyphRunList& glyphRunList) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
|
||||
SkBlendMode bmode, const SkPaint& paint) {
|
||||
void SkBitmapDevice::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
|
||||
BDDraw(this).drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
|
||||
vertices->texCoords(), vertices->colors(), vertices->boneIndices(),
|
||||
vertices->boneWeights(), bmode, vertices->indices(),
|
||||
|
@ -102,7 +102,7 @@ protected:
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
|
||||
void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const SkPaint& paint) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
|
@ -1678,16 +1678,16 @@ void SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const
|
||||
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) {
|
||||
void SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint) {
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
RETURN_ON_NULL(vertices);
|
||||
SkASSERT(boneCount <= 80);
|
||||
this->onDrawVerticesObject(vertices.get(), bones, boneCount, mode, paint);
|
||||
}
|
||||
|
||||
void SkCanvas::drawVertices(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
void SkCanvas::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint) {
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
RETURN_ON_NULL(vertices);
|
||||
SkASSERT(boneCount <= 80);
|
||||
@ -2576,7 +2576,7 @@ void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
this->onDrawTextBlob(blob, x, y, paint);
|
||||
}
|
||||
|
||||
void SkCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
void SkCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, nullptr)
|
||||
|
||||
|
@ -90,7 +90,8 @@ public:
|
||||
const SkPaint& paint) override {
|
||||
fTarget->drawPoints(mode, count, pts, fXformer->apply(paint));
|
||||
}
|
||||
void onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones, int boneCount,
|
||||
|
||||
void onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint) override {
|
||||
sk_sp<SkVertices> copy;
|
||||
if (vertices->hasColors()) {
|
||||
|
@ -213,8 +213,8 @@ protected:
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
|
||||
virtual void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) = 0;
|
||||
virtual void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) = 0;
|
||||
virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
|
||||
|
||||
virtual void drawGlyphRunList(const SkGlyphRunList& glyphRunList);
|
||||
@ -420,7 +420,7 @@ 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*, const SkMatrix*, int, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone[], int, SkBlendMode,
|
||||
const SkPaint&) override {}
|
||||
|
||||
private:
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
const SkColor colors[], const SkVertices::BoneIndices boneIndices[],
|
||||
const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
|
||||
const uint16_t indices[], int ptCount,
|
||||
const SkPaint& paint, const SkMatrix* bones, int boneCount) const;
|
||||
const SkPaint& paint, const SkVertices::Bone bones[], int boneCount) const;
|
||||
|
||||
/**
|
||||
* Overwrite the target with the path's coverage (i.e. its mask).
|
||||
|
@ -167,7 +167,8 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int vertexCount,
|
||||
const SkColor colors[], const SkVertices::BoneIndices boneIndices[],
|
||||
const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint, const SkMatrix* bones, int boneCount) const {
|
||||
const SkPaint& paint, const SkVertices::Bone bones[],
|
||||
int boneCount) const {
|
||||
SkASSERT(0 == vertexCount || vertices);
|
||||
|
||||
// abort early if there is nothing to draw
|
||||
@ -207,11 +208,9 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int vertexCount,
|
||||
}
|
||||
|
||||
constexpr size_t kDefVertexCount = 16;
|
||||
constexpr size_t kDefBoneCount = 8;
|
||||
constexpr size_t kOuterSize = sizeof(SkTriColorShader) +
|
||||
sizeof(SkComposeShader) +
|
||||
(2 * sizeof(SkPoint) + sizeof(SkPM4f)) * kDefVertexCount +
|
||||
sizeof(SkMatrix) * kDefBoneCount;
|
||||
(2 * sizeof(SkPoint) + sizeof(SkPM4f)) * kDefVertexCount;
|
||||
SkSTArenaAlloc<kOuterSize> outerAlloc;
|
||||
|
||||
// deform vertices using the skeleton if it is passed in
|
||||
@ -219,28 +218,21 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int vertexCount,
|
||||
// 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 the world transform
|
||||
SkPoint worldPoint = bones[0].mapPoint(vertices[i]);
|
||||
|
||||
// apply bone deformations
|
||||
SkPoint result = SkPoint::Make(0.0f, 0.0f);
|
||||
SkPoint transformed;
|
||||
deformed[i] = SkPoint::Make(0.0f, 0.0f);
|
||||
for (uint32_t j = 0; j < 4; j ++) {
|
||||
// get the attachment data
|
||||
uint32_t index = indices.indices[j];
|
||||
float weight = weights.weights[j];
|
||||
uint32_t index = indices[j];
|
||||
float weight = weights[j];
|
||||
|
||||
// skip the bone if there is no weight
|
||||
if (weight == 0.0f) {
|
||||
@ -248,19 +240,14 @@ void SkDraw::drawVertices(SkVertices::VertexMode vmode, int vertexCount,
|
||||
}
|
||||
SkASSERT(index != 0);
|
||||
|
||||
// transformed = M * v
|
||||
transformedBones[index].mapPoints(&transformed, &vertices[i], 1);
|
||||
|
||||
// result += transformed * w
|
||||
result += transformed * weight;
|
||||
// deformed += M * v * w
|
||||
deformed[i] += bones[index].mapPoint(worldPoint) * weight;
|
||||
}
|
||||
|
||||
// set the deformed point
|
||||
deformed[i] = result;
|
||||
}
|
||||
} else {
|
||||
// no bones, so only apply world transform
|
||||
const SkMatrix& worldTransform = bones[0];
|
||||
SkMatrix worldTransform = SkMatrix::I();
|
||||
worldTransform.setAffine(bones[0].values);
|
||||
worldTransform.mapPoints(deformed, vertices, vertexCount);
|
||||
}
|
||||
|
||||
|
@ -455,7 +455,7 @@ namespace {
|
||||
SkBlendMode mode;
|
||||
SkPaint paint;
|
||||
void draw(SkCanvas* c, const SkMatrix&) const {
|
||||
c->drawVertices(vertices, pod<SkMatrix>(this), boneCount, mode, paint);
|
||||
c->drawVertices(vertices, pod<SkVertices::Bone>(this), boneCount, mode, paint);
|
||||
}
|
||||
};
|
||||
struct DrawAtlas final : Op {
|
||||
@ -660,9 +660,9 @@ 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, const SkMatrix* bones, int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
void* pod = this->push<DrawVertices>(boneCount * sizeof(SkMatrix),
|
||||
void SkLiteDL::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint) {
|
||||
void* pod = this->push<DrawVertices>(boneCount * sizeof(SkVertices::Bone),
|
||||
vertices,
|
||||
boneCount,
|
||||
mode,
|
||||
|
@ -72,7 +72,7 @@ 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*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const SkPaint&);
|
||||
void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
|
||||
SkBlendMode, const SkRect*, const SkPaint*);
|
||||
|
@ -175,8 +175,9 @@ void SkLiteRecorder::onDrawPoints(SkCanvas::PointMode mode,
|
||||
const SkPaint& paint) {
|
||||
fDL->drawPoints(mode, count, pts, paint);
|
||||
}
|
||||
void SkLiteRecorder::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint) {
|
||||
void SkLiteRecorder::onDrawVerticesObject(const SkVertices* vertices,
|
||||
const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
fDL->drawVertices(vertices, bones, boneCount, mode, paint);
|
||||
}
|
||||
void SkLiteRecorder::onDrawAtlas(const SkImage* atlas,
|
||||
|
@ -73,8 +73,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*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone 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;
|
||||
|
@ -216,9 +216,9 @@ 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, const SkMatrix* bones,
|
||||
int boneCount, SkBlendMode blendMode,
|
||||
const SkPaint& paint) {
|
||||
void SkOverdrawCanvas::onDrawVerticesObject(const SkVertices* vertices,
|
||||
const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode blendMode, const SkPaint& paint) {
|
||||
fList[0]->onDrawVerticesObject(vertices,
|
||||
bones,
|
||||
boneCount,
|
||||
|
@ -616,9 +616,9 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
||||
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;
|
||||
const SkVertices::Bone* bones = boneCount ?
|
||||
(const SkVertices::Bone*) reader->skip(boneCount, sizeof(SkVertices::Bone)) :
|
||||
nullptr;
|
||||
SkBlendMode bmode = reader->read32LE(SkBlendMode::kLastMode);
|
||||
BREAK_ON_READ_ERROR(reader);
|
||||
|
||||
|
@ -682,16 +682,17 @@ void SkPictureRecord::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matri
|
||||
this->validate(initialOffset, size);
|
||||
}
|
||||
|
||||
void SkPictureRecord::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint) {
|
||||
void SkPictureRecord::onDrawVerticesObject(const SkVertices* vertices,
|
||||
const SkVertices::Bone 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 size = 5 * kUInt32Size + boneCount * sizeof(SkVertices::Bone);
|
||||
size_t initialOffset = this->addDraw(DRAW_VERTICES_OBJECT, &size);
|
||||
|
||||
this->addPaint(paint);
|
||||
this->addVertices(vertices);
|
||||
this->addInt(boneCount);
|
||||
fWriter.write(bones, boneCount * sizeof(SkMatrix));
|
||||
fWriter.write(bones, boneCount * sizeof(SkVertices::Bone));
|
||||
this->addInt(static_cast<uint32_t>(mode));
|
||||
|
||||
this->validate(initialOffset, size);
|
||||
|
@ -196,8 +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*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) override;
|
||||
|
||||
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
|
@ -317,7 +317,7 @@ void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con
|
||||
}
|
||||
}
|
||||
|
||||
void SkRecorder::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
void SkRecorder::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
|
||||
this->append<SkRecords::DrawVertices>(paint,
|
||||
sk_ref_sp(const_cast<SkVertices*>(vertices)),
|
||||
|
@ -121,8 +121,8 @@ public:
|
||||
const SkPaint*) override;
|
||||
void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint*) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone 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;
|
||||
|
@ -344,7 +344,7 @@ RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
||||
RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
|
||||
SkPaint paint;
|
||||
sk_sp<SkVertices> vertices;
|
||||
PODArray<SkMatrix> bones;
|
||||
PODArray<SkVertices::Bone> bones;
|
||||
int boneCount;
|
||||
SkBlendMode bmode);
|
||||
RECORD(DrawShadowRec, kDraw_Tag,
|
||||
|
@ -207,6 +207,69 @@ uint16_t* SkVertices::Builder::indices() {
|
||||
return const_cast<uint16_t*>(fVertices->indices());
|
||||
}
|
||||
|
||||
/** Makes a copy of the SkVertices and applies a set of bones, then returns the deformed
|
||||
vertices.
|
||||
|
||||
@param bones The bones to apply.
|
||||
@param boneCount The number of bones.
|
||||
@return The transformed SkVertices.
|
||||
*/
|
||||
sk_sp<SkVertices> SkVertices::applyBones(const SkVertices::Bone bones[], int boneCount) const {
|
||||
// If there aren't any bones, then nothing changes.
|
||||
// We don't check if the SkVertices object has bone indices/weights because there is the case
|
||||
// where the object can have no indices/weights but still have a world transform applied.
|
||||
if (!bones || !boneCount) {
|
||||
return sk_ref_sp(this);
|
||||
}
|
||||
SkASSERT(boneCount >= 1);
|
||||
|
||||
// Copy the SkVertices.
|
||||
sk_sp<SkVertices> copy = SkVertices::MakeCopy(this->mode(),
|
||||
this->vertexCount(),
|
||||
this->positions(),
|
||||
this->texCoords(),
|
||||
this->colors(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
this->indexCount(),
|
||||
this->indices());
|
||||
|
||||
// Transform the positions.
|
||||
for (int i = 0; i < this->vertexCount(); i++) {
|
||||
SkPoint& position = copy->fPositions[i];
|
||||
|
||||
// Apply the world transform.
|
||||
position = bones[0].mapPoint(position);
|
||||
|
||||
// Apply the bone deformations.
|
||||
if (boneCount > 1) {
|
||||
SkASSERT(this->boneIndices());
|
||||
SkASSERT(this->boneWeights());
|
||||
|
||||
SkPoint result = SkPoint::Make(0.0f, 0.0f);
|
||||
const SkVertices::BoneIndices& indices = this->boneIndices()[i];
|
||||
const SkVertices::BoneWeights& weights = this->boneWeights()[i];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
int index = indices[j];
|
||||
float weight = weights[j];
|
||||
if (index == 0 || weight == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
SkASSERT(index < boneCount);
|
||||
|
||||
// result += M * v * w.
|
||||
result += bones[index].mapPoint(position) * weight;
|
||||
}
|
||||
position = result;
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate the bounds.
|
||||
copy->fBounds.set(copy->fPositions, copy->fVertexCnt);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount,
|
||||
|
@ -31,8 +31,9 @@ enum GPFlag {
|
||||
kBonesAttribute_GPFlag = 0x10,
|
||||
};
|
||||
|
||||
static constexpr int kMaxBones = 80; // Due to GPU memory limitations, only up to 80 bone
|
||||
// matrices are accepted.
|
||||
static constexpr int kNumVec2sPerBone = 3; // Our bone matrices are 3x2 matrices passed in as
|
||||
// vec2s in column major order, and thus there are 3
|
||||
// vec2s per bone.
|
||||
|
||||
class DefaultGeoProc : public GrGeometryProcessor {
|
||||
public:
|
||||
@ -111,21 +112,36 @@ public:
|
||||
}
|
||||
|
||||
// Setup bone transforms
|
||||
// NOTE: This code path is currently unused. Benchmarks have found that for all
|
||||
// reasonable cases of skinned vertices, the overhead involved in copying and uploading
|
||||
// bone data makes performing the transformations on the CPU faster than doing so on
|
||||
// the GPU. This is being kept here in case that changes.
|
||||
const char* transformedPositionName = gp.fInPosition.name();
|
||||
if (gp.hasBones()) {
|
||||
// Set up the uniform for the bones.
|
||||
const char* vertBonesUniformName;
|
||||
fBonesUniform = uniformHandler->addUniformArray(kVertex_GrShaderFlag,
|
||||
kFloat3x3_GrSLType,
|
||||
kFloat2_GrSLType,
|
||||
"Bones",
|
||||
kMaxBones,
|
||||
kMaxBones * kNumVec2sPerBone,
|
||||
&vertBonesUniformName);
|
||||
|
||||
// Set up the bone application function.
|
||||
SkString applyBoneFunctionName;
|
||||
this->emitApplyBoneFunction(vertBuilder,
|
||||
vertBonesUniformName,
|
||||
&applyBoneFunctionName);
|
||||
|
||||
// Apply the world transform to the position first.
|
||||
vertBuilder->codeAppendf(
|
||||
"float3 originalPosition = %s[0] * float3(%s, 1);"
|
||||
"float2 transformedPosition = float2(0);"
|
||||
"float2 worldPosition = %s(0, %s);"
|
||||
"float2 transformedPosition = float2(0, 0);"
|
||||
"for (int i = 0; i < 4; i++) {",
|
||||
vertBonesUniformName,
|
||||
applyBoneFunctionName.c_str(),
|
||||
gp.fInPosition.name());
|
||||
|
||||
// If the GPU supports unsigned integers, then we can read the index. Otherwise,
|
||||
// we have to estimate it given the float representation.
|
||||
if (args.fShaderCaps->unsignedSupport()) {
|
||||
vertBuilder->codeAppendf(
|
||||
" byte index = %s[i];",
|
||||
@ -136,12 +152,13 @@ public:
|
||||
gp.fInBoneIndices.name());
|
||||
}
|
||||
|
||||
// Get the weight and apply the transformation.
|
||||
vertBuilder->codeAppendf(
|
||||
" float weight = %s[i];"
|
||||
" transformedPosition += (%s[index] * originalPosition * weight).xy;"
|
||||
" transformedPosition += %s(index, worldPosition) * weight;"
|
||||
"}",
|
||||
gp.fInBoneWeights.name(),
|
||||
vertBonesUniformName);
|
||||
applyBoneFunctionName.c_str());
|
||||
transformedPositionName = "transformedPosition";
|
||||
}
|
||||
|
||||
@ -228,10 +245,40 @@ public:
|
||||
fColorSpaceHelper.setData(pdman, dgp.fColorSpaceXform.get());
|
||||
|
||||
if (dgp.hasBones()) {
|
||||
pdman.setMatrix3fv(fBonesUniform, dgp.boneCount(), dgp.bones());
|
||||
pdman.set2fv(fBonesUniform, dgp.boneCount() * kNumVec2sPerBone, dgp.bones());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void emitApplyBoneFunction(GrGLSLVertexBuilder* vertBuilder,
|
||||
const char* vertBonesUniformName,
|
||||
SkString* funcName) {
|
||||
// The bone matrices are passed in as 3x2 matrices in column-major order as groups
|
||||
// of 3 float2s. This code takes those float2s and performs the matrix operation on
|
||||
// a given matrix and float2.
|
||||
static const GrShaderVar gApplyBoneArgs[] = {
|
||||
GrShaderVar("index", kByte_GrSLType),
|
||||
GrShaderVar("vec", kFloat2_GrSLType),
|
||||
};
|
||||
SkString body;
|
||||
body.appendf(
|
||||
" float2 c0 = %s[index * 3];"
|
||||
" float2 c1 = %s[index * 3 + 1];"
|
||||
" float2 c2 = %s[index * 3 + 2];"
|
||||
" float x = c0.x * vec.x + c1.x * vec.y + c2.x;"
|
||||
" float y = c0.y * vec.x + c1.y * vec.y + c2.y;"
|
||||
" return float2(x, y);",
|
||||
vertBonesUniformName,
|
||||
vertBonesUniformName,
|
||||
vertBonesUniformName);
|
||||
vertBuilder->emitFunction(kFloat2_GrSLType,
|
||||
"applyBone",
|
||||
SK_ARRAY_COUNT(gApplyBoneArgs),
|
||||
gApplyBoneArgs,
|
||||
body.c_str(),
|
||||
funcName);
|
||||
}
|
||||
|
||||
private:
|
||||
SkMatrix fViewMatrix;
|
||||
GrColor fColor;
|
||||
@ -336,13 +383,13 @@ private:
|
||||
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
static constexpr int kNumFloatsPerSkMatrix = 9;
|
||||
static constexpr int kNumFloatsPerBone = 6;
|
||||
static constexpr int kTestBoneCount = 4;
|
||||
static constexpr float kTestBones[kTestBoneCount * kNumFloatsPerSkMatrix] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
static constexpr float kTestBones[kTestBoneCount * kNumFloatsPerBone] = {
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
};
|
||||
|
||||
sk_sp<GrGeometryProcessor> DefaultGeoProc::TestCreate(GrProcessorTestData* d) {
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "GrGeometryProcessor.h"
|
||||
#include "GrShaderCaps.h"
|
||||
|
||||
constexpr int kMaxBones = 80; // Supports up to 80 bones per mesh.
|
||||
|
||||
/*
|
||||
* A factory for creating default Geometry Processors which simply multiply position by the uniform
|
||||
* view matrix and wire through color, coverage, UV coords if requested.
|
||||
|
@ -839,7 +839,7 @@ void GrRenderTargetContext::drawVertices(const GrClip& clip,
|
||||
GrPaint&& paint,
|
||||
const SkMatrix& viewMatrix,
|
||||
sk_sp<SkVertices> vertices,
|
||||
const SkMatrix bones[],
|
||||
const SkVertices::Bone bones[],
|
||||
int boneCount,
|
||||
GrPrimitiveType* overridePrimType) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
|
@ -215,7 +215,7 @@ public:
|
||||
GrPaint&& paint,
|
||||
const SkMatrix& viewMatrix,
|
||||
sk_sp<SkVertices> vertices,
|
||||
const SkMatrix bones[],
|
||||
const SkVertices::Bone bones[],
|
||||
int boneCount,
|
||||
GrPrimitiveType* overridePrimType = nullptr);
|
||||
|
||||
|
@ -1484,7 +1484,7 @@ static bool init_vertices_paint(GrContext* context, const GrColorSpaceInfo& colo
|
||||
|
||||
void SkGpuDevice::wireframeVertices(SkVertices::VertexMode vmode, int vertexCount,
|
||||
const SkPoint vertices[],
|
||||
const SkMatrix bones[], int boneCount,
|
||||
const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode bmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) {
|
||||
@ -1548,8 +1548,8 @@ void SkGpuDevice::wireframeVertices(SkVertices::VertexMode vmode, int vertexCoun
|
||||
&primitiveType);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawVertices(const SkVertices* vertices, const SkMatrix bones[], int boneCount,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode mode, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVertices", fContext.get());
|
||||
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
void drawPosText(const void* text, size_t len, const SkScalar pos[],
|
||||
int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
|
||||
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
|
||||
void drawVertices(const SkVertices*, const SkMatrix bones[], int boneCount, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
@ -244,7 +244,7 @@ private:
|
||||
void drawStrokedLine(const SkPoint pts[2], const SkPaint&);
|
||||
|
||||
void wireframeVertices(SkVertices::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
const SkMatrix bones[], int boneCount, SkBlendMode,
|
||||
const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const uint16_t indices[], int indexCount, const SkPaint&);
|
||||
|
||||
static sk_sp<GrRenderTargetContext> MakeRenderTargetContext(GrContext*,
|
||||
|
@ -12,12 +12,10 @@
|
||||
#include "SkGr.h"
|
||||
#include "SkRectPriv.h"
|
||||
|
||||
static constexpr int kNumFloatsPerSkMatrix = 9;
|
||||
|
||||
std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrContext* context,
|
||||
GrPaint&& paint,
|
||||
sk_sp<SkVertices> vertices,
|
||||
const SkMatrix bones[],
|
||||
const SkVertices::Bone bones[],
|
||||
int boneCount,
|
||||
const SkMatrix& viewMatrix,
|
||||
GrAAType aaType,
|
||||
@ -32,7 +30,7 @@ std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrContext* context,
|
||||
}
|
||||
|
||||
GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor color,
|
||||
sk_sp<SkVertices> vertices, const SkMatrix bones[],
|
||||
sk_sp<SkVertices> vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, GrPrimitiveType primitiveType, GrAAType aaType,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& viewMatrix)
|
||||
@ -51,26 +49,23 @@ GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor c
|
||||
mesh.fColor = color;
|
||||
mesh.fViewMatrix = viewMatrix;
|
||||
mesh.fVertices = std::move(vertices);
|
||||
if (bones) {
|
||||
// Copy the bone data over in the format that the GPU would upload.
|
||||
mesh.fBones.reserve(boneCount * kNumFloatsPerSkMatrix);
|
||||
for (int i = 0; i < boneCount; i ++) {
|
||||
const SkMatrix& matrix = bones[i];
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMScaleX));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMSkewY));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMPersp0));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMSkewX));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMScaleY));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMPersp1));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMTransX));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMTransY));
|
||||
mesh.fBones.push_back(matrix.get(SkMatrix::kMPersp2));
|
||||
}
|
||||
}
|
||||
mesh.fIgnoreTexCoords = false;
|
||||
mesh.fIgnoreColors = false;
|
||||
mesh.fIgnoreBones = false;
|
||||
|
||||
if (mesh.fVertices->hasBones() && bones) {
|
||||
// Perform the transformations on the CPU instead of the GPU.
|
||||
mesh.fVertices = mesh.fVertices->applyBones(bones, boneCount);
|
||||
} else {
|
||||
if (bones && boneCount > 1) {
|
||||
// NOTE: This should never be used. All bone transforms are being done on the CPU
|
||||
// instead of the GPU.
|
||||
|
||||
// Copy the bone data.
|
||||
fBones.assign(bones, bones + boneCount);
|
||||
}
|
||||
}
|
||||
|
||||
fFlags = 0;
|
||||
if (mesh.hasPerVertexColors()) {
|
||||
fFlags |= kRequiresPerVertexColors_Flag;
|
||||
@ -85,7 +80,9 @@ GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor c
|
||||
// Special case for meshes with a world transform but no bone weights.
|
||||
// These will be considered normal vertices draws without bones.
|
||||
if (!mesh.fVertices->hasBones() && boneCount == 1) {
|
||||
mesh.fViewMatrix.preConcat(bones[0]);
|
||||
SkMatrix worldTransform;
|
||||
worldTransform.setAffine(bones[0].values);
|
||||
mesh.fViewMatrix.preConcat(worldTransform);
|
||||
}
|
||||
|
||||
IsZeroArea zeroArea;
|
||||
@ -101,7 +98,7 @@ GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor c
|
||||
SkRect bounds = SkRect::MakeEmpty();
|
||||
const SkRect originalBounds = bones[0].mapRect(mesh.fVertices->bounds());
|
||||
for (int i = 1; i < boneCount; i++) {
|
||||
const SkMatrix& matrix = bones[i];
|
||||
const SkVertices::Bone& matrix = bones[i];
|
||||
bounds.join(matrix.mapRect(originalBounds));
|
||||
}
|
||||
|
||||
@ -188,7 +185,9 @@ sk_sp<GrGeometryProcessor> GrDrawVerticesOp::makeGP(const GrShaderCaps* shaderCa
|
||||
|
||||
const SkMatrix& vm = this->hasMultipleViewMatrices() ? SkMatrix::I() : fMeshes[0].fViewMatrix;
|
||||
|
||||
Bones bones(fMeshes[0].fBones.data(), fMeshes[0].fBones.size() / kNumFloatsPerSkMatrix);
|
||||
// The bones are packed as 6 floats in column major order, so we can directly upload them to
|
||||
// the GPU as groups of 3 vec2s.
|
||||
Bones bones(reinterpret_cast<const float*>(fBones.data()), fBones.size());
|
||||
*hasBoneAttribute = this->hasBones();
|
||||
|
||||
if (this->hasBones()) {
|
||||
|
@ -38,16 +38,16 @@ public:
|
||||
static std::unique_ptr<GrDrawOp> Make(GrContext* context,
|
||||
GrPaint&&,
|
||||
sk_sp<SkVertices>,
|
||||
const SkMatrix bones[],
|
||||
const SkVertices::Bone bones[],
|
||||
int boneCount,
|
||||
const SkMatrix& viewMatrix,
|
||||
GrAAType,
|
||||
sk_sp<GrColorSpaceXform>,
|
||||
GrPrimitiveType* overridePrimType = nullptr);
|
||||
|
||||
GrDrawVerticesOp(const Helper::MakeArgs&, GrColor, sk_sp<SkVertices>, const SkMatrix bones[],
|
||||
int boneCount, GrPrimitiveType, GrAAType, sk_sp<GrColorSpaceXform>,
|
||||
const SkMatrix& viewMatrix);
|
||||
GrDrawVerticesOp(const Helper::MakeArgs&, GrColor, sk_sp<SkVertices>,
|
||||
const SkVertices::Bone bones[], int boneCount, GrPrimitiveType, GrAAType,
|
||||
sk_sp<GrColorSpaceXform>, const SkMatrix& viewMatrix);
|
||||
|
||||
const char* name() const override { return "DrawVerticesOp"; }
|
||||
|
||||
@ -103,7 +103,6 @@ private:
|
||||
struct Mesh {
|
||||
GrColor fColor; // Used if this->hasPerVertexColors() is false.
|
||||
sk_sp<SkVertices> fVertices;
|
||||
std::vector<float> fBones; // Transformation matrices stored in GPU format.
|
||||
SkMatrix fViewMatrix;
|
||||
bool fIgnoreTexCoords;
|
||||
bool fIgnoreColors;
|
||||
@ -118,7 +117,7 @@ private:
|
||||
}
|
||||
|
||||
bool hasBones() const {
|
||||
return fVertices->hasBones() && fBones.size() && !fIgnoreBones;
|
||||
return fVertices->hasBones() && !fIgnoreBones;
|
||||
}
|
||||
};
|
||||
|
||||
@ -152,6 +151,7 @@ private:
|
||||
|
||||
Helper fHelper;
|
||||
SkSTArray<1, Mesh, true> fMeshes;
|
||||
std::vector<SkVertices::Bone> fBones; // Bone transformation matrices.
|
||||
// GrPrimitiveType is more expressive than fVertices.mode() so it is used instead and we ignore
|
||||
// the SkVertices mode (though fPrimitiveType may have been inferred from it).
|
||||
GrPrimitiveType fPrimitiveType;
|
||||
|
@ -1375,7 +1375,7 @@ void SkPDFDevice::drawGlyphRunList(const SkGlyphRunList& glyphRunList) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawVertices(const SkVertices*, const SkMatrix*, int, SkBlendMode,
|
||||
void SkPDFDevice::drawVertices(const SkVertices*, const SkVertices::Bone[], int, SkBlendMode,
|
||||
const SkPaint&) {
|
||||
if (this->hasEmptyClip()) {
|
||||
return;
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint&) override { SkASSERT(false); }
|
||||
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
|
||||
void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
@ -728,7 +728,7 @@ void SkPipeCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
write_paint(writer, paint, kGeometry_PaintUsage);
|
||||
}
|
||||
|
||||
void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
|
||||
unsigned extra = static_cast<unsigned>(bmode);
|
||||
|
||||
@ -737,7 +737,7 @@ void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatr
|
||||
// TODO: dedup vertices?
|
||||
writer.writeDataAsByteArray(vertices->encode().get());
|
||||
writer.write32(boneCount);
|
||||
writer.write(bones, sizeof(SkMatrix) * boneCount);
|
||||
writer.write(bones, sizeof(SkVertices::Bone) * boneCount);
|
||||
write_paint(writer, paint, kVertices_PaintUsage);
|
||||
}
|
||||
|
||||
|
@ -135,8 +135,8 @@ protected:
|
||||
const SkPaint*) override;
|
||||
void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint*) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) override;
|
||||
|
||||
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
|
||||
|
@ -567,7 +567,7 @@ static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa
|
||||
vertices = SkVertices::Decode(data->data(), data->size());
|
||||
}
|
||||
int boneCount = reader.read32();
|
||||
const SkMatrix* bones = boneCount ? reader.skipT<SkMatrix>(boneCount) : nullptr;
|
||||
const SkVertices::Bone* bones = boneCount ? reader.skipT<SkVertices::Bone>(boneCount) : nullptr;
|
||||
if (vertices) {
|
||||
canvas->drawVertices(vertices, bones, boneCount, bmode, read_paint(reader));
|
||||
}
|
||||
|
@ -1040,7 +1040,7 @@ void SkSVGDevice::drawTextOnPath(const void* text, size_t len, const SkPath& pat
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawVertices(const SkVertices*, const SkMatrix*, int, SkBlendMode,
|
||||
void SkSVGDevice::drawVertices(const SkVertices*, const SkVertices::Bone[], int, SkBlendMode,
|
||||
const SkPaint&) {
|
||||
// todo
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ protected:
|
||||
void drawTextOnPath(const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) override;
|
||||
void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawDevice(SkBaseDevice*, int x, int y,
|
||||
|
@ -314,8 +314,8 @@ void SkLuaCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
|
||||
this->INHERITED::onDrawDrawable(drawable, matrix);
|
||||
}
|
||||
|
||||
void SkLuaCanvas::onDrawVerticesObject(const SkVertices*, const SkMatrix*, int, SkBlendMode,
|
||||
const SkPaint& paint) {
|
||||
void SkLuaCanvas::onDrawVerticesObject(const SkVertices*, const SkVertices::Bone[], int,
|
||||
SkBlendMode, const SkPaint& paint) {
|
||||
AUTO_LUA("drawVertices");
|
||||
lua.pushPaint(paint, "paint");
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ void SkNWayCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix)
|
||||
}
|
||||
}
|
||||
|
||||
void SkNWayCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
void SkNWayCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
|
||||
Iter iter(fList);
|
||||
while (iter.next()) {
|
||||
|
@ -173,9 +173,9 @@ void SkPaintFilterCanvas::onDrawImageLattice(const SkImage* image, const Lattice
|
||||
}
|
||||
}
|
||||
|
||||
void SkPaintFilterCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
int boneCount, SkBlendMode bmode,
|
||||
const SkPaint& paint) {
|
||||
void SkPaintFilterCanvas::onDrawVerticesObject(const SkVertices* vertices,
|
||||
const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode bmode, const SkPaint& paint) {
|
||||
AutoPaintFilter apf(this, kVertices_Type, paint);
|
||||
if (apf.shouldDraw()) {
|
||||
this->SkNWayCanvas::onDrawVerticesObject(vertices, bones, boneCount, bmode, *apf.paint());
|
||||
|
@ -1156,7 +1156,7 @@ void SkXPSDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
draw(this, &SkDraw::drawPoints, mode, count, points, paint, this);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawVertices(const SkVertices* v, const SkMatrix* bones, int boneCount,
|
||||
void SkXPSDevice::drawVertices(const SkVertices* v, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode blendMode, const SkPaint& paint) {
|
||||
draw(this, &SkDraw::drawVertices, v->mode(), v->vertexCount(), v->positions(), v->texCoords(),
|
||||
v->colors(), v->boneIndices(), v->boneWeights(), blendMode, v->indices(), v->indexCount(),
|
||||
|
@ -99,7 +99,7 @@ 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*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
@ -445,7 +445,7 @@ void SkDebugCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4
|
||||
this->addDrawCommand(new SkDrawPatchCommand(cubics, colors, texCoords, bmode, paint));
|
||||
}
|
||||
|
||||
void SkDebugCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkMatrix* bones,
|
||||
void SkDebugCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
|
||||
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
|
||||
// TODO: ANIMATION NOT LOGGED
|
||||
this->addDrawCommand(new SkDrawVerticesCommand(sk_ref_sp(const_cast<SkVertices*>(vertices)),
|
||||
|
@ -146,8 +146,8 @@ protected:
|
||||
void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
|
||||
void onDrawRRect(const SkRRect&, const SkPaint&) override;
|
||||
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
|
||||
SkBlendMode, const SkPaint&) override;
|
||||
void onDrawPath(const SkPath&, const SkPaint&) override;
|
||||
void onDrawRegion(const SkRegion&, const SkPaint&) override;
|
||||
void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override;
|
||||
|
@ -18,20 +18,6 @@
|
||||
using namespace sk_app;
|
||||
using namespace nima;
|
||||
|
||||
// NIMA stores its matrices as 6 floats to represent translation and scale. This function takes
|
||||
// that format and converts it into a 3x3 matrix representation.
|
||||
static void nima_to_skmatrix(const float* nimaData, SkMatrix& matrix) {
|
||||
matrix[0] = nimaData[0];
|
||||
matrix[1] = nimaData[2];
|
||||
matrix[2] = nimaData[4];
|
||||
matrix[3] = nimaData[1];
|
||||
matrix[4] = nimaData[3];
|
||||
matrix[5] = nimaData[5];
|
||||
matrix[6] = 0.0f;
|
||||
matrix[7] = 0.0f;
|
||||
matrix[8] = 1.0f;
|
||||
}
|
||||
|
||||
// ImGui expects an array of const char* when displaying a ListBox. This function is for an
|
||||
// overload of ImGui::ListBox that takes a getter so that ListBox works with
|
||||
// std::vector<std::string>.
|
||||
@ -58,11 +44,8 @@ public:
|
||||
, fVertices(nullptr)
|
||||
, fRenderFlags(0) {
|
||||
// Update the vertices and bones.
|
||||
this->updateVertices();
|
||||
this->updateVertices(true);
|
||||
this->updateBones();
|
||||
|
||||
// Update the vertices object.
|
||||
this->updateVerticesObject(false, false);
|
||||
}
|
||||
|
||||
void render(SkCanvas* canvas, uint32_t renderFlags) {
|
||||
@ -73,47 +56,39 @@ public:
|
||||
bool useCache = renderFlags & kCache_RenderFlag;
|
||||
bool drawBounds = renderFlags & kBounds_RenderFlag;
|
||||
|
||||
// Don't use the cache if drawing in immediate mode.
|
||||
useCache &= !useImmediate;
|
||||
|
||||
if (fActorImage->doesAnimationVertexDeform() || dirty) {
|
||||
// These are vertices that transform beyond just bone transforms, so they must be
|
||||
// updated every frame.
|
||||
// If the render flags are dirty, reset the vertices object.
|
||||
this->updateVertices(!useCache);
|
||||
}
|
||||
|
||||
// Update the bones.
|
||||
this->updateBones();
|
||||
|
||||
// Deform the bones in immediate mode.
|
||||
sk_sp<SkVertices> vertices = fVertices;
|
||||
if (useImmediate) {
|
||||
// Immediate mode transforms.
|
||||
// Update the vertex data.
|
||||
if (fActorImage->doesAnimationVertexDeform() && fActorImage->isVertexDeformDirty()) {
|
||||
this->updateVertices();
|
||||
fActorImage->isVertexDeformDirty(false);
|
||||
}
|
||||
|
||||
// Update the vertices object.
|
||||
this->updateVerticesObject(true, true); // Immediate mode vertices change every frame,
|
||||
// so they must be volatile.
|
||||
} else {
|
||||
// Backend transformations.
|
||||
if (fActorImage->doesAnimationVertexDeform()) {
|
||||
// These are vertices that transform beyond just bone transforms, so they must be
|
||||
// updated every frame.
|
||||
this->updateVertices();
|
||||
this->updateVerticesObject(false, true);
|
||||
} else if (dirty) {
|
||||
// If the render flags are dirty, reset the vertices object.
|
||||
this->updateVertices();
|
||||
this->updateVerticesObject(false, !useCache);
|
||||
}
|
||||
|
||||
// Update the bones.
|
||||
this->updateBones();
|
||||
vertices = fVertices->applyBones(fBones.data(), fBones.size());
|
||||
}
|
||||
|
||||
// Draw the vertices object.
|
||||
this->drawVerticesObject(canvas, !useImmediate);
|
||||
this->drawVerticesObject(vertices.get(), canvas, !useImmediate);
|
||||
|
||||
// Draw the bounds.
|
||||
if (drawBounds && fActorImage->renderOpacity() > 0.0f) {
|
||||
// Get the bounds.
|
||||
SkRect bounds = fVertices->bounds();
|
||||
SkRect bounds = vertices->bounds();
|
||||
|
||||
// Approximate bounds if not using immediate transforms.
|
||||
if (!useImmediate) {
|
||||
const SkRect originalBounds = fBones[0].mapRect(fVertices->bounds());
|
||||
const SkRect originalBounds = fBones[0].mapRect(vertices->bounds());
|
||||
bounds = originalBounds;
|
||||
for (size_t i = 1; i < fBones.size(); i++) {
|
||||
const SkMatrix& matrix = fBones[i];
|
||||
const SkVertices::Bone& matrix = fBones[i];
|
||||
bounds.join(matrix.mapRect(originalBounds));
|
||||
}
|
||||
}
|
||||
@ -129,7 +104,7 @@ public:
|
||||
int drawOrder() const { return fActorImage->drawOrder(); }
|
||||
|
||||
private:
|
||||
void updateVertices() {
|
||||
void updateVertices(bool isVolatile) {
|
||||
// Update whether the image is skinned.
|
||||
fSkinned = fActorImage->connectedBoneCount() > 0;
|
||||
|
||||
@ -177,12 +152,24 @@ private:
|
||||
fTexs[i].set(attrTex[0] * fTexture->width(), attrTex[1] * fTexture->height());
|
||||
if (fSkinned) {
|
||||
for (uint32_t k = 0; k < 4; k ++) {
|
||||
fBoneIdx[i].indices[k] = static_cast<uint32_t>(attrBoneIdx[k]);
|
||||
fBoneWgt[i].weights[k] = attrBoneWgt[k];
|
||||
fBoneIdx[i][k] = static_cast<uint32_t>(attrBoneIdx[k]);
|
||||
fBoneWgt[i][k] = attrBoneWgt[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(fIndices.data(), indexData, indexCount * sizeof(uint16_t));
|
||||
|
||||
// Update the vertices object.
|
||||
fVertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
|
||||
vertexCount,
|
||||
fPositions.data(),
|
||||
fTexs.data(),
|
||||
nullptr,
|
||||
fBoneIdx.data(),
|
||||
fBoneWgt.data(),
|
||||
fIndices.size(),
|
||||
fIndices.data(),
|
||||
isVolatile);
|
||||
}
|
||||
|
||||
void updateBones() {
|
||||
@ -195,59 +182,24 @@ private:
|
||||
if (fSkinned) {
|
||||
numMatrices = fActorImage->boneInfluenceMatricesLength() / kNIMAMatrixSize;
|
||||
}
|
||||
fBones.assign(numMatrices, SkMatrix());
|
||||
|
||||
// Initialize all matrices to the identity matrix.
|
||||
fBones.assign(numMatrices, {{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }});
|
||||
}
|
||||
|
||||
if (fSkinned) {
|
||||
// Update the matrices.
|
||||
float* matrixData = fActorImage->boneInfluenceMatrices();
|
||||
for (uint32_t i = 1; i < fBones.size(); i ++) {
|
||||
SkMatrix& matrix = fBones[i];
|
||||
float* data = matrixData + i * kNIMAMatrixSize;
|
||||
nima_to_skmatrix(data, matrix);
|
||||
}
|
||||
memcpy(fBones.data(), matrixData, fBones.size() * kNIMAMatrixSize * sizeof(float));
|
||||
}
|
||||
|
||||
// Set the zero matrix to be the world transform.
|
||||
nima_to_skmatrix(fActorImage->worldTransform().values(), fBones[0]);
|
||||
memcpy(fBones.data(),
|
||||
fActorImage->worldTransform().values(),
|
||||
kNIMAMatrixSize * sizeof(float));
|
||||
}
|
||||
|
||||
void updateVerticesObject(bool applyDeforms, bool isVolatile) {
|
||||
std::vector<SkPoint>* positions = &fPositions;
|
||||
|
||||
// Apply deforms if requested.
|
||||
uint32_t vertexCount = fPositions.size();
|
||||
std::vector<SkPoint> deformedPositions;
|
||||
if (applyDeforms) {
|
||||
positions = &deformedPositions;
|
||||
deformedPositions.reserve(vertexCount);
|
||||
for (uint32_t i = 0; i < vertexCount; i ++) {
|
||||
Vec2D nimaPoint(fPositions[i].x(), fPositions[i].y());
|
||||
uint32_t* boneIdx = nullptr;
|
||||
float* boneWgt = nullptr;
|
||||
if (fSkinned) {
|
||||
boneIdx = fBoneIdx[i].indices;
|
||||
boneWgt = fBoneWgt[i].weights;
|
||||
}
|
||||
nimaPoint = this->deform(nimaPoint, boneIdx, boneWgt);
|
||||
deformedPositions.push_back(SkPoint::Make(nimaPoint[0], nimaPoint[1]));
|
||||
}
|
||||
}
|
||||
|
||||
// Update the vertices object.
|
||||
fVertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
|
||||
vertexCount,
|
||||
positions->data(),
|
||||
fTexs.data(),
|
||||
nullptr,
|
||||
fBoneIdx.data(),
|
||||
fBoneWgt.data(),
|
||||
fIndices.size(),
|
||||
fIndices.data(),
|
||||
isVolatile);
|
||||
}
|
||||
|
||||
void drawVerticesObject(SkCanvas* canvas, bool useBones) const {
|
||||
void drawVerticesObject(SkVertices* vertices, SkCanvas* canvas, bool useBones) const {
|
||||
// Determine the blend mode.
|
||||
SkBlendMode blendMode;
|
||||
switch (fActorImage->blendMode()) {
|
||||
@ -278,48 +230,15 @@ private:
|
||||
|
||||
// Draw the vertices.
|
||||
if (useBones) {
|
||||
canvas->drawVertices(fVertices, fBones.data(), fBones.size(), blendMode, *fPaint);
|
||||
canvas->drawVertices(vertices, fBones.data(), fBones.size(), blendMode, *fPaint);
|
||||
} else {
|
||||
canvas->drawVertices(fVertices, blendMode, *fPaint);
|
||||
canvas->drawVertices(vertices, blendMode, *fPaint);
|
||||
}
|
||||
|
||||
// Reset the opacity.
|
||||
fPaint->setAlpha(255);
|
||||
}
|
||||
|
||||
Vec2D deform(const Vec2D& position, uint32_t* boneIdx, float* boneWgt) const {
|
||||
float px = position[0], py = position[1];
|
||||
float px2 = px, py2 = py;
|
||||
float influence[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Apply the world transform.
|
||||
Mat2D worldTransform = fActorImage->worldTransform();
|
||||
px2 = worldTransform[0] * px + worldTransform[2] * py + worldTransform[4];
|
||||
py2 = worldTransform[1] * px + worldTransform[3] * py + worldTransform[5];
|
||||
|
||||
// Apply deformations based on bone offsets.
|
||||
if (boneIdx && boneWgt) {
|
||||
float* matrices = fActorImage->boneInfluenceMatrices();
|
||||
|
||||
for (uint32_t i = 0; i < 4; i ++) {
|
||||
uint32_t index = boneIdx[i];
|
||||
float weight = boneWgt[i];
|
||||
for (int j = 0; j < 6; j ++) {
|
||||
influence[j] += matrices[index * 6 + j] * weight;
|
||||
}
|
||||
}
|
||||
|
||||
px = influence[0] * px2 + influence[2] * py2 + influence[4];
|
||||
py = influence[1] * px2 + influence[3] * py2 + influence[5];
|
||||
} else {
|
||||
px = px2;
|
||||
py = py2;
|
||||
}
|
||||
|
||||
// Return the transformed position.
|
||||
return Vec2D(px, py);
|
||||
}
|
||||
|
||||
private:
|
||||
ActorImage* fActorImage;
|
||||
SkImage* fTexture;
|
||||
@ -332,8 +251,8 @@ private:
|
||||
std::vector<SkVertices::BoneWeights> fBoneWgt;
|
||||
std::vector<uint16_t> fIndices;
|
||||
|
||||
std::vector<SkMatrix> fBones;
|
||||
sk_sp<SkVertices> fVertices;
|
||||
std::vector<SkVertices::Bone> fBones;
|
||||
sk_sp<SkVertices> fVertices;
|
||||
|
||||
uint32_t fRenderFlags;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user