Move DstCoordTexture to GrXP, rename and remove the word "copy" from dstcopytexture names.

Review URL: https://codereview.chromium.org/1132093004
This commit is contained in:
bsalomon 2015-05-22 14:32:10 -07:00 committed by Commit bot
parent 3e2d59ef36
commit bb106b5f6e
27 changed files with 171 additions and 170 deletions

View File

@ -70,43 +70,4 @@ private:
typedef GrSurface INHERITED; typedef GrSurface INHERITED;
}; };
/**
* Represents a texture that is intended to be accessed in device coords with an offset.
*/
class GrDeviceCoordTexture {
public:
GrDeviceCoordTexture() { fOffset.set(0, 0); }
GrDeviceCoordTexture(const GrDeviceCoordTexture& other) {
*this = other;
}
GrDeviceCoordTexture(GrTexture* texture, const SkIPoint& offset)
: fTexture(SkSafeRef(texture))
, fOffset(offset) {
}
GrDeviceCoordTexture& operator=(const GrDeviceCoordTexture& other) {
fTexture.reset(SkSafeRef(other.fTexture.get()));
fOffset = other.fOffset;
return *this;
}
const SkIPoint& offset() const { return fOffset; }
void setOffset(const SkIPoint& offset) { fOffset = offset; }
void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
GrTexture* texture() const { return fTexture.get(); }
GrTexture* setTexture(GrTexture* texture) {
fTexture.reset(SkSafeRef(texture));
return texture;
}
private:
SkAutoTUnref<GrTexture> fTexture;
SkIPoint fOffset;
};
#endif #endif

View File

