Revert of Move DstCopy on gpu into the GrXferProcessor. (patchset #11 id:200001 of https://codereview.chromium.org/885923002/)

Reason for revert:
Testing to see if reverting fixes 10.9 bots.

Original issue's description:
> Move DstCopy on gpu into the GrXferProcessor.
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/74a11753604768bf461b80cabb66060e8564d82c
>
> Committed: https://skia.googlesource.com/skia/+/5e1378d0e075a323144ba14e0a4cbcca35eccc69

TBR=joshualitt@google.com,egdaniel@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/901663007
This commit is contained in:
bsalomon 2015-02-05 14:18:05 -08:00 committed by Commit bot
parent f71b4c1857
commit 21b2c53218
38 changed files with 376 additions and 416 deletions

View File

@ -175,7 +175,6 @@
'<(skia_src_path)/gpu/GrTextureAccess.cpp',
'<(skia_src_path)/gpu/GrTRecorder.h',
'<(skia_src_path)/gpu/GrVertexBuffer.h',
'<(skia_src_path)/gpu/GrXferProcessor.cpp',
'<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h',
'<(skia_src_path)/gpu/effects/GrConfigConversionEffect.cpp',
@ -275,8 +274,6 @@
'<(skia_src_path)/gpu/gl/GrGLVertexArray.h',
'<(skia_src_path)/gpu/gl/GrGLVertexBuffer.cpp',
'<(skia_src_path)/gpu/gl/GrGLVertexBuffer.h',
'<(skia_src_path)/gpu/gl/GrGLXferProcessor.cpp',
'<(skia_src_path)/gpu/gl/GrGLXferProcessor.h',
# Files for building GLSL shaders
'<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.cpp',

View File

@ -10,7 +10,6 @@
#include "GrColor.h"
#include "GrProcessor.h"
#include "GrTexture.h"
#include "GrTypes.h"
#include "SkXfermode.h"
@ -35,10 +34,11 @@ class GrProcOptInfo;
class GrXferProcessor : public GrProcessor {
public:
/**
* Sets a unique key on the GrProcessorKeyBuilder calls onGetGLProcessorKey(...) to get the
* specific subclass's key.
*/
void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const;
* Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
* processor's GL backend implementation.
*/
virtual void getGLProcessorKey(const GrGLCaps& caps,
GrProcessorKeyBuilder* b) const = 0;
/** Returns a new instance of the appropriate *GL* implementation class
for the given GrXferProcessor; caller is responsible for deleting
@ -103,24 +103,9 @@ public:
virtual void getBlendInfo(BlendInfo* blendInfo) const = 0;
/** Will this prceossor read the destination pixel value? */
bool willReadDstColor() const { return fWillReadDstColor; }
/**
* Returns the texture to be used as the destination when reading the dst in the fragment
* 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.
*/
const GrTexture* getDstCopyTexture() const { return fDstCopy.getTexture(); }
/**
* Returns the offset into the DstCopyTexture to use when reading it in the shader. This value
* is only valid if getDstCopyTexture() != NULL.
*/
const SkIPoint& dstCopyTextureOffset() const {
SkASSERT(this->getDstCopyTexture());
return fDstCopyTextureOffset;
}
/**
* Returns whether or not this xferProcossor will set a secondary output to be used with dual
* source blending.
@ -138,43 +123,29 @@ public:
if (this->classID() != that.classID()) {
return false;
}
if (this->fWillReadDstColor != that.fWillReadDstColor) {
return false;
}
if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) {
return false;
}
if (this->fDstCopyTextureOffset != that.fDstCopyTextureOffset) {
return false;
}
return this->onIsEqual(that);
}
protected:
GrXferProcessor();
GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
GrXferProcessor() : fWillReadDstColor(false) {}
/**
* If the prceossor subclass will read the destination pixel value then it must call this
* function from its constructor. Otherwise, when its generated backend-specific prceossor class
* attempts to generate code that reads the destination pixel it will fail.
*/
void setWillReadDstColor() { fWillReadDstColor = true; }
private:
/**
* Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
* processor's GL backend implementation.
*/
virtual void onGetGLProcessorKey(const GrGLCaps& caps,
GrProcessorKeyBuilder* b) const = 0;
virtual bool onIsEqual(const GrXferProcessor&) const = 0;
bool fWillReadDstColor;
SkIPoint fDstCopyTextureOffset;
GrTextureAccess fDstCopy;
bool fWillReadDstColor;
typedef GrFragmentProcessor INHERITED;
};
GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
///////////////////////////////////////////////////////////////////////////////
/**
* We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is
* known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the
@ -188,10 +159,8 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
*/
class GrXPFactory : public SkRefCnt {
public:
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy,
const GrDrawTargetCaps& caps) const;
virtual GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const = 0;
/**
* This function returns true if the GrXferProcessor generated from this factory will be able to
@ -233,7 +202,10 @@ public:
*/
virtual bool canTweakAlphaForCoverage() const = 0;
bool willNeedDstCopy(const GrDrawTargetCaps& caps) const;
/**
* Returns true if the XP generated by this factory will read dst.
*/
virtual bool willReadDst() const = 0;
bool isEqual(const GrXPFactory& that) const {
if (this->classID() != that.classID()) {
@ -260,15 +232,6 @@ protected:
uint32_t fClassID;
private:
virtual GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const = 0;
/**
* Returns true if the XP generated by this factory will explicitly read dst in the fragment
* shader.
*/
virtual bool willReadDstColor() const = 0;
virtual bool onIsEqual(const GrXPFactory&) const = 0;
static uint32_t GenClassID() {

View File

@ -12,22 +12,21 @@
#include "GrXferProcessor.h"
#include "SkXfermode.h"
class GrDrawTargetCaps;
class GrProcOptInfo;
class GrPorterDuffXferProcessor : public GrXferProcessor {
public:
static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
GrColor constant, const GrDeviceCoordTexture* dstCopy,
bool willReadDstColor) {
return SkNEW_ARGS(GrPorterDuffXferProcessor, (srcBlend, dstBlend, constant, dstCopy,
willReadDstColor));
GrColor constant = 0) {
return SkNEW_ARGS(GrPorterDuffXferProcessor, (srcBlend, dstBlend, constant));
}
~GrPorterDuffXferProcessor() SK_OVERRIDE;
const char* name() const SK_OVERRIDE { return "Porter Duff"; }
void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
bool hasSecondaryOutput() const SK_OVERRIDE;
@ -76,10 +75,7 @@ public:
}
private:
GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant);
bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
const GrPorterDuffXferProcessor& xp = xpBase.cast<GrPorterDuffXferProcessor>();
@ -123,6 +119,9 @@ public:
return SkNEW_ARGS(GrPorterDuffXPFactory, (src, dst));
}
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE;
bool canApplyCoverage(const GrProcOptInfo& colorPOI,
@ -133,15 +132,11 @@ public:
void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
bool willReadDst() const SK_OVERRIDE { return false; }
private:
GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst);
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
bool willReadDstColor() const SK_OVERRIDE;
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
return (fSrcCoeff == xpf.fSrcCoeff && fDstCoeff == xpf.fDstCoeff);

View File

@ -166,15 +166,7 @@ public:
~GLArithmeticXP() SK_OVERRIDE {}
static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
const GrArithmeticXP& arith = processor.cast<GrArithmeticXP>();
uint32_t key = arith.enforcePMColor() ? 1 : 0;
b->add32(key);
}
private:
void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
void emitCode(const EmitArgs& args) SK_OVERRIDE {
GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
const char* dstColor = fsBuilder->dstColor();
@ -192,13 +184,21 @@ private:
args.fInputCoverage, dstColor);
}
void onSetData(const GrGLProgramDataManager& pdman,
const GrXferProcessor& processor) SK_OVERRIDE {
void setData(const GrGLProgramDataManager& pdman,
const GrXferProcessor& processor) SK_OVERRIDE {
const GrArithmeticXP& arith = processor.cast<GrArithmeticXP>();
pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
fEnforcePMColor = arith.enforcePMColor();
};
static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
const GrArithmeticXP& arith = processor.cast<GrArithmeticXP>();
uint32_t key = arith.enforcePMColor() ? 1 : 0;
b->add32(key);
}
private:
GrGLProgramDataManager::UniformHandle fKUni;
bool fEnforcePMColor;
@ -207,18 +207,17 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrArithmeticXP::GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor)
: INHERITED(dstCopy, willReadDstColor)
, fK1(k1)
GrArithmeticXP::GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor)
: fK1(k1)
, fK2(k2)
, fK3(k3)
, fK4(k4)
, fEnforcePMColor(enforcePMColor) {
this->initClassID<GrArithmeticXP>();
this->setWillReadDstColor();
}
void GrArithmeticXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
void GrArithmeticXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
GLArithmeticXP::GenKey(*this, caps, b);
}

