Skip to content

Commit

Permalink
Move GrTessellator::VertexAllocator to GrEagerVertexAllocator
Browse files Browse the repository at this point in the history
Moves the interface up to Ganesh level and starts using it from other
locations.

Change-Id: I939d2b357d3ae8551976d0d71b877b72da403712
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/266063
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
  • Loading branch information
csmartdalton86 authored and Skia Commit-Bot committed Jan 23, 2020
1 parent 1a496c5 commit d081dce
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 140 deletions.
1 change: 1 addition & 0 deletions gn/gpu.gni
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ skia_gpu_sources = [
"$_src/gpu/GrDrawOpTest.cpp",
"$_src/gpu/GrDrawOpTest.h",
"$_src/gpu/GrDriverBugWorkarounds.cpp",
"$_src/gpu/GrEagerVertexAllocator.h",
"$_src/gpu/GrFixedClip.cpp",
"$_src/gpu/GrFixedClip.h",
"$_src/gpu/GrFragmentProcessor.cpp",
Expand Down
84 changes: 84 additions & 0 deletions src/gpu/GrEagerVertexAllocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2020 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#ifndef GrEagerVertexAllocator_DEFINED
#define GrEagerVertexAllocator_DEFINED

#include "src/gpu/ops/GrMeshDrawOp.h"

// This interface is used to allocate and map GPU vertex data before the exact number of required
// vertices is known. Usage pattern:
//
// 1. Call lock(eagerCount) with an upper bound on the number of required vertices.
// 2. Compute and write vertex data to the returned pointer (if not null).
// 3. Call unlock(actualCount) and provide the actual number of vertices written during step #2.
//
// On step #3, the implementation will attempt to shrink the underlying GPU memory slot to fit the
// actual vertex count.
class GrEagerVertexAllocator {
public:
template<typename T> T* lock(int eagerCount) {
return static_cast<T*>(this->lock(sizeof(T), eagerCount));
}
virtual void* lock(size_t stride, int eagerCount) = 0;

virtual void unlock(int actualCount) = 0;

virtual ~GrEagerVertexAllocator() {}
};

// GrEagerVertexAllocator implementation that uses GrMeshDrawOp::Target::makeVertexSpace and
// GrMeshDrawOp::Target::putBackVertices.
class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator {
public:
GrEagerDynamicVertexAllocator(GrMeshDrawOp::Target* target,
sk_sp<const GrBuffer>* vertexBuffer, int* baseVertex)
: fTarget(target)
, fVertexBuffer(vertexBuffer)
, fBaseVertex(baseVertex) {
}

#ifdef SK_DEBUG
~GrEagerDynamicVertexAllocator() override {
SkASSERT(!fLockCount);
}
#endif

void* lock(size_t stride, int eagerCount) override {
SkASSERT(!fLockCount);
SkASSERT(eagerCount);
if (void* data = fTarget->makeVertexSpace(stride, eagerCount, fVertexBuffer, fBaseVertex)) {
fLockStride = stride;
fLockCount = eagerCount;
return data;
}
fVertexBuffer->reset();
*fBaseVertex = 0;
return nullptr;
}

void unlock(int actualCount) override {
SkASSERT(fLockCount);
SkASSERT(actualCount <= fLockCount);
fTarget->putBackVertices(fLockCount - actualCount, fLockStride);
if (!actualCount) {
fVertexBuffer->reset();
*fBaseVertex = 0;
}
fLockCount = 0;
}

private:
GrMeshDrawOp::Target* const fTarget;
sk_sp<const GrBuffer>* const fVertexBuffer;
int* const fBaseVertex;

size_t fLockStride;
int fLockCount = 0;
};

#endif
8 changes: 5 additions & 3 deletions src/gpu/GrTessellator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "src/gpu/GrTessellator.h"

#include "src/gpu/GrDefaultGeoProcFactory.h"
#include "src/gpu/GrEagerVertexAllocator.h"
#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/geometry/GrPathUtils.h"

Expand Down Expand Up @@ -2358,7 +2359,7 @@ namespace GrTessellator {
// Stage 6: Triangulate the monotone polygons into a vertex buffer.

int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
VertexAllocator* vertexAllocator, bool antialias, bool* isLinear) {
GrEagerVertexAllocator* vertexAllocator, bool antialias, bool* isLinear) {
int contourCnt = get_contour_count(path, tolerance);
if (contourCnt <= 0) {
*isLinear = true;
Expand All @@ -2378,7 +2379,8 @@ int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBo
}
int count = count64;

void* verts = vertexAllocator->lock(count);
size_t vertexStride = GetVertexStride(antialias);
void* verts = vertexAllocator->lock(vertexStride, count);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return 0;
Expand All @@ -2389,7 +2391,7 @@ int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBo
end = outer_mesh_to_triangles(outerMesh, true, end);

int actualCount = static_cast<int>((static_cast<uint8_t*>(end) - static_cast<uint8_t*>(verts))
/ vertexAllocator->stride());
/ vertexStride);
SkASSERT(actualCount <= count);
vertexAllocator->unlock(actualCount);
return actualCount;
Expand Down
18 changes: 6 additions & 12 deletions src/gpu/GrTessellator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "include/private/SkColorData.h"
#include "src/gpu/GrColor.h"

class GrEagerVertexAllocator;
class SkPath;
struct SkRect;

Expand All @@ -23,17 +24,6 @@ struct SkRect;

namespace GrTessellator {

class VertexAllocator {
public:
VertexAllocator(size_t stride) : fStride(stride) {}
virtual ~VertexAllocator() {}
virtual void* lock(int vertexCount) = 0;
virtual void unlock(int actualCount) = 0;
size_t stride() const { return fStride; }
private:
size_t fStride;
};

struct WindingVertex {
SkPoint fPos;
int fWinding;
Expand All @@ -46,8 +36,12 @@ struct WindingVertex {
int PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
WindingVertex** verts);

constexpr size_t GetVertexStride(bool antialias) {
return sizeof(SkPoint) + ((antialias) ? sizeof(float) : 0);
}

int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds,
VertexAllocator*, bool antialias, bool *isLinear);
GrEagerVertexAllocator*, bool antialias, bool *isLinear);
}

