added caching of SkVertices
SkVertices can now be "volatile", meaning they should not be cached. SkVertices is volatile by default if the argument is not given. Pulled from reverted CL: https://skia-review.googlesource.com/c/skia/+/138596 Docs-Preview: https://skia.org/?cl=139545 Bug: skia: Change-Id: I92cf832efe1c0aaa8f432eedde2678582dd2454e Reviewed-on: https://skia-review.googlesource.com/139545 Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Ruiqi Mao <ruiqimao@google.com>
This commit is contained in:
parent
c3833b4c15
commit
9a6e42ff18
@ -5772,6 +5772,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.
|
||||
|
||||
#Param vertices triangle mesh to draw ##
|
||||
#Param bones bone matrix data ##
|
||||
@ -5821,6 +5822,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.
|
||||
|
||||
#Param vertices triangle mesh to draw ##
|
||||
#Param bones bone matrix data ##
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/* Generated by tools/bookmaker from include/core/SkCanvas.h and docs/SkCanvas_Reference.bmh
|
||||
on 2018-07-02 10:27:08. Additional documentation and examples can be found at:
|
||||
on 2018-07-03 11:34:22. Additional documentation and examples can be found at:
|
||||
https://skia.org/user/api/SkCanvas_Reference
|
||||
|
||||
You may edit either file directly. Structural changes to public interfaces require
|
||||
@ -2156,6 +2156,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.
|
||||
|
||||
@param vertices triangle mesh to draw
|
||||
@param bones bone matrix data
|
||||
@ -2173,6 +2174,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.
|
||||
|
||||
@param vertices triangle mesh to draw
|
||||
@param bones bone matrix data
|
||||
|
@ -55,14 +55,16 @@ public:
|
||||
const BoneIndices boneIndices[],
|
||||
const BoneWeights boneWeights[],
|
||||
int indexCount,
|
||||
const uint16_t indices[]);
|
||||
const uint16_t indices[],
|
||||
bool isVolatile = true);
|
||||
|
||||
static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
|
||||
const SkPoint positions[],
|
||||
const SkPoint texs[],
|
||||
const SkColor colors[],
|
||||
const BoneIndices boneIndices[],
|
||||
const BoneWeights boneWeights[]) {
|
||||
const BoneWeights boneWeights[],
|
||||
bool isVolatile = true) {
|
||||
return MakeCopy(mode,
|
||||
vertexCount,
|
||||
positions,
|
||||
@ -71,7 +73,8 @@ public:
|
||||
boneIndices,
|
||||
boneWeights,
|
||||
0,
|
||||
nullptr);
|
||||
nullptr,
|
||||
isVolatile);
|
||||
}
|
||||
|
||||
static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
|
||||
@ -79,7 +82,8 @@ public:
|
||||
const SkPoint texs[],
|
||||
const SkColor colors[],
|
||||
int indexCount,
|
||||
const uint16_t indices[]) {
|
||||
const uint16_t indices[],
|
||||
bool isVolatile = true) {
|
||||
return MakeCopy(mode,
|
||||
vertexCount,
|
||||
positions,
|
||||
@ -88,14 +92,16 @@ public:
|
||||
nullptr,
|
||||
nullptr,
|
||||
indexCount,
|
||||
indices);
|
||||
indices,
|
||||
isVolatile);
|
||||
}
|
||||
|
||||
static sk_sp<SkVertices> MakeCopy(VertexMode mode, int vertexCount,
|
||||
const SkPoint positions[],
|
||||
const SkPoint texs[],
|
||||
const SkColor colors[]) {
|
||||
return MakeCopy(mode, vertexCount, positions, texs, colors, nullptr, nullptr);
|
||||
const SkColor colors[],
|
||||
bool isVolatile = true) {
|
||||
return MakeCopy(mode, vertexCount, positions, texs, colors, nullptr, nullptr, isVolatile);
|
||||
}
|
||||
|
||||
struct Sizes;
|
||||
@ -104,6 +110,7 @@ public:
|
||||
kHasTexCoords_BuilderFlag = 1 << 0,
|
||||
kHasColors_BuilderFlag = 1 << 1,
|
||||
kHasBones_BuilderFlag = 1 << 2,
|
||||
kIsNonVolatile_BuilderFlag = 1 << 3,
|
||||
};
|
||||
class Builder {
|
||||
public:
|
||||
@ -114,6 +121,7 @@ public:
|
||||
// if the builder is invalid, these will return 0
|
||||
int vertexCount() const;
|
||||
int indexCount() const;
|
||||
bool isVolatile() const;
|
||||
SkPoint* positions();
|
||||
SkPoint* texCoords(); // returns null if there are no texCoords
|
||||
SkColor* colors(); // returns null if there are no colors
|
||||
@ -125,9 +133,9 @@ public:
|
||||
sk_sp<SkVertices> detach();
|
||||
|
||||
private:
|
||||
Builder(VertexMode mode, int vertexCount, int indexCount, const Sizes&);
|
||||
Builder(VertexMode mode, int vertexCount, int indexCount, bool isVolatile, const Sizes&);
|
||||
|
||||
void init(VertexMode mode, int vertexCount, int indexCount, const Sizes&);
|
||||
void init(VertexMode mode, int vertexCount, int indexCount, bool isVolatile, const Sizes&);
|
||||
|
||||
// holds a partially complete object. only completed in detach()
|
||||
sk_sp<SkVertices> fVertices;
|
||||
@ -158,6 +166,8 @@ public:
|
||||
int indexCount() const { return fIndexCnt; }
|
||||
const uint16_t* indices() const { return fIndices; }
|
||||
|
||||
bool isVolatile() const { return fIsVolatile; }
|
||||
|
||||
// returns approximate byte size of the vertices object
|
||||
size_t approximateSize() const;
|
||||
|
||||
@ -199,6 +209,8 @@ private:
|
||||
int fVertexCnt;
|
||||
int fIndexCnt;
|
||||
|
||||
bool fIsVolatile;
|
||||
|
||||
VertexMode fMode;
|
||||
// below here is where the actual array data is stored.
|
||||
};
|
||||
|
@ -6537,6 +6537,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.
|
||||
|
||||
### Parameters
|
||||
|
||||
@ -6581,6 +6582,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.
|
||||
|
||||
### Parameters
|
||||
|
||||
|
@ -1715,6 +1715,7 @@ void SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, const SkMatrix* b
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
RETURN_ON_NULL(vertices);
|
||||
SkASSERT(boneCount <= 100);
|
||||
this->onDrawVerticesObject(vertices.get(), bones, boneCount, mode, paint);
|
||||
}
|
||||
|
||||
@ -1722,6 +1723,7 @@ void SkCanvas::drawVertices(const SkVertices* vertices, const SkMatrix* bones, i
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
RETURN_ON_NULL(vertices);
|
||||
SkASSERT(boneCount <= 100);
|
||||
this->onDrawVerticesObject(vertices, bones, boneCount, mode, paint);
|
||||
}
|
||||
|
||||
|
@ -95,16 +95,17 @@ SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount,
|
||||
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,
|
||||
bool isVolatile = !SkToBool(builderFlags & SkVertices::kIsNonVolatile_BuilderFlag);
|
||||
this->init(mode, vertexCount, indexCount, isVolatile,
|
||||
SkVertices::Sizes(mode, vertexCount, indexCount, hasTexs, hasColors, hasBones));
|
||||
}
|
||||
|
||||
SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount,
|
||||
SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount, bool isVolatile,
|
||||
const SkVertices::Sizes& sizes) {
|
||||
this->init(mode, vertexCount, indexCount, sizes);
|
||||
this->init(mode, vertexCount, indexCount, isVolatile, sizes);
|
||||
}
|
||||
|
||||
void SkVertices::Builder::init(VertexMode mode, int vertexCount, int indexCount,
|
||||
void SkVertices::Builder::init(VertexMode mode, int vertexCount, int indexCount, bool isVolatile,
|
||||
const SkVertices::Sizes& sizes) {
|
||||
if (!sizes.isValid()) {
|
||||
return; // fVertices will already be null
|
||||
@ -128,6 +129,7 @@ void SkVertices::Builder::init(VertexMode mode, int vertexCount, int indexCount,
|
||||
fVertices->fIndices = sizes.fISize ? (uint16_t*)ptr : nullptr;
|
||||
fVertices->fVertexCnt = vertexCount;
|
||||
fVertices->fIndexCnt = indexCount;
|
||||
fVertices->fIsVolatile = isVolatile;
|
||||
fVertices->fMode = mode;
|
||||
|
||||
// We defer assigning fBounds and fUniqueID until detach() is called
|
||||
@ -171,6 +173,10 @@ int SkVertices::Builder::indexCount() const {
|
||||
return fVertices ? fVertices->indexCount() : 0;
|
||||
}
|
||||
|
||||
bool SkVertices::Builder::isVolatile() const {
|
||||
return fVertices ? fVertices->isVolatile() : true;
|
||||
}
|
||||
|
||||
SkPoint* SkVertices::Builder::positions() {
|
||||
return fVertices ? const_cast<SkPoint*>(fVertices->positions()) : nullptr;
|
||||
}
|
||||
@ -208,7 +214,8 @@ sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount,
|
||||
const SkColor colors[],
|
||||
const BoneIndices boneIndices[],
|
||||
const BoneWeights boneWeights[],
|
||||
int indexCount, const uint16_t indices[]) {
|
||||
int indexCount, const uint16_t indices[],
|
||||
bool isVolatile) {
|
||||
SkASSERT((!boneIndices && !boneWeights) || (boneIndices && boneWeights));
|
||||
Sizes sizes(mode,
|
||||
vertexCount,
|
||||
@ -220,7 +227,7 @@ sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Builder builder(mode, vertexCount, indexCount, sizes);
|
||||
Builder builder(mode, vertexCount, indexCount, isVolatile, sizes);
|
||||
SkASSERT(builder.isValid());
|
||||
|
||||
sk_careful_memcpy(builder.positions(), pos, sizes.fVSize);
|
||||
@ -255,6 +262,7 @@ size_t SkVertices::approximateSize() const {
|
||||
#define kHasTexs_Mask 0x100
|
||||
#define kHasColors_Mask 0x200
|
||||
#define kHasBones_Mask 0x400
|
||||
#define kIsNonVolatile_Mask 0x800
|
||||
#define kHeaderSize (3 * sizeof(uint32_t))
|
||||
|
||||
sk_sp<SkData> SkVertices::encode() const {
|
||||
@ -270,6 +278,9 @@ sk_sp<SkData> SkVertices::encode() const {
|
||||
if (this->hasBones()) {
|
||||
packed |= kHasBones_Mask;
|
||||
}
|
||||
if (!this->isVolatile()) {
|
||||
packed |= kIsNonVolatile_Mask;
|
||||
}
|
||||
|
||||
Sizes sizes(fMode,
|
||||
fVertexCnt,
|
||||
@ -318,6 +329,7 @@ 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);
|
||||
const bool hasBones = SkToBool(packed & kHasBones_Mask);
|
||||
const bool isVolatile = !SkToBool(packed & kIsNonVolatile_Mask);
|
||||
Sizes sizes(mode, vertexCount, indexCount, hasTexs, hasColors, hasBones);
|
||||
if (!sizes.isValid()) {
|
||||
return nullptr;
|
||||
@ -327,7 +339,7 @@ sk_sp<SkVertices> SkVertices::Decode(const void* data, size_t length) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Builder builder(mode, vertexCount, indexCount, sizes);
|
||||
Builder builder(mode, vertexCount, indexCount, isVolatile, sizes);
|
||||
|
||||
reader.read(builder.positions(), sizes.fVSize);
|
||||
reader.read(builder.texCoords(), sizes.fTSize);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "GrDefaultGeoProcFactory.h"
|
||||
#include "GrOpFlushState.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkRectPriv.h"
|
||||
|
||||
std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrContext* context,
|
||||
GrPaint&& paint,
|
||||
@ -53,7 +54,7 @@ GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor c
|
||||
fFlags |= kRequiresPerVertexColors_Flag;
|
||||
}
|
||||
if (mesh.hasExplicitLocalCoords()) {
|
||||
fFlags |= kAnyMeshHasExplicitLocalCoords;
|
||||
fFlags |= kAnyMeshHasExplicitLocalCoords_Flag;
|
||||
}
|
||||
|
||||
IsZeroArea zeroArea;
|
||||
@ -62,7 +63,11 @@ GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor c
|
||||
} else {
|
||||
zeroArea = IsZeroArea::kNo;
|
||||
}
|
||||
this->setTransformedBounds(mesh.fVertices->bounds(), viewMatrix, HasAABloat::kNo, zeroArea);
|
||||
|
||||
this->setTransformedBounds(mesh.fVertices->bounds(),
|
||||
mesh.fViewMatrix,
|
||||
HasAABloat::kNo,
|
||||
zeroArea);
|
||||
}
|
||||
|
||||
SkString GrDrawVerticesOp::dumpInfo() const {
|
||||
@ -96,7 +101,7 @@ GrDrawOp::RequiresDstTexture GrDrawVerticesOp::finalize(const GrCaps& caps,
|
||||
}
|
||||
if (!fHelper.usesLocalCoords()) {
|
||||
fMeshes[0].fIgnoreTexCoords = true;
|
||||
fFlags &= ~kAnyMeshHasExplicitLocalCoords;
|
||||
fFlags &= ~kAnyMeshHasExplicitLocalCoords_Flag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -132,26 +137,39 @@ sk_sp<GrGeometryProcessor> GrDrawVerticesOp::makeGP(bool* hasColorAttribute,
|
||||
} else {
|
||||
*hasColorAttribute = false;
|
||||
};
|
||||
|
||||
const SkMatrix& vm = this->hasMultipleViewMatrices() ? SkMatrix::I() : fMeshes[0].fViewMatrix;
|
||||
return GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, vm);
|
||||
|
||||
return GrDefaultGeoProcFactory::Make(color,
|
||||
Coverage::kSolid_Type,
|
||||
localCoordsType,
|
||||
vm);
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::onPrepareDraws(Target* target) {
|
||||
if (fMeshes[0].fVertices->isVolatile()) {
|
||||
this->drawVolatile(target);
|
||||
} else {
|
||||
this->drawNonVolatile(target);
|
||||
}
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::drawVolatile(Target* target) {
|
||||
bool hasColorAttribute;
|
||||
bool hasLocalCoordsAttribute;
|
||||
sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute, &hasLocalCoordsAttribute);
|
||||
sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute,
|
||||
&hasLocalCoordsAttribute);
|
||||
|
||||
size_t vertexStride = sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) +
|
||||
// Calculate the stride.
|
||||
size_t vertexStride = sizeof(SkPoint) +
|
||||
(hasColorAttribute ? sizeof(uint32_t) : 0) +
|
||||
(hasLocalCoordsAttribute ? sizeof(SkPoint) : 0);
|
||||
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
|
||||
|
||||
int instanceCount = fMeshes.count();
|
||||
|
||||
const GrBuffer* vertexBuffer;
|
||||
int firstVertex;
|
||||
|
||||
// Allocate buffers.
|
||||
const GrBuffer* vertexBuffer = nullptr;
|
||||
int firstVertex = 0;
|
||||
void* verts = target->makeVertexSpace(vertexStride, fVertexCount, &vertexBuffer, &firstVertex);
|
||||
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
@ -159,29 +177,139 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) {
|
||||
|
||||
const GrBuffer* indexBuffer = nullptr;
|
||||
int firstIndex = 0;
|
||||
|
||||
uint16_t* indices = nullptr;
|
||||
if (this->isIndexed()) {
|
||||
indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex);
|
||||
|
||||
if (!indices) {
|
||||
SkDebugf("Could not allocate indices\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the buffers.
|
||||
this->fillBuffers(hasColorAttribute,
|
||||
hasLocalCoordsAttribute,
|
||||
vertexStride,
|
||||
verts,
|
||||
indices);
|
||||
|
||||
// Draw the vertices.
|
||||
this->drawVertices(target, gp.get(), vertexBuffer, firstVertex, indexBuffer, firstIndex);
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::drawNonVolatile(Target* target) {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
|
||||
bool hasColorAttribute;
|
||||
bool hasLocalCoordsAttribute;
|
||||
sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute,
|
||||
&hasLocalCoordsAttribute);
|
||||
|
||||
SkASSERT(fMeshes.count() == 1); // Non-volatile meshes should never combine.
|
||||
|
||||
// Get the resource provider.
|
||||
GrResourceProvider* rp = target->resourceProvider();
|
||||
|
||||
// Generate keys for the buffers.
|
||||
GrUniqueKey vertexKey, indexKey;
|
||||
GrUniqueKey::Builder vertexKeyBuilder(&vertexKey, kDomain, 2);
|
||||
GrUniqueKey::Builder indexKeyBuilder(&indexKey, kDomain, 2);
|
||||
vertexKeyBuilder[0] = indexKeyBuilder[0] = fMeshes[0].fVertices->uniqueID();
|
||||
vertexKeyBuilder[1] = 0;
|
||||
indexKeyBuilder[1] = 1;
|
||||
vertexKeyBuilder.finish();
|
||||
indexKeyBuilder.finish();
|
||||
|
||||
// Try to grab data from the cache.
|
||||
sk_sp<GrBuffer> vertexBuffer = rp->findByUniqueKey<GrBuffer>(vertexKey);
|
||||
sk_sp<GrBuffer> indexBuffer = this->isIndexed() ?
|
||||
rp->findByUniqueKey<GrBuffer>(indexKey) :
|
||||
nullptr;
|
||||
|
||||
// Draw using the cached buffers if possible.
|
||||
if (vertexBuffer && (!this->isIndexed() || indexBuffer)) {
|
||||
this->drawVertices(target, gp.get(), vertexBuffer.get(), 0, indexBuffer.get(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the stride.
|
||||
size_t vertexStride = sizeof(SkPoint) +
|
||||
(hasColorAttribute ? sizeof(uint32_t) : 0) +
|
||||
(hasLocalCoordsAttribute ? sizeof(SkPoint) : 0);
|
||||
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
|
||||
|
||||
// Allocate vertex buffer.
|
||||
vertexBuffer.reset(rp->createBuffer(fVertexCount * vertexStride,
|
||||
kVertex_GrBufferType,
|
||||
kStatic_GrAccessPattern,
|
||||
0));
|
||||
void* verts = vertexBuffer ? vertexBuffer->map() : nullptr;
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate index buffer.
|
||||
uint16_t* indices = nullptr;
|
||||
if (this->isIndexed()) {
|
||||
indexBuffer.reset(rp->createBuffer(fIndexCount * sizeof(uint16_t),
|
||||
kIndex_GrBufferType,
|
||||
kStatic_GrAccessPattern,
|
||||
0));
|
||||
indices = indexBuffer ? static_cast<uint16_t*>(indexBuffer->map()) : nullptr;
|
||||
if (!indices) {
|
||||
SkDebugf("Could not allocate indices\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the buffers.
|
||||
this->fillBuffers(hasColorAttribute,
|
||||
hasLocalCoordsAttribute,
|
||||
vertexStride,
|
||||
verts,
|
||||
indices);
|
||||
|
||||
// Unmap the buffers.
|
||||
vertexBuffer->unmap();
|
||||
if (indexBuffer) {
|
||||
indexBuffer->unmap();
|
||||
}
|
||||
|
||||
// Cache the buffers.
|
||||
rp->assignUniqueKeyToResource(vertexKey, vertexBuffer.get());
|
||||
rp->assignUniqueKeyToResource(indexKey, indexBuffer.get());
|
||||
|
||||
// Draw the vertices.
|
||||
this->drawVertices(target, gp.get(), vertexBuffer.get(), 0, indexBuffer.get(), 0);
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::fillBuffers(bool hasColorAttribute,
|
||||
bool hasLocalCoordsAttribute,
|
||||
size_t vertexStride,
|
||||
void* verts,
|
||||
uint16_t* indices) const {
|
||||
int instanceCount = fMeshes.count();
|
||||
|
||||
// Copy data into the buffers.
|
||||
int vertexOffset = 0;
|
||||
// We have a fast case below for uploading the vertex data when the matrix is translate
|
||||
// only and there are colors but not local coords.
|
||||
// only and there are colors but not local coords. Fast case does not apply when there are bone
|
||||
// transformations.
|
||||
bool fastAttrs = hasColorAttribute && !hasLocalCoordsAttribute;
|
||||
for (int i = 0; i < instanceCount; i++) {
|
||||
// Get each mesh.
|
||||
const Mesh& mesh = fMeshes[i];
|
||||
|
||||
// Copy data into the index buffer.
|
||||
if (indices) {
|
||||
int indexCount = mesh.fVertices->indexCount();
|
||||
for (int j = 0; j < indexCount; ++j) {
|
||||
*indices++ = mesh.fVertices->indices()[j] + vertexOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data into the vertex buffer.
|
||||
int vertexCount = mesh.fVertices->vertexCount();
|
||||
const SkPoint* positions = mesh.fVertices->positions();
|
||||
const SkColor* colors = mesh.fVertices->colors();
|
||||
@ -190,6 +318,7 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) {
|
||||
mesh.fViewMatrix.getType() <= SkMatrix::kTranslate_Mask) &&
|
||||
mesh.hasPerVertexColors();
|
||||
if (fastAttrs && fastMesh) {
|
||||
// Fast case.
|
||||
struct V {
|
||||
SkPoint fPos;
|
||||
uint32_t fColor;
|
||||
@ -207,9 +336,13 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) {
|
||||
}
|
||||
verts = v + vertexCount;
|
||||
} else {
|
||||
// Normal case.
|
||||
static constexpr size_t kColorOffset = sizeof(SkPoint);
|
||||
size_t localCoordOffset =
|
||||
hasColorAttribute ? kColorOffset + sizeof(uint32_t) : kColorOffset;
|
||||
size_t offset = kColorOffset;
|
||||
if (hasColorAttribute) {
|
||||
offset += sizeof(uint32_t);
|
||||
}
|
||||
size_t localCoordOffset = offset;
|
||||
|
||||
for (int j = 0; j < vertexCount; ++j) {
|
||||
if (this->hasMultipleViewMatrices()) {
|
||||
@ -236,17 +369,25 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) {
|
||||
}
|
||||
vertexOffset += vertexCount;
|
||||
}
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::drawVertices(Target* target,
|
||||
GrGeometryProcessor* gp,
|
||||
const GrBuffer* vertexBuffer,
|
||||
int firstVertex,
|
||||
const GrBuffer* indexBuffer,
|
||||
int firstIndex) {
|
||||
GrMesh mesh(this->primitiveType());
|
||||
if (!indices) {
|
||||
mesh.setNonIndexedNonInstanced(fVertexCount);
|
||||
} else {
|
||||
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1,
|
||||
if (this->isIndexed()) {
|
||||
mesh.setIndexed(indexBuffer, fIndexCount,
|
||||
firstIndex, 0, fVertexCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
} else {
|
||||
mesh.setNonIndexedNonInstanced(fVertexCount);
|
||||
}
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
|
||||
@ -256,6 +397,13 @@ bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Non-volatile meshes cannot batch, because if a non-volatile mesh batches with another mesh,
|
||||
// then on the next frame, if that non-volatile mesh is drawn, it will draw the other mesh
|
||||
// that was saved in its vertex buffer, which is not necessarily there anymore.
|
||||
if (!this->fMeshes[0].fVertices->isVolatile() || !that->fMeshes[0].fVertices->isVolatile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->combinablePrimitive() || this->primitiveType() != that->primitiveType()) {
|
||||
return false;
|
||||
}
|
||||
@ -410,8 +558,8 @@ GR_DRAW_OP_TEST_DEFINE(GrDrawVerticesOp) {
|
||||
if (GrFSAAType::kUnifiedMSAA == fsaaType && random->nextBool()) {
|
||||
aaType = GrAAType::kMSAA;
|
||||
}
|
||||
return GrDrawVerticesOp::Make(context, std::move(paint), std::move(vertices), viewMatrix,
|
||||
aaType, std::move(colorSpaceXform), &type);
|
||||
return GrDrawVerticesOp::Make(context, std::move(paint), std::move(vertices),
|
||||
viewMatrix, aaType, std::move(colorSpaceXform), &type);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -43,9 +43,8 @@ public:
|
||||
sk_sp<GrColorSpaceXform>,
|
||||
GrPrimitiveType* overridePrimType = nullptr);
|
||||
|
||||
GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor, sk_sp<SkVertices>,
|
||||
GrPrimitiveType, GrAAType, sk_sp<GrColorSpaceXform>,
|
||||
const SkMatrix& viewMatrix);
|
||||
GrDrawVerticesOp(const Helper::MakeArgs&, GrColor, sk_sp<SkVertices>, GrPrimitiveType, GrAAType,
|
||||
sk_sp<GrColorSpaceXform>, const SkMatrix& viewMatrix);
|
||||
|
||||
const char* name() const override { return "DrawVerticesOp"; }
|
||||
|
||||
@ -68,7 +67,24 @@ private:
|
||||
|
||||
void onPrepareDraws(Target*) override;
|
||||
|
||||
sk_sp<GrGeometryProcessor> makeGP(bool* hasColorAttribute, bool* hasLocalCoordAttribute) const;
|
||||
void drawVolatile(Target*);
|
||||
void drawNonVolatile(Target*);
|
||||
|
||||
void fillBuffers(bool hasColorAttribute,
|
||||
bool hasLocalCoordsAttribute,
|
||||
size_t vertexStride,
|
||||
void* verts,
|
||||
uint16_t* indices) const;
|
||||
|
||||
void drawVertices(Target*,
|
||||
GrGeometryProcessor*,
|
||||
const GrBuffer* vertexBuffer,
|
||||
int firstVertex,
|
||||
const GrBuffer* indexBuffer,
|
||||
int firstIndex);
|
||||
|
||||
sk_sp<GrGeometryProcessor> makeGP(bool* hasColorAttribute,
|
||||
bool* hasLocalCoordAttribute) const;
|
||||
|
||||
GrPrimitiveType primitiveType() const { return fPrimitiveType; }
|
||||
bool combinablePrimitive() const {
|
||||
@ -105,7 +121,7 @@ private:
|
||||
}
|
||||
|
||||
bool anyMeshHasExplicitLocalCoords() const {
|
||||
return SkToBool(kAnyMeshHasExplicitLocalCoords & fFlags);
|
||||
return SkToBool(kAnyMeshHasExplicitLocalCoords_Flag & fFlags);
|
||||
}
|
||||
|
||||
bool hasMultipleViewMatrices() const {
|
||||
@ -113,10 +129,9 @@ private:
|
||||
}
|
||||
|
||||
enum Flags {
|
||||
kRequiresPerVertexColors_Flag = 0x1,
|
||||
kAnyMeshHasExplicitLocalCoords = 0x2,
|
||||
kHasMultipleViewMatrices_Flag = 0x4
|
||||
|
||||
kRequiresPerVertexColors_Flag = 0x1,
|
||||
kAnyMeshHasExplicitLocalCoords_Flag = 0x2,
|
||||
kHasMultipleViewMatrices_Flag = 0x4,
|
||||
};
|
||||
|
||||
Helper fHelper;
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
this->updateBones();
|
||||
|
||||
// Update the vertices object.
|
||||
this->updateVerticesObject(false);
|
||||
this->updateVerticesObject(false, false);
|
||||
}
|
||||
|
||||
void renderBackend(SkCanvas* canvas) {
|
||||
@ -70,16 +70,13 @@ public:
|
||||
if (fRenderMode != kBackend_RenderMode) {
|
||||
fRenderMode = kBackend_RenderMode;
|
||||
this->updateVertices();
|
||||
this->updateVerticesObject(false);
|
||||
this->updateVerticesObject(false, false);
|
||||
}
|
||||
|
||||
canvas->save();
|
||||
|
||||
// Update the vertex data.
|
||||
if (fActorImage->doesAnimationVertexDeform() && fActorImage->isVertexDeformDirty()) {
|
||||
if (fActorImage->doesAnimationVertexDeform()) {
|
||||
this->updateVertices();
|
||||
this->updateVerticesObject(false);
|
||||
fActorImage->isVertexDeformDirty(false);
|
||||
this->updateVerticesObject(false, true);
|
||||
}
|
||||
|
||||
// Update the bones.
|
||||
@ -87,8 +84,6 @@ public:
|
||||
|
||||
// Draw the vertices object.
|
||||
this->drawVerticesObject(canvas, true);
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
void renderImmediate(SkCanvas* canvas) {
|
||||
@ -96,7 +91,7 @@ public:
|
||||
if (fRenderMode != kImmediate_RenderMode) {
|
||||
fRenderMode = kImmediate_RenderMode;
|
||||
this->updateVertices();
|
||||
this->updateVerticesObject(true);
|
||||
this->updateVerticesObject(true, true);
|
||||
}
|
||||
|
||||
// Update the vertex data.
|
||||
@ -106,7 +101,7 @@ public:
|
||||
}
|
||||
|
||||
// Update the vertices object.
|
||||
this->updateVerticesObject(true);
|
||||
this->updateVerticesObject(true, true);
|
||||
|
||||
// Draw the vertices object.
|
||||
this->drawVerticesObject(canvas, false);
|
||||
@ -198,7 +193,7 @@ private:
|
||||
nima_to_skmatrix(fActorImage->worldTransform().values(), fBones[0]);
|
||||
}
|
||||
|
||||
void updateVerticesObject(bool applyDeforms) {
|
||||
void updateVerticesObject(bool applyDeforms, bool isVolatile) {
|
||||
std::vector<SkPoint>* positions = &fPositions;
|
||||
|
||||
// Apply deforms if requested.
|
||||
@ -229,7 +224,8 @@ private:
|
||||
fBoneIdx.data(),
|
||||
fBoneWgt.data(),
|
||||
fIndices.size(),
|
||||
fIndices.data());
|
||||
fIndices.data(),
|
||||
isVolatile);
|
||||
}
|
||||
|
||||
void drawVerticesObject(SkCanvas* canvas, bool useBones) const {
|
||||
@ -421,11 +417,19 @@ NIMASlide::~NIMASlide() {}
|
||||
void NIMASlide::draw(SkCanvas* canvas) {
|
||||
canvas->save();
|
||||
|
||||
canvas->translate(500, 500);
|
||||
canvas->scale(1, -1);
|
||||
for (int i = 0; i < 10; i ++) {
|
||||
for (int j = 0; j < 10; j ++) {
|
||||
canvas->save();
|
||||
|
||||
// Render the actor.
|
||||
fActor->render(canvas, fRenderMode);
|
||||
canvas->translate(1250 - 250 * i, 1250 - 250 * j);
|
||||
canvas->scale(0.5, -0.5);
|
||||
|
||||
// Render the actor.
|
||||
fActor->render(canvas, fRenderMode);
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
|
||||
canvas->restore();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user