From 2a9ca782ba5db5a7ebdc315655d9a30dcd6d9845 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Fri, 5 Sep 2014 14:27:43 -0700 Subject: [PATCH] Make GrDrawState and GrEffectStage use the pending io/exec ref mechanisms. BUG=skia:2889 R=robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/542723004 --- include/gpu/GrEffectStage.h | 7 ++++--- include/gpu/GrProgramElementRef.h | 2 +- include/gpu/GrTextureAccess.h | 23 +++++++++++++++-------- src/gpu/GrDrawState.cpp | 9 ++++++--- src/gpu/GrDrawState.h | 8 +++++--- src/gpu/GrDrawTarget.h | 4 ++++ src/gpu/GrEffect.cpp | 1 + src/gpu/GrInOrderDrawBuffer.cpp | 8 ++++++-- src/gpu/GrRODrawState.cpp | 15 ++++++++++++++- src/gpu/GrRODrawState.h | 23 +++++++++++++++++++---- src/gpu/GrTextureAccess.cpp | 8 ++++---- 11 files changed, 79 insertions(+), 29 deletions(-) diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h index f4cee51417..a3ae9a8c51 100644 --- a/include/gpu/GrEffectStage.h +++ b/include/gpu/GrEffectStage.h @@ -13,9 +13,8 @@ #include "GrBackendEffectFactory.h" #include "GrEffect.h" +#include "GrProgramElementRef.h" #include "SkMatrix.h" -#include "GrTypes.h" - #include "SkShader.h" class GrEffectStage { @@ -136,10 +135,12 @@ public: const int* getVertexAttribIndices() const { return fVertexAttribIndices; } int getVertexAttribIndexCount() const { return fEffect->numVertexAttribs(); } + void convertToPendingExec() { fEffect.convertToPendingExec(); } + private: bool fCoordChangeMatrixSet; SkMatrix fCoordChangeMatrix; - SkAutoTUnref fEffect; + GrProgramElementRef fEffect; int fVertexAttribIndices[2]; }; diff --git a/include/gpu/GrProgramElementRef.h b/include/gpu/GrProgramElementRef.h index 1e3b4f8ebe..920ab78a48 100644 --- a/include/gpu/GrProgramElementRef.h +++ b/include/gpu/GrProgramElementRef.h @@ -42,7 +42,7 @@ public: operator T*() { return fObj; } /** If T is const, the type returned from operator-> will also be const. */ - typedef typename SkTConstType::BlockRef, + typedef typename SkTConstType::template BlockRef, SkTIsConst::value>::type BlockRefType; /** diff --git a/include/gpu/GrTextureAccess.h b/include/gpu/GrTextureAccess.h index 9f56171c60..3d44d9e44f 100644 --- a/include/gpu/GrTextureAccess.h +++ b/include/gpu/GrTextureAccess.h @@ -10,7 +10,7 @@ #include "SkRefCnt.h" #include "SkShader.h" -#include "SkTypes.h" +#include "GrProgramResource.h" class GrTexture; @@ -112,8 +112,10 @@ private: * key. However, if a GrEffect uses different swizzles based on its input then it must * consider that variation in its key-generation. */ -class GrTextureAccess : SkNoncopyable { +class GrTextureAccess : public SkNoncopyable { public: + SK_DECLARE_INST_COUNT_ROOT(GrTextureAccess); + /** * A default GrTextureAccess must have reset() called on it in a GrEffect subclass's * constructor if it will be accessible via GrEffect::textureAccess(). @@ -155,13 +157,18 @@ public: strcmp(fSwizzle, other.fSwizzle)); #endif return fParams == other.fParams && - (fTexture.get() == other.fTexture.get()) && + (this->getTexture() == other.getTexture()) && (0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1)); } bool operator!= (const GrTextureAccess& other) const { return !(*this == other); } - GrTexture* getTexture() const { return fTexture.get(); } + GrTexture* getTexture() const { return (GrTexture*)fTexture.getResource(); } + + /** + * For internal use by GrEffect. + */ + const GrProgramResource* getTextureProgramResource() const { return &fTexture; } /** * Returns a string representing the swizzle. The string is is null-terminated. @@ -177,10 +184,10 @@ public: private: void setSwizzle(const char*); - GrTextureParams fParams; - SkAutoTUnref fTexture; - uint32_t fSwizzleMask; - char fSwizzle[5]; + GrProgramResource fTexture; + GrTextureParams fParams; + uint32_t fSwizzleMask; + char fSwizzle[5]; typedef SkNoncopyable INHERITED; }; diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 4834811a87..ffec6627ca 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -69,7 +69,9 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr GrDrawState& GrDrawState::operator=(const GrDrawState& that) { SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); - this->setRenderTarget(that.fRenderTarget.get()); + SkASSERT(!that.fRenderTarget.ownsPendingIO()); + SkASSERT(!this->fRenderTarget.ownsPendingIO()); + this->setRenderTarget(that.getRenderTarget()); fColor = that.fColor; fViewMatrix = that.fViewMatrix; fSrcBlend = that.fSrcBlend; @@ -103,11 +105,13 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); + SkASSERT(!fRenderTarget.ownsPendingIO()); + fGeometryProcessor.reset(NULL); fColorStages.reset(); fCoverageStages.reset(); - fRenderTarget.reset(NULL); + fRenderTarget.reset(); this->setDefaultVertexAttribs(); @@ -609,4 +613,3 @@ bool GrDrawState::canIgnoreColorAttribute() const { return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFlag | GrRODrawState::kEmitCoverage_BlendOptFlag)); } - diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index f7dc69f0a1..2fe56a3d34 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -8,9 +8,9 @@ #ifndef GrDrawState_DEFINED #define GrDrawState_DEFINED -#include "GrRODrawState.h" - #include "GrBlend.h" +#include "GrProgramResource.h" +#include "GrRODrawState.h" #include "effects/GrSimpleTextureEffect.h" /** @@ -414,7 +414,9 @@ public: * * @param target The render target to set. */ - void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); } + void setRenderTarget(GrRenderTarget* target) { + fRenderTarget.setResource(SkSafeRef(target), GrProgramResource::kWrite_IOType); + } /// @} diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 814d57f326..8ffc681627 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -694,6 +694,10 @@ public: virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); } protected: + // Extend access to GrRODrawState::convertToPEndeingExec to subclasses. + void convertDrawStateToPendingExec(GrRODrawState* ds) { + ds->convertToPendingExec(); + } enum GeometrySrcType { kNone_GeometrySrcType, //addProgramResource(access->getTextureProgramResource()); } void* GrEffect::operator new(size_t size) { diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index b7180da45c..1f2692d576 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -888,14 +888,18 @@ void GrInOrderDrawBuffer::recordStateIfNecessary() { GrDrawState& prev = fStates.back(); switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) { case GrDrawState::kIncompatible_CombinedState: - fStates.push_back() = this->getDrawState(); + this->convertDrawStateToPendingExec(&fStates.push_back(curr)); this->addToCmdBuffer(kSetState_Cmd); break; case GrDrawState::kA_CombinedState: case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. break; case GrDrawState::kB_CombinedState: - prev = curr; + // prev has already been converted to pending execution. That is a one-way ticket. + // So here we just delete prev and push back a new copy of curr. Note that this + // goes away when we move GrIODB over to taking optimized snapshots of draw states. + fStates.pop_back(); + this->convertDrawStateToPendingExec(&fStates.push_back(curr)); break; } } diff --git a/src/gpu/GrRODrawState.cpp b/src/gpu/GrRODrawState.cpp index f2ac34b388..8d6c283f7a 100644 --- a/src/gpu/GrRODrawState.cpp +++ b/src/gpu/GrRODrawState.cpp @@ -16,7 +16,7 @@ bool GrRODrawState::isEqual(const GrRODrawState& that) const { return false; } - if (this->fRenderTarget.get() != that.fRenderTarget.get() || + if (this->getRenderTarget() != that.getRenderTarget() || this->fColorStages.count() != that.fColorStages.count() || this->fCoverageStages.count() != that.fCoverageStages.count() || !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || @@ -184,3 +184,16 @@ bool GrRODrawState::canTweakAlphaForCoverage() const { this->isCoverageDrawing(); } +void GrRODrawState::convertToPendingExec() { + fRenderTarget.markPendingIO(); + fRenderTarget.removeRef(); + for (int i = 0; i < fColorStages.count(); ++i) { + fColorStages[i].convertToPendingExec(); + } + if (fGeometryProcessor) { + fGeometryProcessor->convertToPendingExec(); + } + for (int i = 0; i < fCoverageStages.count(); ++i) { + fCoverageStages[i].convertToPendingExec(); + } +} diff --git a/src/gpu/GrRODrawState.h b/src/gpu/GrRODrawState.h index 19bbfc160d..bba50c5522 100644 --- a/src/gpu/GrRODrawState.h +++ b/src/gpu/GrRODrawState.h @@ -8,13 +8,13 @@ #ifndef GrRODrawState_DEFINED #define GrRODrawState_DEFINED -#include "GrStencil.h" #include "GrEffectStage.h" +#include "GrRenderTarget.h" +#include "GrStencil.h" #include "SkMatrix.h" class GrDrawTargetCaps; class GrPaint; -class GrRenderTarget; class GrTexture; /** @@ -243,7 +243,9 @@ public: * * @return The currently set render target. */ - GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } + GrRenderTarget* getRenderTarget() const { + return static_cast(fRenderTarget.getResource()); + } /// @} @@ -344,11 +346,24 @@ public: kB_CombinedState, }; +protected: + /** + * Converts refs on GrGpuResources owned directly or indirectly by this GrRODrawState into + * pending reads and writes. This should be called when a GrDrawState is recorded into + * a GrDrawTarget for later execution. Subclasses of GrRODrawState may add setters. However, + * once this call has been made the GrRODrawState is immutable. It is also no longer copyable. + * In the future this conversion will automatically happen when converting a GrDrawState into + * an optimized draw state. + */ + void convertToPendingExec(); + + friend class GrDrawTarget; + protected: bool isEqual(const GrRODrawState& that) const; // These fields are roughly sorted by decreasing likelihood of being different in op== - SkAutoTUnref fRenderTarget; + GrProgramResource fRenderTarget; GrColor fColor; SkMatrix fViewMatrix; GrColor fBlendConstant; diff --git a/src/gpu/GrTextureAccess.cpp b/src/gpu/GrTextureAccess.cpp index b0c760f054..0886db411a 100644 --- a/src/gpu/GrTextureAccess.cpp +++ b/src/gpu/GrTextureAccess.cpp @@ -46,7 +46,7 @@ void GrTextureAccess::reset(GrTexture* texture, SkASSERT(strlen(swizzle) >= 1 && strlen(swizzle) <= 4); fParams = params; - fTexture.reset(SkRef(texture)); + fTexture.setResource(SkRef(texture), GrProgramResource::kRead_IOType); this->setSwizzle(swizzle); } @@ -58,14 +58,14 @@ void GrTextureAccess::reset(GrTexture* texture, SkASSERT(strlen(swizzle) >= 1 && strlen(swizzle) <= 4); fParams.reset(tileXAndY, filterMode); - fTexture.reset(SkRef(texture)); + fTexture.setResource(SkRef(texture), GrProgramResource::kRead_IOType); this->setSwizzle(swizzle); } void GrTextureAccess::reset(GrTexture* texture, const GrTextureParams& params) { SkASSERT(texture); - fTexture.reset(SkRef(texture)); + fTexture.setResource(SkRef(texture), GrProgramResource::kRead_IOType); fParams = params; memcpy(fSwizzle, "rgba", 5); fSwizzleMask = kRGBA_GrColorComponentFlags; @@ -75,7 +75,7 @@ void GrTextureAccess::reset(GrTexture* texture, GrTextureParams::FilterMode filterMode, SkShader::TileMode tileXAndY) { SkASSERT(texture); - fTexture.reset(SkRef(texture)); + fTexture.setResource(SkRef(texture), GrProgramResource::kRead_IOType); fParams.reset(tileXAndY, filterMode); memcpy(fSwizzle, "rgba", 5); fSwizzleMask = kRGBA_GrColorComponentFlags;