if (path->isEmpty()) {
return true;
}
+ GrDrawTarget::AutoStateRestore asr(target,
+ GrDrawTarget::kPreserve_ASRInit);
GrDrawState* drawState = target->drawState();
- GrDrawTarget::AutoStateRestore asr;
GrMatrix vm = drawState->getViewMatrix();
if (NULL != translate) {
vm.postTranslate(translate->fX, translate->fY);
}
- asr.set(target);
GrMatrix ivm;
if (vm.invert(&ivm)) {
drawState->preConcatSamplerMatrices(stageMask, ivm);
return false;
}
- GrDrawState* drawState = target->drawState();
-
GrDrawTarget::AutoStateRestore asr;
+ GrDrawState* drawState = target->drawState();
if (!drawState->getViewMatrix().hasPerspective()) {
- asr.set(target);
+ // we are going to whack the view matrix to identity to remove
+ // perspective.
+ asr.set(target,
+ GrDrawTarget::kPreserve_ASRInit);
+ drawState = target->drawState();
GrMatrix ivm;
if (drawState->getViewInverse(&ivm)) {
drawState->preConcatSamplerMatrices(stageMask, ivm);
}
drawState->viewMatrix()->reset();
}
+
// TODO: See whether rendering lines as degenerate quads improves perf
// when we have a mix
GrAssert(filter == GrSamplerState::kErode_Filter ||
filter == GrSamplerState::kDilate_Filter);
- GrDrawTarget::AutoStateRestore asr(gpu);
+ GrRenderTarget* target = gpu->drawState()->getRenderTarget();
+ GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = gpu->drawState();
- GrRenderTarget* target = drawState->getRenderTarget();
- drawState->reset();
drawState->setRenderTarget(target);
GrMatrix sampleM;
sampleM.setIDiv(texture->width(), texture->height());
const float* kernel,
int kernelWidth,
GrSamplerState::FilterDirection direction) {
- GrDrawTarget::AutoStateRestore asr(gpu);
+ GrRenderTarget* target = gpu->drawState()->getRenderTarget();
+ GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = gpu->drawState();
- GrRenderTarget* target = drawState->getRenderTarget();
- drawState->reset();
drawState->setRenderTarget(target);
GrMatrix sampleM;
sampleM.setIDiv(texture->width(), texture->height());
GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
if (NULL != texture) {
- GrDrawTarget::AutoStateRestore asr(fGpu);
+ GrDrawTarget::AutoStateRestore asr(fGpu,
+ GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
- drawState->reset();
drawState->setRenderTarget(texture->asRenderTarget());
drawState->setTexture(0, clampEntry.texture());
target = texture->asRenderTarget();
GrAssert(NULL != target);
- GrDrawTarget::AutoStateRestore asr(fGpu);
+ GrDrawTarget::AutoStateRestore asr(fGpu,
+ GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
- drawState->reset();
drawState->setRenderTarget(target);
GrMatrix matrix;
}
ASSERT_OWNED_RESOURCE(src);
- GrDrawTarget::AutoStateRestore asr(fGpu);
+ GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
- drawState->reset();
drawState->setRenderTarget(dst);
GrMatrix sampleM;
sampleM.setIDiv(src->width(), src->height());
ASSERT_OWNED_RESOURCE(target);
if (NULL == target) {
- target = fGpu->drawState()->getRenderTarget();
+ target = fDrawState->getRenderTarget();
if (NULL == target) {
return;
}
this->internalWriteTexturePixels(texture, 0, 0, width, height,
config, buffer, rowBytes, flags);
- GrDrawTarget::AutoStateRestore asr(fGpu);
+ GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
- drawState->reset();
GrMatrix matrix;
matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
GrMatrix viewM = target->getDrawState().getViewMatrix();
GrScalar tol = GR_Scalar1;
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
- GrDrawState* drawState = target->drawState();
int vertexCnt;
int indexCnt;
}
GrAssert(NULL != target);
- GrDrawTarget::AutoStateRestore asr(target);
+ GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
+ GrDrawState* drawState = target->drawState();
bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
}
}
-void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
- state->fState.set(this->getDrawState());
-}
-
-void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
- *fDrawState = *state.fState.get();
-}
-
-void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
- *fDrawState = srcTarget.getDrawState();
-}
-
bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
int vertexCount,
void** vertices) {
fDrawTarget = NULL;
}
-GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
- fDrawTarget = target;
- if (NULL != fDrawTarget) {
- fDrawTarget->saveCurrentDrawState(&fDrawState);
- }
+GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
+ ASRInit init) {
+ fDrawTarget = NULL;
+ this->set(target, init);
}
GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
if (NULL != fDrawTarget) {
- fDrawTarget->restoreDrawState(fDrawState);
+ fDrawTarget->setDrawState(fSavedState);
+ fSavedState->unref();
}
}
-void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
- if (target != fDrawTarget) {
- if (NULL != fDrawTarget) {
- fDrawTarget->restoreDrawState(fDrawState);
- }
- if (NULL != target) {
- target->saveCurrentDrawState(&fDrawState);
- }
- fDrawTarget = target;
+void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) {
+ GrAssert(NULL == fDrawTarget);
+ fDrawTarget = target;
+ fSavedState = target->drawState();
+ GrAssert(fSavedState);
+ fSavedState->ref();
+ if (kReset_ASRInit == init) {
+ // calls the default cons
+ fTempState.init();
+ } else {
+ GrAssert(kPreserve_ASRInit == init);
+ // calls the copy cons
+ fTempState.set(*fSavedState);
}
+ target->setDrawState(fTempState.get());
}
////////////////////////////////////////////////////////////////////////////////
bool willUseHWAALines() const;
/**
- * Used to save and restore the GrGpu's drawing state
- */
- struct SavedDrawState {
- private:
- SkTLazy<GrDrawState> fState;
- friend class GrDrawTarget;
- };
-
- /**
- * Saves the current draw state. The state can be restored at a later time
- * with restoreDrawState.
- *
- * See also AutoStateRestore class.
- *
- * @param state will hold the state after the function returns.
- */
- void saveCurrentDrawState(SavedDrawState* state) const;
-
- /**
- * Restores previously saved draw state. The client guarantees that state
- * was previously passed to saveCurrentDrawState and that the rendertarget
- * and texture set at save are still valid.
- *
- * See also AutoStateRestore class.
- *
- * @param state the previously saved state to restore.
- */
- void restoreDrawState(const SavedDrawState& state);
-
- /**
- * Copies the draw state from another target to this target.
- *
- * @param srcTarget draw target used as src of the draw state.
- */
- void copyDrawState(const GrDrawTarget& srcTarget);
-
- /**
* The format of vertices is represented as a bitfield of flags.
* Flags that indicate the layout of vertex data. Vertices always contain
* positions and may also contain up to GrDrawState::kMaxTexCoords sets
////////////////////////////////////////////////////////////////////////////
+ /**
+ * See AutoStateRestore below.
+ */
+ enum ASRInit {
+ kPreserve_ASRInit,
+ kReset_ASRInit
+ };
+
+ /**
+ * Saves off the current state and restores it in the destructor. It will
+ * install a new GrDrawState object on the target (setDrawState) and restore
+ * the previous one in the destructor. The caller should call drawState() to
+ * get the new draw state after the ASR is installed.
+ *
+ * GrDrawState* state = target->drawState();
+ * AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit).
+ * state->setRenderTarget(rt); // state refers to the GrDrawState set on
+ * // target before asr was initialized.
+ * // Therefore, rt is set on the GrDrawState
+ * // that will be restored after asr's
+ * // destructor rather than target's current
+ * // GrDrawState.
+ */
class AutoStateRestore : ::GrNoncopyable {
public:
+ /**
+ * Default ASR will have no effect unless set() is subsequently called.
+ */
AutoStateRestore();
- AutoStateRestore(GrDrawTarget* target);
+
+ /**
+ * Saves the state on target. The state will be restored when the ASR
+ * is destroyed. If this constructor is used do not call set().
+ *
+ * @param init Should the newly installed GrDrawState be a copy of the
+ * previous state or a default-initialized GrDrawState.
+ */
+ AutoStateRestore(GrDrawTarget* target, ASRInit init);
+
~AutoStateRestore();
/**
- * if this object is already saving state for param target then
- * this does nothing. Otherise, it restores previously saved state on
- * previous target (if any) and saves current state on param target.
+ * Saves the state on target. The state will be restored when the ASR
+ * is destroyed. This should only be called once per ASR object and only
+ * when the default constructor was used. For nested saves use multiple
+ * ASR objects.
+ *
+ * @param init Should the newly installed GrDrawState be a copy of the
+ * previous state or a default-initialized GrDrawState.
*/
- void set(GrDrawTarget* target);
+ void set(GrDrawTarget* target, ASRInit init);
private:
- GrDrawTarget* fDrawTarget;
- SavedDrawState fDrawState;
+ GrDrawTarget* fDrawTarget;
+ SkTLazy<GrDrawState> fTempState;
+ GrDrawState* fSavedState;
};
////////////////////////////////////////////////////////////////////////////
return mask;
}
- // Helpers for GrDrawTarget subclasses that won't have private access to
- // SavedDrawState but need to peek at the state values.
- static GrDrawState& accessSavedDrawState(SavedDrawState& sds) {
- return *sds.fState.get();
- }
- static const GrDrawState& accessSavedDrawState(const SavedDrawState& sds){
- return *sds.fState.get();
- }
-
// A sublcass can optionally overload this function to be notified before
// vertex and index space is reserved.
virtual void willReserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
GrIRect clipRect;
GrDrawState* drawState = this->drawState();
- const GrRenderTarget* rt = drawState->getRenderTarget();
+ GrRenderTarget* rt = drawState->getRenderTarget();
// GrDrawTarget should have filtered this for us
GrAssert(NULL != rt);
const GrClip& clip = stencilBuffer->getLastClip();
fClip.setFromRect(bounds);
- AutoStateRestore asr(this);
+ AutoStateRestore asr(this, GrDrawTarget::kReset_ASRInit);
+ drawState = this->drawState();
+ drawState->setRenderTarget(rt);
AutoGeometryPush agp(this);
- drawState->viewMatrix()->reset();
this->flushScissor(NULL);
#if !VISUALIZE_COMPLEX_CLIP
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
-#else
- drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
#endif
+
int count = clip.getElementCount();
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) &&
this->resetIndexSource();
uint32_t numStates = fStates.count();
for (uint32_t i = 0; i < numStates; ++i) {
- const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- GrSafeUnref(dstate.getTexture(s));
+ GrSafeUnref(fStates[i].getTexture(s));
}
- GrSafeUnref(dstate.getRenderTarget());
+ GrSafeUnref(fStates[i].getRenderTarget());
}
int numDraws = fDraws.count();
for (int d = 0; d < numDraws; ++d) {
const Draw& draw = fDraws[i];
if (draw.fStateChanged) {
++currState;
- GrDrawState* ds = &GrDrawTarget::accessSavedDrawState(fStates[currState]);
- target->setDrawState(ds);
+ target->setDrawState(&fStates[currState]);
}
if (draw.fClipChanged) {
++currClip;
if (fStates.empty()) {
return true;
} else {
- const GrDrawState& old = this->accessSavedDrawState(fStates.back());
- return old != this->getDrawState();
+ return fStates.back() != this->getDrawState();
}
}
GrSafeRef(drawState.getTexture(s));
}
GrSafeRef(drawState.getRenderTarget());
- this->saveCurrentDrawState(&fStates.push_back());
+ fStates.push_back(this->getDrawState());
}
bool GrInOrderDrawBuffer::needsNewClip() const {
};
GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
- GrSTAllocator<kStatePreallocCnt, SavedDrawState> fStates;
+ GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
GrSTAllocator<kClearPreallocCnt, Clear> fClears;
GrSTAllocator<kClipPreallocCnt, GrClip> fClips;
GrDrawState::StageMask stageMask,
bool antiAlias) {
- GrDrawTarget::AutoStateRestore asr(target);
+ GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
GrDrawState* drawState = target->drawState();
// face culling doesn't make sense here
GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());