View File

@ -13,7 +13,6 @@
#if SK_SUPPORT_GPU
#include "GrCoordTransform.h"
#include "GrDrawTargetCaps.h"
#include "GrFragmentProcessor.h"
#include "GrTextureAccess.h"
#include "GrTypes.h"
@ -73,17 +72,16 @@ private:
class GrArithmeticXP : public GrXferProcessor {
public:
static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy,
bool willReadDstColor) {
return SkNEW_ARGS(GrArithmeticXP, (k1, k2, k3, k4, enforcePMColor, dstCopy,
willReadDstColor));
static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor) {
return SkNEW_ARGS(GrArithmeticXP, (k1, k2, k3, k4, enforcePMColor));
}
~GrArithmeticXP() SK_OVERRIDE {};
const char* name() const SK_OVERRIDE { return "Arithmetic"; }
void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
bool hasSecondaryOutput() const SK_OVERRIDE { return false; }
@ -107,10 +105,7 @@ public:
bool enforcePMColor() const { return fEnforcePMColor; }
private:
GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor);
bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
const GrArithmeticXP& xp = xpBase.cast<GrArithmeticXP>();
@ -138,6 +133,11 @@ public:
return SkNEW_ARGS(GrArithmeticXPFactory, (k1, k2, k3, k4, enforcePMColor));
}
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
return GrArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor);
}
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE {
return true;
}
@ -154,18 +154,11 @@ public:
void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
bool willReadDst() const SK_OVERRIDE { return true; }
private:
GrArithmeticXPFactory(float k1, float k2, float k3, float k4, bool enforcePMColor);
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE {
return GrArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstCopy,
this->willReadDstColor());
}
bool willReadDstColor() const SK_OVERRIDE { return true; }
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
const GrArithmeticXPFactory& xpf = xpfBase.cast<GrArithmeticXPFactory>();
if (fK1 != xpf.fK1 ||

View File

@ -21,7 +21,8 @@ void GrBatchTarget::flush() {
BufferedFlush* bf = iter.get();
const GrPipeline* pipeline = bf->fPipeline;
const GrPrimitiveProcessor* primProc = bf->fPrimitiveProcessor.get();
fGpu->buildProgramDesc(&desc, *primProc, *pipeline, bf->fBatchTracker);
fGpu->buildProgramDesc(&desc, *primProc, *pipeline, pipeline->descInfo(),
bf->fBatchTracker);
GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);
for (int i = 0; i < bf->fDraws.count(); i++) {
@ -39,7 +40,8 @@ void GrBatchTarget::flushNext(int n) {
BufferedFlush* bf = fIter.get();
const GrPipeline* pipeline = bf->fPipeline;
const GrPrimitiveProcessor* primProc = bf->fPrimitiveProcessor.get();
fGpu->buildProgramDesc(&desc, *primProc, *pipeline, bf->fBatchTracker);
fGpu->buildProgramDesc(&desc, *primProc, *pipeline, pipeline->descInfo(),
bf->fBatchTracker);
GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);
for (int i = 0; i < bf->fDraws.count(); i++) {

View File

@ -56,7 +56,8 @@ public:
BufferedFlush* bf = fIter.get();
const GrPipeline* pipeline = bf->fPipeline;
const GrPrimitiveProcessor* primProc = bf->fPrimitiveProcessor.get();
fGpu->buildProgramDesc(&desc, *primProc, *pipeline, bf->fBatchTracker);
fGpu->buildProgramDesc(&desc, *primProc, *pipeline, pipeline->descInfo(),
bf->fBatchTracker);
GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);

View File

@ -384,15 +384,15 @@ bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder,
return true;
}
bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
bool GrDrawTarget::setupDstReadIfNecessary(GrPipelineBuilder* pipelineBuilder,
GrDeviceCoordTexture* dstCopy,
const SkRect* drawBounds) {
if (!pipelineBuilder.willXPNeedDstCopy(*this->caps())) {
if (this->caps()->dstReadInShaderSupport() || !pipelineBuilder->willEffectReadDstColor()) {
return true;
}
SkIRect copyRect;
const GrClipData* clip = this->getClip();
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
clip->getConservativeBounds(rt, &copyRect);
if (drawBounds) {
@ -470,9 +470,14 @@ void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder,
info.setDevBounds(*devBounds);
}
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
return;
}
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*pipelineBuilder, gp, info, scissorState);
this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
}
@ -509,9 +514,15 @@ void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder,
info.setDevBounds(*devBounds);
}
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
return;
}
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*pipelineBuilder, gp, info, scissorState);
this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
}
@ -530,7 +541,12 @@ void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder,
return;
}
this->onDrawBatch(batch, *pipelineBuilder, scissorState, devBounds);
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
return;
}
this->onDrawBatch(batch, *pipelineBuilder, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
static const GrStencilSettings& winding_path_stencil_settings() {
@ -620,8 +636,13 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder,
pipelineBuilder->getRenderTarget()->getStencilBuffer(),
&stencilSettings);
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, &devBounds)) {
return;
}
this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings,
&devBounds);
dstCopy.texture() ? &dstCopy : NULL);
}
void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
@ -655,12 +676,18 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
pipelineBuilder->getRenderTarget()->getStencilBuffer(),
&stencilSettings);
// Don't compute a bounding box for dst copy texture, we'll opt
// Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
// instead for it to just copy the entire dst. Realistically this is a moot
// point, because any context that supports NV_path_rendering will also
// support NV_blend_equation_advanced.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, NULL)) {
return;
}
this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType, transformValues,
transformType, count, scissorState, stencilSettings, NULL);
transformType, count, scissorState, stencilSettings,
dstCopy.texture() ? &dstCopy : NULL);
}
void GrDrawTarget::clear(const SkIRect* rect,
@ -766,6 +793,12 @@ void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder,
info.setDevBounds(*devBounds);
}
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
return;
}
while (instanceCount) {
info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
info.fVertexCount = info.fInstanceCount * verticesPerInstance;
@ -779,7 +812,8 @@ void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder,
info.fVertexCount,
info.fIndexCount)) {
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*pipelineBuilder, gp, info, scissorState);
this->onDraw(*pipelineBuilder, gp, info, scissorState,
dstCopy.texture() ? &dstCopy : NULL);
}
info.fStartVertex += info.fVertexCount;
instanceCount -= info.fInstanceCount;