@ -103,6 +103,47 @@ enum GrXferBarrierType {
*/ */
class GrXferProcessor : public GrProcessor { class GrXferProcessor : public GrProcessor {
public: public:
/**
* A texture that contains the dst pixel values and an integer coord offset from device space
* to the space of the texture. Depending on GPU capabilities a DstTexture may be used by a
* GrXferProcessor for blending in the fragment shader.
*/
class DstTexture {
public:
DstTexture() { fOffset.set(0, 0); }
DstTexture(const DstTexture& other) {
*this = other;
}
DstTexture(GrTexture* texture, const SkIPoint& offset)
: fTexture(SkSafeRef(texture))
, fOffset(offset) {
}
DstTexture& operator=(const DstTexture& other) {
fTexture.reset(SkSafeRef(other.fTexture.get()));
fOffset = other.fOffset;
return *this;
}
const SkIPoint& offset() const { return fOffset; }
void setOffset(const SkIPoint& offset) { fOffset = offset; }
void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
GrTexture* texture() const { return fTexture.get(); }
GrTexture* setTexture(GrTexture* texture) {
fTexture.reset(SkSafeRef(texture));
return texture;
}
private:
SkAutoTUnref<GrTexture> fTexture;
SkIPoint fOffset;
};
/** /**
* Sets a unique key on the GrProcessorKeyBuilder calls onGetGLProcessorKey(...) to get the * Sets a unique key on the GrProcessorKeyBuilder calls onGetGLProcessorKey(...) to get the
* specific subclass's key. * specific subclass's key.
@ -199,15 +240,15 @@ public:
* shader. If the returned texture is NULL then the XP is either not reading the dst or we have * shader. If the returned texture is NULL then the XP is either not reading the dst or we have
* extentions that support framebuffer fetching and thus don't need a copy of the dst texture. * extentions that support framebuffer fetching and thus don't need a copy of the dst texture.
*/ */
const GrTexture* getDstCopyTexture() const { return fDstCopy.getTexture(); } const GrTexture* getDstTexture() const { return fDstTexture.getTexture(); }
/** /**
* Returns the offset into the DstCopyTexture to use when reading it in the shader. This value * Returns the offset in device coords to use when accessing the dst texture to get the dst
* is only valid if getDstCopyTexture() != NULL. * pixel color in the shader. This value is only valid if getDstTexture() != NULL.
*/ */
const SkIPoint& dstCopyTextureOffset() const { const SkIPoint& dstTextureOffset() const {
SkASSERT(this->getDstCopyTexture()); SkASSERT(this->getDstTexture());
return fDstCopyTextureOffset; return fDstTextureOffset;
} }
/** /**
@ -238,10 +279,10 @@ public:
if (this->fReadsCoverage != that.fReadsCoverage) { if (this->fReadsCoverage != that.fReadsCoverage) {
return false; return false;
} }
if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) { if (this->fDstTexture.getTexture() != that.fDstTexture.getTexture()) {
return false; return false;
} }
if (this->fDstCopyTextureOffset != that.fDstCopyTextureOffset) { if (this->fDstTextureOffset != that.fDstTextureOffset) {
return false; return false;
} }
return this->onIsEqual(that); return this->onIsEqual(that);
@ -249,7 +290,7 @@ public:
protected: protected:
GrXferProcessor(); GrXferProcessor();
GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); GrXferProcessor(const DstTexture*, bool willReadDstColor);
private: private:
virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
@ -286,8 +327,8 @@ private:
bool fWillReadDstColor; bool fWillReadDstColor;
bool fReadsCoverage; bool fReadsCoverage;
SkIPoint fDstCopyTextureOffset; SkIPoint fDstTextureOffset;
GrTextureAccess fDstCopy; GrTextureAccess fDstTexture;
typedef GrFragmentProcessor INHERITED; typedef GrFragmentProcessor INHERITED;
}; };
@ -309,9 +350,10 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
*/ */
class GrXPFactory : public SkRefCnt { class GrXPFactory : public SkRefCnt {
public: public:
typedef GrXferProcessor::DstTexture DstTexture;
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI, GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy, const DstTexture*,
const GrCaps& caps) const; const GrCaps& caps) const;
/** /**
@ -335,7 +377,7 @@ public:
virtual void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, virtual void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
InvariantOutput*) const = 0; InvariantOutput*) const = 0;
bool willNeedDstCopy(const GrCaps& caps, const GrProcOptInfo& colorPOI, bool willNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const; const GrProcOptInfo& coveragePOI) const;
bool isEqual(const GrXPFactory& that) const { bool isEqual(const GrXPFactory& that) const {
@ -366,7 +408,7 @@ private:
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const = 0; const DstTexture*) const = 0;
/** /**
* Returns true if the XP generated by this factory will explicitly read dst in the fragment * Returns true if the XP generated by this factory will explicitly read dst in the fragment
* shader. * shader.

View File

@ -37,7 +37,7 @@ private:
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const override; const DstTexture*) const override;
bool willReadDstColor(const GrCaps& /*caps*/, bool willReadDstColor(const GrCaps& /*caps*/,
const GrProcOptInfo& /*colorPOI*/, const GrProcOptInfo& /*colorPOI*/,

View File

@ -29,7 +29,7 @@ private:
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const override; const DstTexture*) const override;
bool willReadDstColor(const GrCaps& caps, bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,

View File

@ -161,9 +161,8 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticFP);
class ArithmeticXP : public GrXferProcessor { class ArithmeticXP : public GrXferProcessor {
public: public:
static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor, static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy, const DstTexture* dstTexture, bool willReadDstColor) {
bool willReadDstColor) { return SkNEW_ARGS(ArithmeticXP, (k1, k2, k3, k4, enforcePMColor, dstTexture,
return SkNEW_ARGS(ArithmeticXP, (k1, k2, k3, k4, enforcePMColor, dstCopy,
willReadDstColor)); willReadDstColor));
} }
@ -183,7 +182,7 @@ public:
private: private:
ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor, ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); const DstTexture*, bool willReadDstColor);
GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
@ -263,8 +262,8 @@ private:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
ArithmeticXP::ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor, ArithmeticXP::ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) const DstTexture* dstTexture, bool willReadDstColor)
: INHERITED(dstCopy, willReadDstColor) : INHERITED(dstTexture, willReadDstColor)
, fK1(k1) , fK1(k1)
, fK2(k2) , fK2(k2)
, fK3(k3) , fK3(k3)
@ -301,8 +300,8 @@ GrXferProcessor*
GrArithmeticXPFactory::onCreateXferProcessor(const GrCaps& caps, GrArithmeticXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const { const DstTexture* dstTexture) const {
return ArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstCopy, return ArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstTexture,
this->willReadDstColor(caps, colorPOI, coveragePOI)); this->willReadDstColor(caps, colorPOI, coveragePOI));
} }

View File

