Snap optdrawstate in inorder draw buffer and pass into gpu

BUG=skia:

Review URL: https://codereview.chromium.org/709133003
This commit is contained in:
joshualitt 2014-11-10 16:03:14 -08:00 committed by Commit bot
parent ac6c4fc524
commit d53a82706e
10 changed files with 157 additions and 179 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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();

View File

@ -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));

View File

@ -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

View File

@ -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) {