View File

@ -677,7 +677,7 @@ protected:
// Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
// but couldn't be made. Otherwise, returns true. This method needs to be protected because it
// needs to be accessed by GLPrograms to setup a correct drawstate
bool setupDstReadIfNecessary(const GrPipelineBuilder&,
bool setupDstReadIfNecessary(GrPipelineBuilder*,
GrDeviceCoordTexture* dstCopy,
const SkRect* drawBounds);
@ -720,11 +720,12 @@ private:
virtual void onDraw(const GrPipelineBuilder&,
const GrGeometryProcessor*,
const DrawInfo&,
const GrScissorState&) = 0;
const GrScissorState&,
const GrDeviceCoordTexture* dstCopy) = 0;
virtual void onDrawBatch(GrBatch*,
const GrPipelineBuilder&,
const GrScissorState&,
const SkRect* devBounds) = 0;
const GrDeviceCoordTexture* dstCopy) = 0;
// TODO copy in order drawbuffer onDrawRect to here
virtual void onDrawRect(GrPipelineBuilder*,
GrColor color,
@ -743,7 +744,7 @@ private:
const GrPath*,
const GrScissorState&,
const GrStencilSettings&,
const SkRect* devBounds) = 0;
const GrDeviceCoordTexture* dstCopy) = 0;
virtual void onDrawPaths(const GrPipelineBuilder&,
const GrPathProcessor*,
const GrPathRange*,
@ -754,7 +755,7 @@ private:
int count,
const GrScissorState&,
const GrStencilSettings&,
const SkRect* devBounds) = 0;
const GrDeviceCoordTexture*) = 0;
virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
GrRenderTarget* renderTarget) = 0;

View File

@ -298,6 +298,7 @@ public:
virtual void buildProgramDesc(GrProgramDesc*,
const GrPrimitiveProcessor&,
const GrPipeline&,
const GrProgramDesc::DescInfo&,
const GrBatchTracker&) const = 0;
// Called to determine whether a copySurface call would succeed or not. Derived

View File