@ -90,7 +90,7 @@ private:
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const override; const DstTexture*) const override;
bool willReadDstColor(const GrCaps& caps, bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,

View File

@ -43,9 +43,9 @@ GrDrawTarget::GrDrawTarget(GrContext* context)
bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder, bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
GrDeviceCoordTexture* dstCopy, GrXferProcessor::DstTexture* dstTexture,
const SkRect* drawBounds) { const SkRect* drawBounds) {
if (!pipelineBuilder.willXPNeedDstCopy(*this->caps(), colorPOI, coveragePOI)) { if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), colorPOI, coveragePOI)) {
return true; return true;
} }
@ -55,8 +55,8 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
if (GrTexture* rtTex = rt->asTexture()) { if (GrTexture* rtTex = rt->asTexture()) {
// The render target is a texture, se we can read from it directly in the shader. The XP // The render target is a texture, se we can read from it directly in the shader. The XP
// will be responsible to detect this situation and request a texture barrier. // will be responsible to detect this situation and request a texture barrier.
dstCopy->setTexture(rtTex); dstTexture->setTexture(rtTex);
dstCopy->setOffset(0, 0); dstTexture->setOffset(0, 0);
return true; return true;
} }
} }
@ -102,8 +102,8 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
} }
SkIPoint dstPoint = {0, 0}; SkIPoint dstPoint = {0, 0};
if (this->copySurface(copy, rt, copyRect, dstPoint)) { if (this->copySurface(copy, rt, copyRect, dstPoint)) {
dstCopy->setTexture(copy); dstTexture->setTexture(copy);
dstCopy->setOffset(copyRect.fLeft, copyRect.fTop); dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
return true; return true;
} else { } else {
return false; return false;
@ -497,7 +497,7 @@ void GrDrawTarget::setupPipeline(const PipelineInfo& pipelineInfo,
pipelineInfo.fCoveragePOI, pipelineInfo.fCoveragePOI,
*this->caps(), *this->caps(),
*pipelineInfo.fScissor, *pipelineInfo.fScissor,
&pipelineInfo.fDstCopy)); &pipelineInfo.fDstTexture));
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -511,7 +511,7 @@ GrDrawTarget::PipelineInfo::PipelineInfo(GrPipelineBuilder* pipelineBuilder,
fColorPOI = fPipelineBuilder->colorProcInfo(primProc); fColorPOI = fPipelineBuilder->colorProcInfo(primProc);
fCoveragePOI = fPipelineBuilder->coverageProcInfo(primProc); fCoveragePOI = fPipelineBuilder->coverageProcInfo(primProc);
if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI, if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI,
&fDstCopy, devBounds)) { &fDstTexture, devBounds)) {
fPipelineBuilder = NULL; fPipelineBuilder = NULL;
} }
} }
@ -526,7 +526,7 @@ GrDrawTarget::PipelineInfo::PipelineInfo(GrPipelineBuilder* pipelineBuilder,
fColorPOI = fPipelineBuilder->colorProcInfo(batch); fColorPOI = fPipelineBuilder->colorProcInfo(batch);
fCoveragePOI = fPipelineBuilder->coverageProcInfo(batch); fCoveragePOI = fPipelineBuilder->coverageProcInfo(batch);
if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI, if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI,
&fDstCopy, devBounds)) { &fDstTexture, devBounds)) {
fPipelineBuilder = NULL; fPipelineBuilder = NULL;
} }
} }

View File

@ -18,6 +18,7 @@
#include "GrPipelineBuilder.h" #include "GrPipelineBuilder.h"
#include "GrTraceMarker.h" #include "GrTraceMarker.h"
#include "GrVertexBuffer.h" #include "GrVertexBuffer.h"
#include "GrXferProcessor.h"
#include "SkClipStack.h" #include "SkClipStack.h"
#include "SkMatrix.h" #include "SkMatrix.h"
@ -230,7 +231,7 @@ protected:
bool setupDstReadIfNecessary(const GrPipelineBuilder&, bool setupDstReadIfNecessary(const GrPipelineBuilder&,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
GrDeviceCoordTexture* dstCopy, GrXferProcessor::DstTexture*,
const SkRect* drawBounds); const SkRect* drawBounds);
struct PipelineInfo { struct PipelineInfo {
@ -254,7 +255,7 @@ protected:
GrScissorState* fScissor; GrScissorState* fScissor;
GrProcOptInfo fColorPOI; GrProcOptInfo fColorPOI;
GrProcOptInfo fCoveragePOI; GrProcOptInfo fCoveragePOI;
GrDeviceCoordTexture fDstCopy; GrXferProcessor::DstTexture fDstTexture;
}; };
void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline); void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline);

View File

