void GrContext::freeGpuResources() {
this->flush();
- fGpu->purgeResources();
if (fDrawBuffer) {
fDrawBuffer->purgeResources();
}
class GrVertexBuffer;
class GrDrawTarget : public SkRefCnt {
-protected:
- class DrawInfo;
-
public:
SK_DECLARE_INST_COUNT(GrDrawTarget)
*/
virtual void purgeResources() {};
+ class DrawInfo;
/**
* For subclass internal use to invoke a call to onDraw(). See DrawInfo below.
*/
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
+ /**
+ * Used to communicate draws to GPUs / subclasses
+ */
+ class DrawInfo {
+ public:
+ DrawInfo(const DrawInfo& di) { (*this) = di; }
+ DrawInfo& operator =(const DrawInfo& di);
+
+ GrPrimitiveType primitiveType() const { return fPrimitiveType; }
+ int startVertex() const { return fStartVertex; }
+ int startIndex() const { return fStartIndex; }
+ int vertexCount() const { return fVertexCount; }
+ int indexCount() const { return fIndexCount; }
+ int verticesPerInstance() const { return fVerticesPerInstance; }
+ int indicesPerInstance() const { return fIndicesPerInstance; }
+ int instanceCount() const { return fInstanceCount; }
+
+ bool isIndexed() const { return fIndexCount > 0; }
+#ifdef SK_DEBUG
+ bool isInstanced() const; // this version is longer because of asserts
+#else
+ bool isInstanced() const { return fInstanceCount > 0; }
+#endif
+
+ // adds or remove instances
+ void adjustInstanceCount(int instanceOffset);
+ // shifts the start vertex
+ void adjustStartVertex(int vertexOffset);
+ // shifts the start index
+ void adjustStartIndex(int indexOffset);
+
+ void setDevBounds(const SkRect& bounds) {
+ fDevBoundsStorage = bounds;
+ fDevBounds = &fDevBoundsStorage;
+ }
+ const SkRect* getDevBounds() const { return fDevBounds; }
+
+ // NULL if no copy of the dst is needed for the draw.
+ const GrDeviceCoordTexture* getDstCopy() const {
+ if (fDstCopy.texture()) {
+ return &fDstCopy;
+ } else {
+ return NULL;
+ }
+ }
+
+ private:
+ DrawInfo() { fDevBounds = NULL; }
+
+ friend class GrDrawTarget;
+
+ GrPrimitiveType fPrimitiveType;
+
+ int fStartVertex;
+ int fStartIndex;
+ int fVertexCount;
+ int fIndexCount;
+
+ int fInstanceCount;
+ int fVerticesPerInstance;
+ int fIndicesPerInstance;
+
+ SkRect fDevBoundsStorage;
+ SkRect* fDevBounds;
+
+ GrDeviceCoordTexture fDstCopy;
+ };
bool programUnitTest(int maxStages);
const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }
- /**
- * Used to communicate draws to subclass's onDraw function.
- */
- class DrawInfo {
- public:
- DrawInfo(const DrawInfo& di) { (*this) = di; }
- DrawInfo& operator =(const DrawInfo& di);
-
- GrPrimitiveType primitiveType() const { return fPrimitiveType; }
- int startVertex() const { return fStartVertex; }
- int startIndex() const { return fStartIndex; }
- int vertexCount() const { return fVertexCount; }
- int indexCount() const { return fIndexCount; }
- int verticesPerInstance() const { return fVerticesPerInstance; }
- int indicesPerInstance() const { return fIndicesPerInstance; }
- int instanceCount() const { return fInstanceCount; }
-
- bool isIndexed() const { return fIndexCount > 0; }
-#ifdef SK_DEBUG
- bool isInstanced() const; // this version is longer because of asserts
-#else
- bool isInstanced() const { return fInstanceCount > 0; }
-#endif
-
- // adds or remove instances
- void adjustInstanceCount(int instanceOffset);
- // shifts the start vertex
- void adjustStartVertex(int vertexOffset);
- // shifts the start index
- void adjustStartIndex(int indexOffset);
-
- void setDevBounds(const SkRect& bounds) {
- fDevBoundsStorage = bounds;
- fDevBounds = &fDevBoundsStorage;
- }
- const SkRect* getDevBounds() const { return fDevBounds; }
-
- // NULL if no copy of the dst is needed for the draw.
- const GrDeviceCoordTexture* getDstCopy() const {
- if (fDstCopy.texture()) {
- return &fDstCopy;
- } else {
- return NULL;
- }
- }
-
- private:
- DrawInfo() { fDevBounds = NULL; }
-
- friend class GrDrawTarget;
-
- GrPrimitiveType fPrimitiveType;
-
- int fStartVertex;
- int fStartIndex;
- int fVertexCount;
- int fIndexCount;
-
- int fInstanceCount;
- int fVerticesPerInstance;
- int fIndicesPerInstance;
-
- SkRect fDevBoundsStorage;
- SkRect* fDevBounds;
-
- GrDeviceCoordTexture fDstCopy;
- };
-
// Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
// but couldn't be made. Otherwise, returns true. This method needs to be protected because it
// needs to be accessed by GLPrograms to setup a correct drawstate
GrTraceMarkerSet fActiveTraceMarkers;
GrTraceMarkerSet fStoredTraceMarkers;
+ // TODO fix this
+ friend class GrGpu;
+ friend class GrGpuGL;
+
typedef SkRefCnt INHERITED;
};
#define DEBUG_INVAL_START_IDX -1
GrGpu::GrGpu(GrContext* context)
- : INHERITED(context)
- , fResetTimestamp(kExpiredTimestamp+1)
+ : fResetTimestamp(kExpiredTimestamp+1)
, fResetBits(kAll_GrBackendState)
, fVertexPool(NULL)
, fIndexPool(NULL)
, fVertexPoolUseCnt(0)
, fIndexPoolUseCnt(0)
- , fQuadIndexBuffer(NULL) {
+ , fQuadIndexBuffer(NULL)
+ , fContext(context) {
fGeomPoolStateStack.push_back();
+ fDrawState = &fDefaultDrawState;
+ // We assume that fDrawState always owns a ref to the object it points at.
+ fDefaultDrawState.ref();
#ifdef SK_DEBUG
GeometryPoolState& poolState = fGeomPoolStateStack.back();
poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
#endif
+
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
+#ifdef SK_DEBUG
+ geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
+ geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+ geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
+ geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
+ geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
}
GrGpu::~GrGpu() {
fVertexPool = NULL;
delete fIndexPool;
fIndexPool = NULL;
+ SkASSERT(1 == fGeoSrcStateStack.count());
+ SkDEBUGCODE(GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
+ SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fIndexSrc);
+ SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fVertexSrc);
+ SkSafeUnref(fDrawState);
}
void GrGpu::contextAbandoned() {}
return buffer;
}
-void GrGpu::onClear(const SkIRect* rect,
- GrColor color,
- bool canIgnoreRect,
- GrRenderTarget* renderTarget) {
+void GrGpu::clear(const SkIRect* rect,
+ GrColor color,
+ bool canIgnoreRect,
+ GrRenderTarget* renderTarget) {
SkASSERT(renderTarget);
this->handleDirtyContext();
this->onGpuClear(renderTarget, rect, color, canIgnoreRect);
this->onResolveRenderTarget(target);
}
+void GrGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
+ // Make the dst of the copy be a render target because the default copySurface draws to the dst.
+ desc->fOrigin = kDefault_GrSurfaceOrigin;
+ desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc->fConfig = src->config();
+}
+
+typedef GrTraceMarkerSet::Iter TMIter;
+void GrGpu::saveActiveTraceMarkers() {
+ if (this->caps()->gpuTracingSupport()) {
+ SkASSERT(0 == fStoredTraceMarkers.count());
+ fStoredTraceMarkers.addSet(fActiveTraceMarkers);
+ for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
+ this->removeGpuTraceMarker(&(*iter));
+ }
+ }
+}
+
+void GrGpu::restoreActiveTraceMarkers() {
+ if (this->caps()->gpuTracingSupport()) {
+ SkASSERT(0 == fActiveTraceMarkers.count());
+ for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
+ this->addGpuTraceMarker(&(*iter));
+ }
+ for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
+ this->fStoredTraceMarkers.remove(*iter);
+ }
+ }
+}
+
+void GrGpu::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
+ if (this->caps()->gpuTracingSupport()) {
+ SkASSERT(fGpuTraceMarkerCount >= 0);
+ this->fActiveTraceMarkers.add(*marker);
+ this->didAddGpuTraceMarker();
+ ++fGpuTraceMarkerCount;
+ }
+}
+
+void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
+ if (this->caps()->gpuTracingSupport()) {
+ SkASSERT(fGpuTraceMarkerCount >= 1);
+ this->fActiveTraceMarkers.remove(*marker);
+ this->didRemoveGpuTraceMarker();
+ --fGpuTraceMarkerCount;
+ }
+}
+
+void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
+ this->releasePreviousVertexSource();
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = GrDrawTarget::kBuffer_GeometrySrcType;
+ geoSrc.fVertexBuffer = buffer;
+ buffer->ref();
+ geoSrc.fVertexSize = this->drawState()->getVertexStride();
+}
+
+void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
+ this->releasePreviousIndexSource();
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = GrDrawTarget::kBuffer_GeometrySrcType;
+ geoSrc.fIndexBuffer = buffer;
+ buffer->ref();
+}
+
+void GrGpu::setDrawState(GrDrawState* drawState) {
+ SkASSERT(fDrawState);
+ if (NULL == drawState) {
+ drawState = &fDefaultDrawState;
+ }
+ if (fDrawState != drawState) {
+ fDrawState->unref();
+ drawState->ref();
+ fDrawState = drawState;
+ }
+}
+
+void GrGpu::resetVertexSource() {
+ this->releasePreviousVertexSource();
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
+}
+
+void GrGpu::resetIndexSource() {
+ this->releasePreviousIndexSource();
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
+}
+
+void GrGpu::pushGeometrySource() {
+ this->geometrySourceWillPush();
+ GrDrawTarget::GeometrySrcState& newState = fGeoSrcStateStack.push_back();
+ newState.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
+ newState.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
+#ifdef SK_DEBUG
+ newState.fVertexCount = ~0;
+ newState.fVertexBuffer = (GrVertexBuffer*)~0;
+ newState.fIndexCount = ~0;
+ newState.fIndexBuffer = (GrIndexBuffer*)~0;
+#endif
+}
+
+void GrGpu::popGeometrySource() {
+ // if popping last element then pops are unbalanced with pushes
+ SkASSERT(fGeoSrcStateStack.count() > 1);
+
+ this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
+ this->releasePreviousVertexSource();
+ this->releasePreviousIndexSource();
+ fGeoSrcStateStack.pop_back();
+}
+
////////////////////////////////////////////////////////////////////////////////
static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
////////////////////////////////////////////////////////////////////////////////
void GrGpu::geometrySourceWillPush() {
- const GeometrySrcState& geoSrc = this->getGeomSrc();
- if (kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
+ const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
+ if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
this->finalizeReservedVertices();
}
- if (kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
+ if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
this->finalizeReservedIndices();
}
GeometryPoolState& newState = fGeomPoolStateStack.push_back();
#endif
}
-void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
+void GrGpu::geometrySourceWillPop(const GrDrawTarget::GeometrySrcState& restoredState) {
// if popping last entry then pops are unbalanced with pushes
SkASSERT(fGeomPoolStateStack.count() > 1);
fGeomPoolStateStack.pop_back();
}
-void GrGpu::onDraw(const DrawInfo& info, const GrClipMaskManager::ScissorState& scissorState) {
+void GrGpu::onDraw(const GrDrawTarget::DrawInfo& info,
+ const GrClipMaskManager::ScissorState& scissorState) {
this->handleDirtyContext();
if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()),
scissorState,
const GrDeviceCoordTexture* dstCopy) {
this->handleDirtyContext();
- drawState()->setDefaultVertexAttribs();
-
if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) {
return;
}
const uint32_t indices[],
int count,
const float transforms[],
- PathTransformType transformsType,
+ GrDrawTarget::PathTransformType transformsType,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings,
const GrDeviceCoordTexture* dstCopy) {
this->handleDirtyContext();
- drawState()->setDefaultVertexAttribs();
-
if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) {
return;
}
}
void GrGpu::releaseReservedVertexSpace() {
- const GeometrySrcState& geoSrc = this->getGeomSrc();
- SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+ const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
+ SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc);
size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize;
fVertexPool->putBack(bytes);
--fVertexPoolUseCnt;
}
void GrGpu::releaseReservedIndexSpace() {
- const GeometrySrcState& geoSrc = this->getGeomSrc();
- SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+ const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
+ SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc);
size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
fIndexPool->putBack(bytes);
--fIndexPoolUseCnt;
}
+
+void GrGpu::releasePreviousVertexSource() {
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ switch (geoSrc.fVertexSrc) {
+ case GrDrawTarget::kNone_GeometrySrcType:
+ break;
+ case GrDrawTarget::kReserved_GeometrySrcType:
+ this->releaseReservedVertexSpace();
+ break;
+ case GrDrawTarget::kBuffer_GeometrySrcType:
+ geoSrc.fVertexBuffer->unref();
+#ifdef SK_DEBUG
+ geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ break;
+ default:
+ SkFAIL("Unknown Vertex Source Type.");
+ break;
+ }
+}
+
+void GrGpu::releasePreviousIndexSource() {
+ GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+ switch (geoSrc.fIndexSrc) {
+ case GrDrawTarget::kNone_GeometrySrcType: // these two don't require
+ break;
+ case GrDrawTarget::kReserved_GeometrySrcType:
+ this->releaseReservedIndexSpace();
+ break;
+ case GrDrawTarget::kBuffer_GeometrySrcType:
+ geoSrc.fIndexBuffer->unref();
+#ifdef SK_DEBUG
+ geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+ break;
+ default:
+ SkFAIL("Unknown Index Source Type.");
+ break;
+ }
+}
+
+void GrGpu::releaseGeometry() {
+ int popCnt = fGeoSrcStateStack.count() - 1;
+ while (popCnt) {
+ this->popGeometrySource();
+ --popCnt;
+ }
+ this->resetVertexSource();
+ this->resetIndexSource();
+}
class GrStencilBuffer;
class GrVertexBufferAllocPool;
-class GrGpu : public GrClipTarget {
+class GrGpu : public SkRefCnt {
public:
/**
GrGpu(GrContext* context);
virtual ~GrGpu();
- GrContext* getContext() { return this->INHERITED::getContext(); }
- const GrContext* getContext() const { return this->INHERITED::getContext(); }
+ GrContext* getContext() { return fContext; }
+ const GrContext* getContext() const { return fContext; }
+
+ /**
+ * Gets the capabilities of the draw target.
+ */
+ const GrDrawTargetCaps* caps() const { return fCaps.get(); }
+
+ /**
+ * Sets the draw state object for the gpu. Note that this does not
+ * make a copy. The GrGpu will take a reference to passed object.
+ * Passing NULL will cause the GrGpu to use its own internal draw
+ * state object rather than an externally provided one.
+ */
+ void setDrawState(GrDrawState* drawState);
+
+ /**
+ * Read-only access to the GrGpu current draw state.
+ */
+ const GrDrawState& getDrawState() const { return *fDrawState; }
+
+ /**
+ * Read-write access to the GrGpu current draw state. Note that
+ * this doesn't ref.
+ */
+ GrDrawState* drawState() { return fDrawState; }
GrPathRendering* pathRendering() {
return fPathRendering.get();
GrPixelConfig config, const void* buffer,
size_t rowBytes);
- // GrDrawTarget overrides
- virtual void clearStencilClip(const SkIRect& rect,
- bool insideClip,
- GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
+ /**
+ * Clear the passed in render target. Ignores the draw state and clip. Clears the whole thing if
+ * rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target
+ * can be optionally cleared.
+ */
+ void clear(const SkIRect* rect,
+ GrColor color,
+ bool canIgnoreRect,
+ GrRenderTarget* renderTarget);
+
+
+ void clearStencilClip(const SkIRect& rect,
+ bool insideClip,
+ GrRenderTarget* renderTarget = NULL);
+
+ /**
+ * Discards the contents render target. NULL indicates that the current render target should
+ * be discarded.
+ **/
+ virtual void discard(GrRenderTarget* = NULL) = 0;
+
+ /**
+ * This is can be called before allocating a texture to be a dst for copySurface. It will
+ * populate the origin, config, and flags fields of the desc such that copySurface is more
+ * likely to succeed and be efficient.
+ */
+ virtual void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc);
// After the client interacts directly with the 3D context state the GrGpu
// must resync its internal state and assumptions about 3D context state.
const GrDeviceCoordTexture* dstCopy,
GrProgramDesc*) = 0;
+ /**
+ * Called at start and end of gpu trace marking
+ * GR_CREATE_GPU_TRACE_MARKER(marker_str, target) will automatically call these at the start
+ * and end of a code block respectively
+ */
+ void addGpuTraceMarker(const GrGpuTraceMarker* marker);
+ void removeGpuTraceMarker(const GrGpuTraceMarker* marker);
+
+ /**
+ * Takes the current active set of markers and stores them for later use. Any current marker
+ * in the active set is removed from the active set and the targets remove function is called.
+ * These functions do not work as a stack so you cannot call save a second time before calling
+ * restore. Also, it is assumed that when restore is called the current active set of markers
+ * is empty. When the stored markers are added back into the active set, the targets add marker
+ * is called.
+ */
+ void saveActiveTraceMarkers();
+ void restoreActiveTraceMarkers();
+
+ /**
+ * Query to find out if the vertex or index source is reserved.
+ */
+ bool hasReservedVerticesOrIndices() const {
+ return GrDrawTarget::kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc ||
+ GrDrawTarget::kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
+ }
+
+ // Called to determine whether an onCopySurface call would succeed or not. This is useful for
+ // proxy subclasses to test whether the copy would succeed without executing it yet. Derived
+ // classes must keep this consistent with their implementation of onCopySurface(). The inputs
+ // are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src
+ // and dst bounds.
+ virtual bool canCopySurface(GrSurface* dst,
+ GrSurface* src,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint) = 0;
+
+ // This method is called by copySurface The srcRect is guaranteed to be entirely within the
+ // src bounds. Likewise, the dst rect implied by dstPoint and srcRect's width and height falls
+ // entirely within the dst. The default implementation will draw a rect from the src to the
+ // dst if the src is a texture and the dst is a render target and fail otherwise.
+ virtual bool copySurface(GrSurface* dst,
+ GrSurface* src,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint) = 0;
+
+ /**
+ * Sets source of vertex data for the next draw. Data does not have to be
+ * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances.
+ *
+ * @param buffer vertex buffer containing vertex data. Must be
+ * unlocked before draw call. Vertex size is queried
+ * from current GrDrawState.
+ */
+ void setVertexSourceToBuffer(const GrVertexBuffer* buffer);
+
+ /**
+ * Sets source of index data for the next indexed draw. Data does not have
+ * to be in the buffer until drawIndexed.
+ *
+ * @param buffer index buffer containing indices. Must be unlocked
+ * before indexed draw call.
+ */
+ void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+
+ /**
+ * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
+ * source to reserved, array, or buffer before next draw. May be able to free
+ * up temporary storage allocated by setVertexSourceToArray or
+ * reserveVertexSpace.
+ */
+ void resetVertexSource();
+
+ /**
+ * Resets index source. Indexed Drawing from reset indices is illegal. Set
+ * index source to reserved, array, or buffer before next indexed draw. May
+ * be able to free up temporary storage allocated by setIndexSourceToArray
+ * or reserveIndexSpace.
+ */
+ void resetIndexSource();
+
+ /**
+ * Pushes and resets the vertex/index sources. Any reserved vertex / index
+ * data is finalized (i.e. cannot be updated after the matching pop but can
+ * be drawn from). Must be balanced by a pop.
+ */
+ void pushGeometrySource();
+
+ /**
+ * Pops the vertex / index sources from the matching push.
+ */
+ void popGeometrySource();
+
protected:
DrawType PrimTypeToDrawType(GrPrimitiveType type) {
switch (type) {
unsigned int* ref,
unsigned int* mask);
+ // subclasses must call this in their destructors to ensure all vertex
+ // and index sources have been released (including those held by
+ // pushGeometrySource())
+ void releaseGeometry();
+
+ // accessors for derived classes
+ const GrDrawTarget::GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); }
+
+ // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert.
+ size_t getVertexSize() const {
+ // the vertex layout is only valid if a vertex source has been specified.
+ SkASSERT(this->getGeomSrc().fVertexSrc != GrDrawTarget::kNone_GeometrySrcType);
+ return this->getGeomSrc().fVertexSize;
+ }
+
+ const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }
+
GrContext::GPUStats fGPUStats;
struct GeometryPoolState {
SkAutoTDelete<GrPathRendering> fPathRendering;
+ // Subclass must initialize this in its constructor.
+ SkAutoTUnref<const GrDrawTargetCaps> fCaps;
+
private:
// GrDrawTarget overrides
- virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE;
- virtual bool onReserveIndexSpace(int indexCount, void** indices) SK_OVERRIDE;
- virtual void releaseReservedVertexSpace() SK_OVERRIDE;
- virtual void releaseReservedIndexSpace() SK_OVERRIDE;
- virtual void geometrySourceWillPush() SK_OVERRIDE;
- virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
- virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
- GrRenderTarget* renderTarget) SK_OVERRIDE;
+ virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices);
+ virtual bool onReserveIndexSpace(int indexCount, void** indices);
+ virtual void releaseReservedVertexSpace();
+ virtual void releaseReservedIndexSpace();
+ virtual void geometrySourceWillPush();
+ virtual void geometrySourceWillPop(const GrDrawTarget::GeometrySrcState& restoredState);
// called when the 3D context state is unknown. Subclass should emit any
// assumed 3D context state and dirty any state cache.
bool insideClip) = 0;
// overridden by backend-specific derived class to perform the draw call.
- virtual void onGpuDraw(const DrawInfo&) = 0;
+ virtual void onGpuDraw(const GrDrawTarget::DrawInfo&) = 0;
// overridden by backend-specific derived class to perform the read pixels.
virtual bool onReadPixels(GrRenderTarget* target,
bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
// GrDrawTarget overrides
- virtual void onDraw(const DrawInfo&, const GrClipMaskManager::ScissorState&) SK_OVERRIDE;
+ virtual void onDraw(const GrDrawTarget::DrawInfo&,
+ const GrClipMaskManager::ScissorState&);
virtual void onStencilPath(const GrPath*,
const GrClipMaskManager::ScissorState&,
- const GrStencilSettings&) SK_OVERRIDE;
+ const GrStencilSettings&);
virtual void onDrawPath(const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
- const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
+ const GrDeviceCoordTexture* dstCopy);
virtual void onDrawPaths(const GrPathRange*,
const uint32_t indices[],
int count,
const float transforms[],
- PathTransformType,
+ GrDrawTarget::PathTransformType,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
- const GrDeviceCoordTexture*) SK_OVERRIDE;
+ const GrDeviceCoordTexture*);
+
+ virtual void didAddGpuTraceMarker() = 0;
+ virtual void didRemoveGpuTraceMarker() = 0;
+
// readies the pools to provide vertex/index data.
void prepareVertexPool();
}
}
+ // called when setting a new vert/idx source to unref prev vb/ib
+ void releasePreviousVertexSource();
+ void releasePreviousIndexSource();
+
+ enum {
+ kPreallocGeoSrcStateStackCnt = 4,
+ };
+ SkSTArray<kPreallocGeoSrcStateStackCnt, GrDrawTarget::GeometrySrcState, true> fGeoSrcStateStack;
+
enum {
kPreallocGeomPoolStateStackCnt = 4,
};
int fIndexPoolUseCnt;
// these are mutable so they can be created on-demand
mutable GrIndexBuffer* fQuadIndexBuffer;
-
- typedef GrClipTarget INHERITED;
+ GrDrawState fDefaultDrawState;
+ GrDrawState* fDrawState;
+ // To keep track that we always have at least as many debug marker adds as removes
+ int fGpuTraceMarkerCount;
+ GrTraceMarkerSet fActiveTraceMarkers;
+ GrTraceMarkerSet fStoredTraceMarkers;
+ // The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu.
+ GrContext* fContext;
+
+ // TODO fix this
+ friend class GrInOrderDrawBuffer;
+
+ typedef SkRefCnt INHERITED;
};
#endif
++fDrawID;
}
-void GrInOrderDrawBuffer::Draw::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) {
gpu->setVertexSourceToBuffer(this->vertexBuffer());
if (fInfo.isIndexed()) {
gpu->setIndexSourceToBuffer(this->indexBuffer());
}
- gpu->executeDraw(fInfo, fScissorState);
+ gpu->onDraw(fInfo, fScissorState);
}
-void GrInOrderDrawBuffer::StencilPath::execute(GrClipTarget* gpu) {
- gpu->executeStencilPath(this->path(), fScissorState, fStencilSettings);
+void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) {
+ gpu->onStencilPath(this->path(), fScissorState, fStencilSettings);
}
-void GrInOrderDrawBuffer::DrawPath::execute(GrClipTarget* gpu) {
- gpu->executeDrawPath(this->path(), fScissorState, fStencilSettings,
+void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) {
+ gpu->onDrawPath(this->path(), fScissorState, fStencilSettings,
fDstCopy.texture() ? &fDstCopy : NULL);
}
-void GrInOrderDrawBuffer::DrawPaths::execute(GrClipTarget* gpu) {
- gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
+void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) {
+ gpu->onDrawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
fTransformsType, fScissorState, fStencilSettings,
fDstCopy.texture() ? &fDstCopy : NULL);
}
-void GrInOrderDrawBuffer::SetState::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) {
gpu->setDrawState(&fState);
}
-void GrInOrderDrawBuffer::Clear::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) {
if (GrColor_ILLEGAL == fColor) {
gpu->discard(this->renderTarget());
} else {
}
}
-void GrInOrderDrawBuffer::ClearStencilClip::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) {
gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
}
-void GrInOrderDrawBuffer::CopySurface::execute(GrClipTarget* gpu) {
+void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) {
gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
}
Cmd(uint8_t type) : fType(type) {}
virtual ~Cmd() {}
- virtual void execute(GrClipTarget*) = 0;
+ virtual void execute(GrGpu*) = 0;
uint8_t fType;
};
const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
DrawInfo fInfo;
ScissorState fScissorState;
const GrPath* path() const { return fPath.get(); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
ScissorState fScissorState;
GrStencilSettings fStencilSettings;
const GrPath* path() const { return fPath.get(); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
GrDeviceCoordTexture fDstCopy;
ScissorState fScissorState;
uint32_t* indices() { return reinterpret_cast<uint32_t*>(CmdBuffer::GetDataForItem(this)); }
float* transforms() { return reinterpret_cast<float*>(&this->indices()[fCount]); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
size_t fCount;
PathTransformType fTransformsType;
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
SkIRect fRect;
GrColor fColor;
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
SkIRect fRect;
bool fInsideClip;
GrSurface* dst() const { return fDst.get(); }
GrSurface* src() const { return fSrc.get(); }
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
SkIPoint fDstPoint;
SkIRect fSrcRect;
struct SetState : public Cmd {
SetState(const GrDrawState& state) : Cmd(kSetState_Cmd), fState(state) {}
- virtual void execute(GrClipTarget*);
+ virtual void execute(GrGpu*);
GrDrawState fState;
};
CmdBuffer fCmdBuffer;
GrDrawState* fLastState;
SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
- GrClipTarget* fDstGpu;
+ GrGpu* fDstGpu;
GrVertexBufferAllocPool& fVertexPool;
GrIndexBufferAllocPool& fIndexPool;
virtual void discard(GrRenderTarget*) SK_OVERRIDE { }
+ virtual bool canCopySurface(GrSurface* dst,
+ GrSurface* src,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint) SK_OVERRIDE { return false; };
+
+ virtual bool copySurface(GrSurface* dst,
+ GrSurface* src,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint) SK_OVERRIDE { return false; };
+
private:
virtual void onResetContext(uint32_t resetBits) { };
virtual GrTexture* onCreateTexture(const GrSurfaceDesc& desc,
const SkIRect& rect,
bool insideClip) SK_OVERRIDE { }
- virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE { }
+ virtual void onGpuDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE { }
virtual bool onReadPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig,
#endif
#endif
-void GrGpuGL::onGpuDraw(const DrawInfo& info) {
+void GrGpuGL::onGpuDraw(const GrDrawTarget::DrawInfo& info) {
size_t indexOffsetInBytes;
this->setupGeometry(info, &indexOffsetInBytes);
virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
- virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
+ virtual void onGpuDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE;
virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
// Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
// an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
// index is relative to the returned offset.
- void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
+ void setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes);
// Subclasses should call this to flush the blend state.
// The params should be the final coefficients to apply
return true;
}
-void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
+void GrGpuGL::setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes) {
SkAutoTUnref<GrOptDrawState> optState(
GrOptDrawState::Create(this->getDrawState(), this, info.getDstCopy(),
PrimTypeToDrawType(info.primitiveType())));
GrGLVertexBuffer* vbuf;
switch (this->getGeomSrc().fVertexSrc) {
- case kBuffer_GeometrySrcType:
+ case GrDrawTarget::kBuffer_GeometrySrcType:
vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
break;
- case kReserved_GeometrySrcType:
+ case GrDrawTarget::kReserved_GeometrySrcType:
this->finalizeReservedVertices();
vertexOffsetInBytes += geoPoolState.fPoolStartVertex * this->getGeomSrc().fVertexSize;
vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
SkASSERT(indexOffsetInBytes);
switch (this->getGeomSrc().fIndexSrc) {
- case kBuffer_GeometrySrcType:
+ case GrDrawTarget::kBuffer_GeometrySrcType:
*indexOffsetInBytes = 0;
ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
break;
- case kReserved_GeometrySrcType:
+ case GrDrawTarget::kReserved_GeometrySrcType:
this->finalizeReservedIndices();
*indexOffsetInBytes = geoPoolState.fPoolStartIndex * sizeof(GrGLushort);
ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;