@ -247,13 +247,14 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const GrPipelineBuilder& pipelineBu
void GrInOrderDrawBuffer::onDraw(const GrPipelineBuilder& pipelineBuilder,
const GrGeometryProcessor* gp,
const DrawInfo& info,
const GrScissorState& scissorState) {
const GrScissorState& scissorState,
const GrDeviceCoordTexture* dstCopy) {
SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
// This closeBatch call is required because we may introduce new draws when we setup clip
this->closeBatch();
if (!this->recordStateAndShouldDraw(pipelineBuilder, gp, scissorState, info.getDevBounds())) {
if (!this->recordStateAndShouldDraw(pipelineBuilder, gp, scissorState, dstCopy)) {
return;
}
@ -275,8 +276,8 @@ void GrInOrderDrawBuffer::onDraw(const GrPipelineBuilder& pipelineBuilder,
void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
const GrPipelineBuilder& pipelineBuilder,
const GrScissorState& scissorState,
const SkRect* devBounds) {
if (!this->recordStateAndShouldDraw(batch, pipelineBuilder, scissorState, devBounds)) {
const GrDeviceCoordTexture* dstCopy) {
if (!this->recordStateAndShouldDraw(batch, pipelineBuilder, scissorState, dstCopy)) {
return;
}
@ -315,11 +316,11 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPipelineBuilder& pipelineBuilder,
const GrPath* path,
const GrScissorState& scissorState,
const GrStencilSettings& stencilSettings,
const SkRect* devBounds) {
const GrDeviceCoordTexture* dstCopy) {
this->closeBatch();
// TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, devBounds)) {
if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, dstCopy)) {
return;
}
DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
@ -337,14 +338,14 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPipelineBuilder& pipelineBuilder,
int count,
const GrScissorState& scissorState,
const GrStencilSettings& stencilSettings,
const SkRect* devBounds) {
const GrDeviceCoordTexture* dstCopy) {
SkASSERT(pathRange);
SkASSERT(indices);
SkASSERT(transformValues);
this->closeBatch();
if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, devBounds)) {
if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, dstCopy)) {
return;
}
@ -488,6 +489,7 @@ void GrInOrderDrawBuffer::onFlush() {
if (ss->fPrimitiveProcessor) {
this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
ss->fPipeline,
ss->fPipeline.descInfo(),
ss->fBatchTracker);
}
currentState = ss;
@ -582,14 +584,10 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrPipelineBuilder& pipelineBuilder,
const GrPrimitiveProcessor* primProc,
const GrScissorState& scissor,
const SkRect* devBounds) {
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
return false;
}
const GrDeviceCoordTexture* dstCopy) {
SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
(pipelineBuilder, primProc, *this->getGpu()->caps(),
scissor, &dstCopy));
scissor, dstCopy));
if (ss->fPipeline.mustSkip()) {
fCmdBuffer.pop_back();
return false;
@ -614,17 +612,13 @@ bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrPipelineBuilder& pipe
bool GrInOrderDrawBuffer::recordStateAndShouldDraw(GrBatch* batch,
const GrPipelineBuilder& pipelineBuilder,
const GrScissorState& scissor,
const SkRect* devBounds) {
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
return false;
}
const GrDeviceCoordTexture* dstCopy) {
// TODO this gets much simpler when we have batches everywhere.
// If the previous command is also a set state, then we check to see if it has a Batch. If so,
// and we can make the two batches equal, and we can combine the states, then we make them equal
SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
(batch, pipelineBuilder, *this->getGpu()->caps(), scissor,
&dstCopy));
dstCopy));
if (ss->fPipeline.mustSkip()) {
fCmdBuffer.pop_back();
return false;

View File

@ -233,11 +233,12 @@ private:
void onDraw(const GrPipelineBuilder&,
const GrGeometryProcessor*,
const DrawInfo&,
const GrScissorState&) SK_OVERRIDE;
const GrScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawBatch(GrBatch*,
const GrPipelineBuilder&,
const GrScissorState&,
const SkRect* devBounds) SK_OVERRIDE;
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawRect(GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
@ -255,7 +256,7 @@ private:
const GrPath*,
const GrScissorState&,
const GrStencilSettings&,
const SkRect* devBounds) SK_OVERRIDE;
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawPaths(const GrPipelineBuilder&,
const GrPathProcessor*,
const GrPathRange*,
@ -266,7 +267,7 @@ private:
int count,
const GrScissorState&,
const GrStencilSettings&,
const SkRect* devBounds) SK_OVERRIDE;
const GrDeviceCoordTexture*) SK_OVERRIDE;
void onClear(const SkIRect* rect,
GrColor color,
bool canIgnoreRect,
@ -287,11 +288,11 @@ private:
bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(const GrPipelineBuilder&,
const GrPrimitiveProcessor*,
const GrScissorState&,
const SkRect*);
const GrDeviceCoordTexture*);
bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(GrBatch*,
const GrPipelineBuilder&,
const GrScissorState&,
const SkRect*);
const GrDeviceCoordTexture*);
// We lazily record clip changes in order to skip clips that have no effect.
void recordClipIfNecessary();

View File

@ -48,7 +48,7 @@ void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder,
const GrDeviceCoordTexture* dstCopy) {
// Create XferProcessor from DS's XPFactory
SkAutoTUnref<GrXferProcessor> xferProcessor(
pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI, dstCopy, caps));
pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI));
GrColor overrideColor = GrColor_ILLEGAL;
if (colorPOI.firstEffectiveStageIndex() != 0) {
@ -82,6 +82,10 @@ void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder,
fScissorState = scissorState;
fStencilSettings = pipelineBuilder.getStencil();
fDrawFace = pipelineBuilder.getDrawFace();
// TODO move this out of GrPipeline
if (dstCopy) {
fDstCopy = *dstCopy;
}
fFlags = 0;
if (pipelineBuilder.isHWAntialias()) {
@ -103,6 +107,8 @@ void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder,
this->adjustProgramFromOptimizations(pipelineBuilder, optFlags, colorPOI, coveragePOI,
&firstColorStageIdx, &firstCoverageStageIdx);
fDescInfo.fReadsDst = fXferProcessor->willReadDstColor();
bool usesLocalCoords = false;
// Copy Stages from PipelineBuilder to Pipeline
@ -136,20 +142,20 @@ void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelin
const GrProcOptInfo& coveragePOI,
int* firstColorStageIdx,
int* firstCoverageStageIdx) {
fReadsFragPosition = false;
fDescInfo.fReadsFragPosition = false;
if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
(flags & GrXferProcessor::kOverrideColor_OptFlag)) {
*firstColorStageIdx = pipelineBuilder.numColorStages();
} else {
fReadsFragPosition = colorPOI.readsFragPosition();
fDescInfo.fReadsFragPosition = colorPOI.readsFragPosition();
}
if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
*firstCoverageStageIdx = pipelineBuilder.numCoverageStages();
} else {
if (coveragePOI.readsFragPosition()) {
fReadsFragPosition = true;
fDescInfo.fReadsFragPosition = true;
}
}
}
@ -163,7 +169,8 @@ bool GrPipeline::isEqual(const GrPipeline& that) const {
this->fScissorState != that.fScissorState ||
this->fFlags != that.fFlags ||
this->fStencilSettings != that.fStencilSettings ||
this->fDrawFace != that.fDrawFace) {
this->fDrawFace != that.fDrawFace ||
this->fDstCopy.texture() != that.fDstCopy.texture()) {
return false;
}

View File