@ -19,10 +19,11 @@ GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrCaps& caps, const GrCaps& caps,
const GrScissorState& scissorState, const GrScissorState& scissorState,
const GrDeviceCoordTexture* dstCopy) { const GrXferProcessor::DstTexture* dstTexture) {
// Create XferProcessor from DS's XPFactory // Create XferProcessor from DS's XPFactory
SkAutoTUnref<GrXferProcessor> xferProcessor( SkAutoTUnref<GrXferProcessor> xferProcessor(
pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI, dstCopy, caps)); pipelineBuilder.getXPFactory()->createXferProcessor(
colorPOI, coveragePOI, dstTexture, caps));
GrColor overrideColor = GrColor_ILLEGAL; GrColor overrideColor = GrColor_ILLEGAL;
if (colorPOI.firstEffectiveStageIndex() != 0) { if (colorPOI.firstEffectiveStageIndex() != 0) {

View File

@ -34,7 +34,7 @@ public:
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrCaps&, const GrCaps&,
const GrScissorState&, const GrScissorState&,
const GrDeviceCoordTexture* dstCopy); const GrXferProcessor::DstTexture*);
/* /*
* Returns true if these pipelines are equivalent. * Returns true if these pipelines are equivalent.

View File

@ -86,10 +86,10 @@ void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, c
//////////////////////////////////////////////////////////////////////////////s //////////////////////////////////////////////////////////////////////////////s
bool GrPipelineBuilder::willXPNeedDstCopy(const GrCaps& caps, bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const { const GrProcOptInfo& coveragePOI) const {
return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI); return this->getXPFactory()->willNeedDstTexture(caps, colorPOI, coveragePOI);
} }
void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) { void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) {

View File

@ -177,9 +177,9 @@ public:
} }
/** /**
* Checks whether the xp will need a copy of the destination to correctly blend. * Checks whether the xp will need destination in a texture to correctly blend.
*/ */
bool willXPNeedDstCopy(const GrCaps& caps, const GrProcOptInfo& colorPOI, bool willXPNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const; const GrProcOptInfo& coveragePOI) const;
/// @} /// @}

View File

@ -9,17 +9,17 @@
#include "gl/GrGLCaps.h" #include "gl/GrGLCaps.h"
GrXferProcessor::GrXferProcessor() GrXferProcessor::GrXferProcessor()
: fWillReadDstColor(false), fReadsCoverage(true), fDstCopyTextureOffset() { : fWillReadDstColor(false), fReadsCoverage(true), fDstTextureOffset() {
} }
GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture, bool willReadDstColor)
: fWillReadDstColor(willReadDstColor) : fWillReadDstColor(willReadDstColor)
, fReadsCoverage(true) , fReadsCoverage(true)
, fDstCopyTextureOffset() { , fDstTextureOffset() {
if (dstCopy && dstCopy->texture()) { if (dstTexture && dstTexture->texture()) {
fDstCopy.reset(dstCopy->texture()); fDstTexture.reset(dstTexture->texture());
fDstCopyTextureOffset = dstCopy->offset(); fDstTextureOffset = dstTexture->offset();
this->addTextureAccess(&fDstCopy); this->addTextureAccess(&fDstTexture);
this->setWillReadFragmentPosition(); this->setWillReadFragmentPosition();
} }
} }
@ -43,8 +43,8 @@ GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrProcOptInfo&
void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
uint32_t key = this->willReadDstColor() ? 0x1 : 0x0; uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
if (this->getDstCopyTexture() && if (this->getDstTexture() &&
kTopLeft_GrSurfaceOrigin == this->getDstCopyTexture()->origin()) { kTopLeft_GrSurfaceOrigin == this->getDstTexture()->origin()) {
key |= 0x2; key |= 0x2;
} }
b->add32(key); b->add32(key);
@ -54,7 +54,7 @@ void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBu
bool GrXferProcessor::willNeedXferBarrier(const GrRenderTarget* rt, bool GrXferProcessor::willNeedXferBarrier(const GrRenderTarget* rt,
const GrCaps& caps, const GrCaps& caps,
GrXferBarrierType* outBarrierType) const { GrXferBarrierType* outBarrierType) const {
if (static_cast<const GrSurface*>(rt) == this->getDstCopyTexture()) { if (static_cast<const GrSurface*>(rt) == this->getDstTexture()) {
// Texture barriers are required when a shader reads and renders to the same texture. // Texture barriers are required when a shader reads and renders to the same texture.
SkASSERT(rt); SkASSERT(rt);
SkASSERT(caps.textureBarrierSupport()); SkASSERT(caps.textureBarrierSupport());
@ -162,25 +162,24 @@ SkString GrXferProcessor::BlendInfo::dump() const {
GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI, GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy, const DstTexture* dstTexture,
const GrCaps& caps) const { const GrCaps& caps) const {
#ifdef SK_DEBUG #ifdef SK_DEBUG
if (this->willReadDstColor(caps, colorPOI, coveragePOI)) { if (this->willReadDstColor(caps, colorPOI, coveragePOI)) {
if (!caps.shaderCaps()->dstReadInShaderSupport()) { if (!caps.shaderCaps()->dstReadInShaderSupport()) {
SkASSERT(dstCopy && dstCopy->texture()); SkASSERT(dstTexture && dstTexture->texture());
} else { } else {
SkASSERT(!dstCopy || !dstCopy->texture()); SkASSERT(!dstTexture || !dstTexture->texture());
} }
} else { } else {
SkASSERT(!dstCopy || !dstCopy->texture()); SkASSERT(!dstTexture || !dstTexture->texture());
} }
#endif #endif
return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, dstCopy); return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, dstTexture);
} }
bool GrXPFactory::willNeedDstCopy(const GrCaps& caps, const GrProcOptInfo& colorPOI, bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const { const GrProcOptInfo& coveragePOI) const {
return (this->willReadDstColor(caps, colorPOI, coveragePOI) return (this->willReadDstColor(caps, colorPOI, coveragePOI)
&& !caps.shaderCaps()->dstReadInShaderSupport()); && !caps.shaderCaps()->dstReadInShaderSupport());
} }

View File

@ -226,7 +226,8 @@ GrXferProcessor*
GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps, GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI, const GrProcOptInfo& covPOI,
const GrDeviceCoordTexture* dstCopy) const { const DstTexture* dst) const {
SkASSERT(!dst);
return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage); return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
} }

