Update SkMesh buffer API to take const void* instead of SkData

Also expose a size() function on the public IB and VB types.

Bug: skia:12720
Change-Id: Ibeccf6d2d6ba411e9e77be582d0cb1622bc76ccd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/555005
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2022-07-01 15:27:15 -04:00 committed by SkCQ
parent 9da66d2a57
commit b2e4416a6b
5 changed files with 106 additions and 69 deletions

View File

@ -107,15 +107,17 @@ protected:
SkTileMode::kMirror);
}
DrawResult onGpuSetup(GrDirectContext* context, SkString* string) override {
DrawResult onGpuSetup(GrDirectContext* dc, SkString* string) override {
this->ensureBuffers();
if (!context || context->abandoned()) {
if (!dc || dc->abandoned()) {
return DrawResult::kOk;
}
fColorVB = SkMesh::MakeVertexBuffer(context, CpuVBAsData(fColorVB));
fColorIndexedVB = SkMesh::MakeVertexBuffer(context, CpuVBAsData(fColorIndexedVB));
fIB[1] = SkMesh::MakeIndexBuffer (context, CpuIBAsData(fIB[0]));
fColorVB = SkMesh::MakeVertexBuffer(dc, CpuVBPeek(fColorVB), fColorVB->size());
fColorIndexedVB = SkMesh::MakeVertexBuffer(dc,
CpuVBPeek(fColorIndexedVB),
fColorIndexedVB->size());
fIB[1] = SkMesh::MakeIndexBuffer (dc, CpuIBPeek(fIB[0]), fIB[0]->size());
if (!fColorVB || !fColorIndexedVB || !fIB[1]) {
return DrawResult::kFail;
}
@ -205,23 +207,23 @@ protected:
}
private:
static sk_sp<const SkData> CpuVBAsData(sk_sp<SkMesh::VertexBuffer> buffer) {
static const void* CpuVBPeek(sk_sp<SkMesh::VertexBuffer> buffer) {
auto vb = static_cast<SkMeshPriv::VB*>(buffer.get());
SkASSERT(vb->asData());
return vb->asData();
SkASSERT(vb->peek());
return vb->peek();
}
static sk_sp<const SkData> CpuIBAsData(sk_sp<SkMesh::IndexBuffer> buffer) {
static const void* CpuIBPeek(sk_sp<SkMesh::IndexBuffer> buffer) {
auto ib = static_cast<SkMeshPriv::IB*>(buffer.get());
SkASSERT(ib->asData());
return ib->asData();
SkASSERT(ib->peek());
return ib->peek();
}
void ensureBuffers() {
if (!fColorVB) {
fColorVB = SkMesh::MakeVertexBuffer(
/*GrDirectContext*=*/nullptr,
SkData::MakeWithoutCopy(kColorQuad, sizeof(kColorQuad)));
fColorVB = SkMesh::MakeVertexBuffer(/*GrDirectContext*=*/nullptr,
kColorQuad,
sizeof(kColorQuad));
}
if (!fNoColorVB) {
@ -230,7 +232,9 @@ private:
std::memcpy(SkTAddOffset<void>(data->writable_data(), kNoColorOffset),
kNoColorQuad,
sizeof(kNoColorQuad));
fNoColorVB = SkMesh::MakeVertexBuffer(/*GrDirectContext*=*/nullptr, std::move(data));
fNoColorVB = SkMesh::MakeVertexBuffer(/*GrDirectContext*=*/nullptr,
data->data(),
data->size());
}
if (!fColorIndexedVB) {
@ -240,13 +244,14 @@ private:
kColorIndexedQuad,
sizeof(kColorIndexedQuad));
fColorIndexedVB = SkMesh::MakeVertexBuffer(/*GrDirectContext*=*/nullptr,
std::move(data));
data->data(),
data->size());
}
if (!fNoColorIndexedVB) {
fNoColorIndexedVB = SkMesh::MakeVertexBuffer(
/*GrDirectContext*=*/nullptr,
SkData::MakeWithoutCopy(kNoColorIndexedQuad, sizeof(kNoColorIndexedQuad)));
fNoColorIndexedVB = SkMesh::MakeVertexBuffer(/*GrDirectContext*=*/nullptr,
kNoColorIndexedQuad,
sizeof(kNoColorIndexedQuad));
}
if (!fIB[0]) {
@ -255,7 +260,9 @@ private:
std::memcpy(SkTAddOffset<void>(data->writable_data(), kIndexOffset),
kIndices,
sizeof(kIndices));
fIB[0] = SkMesh::MakeIndexBuffer(/*GrDirectContext*=*/nullptr, std::move(data));
fIB[0] = SkMesh::MakeIndexBuffer(/*GrDirectContext*=*/nullptr,
data->data(),
data->size());
}
if (!fIB[1]) {
@ -397,7 +404,7 @@ protected:
SkColor colors[] = {SK_ColorWHITE, SK_ColorTRANSPARENT};
fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kMirror);
fVB = SkMesh::MakeVertexBuffer(nullptr, SkData::MakeWithoutCopy(kQuad, sizeof(kQuad)));
fVB = SkMesh::MakeVertexBuffer(nullptr, kQuad, sizeof(kQuad));
}
SkString onShortName() override { return SkString("custommesh_cs"); }
@ -530,7 +537,7 @@ protected:
2,
SkTileMode::kMirror);
fVB = SkMesh::MakeVertexBuffer(nullptr, SkData::MakeWithoutCopy(kQuad, sizeof(kQuad)));
fVB = SkMesh::MakeVertexBuffer(nullptr, kQuad, sizeof(kQuad));
}
SkString onShortName() override { return SkString("custommesh_uniforms"); }

