aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2014-09-19 11:10:40 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-19 11:10:40 -0700
commitb3e3a955b6628acc540ef14854b57abb089e62df (patch)
tree056b3b34e445396cee310ce15cac25999a2ad4e1
parent87e2437fe574a5ed76caa225c4ff6464641ef64f (diff)
Make GrIODB keep pending IO refs on all resources it records into its cmd stream.
BUG=skia:2889 R=robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/581123002
-rw-r--r--include/gpu/GrGpuResource.h1
-rw-r--r--include/gpu/GrGpuResourceRef.h84
-rw-r--r--src/gpu/GrAllocator.h22
-rw-r--r--src/gpu/GrGpuResourceRef.cpp1
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp174
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h202
6 files changed, 286 insertions, 198 deletions
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h
index 911ee3985b..32f4b9396a 100644
--- a/include/gpu/GrGpuResource.h
+++ b/include/gpu/GrGpuResource.h
@@ -111,6 +111,7 @@ private:
// This class is used to manage conversion of refs to pending reads/writes.
friend class GrGpuResourceRef;
+ template <typename T> friend class GrPendingIOResource;
};
/**
diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h
index 28299f2b11..d178908f93 100644
--- a/include/gpu/GrGpuResourceRef.h
+++ b/include/gpu/GrGpuResourceRef.h
@@ -13,9 +13,25 @@
class GrGpuResource;
/**
+ * This class is intended only for internal use in core Gr code.
+ *
* Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages
- * converting refs to pending io operations. Like SkAutoTUnref, its constructor and setter adopt
- * a ref from their caller. This class is intended only for internal use in core Gr code.
+ * converting refs to pending IO operations. It allows a resource ownership to be in three
+ * states:
+ * 1. Owns a single ref
+ * 2. Owns a single ref and a pending IO operation (read, write, or read-write)
+ * 3. Owns a single pending IO operation.
+ *
+ * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state
+ * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from
+ * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no
+ * valid way of going from state 3 back to 2 or 1.
+ *
+ * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller.
+ *
+ * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no
+ * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef
+ * only settable via the constructor.
*/
class GrGpuResourceRef : SkNoncopyable {
public:
@@ -53,18 +69,19 @@ protected:
private:
/** Called by owning GrProgramElement when the program element is first scheduled for
- execution. */
+ execution. It can only be called once. */
void markPendingIO() const;
/** Called when the program element/draw state is no longer owned by GrDrawTarget-client code.
This lets the cache know that the drawing code will no longer schedule additional reads or
- writes to the resource using the program element or draw state. */
+ writes to the resource using the program element or draw state. It can only be called once.
+ */
void removeRef() const;
/** Called to indicate that the previous pending IO is complete. Useful when the owning object
still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
- pending executions have been complete.
- */
+ pending executions have been complete. Can only be called if removeRef() was not previously
+ called. */
void pendingIOComplete() const;
friend class GrRODrawState;
@@ -78,6 +95,9 @@ private:
typedef SkNoncopyable INHERITED;
};
+/**
+ * Templated version of GrGpuResourceRef to enforce type safety.
+ */
template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
public:
GrTGpuResourceRef() {}
@@ -96,5 +116,57 @@ private:
typedef GrGpuResourceRef INHERITED;
};
+/**
+ * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
+ * ref.
+ */
+template <typename T> class GrPendingIOResource : SkNoncopyable {
+public:
+ typedef GrGpuResourceRef::IOType IOType;
+ GrPendingIOResource(T* resource, IOType ioType) : fResource(resource), fIOType(ioType) {
+ if (NULL != fResource) {
+ switch (fIOType) {
+ case GrGpuResourceRef::kNone_IOType:
+ SkFAIL("GrPendingIOResource with neither reads nor writes?");
+ break;
+ case GrGpuResourceRef::kRead_IOType:
+ fResource->addPendingRead();
+ break;
+ case GrGpuResourceRef::kWrite_IOType:
+ fResource->addPendingWrite();
+ break;
+ case GrGpuResourceRef::kRW_IOType:
+ fResource->addPendingRead();
+ fResource->addPendingWrite();
+ break;
+ }
+ }
+ }
+
+ ~GrPendingIOResource() {
+ if (NULL != fResource) {
+ switch (fIOType) {
+ case GrGpuResourceRef::kNone_IOType:
+ SkFAIL("GrPendingIOResource with neither reads nor writes?");
+ break;
+ case GrGpuResourceRef::kRead_IOType:
+ fResource->completedRead();
+ break;
+ case GrGpuResourceRef::kWrite_IOType:
+ fResource->completedWrite();
+ break;
+ case GrGpuResourceRef::kRW_IOType:
+ fResource->completedRead();
+ fResource->completedWrite();
+ break;
+ }
+ }
+ }
+
+ T* get() const { return fResource; }
+private:
+ T* fResource;
+ IOType fIOType;
+};
#endif
diff --git a/src/gpu/GrAllocator.h b/src/gpu/GrAllocator.h
index fd45e8ad68..861c3cbe2c 100644
--- a/src/gpu/GrAllocator.h
+++ b/src/gpu/GrAllocator.h
@@ -224,8 +224,10 @@ private:
typedef SkNoncopyable INHERITED;
};
-template <typename T>
-class GrTAllocator : SkNoncopyable {
+template <typename T> class GrTAllocator;
+template <typename T> void* operator new(size_t, GrTAllocator<T>*);
+
+template <typename T> class GrTAllocator : SkNoncopyable {
public:
virtual ~GrTAllocator() { this->reset(); };
@@ -360,6 +362,8 @@ protected:
}
private:
+ friend void* operator new<T>(size_t, GrTAllocator*);
+
GrAllocator fAllocator;
typedef SkNoncopyable INHERITED;
};
@@ -377,4 +381,18 @@ private:
SkAlignedSTStorage<N, T> fStorage;
};
+template <typename T> void* operator new(size_t size, GrTAllocator<T>* allocator) {
+ return allocator->fAllocator.push_back();
+}
+
+// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
+// to match the op new silences warnings about missing op delete when a constructor throws an
+// exception.
+template <typename T> void operator delete(void*, GrTAllocator<T>*) {
+ SK_CRASH();
+}
+
+#define GrNEW_APPEND_TO_ALLOCATOR(allocator_ptr, type_name, args) \
+ new (allocator_ptr) type_name args
+
#endif
diff --git a/src/gpu/GrGpuResourceRef.cpp b/src/gpu/GrGpuResourceRef.cpp
index 74b1ef0eba..e2a702ef6d 100644
--- a/src/gpu/GrGpuResourceRef.cpp
+++ b/src/gpu/GrGpuResourceRef.cpp
@@ -93,7 +93,6 @@ void GrGpuResourceRef::markPendingIO() const {
fResource->addPendingRead();
fResource->addPendingWrite();
break;
-
}
}
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 1f2692d576..efbe8611da 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -11,13 +11,8 @@
#include "GrDrawTargetCaps.h"
#include "GrTextStrike.h"
#include "GrGpu.h"
-#include "GrIndexBuffer.h"
-#include "GrPath.h"
-#include "GrPathRange.h"
-#include "GrRenderTarget.h"
#include "GrTemplates.h"
#include "GrTexture.h"
-#include "GrVertexBuffer.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
GrVertexBufferAllocPool* vertexPool,
@@ -239,15 +234,15 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
return 0;
}
- DrawRecord* draw = &fDraws.back();
+ Draw* draw = &fDraws.back();
GeometryPoolState& poolState = fGeoPoolStateStack.back();
const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
if (!draw->isInstanced() ||
draw->verticesPerInstance() != info.verticesPerInstance() ||
draw->indicesPerInstance() != info.indicesPerInstance() ||
- draw->fVertexBuffer != vertexBuffer ||
- draw->fIndexBuffer != geomSrc.fIndexBuffer) {
+ draw->vertexBuffer() != vertexBuffer ||
+ draw->indexBuffer() != geomSrc.fIndexBuffer) {
return 0;
}
// info does not yet account for the offset from the start of the pool's VB while the previous
@@ -319,68 +314,47 @@ void GrInOrderDrawBuffer::onDraw(const DrawInfo& info) {
}
this->recordStateIfNecessary();
- DrawRecord* draw;
- if (info.isInstanced()) {
- int instancesConcated = this->concatInstancedDraw(info);
- if (info.instanceCount() > instancesConcated) {
- draw = this->recordDraw(info);
- draw->adjustInstanceCount(-instancesConcated);
- } else {
- return;
- }
+ const GrVertexBuffer* vb;
+ if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
+ vb = this->getGeomSrc().fVertexBuffer;
} else {
- draw = this->recordDraw(info);
+ vb = poolState.fPoolVertexBuffer;
}
- switch (this->getGeomSrc().fVertexSrc) {
- case kBuffer_GeometrySrcType:
- draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
- break;
- case kReserved_GeometrySrcType: // fallthrough
- case kArray_GeometrySrcType: {
- size_t vertexBytes = (info.vertexCount() + info.startVertex()) *
- drawState.getVertexStride();
- poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
- draw->fVertexBuffer = poolState.fPoolVertexBuffer;
- draw->adjustStartVertex(poolState.fPoolStartVertex);
- break;
+ const GrIndexBuffer* ib = NULL;
+ if (info.isIndexed()) {
+ if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
+ ib = this->getGeomSrc().fIndexBuffer;
+ } else {
+ ib = poolState.fPoolIndexBuffer;
}
- default:
- SkFAIL("unknown geom src type");
}
- draw->fVertexBuffer->ref();
- if (info.isIndexed()) {
- switch (this->getGeomSrc().fIndexSrc) {
- case kBuffer_GeometrySrcType:
- draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
- break;
- case kReserved_GeometrySrcType: // fallthrough
- case kArray_GeometrySrcType: {
- size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
- poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, indexBytes);
- draw->fIndexBuffer = poolState.fPoolIndexBuffer;
- draw->adjustStartIndex(poolState.fPoolStartIndex);
- break;
- }
- default:
- SkFAIL("unknown geom src type");
+ Draw* draw;
+ if (info.isInstanced()) {
+ int instancesConcated = this->concatInstancedDraw(info);
+ if (info.instanceCount() > instancesConcated) {
+ draw = this->recordDraw(info, vb, ib);
+ draw->adjustInstanceCount(-instancesConcated);
+ } else {
+ return;
}
- draw->fIndexBuffer->ref();
} else {
- draw->fIndexBuffer = NULL;
+ draw = this->recordDraw(info, vb, ib);
}
-}
-GrInOrderDrawBuffer::StencilPath::StencilPath() {}
-GrInOrderDrawBuffer::DrawPath::DrawPath() {}
-GrInOrderDrawBuffer::DrawPaths::DrawPaths() {}
-GrInOrderDrawBuffer::DrawPaths::~DrawPaths() {
- if (fTransforms) {
- SkDELETE_ARRAY(fTransforms);
+ // Adjust the starting vertex and index when we are using reserved or array sources to
+ // compensate for the fact that the data was inserted into a larger vb/ib owned by the pool.
+ if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
+ size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.getVertexStride();
+ poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
+ draw->adjustStartVertex(poolState.fPoolStartVertex);
}
- if (fIndices) {
- SkDELETE_ARRAY(fIndices);
+
+ if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndexSrc) {
+ size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
+ poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, bytes);
+ draw->adjustStartIndex(poolState.fPoolStartIndex);
}
}
@@ -390,9 +364,7 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
}
// Only compare the subset of GrDrawState relevant to path stenciling?
this->recordStateIfNecessary();
- StencilPath* sp = this->recordStencilPath();
- sp->fPath.reset(path);
- path->ref();
+ StencilPath* sp = this->recordStencilPath(path);
sp->fFill = fill;
}
@@ -403,9 +375,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
}
// TODO: Only compare the subset of GrDrawState relevant to path covering?
this->recordStateIfNecessary();
- DrawPath* cp = this->recordDrawPath();
- cp->fPath.reset(path);
- path->ref();
+ DrawPath* cp = this->recordDrawPath(path);
cp->fFill = fill;
if (dstCopy) {
cp->fDstCopy = *dstCopy;
@@ -424,8 +394,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
this->recordClip();
}
this->recordStateIfNecessary();
- DrawPaths* dp = this->recordDrawPaths();
- dp->fPathRange.reset(SkRef(pathRange));
+ DrawPaths* dp = this->recordDrawPaths(pathRange);
dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this without a malloc
memcpy(dp->fIndices, indices, sizeof(uint32_t) * count);
dp->fCount = count;
@@ -456,13 +425,11 @@ void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color,
r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
rect = &r;
}
- Clear* clr = this->recordClear();
+ Clear* clr = this->recordClear(renderTarget);
GrColorIsPMAssert(color);
clr->fColor = color;
clr->fRect = *rect;
clr->fCanIgnoreRect = canIgnoreRect;
- clr->fRenderTarget = renderTarget;
- renderTarget->ref();
}
void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
@@ -473,10 +440,8 @@ void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
renderTarget = this->drawState()->getRenderTarget();
SkASSERT(renderTarget);
}
- Clear* clr = this->recordClear();
+ Clear* clr = this->recordClear(renderTarget);
clr->fColor = GrColor_ILLEGAL;
- clr->fRenderTarget = renderTarget;
- renderTarget->ref();
}
void GrInOrderDrawBuffer::reset() {
@@ -484,13 +449,6 @@ void GrInOrderDrawBuffer::reset() {
this->resetVertexSource();
this->resetIndexSource();
- DrawAllocator::Iter drawIter(&fDraws);
- while (drawIter.next()) {
- // we always have a VB, but not always an IB
- SkASSERT(drawIter->fVertexBuffer);
- drawIter->fVertexBuffer->unref();
- SkSafeUnref(drawIter->fIndexBuffer);
- }
fCmds.reset();
fDraws.reset();
fStencilPaths.reset();
@@ -559,9 +517,9 @@ void GrInOrderDrawBuffer::flush() {
case kDraw_Cmd: {
SkASSERT(fDstGpu->drawState() != prevDrawState);
SkAssertResult(drawIter.next());
- fDstGpu->setVertexSourceToBuffer(drawIter->fVertexBuffer);
+ fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer());
if (drawIter->isIndexed()) {
- fDstGpu->setIndexSourceToBuffer(drawIter->fIndexBuffer);
+ fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer());
}
fDstGpu->executeDraw(*drawIter);
break;
@@ -569,13 +527,13 @@ void GrInOrderDrawBuffer::flush() {
case kStencilPath_Cmd: {
SkASSERT(fDstGpu->drawState() != prevDrawState);
SkAssertResult(stencilPathIter.next());
- fDstGpu->stencilPath(stencilPathIter->fPath.get(), stencilPathIter->fFill);
+ fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->fFill);
break;
}
case kDrawPath_Cmd: {
SkASSERT(fDstGpu->drawState() != prevDrawState);
SkAssertResult(drawPathIter.next());
- fDstGpu->executeDrawPath(drawPathIter->fPath.get(), drawPathIter->fFill,
+ fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFill,
drawPathIter->fDstCopy.texture() ?
&drawPathIter->fDstCopy :
NULL);
@@ -586,7 +544,7 @@ void GrInOrderDrawBuffer::flush() {
SkAssertResult(drawPathsIter.next());
const GrDeviceCoordTexture* dstCopy =
drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy : NULL;
- fDstGpu->executeDrawPaths(drawPathsIter->fPathRange.get(),
+ fDstGpu->executeDrawPaths(drawPathsIter->pathRange(),
drawPathsIter->fIndices,
drawPathsIter->fCount,
drawPathsIter->fTransforms,
@@ -608,18 +566,18 @@ void GrInOrderDrawBuffer::flush() {
case kClear_Cmd:
SkAssertResult(clearIter.next());
if (GrColor_ILLEGAL == clearIter->fColor) {
- fDstGpu->discard(clearIter->fRenderTarget);
+ fDstGpu->discard(clearIter->renderTarget());
} else {
fDstGpu->clear(&clearIter->fRect,
clearIter->fColor,
clearIter->fCanIgnoreRect,
- clearIter->fRenderTarget);
+ clearIter->renderTarget());
}
break;
case kCopySurface_Cmd:
SkAssertResult(copySurfaceIter.next());
- fDstGpu->copySurface(copySurfaceIter->fDst.get(),
- copySurfaceIter->fSrc.get(),
+ fDstGpu->copySurface(copySurfaceIter->dst(),
+ copySurfaceIter->src(),
copySurfaceIter->fSrcRect,
copySurfaceIter->fDstPoint);
break;
@@ -652,9 +610,7 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
- CopySurface* cs = this->recordCopySurface();
- cs->fDst.reset(SkRef(dst));
- cs->fSrc.reset(SkRef(src));
+ CopySurface* cs = this->recordCopySurface(dst, src);
cs->fSrcRect = srcRect;
cs->fDstPoint = dstPoint;
return true;
@@ -805,9 +761,7 @@ void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
poolState.fPoolStartIndex = 0;
}
-void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
- int vertexCount) {
-
+void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
GeometryPoolState& poolState = fGeoPoolStateStack.back();
SkASSERT(0 == poolState.fUsedPoolVertexBytes);
#ifdef SK_DEBUG
@@ -859,8 +813,7 @@ void GrInOrderDrawBuffer::geometrySourceWillPush() {
#endif
}
-void GrInOrderDrawBuffer::geometrySourceWillPop(
- const GeometrySrcState& restoredState) {
+void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restoredState) {
SkASSERT(fGeoPoolStateStack.count() > 1);
fGeoPoolStateStack.pop_back();
GeometryPoolState& poolState = fGeoPoolStateStack.back();
@@ -934,34 +887,37 @@ void GrInOrderDrawBuffer::recordClip() {
this->addToCmdBuffer(kSetClip_Cmd);
}
-GrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) {
+GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info,
+ const GrVertexBuffer* vb,
+ const GrIndexBuffer* ib) {
this->addToCmdBuffer(kDraw_Cmd);
- return &fDraws.push_back(info);
+ return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib));
}
-GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
+GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const GrPath* path) {
this->addToCmdBuffer(kStencilPath_Cmd);
- return &fStencilPaths.push_back();
+ return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path));
}
-GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath() {
+GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath* path) {
this->addToCmdBuffer(kDrawPath_Cmd);
- return &fDrawPath.push_back();
+ return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path));
}
-GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths() {
+GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPathRange* pathRange) {
this->addToCmdBuffer(kDrawPaths_Cmd);
- return &fDrawPaths.push_back();
+ return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange));
}
-GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
+GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt) {
this->addToCmdBuffer(kClear_Cmd);
- return &fClears.push_back();
+ return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt));
}
-GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface() {
+GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurface* dst,
+ GrSurface* src) {
this->addToCmdBuffer(kCopySurface_Cmd);
- return &fCopySurfaces.push_back();
+ return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src));
}
void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 491da5dbfb..532b83f1d1 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -11,7 +11,12 @@
#include "GrDrawTarget.h"
#include "GrAllocPool.h"
#include "GrAllocator.h"
+#include "GrIndexBuffer.h"
+#include "GrRenderTarget.h"
#include "GrPath.h"
+#include "GrPathRange.h"
+#include "GrSurface.h"
+#include "GrVertexBuffer.h"
#include "SkClipStack.h"
#include "SkTemplates.h"
@@ -19,7 +24,6 @@
class GrGpu;
class GrIndexBufferAllocPool;
-class GrPathRange;
class GrVertexBufferAllocPool;
/**
@@ -94,57 +98,98 @@ private:
kDrawPaths_Cmd = 8,
};
- class DrawRecord : public DrawInfo {
+ class Draw : public DrawInfo {
public:
- DrawRecord(const DrawInfo& info) : DrawInfo(info) {}
- const GrVertexBuffer* fVertexBuffer;
- const GrIndexBuffer* fIndexBuffer;
+ Draw(const DrawInfo& info, const GrVertexBuffer* vb, const GrIndexBuffer* ib)
+ : DrawInfo(info)
+ , fVertexBuffer(vb, GrGpuResourceRef::kRead_IOType)
+ , fIndexBuffer(ib, GrGpuResourceRef::kRead_IOType) {}
+
+ const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
+ const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
+
+ private:
+ GrPendingIOResource<const GrVertexBuffer> fVertexBuffer;
+ GrPendingIOResource<const GrIndexBuffer> fIndexBuffer;
};
struct StencilPath : public ::SkNoncopyable {
- StencilPath();
+ StencilPath(const GrPath* path) : fPath(path, GrGpuResourceRef::kRead_IOType) {}
+
+ const GrPath* path() const { return fPath.get(); }
- SkAutoTUnref<const GrPath> fPath;
- SkPath::FillType fFill;
+ SkPath::FillType fFill;
+
+ private:
+ GrPendingIOResource<const GrPath> fPath;
};
struct DrawPath : public ::SkNoncopyable {
- DrawPath();
+ DrawPath(const GrPath* path) : fPath(path, GrGpuResourceRef::kRead_IOType) {}
+
+ const GrPath* path() const { return fPath.get(); }
- SkAutoTUnref<const GrPath> fPath;
- SkPath::FillType fFill;
- GrDeviceCoordTexture fDstCopy;
+ SkPath::FillType fFill;
+ GrDeviceCoordTexture fDstCopy;
+
+ private:
+ GrPendingIOResource<const GrPath> fPath;
};
struct DrawPaths : public ::SkNoncopyable {
- DrawPaths();
- ~DrawPaths();
-
- SkAutoTUnref<const GrPathRange> fPathRange;
- uint32_t* fIndices;
- size_t fCount;
- float* fTransforms;
- PathTransformType fTransformsType;
- SkPath::FillType fFill;
- GrDeviceCoordTexture fDstCopy;
+ DrawPaths(const GrPathRange* pathRange)
+ : fPathRange(pathRange, GrGpuResourceRef::kRead_IOType) {}
+
+ ~DrawPaths() {
+ if (fTransforms) {
+ SkDELETE_ARRAY(fTransforms);
+ }
+ if (fIndices) {
+ SkDELETE_ARRAY(fIndices);
+ }
+ }
+
+ const GrPathRange* pathRange() const { return fPathRange.get(); }
+
+ uint32_t* fIndices;
+ size_t fCount;
+ float* fTransforms;
+ PathTransformType fTransformsType;
+ SkPath::FillType fFill;
+ GrDeviceCoordTexture fDstCopy;
+
+ private:
+ GrPendingIOResource<const GrPathRange> fPathRange;
};
// This is also used to record a discard by setting the color to GrColor_ILLEGAL
struct Clear : public ::SkNoncopyable {
- Clear() : fRenderTarget(NULL) {}
- ~Clear() { SkSafeUnref(fRenderTarget); }
+ Clear(GrRenderTarget* rt) : fRenderTarget(rt, GrGpuResourceRef::kWrite_IOType) {}
+ ~Clear() { }
+ GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
+
+ SkIRect fRect;
+ GrColor fColor;
+ bool fCanIgnoreRect;
- SkIRect fRect;
- GrColor fColor;
- bool fCanIgnoreRect;
- GrRenderTarget* fRenderTarget;
+ private:
+ GrPendingIOResource<GrRenderTarget> fRenderTarget;
};
struct CopySurface : public ::SkNoncopyable {
- SkAutoTUnref<GrSurface> fDst;
- SkAutoTUnref<GrSurface> fSrc;
- SkIRect fSrcRect;
- SkIPoint fDstPoint;
+ CopySurface(GrSurface* dst, GrSurface* src)
+ : fDst(dst, GrGpuResourceRef::kWrite_IOType)
+ , fSrc(src, GrGpuResourceRef::kRead_IOType) {}
+
+ GrSurface* dst() const { return fDst.get(); }
+ GrSurface* src() const { return fSrc.get(); }
+
+ SkIPoint fDstPoint;
+ SkIRect fSrcRect;
+
+ private:
+ GrPendingIOResource<GrSurface> fDst;
+ GrPendingIOResource<GrSurface> fSrc;
};
struct Clip : public ::SkNoncopyable {
@@ -209,12 +254,15 @@ private:
// these functions record a command
void recordState();
void recordClip();
- DrawRecord* recordDraw(const DrawInfo&);
- StencilPath* recordStencilPath();
- DrawPath* recordDrawPath();
- DrawPaths* recordDrawPaths();
- Clear* recordClear();
- CopySurface* recordCopySurface();
+ Draw* recordDraw(const DrawInfo&, const GrVertexBuffer*, const GrIndexBuffer*);
+ StencilPath* recordStencilPath(const GrPath*);
+ DrawPath* recordDrawPath(const GrPath*);
+ DrawPaths* recordDrawPaths(const GrPathRange*);
+ Clear* recordClear(GrRenderTarget*);
+ CopySurface* recordCopySurface(GrSurface* dst, GrSurface* src);
+
+ virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
+ void addToCmdBuffer(uint8_t cmd);
// TODO: Use a single allocator for commands and records
enum {
@@ -230,63 +278,57 @@ private:
kCopySurfacePreallocCnt = 4,
};
- typedef GrTAllocator<DrawRecord> DrawAllocator;
- typedef GrTAllocator<StencilPath> StencilPathAllocator;
- typedef GrTAllocator<DrawPath> DrawPathAllocator;
- typedef GrTAllocator<DrawPaths> DrawPathsAllocator;
- typedef GrTAllocator<GrDrawState> StateAllocator;
- typedef GrTAllocator<Clear> ClearAllocator;
- typedef GrTAllocator<CopySurface> CopySurfaceAllocator;
- typedef GrTAllocator<Clip> ClipAllocator;
-
- GrSTAllocator<kDrawPreallocCnt, DrawRecord> fDraws;
- GrSTAllocator<kStencilPathPreallocCnt, StencilPath> fStencilPaths;
- GrSTAllocator<kDrawPathPreallocCnt, DrawPath> fDrawPath;
- GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths> fDrawPaths;
- GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
- GrSTAllocator<kClearPreallocCnt, Clear> fClears;
- GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces;
- GrSTAllocator<kClipPreallocCnt, Clip> fClips;
-
- SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
-
- SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
-
- GrDrawTarget* fDstGpu;
-
- bool fClipSet;
+ typedef GrTAllocator<Draw> DrawAllocator;
+ typedef GrTAllocator<StencilPath> StencilPathAllocator;
+ typedef GrTAllocator<DrawPath> DrawPathAllocator;
+ typedef GrTAllocator<DrawPaths> DrawPathsAllocator;
+ typedef GrTAllocator<GrDrawState> StateAllocator;
+ typedef GrTAllocator<Clear> ClearAllocator;
+ typedef GrTAllocator<CopySurface> CopySurfaceAllocator;
+ typedef GrTAllocator<Clip> ClipAllocator;
+
+ GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
+ GrSTAllocator<kStencilPathPreallocCnt, StencilPath> fStencilPaths;
+ GrSTAllocator<kDrawPathPreallocCnt, DrawPath> fDrawPath;
+ GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths> fDrawPaths;
+ GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
+ GrSTAllocator<kClearPreallocCnt, Clear> fClears;
+ GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces;
+ GrSTAllocator<kClipPreallocCnt, Clip> fClips;
+
+ SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
+ SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
+ GrDrawTarget* fDstGpu;
+ bool fClipSet;
enum ClipProxyState {
kUnknown_ClipProxyState,
kValid_ClipProxyState,
kInvalid_ClipProxyState
};
- ClipProxyState fClipProxyState;
- SkRect fClipProxy;
-
- GrVertexBufferAllocPool& fVertexPool;
- GrIndexBufferAllocPool& fIndexPool;
+ ClipProxyState fClipProxyState;
+ SkRect fClipProxy;
+ GrVertexBufferAllocPool& fVertexPool;
+ GrIndexBufferAllocPool& fIndexPool;
struct GeometryPoolState {
- const GrVertexBuffer* fPoolVertexBuffer;
- int fPoolStartVertex;
- const GrIndexBuffer* fPoolIndexBuffer;
- int fPoolStartIndex;
+ const GrVertexBuffer* fPoolVertexBuffer;
+ int fPoolStartVertex;
+ const GrIndexBuffer* fPoolIndexBuffer;
+ int fPoolStartIndex;
// caller may conservatively over reserve vertices / indices.
// we release unused space back to allocator if possible
// can only do this if there isn't an intervening pushGeometrySource()
- size_t fUsedPoolVertexBytes;
- size_t fUsedPoolIndexBytes;
+ size_t fUsedPoolVertexBytes;
+ size_t fUsedPoolIndexBytes;
};
- SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
- virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
-
- void addToCmdBuffer(uint8_t cmd);
+ typedef SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> GeoPoolStateStack;
- bool fFlushing;
- uint32_t fDrawID;
+ GeoPoolStateStack fGeoPoolStateStack;
+ bool fFlushing;
+ uint32_t fDrawID;
typedef GrDrawTarget INHERITED;
};