View File

@ -508,12 +508,12 @@ GrFragmentProcessor* GrCustomXferFP::TestCreate(SkRandom* rand,
class CustomXP : public GrXferProcessor { class CustomXP : public GrXferProcessor {
public: public:
static GrXferProcessor* Create(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, static GrXferProcessor* Create(SkXfermode::Mode mode, const DstTexture* dstTexture,
bool willReadDstColor) { bool willReadDstColor) {
if (!GrCustomXfermode::IsSupportedMode(mode)) { if (!GrCustomXfermode::IsSupportedMode(mode)) {
return NULL; return NULL;
} else { } else {
return SkNEW_ARGS(CustomXP, (mode, dstCopy, willReadDstColor)); return SkNEW_ARGS(CustomXP, (mode, dstTexture, willReadDstColor));
} }
} }
@ -534,7 +534,7 @@ public:
} }
private: private:
CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); CustomXP(SkXfermode::Mode mode, const DstTexture*, bool willReadDstColor);
GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
@ -626,9 +626,8 @@ private:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, CustomXP::CustomXP(SkXfermode::Mode mode, const DstTexture* dstTexture, bool willReadDstColor)
bool willReadDstColor) : INHERITED(dstTexture, willReadDstColor),
: INHERITED(dstCopy, willReadDstColor),
fMode(mode), fMode(mode),
fHWBlendEquation(static_cast<GrBlendEquation>(-1)) { fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
this->initClassID<CustomXP>(); this->initClassID<CustomXP>();
@ -790,8 +789,8 @@ GrXferProcessor*
GrCustomXPFactory::onCreateXferProcessor(const GrCaps& caps, GrCustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const { const DstTexture* dstTexture) const {
return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPOI, coveragePOI)); return CustomXP::Create(fMode, dstTexture, this->willReadDstColor(caps, colorPOI, coveragePOI));
} }
bool GrCustomXPFactory::willReadDstColor(const GrCaps& caps, bool GrCustomXPFactory::willReadDstColor(const GrCaps& caps,

View File

@ -71,7 +71,7 @@ private:
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const override; const DstTexture*) const override;
bool willReadDstColor(const GrCaps& caps, bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,

View File

@ -103,7 +103,8 @@ GrXferProcessor*
GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps, GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI, const GrProcOptInfo& covPOI,
const GrDeviceCoordTexture* dstCopy) const { const DstTexture* dst) const {
SkASSERT(!dst);
return DisableColorXP::Create(); return DisableColorXP::Create();
} }

View File