@ -132,7 +132,9 @@ public:
///////////////////////////////////////////////////////////////////////////
bool readsFragPosition() const { return fReadsFragPosition; }
const GrDeviceCoordTexture* getDstCopy() const { return fDstCopy.texture() ? &fDstCopy : NULL; }
const GrProgramDesc::DescInfo& descInfo() const { return fDescInfo; }
const GrPipelineInfo& getInitBatchTracker() const { return fInitBT; }
@ -175,10 +177,11 @@ private:
GrScissorState fScissorState;
GrStencilSettings fStencilSettings;
GrPipelineBuilder::DrawFace fDrawFace;
GrDeviceCoordTexture fDstCopy;
uint32_t fFlags;
ProgramXferProcessor fXferProcessor;
FragmentStageArray fFragmentStages;
bool fReadsFragPosition;
GrProgramDesc::DescInfo fDescInfo;
GrPipelineInfo fInitBT;
// This function is equivalent to the offset into fFragmentStages where coverage stages begin.

View File

@ -101,8 +101,8 @@ bool GrPipelineBuilder::canUseFracCoveragePrimProc(GrColor color,
//////////////////////////////////////////////////////////////////////////////s
bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps) const {
return this->getXPFactory()->willNeedDstCopy(caps);
bool GrPipelineBuilder::willEffectReadDstColor() const {
return this->getXPFactory()->willReadDst();
}
void GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuilder) {

View File

@ -102,9 +102,10 @@ public:
const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
/**
* Checks whether the xp will need a copy of the destination to correctly blend.
* Checks whether the xp will read the dst pixel color.
* TODO: remove when we have dstCpy contained inside of GrXP
*/
bool willXPNeedDstCopy(const GrDrawTargetCaps& caps) const;
bool willEffectReadDstColor() const;
/**
* The xfer processor factory.

View File

@ -55,6 +55,9 @@ public:
}
struct KeyHeader {
uint8_t fDstReadKey; // set by GrGLShaderBuilder if there
// are effects that must read the dst.
// Otherwise, 0.
uint8_t fFragPosKey; // set by GrGLShaderBuilder if there are
// effects that read the fragment position.
// Otherwise, 0.
@ -76,6 +79,20 @@ public:
// This should really only be used internally, base classes should return their own headers
const KeyHeader& header() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
// A struct to communicate descriptor information to the program descriptor builder
struct DescInfo {
bool operator==(const DescInfo& that) const {
return fReadsDst == that.fReadsDst &&
fReadsFragPosition == that.fReadsFragPosition;
}
bool operator!=(const DescInfo& that) const { return !(*this == that); };
// These flags give aggregated info on the processor stages that are used when building
// programs.
bool fReadsDst;
bool fReadsFragPosition;
};
private:
template<typename T, size_t OFFSET> T* atOffset() {
return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);

View File

@ -142,6 +142,7 @@ public:
size_t rowBytes) const SK_OVERRIDE { return false; }
void buildProgramDesc(GrProgramDesc*,const GrPrimitiveProcessor&,
const GrPipeline&,
const GrProgramDesc::DescInfo&,
const GrBatchTracker&) const SK_OVERRIDE {}
void discard(GrRenderTarget*) SK_OVERRIDE {}

View File

@ -1,58 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrXferProcessor.h"
#include "gl/GrGLCaps.h"
GrXferProcessor::GrXferProcessor() : fWillReadDstColor(false), fDstCopyTextureOffset() {
}
GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor)
: fWillReadDstColor(willReadDstColor)
, fDstCopyTextureOffset() {
if (dstCopy && dstCopy->texture()) {
fDstCopy.reset(dstCopy->texture());
fDstCopyTextureOffset = dstCopy->offset();
this->addTextureAccess(&fDstCopy);
}
}
void GrXferProcessor::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
if (this->getDstCopyTexture() &&
kTopLeft_GrSurfaceOrigin == this->getDstCopyTexture()->origin()) {
key |= 0x2;
}
b->add32(key);
this->onGetGLProcessorKey(caps, b);
}
///////////////////////////////////////////////////////////////////////////////
GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy,
const GrDrawTargetCaps& caps) const {
#ifdef SK_DEBUG
if (this->willReadDstColor()) {
if (!caps.dstReadInShaderSupport()) {
SkASSERT(dstCopy && dstCopy->texture());
} else {
SkASSERT(!dstCopy || !dstCopy->texture());
}
} else {
SkASSERT(!dstCopy || !dstCopy->texture());
}
#endif
return this->onCreateXferProcessor(colorPOI, coveragePOI, dstCopy);
}
bool GrXPFactory::willNeedDstCopy(const GrDrawTargetCaps& caps) const {
return (this->willReadDstColor() && !caps.dstReadInShaderSupport());
}

View File

@ -21,15 +21,7 @@ public:
~GrGLCoverageSetOpXP() SK_OVERRIDE {}
static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>();
uint32_t key = xp.invertCoverage() ? 0x0 : 0x1;
b->add32(key);
};
private:
void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
void emitCode(const EmitArgs& args) SK_OVERRIDE {
const GrCoverageSetOpXP& xp = args.fXP.cast<GrCoverageSetOpXP>();
GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@ -40,8 +32,16 @@ private:
}
}
void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>();
uint32_t key = xp.invertCoverage() ? 0x0 : 0x1;
b->add32(key);
};
private:
typedef GrGLXferProcessor INHERITED;
};
@ -56,7 +56,7 @@ GrCoverageSetOpXP::GrCoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage)
GrCoverageSetOpXP::~GrCoverageSetOpXP() {
}
void GrCoverageSetOpXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
void GrCoverageSetOpXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
GrGLCoverageSetOpXP::GenKey(*this, caps, b);
}
@ -179,10 +179,8 @@ GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert
}
}
GrXferProcessor*
GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI,
const GrDeviceCoordTexture* dstCopy) const {
GrXferProcessor* GrCoverageSetOpXPFactory::createXferProcessor(const GrProcOptInfo& /* colorPOI*/,
const GrProcOptInfo& covPOI) const {
return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
}

View File