#endif
73 changes: 29 additions & 44 deletions src/gpu/ops/GrTessellatingPathRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "src/gpu/GrClip.h"
#include "src/gpu/GrDefaultGeoProcFactory.h"
#include "src/gpu/GrDrawOpTest.h"
#include "src/gpu/GrEagerVertexAllocator.h"
#include "src/gpu/GrMesh.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrResourceCache.h"
Expand Down Expand Up @@ -68,16 +69,22 @@ bool cache_match(GrGpuBuffer* vertexBuffer, SkScalar tol, int* actualCount) {
return false;
}

class StaticVertexAllocator : public GrTessellator::VertexAllocator {
class StaticVertexAllocator : public GrEagerVertexAllocator {
public:
StaticVertexAllocator(size_t stride, GrResourceProvider* resourceProvider, bool canMapVB)
: VertexAllocator(stride)
, fResourceProvider(resourceProvider)
StaticVertexAllocator(GrResourceProvider* resourceProvider, bool canMapVB)
: fResourceProvider(resourceProvider)
, fCanMapVB(canMapVB)
, fVertices(nullptr) {
}
void* lock(int vertexCount) override {
size_t size = vertexCount * stride();
#ifdef SK_DEBUG
~StaticVertexAllocator() override {
SkASSERT(!fLockStride);
}
#endif
void* lock(size_t stride, int eagerCount) override {
SkASSERT(!fLockStride);
SkASSERT(stride);
size_t size = eagerCount * stride;
fVertexBuffer = fResourceProvider->createBuffer(size, GrGpuBufferType::kVertex,
kStatic_GrAccessPattern);
if (!fVertexBuffer.get()) {
Expand All @@ -86,18 +93,21 @@ class StaticVertexAllocator : public GrTessellator::VertexAllocator {
if (fCanMapVB) {
fVertices = fVertexBuffer->map();
} else {
fVertices = sk_malloc_throw(vertexCount * stride());
fVertices = sk_malloc_throw(eagerCount * stride);
}
fLockStride = stride;
return fVertices;
}
void unlock(int actualCount) override {
SkASSERT(fLockStride);
if (fCanMapVB) {
fVertexBuffer->unmap();
} else {
fVertexBuffer->updateData(fVertices, actualCount * stride());
fVertexBuffer->updateData(fVertices, actualCount * fLockStride);
sk_free(fVertices);
}
fVertices = nullptr;
fLockStride = 0;
}
sk_sp<GrGpuBuffer> detachVertexBuffer() { return std::move(fVertexBuffer); }

Expand All @@ -106,33 +116,7 @@ class StaticVertexAllocator : public GrTessellator::VertexAllocator {
GrResourceProvider* fResourceProvider;
bool fCanMapVB;
void* fVertices;
};

class DynamicVertexAllocator : public GrTessellator::VertexAllocator {
public:
DynamicVertexAllocator(size_t stride, GrMeshDrawOp::Target* target)
: VertexAllocator(stride)
, fTarget(target)
, fVertexBuffer(nullptr)
, fVertices(nullptr) {}
void* lock(int vertexCount) override {
fVertexCount = vertexCount;
fVertices = fTarget->makeVertexSpace(stride(), vertexCount, &fVertexBuffer, &fFirstVertex);
return fVertices;
}
void unlock(int actualCount) override {
fTarget->putBackVertices(fVertexCount - actualCount, stride());
fVertices = nullptr;
}
sk_sp<const GrBuffer> detachVertexBuffer() const { return std::move(fVertexBuffer); }
int firstVertex() const { return fFirstVertex; }

private:
GrMeshDrawOp::Target* fTarget;
sk_sp<const GrBuffer> fVertexBuffer;
int fVertexCount;
int fFirstVertex;
void* fVertices;
size_t fLockStride = 0;
};

} // namespace
Expand Down Expand Up @@ -255,7 +239,7 @@ class TessellatingPathOp final : public GrMeshDrawOp {
return path;
}

void draw(Target* target, const GrGeometryProcessor* gp, size_t vertexStride) {
void draw(Target* target, const GrGeometryProcessor* gp) {
SkASSERT(!fAntiAlias);
GrResourceProvider* rp = target->resourceProvider();
bool inverseFill = fShape.inverseFilled();
Expand Down Expand Up @@ -292,7 +276,7 @@ class TessellatingPathOp final : public GrMeshDrawOp {
vmi.mapRect(&clipBounds);
bool isLinear;
bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags();
StaticVertexAllocator allocator(vertexStride, rp, canMapVB);
StaticVertexAllocator allocator(rp, canMapVB);
int count = GrTessellator::PathToTriangles(getPath(), tol, clipBounds, &allocator, false,
&isLinear);
if (count == 0) {
Expand All @@ -309,7 +293,7 @@ class TessellatingPathOp final : public GrMeshDrawOp {
this->drawVertices(target, gp, std::move(vb), 0, count);
}

void drawAA(Target* target, const GrGeometryProcessor* gp, size_t vertexStride) {
void drawAA(Target* target, const GrGeometryProcessor* gp) {
SkASSERT(fAntiAlias);
SkPath path = getPath();
if (path.isEmpty()) {
Expand All @@ -318,15 +302,16 @@ class TessellatingPathOp final : public GrMeshDrawOp {
SkRect clipBounds = SkRect::Make(fDevClipBounds);
path.transform(fViewMatrix);
SkScalar tol = GrPathUtils::kDefaultTolerance;
sk_sp<const GrBuffer> vertexBuffer;
int firstVertex;
bool isLinear;
DynamicVertexAllocator allocator(vertexStride, target);
GrEagerDynamicVertexAllocator allocator(target, &vertexBuffer, &firstVertex);
int count = GrTessellator::PathToTriangles(path, tol, clipBounds, &allocator, true,
&isLinear);
if (count == 0) {
return;
}
this->drawVertices(target, gp, allocator.detachVertexBuffer(),
allocator.firstVertex(), count);
this->drawVertices(target, gp, std::move(vertexBuffer), firstVertex, count);
}

void onPrepareDraws(Target* target) override {
Expand Down Expand Up @@ -362,11 +347,11 @@ class TessellatingPathOp final : public GrMeshDrawOp {
if (!gp) {
return;
}
size_t vertexStride = gp->vertexStride();
SkASSERT(GrTessellator::GetVertexStride(fAntiAlias) == gp->vertexStride());
if (fAntiAlias) {
this->drawAA(target, gp, vertexStride);
this->drawAA(target, gp);
} else {
this->draw(target, gp, vertexStride);
this->draw(target, gp);
}
}

Expand Down
Loading

0 comments on commit d081dce

Please sign in to comment.