@ -35,7 +35,7 @@ private:
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const override; const DstTexture* dstTexture) const override;
bool willReadDstColor(const GrCaps& caps, bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,

View File

@ -307,9 +307,9 @@ static BlendFormula get_unoptimized_blend_formula(SkXfermode::Mode xfermode) {
class PorterDuffXferProcessor : public GrXferProcessor { class PorterDuffXferProcessor : public GrXferProcessor {
public: public:
static GrXferProcessor* Create(SkXfermode::Mode xfermode, const GrDeviceCoordTexture* dstCopy, static GrXferProcessor* Create(SkXfermode::Mode xfermode, const DstTexture* dstTexture,
bool willReadDstColor) { bool willReadDstColor) {
return SkNEW_ARGS(PorterDuffXferProcessor, (xfermode, dstCopy, willReadDstColor)); return SkNEW_ARGS(PorterDuffXferProcessor, (xfermode, dstTexture, willReadDstColor));
} }
~PorterDuffXferProcessor() override; ~PorterDuffXferProcessor() override;
@ -326,8 +326,7 @@ public:
BlendFormula getBlendFormula() const { return fBlendFormula; } BlendFormula getBlendFormula() const { return fBlendFormula; }
private: private:
PorterDuffXferProcessor(SkXfermode::Mode, const GrDeviceCoordTexture* dstCopy, PorterDuffXferProcessor(SkXfermode::Mode, const DstTexture*, bool willReadDstColor);
bool willReadDstColor);
GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI, const GrProcOptInfo& coveragePOI,
@ -506,9 +505,9 @@ private:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
PorterDuffXferProcessor::PorterDuffXferProcessor(SkXfermode::Mode xfermode, PorterDuffXferProcessor::PorterDuffXferProcessor(SkXfermode::Mode xfermode,
const GrDeviceCoordTexture* dstCopy, const DstTexture* dstTexture,
bool willReadDstColor) bool willReadDstColor)
: INHERITED(dstCopy, willReadDstColor) : INHERITED(dstTexture, willReadDstColor)
, fXfermode(xfermode) , fXfermode(xfermode)
, fBlendFormula(get_unoptimized_blend_formula(xfermode)) { , fBlendFormula(get_unoptimized_blend_formula(xfermode)) {
this->initClassID<PorterDuffXferProcessor>(); this->initClassID<PorterDuffXferProcessor>();
@ -723,11 +722,11 @@ GrXferProcessor*
GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI, const GrProcOptInfo& covPOI,
const GrDeviceCoordTexture* dstCopy) const { const DstTexture* dstTexture) const {
if (covPOI.isFourChannelOutput()) { if (covPOI.isFourChannelOutput()) {
return PDLCDXferProcessor::Create(fXfermode, colorPOI); return PDLCDXferProcessor::Create(fXfermode, colorPOI);
} else { } else {
return PorterDuffXferProcessor::Create(fXfermode, dstCopy, return PorterDuffXferProcessor::Create(fXfermode, dstTexture,
this->willReadDstColor(caps, colorPOI, covPOI)); this->willReadDstColor(caps, colorPOI, covPOI));
} }
} }

View File

@ -36,7 +36,7 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
GrGLInstalledFragProcs* fragmentProcessors) GrGLInstalledFragProcs* fragmentProcessors)
: fColor(GrColor_ILLEGAL) : fColor(GrColor_ILLEGAL)
, fCoverage(0) , fCoverage(0)
, fDstCopyTexUnit(-1) , fDstTextureUnit(-1)
, fBuiltinUniformHandles(builtinUniforms) , fBuiltinUniformHandles(builtinUniforms)
, fProgramID(programID) , fProgramID(programID)
, fGeometryProcessor(geometryProcessor) , fGeometryProcessor(geometryProcessor)

View File

@ -138,7 +138,7 @@ protected:
RenderTargetState fRenderTargetState; RenderTargetState fRenderTargetState;
GrColor fColor; GrColor fColor;
uint8_t fCoverage; uint8_t fCoverage;
int fDstCopyTexUnit; int fDstTextureUnit;
BuiltinUniformHandles fBuiltinUniformHandles; BuiltinUniformHandles fBuiltinUniformHandles;
GrGLuint fProgramID; GrGLuint fProgramID;

View File

@ -54,8 +54,6 @@ public:
* this optstate. * this optstate.
* @param GrGLGpu A GL Gpu, the caps and Gpu object are used to output processor specific * @param GrGLGpu A GL Gpu, the caps and Gpu object are used to output processor specific
* parts of the descriptor. * parts of the descriptor.
* @param GrDeviceCoordTexture A dstCopy texture, which may be null if frame buffer fetch is
* supported
* @param GrProgramDesc The built and finalized descriptor * @param GrProgramDesc The built and finalized descriptor
**/ **/
static bool Build(GrProgramDesc*, static bool Build(GrProgramDesc*,

View File

@ -12,8 +12,8 @@
#include "gl/builders/GrGLProgramBuilder.h" #include "gl/builders/GrGLProgramBuilder.h"
void GrGLXferProcessor::emitCode(const EmitArgs& args) { void GrGLXferProcessor::emitCode(const EmitArgs& args) {
if (args.fXP.getDstCopyTexture()) { if (args.fXP.getDstTexture()) {
bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstCopyTexture()->origin(); bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@ -27,24 +27,24 @@ void GrGLXferProcessor::emitCode(const EmitArgs& args) {
const char* dstColor = fsBuilder->dstColor(); const char* dstColor = fsBuilder->dstColor();
const char* dstCopyTopLeftName; const char* dstTopLeftName;
const char* dstCopyCoordScaleName; const char* dstCoordScaleName;
fDstCopyTopLeftUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, fDstTopLeftUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, kVec2f_GrSLType,
kDefault_GrSLPrecision, kDefault_GrSLPrecision,
"DstCopyUpperLeft", "DstTextureUpperLeft",
&dstCopyTopLeftName); &dstTopLeftName);
fDstCopyScaleUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, fDstScaleUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, kVec2f_GrSLType,
kDefault_GrSLPrecision, kDefault_GrSLPrecision,
"DstCopyCoordScale", "DstTextureCoordScale",
&dstCopyCoordScaleName); &dstCoordScaleName);
const char* fragPos = fsBuilder->fragmentPosition(); const char* fragPos = fsBuilder->fragmentPosition();
fsBuilder->codeAppend("// Read color from copy of the destination.\n"); fsBuilder->codeAppend("// Read color from copy of the destination.\n");
fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;", fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); fragPos, dstTopLeftName, dstCoordScaleName);
if (!topDown) { if (!topDown) {
fsBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;"); fsBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
@ -59,18 +59,18 @@ void GrGLXferProcessor::emitCode(const EmitArgs& args) {
} }
void GrGLXferProcessor::setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp) { void GrGLXferProcessor::setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp) {
if (xp.getDstCopyTexture()) { if (xp.getDstTexture()) {
if (fDstCopyTopLeftUni.isValid()) { if (fDstTopLeftUni.isValid()) {
pdm.set2f(fDstCopyTopLeftUni, static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fX), pdm.set2f(fDstTopLeftUni, static_cast<GrGLfloat>(xp.dstTextureOffset().fX),
static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fY)); static_cast<GrGLfloat>(xp.dstTextureOffset().fY));
pdm.set2f(fDstCopyScaleUni, 1.f / xp.getDstCopyTexture()->width(), pdm.set2f(fDstScaleUni, 1.f / xp.getDstTexture()->width(),
1.f / xp.getDstCopyTexture()->height()); 1.f / xp.getDstTexture()->height());
} else { } else {
SkASSERT(!fDstCopyScaleUni.isValid()); SkASSERT(!fDstScaleUni.isValid());
} }
} else { } else {
SkASSERT(!fDstCopyTopLeftUni.isValid()); SkASSERT(!fDstTopLeftUni.isValid());
SkASSERT(!fDstCopyScaleUni.isValid()); SkASSERT(!fDstScaleUni.isValid());
} }
this->onSetData(pdm, xp); this->onSetData(pdm, xp);
} }

View File

@ -63,8 +63,8 @@ private:
virtual void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) = 0; virtual void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) = 0;
GrGLProgramDataManager::UniformHandle fDstCopyTopLeftUni; GrGLProgramDataManager::UniformHandle fDstTopLeftUni;
GrGLProgramDataManager::UniformHandle fDstCopyScaleUni; GrGLProgramDataManager::UniformHandle fDstScaleUni;
typedef GrGLProcessor INHERITED; typedef GrGLProcessor INHERITED;
}; };