@ -29,6 +29,8 @@ public:
const char* name() const SK_OVERRIDE { return "Coverage Set Op"; }
void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
bool hasSecondaryOutput() const SK_OVERRIDE { return false; }
@ -46,8 +48,6 @@ public:
private:
GrCoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage);
void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
const GrCoverageSetOpXP& xp = xpBase.cast<GrCoverageSetOpXP>();
return (fRegionOp == xp.fRegionOp &&
@ -66,6 +66,9 @@ class GrCoverageSetOpXPFactory : public GrXPFactory {
public:
static GrXPFactory* Create(SkRegion::Op regionOp, bool invertCoverage = false);
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE {
return true;
}
@ -80,15 +83,11 @@ public:
void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
bool willReadDst() const SK_OVERRIDE { return false; }
private:
GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
bool willReadDstColor() const SK_OVERRIDE { return false; }
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
const GrCoverageSetOpXPFactory& xpf = xpfBase.cast<GrCoverageSetOpXPFactory>();
return fRegionOp == xpf.fRegionOp;

View File

@ -499,15 +499,7 @@ public:
GLCustomXP(const GrXferProcessor&) {}
~GLCustomXP() SK_OVERRIDE {}
static void GenKey(const GrXferProcessor& proc, const GrGLCaps&, GrProcessorKeyBuilder* b) {
uint32_t key = proc.numTextures();
SkASSERT(key <= 1);
key |= proc.cast<GrCustomXP>().mode() << 1;
b->add32(key);
}
private:
void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
void emitCode(const EmitArgs& args) SK_OVERRIDE {
SkXfermode::Mode mode = args.fXP.cast<GrCustomXP>().mode();
GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
const char* dstColor = fsBuilder->dstColor();
@ -519,20 +511,28 @@ private:
args.fInputCoverage, dstColor);
}
void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}
void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}
static void GenKey(const GrXferProcessor& proc, const GrGLCaps&, GrProcessorKeyBuilder* b) {
uint32_t key = proc.numTextures();
SkASSERT(key <= 1);
key |= proc.cast<GrCustomXP>().mode() << 1;
b->add32(key);
}
private:
typedef GrGLFragmentProcessor INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
GrCustomXP::GrCustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy,
bool willReadDstColor)
: INHERITED(dstCopy, willReadDstColor), fMode(mode) {
GrCustomXP::GrCustomXP(SkXfermode::Mode mode)
: fMode(mode) {
this->initClassID<GrCustomXP>();
this->setWillReadDstColor();
}
void GrCustomXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
void GrCustomXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
GLCustomXP::GenKey(*this, caps, b);
}

View File

@ -9,7 +9,6 @@
#define GrCustomXfermodePriv_DEFINED
#include "GrCoordTransform.h"
#include "GrDrawTargetCaps.h"
#include "GrFragmentProcessor.h"
#include "GrTextureAccess.h"
#include "GrXferProcessor.h"
@ -58,12 +57,11 @@ private:
class GrCustomXP : public GrXferProcessor {
public:
static GrXferProcessor* Create(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy,
bool willReadDstColor) {
static GrXferProcessor* Create(SkXfermode::Mode mode) {
if (!GrCustomXfermode::IsSupportedMode(mode)) {
return NULL;
} else {
return SkNEW_ARGS(GrCustomXP, (mode, dstCopy, willReadDstColor));
return SkNEW_ARGS(GrCustomXP, (mode));
}
}
@ -71,6 +69,8 @@ public:
const char* name() const SK_OVERRIDE { return "Custom Xfermode"; }
void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
bool hasSecondaryOutput() const SK_OVERRIDE { return false; }
@ -90,9 +90,7 @@ public:
SkXfermode::Mode mode() const { return fMode; }
private:
GrCustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrCustomXP(SkXfermode::Mode mode);
bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE;
@ -107,6 +105,11 @@ class GrCustomXPFactory : public GrXPFactory {
public:
GrCustomXPFactory(SkXfermode::Mode mode);
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
return GrCustomXP::Create(fMode);
}
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE {
return true;
}
@ -123,15 +126,9 @@ public:
void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
bool willReadDst() const SK_OVERRIDE { return true; }
private:
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE {
return GrCustomXP::Create(fMode, dstCopy, this->willReadDstColor());
}
bool willReadDstColor() const SK_OVERRIDE { return true; }
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
const GrCustomXPFactory& xpf = xpfBase.cast<GrCustomXPFactory>();
return fMode == xpf.fMode;

View File

@ -17,10 +17,7 @@ public:
~GrGLDisableColorXP() SK_OVERRIDE {}
static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
private:
void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
void emitCode(const EmitArgs& args) SK_OVERRIDE {
// This emit code should be empty. However, on the nexus 6 there is a driver bug where if
// you do not give gl_FragColor a value, the gl context is lost and we end up drawing
// nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
@ -28,8 +25,11 @@ private:
fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
}
void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}
void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}
static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
private:
typedef GrGLXferProcessor INHERITED;
};
@ -39,7 +39,7 @@ GrDisableColorXP::GrDisableColorXP() {
this->initClassID<GrDisableColorXP>();
}
void GrDisableColorXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
void GrDisableColorXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
GrGLDisableColorXP::GenKey(*this, caps, b);
}
@ -57,10 +57,8 @@ GrDisableColorXPFactory::GrDisableColorXPFactory() {
this->initClassID<GrDisableColorXPFactory>();
}
GrXferProcessor*
GrDisableColorXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI,
const GrDeviceCoordTexture* dstCopy) const {
GrXferProcessor* GrDisableColorXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI) const {
return GrDisableColorXP::Create();
}

View File

@ -27,6 +27,8 @@ public:
const char* name() const SK_OVERRIDE { return "Disable Color"; }
void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
bool hasSecondaryOutput() const SK_OVERRIDE { return false; }
@ -44,8 +46,6 @@ public:
private:
GrDisableColorXP();
void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
return true;
}
@ -61,6 +61,9 @@ public:
return SkNEW(GrDisableColorXPFactory);
}
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE {
return true;
}
@ -78,15 +81,11 @@ public:
output->fWillBlendWithDst = 0;
}
bool willReadDst() const SK_OVERRIDE { return false; }
private:
GrDisableColorXPFactory();
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
bool willReadDstColor() const SK_OVERRIDE { return false; }
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
return true;
}

View File

