aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar kkinnunen <kkinnunen@nvidia.com>2014-08-25 22:21:16 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-25 22:21:16 -0700
commitec56e4545477e30d4f165ca55ed99f90525c6c38 (patch)
tree78564548fe8d235934e217d95e6eb021644ba673
parentbc818f513be494fb3ab0c211892c7dc4cfb6a3d7 (diff)
Implement NV_path_rendering on OpenGL ES
Implement support for NV_path_rendering on OpenGL ES. Use glProgramPathFragmentInputGenNV function call instead of glPathTexGenNV to communicate transforms to fragment shader. The intention is that the NVPR paths will be drawn with the same shader program as non-NVPR geometry. For NVPR calls, the GPU will skip the vertex shader and just run the fragment shader. After program is linked, query the locations of the fragment shader inputs with glGetResourceLocation. The location will be used to set the transforms with glProgramPathFragmentInputGenNV. The functions and their workings are documented in: glProgramPathFragmentInputGenNV https://www.opengl.org/registry/specs/NV/path_rendering.txt (note: addition as of API version 1.3) glGetResourceLocation https://www.opengl.org/registry/specs/ARB/program_interface_query.txt http://www.opengl.org/registry/doc/glspec44.core.pdf (function is in core Open GL 4.4) Note: glProgramPathFragmentInputGenNV could be used also for OpenGL. However, using seems to trigger a bug in the driver. Disable this feature on OpenGL at least until the driver is fixed and released. The bug manifests in shadertext test, where the lower-left text pair is missing. Valgrind catches a bad read for the test and causes the context to OOM reproducibly. R=bsalomon@google.com, cdalton@nvidia.com, joshualitt@google.com, joshualitt@chromium.org Author: kkinnunen@nvidia.com Review URL: https://codereview.chromium.org/367643004
-rw-r--r--include/gpu/GrEffect.h10
-rw-r--r--src/gpu/GrGpu.h4
-rw-r--r--src/gpu/effects/GrVertexEffect.h2
-rw-r--r--src/gpu/gl/GrGLCaps.cpp3
-rw-r--r--src/gpu/gl/GrGLDefines.h7
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp30
-rw-r--r--src/gpu/gl/GrGLProgram.cpp26
-rw-r--r--src/gpu/gl/GrGLProgram.h5
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.cpp30
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.h55
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp24
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h4
-rw-r--r--src/gpu/gl/GrGLProgramEffects.cpp71
-rw-r--r--src/gpu/gl/GrGLProgramEffects.h17
-rw-r--r--src/gpu/gl/GrGpuGL.h7
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp6
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp29
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h26
-rw-r--r--tests/GLProgramsTest.cpp21
19 files changed, 279 insertions, 98 deletions
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 4734c7c377..09d716f80a 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -114,10 +114,10 @@ public:
/** Will this effect emit custom vertex shader code?
(To set this value the effect must inherit from GrEffect.) */
- bool hasVertexCode() const { return fHasVertexCode; }
+ bool requiresVertexShader() const { return fRequiresVertexShader; }
int numVertexAttribs() const {
- SkASSERT(0 == fVertexAttribTypes.count() || fHasVertexCode);
+ SkASSERT(0 == fVertexAttribTypes.count() || fRequiresVertexShader);
return fVertexAttribTypes.count();
}
@@ -166,7 +166,7 @@ protected:
: fWillReadDstColor(false)
, fWillReadFragmentPosition(false)
, fWillUseInputColor(true)
- , fHasVertexCode(false) {}
+ , fRequiresVertexShader(false) {}
/**
* Helper for down-casting to a GrEffect subclass
@@ -204,7 +204,7 @@ private:
getFactory()).*/
virtual bool onIsEqual(const GrEffect& other) const = 0;
- friend class GrVertexEffect; // to set fHasVertexCode and build fVertexAttribTypes.
+ friend class GrVertexEffect; // to set fRequiresVertexShader and build fVertexAttribTypes.
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
@@ -212,7 +212,7 @@ private:
bool fWillReadDstColor;
bool fWillReadFragmentPosition;
bool fWillUseInputColor;
- bool fHasVertexCode;
+ bool fRequiresVertexShader;
typedef SkRefCnt INHERITED;
};
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 353ec33437..e495de9afa 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -336,6 +336,10 @@ public:
kDrawPaths_DrawType,
};
+ static bool IsPathRenderingDrawType(DrawType type) {
+ return kDrawPath_DrawType == type || kDrawPaths_DrawType == type;
+ }
+
protected:
DrawType PrimTypeToDrawType(GrPrimitiveType type) {
switch (type) {
diff --git a/src/gpu/effects/GrVertexEffect.h b/src/gpu/effects/GrVertexEffect.h
index 387ec7aee9..323c85e34e 100644
--- a/src/gpu/effects/GrVertexEffect.h
+++ b/src/gpu/effects/GrVertexEffect.h
@@ -17,7 +17,7 @@
*/
class GrVertexEffect : public GrEffect {
public:
- GrVertexEffect() { fHasVertexCode = true; }
+ GrVertexEffect() { fRequiresVertexShader = true; }
protected:
/**
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index f12871192c..f9030d84d7 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -342,8 +342,7 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
ctxInfo.hasExtension("GL_ARB_program_interface_query")) &&
NULL != gli->fFunctions.fProgramPathFragmentInputGen));
} else {
- // Note: path rendering is not yet implemented for GLES.
- fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3,1) && false;
+ fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3,1);
}
}
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 06dd99dae1..048ad54df6 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -900,8 +900,13 @@
// shader stage of <program> (if a fragment stage exists).
#define GR_GL_FRAGMENT_INPUT 0x936D
+// NV_path_rendering extension to EXT_direct_state_access:
+// [the matrix functions] must support the PATH_PROJECTION_NV and
+// PATH_MODELVIEW_NV tokens for matrixMode.
+#define GR_GL_PATH_PROJECTION 0x1701
+#define GR_GL_PATH_MODELVIEW 0x1700
+
/* ARM specific define for MSAA support on framebuffer fetch */
#define GR_GL_FETCH_PER_SAMPLE_ARM 0x8F65
-
#endif
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 135eb16866..337e83e811 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -54,8 +54,12 @@ GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu)
NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced &&
NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced;
fCaps.fragmentInputGenSupport =
+ kGLES_GrGLStandard == glInterface->fStandard &&
NULL != glInterface->fFunctions.fProgramPathFragmentInputGen;
- fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords());
+
+ if (!fCaps.fragmentInputGenSupport) {
+ fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords());
+ }
}
GrGLPathRendering::~GrGLPathRendering() {
@@ -68,14 +72,18 @@ void GrGLPathRendering::abandonGpuResources() {
void GrGLPathRendering::resetContext() {
fHWProjectionMatrixState.invalidate();
// we don't use the model view matrix.
- GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW));
-
- for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) {
- GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
- fHWPathTexGenSettings[i].fMode = GR_GL_NONE;
- fHWPathTexGenSettings[i].fNumComponents = 0;
+ GrGLenum matrixMode =
+ fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_MODELVIEW : GR_GL_MODELVIEW;
+ GL_CALL(MatrixLoadIdentity(matrixMode));
+
+ if (!caps().fragmentInputGenSupport) {
+ for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) {
+ GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
+ fHWPathTexGenSettings[i].fMode = GR_GL_NONE;
+ fHWPathTexGenSettings[i].fNumComponents = 0;
+ }
+ fHWActivePathTexGenSets = 0;
}
- fHWActivePathTexGenSets = 0;
fHWPathStencilSettings.invalidate();
}
@@ -105,7 +113,6 @@ void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) {
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());
- SkASSERT(!fGpu->fCurrentProgram->hasVertexShader());
this->flushPathStencilSettings(fill);
SkASSERT(!fHWPathStencilSettings.isTwoSided());
@@ -162,7 +169,6 @@ void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t i
SkASSERT(fGpu->caps()->pathRenderingSupport());
SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());
- SkASSERT(!fGpu->fCurrentProgram->hasVertexShader());
GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
@@ -347,7 +353,9 @@ void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
GrGLfloat glMatrix[4 * 4];
fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
- GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix));
+ GrGLenum matrixMode =
+ fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_PROJECTION : GR_GL_PROJECTION;
+ GL_CALL(MatrixLoadf(matrixMode, glMatrix));
}
GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index d49d000fe3..11efda9214 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -13,6 +13,7 @@
#include "GrDrawEffect.h"
#include "GrGLEffect.h"
#include "GrGpuGL.h"
+#include "GrGLPathRendering.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
#include "SkXfermode.h"
@@ -25,10 +26,12 @@ GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[]) {
SkAutoTDelete<GrGLProgramBuilder> builder;
- if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) {
- builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc)));
- } else {
+ if (!desc.getHeader().fRequiresVertexShader &&
+ gpu->glCaps().pathRenderingSupport() &&
+ gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode) {
builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc)));
+ } else {
+ builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc)));
}
if (builder->genProgram(colorStages, coverageStages)) {
SkASSERT(0 != builder->getProgramID());
@@ -100,7 +103,8 @@ void GrGLProgram::initSamplerUniforms() {
///////////////////////////////////////////////////////////////////////////////
-void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
+void GrGLProgram::setData(GrGpu::DrawType drawType,
+ GrDrawState::BlendOptFlags blendOpts,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy,
@@ -122,7 +126,7 @@ void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
this->setColor(drawState, color, sharedState);
this->setCoverage(drawState, coverage, sharedState);
- this->setMatrixAndRenderTargetHeight(drawState);
+ this->setMatrixAndRenderTargetHeight(drawType, drawState);
if (NULL != dstCopy) {
if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
@@ -145,9 +149,8 @@ void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
}
- fColorEffects->setData(fGpu, fProgramDataManager, colorStages);
- fCoverageEffects->setData(fGpu, fProgramDataManager, coverageStages);
-
+ fColorEffects->setData(fGpu, drawType,fProgramDataManager, colorStages);
+ fCoverageEffects->setData(fGpu, drawType,fProgramDataManager, coverageStages);
// PathTexGen state applies to the the fixed function vertex shader. For
// custom shaders, it's ignored, so we don't need to change the texgen
@@ -231,7 +234,8 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
}
}
-void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
+void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
+ const GrDrawState& drawState) {
const GrRenderTarget* rt = drawState.getRenderTarget();
SkISize size;
size.set(rt->width(), rt->height());
@@ -243,9 +247,7 @@ void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
SkIntToScalar(size.fHeight));
}
- if (!fHasVertexShader) {
- SkASSERT(!fBuiltinUniformHandles.fViewMatrixUni.isValid());
- SkASSERT(!fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
+ if (GrGpu::IsPathRenderingDrawType(drawType)) {
fGpu->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
} else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
fMatrixState.fRenderTargetSize != size ||
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 7af55f10ee..5b9deb9f91 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -156,7 +156,8 @@ public:
* GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage
* stages come from GrGLProgramDesc::Build().
*/
- void setData(GrDrawState::BlendOptFlags,
+ void setData(GrGpu::DrawType,
+ GrDrawState::BlendOptFlags,
const GrEffectStage* colorStages[],
const GrEffectStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy, // can be NULL
@@ -181,7 +182,7 @@ private:
void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*);
// Helper for setData() that sets the view matrix and loads the render target height uniform
- void setMatrixAndRenderTargetHeight(const GrDrawState&);
+ void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrDrawState&);
// these reflect the current values of uniforms (GL uniform values travel with program)
MatrixState fMatrixState;
diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
index eed9d1935d..c53abd79ab 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -6,6 +6,7 @@
*/
#include "gl/builders/GrGLProgramBuilder.h"
+#include "gl/GrGLPathRendering.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLUniformHandle.h"
#include "gl/GrGpuGL.h"
@@ -16,9 +17,10 @@
(1 == arrayCount && GrGLShaderVar::kNonArray == uni.fArrayCount))
GrGLProgramDataManager::GrGLProgramDataManager(GrGpuGL* gpu,
- GrGLProgram*,
+ GrGLProgram* program,
const GrGLProgramBuilder& builder)
- : fGpu(gpu) {
+ : fGpu(gpu),
+ fProgram(program) {
int count = builder.getUniformInfos().count();
fUniforms.push_back_n(count);
for (int i = 0; i < count; i++) {
@@ -43,6 +45,19 @@ GrGLProgramDataManager::GrGLProgramDataManager(GrGpuGL* gpu,
uniform.fFSLocation = kUnusedUniform;
}
}
+
+ count = builder.getSeparableVaryingInfos().count();
+ fVaryings.push_back_n(count);
+ for (int i = 0; i < count; i++) {
+ Varying& varying = fVaryings[i];
+ const GrGLProgramBuilder::SeparableVaryingInfo& builderVarying =
+ builder.getSeparableVaryingInfos()[i];
+ SkASSERT(GrGLShaderVar::kNonArray == builderVarying.fVariable.getArrayCount());
+ SkDEBUGCODE(
+ varying.fType = builderVarying.fVariable.getType();
+ );
+ varying.fLocation = builderVarying.fLocation;
+ }
}
void GrGLProgramDataManager::setSampler(UniformHandle u, GrGLint texUnit) const {
@@ -261,3 +276,14 @@ void GrGLProgramDataManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix
};
this->setMatrix3f(u, mt);
}
+
+void GrGLProgramDataManager::setProgramPathFragmentInputTransform(VaryingHandle i,
+ unsigned components,
+ const SkMatrix& matrix) const {
+ const Varying& fragmentInput = fVaryings[i.toProgramDataIndex()];
+ fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgram->programID(),
+ fragmentInput.fLocation,
+ GR_GL_OBJECT_LINEAR,
+ components,
+ matrix);
+}
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
index 3082f6f02b..8a98a75cae 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -26,34 +26,51 @@ class GrGLProgramBuilder;
class GrGLProgramDataManager : public SkRefCnt {
public:
// Opaque handle to a uniform
- class UniformHandle {
+ class ShaderResourceHandle {
public:
- /** Creates a reference to an unifrom of a GrGLShaderBuilder.
- * The ref can be used to set the uniform with corresponding the GrGLProgramDataManager.*/
- static UniformHandle CreateFromUniformIndex(int i);
-
bool isValid() const { return -1 != fValue; }
-
- bool operator==(const UniformHandle& other) const { return other.fValue == fValue; }
-
- UniformHandle()
+ ShaderResourceHandle()
: fValue(-1) {
}
-
- private:
- UniformHandle(int value)
+ protected:
+ ShaderResourceHandle(int value)
: fValue(value) {
SkASSERT(isValid());
}
+ int fValue;
+ };
+ class UniformHandle : public ShaderResourceHandle {
+ public:
+ /** Creates a reference to an unifrom of a GrGLShaderBuilder.
+ * The ref can be used to set the uniform with corresponding the GrGLProgramDataManager.*/
+ static UniformHandle CreateFromUniformIndex(int i);
+ UniformHandle() { }
+ bool operator==(const UniformHandle& other) const { return other.fValue == fValue; }
+ private:
+ UniformHandle(int value) : ShaderResourceHandle(value) { }
int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
int toShaderBuilderIndex() const { return toProgramDataIndex(); }
- int fValue;
friend class GrGLProgramDataManager; // For accessing toProgramDataIndex().
friend class GrGLProgramBuilder; // For accessing toShaderBuilderIndex().
};
+ class VaryingHandle : public ShaderResourceHandle {
+ public:
+ /** Creates a reference to a varying in separable varyings of a GrGLShaderBuilder.
+ * The ref can be used to set the varying with the corresponding GrGLProgramDataManager.*/
+ static VaryingHandle CreateFromSeparableVaryingIndex(int i) {
+ return VaryingHandle(i);
+ }
+ VaryingHandle() { }
+ bool operator==(const VaryingHandle& other) const { return other.fValue == fValue; }
+ private:
+ VaryingHandle(int value) : ShaderResourceHandle(value) { }
+ int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
+ friend class GrGLProgramDataManager; // For accessing toProgramDataIndex().
+ };
+
GrGLProgramDataManager(GrGpuGL*, GrGLProgram*, const GrGLProgramBuilder&);
/** Functions for uploading uniform values. The varities ending in v can be used to upload to an
@@ -78,6 +95,10 @@ public:
// convenience method for uploading a SkMatrix to a 3x3 matrix uniform
void setSkMatrix(UniformHandle, const SkMatrix&) const;
+ void setProgramPathFragmentInputTransform(VaryingHandle i,
+ unsigned components,
+ const SkMatrix& matrix) const;
+
private:
enum {
kUnusedUniform = -1,
@@ -91,9 +112,17 @@ private:
int fArrayCount;
);
};
+ struct Varying {
+ GrGLint fLocation;
+ SkDEBUGCODE(
+ GrSLType fType;
+ );
+ };
SkTArray<Uniform, true> fUniforms;
+ SkTArray<Varying, true> fVaryings;
GrGpuGL* fGpu;
+ GrGLProgram* fProgram;
typedef SkRefCnt INHERITED;
};
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 7cdbcd0efc..286924e1ef 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -21,7 +21,7 @@ bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage,
uint16_t* effectKeySize,
bool* setTrueIfReadsDst,
bool* setTrueIfReadsPos,
- bool* setTrueIfHasVertexCode) {
+ bool* setTrueIfRequiresVertexShader) {
const GrBackendEffectFactory& factory = stage.getEffect()->getFactory();
GrDrawEffect drawEffect(stage, useExplicitLocalCoords);
if (stage.getEffect()->willReadDstColor()) {
@@ -30,8 +30,8 @@ bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage,
if (stage.getEffect()->willReadFragmentPosition()) {
*setTrueIfReadsPos = true;
}
- if (stage.getEffect()->hasVertexCode()) {
- *setTrueIfHasVertexCode = true;
+ if (stage.getEffect()->requiresVertexShader()) {
+ *setTrueIfRequiresVertexShader = true;
}
factory.getGLEffectKey(drawEffect, caps, b);
size_t size = b->size();
@@ -102,9 +102,10 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
bool readsDst = false;
bool readFragPosition = false;
- // We use vertexshader-less shader programs only when drawing paths.
- bool hasVertexCode = !(GrGpu::kDrawPath_DrawType == drawType ||
- GrGpu::kDrawPaths_DrawType == drawType);
+
+ // Provide option for shader programs without vertex shader only when drawing paths.
+ bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType);
+
int numStages = 0;
if (!skipColor) {
numStages += drawState.numColorStages() - firstEffectiveColorStage;
@@ -118,7 +119,6 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages);
int offsetAndSizeIndex = 0;
-
bool effectKeySuccess = true;
if (!skipColor) {
for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
@@ -133,7 +133,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
drawState.getColorStage(s), gpu->glCaps(),
requiresLocalCoordAttrib, &b,
&effectKeySize, &readsDst,
- &readFragPosition, &hasVertexCode);
+ &readFragPosition, &requiresVertexShader);
effectKeySuccess |= (effectOffset <= SK_MaxU16);
offsetAndSize[0] = SkToU16(effectOffset);
@@ -154,7 +154,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
drawState.getCoverageStage(s), gpu->glCaps(),
requiresLocalCoordAttrib, &b,
&effectKeySize, &readsDst,
- &readFragPosition, &hasVertexCode);
+ &readFragPosition, &requiresVertexShader);
effectKeySuccess |= (effectOffset <= SK_MaxU16);
offsetAndSize[0] = SkToU16(effectOffset);
@@ -174,7 +174,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
// Because header is a pointer into the dynamic array, we can't push any new data into the key
// below here.
- header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib;
+ header->fRequiresVertexShader = requiresVertexShader || requiresLocalCoordAttrib;
header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType;
// Currently the experimental GS will only work with triangle prims (and it doesn't do anything
@@ -192,7 +192,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
header->fColorInput = kUniform_ColorInput;
} else {
header->fColorInput = kAttribute_ColorInput;
- header->fHasVertexCode = true;
+ header->fRequiresVertexShader = true;
}
bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
@@ -203,7 +203,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
header->fCoverageInput = kUniform_ColorInput;
} else {
header->fCoverageInput = kAttribute_ColorInput;
- header->fHasVertexCode = true;
+ header->fRequiresVertexShader = true;
}
if (readsDst) {
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index e8925d0c5c..4796d5a4b3 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -147,7 +147,7 @@ private:
ColorInput fCoverageInput : 8;
CoverageOutput fCoverageOutput : 8;
- SkBool8 fHasVertexCode;
+ SkBool8 fRequiresVertexShader;
SkBool8 fEmitsPointSize;
// To enable experimental geometry shader code (not for use in
@@ -203,7 +203,7 @@ private:
uint16_t* effectKeySize,
bool* setTrueIfReadsDst,
bool* setTrueIfReadsPos,
- bool* setTrueIfHasVertexCode);
+ bool* setTrueIfRequiresVertexShader);
void finalize();
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
index efb64fe640..8d97b42329 100644
--- a/src/gpu/gl/GrGLProgramEffects.cpp
+++ b/src/gpu/gl/GrGLProgramEffects.cpp
@@ -9,6 +9,8 @@
#include "GrGLProgramEffects.h"
#include "GrDrawEffect.h"
#include "gl/GrGLEffect.h"
+#include "gl/GrGLPathRendering.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "gl/GrGLVertexEffect.h"
#include "gl/GrGpuGL.h"
@@ -294,6 +296,16 @@ void GrGLVertexProgramEffects::emitTransforms(GrGLFullProgramBuilder* builder,
uint32_t totalKey = GenTransformKey(drawEffect);
int numTransforms = drawEffect.effect()->numTransforms();
transforms.push_back_n(numTransforms);
+
+ SkTArray<PathTransform, true>* pathTransforms = NULL;
+ const GrGLCaps* glCaps = builder->ctxInfo().caps();
+ if (glCaps->pathRenderingSupport() &&
+ builder->gpu()->glPathRendering()->texturingMode() ==
+ GrGLPathRendering::SeparableShaders_TexturingMode) {
+ pathTransforms = &fPathTransforms.push_back();
+ pathTransforms->push_back_n(numTransforms);
+ }
+
for (int t = 0; t < numTransforms; t++) {
GrSLType varyingType = kVoid_GrSLType;
const char* uniName;
@@ -330,7 +342,13 @@ void GrGLVertexProgramEffects::emitTransforms(GrGLFullProgramBuilder* builder,
const char* vsVaryingName;
const char* fsVaryingName;
GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
- builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+ if (pathTransforms) {
+ (*pathTransforms)[t].fHandle =
+ builder->addSeparableVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+ (*pathTransforms)[t].fType = varyingType;
+ } else {
+ builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+ }
const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ?
vsBuilder->positionAttribute() :
@@ -350,20 +368,27 @@ void GrGLVertexProgramEffects::emitTransforms(GrGLFullProgramBuilder* builder,
}
void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
- const GrGLProgramDataManager& programResourceManager,
+ GrGpu::DrawType drawType,
+ const GrGLProgramDataManager& programDataManager,
const GrEffectStage* effectStages[]) {
int numEffects = fGLEffects.count();
SkASSERT(numEffects == fTransforms.count());
SkASSERT(numEffects == fSamplers.count());
for (int e = 0; e < numEffects; ++e) {
GrDrawEffect drawEffect(*effectStages[e], fHasExplicitLocalCoords);
- fGLEffects[e]->setData(programResourceManager, drawEffect);
- this->setTransformData(programResourceManager, drawEffect, e);
+ fGLEffects[e]->setData(programDataManager, drawEffect);
+ if (GrGpu::IsPathRenderingDrawType(drawType)) {
+ this->setPathTransformData(gpu, programDataManager, drawEffect, e);
+ } else {
+ this->setTransformData(gpu, programDataManager, drawEffect, e);
+ }
+
this->bindTextures(gpu, drawEffect.effect(), e);
}
}
-void GrGLVertexProgramEffects::setTransformData(const GrGLProgramDataManager& programResourceManager,
+void GrGLVertexProgramEffects::setTransformData(GrGpuGL* gpu,
+ const GrGLProgramDataManager& pdman,
const GrDrawEffect& drawEffect,
int effectIdx) {
SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
@@ -373,12 +398,39 @@ void GrGLVertexProgramEffects::setTransformData(const GrGLProgramDataManager& pr
SkASSERT(transforms[t].fHandle.isValid());
const SkMatrix& matrix = get_transform_matrix(drawEffect, t);
if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
- programResourceManager.setSkMatrix(transforms[t].fHandle, matrix);
+ pdman.setSkMatrix(transforms[t].fHandle, matrix);
transforms[t].fCurrentValue = matrix;
}
}
}
+void GrGLVertexProgramEffects::setPathTransformData(GrGpuGL* gpu,
+ const GrGLProgramDataManager& pdman,
+ const GrDrawEffect& drawEffect,
+ int effectIdx) {
+ SkTArray<PathTransform, true>& transforms = fPathTransforms[effectIdx];
+ int numTransforms = transforms.count();
+ SkASSERT(numTransforms == drawEffect.effect()->numTransforms());
+ for (int t = 0; t < numTransforms; ++t) {
+ SkASSERT(transforms[t].fHandle.isValid());
+ const SkMatrix& transform = get_transform_matrix(drawEffect, t);
+ if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
+ continue;
+ }
+ transforms[t].fCurrentValue = transform;
+ switch (transforms[t].fType) {
+ case kVec2f_GrSLType:
+ pdman.setProgramPathFragmentInputTransform(transforms[t].fHandle, 2, transform);
+ break;
+ case kVec3f_GrSLType:
+ pdman.setProgramPathFragmentInputTransform(transforms[t].fHandle, 3, transform);
+ break;
+ default:
+ SkFAIL("Unexpected matrix type.");
+ }
+ }
+}
+
GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullProgramBuilder* builder,
int reserveCount)
: fBuilder(builder)
@@ -445,14 +497,15 @@ void GrGLPathTexGenProgramEffects::setupPathTexGen(GrGLFragmentOnlyProgramBuilde
}
void GrGLPathTexGenProgramEffects::setData(GrGpuGL* gpu,
- const GrGLProgramDataManager& programResourceManager,
- const GrEffectStage* effectStages[]) {
+ GrGpu::DrawType,
+ const GrGLProgramDataManager& pdman,
+ const GrEffectStage* effectStages[]) {
int numEffects = fGLEffects.count();
SkASSERT(numEffects == fTransforms.count());
SkASSERT(numEffects == fSamplers.count());
for (int e = 0; e < numEffects; ++e) {
GrDrawEffect drawEffect(*effectStages[e], false);
- fGLEffects[e]->setData(programResourceManager, drawEffect);
+ fGLEffects[e]->setData(pdman, drawEffect);
this->setPathTexGenState(gpu, drawEffect, e);
this->bindTextures(gpu, drawEffect.effect(), e);
}
diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h
index e4d84a013b..0eaff53b76 100644
--- a/src/gpu/gl/GrGLProgramEffects.h
+++ b/src/gpu/gl/GrGLProgramEffects.h
@@ -10,6 +10,7 @@
#include "GrBackendEffectFactory.h"
#include "GrGLProgramDataManager.h"
+#include "GrGpu.h"
#include "GrTexture.h"
#include "GrTextureAccess.h"
@@ -28,6 +29,7 @@ class GrGLFragmentOnlyProgramBuilder;
class GrGLProgramEffects : public SkRefCnt {
public:
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+ typedef GrGLProgramDataManager::VaryingHandle VaryingHandle;
/**
* This class emits some of the code inserted into the shaders for an effect. The code it
@@ -51,6 +53,7 @@ public:
* Calls setData() on each effect, and sets their transformation matrices and texture bindings.
*/
virtual void setData(GrGpuGL*,
+ GrGpu::DrawType,
const GrGLProgramDataManager&,
const GrEffectStage* effectStages[]) = 0;
@@ -165,6 +168,7 @@ public:
class GrGLVertexProgramEffects : public GrGLProgramEffects {
public:
virtual void setData(GrGpuGL*,
+ GrGpu::DrawType,
const GrGLProgramDataManager&,
const GrEffectStage* effectStages[]) SK_OVERRIDE;
@@ -205,7 +209,9 @@ private:
/**
* Helper for setData(). Sets all the transform matrices for an effect.
*/
- void setTransformData(const GrGLProgramDataManager&, const GrDrawEffect&, int effectIdx);
+ void setTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrDrawEffect&, int effectIdx);
+ void setPathTransformData(GrGpuGL* gpu, const GrGLProgramDataManager&, const GrDrawEffect&,
+ int effectIdx);
struct Transform {
Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
@@ -213,7 +219,15 @@ private:
SkMatrix fCurrentValue;
};
+ struct PathTransform {
+ PathTransform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
+ VaryingHandle fHandle;
+ SkMatrix fCurrentValue;
+ GrSLType fType;
+ };
+
SkTArray<SkSTArray<2, Transform, true> > fTransforms;
+ SkTArray<SkTArray<PathTransform, true> > fPathTransforms;
bool fHasExplicitLocalCoords;
friend class GrGLVertexProgramEffectsBuilder;
@@ -253,6 +267,7 @@ private:
class GrGLPathTexGenProgramEffects : public GrGLProgramEffects {
public:
virtual void setData(GrGpuGL*,
+ GrGpu::DrawType,
const GrGLProgramDataManager&,
const GrEffectStage* effectStages[]) SK_OVERRIDE;
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 110a6671ba..94fd307f6d 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -52,13 +52,6 @@ public:
// state.
void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
- bool shouldUseFixedFunctionTexturing() const {
- // At the moment non-fixed-function texturing is not implemented
- // even though the GrGLPathRendering would support it. Thus just
- // return the below.
- return this->glCaps().pathRenderingSupport();
- }
-
bool programUnitTest(int maxStages);
// GrGpu overrides
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index dac7443d17..b19676adb9 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -247,9 +247,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
return false;
}
- SkASSERT((kDrawPath_DrawType != type && kDrawPaths_DrawType != type)
- || !fCurrentProgram->hasVertexShader());
-
fCurrentProgram.get()->ref();
GrGLuint programID = fCurrentProgram->programID();
@@ -261,7 +258,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
- fCurrentProgram->setData(blendOpts,
+ fCurrentProgram->setData(type,
+ blendOpts,
colorStages.begin(),
coverageStages.begin(),
dstCopy,
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index f4ee32b48d..41b84d806a 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -99,10 +99,13 @@ bool GrGLProgramBuilder::genProgram(const GrEffectStage* colorStages[],
GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
const GrGLProgramDesc& desc)
- : fFragOnly(!desc.getHeader().fHasVertexCode && gpu->shouldUseFixedFunctionTexturing())
+ : fFragOnly(!desc.getHeader().fRequiresVertexShader &&
+ gpu->glCaps().pathRenderingSupport() &&
+ gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode)
, fTexCoordSetCnt(0)
, fProgramID(0)
, fFS(this, desc)
+ , fSeparableVaryingInfos(kVarsPerBlock)
, fDesc(desc)
, fGpu(gpu)
, fUniforms(kVarsPerBlock) {
@@ -304,6 +307,16 @@ void GrGLProgramBuilder::resolveProgramLocations(GrGLuint programId) {
fUniforms[i].fLocation = location;
}
}
+
+ int count = fSeparableVaryingInfos.count();
+ for (int i = 0; i < count; ++i) {
+ GrGLint location;
+ GL_CALL_RET(location,
+ GetProgramResourceLocation(programId,
+ GR_GL_FRAGMENT_INPUT,
+ fSeparableVaryingInfos[i].fVariable.c_str()));
+ fSeparableVaryingInfos[i].fLocation = location;
+ }
}
const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
@@ -345,6 +358,18 @@ void GrGLFullProgramBuilder::addVarying(GrSLType type,
fFS.addVarying(type, fsInputName->c_str(), fsInName);
}
+GrGLFullProgramBuilder::VaryingHandle
+GrGLFullProgramBuilder::addSeparableVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName,
+ const char** fsInName) {
+ addVarying(type, name, vsOutName, fsInName);
+ SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
+ varying.fVariable = fFS.fInputs.back();
+ return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos.count() - 1);
+}
+
+
GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffects(
const GrEffectStage* effectStages[],
int effectCnt,
@@ -381,7 +406,7 @@ void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) {
GrGLFragmentOnlyProgramBuilder::GrGLFragmentOnlyProgramBuilder(GrGpuGL* gpu,
const GrGLProgramDesc& desc)
: INHERITED(gpu, desc) {
- SkASSERT(!desc.getHeader().fHasVertexCode);
+ SkASSERT(!desc.getHeader().fRequiresVertexShader);
SkASSERT(gpu->glCaps().pathRenderingSupport());
SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 09f7eba511..d1af63fc4e 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -40,6 +40,7 @@ public:
};
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+ typedef GrGLProgramDataManager::VaryingHandle VaryingHandle;
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
@@ -69,6 +70,13 @@ public:
// name strings. Otherwise, we'd have to hand out copies.
typedef GrTAllocator<UniformInfo> UniformInfoArray;
+ struct SeparableVaryingInfo {
+ GrGLShaderVar fVariable;
+ GrGLint fLocation;
+ };
+
+ typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray;
+
/** Generates a shader program.
*
* The program implements what is specified in the stages given as input.
@@ -91,6 +99,9 @@ public:
bool hasVertexShader() const { SkASSERT(fProgramID); return !fFragOnly; }
int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetCnt; }
const UniformInfoArray& getUniformInfos() const { return fUniforms; }
+ const SeparableVaryingInfoArray& getSeparableVaryingInfos() const {
+ return fSeparableVaryingInfos;
+ }
virtual ~GrGLProgramBuilder() {}
@@ -126,13 +137,12 @@ public:
const GrGLContextInfo& ctxInfo() const;
GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; }
+ GrGpuGL* gpu() const { return fGpu; }
protected:
typedef GrTAllocator<GrGLShaderVar> VarArray;
GrGLProgramBuilder(GrGpuGL*, const GrGLProgramDesc&);
- GrGpuGL* gpu() const { return fGpu; }
-
const GrGLProgramDesc& desc() const { return fDesc; }
// Helper for emitEffects().
@@ -162,6 +172,7 @@ protected:
int fTexCoordSetCnt;
GrGLuint fProgramID;
GrGLFragmentShaderBuilder fFS;
+ SeparableVaryingInfoArray fSeparableVaryingInfos;
private:
class CodeStage : SkNoncopyable {
public:
@@ -271,6 +282,17 @@ public:
const char** vsOutName = NULL,
const char** fsInName = NULL);
+ /** Add a separable varying input variable to the current program.
+ * A separable varying (fragment shader input) is a varying that can be used also when vertex
+ * shaders are not used. With a vertex shader, the operation is same as with other
+ * varyings. Without a vertex shader, such as with NV_path_rendering, GL APIs are used to
+ * populate the variable. The APIs can refer to the variable through the returned handle.
+ */
+ VaryingHandle addSeparableVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName,
+ const char** fsInName);
+
GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; }
private:
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 3ab17d4f8d..af280466ae 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -16,8 +16,8 @@
#include "GrContextFactory.h"
#include "GrDrawEffect.h"
#include "effects/GrConfigConversionEffect.h"
+#include "gl/GrGLPathRendering.h"
#include "gl/GrGpuGL.h"
-
#include "SkChecksum.h"
#include "SkRandom.h"
#include "Test.h"
@@ -42,7 +42,7 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
bool dstRead = false;
bool fragPos = false;
- bool vertexCode = false;
+ bool vertexShader = false;
for (int s = 0; s < numStages; ++s) {
uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
kEffectKeyOffsetsAndLengthOffset +
@@ -56,7 +56,7 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
GrEffectKeyBuilder b(&fKey);
uint16_t effectKeySize;
if (!GetEffectKeyAndUpdateStats(*stages[s], gpu->glCaps(), useLocalCoords, &b,
- &effectKeySize, &dstRead, &fragPos, &vertexCode)) {
+ &effectKeySize, &dstRead, &fragPos, &vertexShader)) {
fKey.reset();
return false;
}
@@ -114,10 +114,10 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
header->fFragPosKey = 0;
}
- header->fHasVertexCode = vertexCode ||
- useLocalCoords ||
- kAttribute_ColorInput == header->fColorInput ||
- kAttribute_ColorInput == header->fCoverageInput;
+ header->fRequiresVertexShader = vertexShader ||
+ useLocalCoords ||
+ kAttribute_ColorInput == header->fColorInput ||
+ kAttribute_ColorInput == header->fCoverageInput;
CoverageOutput coverageOutput;
bool illegalCoverageOutput;
@@ -178,7 +178,8 @@ bool GrGpuGL::programUnitTest(int maxStages) {
SkAutoSTMalloc<8, const GrEffectStage*> stages(numStages);
- bool useFixedFunctionTexturing = this->shouldUseFixedFunctionTexturing();
+ bool useFixedFunctionPathRendering = this->glCaps().pathRenderingSupport() &&
+ this->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode;
for (int s = 0; s < numStages;) {
SkAutoTUnref<const GrEffect> effect(GrEffectTestFactory::CreateStage(
@@ -198,7 +199,7 @@ bool GrGpuGL::programUnitTest(int maxStages) {
// If adding this effect would exceed the max texture coord set count then generate a
// new random effect.
- if (useFixedFunctionTexturing && !effect->hasVertexCode()) {
+ if (useFixedFunctionPathRendering && !effect->requiresVertexShader()) {
int numTransforms = effect->numTransforms();
if (currTextureCoordSet + numTransforms > this->glCaps().maxFixedFunctionTextureCoords()) {
continue;
@@ -206,7 +207,7 @@ bool GrGpuGL::programUnitTest(int maxStages) {
currTextureCoordSet += numTransforms;
}
- useFixedFunctionTexturing = useFixedFunctionTexturing && !effect->hasVertexCode();
+ useFixedFunctionPathRendering = useFixedFunctionPathRendering && !effect->requiresVertexShader();
for (int i = 0; i < numAttribs; ++i) {
attribIndices[i] = currAttribIndex++;