View File

@ -12,7 +12,7 @@
#define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X) #define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X) #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X)
const char* GrGLFragmentShaderBuilder::kDstCopyColorName = "_dstColor"; const char* GrGLFragmentShaderBuilder::kDstTextureColorName = "_dstColor";
static const char* declared_color_output_name() { return "fsColorOut"; } static const char* declared_color_output_name() { return "fsColorOut"; }
static const char* dual_source_output_name() { return "dualSourceOut"; } static const char* dual_source_output_name() { return "dualSourceOut"; }
static void append_default_precision_qualifier(GrSLPrecision p, static void append_default_precision_qualifier(GrSLPrecision p,
@ -78,17 +78,17 @@ static const char* specific_layout_qualifier_name(GrBlendEquation equation) {
} }
GrGLFragmentShaderBuilder::DstReadKey GrGLFragmentShaderBuilder::DstReadKey
GrGLFragmentShaderBuilder::KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps& caps) { GrGLFragmentShaderBuilder::KeyForDstRead(const GrTexture* dstTexture, const GrGLCaps& caps) {
uint32_t key = kYesDstRead_DstReadKeyBit; uint32_t key = kYesDstRead_DstReadKeyBit;
if (caps.glslCaps()->fbFetchSupport()) { if (caps.glslCaps()->fbFetchSupport()) {
return key; return key;
} }
SkASSERT(dstCopy); SkASSERT(dstTexture);
if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) { if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstTexture->config())) {
// The fact that the config is alpha-only must be considered when generating code. // The fact that the config is alpha-only must be considered when generating code.
key |= kUseAlphaConfig_DstReadKeyBit; key |= kUseAlphaConfig_DstReadKeyBit;
} }
if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) { if (kTopLeft_GrSurfaceOrigin == dstTexture->origin()) {
key |= kTopLeftOrigin_DstReadKeyBit; key |= kTopLeftOrigin_DstReadKeyBit;
} }
SkASSERT(static_cast<DstReadKey>(key) == key); SkASSERT(static_cast<DstReadKey>(key) == key);
@ -220,7 +220,7 @@ const char* GrGLFragmentShaderBuilder::dstColor() {
} }
return fbFetchColorName; return fbFetchColorName;
} else { } else {
return kDstCopyColorName; return kDstTextureColorName;
} }
} }