@ -38,15 +38,7 @@ public:
virtual ~GrGLPorterDuffXferProcessor() {}
static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>();
b->add32(xp.primaryOutputType());
b->add32(xp.secondaryOutputType());
};
private:
void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
void emitCode(const EmitArgs& args) SK_OVERRIDE {
const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProcessor>();
GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
if (xp.hasSecondaryOutput()) {
@ -88,18 +80,23 @@ private:
}
}
void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>();
b->add32(xp.primaryOutputType());
b->add32(xp.secondaryOutputType());
};
private:
typedef GrGLXferProcessor INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend,
GrBlendCoeff dstBlend,
GrColor constant,
const GrDeviceCoordTexture* dstCopy,
bool willReadDstColor)
GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
GrColor constant)
: fSrcBlend(srcBlend)
, fDstBlend(dstBlend)
, fBlendConstant(constant)
@ -111,8 +108,8 @@ GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend,
GrPorterDuffXferProcessor::~GrPorterDuffXferProcessor() {
}
void GrPorterDuffXferProcessor::onGetGLProcessorKey(const GrGLCaps& caps,
GrProcessorKeyBuilder* b) const {
void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps,
GrProcessorKeyBuilder* b) const {
GrGLPorterDuffXferProcessor::GenKey(*this, caps, b);
}
@ -356,20 +353,16 @@ GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) {
}
}
GrXferProcessor*
GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI,
const GrDeviceCoordTexture* dstCopy) const {
GrXferProcessor* GrPorterDuffXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI) const {
if (!covPOI.isFourChannelOutput()) {
return GrPorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy,
this->willReadDstColor());
return GrPorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff);
} else {
if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) {
SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
GrColor blendConstant = GrUnPreMulColor(colorPOI.color());
return GrPorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff,
blendConstant, dstCopy,
this->willReadDstColor());
blendConstant);
} else {
return NULL;
}
@ -491,10 +484,6 @@ void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
output->fWillBlendWithDst = false;
}
bool GrPorterDuffXPFactory::willReadDstColor() const {
return false;
}
GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,

View File

@ -1451,8 +1451,10 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
void GrGLGpu::buildProgramDesc(GrProgramDesc* desc,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrProgramDesc::DescInfo& descInfo,
const GrBatchTracker& batchTracker) const {
if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, this, batchTracker)) {
if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, descInfo, this,
batchTracker)) {
SkDEBUGFAIL("Failed to generate GL program descriptor");
}
}

View File

@ -108,6 +108,7 @@ public:
void buildProgramDesc(GrProgramDesc*,
const GrPrimitiveProcessor&,
const GrPipeline&,
const GrProgramDesc::DescInfo&,
const GrBatchTracker&) const SK_OVERRIDE;
private:

View File

@ -61,6 +61,10 @@ void GrGLProgram::abandon() {
void GrGLProgram::initSamplerUniforms() {
GL_CALL(UseProgram(fProgramID));
GrGLint texUnitIdx = 0;
if (fBuiltinUniformHandles.fDstCopySamplerUni.isValid()) {
fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx);
fDstCopyTexUnit = texUnitIdx++;
}
this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
if (fXferProcessor.get()) {
this->initSamplers(fXferProcessor.get(), &texUnitIdx);
@ -103,15 +107,38 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
const GrBatchTracker& batchTracker) {
this->setRenderTargetState(primProc, pipeline);
const GrDeviceCoordTexture* dstCopy = pipeline.getDstCopy();
if (dstCopy) {
if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni,
static_cast<GrGLfloat>(dstCopy->offset().fX),
static_cast<GrGLfloat>(dstCopy->offset().fY));
fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni,
1.f / dstCopy->texture()->width(),
1.f / dstCopy->texture()->height());
GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
static GrTextureParams kParams; // the default is clamp, nearest filtering.
fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
} else {
SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
}
} else {
SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid());
SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
}
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
// of GLProgram determine how to set coord transforms
fGeometryProcessor->fGLProc->setData(fProgramDataManager, primProc, batchTracker);
this->bindTextures(fGeometryProcessor.get(), primProc);
const GrXferProcessor& xp = *pipeline.getXferProcessor();
fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
this->bindTextures(fXferProcessor.get(), xp);
if (fXferProcessor.get()) {
const GrXferProcessor& xp = *pipeline.getXferProcessor();
fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
this->bindTextures(fXferProcessor.get(), xp);
}
this->setFragmentData(primProc, pipeline);
// Some of GrGLProgram subclasses need to update state here

View File

@ -89,6 +89,7 @@ static bool get_meta_key(const GrProcessor& proc,
bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrProgramDesc::DescInfo& descInfo,
const GrGLGpu* gpu,
const GrBatchTracker& batchTracker) {
// The descriptor is used as a cache key. Thus when a field of the
@ -134,7 +135,21 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
// make sure any padding in the header is zeroed.
memset(header, 0, kHeaderSize);
if (pipeline.readsFragPosition()) {
if (descInfo.fReadsDst) {
const GrDeviceCoordTexture* dstCopy = pipeline.getDstCopy();
SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
const GrTexture* dstCopyTexture = NULL;
if (dstCopy) {
dstCopyTexture = dstCopy->texture();
}
header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
gpu->glCaps());
SkASSERT(0 != header->fDstReadKey);
} else {
header->fDstReadKey = 0;
}
if (descInfo.fReadsFragPosition) {
header->fFragPosKey =
GrGLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.getRenderTarget(),
gpu->glCaps());

View File

@ -47,6 +47,8 @@ public:
* general draw information, as well as the specific color, geometry,
* and coverage stages which will be used to generate the GL Program for
* this optstate.
* @param DescInfo A descriptor info struct, generated by the optstate, which contains a number
* of important facts about the program the built descriptor will represent
* @param GrGLGpu A GL Gpu, the caps and Gpu object are used to output processor specific
* parts of the descriptor.
* @param GrDeviceCoordTexture A dstCopy texture, which may be null if frame buffer fetch is
@ -56,6 +58,7 @@ public:
static bool Build(GrProgramDesc*,
const GrPrimitiveProcessor&,
const GrPipeline&,
const GrProgramDesc::DescInfo&,
const GrGLGpu*,
const GrBatchTracker&);
};

View File