View File

@ -231,8 +231,15 @@ private:
*/
class SkMesh {
public:
class IndexBuffer : public SkRefCnt {};
class VertexBuffer : public SkRefCnt {};
class IndexBuffer : public SkRefCnt {
public:
virtual size_t size() const = 0;
};
class VertexBuffer : public SkRefCnt {
public:
virtual size_t size() const = 0;
};
SkMesh();
~SkMesh();
@ -244,29 +251,37 @@ public:
SkMesh& operator=(SkMesh&&);
/**
* Makes an index buffer to be used with SkMeshes. The SkData is used to determine the
* size and contents of the buffer. The buffer may be CPU- or GPU-backed depending on whether
* GrDirectContext* is nullptr.
* Makes an index buffer to be used with SkMeshes. The buffer may be CPU- or GPU-backed
* depending on whether GrDirectContext* is nullptr.
*
* @param GrDirectContext* If nullptr a CPU-backed object is returned that owns the SkData.
* Otherwise, the data is uploaded to the GPU and a GPU-backed buffer
* is returned. It may only be used to draw into SkSurfaces that
* are backed by the passed GrDirectContext.
* @param sk_sp<SkData> required. The data used to populate the buffer.
* @param GrDirectContext* If nullptr a CPU-backed object is returned. Otherwise, the data is
* uploaded to the GPU and a GPU-backed buffer is returned. It may
* only be used to draw into SkSurfaces that are backed by the passed
* GrDirectContext.
* @param data required. The data used to populate the buffer.
* @param size Both the size of the data in 'data' and the size of the resulting
* buffer.
*/
static sk_sp<IndexBuffer> MakeIndexBuffer(GrDirectContext*, const void* data, size_t size);
/** Deprecated in favor of const void* and size_t version above. */
static sk_sp<IndexBuffer> MakeIndexBuffer(GrDirectContext*, sk_sp<const SkData>);
/**
* Makes a vertex buffer to be used with SkMeshes. The SkData is used to determine the
* size and contents of the buffer.The buffer may be CPU- or GPU-backed depending on whether
* GrDirectContext* is nullptr.
* Makes a vertex buffer to be used with SkMeshes. The buffer may be CPU- or GPU-backed
* depending on whether GrDirectContext* is nullptr.
*
* @param GrDirectContext* If nullptr a CPU-backed object is returned that owns the SkData.
* Otherwise, the data is uploaded to the GPU and a GPU-backed buffer
* is returned. It may only be used to draw into SkSurfaces that
* are backed by the passed GrDirectContext.
* @param sk_sp<SkData> required. The data used to populate the buffer.
* @param GrDirectContext* If nullptr a CPU-backed object is returned. Otherwise, the data is
* uploaded to the GPU and a GPU-backed buffer is returned. It may
* only be used to draw into SkSurfaces that are backed by the passed
* GrDirectContext.
* @param data required. The data used to populate the buffer.
* @param size Both the size of the data in 'data' and the size of the resulting
* buffer.
*/
static sk_sp<VertexBuffer> MakeVertexBuffer(GrDirectContext*, const void*, size_t size);
/** Deprecated in favor of const void* and size_t version above. */
static sk_sp<VertexBuffer> MakeVertexBuffer(GrDirectContext*, sk_sp<const SkData>);
enum class Mode { kTriangles, kTriangleStrip };

View File

@ -470,15 +470,35 @@ SkMesh::SkMesh(SkMesh&&) = default;
SkMesh& SkMesh::operator=(const SkMesh&) = default;
SkMesh& SkMesh::operator=(SkMesh&&) = default;
sk_sp<IndexBuffer> SkMesh::MakeIndexBuffer(GrDirectContext* dc, sk_sp<const SkData> data) {
sk_sp<IndexBuffer> SkMesh::MakeIndexBuffer(GrDirectContext* dc, const void* data, size_t size) {
if (!data) {
return nullptr;
}
if (!dc) {
return SkMeshPriv::CpuIndexBuffer::Make(std::move(data));
return SkMeshPriv::CpuIndexBuffer::Make(data, size);
}
#if SK_SUPPORT_GPU
return SkMeshPriv::GpuIndexBuffer::Make(dc, std::move(data));
return SkMeshPriv::GpuIndexBuffer::Make(dc, data, size);
#endif
return nullptr;
}
sk_sp<IndexBuffer> SkMesh::MakeIndexBuffer(GrDirectContext* dc, sk_sp<const SkData> data) {
if (!data) {
return nullptr;
}
return MakeIndexBuffer(dc, data->data(), data->size());
}
sk_sp<VertexBuffer> SkMesh::MakeVertexBuffer(GrDirectContext* dc, const void* data, size_t size) {
if (!data) {
return nullptr;
}
if (!dc) {
return SkMeshPriv::CpuVertexBuffer::Make(data, size);
}
#if SK_SUPPORT_GPU
return SkMeshPriv::GpuVertexBuffer::Make(dc, data, size);
#endif
return nullptr;
}
@ -487,13 +507,7 @@ sk_sp<VertexBuffer> SkMesh::MakeVertexBuffer(GrDirectContext* dc, sk_sp<const Sk
if (!data) {
return nullptr;
}
if (!dc) {
return SkMeshPriv::CpuVertexBuffer::Make(std::move(data));
}
#if SK_SUPPORT_GPU
return SkMeshPriv::GpuVertexBuffer::Make(dc, std::move(data));
#endif
return nullptr;
return MakeVertexBuffer(dc, data->data(), data->size());
}
SkMesh SkMesh::Make(sk_sp<SkMeshSpecification> spec,

View File

@ -99,13 +99,11 @@ struct SkMeshPriv {
Buffer& operator=(const Buffer&) = delete;
virtual sk_sp<const SkData> asData() const { return nullptr; }
virtual const void* peek() const { return nullptr; }
#if SK_SUPPORT_GPU
virtual sk_sp<const GrGpuBuffer> asGpuBuffer() const { return nullptr; }
#endif
virtual size_t size() const = 0;
};
class IB : public Buffer, public SkMesh::IndexBuffer {};
@ -113,17 +111,18 @@ struct SkMeshPriv {
template <typename Base> class CpuBuffer final : public Base {
public:
CpuBuffer() = default;
~CpuBuffer() override = default;
static sk_sp<Base> Make(sk_sp<const SkData> data);
static sk_sp<Base> Make(const void* data, size_t size);
sk_sp<const SkData> asData() const override { return fData; }
const void* peek() const override { return fData->data(); }
size_t size() const override { return fData->size(); }
private:
sk_sp<const SkData> fData;
CpuBuffer(sk_sp<SkData> data) : fData(std::move(data)) {}
sk_sp<SkData> fData;
};
using CpuIndexBuffer = CpuBuffer<IB>;
@ -136,7 +135,7 @@ struct SkMeshPriv {
~GpuBuffer() override;
static sk_sp<Base> Make(GrDirectContext*, sk_sp<const SkData>);
static sk_sp<Base> Make(GrDirectContext*, const void* data, size_t size);
sk_sp<const GrGpuBuffer> asGpuBuffer() const override { return fBuffer; }
@ -154,11 +153,11 @@ struct SkMeshPriv {
inline SkMeshPriv::Buffer::~Buffer() = default;
template <typename Base> sk_sp<Base> SkMeshPriv::CpuBuffer<Base>::Make(sk_sp<const SkData> data) {
template <typename Base> sk_sp<Base> SkMeshPriv::CpuBuffer<Base>::Make(const void* data,
size_t size) {
SkASSERT(data);
auto result = new CpuBuffer<Base>;
result->fData = std::move(data);
return sk_sp<Base>(result);
SkASSERT(size);
return sk_sp<Base>(new CpuBuffer<Base>(SkData::MakeWithCopy(data, size)));
}
#if SK_SUPPORT_GPU
@ -167,13 +166,15 @@ template <typename Base, GrGpuBufferType Type> SkMeshPriv::GpuBuffer<Base, Type>
}
template <typename Base, GrGpuBufferType Type>
sk_sp<Base> SkMeshPriv::GpuBuffer<Base, Type>::Make(GrDirectContext* dc,sk_sp<const SkData> data) {
sk_sp<Base> SkMeshPriv::GpuBuffer<Base, Type>::Make(GrDirectContext* dc,
const void* data,
size_t size) {
SkASSERT(dc);
SkASSERT(data);
sk_sp<GrGpuBuffer> buffer = dc->priv().resourceProvider()->createBuffer(
data->data(),
data->size(),
data,
size,
Type,
kStatic_GrAccessPattern);
if (!buffer) {

View File

@ -504,11 +504,11 @@ private:
if (!fMeshData.ib) {
return nullptr;
}
auto data = fMeshData.ib->asData();
auto data = fMeshData.ib->peek();
if (!data) {
return nullptr;
}
return SkTAddOffset<const uint16_t>(data->data(), fMeshData.ioffset);
return SkTAddOffset<const uint16_t>(data, fMeshData.ioffset);
}
int indexCount() const {
@ -609,9 +609,9 @@ void MeshOp::Mesh::writeVertices(skgpu::VertexWriter& writer,
}
}
} else {
sk_sp<const SkData> data = fMeshData.vb->asData();
const void* data = fMeshData.vb->peek();
if (data) {
auto vdata = static_cast<const char*>(data->data()) + fMeshData.voffset;
auto vdata = SkTAddOffset<const char>(data, fMeshData.voffset);
writer << skgpu::VertexWriter::Array(vdata, spec.stride()*fMeshData.vcount);
}
}