View File

@ -81,10 +81,10 @@ public:
typedef uint8_t DstReadKey; typedef uint8_t DstReadKey;
typedef uint8_t FragPosKey; typedef uint8_t FragPosKey;
/** Returns a key for adding code to read the copy-of-dst color in service of effects that /** Returns a key for adding code to read the dst texture color in service of effects that
require reading the dst. It must not return 0 because 0 indicates that there is no dst require reading the dst. It must not return 0 because 0 indicates that there is no dst
copy read at all (in which case this function should not be called). */ texture at all (in which case this function should not be called). */
static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); static DstReadKey KeyForDstRead(const GrTexture* dsttexture, const GrGLCaps&);
/** Returns a key for reading the fragment location. This should only be called if there is an /** Returns a key for reading the fragment location. This should only be called if there is an
effect that will requires the fragment position. If the fragment position is not required, effect that will requires the fragment position. If the fragment position is not required,
@ -149,7 +149,7 @@ private:
kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left. kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
}; };
static const char* kDstCopyColorName; static const char* kDstTextureColorName;
bool fHasCustomColorOutput; bool fHasCustomColorOutput;
bool fHasSecondaryOutput; bool fHasSecondaryOutput;

View File

@ -76,7 +76,7 @@ public:
const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI) { const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI) {
SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(xfermode)); SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(xfermode));
SkAutoTUnref<GrXferProcessor> xp(xpf->createXferProcessor(colorPOI, covPOI, 0, caps)); SkAutoTUnref<GrXferProcessor> xp(xpf->createXferProcessor(colorPOI, covPOI, 0, caps));
TEST_ASSERT(!xpf->willNeedDstCopy(caps, colorPOI, covPOI)); TEST_ASSERT(!xpf->willNeedDstTexture(caps, colorPOI, covPOI));
xpf->getInvariantOutput(colorPOI, covPOI, &fInvariantOutput); xpf->getInvariantOutput(colorPOI, covPOI, &fInvariantOutput);
fOptFlags = xp->getOptimizations(colorPOI, covPOI, false, 0, caps); fOptFlags = xp->getOptimizations(colorPOI, covPOI, false, 0, caps);
GetXPOutputTypes(xp, &fPrimaryOutputType, &fSecondaryOutputType); GetXPOutputTypes(xp, &fPrimaryOutputType, &fSecondaryOutputType);
@ -1311,7 +1311,7 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
SkASSERT(covPOI.isFourChannelOutput()); SkASSERT(covPOI.isFourChannelOutput());
SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode)); SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode));
TEST_ASSERT(!xpf->willNeedDstCopy(caps, colorPOI, covPOI)); TEST_ASSERT(!xpf->willNeedDstTexture(caps, colorPOI, covPOI));
GrXPFactory::InvariantOutput invariantOutput; GrXPFactory::InvariantOutput invariantOutput;
xpf->getInvariantOutput(colorPOI, covPOI, &invariantOutput); xpf->getInvariantOutput(colorPOI, covPOI, &invariantOutput);