Refactor DrawTarget and GPU to be independent
BUG=skia:
Review URL: https://codereview.chromium.org/705593002
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 2a1f5b6..47863bb 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -28,15 +28,18 @@
#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;
@@ -44,6 +47,16 @@
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() {
@@ -52,6 +65,11 @@
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() {}
@@ -194,10 +212,10 @@
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);
@@ -241,6 +259,118 @@
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;
@@ -267,11 +397,11 @@
////////////////////////////////////////////////////////////////////////////////
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();
@@ -285,13 +415,14 @@
#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,
@@ -320,8 +451,6 @@
const GrDeviceCoordTexture* dstCopy) {
this->handleDirtyContext();
- drawState()->setDefaultVertexAttribs();
-
if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) {
return;
}
@@ -333,14 +462,12 @@
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;
}
@@ -426,17 +553,67 @@
}
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();
+}