aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2014-11-10 16:03:14 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-10 16:03:15 -0800
commitd53a82706ebd227bc0e4dd535118cdd8298131bd (patch)
tree9bc2164890ae6d909492e973f5d982d2964fb764 /src/gpu
parentac6c4fc524a1a7e5631f9109a6af0aac7bb7c485 (diff)
Snap optdrawstate in inorder draw buffer and pass into gpu
Diffstat (limited to 'src/gpu')
-rwxr-xr-xsrc/gpu/GrContext.cpp1
-rw-r--r--src/gpu/GrGpu.cpp77
-rw-r--r--src/gpu/GrGpu.h46
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp106
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h24
-rw-r--r--src/gpu/GrTest.cpp7
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp6
-rw-r--r--src/gpu/gl/GrGpuGL.cpp4
-rw-r--r--src/gpu/gl/GrGpuGL.h9
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp56
10 files changed, 157 insertions, 179 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 6f9395b5c3..fee62a8dc4 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -127,7 +127,6 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
void GrContext::initCommon() {
fDrawState = SkNEW(GrDrawState);
- fGpu->setDrawState(fDrawState);
fResourceCache = SkNEW_ARGS(GrResourceCache, (fGpu->caps(),
MAX_RESOURCE_CACHE_COUNT,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index ab24c5447f..d3fcddf432 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -26,14 +26,10 @@ GrGpu::GrGpu(GrContext* context)
, fResetBits(kAll_GrBackendState)
, fQuadIndexBuffer(NULL)
, fContext(context) {
- fDrawState = &fDefaultDrawState;
- // We assume that fDrawState always owns a ref to the object it points at.
- fDefaultDrawState.ref();
}
GrGpu::~GrGpu() {
SkSafeSetNull(fQuadIndexBuffer);
- SkSafeUnref(fDrawState);
SkSafeUnref(fGeoSrcState.fVertexBuffer);
SkSafeUnref(fGeoSrcState.fIndexBuffer);
}
@@ -187,13 +183,7 @@ void GrGpu::clear(const SkIRect* rect,
void GrGpu::clearStencilClip(const SkIRect& rect,
bool insideClip,
GrRenderTarget* renderTarget) {
- if (NULL == renderTarget) {
- renderTarget = this->getDrawState().getRenderTarget();
- }
- if (NULL == renderTarget) {
- SkASSERT(0);
- return;
- }
+ SkASSERT(renderTarget);
this->handleDirtyContext();
this->onClearStencilClip(renderTarget, rect, insideClip);
}
@@ -270,11 +260,11 @@ void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
}
}
-void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
+void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) {
SkSafeUnref(fGeoSrcState.fVertexBuffer);
fGeoSrcState.fVertexBuffer = buffer;
buffer->ref();
- fGeoSrcState.fVertexSize = this->drawState()->getVertexStride();
+ fGeoSrcState.fVertexSize = vertexStride;
}
void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
@@ -283,18 +273,6 @@ void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
buffer->ref();
}
-void GrGpu::setDrawState(GrDrawState* drawState) {
- SkASSERT(fDrawState);
- if (NULL == drawState) {
- drawState = &fDefaultDrawState;
- }
- if (fDrawState != drawState) {
- fDrawState->unref();
- drawState->ref();
- fDrawState = drawState;
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
@@ -320,23 +298,26 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
////////////////////////////////////////////////////////////////////////////////
-void GrGpu::draw(const GrDrawTarget::DrawInfo& info,
- const GrClipMaskManager::ScissorState& scissorState) {
+void GrGpu::draw(const GrOptDrawState& ds,
+ const GrDrawTarget::DrawInfo& info,
+ const GrClipMaskManager::ScissorState& scissorState) {
this->handleDirtyContext();
- if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()),
+ if (!this->flushGraphicsState(ds,
+ PrimTypeToDrawType(info.primitiveType()),
scissorState,
info.getDstCopy())) {
return;
}
- this->onDraw(info);
+ this->onDraw(ds, info);
}
-void GrGpu::stencilPath(const GrPath* path,
- const GrClipMaskManager::ScissorState& scissorState,
- const GrStencilSettings& stencilSettings) {
+void GrGpu::stencilPath(const GrOptDrawState& ds,
+ const GrPath* path,
+ const GrClipMaskManager::ScissorState& scissorState,
+ const GrStencilSettings& stencilSettings) {
this->handleDirtyContext();
- if (!this->flushGraphicsState(kStencilPath_DrawType, scissorState, NULL)) {
+ if (!this->flushGraphicsState(ds, kStencilPath_DrawType, scissorState, NULL)) {
return;
}
@@ -344,30 +325,32 @@ void GrGpu::stencilPath(const GrPath* path,
}
-void GrGpu::drawPath(const GrPath* path,
- const GrClipMaskManager::ScissorState& scissorState,
- const GrStencilSettings& stencilSettings,
- const GrDeviceCoordTexture* dstCopy) {
+void GrGpu::drawPath(const GrOptDrawState& ds,
+ const GrPath* path,
+ const GrClipMaskManager::ScissorState& scissorState,
+ const GrStencilSettings& stencilSettings,
+ const GrDeviceCoordTexture* dstCopy) {
this->handleDirtyContext();
- if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) {
+ if (!this->flushGraphicsState(ds, kDrawPath_DrawType, scissorState, dstCopy)) {
return;
}
this->pathRendering()->drawPath(path, stencilSettings);
}
-void GrGpu::drawPaths(const GrPathRange* pathRange,
- const uint32_t indices[],
- int count,
- const float transforms[],
- GrDrawTarget::PathTransformType transformsType,
- const GrClipMaskManager::ScissorState& scissorState,
- const GrStencilSettings& stencilSettings,
- const GrDeviceCoordTexture* dstCopy) {
+void GrGpu::drawPaths(const GrOptDrawState& ds,
+ const GrPathRange* pathRange,
+ const uint32_t indices[],
+ int count,
+ const float transforms[],
+ GrDrawTarget::PathTransformType transformsType,
+ const GrClipMaskManager::ScissorState& scissorState,
+ const GrStencilSettings& stencilSettings,
+ const GrDeviceCoordTexture* dstCopy) {
this->handleDirtyContext();
- if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) {
+ if (!this->flushGraphicsState(ds, kDrawPaths_DrawType, scissorState, dstCopy)) {
return;
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 5279ce8b39..dfc71fe970 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -60,25 +60,6 @@ public:
*/
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();
}
@@ -302,7 +283,7 @@ public:
void clearStencilClip(const SkIRect& rect,
bool insideClip,
- GrRenderTarget* renderTarget = NULL);
+ GrRenderTarget* renderTarget);
/**
* Discards the contents render target. NULL indicates that the current render target should
@@ -401,7 +382,7 @@ public:
* unlocked before draw call. Vertex size is queried
* from current GrDrawState.
*/
- void setVertexSourceToBuffer(const GrVertexBuffer* buffer);
+ void setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride);
/**
* Sets source of index data for the next indexed draw. Data does not have
@@ -412,16 +393,20 @@ public:
*/
void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
- virtual void draw(const GrDrawTarget::DrawInfo&,
+ virtual void draw(const GrOptDrawState&,
+ const GrDrawTarget::DrawInfo&,
const GrClipMaskManager::ScissorState&);
- virtual void stencilPath(const GrPath*,
+ virtual void stencilPath(const GrOptDrawState&,
+ const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&);
- virtual void drawPath(const GrPath*,
+ virtual void drawPath(const GrOptDrawState&,
+ const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy);
- virtual void drawPaths(const GrPathRange*,
+ virtual void drawPaths(const GrOptDrawState&,
+ const GrPathRange*,
const uint32_t indices[],
int count,
const float transforms[],
@@ -430,8 +415,7 @@ public:
const GrStencilSettings&,
const GrDeviceCoordTexture*);
-protected:
- DrawType PrimTypeToDrawType(GrPrimitiveType type) {
+ static DrawType PrimTypeToDrawType(GrPrimitiveType type) {
switch (type) {
case kTriangles_GrPrimitiveType:
case kTriangleStrip_GrPrimitiveType:
@@ -448,6 +432,7 @@ protected:
}
}
+protected:
// Functions used to map clip-respecting stencil tests into normal
// stencil funcs supported by GPUs.
static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
@@ -513,7 +498,7 @@ private:
bool insideClip) = 0;
// overridden by backend-specific derived class to perform the draw call.
- virtual void onDraw(const GrDrawTarget::DrawInfo&) = 0;
+ virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) = 0;
// overridden by backend-specific derived class to perform the read pixels.
virtual bool onReadPixels(GrRenderTarget* target,
@@ -543,7 +528,8 @@ private:
// deltas from previous state at draw time. This function does the
// backend-specific flush of the state.
// returns false if current state is unsupported.
- virtual bool flushGraphicsState(DrawType,
+ virtual bool flushGraphicsState(const GrOptDrawState&,
+ DrawType,
const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture* dstCopy) = 0;
@@ -573,8 +559,6 @@ private:
uint32_t fResetBits;
// these are mutable so they can be created on-demand
mutable GrIndexBuffer* fQuadIndexBuffer;
- GrDrawState fDefaultDrawState;
- GrDrawState* fDrawState;
// To keep track that we always have at least as many debug marker adds as removes
int fGpuTraceMarkerCount;
GrTraceMarkerSet fActiveTraceMarkers;
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 9835200598..1789c49aca 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -9,9 +9,10 @@
#include "GrBufferAllocPool.h"
#include "GrDrawTargetCaps.h"
-#include "GrTextStrike.h"
#include "GrGpu.h"
+#include "GrOptDrawState.h"
#include "GrTemplates.h"
+#include "GrTextStrike.h"
#include "GrTexture.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
@@ -246,7 +247,8 @@ void GrInOrderDrawBuffer::onDraw(const DrawInfo& info,
GeometryPoolState& poolState = fGeoPoolStateStack.back();
const GrDrawState& drawState = this->getDrawState();
- this->recordStateIfNecessary();
+ this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType()),
+ info.getDstCopy());
const GrVertexBuffer* vb;
if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
@@ -297,7 +299,7 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings) {
// Only compare the subset of GrDrawState relevant to path stenciling?
- this->recordStateIfNecessary();
+ this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL);
StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
sp->fScissorState = scissorState;
sp->fStencilSettings = stencilSettings;
@@ -309,7 +311,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
const GrStencilSettings& stencilSettings,
const GrDeviceCoordTexture* dstCopy) {
// TODO: Only compare the subset of GrDrawState relevant to path covering?
- this->recordStateIfNecessary();
+ this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy);
DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
if (dstCopy) {
dp->fDstCopy = *dstCopy;
@@ -331,7 +333,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
SkASSERT(indices);
SkASSERT(transforms);
- this->recordStateIfNecessary();
+ this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy);
int sizeOfIndices = sizeof(uint32_t) * count;
int sizeOfTransforms = sizeof(float) * count *
@@ -429,13 +431,15 @@ void GrInOrderDrawBuffer::flush() {
fVertexPool.unmap();
fIndexPool.unmap();
- GrDrawState* prevDrawState = SkRef(fDstGpu->drawState());
-
CmdBuffer::Iter iter(fCmdBuffer);
int currCmdMarker = 0;
fDstGpu->saveActiveTraceMarkers();
+ // Gpu no longer maintains the current drawstate, so we track the setstate calls below.
+ // NOTE: we always record a new drawstate at flush boundaries
+ SkAutoTUnref<const GrOptDrawState> currentOptState;
+
while (iter.next()) {
GrGpuTraceMarker newMarker("", -1);
SkString traceString;
@@ -446,13 +450,15 @@ void GrInOrderDrawBuffer::flush() {
++currCmdMarker;
}
- SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) ||
- kStencilPath_Cmd == strip_trace_bit(iter->fType) ||
- kDrawPath_Cmd == strip_trace_bit(iter->fType) ||
- kDrawPaths_Cmd == strip_trace_bit(iter->fType));
- SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState);
-
- iter->execute(fDstGpu);
+ if (kSetState_Cmd == strip_trace_bit(iter->fType)) {
+ const SetState* ss = reinterpret_cast<const SetState*>(iter.get());
+ currentOptState.reset(GrOptDrawState::Create(ss->fState,
+ fDstGpu,
+ &ss->fDstCopy,
+ ss->fDrawType));
+ } else {
+ iter->execute(fDstGpu, currentOptState.get());
+ }
if (cmd_has_trace_marker(iter->fType)) {
fDstGpu->removeGpuTraceMarker(&newMarker);
@@ -462,40 +468,49 @@ void GrInOrderDrawBuffer::flush() {
fDstGpu->restoreActiveTraceMarkers();
SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
- fDstGpu->setDrawState(prevDrawState);
- prevDrawState->unref();
this->reset();
++fDrawID;
}
-void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) {
- gpu->setVertexSourceToBuffer(this->vertexBuffer());
+void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu, const GrOptDrawState* optState) {
+ if (!optState) {
+ return;
+ }
+ gpu->setVertexSourceToBuffer(this->vertexBuffer(), optState->getVertexStride());
if (fInfo.isIndexed()) {
gpu->setIndexSourceToBuffer(this->indexBuffer());
}
- gpu->draw(fInfo, fScissorState);
+ gpu->draw(*optState, fInfo, fScissorState);
}
-void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) {
- gpu->stencilPath(this->path(), fScissorState, fStencilSettings);
+void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu, const GrOptDrawState* optState) {
+ if (!optState) {
+ return;
+ }
+ gpu->stencilPath(*optState, this->path(), fScissorState, fStencilSettings);
}
-void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) {
- gpu->drawPath(this->path(), fScissorState, fStencilSettings,
- fDstCopy.texture() ? &fDstCopy : NULL);
+void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu, const GrOptDrawState* optState) {
+ if (!optState) {
+ return;
+ }
+ gpu->drawPath(*optState, this->path(), fScissorState, fStencilSettings,
+ fDstCopy.texture() ? &fDstCopy : NULL);
}
-void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) {
- gpu->drawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
- fTransformsType, fScissorState, fStencilSettings,
- fDstCopy.texture() ? &fDstCopy : NULL);
+void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu, const GrOptDrawState* optState) {
+ if (!optState) {
+ return;
+ }
+ gpu->drawPaths(*optState, this->pathRange(), this->indices(), fCount, this->transforms(),
+ fTransformsType, fScissorState, fStencilSettings,
+ fDstCopy.texture() ? &fDstCopy : NULL);
}
-void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) {
- gpu->setDrawState(&fState);
+void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu, const GrOptDrawState*) {
}
-void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) {
+void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu, const GrOptDrawState*) {
if (GrColor_ILLEGAL == fColor) {
gpu->discard(this->renderTarget());
} else {
@@ -503,11 +518,11 @@ void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) {
}
}
-void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) {
- gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
+void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu, const GrOptDrawState*) {
+ gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
}
-void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) {
+void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu, const GrOptDrawState*){
gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
}
@@ -640,8 +655,7 @@ void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
// offset into the pool's pointer that was referenced. Now we return to the
// pool any portion at the tail of the allocation that no draw referenced.
size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount;
- fVertexPool.putBack(reservedVertexBytes -
- poolState.fUsedPoolVertexBytes);
+ fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
poolState.fUsedPoolVertexBytes = 0;
poolState.fPoolVertexBuffer = NULL;
poolState.fPoolStartVertex = 0;
@@ -687,26 +701,36 @@ void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restored
poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount;
}
if (kReserved_GeometrySrcType == restoredState.fIndexSrc) {
- poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
- restoredState.fIndexCount;
+ poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexCount;
}
}
-void GrInOrderDrawBuffer::recordStateIfNecessary() {
+void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType,
+ const GrDeviceCoordTexture* dstCopy) {
if (!fLastState) {
SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->getDrawState()));
fLastState = &ss->fState;
+ if (dstCopy) {
+ ss->fDstCopy = *dstCopy;
+ }
+ ss->fDrawType = drawType;
this->convertDrawStateToPendingExec(fLastState);
this->recordTraceMarkersIfNecessary();
return;
}
const GrDrawState& curr = this->getDrawState();
switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
- case GrDrawState::kIncompatible_CombinedState:
- fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr))->fState;
+ case GrDrawState::kIncompatible_CombinedState: {
+ SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr));
+ fLastState = &ss->fState;
+ if (dstCopy) {
+ ss->fDstCopy = *dstCopy;
+ }
+ ss->fDrawType = drawType;
this->convertDrawStateToPendingExec(fLastState);
this->recordTraceMarkersIfNecessary();
break;
+ }
case GrDrawState::kA_CombinedState:
case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
break;
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index ed62a93247..7780e402ed 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -11,6 +11,7 @@
#include "GrDrawTarget.h"
#include "GrAllocPool.h"
#include "GrAllocator.h"
+#include "GrGpu.h"
#include "GrIndexBuffer.h"
#include "GrRenderTarget.h"
#include "GrPath.h"
@@ -23,7 +24,6 @@
#include "SkTemplates.h"
#include "SkTypes.h"
-class GrGpu;
class GrIndexBufferAllocPool;
class GrVertexBufferAllocPool;
@@ -110,7 +110,7 @@ private:
Cmd(uint8_t type) : fType(type) {}
virtual ~Cmd() {}
- virtual void execute(GrGpu*) = 0;
+ virtual void execute(GrGpu*, const GrOptDrawState*) = 0;
uint8_t fType;
};
@@ -129,7 +129,7 @@ private:
const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
DrawInfo fInfo;
ScissorState fScissorState;
@@ -144,7 +144,7 @@ private:
const GrPath* path() const { return fPath.get(); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
ScissorState fScissorState;
GrStencilSettings fStencilSettings;
@@ -158,7 +158,7 @@ private:
const GrPath* path() const { return fPath.get(); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
GrDeviceCoordTexture fDstCopy;
ScissorState fScissorState;
@@ -175,7 +175,7 @@ private:
uint32_t* indices() { return reinterpret_cast<uint32_t*>(CmdBuffer::GetDataForItem(this)); }
float* transforms() { return reinterpret_cast<float*>(&this->indices()[fCount]); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
size_t fCount;
PathTransformType fTransformsType;
@@ -193,7 +193,7 @@ private:
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
SkIRect fRect;
GrColor fColor;
@@ -209,7 +209,7 @@ private:
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
SkIRect fRect;
bool fInsideClip;
@@ -224,7 +224,7 @@ private:
GrSurface* dst() const { return fDst.get(); }
GrSurface* src() const { return fSrc.get(); }
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
SkIPoint fDstPoint;
SkIRect fSrcRect;
@@ -237,9 +237,11 @@ private:
struct SetState : public Cmd {
SetState(const GrDrawState& state) : Cmd(kSetState_Cmd), fState(state) {}
- virtual void execute(GrGpu*);
+ virtual void execute(GrGpu*, const GrOptDrawState*);
GrDrawState fState;
+ GrGpu::DrawType fDrawType;
+ GrDeviceCoordTexture fDstCopy;
};
typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
@@ -288,7 +290,7 @@ private:
int concatInstancedDraw(const DrawInfo& info, const GrClipMaskManager::ScissorState&);
// Determines whether the current draw operation requieres a new drawstate and if so records it.
- void recordStateIfNecessary();
+ void recordStateIfNecessary(GrGpu::DrawType, const GrDeviceCoordTexture*);
// We lazily record clip changes in order to skip clips that have no effect.
void recordClipIfNecessary();
// Records any trace markers for a command after adding it to the buffer.
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index b176d3c0fc..611059ae4c 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -49,6 +49,8 @@ void GrContext::purgeAllUnlockedResources() {
#include "GrInOrderDrawBuffer.h"
#include "GrGpu.h"
+class GrOptDrawState;
+
class MockGpu : public GrGpu {
public:
MockGpu(GrContext* context) : INHERITED(context) { fCaps.reset(SkNEW(GrDrawTargetCaps)); }
@@ -118,7 +120,7 @@ private:
const SkIRect& rect,
bool insideClip) SK_OVERRIDE { }
- virtual void onDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE { }
+ virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) SK_OVERRIDE { }
virtual bool onReadPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig,
@@ -147,7 +149,8 @@ private:
return false;
}
- virtual bool flushGraphicsState(DrawType,
+ virtual bool flushGraphicsState(const GrOptDrawState&,
+ DrawType,
const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE {
return false;
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 66b129e876..2a46078d03 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -154,8 +154,6 @@ GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface,
void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) {
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
- SkASSERT(fGpu->drawState()->getRenderTarget());
- SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
this->flushPathStencilSettings(stencilSettings);
SkASSERT(!fHWPathStencilSettings.isTwoSided());
@@ -176,8 +174,6 @@ void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings&
void GrGLPathRendering::drawPath(const GrPath* path, const GrStencilSettings& stencilSettings) {
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
- SkASSERT(fGpu->drawState()->getRenderTarget());
- SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
this->flushPathStencilSettings(stencilSettings);
SkASSERT(!fHWPathStencilSettings.isTwoSided());
@@ -202,8 +198,6 @@ void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t i
const float transforms[], PathTransformType transformsType,
const GrStencilSettings& stencilSettings) {
SkASSERT(fGpu->caps()->pathRenderingSupport());
- SkASSERT(fGpu->drawState()->getRenderTarget());
- SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 888f818993..877c21fc7e 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1729,9 +1729,9 @@ GrGLenum gPrimitiveType2GLMode[] = {
#endif
#endif
-void GrGpuGL::onDraw(const GrDrawTarget::DrawInfo& info) {
+void GrGpuGL::onDraw(const GrOptDrawState& ds, const GrDrawTarget::DrawInfo& info) {
size_t indexOffsetInBytes;
- this->setupGeometry(info, &indexOffsetInBytes);
+ this->setupGeometry(ds, info, &indexOffsetInBytes);
SkASSERT((size_t)info.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode));
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index fc7ad4e273..3757d76204 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -153,11 +153,12 @@ private:
virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
- virtual void onDraw(const GrDrawTarget::DrawInfo&) SK_OVERRIDE;
+ virtual void onDraw(const GrOptDrawState&, const GrDrawTarget::DrawInfo&) SK_OVERRIDE;
virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
- virtual bool flushGraphicsState(DrawType,
+ virtual bool flushGraphicsState(const GrOptDrawState&,
+ DrawType,
const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
@@ -171,7 +172,9 @@ private:
// 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 GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes);
+ void setupGeometry(const GrOptDrawState&,
+ 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
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index b197dc9caa..68f38df9f0 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -201,39 +201,31 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState, D
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
-bool GrGpuGL::flushGraphicsState(DrawType type,
+bool GrGpuGL::flushGraphicsState(const GrOptDrawState& optState,
+ DrawType type,
const GrClipMaskManager::ScissorState& scissorState,
const GrDeviceCoordTexture* dstCopy) {
- SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDrawState(),
- this,
- dstCopy,
- type));
-
- if (!optState) {
- return false;
- }
-
// GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
- SkASSERT(optState->getRenderTarget());
+ SkASSERT(optState.getRenderTarget());
if (kStencilPath_DrawType == type) {
- const GrRenderTarget* rt = optState->getRenderTarget();
+ const GrRenderTarget* rt = optState.getRenderTarget();
SkISize size;
size.set(rt->width(), rt->height());
- this->glPathRendering()->setProjectionMatrix(optState->getViewMatrix(), size, rt->origin());
+ this->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin());
} else {
- this->flushMiscFixedFunctionState(*optState.get());
+ this->flushMiscFixedFunctionState(optState);
- GrBlendCoeff srcCoeff = optState->getSrcBlendCoeff();
- GrBlendCoeff dstCoeff = optState->getDstBlendCoeff();
+ GrBlendCoeff srcCoeff = optState.getSrcBlendCoeff();
+ GrBlendCoeff dstCoeff = optState.getDstBlendCoeff();
// In these blend coeff's we end up drawing nothing so we can skip draw all together
if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff &&
- !optState->getStencil().doesWrite()) {
+ !optState.getStencil().doesWrite()) {
return false;
}
- fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), type));
+ fCurrentProgram.reset(fProgramCache->getProgram(optState, type));
if (NULL == fCurrentProgram.get()) {
SkDEBUGFAIL("Failed to create program!");
return false;
@@ -247,15 +239,15 @@ bool GrGpuGL::flushGraphicsState(DrawType type,
fHWProgramID = programID;
}
- this->flushBlend(*optState.get(), kDrawLines_DrawType == type, srcCoeff, dstCoeff);
+ this->flushBlend(optState, kDrawLines_DrawType == type, srcCoeff, dstCoeff);
- fCurrentProgram->setData(*optState.get(), type, dstCopy);
+ fCurrentProgram->setData(optState, type, dstCopy);
}
- GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
- this->flushStencil(optState->getStencil(), type);
+ GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState.getRenderTarget());
+ this->flushStencil(optState.getStencil(), type);
this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
- this->flushAAState(*optState.get(), type);
+ this->flushAAState(optState, type);
// This must come after textures are flushed because a texture may need
// to be msaa-resolved (which will modify bound FBO state).
@@ -264,16 +256,10 @@ bool GrGpuGL::flushGraphicsState(DrawType type,
return true;
}
-void GrGpuGL::setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOffsetInBytes) {
- SkAutoTUnref<GrOptDrawState> optState(
- GrOptDrawState::Create(this->getDrawState(), this, info.getDstCopy(),
- PrimTypeToDrawType(info.primitiveType())));
-
- // If the optState would is NULL it should have been caught in flushGraphicsState before getting
- // here.
- SkASSERT(optState);
-
- GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride());
+void GrGpuGL::setupGeometry(const GrOptDrawState& optState,
+ const GrDrawTarget::DrawInfo& info,
+ size_t* indexOffsetInBytes) {
+ GrGLsizei stride = static_cast<GrGLsizei>(optState.getVertexStride());
size_t vertexOffsetInBytes = stride * info.startVertex();
@@ -299,9 +285,9 @@ void GrGpuGL::setupGeometry(const GrDrawTarget::DrawInfo& info, size_t* indexOff
fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
if (fCurrentProgram->hasVertexShader()) {
- int vertexAttribCount = optState->getVertexAttribCount();
+ int vertexAttribCount = optState.getVertexAttribCount();
uint32_t usedAttribArraysMask = 0;
- const GrVertexAttrib* vertexAttrib = optState->getVertexAttribs();
+ const GrVertexAttrib* vertexAttrib = optState.getVertexAttribs();
for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
++vertexAttribIndex, ++vertexAttrib) {