@ -1,69 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gl/GrGLXferProcessor.h"
#include "GrXferProcessor.h"
#include "gl/builders/GrGLFragmentShaderBuilder.h"
#include "gl/builders/GrGLProgramBuilder.h"
void GrGLXferProcessor::emitCode(const EmitArgs& args) {
if (args.fXP.getDstCopyTexture()) {
bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstCopyTexture()->origin();
GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
const char* dstColor = fsBuilder->dstColor();
const char* dstCopyTopLeftName;
const char* dstCopyCoordScaleName;
fDstCopyTopLeftUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstCopyUpperLeft",
&dstCopyTopLeftName);
fDstCopyScaleUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstCopyCoordScale",
&dstCopyCoordScaleName);
const char* fragPos = fsBuilder->fragmentPosition();
fsBuilder->codeAppend("// Read color from copy of the destination.\n");
fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
if (!topDown) {
fsBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
}
fsBuilder->codeAppendf("vec4 %s = ", dstColor);
fsBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
fsBuilder->codeAppend(";");
}
this->onEmitCode(args);
}
void GrGLXferProcessor::setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp) {
if (xp.getDstCopyTexture()) {
if (fDstCopyTopLeftUni.isValid()) {
pdm.set2f(fDstCopyTopLeftUni, static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fX),
static_cast<GrGLfloat>(xp.dstCopyTextureOffset().fY));
pdm.set2f(fDstCopyScaleUni, 1.f / xp.getDstCopyTexture()->width(),
1.f / xp.getDstCopyTexture()->height());
} else {
SkASSERT(!fDstCopyScaleUni.isValid());
}
} else {
SkASSERT(!fDstCopyTopLeftUni.isValid());
SkASSERT(!fDstCopyScaleUni.isValid());
}
this->onSetData(pdm, xp);
}

View File

@ -11,7 +11,6 @@
#include "GrGLProcessor.h"
class GrGLXPBuilder;
class GrXferProcessor;
class GrGLXferProcessor {
public:
@ -47,25 +46,16 @@ public:
* This is similar to emitCode() in the base class, except it takes a full shader builder.
* This allows the effect subclass to emit vertex code.
*/
void emitCode(const EmitArgs&);
virtual void emitCode(const EmitArgs&) = 0;
/** A GrGLXferProcessor instance can be reused with any GrGLXferProcessor that produces
the same stage key; this function reads data from a GrGLXferProcessor and uploads any
uniform variables required by the shaders created in emitCode(). The GrXferProcessor
parameter is guaranteed to be of the same type that created this GrGLXferProcessor and
to have an identical processor key as the one that created this GrGLXferProcessor. This
function calls onSetData on the subclass of GrGLXferProcessor
*/
void setData(const GrGLProgramDataManager& pdm, const GrXferProcessor& xp);
to have an identical processor key as the one that created this GrGLXferProcessor. */
virtual void setData(const GrGLProgramDataManager&,
const GrXferProcessor&) = 0;
private:
virtual void onEmitCode(const EmitArgs&) = 0;
virtual void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) = 0;
GrGLProgramDataManager::UniformHandle fDstCopyTopLeftUni;
GrGLProgramDataManager::UniformHandle fDstCopyScaleUni;
typedef GrGLProcessor INHERITED;
};
#endif

View File

@ -179,9 +179,56 @@ const char* GrGLFragmentShaderBuilder::dstColor() {
fbFetchColorName = declared_color_output_name();
}
return fbFetchColorName;
} else {
} else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) {
return kDstCopyColorName;
}
} else {
return "";
}
}
void GrGLFragmentShaderBuilder::emitCodeToReadDstTexture() {
bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & fProgramBuilder->header().fDstReadKey);
const char* dstCopyTopLeftName;
const char* dstCopyCoordScaleName;
const char* dstCopySamplerName;
uint32_t configMask;
if (SkToBool(kUseAlphaConfig_DstReadKeyBit & fProgramBuilder->header().fDstReadKey)) {
configMask = kA_GrColorComponentFlag;
} else {
configMask = kRGBA_GrColorComponentFlags;
}
fProgramBuilder->fUniformHandles.fDstCopySamplerUni =
fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kSampler2D_GrSLType,
kDefault_GrSLPrecision,
"DstCopySampler",
&dstCopySamplerName);
fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni =
fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstCopyUpperLeft",
&dstCopyTopLeftName);
fProgramBuilder->fUniformHandles.fDstCopyScaleUni =
fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstCopyCoordScale",
&dstCopyCoordScaleName);
const char* fragPos = this->fragmentPosition();
this->codeAppend("// Read color from copy of the destination.\n");
this->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
if (!topDown) {
this->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
}
this->codeAppendf("vec4 %s = ", GrGLFragmentShaderBuilder::kDstCopyColorName);
this->appendTextureLookup(dstCopySamplerName,
"_dstTexCoord",
configMask,
"rgba");
this->codeAppend(";");
}
void GrGLFragmentShaderBuilder::enableCustomOutput() {

View File

@ -97,6 +97,7 @@ public:
private:
// Private public interface, used by GrGLProgramBuilder to build a fragment shader
void emitCodeToReadDstTexture();
void enableCustomOutput();
void enableSecondaryOutput();
const char* getPrimaryColorOutputName() const;

View File

@ -56,6 +56,12 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp
GrGLProgramBuilder* pb = builder.get();
// emit code to read the dst copy texture, if necessary
if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != pb->header().fDstReadKey &&
!gpu->glCaps().fbFetchSupport()) {
pb->fFS.emitCodeToReadDstTexture();
}
// TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can
// seed correctly here
GrGLSLExpr4 inputColor;

View File

@ -267,6 +267,11 @@ public:
// We use the render target height to provide a y-down frag coord when specifying
// origin_upper_left is not supported.
UniformHandle fRTHeightUni;
// Uniforms for computing texture coords to do the dst-copy lookup
UniformHandle fDstCopyTopLeftUni;
UniformHandle fDstCopyScaleUni;
UniformHandle fDstCopySamplerUni;
};
protected:

View File

@ -298,7 +298,7 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
} else {
primProc = pathProc.get();
}
if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, NULL)) {
if (!this->setupDstReadIfNecessary(&pipelineBuilder, &dstCopy, NULL)) {
SkDebugf("Couldn't setup dst read texture");
return false;
}
@ -313,7 +313,7 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
primProc->initBatchTracker(&bt, pipeline.getInitBatchTracker());
GrProgramDesc desc;
gpu->buildProgramDesc(&desc, *primProc, pipeline, bt);
gpu->buildProgramDesc(&desc, *primProc, pipeline, pipeline.descInfo(), bt);
GrGpu::DrawArgs args(primProc, &pipeline, &desc, &bt);
SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(args, gpu));