зеркало из https://github.com/mozilla/moz-skia.git
Use vertexless shaders when NVpr is available
Adds support for vertexless shaders and enables them when NV_path_rendering is available. This takes a GrGLFragmentOnlyShaderBuilder class, a GrGLTexGenEffectArray class, support for setting TexGen and the projection matrix in GrGpuGL, and code for setting the GL fixed function state where necessary. R=bsalomon@google.com, kkinnunen@nvidia.com Author: cdalton@nvidia.com Review URL: https://codereview.chromium.org/25846002 git-svn-id: http://skia.googlecode.com/svn/trunk@11620 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
d35736d2d2
Коммит
6b30e45740
|
@ -39,7 +39,9 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
|
|||
const GrEffectStage* colorStages[],
|
||||
const GrEffectStage* coverageStages[])
|
||||
: fGpu(gpu)
|
||||
, fUniformManager(gpu) {
|
||||
, fUniformManager(gpu)
|
||||
, fHasVertexShader(false)
|
||||
, fNumTexCoordSets(0) {
|
||||
fDesc = desc;
|
||||
fProgramID = 0;
|
||||
|
||||
|
@ -48,7 +50,21 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
|
|||
fColor = GrColor_ILLEGAL;
|
||||
fColorFilterColor = GrColor_ILLEGAL;
|
||||
|
||||
this->genProgram(colorStages, coverageStages);
|
||||
if (fDesc.getHeader().fHasVertexCode ||
|
||||
!fGpu->glCaps().fixedFunctionSupport() ||
|
||||
!fGpu->glCaps().pathStencilingSupport()) {
|
||||
|
||||
GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc);
|
||||
if (this->genProgram(&fullBuilder, colorStages, coverageStages)) {
|
||||
fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform();
|
||||
fHasVertexShader = true;
|
||||
}
|
||||
} else {
|
||||
GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager, fDesc);
|
||||
if (this->genProgram(&fragmentOnlyBuilder, colorStages, coverageStages)) {
|
||||
fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GrGLProgram::~GrGLProgram() {
|
||||
|
@ -205,18 +221,16 @@ void expand_known_value4f(SkString* string, GrSLConstantVec vec) {
|
|||
|
||||
}
|
||||
|
||||
bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
|
||||
bool GrGLProgram::genProgram(GrGLShaderBuilder* builder,
|
||||
const GrEffectStage* colorStages[],
|
||||
const GrEffectStage* coverageStages[]) {
|
||||
SkASSERT(0 == fProgramID);
|
||||
|
||||
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
|
||||
|
||||
GrGLFullShaderBuilder builder(fGpu, fUniformManager, fDesc);
|
||||
fUniformHandles.fViewMatrixUni = builder.getViewMatrixUniform();
|
||||
|
||||
// incoming color to current stage being processed.
|
||||
SkString inColor = builder.getInputColor();
|
||||
GrSLConstantVec knownColorValue = builder.getKnownColorValue();
|
||||
SkString inColor = builder->getInputColor();
|
||||
GrSLConstantVec knownColorValue = builder->getKnownColorValue();
|
||||
|
||||
// Get the coeffs for the Mode-based color filter, determine if color is needed.
|
||||
SkXfermode::Coeff colorCoeff;
|
||||
|
@ -229,20 +243,20 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
|
|||
need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
|
||||
|
||||
fColorEffects.reset(
|
||||
builder.createAndEmitEffects(colorStages,
|
||||
fDesc.effectKeys(),
|
||||
needColor ? fDesc.numColorEffects() : 0,
|
||||
&inColor,
|
||||
&knownColorValue));
|
||||
builder->createAndEmitEffects(colorStages,
|
||||
fDesc.effectKeys(),
|
||||
needColor ? fDesc.numColorEffects() : 0,
|
||||
&inColor,
|
||||
&knownColorValue));
|
||||
|
||||
// Insert the color filter. This will soon be replaced by a color effect.
|
||||
if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) {
|
||||
const char* colorFilterColorUniName = NULL;
|
||||
fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
||||
kVec4f_GrSLType, "FilterColor",
|
||||
&colorFilterColorUniName);
|
||||
fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
||||
kVec4f_GrSLType, "FilterColor",
|
||||
&colorFilterColorUniName);
|
||||
|
||||
builder.fsCodeAppend("\tvec4 filteredColor;\n");
|
||||
builder->fsCodeAppend("\tvec4 filteredColor;\n");
|
||||
const char* color;
|
||||
// add_color_filter requires a real input string.
|
||||
if (knownColorValue == kOnes_GrSLConstantVec) {
|
||||
|
@ -252,36 +266,36 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
|
|||
} else {
|
||||
color = inColor.c_str();
|
||||
}
|
||||
add_color_filter(&builder, "filteredColor", filterColorCoeff,
|
||||
add_color_filter(builder, "filteredColor", filterColorCoeff,
|
||||
colorCoeff, colorFilterColorUniName, color);
|
||||
inColor = "filteredColor";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// compute the partial coverage
|
||||
SkString inCoverage = builder.getInputCoverage();
|
||||
GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue();
|
||||
SkString inCoverage = builder->getInputCoverage();
|
||||
GrSLConstantVec knownCoverageValue = builder->getKnownCoverageValue();
|
||||
|
||||
fCoverageEffects.reset(
|
||||
builder.createAndEmitEffects(coverageStages,
|
||||
fDesc.getEffectKeys() + fDesc.numColorEffects(),
|
||||
fDesc.numCoverageEffects(),
|
||||
&inCoverage,
|
||||
&knownCoverageValue));
|
||||
builder->createAndEmitEffects(coverageStages,
|
||||
fDesc.getEffectKeys() + fDesc.numColorEffects(),
|
||||
fDesc.numCoverageEffects(),
|
||||
&inCoverage,
|
||||
&knownCoverageValue));
|
||||
|
||||
// discard if coverage is zero
|
||||
if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) {
|
||||
if (kZeros_GrSLConstantVec == knownCoverageValue) {
|
||||
// This is unfortunate.
|
||||
builder.fsCodeAppend("\tdiscard;\n");
|
||||
builder->fsCodeAppend("\tdiscard;\n");
|
||||
} else {
|
||||
builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
|
||||
inCoverage.c_str());
|
||||
builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
|
||||
inCoverage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
|
||||
const char* secondaryOutputName = builder.enableSecondaryOutput();
|
||||
const char* secondaryOutputName = builder->enableSecondaryOutput();
|
||||
|
||||
// default coeff to ones for kCoverage_DualSrcOutput
|
||||
SkString coeff;
|
||||
|
@ -317,7 +331,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
|
|||
knownCoeffValue,
|
||||
knownCoverageValue,
|
||||
false);
|
||||
builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_str());
|
||||
builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -343,7 +357,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
|
|||
SkString dstContribution;
|
||||
GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContribution,
|
||||
dstCoeff.c_str(),
|
||||
builder.dstColor(),
|
||||
builder->dstColor(),
|
||||
knownDstCoeffValue,
|
||||
kNone_GrSLConstantVec,
|
||||
true);
|
||||
|
@ -358,18 +372,18 @@ bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
|
|||
} else {
|
||||
expand_known_value4f(&fragColor, knownFragColorValue);
|
||||
}
|
||||
builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColor.c_str());
|
||||
builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragColor.c_str());
|
||||
|
||||
if (!builder.finish(&fProgramID)) {
|
||||
if (!builder->finish(&fProgramID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fUniformHandles.fRTHeightUni = builder.getRTHeightUniform();
|
||||
fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform();
|
||||
fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform();
|
||||
fUniformHandles.fColorUni = builder.getColorUniform();
|
||||
fUniformHandles.fCoverageUni = builder.getCoverageUniform();
|
||||
fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform();
|
||||
fUniformHandles.fRTHeightUni = builder->getRTHeightUniform();
|
||||
fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform();
|
||||
fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform();
|
||||
fUniformHandles.fColorUni = builder->getColorUniform();
|
||||
fUniformHandles.fCoverageUni = builder->getCoverageUniform();
|
||||
fUniformHandles.fDstCopySamplerUni = builder->getDstCopySamplerUniform();
|
||||
// This must be called after we set fDstCopySamplerUni above.
|
||||
this->initSamplerUniforms();
|
||||
|
||||
|
@ -445,6 +459,10 @@ void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
|
|||
|
||||
fColorEffects->setData(fGpu, fUniformManager, colorStages);
|
||||
fCoverageEffects->setData(fGpu, fUniformManager, coverageStages);
|
||||
|
||||
if (!fHasVertexShader) {
|
||||
fGpu->disableUnusedTexGen(fNumTexCoordSets);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgram::setColor(const GrDrawState& drawState,
|
||||
|
@ -537,9 +555,13 @@ void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
|
|||
fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight));
|
||||
}
|
||||
|
||||
if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
|
||||
!fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) ||
|
||||
fMatrixState.fRenderTargetSize != size) {
|
||||
if (!fHasVertexShader) {
|
||||
SkASSERT(!fUniformHandles.fViewMatrixUni.isValid());
|
||||
fGpu->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
|
||||
} else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
|
||||
fMatrixState.fRenderTargetSize != size ||
|
||||
!fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) {
|
||||
SkASSERT(fUniformHandles.fViewMatrixUni.isValid());
|
||||
|
||||
fMatrixState.fViewMatrix = drawState.getViewMatrix();
|
||||
fMatrixState.fRenderTargetSize = size;
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
*/
|
||||
GrGLuint programID() const { return fProgramID; }
|
||||
|
||||
bool hasVertexShader() const { return fHasVertexShader; }
|
||||
|
||||
/**
|
||||
* Some GL state that is relevant to programs is not stored per-program. In particular color
|
||||
* and coverage attributes can be global state. This struct is read and updated by
|
||||
|
@ -160,7 +162,9 @@ private:
|
|||
* This is the heavy initialization routine for building a GLProgram. colorStages and
|
||||
* coverageStages correspond to the output of GrGLProgramDesc::Build().
|
||||
*/
|
||||
bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]);
|
||||
bool genProgram(GrGLShaderBuilder* builder,
|
||||
const GrEffectStage* colorStages[],
|
||||
const GrEffectStage* coverageStages[]);
|
||||
|
||||
// Sets the texture units for samplers
|
||||
void initSamplerUniforms();
|
||||
|
@ -195,6 +199,9 @@ private:
|
|||
GrGLUniformManager fUniformManager;
|
||||
UniformHandles fUniformHandles;
|
||||
|
||||
bool fHasVertexShader;
|
||||
int fNumTexCoordSets;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
|
|
|
@ -233,6 +233,7 @@ private:
|
|||
friend class GrGLProgram;
|
||||
friend class GrGLShaderBuilder;
|
||||
friend class GrGLFullShaderBuilder;
|
||||
friend class GrGLFragmentOnlyShaderBuilder;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,6 @@ enum {
|
|||
kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
|
||||
kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
|
||||
kTransformKeyBits = kMatrixTypeKeyBits + 1,
|
||||
kTransformKeyMask = (1 << kTransformKeyBits) - 1,
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
@ -69,8 +68,78 @@ inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the matrix type from transformKey for the transform at transformIdx.
|
||||
*/
|
||||
MatrixType get_matrix_type(EffectKey transformKey, int transformIdx) {
|
||||
return static_cast<MatrixType>(
|
||||
(transformKey >> (kTransformKeyBits * transformIdx)) & kMatrixTypeKeyMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the source coords from transformKey for the transform at transformIdx. It may not be
|
||||
* the same coordinate set as the original GrCoordTransform if the position and local coords are
|
||||
* identical for this program.
|
||||
*/
|
||||
GrCoordSet get_source_coords(EffectKey transformKey, int transformIdx) {
|
||||
return (transformKey >> (kTransformKeyBits * transformIdx)) & kPositionCoords_Flag ?
|
||||
kPosition_GrCoordSet :
|
||||
kLocal_GrCoordSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the final translation that a transform needs to apply to its source coords (and
|
||||
* verifies that a translation is all it needs).
|
||||
*/
|
||||
void get_transform_translation(const GrDrawEffect& drawEffect,
|
||||
int transformIdx,
|
||||
GrGLfloat* tx,
|
||||
GrGLfloat* ty) {
|
||||
const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx);
|
||||
SkASSERT(!coordTransform.reverseY());
|
||||
const SkMatrix& matrix = coordTransform.getMatrix();
|
||||
if (kLocal_GrCoordSet == coordTransform.sourceCoords() &&
|
||||
!drawEffect.programHasExplicitLocalCoords()) {
|
||||
const SkMatrix& coordChangeMatrix = drawEffect.getCoordChangeMatrix();
|
||||
SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
|
||||
*tx = SkScalarToFloat(matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX]);
|
||||
*ty = SkScalarToFloat(matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY]);
|
||||
} else {
|
||||
SkASSERT(SkMatrix::kTranslate_Mask == matrix.getType());
|
||||
*tx = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
|
||||
*ty = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the final matrix that a transform needs to apply to its source coords.
|
||||
*/
|
||||
SkMatrix get_transform_matrix(const GrDrawEffect& drawEffect, int transformIdx) {
|
||||
const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(transformIdx);
|
||||
SkMatrix combined;
|
||||
if (kLocal_GrCoordSet == coordTransform.sourceCoords() &&
|
||||
!drawEffect.programHasExplicitLocalCoords()) {
|
||||
combined.setConcat(coordTransform.getMatrix(), drawEffect.getCoordChangeMatrix());
|
||||
} else {
|
||||
combined = coordTransform.getMatrix();
|
||||
}
|
||||
if (coordTransform.reverseY()) {
|
||||
// combined.postScale(1,-1);
|
||||
// combined.postTranslate(0,1);
|
||||
combined.set(SkMatrix::kMSkewY,
|
||||
combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
||||
combined.set(SkMatrix::kMScaleY,
|
||||
combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
||||
combined.set(SkMatrix::kMTransY,
|
||||
combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EffectKey GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) {
|
||||
EffectKey key = 0;
|
||||
int numAttributes = drawEffect.getVertexAttribIndexCount();
|
||||
|
@ -144,6 +213,23 @@ GrGLProgramEffects::~GrGLProgramEffects() {
|
|||
}
|
||||
}
|
||||
|
||||
void GrGLProgramEffects::emitSamplers(GrGLShaderBuilder* builder,
|
||||
const GrEffectRef& effect,
|
||||
TextureSamplerArray* outSamplers) {
|
||||
SkTArray<Sampler, true>& samplers = fSamplers.push_back();
|
||||
int numTextures = effect->numTextures();
|
||||
samplers.push_back_n(numTextures);
|
||||
SkString name;
|
||||
for (int t = 0; t < numTextures; ++t) {
|
||||
name.printf("Sampler%d", t);
|
||||
samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
||||
kSampler2D_GrSLType,
|
||||
name.c_str());
|
||||
SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
|
||||
(samplers[t].fUniform, effect->textureAccess(t)));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager, int* texUnitIdx) {
|
||||
int numEffects = fGLEffects.count();
|
||||
SkASSERT(numEffects == fSamplers.count());
|
||||
|
@ -158,77 +244,6 @@ void GrGLProgramEffects::initSamplers(const GrGLUniformManager& uniformManager,
|
|||
}
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
|
||||
const GrGLUniformManager& uniformManager,
|
||||
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(uniformManager, drawEffect);
|
||||
this->setTransformData(uniformManager, drawEffect, e);
|
||||
this->bindTextures(gpu, *drawEffect.effect(), e);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager,
|
||||
const GrDrawEffect& drawEffect,
|
||||
int effectIdx) {
|
||||
SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
|
||||
int numTransforms = transforms.count();
|
||||
SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms());
|
||||
for (int t = 0; t < numTransforms; ++t) {
|
||||
const GrCoordTransform& coordTransform = (*drawEffect.effect())->coordTransform(t);
|
||||
const SkMatrix& matrix = coordTransform.getMatrix();
|
||||
const SkMatrix& coordChangeMatrix = kLocal_GrCoordSet == coordTransform.sourceCoords() ?
|
||||
drawEffect.getCoordChangeMatrix() :
|
||||
SkMatrix::I();
|
||||
SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType));
|
||||
switch (transforms[t].fType) {
|
||||
case kVoid_GrSLType:
|
||||
SkASSERT(matrix.isIdentity());
|
||||
SkASSERT(coordChangeMatrix.isIdentity());
|
||||
SkASSERT(!coordTransform.reverseY());
|
||||
return;
|
||||
case kVec2f_GrSLType: {
|
||||
SkASSERT(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
|
||||
SkASSERT(!coordTransform.reverseY());
|
||||
SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
|
||||
SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
|
||||
if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx ||
|
||||
transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) {
|
||||
uniformManager.set2f(transforms[t].fHandle, tx, ty);
|
||||
transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx);
|
||||
transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMat33f_GrSLType: {
|
||||
SkMatrix combined;
|
||||
combined.setConcat(matrix, coordChangeMatrix);
|
||||
if (coordTransform.reverseY()) {
|
||||
// combined.postScale(1,-1);
|
||||
// combined.postTranslate(0,1);
|
||||
combined.set(SkMatrix::kMSkewY,
|
||||
combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
||||
combined.set(SkMatrix::kMScaleY,
|
||||
combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
||||
combined.set(SkMatrix::kMTransY,
|
||||
combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
||||
}
|
||||
if (!transforms[t].fCurrentValue.cheapEqualTo(combined)) {
|
||||
uniformManager.setSkMatrix(transforms[t].fHandle, combined);
|
||||
transforms[t].fCurrentValue = combined;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GrCrash("Unexpected uniform type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, int effectIdx) {
|
||||
const SkTArray<Sampler, true>& samplers = fSamplers[effectIdx];
|
||||
int numSamplers = samplers.count();
|
||||
|
@ -244,75 +259,67 @@ void GrGLProgramEffects::bindTextures(GrGpuGL* gpu, const GrEffectRef& effect, i
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder,
|
||||
int reserveCount)
|
||||
: fBuilder(builder)
|
||||
, fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
|
||||
(reserveCount, fBuilder->hasExplicitLocalCoords()))) {
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
|
||||
EffectKey key,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) {
|
||||
SkASSERT(NULL != fProgramEffects.get());
|
||||
|
||||
GrDrawEffect drawEffect(stage, fProgramEffects->fHasExplicitLocalCoords);
|
||||
void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
|
||||
const GrEffectStage& stage,
|
||||
EffectKey key,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) {
|
||||
GrDrawEffect drawEffect(stage, fHasExplicitLocalCoords);
|
||||
const GrEffectRef& effect = *stage.getEffect();
|
||||
SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
|
||||
SkSTArray<4, TextureSampler> samplers(effect->numTextures());
|
||||
|
||||
this->emitAttributes(stage);
|
||||
this->emitTransforms(effect, key, &coords);
|
||||
INHERITED::emitSamplers(fBuilder, fProgramEffects.get(), effect, &samplers);
|
||||
this->emitAttributes(builder, stage);
|
||||
this->emitTransforms(builder, effect, key, &coords);
|
||||
this->emitSamplers(builder, effect, &samplers);
|
||||
|
||||
GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
|
||||
fProgramEffects->fGLEffects.push_back(glEffect);
|
||||
fGLEffects.push_back(glEffect);
|
||||
|
||||
// Enclose custom code in a block to avoid namespace conflicts
|
||||
SkString openBrace;
|
||||
openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
|
||||
fBuilder->vsCodeAppend(openBrace.c_str());
|
||||
fBuilder->fsCodeAppend(openBrace.c_str());
|
||||
builder->vsCodeAppend(openBrace.c_str());
|
||||
builder->fsCodeAppend(openBrace.c_str());
|
||||
|
||||
if (glEffect->isVertexEffect()) {
|
||||
GrGLVertexEffect* vertexEffect = static_cast<GrGLVertexEffect*>(glEffect);
|
||||
vertexEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers);
|
||||
vertexEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
|
||||
} else {
|
||||
glEffect->emitCode(fBuilder, drawEffect, key, outColor, inColor, coords, samplers);
|
||||
glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
|
||||
}
|
||||
|
||||
fBuilder->vsCodeAppend("\t}\n");
|
||||
fBuilder->fsCodeAppend("\t}\n");
|
||||
builder->vsCodeAppend("\t}\n");
|
||||
builder->fsCodeAppend("\t}\n");
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffectsBuilder::emitAttributes(const GrEffectStage& stage) {
|
||||
void GrGLVertexProgramEffects::emitAttributes(GrGLFullShaderBuilder* builder,
|
||||
const GrEffectStage& stage) {
|
||||
int numAttributes = stage.getVertexAttribIndexCount();
|
||||
const int* attributeIndices = stage.getVertexAttribIndices();
|
||||
for (int a = 0; a < numAttributes; ++a) {
|
||||
// TODO: Make addAttribute mangle the name.
|
||||
SkString attributeName("aAttr");
|
||||
attributeName.appendS32(attributeIndices[a]);
|
||||
fBuilder->addEffectAttribute(attributeIndices[a],
|
||||
(*stage.getEffect())->vertexAttribType(a),
|
||||
attributeName);
|
||||
builder->addEffectAttribute(attributeIndices[a],
|
||||
(*stage.getEffect())->vertexAttribType(a),
|
||||
attributeName);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
|
||||
EffectKey effectKey,
|
||||
TransformedCoordsArray* outCoords) {
|
||||
typedef GrGLVertexProgramEffects::Transform Transform;
|
||||
SkTArray<Transform, true>& transforms = fProgramEffects->fTransforms.push_back();
|
||||
void GrGLVertexProgramEffects::emitTransforms(GrGLFullShaderBuilder* builder,
|
||||
const GrEffectRef& effect,
|
||||
EffectKey effectKey,
|
||||
TransformedCoordsArray* outCoords) {
|
||||
SkTArray<Transform, true>& transforms = fTransforms.push_back();
|
||||
EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
|
||||
int numTransforms = effect->numTransforms();
|
||||
transforms.push_back_n(numTransforms);
|
||||
for (int t = 0; t < numTransforms; t++) {
|
||||
EffectKey key = (totalKey >> (kTransformKeyBits * t)) & kTransformKeyMask;
|
||||
GrSLType varyingType = kVoid_GrSLType;
|
||||
const char* uniName;
|
||||
switch (key & kMatrixTypeKeyMask) {
|
||||
switch (get_matrix_type(totalKey, t)) {
|
||||
case kIdentity_MatrixType:
|
||||
transforms[t].fType = kVoid_GrSLType;
|
||||
uniName = NULL;
|
||||
|
@ -343,10 +350,10 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
|
|||
suffixedUniName.appendf("_%i", t);
|
||||
uniName = suffixedUniName.c_str();
|
||||
}
|
||||
transforms[t].fHandle = fBuilder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
|
||||
transforms[t].fType,
|
||||
uniName,
|
||||
&uniName);
|
||||
transforms[t].fHandle = builder->addUniform(GrGLShaderBuilder::kVertex_Visibility,
|
||||
transforms[t].fType,
|
||||
uniName,
|
||||
&uniName);
|
||||
}
|
||||
|
||||
const char* varyingName = "MatrixCoord";
|
||||
|
@ -358,55 +365,222 @@ void GrGLVertexProgramEffectsBuilder::emitTransforms(const GrEffectRef& effect,
|
|||
}
|
||||
const char* vsVaryingName;
|
||||
const char* fsVaryingName;
|
||||
fBuilder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
|
||||
builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
|
||||
|
||||
const GrGLShaderVar& coords = (kPositionCoords_Flag & key) ?
|
||||
fBuilder->positionAttribute() :
|
||||
fBuilder->localCoordsAttribute();
|
||||
const GrGLShaderVar& coords = kPosition_GrCoordSet == get_source_coords(totalKey, t) ?
|
||||
builder->positionAttribute() :
|
||||
builder->localCoordsAttribute();
|
||||
// varying = matrix * coords (logically)
|
||||
switch (transforms[t].fType) {
|
||||
case kVoid_GrSLType:
|
||||
SkASSERT(kVec2f_GrSLType == varyingType);
|
||||
fBuilder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str());
|
||||
builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords.c_str());
|
||||
break;
|
||||
case kVec2f_GrSLType:
|
||||
SkASSERT(kVec2f_GrSLType == varyingType);
|
||||
fBuilder->vsCodeAppendf("\t%s = %s + %s;\n",
|
||||
vsVaryingName, uniName, coords.c_str());
|
||||
builder->vsCodeAppendf("\t%s = %s + %s;\n",
|
||||
vsVaryingName, uniName, coords.c_str());
|
||||
break;
|
||||
case kMat33f_GrSLType: {
|
||||
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
|
||||
if (kVec2f_GrSLType == varyingType) {
|
||||
fBuilder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
|
||||
vsVaryingName, uniName, coords.c_str());
|
||||
builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
|
||||
vsVaryingName, uniName, coords.c_str());
|
||||
} else {
|
||||
fBuilder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
|
||||
vsVaryingName, uniName, coords.c_str());
|
||||
builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
|
||||
vsVaryingName, uniName, coords.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GrCrash("Unexpected uniform type.");
|
||||
}
|
||||
SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (fsVaryingName, varyingType));
|
||||
SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords,
|
||||
(SkString(fsVaryingName), varyingType));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgramEffectsBuilder::emitSamplers(GrGLShaderBuilder* builder,
|
||||
GrGLProgramEffects* programEffects,
|
||||
const GrEffectRef& effect,
|
||||
TextureSamplerArray* outSamplers) {
|
||||
typedef GrGLProgramEffects::Sampler Sampler;
|
||||
SkTArray<Sampler, true>& samplers = programEffects->fSamplers.push_back();
|
||||
int numTextures = effect->numTextures();
|
||||
samplers.push_back_n(numTextures);
|
||||
SkString name;
|
||||
for (int t = 0; t < numTextures; ++t) {
|
||||
name.printf("Sampler%d", t);
|
||||
samplers[t].fUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
||||
kSampler2D_GrSLType,
|
||||
name.c_str());
|
||||
SkNEW_APPEND_TO_TARRAY(outSamplers, TextureSampler,
|
||||
(samplers[t].fUniform, effect->textureAccess(t)));
|
||||
void GrGLVertexProgramEffects::setData(GrGpuGL* gpu,
|
||||
const GrGLUniformManager& uniformManager,
|
||||
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(uniformManager, drawEffect);
|
||||
this->setTransformData(uniformManager, drawEffect, e);
|
||||
this->bindTextures(gpu, *drawEffect.effect(), e);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffects::setTransformData(const GrGLUniformManager& uniformManager,
|
||||
const GrDrawEffect& drawEffect,
|
||||
int effectIdx) {
|
||||
SkTArray<Transform, true>& transforms = fTransforms[effectIdx];
|
||||
int numTransforms = transforms.count();
|
||||
SkASSERT(numTransforms == (*drawEffect.effect())->numTransforms());
|
||||
for (int t = 0; t < numTransforms; ++t) {
|
||||
SkASSERT(transforms[t].fHandle.isValid() != (kVoid_GrSLType == transforms[t].fType));
|
||||
switch (transforms[t].fType) {
|
||||
case kVoid_GrSLType:
|
||||
SkASSERT(get_transform_matrix(drawEffect, t).isIdentity());
|
||||
return;
|
||||
case kVec2f_GrSLType: {
|
||||
GrGLfloat tx, ty;
|
||||
get_transform_translation(drawEffect, t, &tx, &ty);
|
||||
if (transforms[t].fCurrentValue.get(SkMatrix::kMTransX) != tx ||
|
||||
transforms[t].fCurrentValue.get(SkMatrix::kMTransY) != ty) {
|
||||
uniformManager.set2f(transforms[t].fHandle, tx, ty);
|
||||
transforms[t].fCurrentValue.set(SkMatrix::kMTransX, tx);
|
||||
transforms[t].fCurrentValue.set(SkMatrix::kMTransY, ty);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMat33f_GrSLType: {
|
||||
const SkMatrix& matrix = get_transform_matrix(drawEffect, t);
|
||||
if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
|
||||
uniformManager.setSkMatrix(transforms[t].fHandle, matrix);
|
||||
transforms[t].fCurrentValue = matrix;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GrCrash("Unexpected uniform type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GrGLVertexProgramEffectsBuilder::GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder* builder,
|
||||
int reserveCount)
|
||||
: fBuilder(builder)
|
||||
, fProgramEffects(SkNEW_ARGS(GrGLVertexProgramEffects,
|
||||
(reserveCount, fBuilder->hasExplicitLocalCoords()))) {
|
||||
}
|
||||
|
||||
void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
|
||||
GrGLProgramEffects::EffectKey key,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) {
|
||||
SkASSERT(NULL != fProgramEffects.get());
|
||||
fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrGLTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder,
|
||||
const GrEffectStage& stage,
|
||||
EffectKey key,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) {
|
||||
GrDrawEffect drawEffect(stage, false);
|
||||
const GrEffectRef& effect = *stage.getEffect();
|
||||
SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
|
||||
SkSTArray<4, TextureSampler> samplers(effect->numTextures());
|
||||
|
||||
SkASSERT(0 == stage.getVertexAttribIndexCount());
|
||||
this->setupTexGen(builder, effect, key, &coords);
|
||||
this->emitSamplers(builder, effect, &samplers);
|
||||
|
||||
GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
|
||||
fGLEffects.push_back(glEffect);
|
||||
|
||||
// Enclose custom code in a block to avoid namespace conflicts
|
||||
SkString openBrace;
|
||||
openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
|
||||
builder->fsCodeAppend(openBrace.c_str());
|
||||
|
||||
SkASSERT(!glEffect->isVertexEffect());
|
||||
glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
|
||||
|
||||
builder->fsCodeAppend("\t}\n");
|
||||
}
|
||||
|
||||
void GrGLTexGenProgramEffects::setupTexGen(GrGLFragmentOnlyShaderBuilder* builder,
|
||||
const GrEffectRef& effect,
|
||||
EffectKey effectKey,
|
||||
TransformedCoordsArray* outCoords) {
|
||||
int numTransforms = effect->numTransforms();
|
||||
EffectKey totalKey = GrBackendEffectFactory::GetTransformKey(effectKey);
|
||||
int texCoordIndex = builder->addTexCoordSets(numTransforms);
|
||||
SkNEW_APPEND_TO_TARRAY(&fTransforms, Transforms, (totalKey, texCoordIndex));
|
||||
SkString name;
|
||||
for (int t = 0; t < numTransforms; ++t) {
|
||||
GrSLType type = kGeneral_MatrixType == get_matrix_type(totalKey, t) ?
|
||||
kVec3f_GrSLType :
|
||||
kVec2f_GrSLType;
|
||||
name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
|
||||
SkNEW_APPEND_TO_TARRAY(outCoords, TransformedCoords, (name, type));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLTexGenProgramEffects::setData(GrGpuGL* gpu,
|
||||
const GrGLUniformManager& uniformManager,
|
||||
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(uniformManager, drawEffect);
|
||||
this->setTexGenState(gpu, drawEffect, e);
|
||||
this->bindTextures(gpu, *drawEffect.effect(), e);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLTexGenProgramEffects::setTexGenState(GrGpuGL* gpu,
|
||||
const GrDrawEffect& drawEffect,
|
||||
int effectIdx) {
|
||||
EffectKey totalKey = fTransforms[effectIdx].fTransformKey;
|
||||
int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex;
|
||||
int numTransforms = (*drawEffect.effect())->numTransforms();
|
||||
for (int t = 0; t < numTransforms; ++t) {
|
||||
switch (get_matrix_type(totalKey, t)) {
|
||||
case kIdentity_MatrixType: {
|
||||
SkASSERT(get_transform_matrix(drawEffect, t).isIdentity());
|
||||
GrGLfloat identity[] = {1, 0, 0,
|
||||
0, 1, 0};
|
||||
gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, identity);
|
||||
break;
|
||||
}
|
||||
case kTrans_MatrixType: {
|
||||
GrGLfloat tx, ty;
|
||||
get_transform_translation(drawEffect, t, &tx, &ty);
|
||||
GrGLfloat translate[] = {1, 0, tx,
|
||||
0, 1, ty};
|
||||
gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, translate);
|
||||
break;
|
||||
}
|
||||
case kNoPersp_MatrixType: {
|
||||
const SkMatrix& transform = get_transform_matrix(drawEffect, t);
|
||||
gpu->enableTexGen(texCoordIndex++, GrGpuGL::kST_TexGenComponents, transform);
|
||||
break;
|
||||
}
|
||||
case kGeneral_MatrixType: {
|
||||
const SkMatrix& transform = get_transform_matrix(drawEffect, t);
|
||||
gpu->enableTexGen(texCoordIndex++, GrGpuGL::kSTR_TexGenComponents, transform);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GrCrash("Unexpected matrixs type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GrGLTexGenProgramEffectsBuilder::GrGLTexGenProgramEffectsBuilder(
|
||||
GrGLFragmentOnlyShaderBuilder* builder,
|
||||
int reserveCount)
|
||||
: fBuilder(builder)
|
||||
, fProgramEffects(SkNEW_ARGS(GrGLTexGenProgramEffects, (reserveCount))) {
|
||||
}
|
||||
|
||||
void GrGLTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
|
||||
GrGLProgramEffects::EffectKey key,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) {
|
||||
SkASSERT(NULL != fProgramEffects.get());
|
||||
fProgramEffects->emitEffect(fBuilder, stage, key, outColor, inColor, stageIndex);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#include "GrGLUniformManager.h"
|
||||
|
||||
class GrEffectStage;
|
||||
class GrGLProgramEffectsBuilder;
|
||||
class GrGLVertexProgramEffectsBuilder;
|
||||
class GrGLShaderBuilder;
|
||||
class GrGLFullShaderBuilder;
|
||||
class GrGLFragmentOnlyShaderBuilder;
|
||||
|
||||
/**
|
||||
* This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
*/
|
||||
class TransformedCoords {
|
||||
public:
|
||||
TransformedCoords(const char* name, GrSLType type)
|
||||
TransformedCoords(const SkString& name, GrSLType type)
|
||||
: fName(name), fType(type) {
|
||||
}
|
||||
|
||||
|
@ -97,13 +97,18 @@ public:
|
|||
typedef SkTArray<TextureSampler> TextureSamplerArray;
|
||||
|
||||
protected:
|
||||
friend class GrGLProgramEffectsBuilder;
|
||||
|
||||
GrGLProgramEffects(int reserveCount)
|
||||
: fGLEffects(reserveCount)
|
||||
, fSamplers(reserveCount) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and
|
||||
* appends the necessary data to the TextureSamplerArray* object so effects can add texture
|
||||
* lookups to their code. This method is only meant to be called during the construction phase.
|
||||
*/
|
||||
void emitSamplers(GrGLShaderBuilder*, const GrEffectRef&, TextureSamplerArray*);
|
||||
|
||||
/**
|
||||
* Helper for setData(). Binds all the textures for an effect.
|
||||
*/
|
||||
|
@ -119,6 +124,23 @@ protected:
|
|||
SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is an abstract base class for constructing different types of GrGLProgramEffects objects.
|
||||
*/
|
||||
class GrGLProgramEffectsBuilder {
|
||||
public:
|
||||
/**
|
||||
* Emits the effect's shader code, and stores the necessary uniforms internally.
|
||||
*/
|
||||
virtual void emitEffect(const GrEffectStage&,
|
||||
GrGLProgramEffects::EffectKey,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader.
|
||||
*/
|
||||
|
@ -137,6 +159,34 @@ private:
|
|||
, fHasExplicitLocalCoords(explicitLocalCoords) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
|
||||
* during the construction phase.
|
||||
*/
|
||||
void emitEffect(GrGLFullShaderBuilder*,
|
||||
const GrEffectStage&,
|
||||
GrGLProgramEffects::EffectKey,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex);
|
||||
|
||||
/**
|
||||
* Helper for emitEffect(). Emits any attributes an effect may have.
|
||||
*/
|
||||
void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&);
|
||||
|
||||
/**
|
||||
* Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
|
||||
* Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
|
||||
* vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
|
||||
* of the varyings in the VS and FS as well their types are appended to the
|
||||
* TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
|
||||
*/
|
||||
void emitTransforms(GrGLFullShaderBuilder*,
|
||||
const GrEffectRef&,
|
||||
EffectKey,
|
||||
TransformedCoordsArray*);
|
||||
|
||||
/**
|
||||
* Helper for setData(). Sets all the transform matrices for an effect.
|
||||
*/
|
||||
|
@ -155,35 +205,8 @@ private:
|
|||
typedef GrGLProgramEffects INHERITED;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This is an abstract base class for constructing different types of GrGLProgramEffects objects.
|
||||
*/
|
||||
class GrGLProgramEffectsBuilder {
|
||||
public:
|
||||
/**
|
||||
* Emits the effect's shader code, and stores the necessary uniforms internally.
|
||||
*/
|
||||
virtual void emitEffect(const GrEffectStage&,
|
||||
GrGLProgramEffects::EffectKey,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Helper for emitEffect(). Emits uniforms for an effect's texture accesses and appends the
|
||||
* necessary data to the TextureSamplerArray* object so effects can add texture lookups.
|
||||
*/
|
||||
static void emitSamplers(GrGLShaderBuilder*,
|
||||
GrGLProgramEffects*,
|
||||
const GrEffectRef&,
|
||||
GrGLProgramEffects::TextureSamplerArray*);
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used to construct a GrGLVertexProgramEffects object.
|
||||
* This class is used to construct a GrGLVertexProgramEffects* object.
|
||||
*/
|
||||
class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
|
||||
public:
|
||||
|
@ -202,26 +225,97 @@ public:
|
|||
GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Helper for emitEffect(). Emits any attributes an effect might have.
|
||||
*/
|
||||
void emitAttributes(const GrEffectStage&);
|
||||
|
||||
/**
|
||||
* Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
|
||||
* Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
|
||||
* vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
|
||||
* of the varyings in the VS and FS as well their types are appended to the
|
||||
* TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
|
||||
*/
|
||||
void emitTransforms(const GrEffectRef&,
|
||||
GrGLProgramEffects::EffectKey,
|
||||
GrGLProgramEffects::TransformedCoordsArray*);
|
||||
|
||||
GrGLFullShaderBuilder* fBuilder;
|
||||
SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
|
||||
|
||||
typedef GrGLProgramEffectsBuilder INHERITED;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This is a GrGLProgramEffects implementation that does coord transforms with the the built-in GL
|
||||
* TexGen functionality.
|
||||
*/
|
||||
class GrGLTexGenProgramEffects : public GrGLProgramEffects {
|
||||
public:
|
||||
virtual void setData(GrGpuGL*,
|
||||
const GrGLUniformManager&,
|
||||
const GrEffectStage* effectStages[]) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
friend class GrGLTexGenProgramEffectsBuilder;
|
||||
|
||||
GrGLTexGenProgramEffects(int reserveCount)
|
||||
: INHERITED(reserveCount)
|
||||
, fTransforms(reserveCount) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
|
||||
* during the construction phase.
|
||||
*/
|
||||
void emitEffect(GrGLFragmentOnlyShaderBuilder*,
|
||||
const GrEffectStage&,
|
||||
GrGLProgramEffects::EffectKey,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex);
|
||||
|
||||
/**
|
||||
* Helper for emitEffect(). Allocates texture units from the builder for each transform in an
|
||||
* effect. The transforms all use adjacent texture units. They either use two or three of the
|
||||
* coordinates at a given texture unit, depending on if they need perspective interpolation.
|
||||
* The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
|
||||
* types are appended to the TransformedCoordsArray* object, which is in turn passed to the
|
||||
* effect's emitCode() function.
|
||||
*/
|
||||
void setupTexGen(GrGLFragmentOnlyShaderBuilder*,
|
||||
const GrEffectRef&,
|
||||
EffectKey,
|
||||
TransformedCoordsArray*);
|
||||
|
||||
/**
|
||||
* Helper for setData(). Sets the TexGen state for each transform in an effect.
|
||||
*/
|
||||
void setTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
|
||||
|
||||
struct Transforms {
|
||||
Transforms(EffectKey transformKey, int texCoordIndex)
|
||||
: fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
|
||||
EffectKey fTransformKey;
|
||||
int fTexCoordIndex;
|
||||
};
|
||||
|
||||
SkTArray<Transforms> fTransforms;
|
||||
|
||||
typedef GrGLProgramEffects INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used to construct a GrGLTexGenProgramEffects* object.
|
||||
*/
|
||||
class GrGLTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
|
||||
public:
|
||||
GrGLTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount);
|
||||
|
||||
virtual void emitEffect(const GrEffectStage&,
|
||||
GrGLProgramEffects::EffectKey,
|
||||
const char* outColor,
|
||||
const char* inColor,
|
||||
int stageIndex) SK_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Finalizes the building process and returns the effect array. After this call, the builder
|
||||
* becomes invalid.
|
||||
*/
|
||||
GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
|
||||
|
||||
private:
|
||||
GrGLFragmentOnlyShaderBuilder* fBuilder;
|
||||
SkAutoTDelete<GrGLTexGenProgramEffects> fProgramEffects;
|
||||
|
||||
typedef GrGLProgramEffectsBuilder INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -441,7 +441,6 @@ const char* GrGLShaderBuilder::fragmentPosition() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType,
|
||||
const char* name,
|
||||
int argCnt,
|
||||
|
@ -920,3 +919,35 @@ void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const {
|
|||
GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu,
|
||||
GrGLUniformManager& uniformManager,
|
||||
const GrGLProgramDesc& desc)
|
||||
: INHERITED(gpu, uniformManager, desc)
|
||||
, fNumTexCoordSets(0) {
|
||||
|
||||
SkASSERT(!desc.getHeader().fHasVertexCode);
|
||||
SkASSERT(gpu->glCaps().fixedFunctionSupport());
|
||||
SkASSERT(gpu->glCaps().pathStencilingSupport());
|
||||
SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
|
||||
SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
|
||||
}
|
||||
|
||||
GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects(
|
||||
const GrEffectStage* effectStages[],
|
||||
const EffectKey effectKeys[],
|
||||
int effectCnt,
|
||||
SkString* inOutFSColor,
|
||||
GrSLConstantVec* fsInOutColorKnownValue) {
|
||||
|
||||
GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt);
|
||||
this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder,
|
||||
effectStages,
|
||||
effectKeys,
|
||||
effectCnt,
|
||||
inOutFSColor,
|
||||
fsInOutColorKnownValue);
|
||||
return texGenEffectsBuilder.finish();
|
||||
}
|
||||
|
|
|
@ -450,4 +450,26 @@ private:
|
|||
typedef GrGLShaderBuilder INHERITED;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder {
|
||||
public:
|
||||
GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
|
||||
|
||||
int getNumTexCoordSets() const { return fNumTexCoordSets; }
|
||||
int addTexCoordSets(int count) { return (fNumTexCoordSets += count) - count; }
|
||||
|
||||
virtual GrGLProgramEffects* createAndEmitEffects(
|
||||
const GrEffectStage* effectStages[],
|
||||
const EffectKey effectKeys[],
|
||||
int effectCnt,
|
||||
SkString* inOutFSColor,
|
||||
GrSLConstantVec* fsInOutColorKnownValue) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
int fNumTexCoordSets;
|
||||
|
||||
typedef GrGLShaderBuilder INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -124,6 +124,7 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
|
|||
fCaps.reset(SkRef(ctx.info().caps()));
|
||||
|
||||
fHWBoundTextures.reset(ctx.info().caps()->maxFragmentTextureUnits());
|
||||
fHWTexGenSettings.reset(ctx.info().caps()->maxFixedFunctionTextureCoords());
|
||||
|
||||
fillInConfigRenderableTable();
|
||||
|
||||
|
@ -377,7 +378,13 @@ void GrGpuGL::onResetContext(uint32_t resetBits) {
|
|||
GL_CALL(Disable(GR_GL_TEXTURE_GEN_T));
|
||||
GL_CALL(Disable(GR_GL_TEXTURE_GEN_Q));
|
||||
GL_CALL(Disable(GR_GL_TEXTURE_GEN_R));
|
||||
if (this->caps()->pathStencilingSupport()) {
|
||||
GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
|
||||
}
|
||||
fHWTexGenSettings[i].fMode = GR_GL_NONE;
|
||||
fHWTexGenSettings[i].fNumComponents = 0;
|
||||
}
|
||||
fHWActiveTexGenSets = 0;
|
||||
}
|
||||
|
||||
// we assume these values
|
||||
|
@ -2114,6 +2121,124 @@ void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
|
|||
texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
|
||||
}
|
||||
|
||||
void GrGpuGL::setProjectionMatrix(const SkMatrix& matrix,
|
||||
const SkISize& renderTargetSize,
|
||||
GrSurfaceOrigin renderTargetOrigin) {
|
||||
|
||||
SkASSERT(this->glCaps().fixedFunctionSupport());
|
||||
|
||||
if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
|
||||
renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
|
||||
matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fHWProjectionMatrixState.fViewMatrix = matrix;
|
||||
fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
|
||||
fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;
|
||||
|
||||
GrGLfloat glMatrix[4 * 4];
|
||||
fHWProjectionMatrixState.getGLMatrix<4>(glMatrix);
|
||||
GL_CALL(MatrixMode(GR_GL_PROJECTION));
|
||||
GL_CALL(LoadMatrixf(glMatrix));
|
||||
}
|
||||
|
||||
void GrGpuGL::enableTexGen(int unitIdx,
|
||||
TexGenComponents components,
|
||||
const GrGLfloat* coefficients) {
|
||||
|
||||
SkASSERT(this->glCaps().fixedFunctionSupport());
|
||||
SkASSERT(this->caps()->pathStencilingSupport());
|
||||
SkASSERT(components >= kS_TexGenComponents && components <= kSTR_TexGenComponents);
|
||||
|
||||
if (GR_GL_OBJECT_LINEAR == fHWTexGenSettings[unitIdx].fMode &&
|
||||
components == fHWTexGenSettings[unitIdx].fNumComponents &&
|
||||
!memcmp(coefficients, fHWTexGenSettings[unitIdx].fCoefficients,
|
||||
3 * components * sizeof(GrGLfloat))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->setTextureUnit(unitIdx);
|
||||
|
||||
if (GR_GL_OBJECT_LINEAR != fHWTexGenSettings[unitIdx].fMode) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
GL_CALL(TexGeni(GR_GL_S + i, GR_GL_TEXTURE_GEN_MODE, GR_GL_OBJECT_LINEAR));
|
||||
}
|
||||
fHWTexGenSettings[unitIdx].fMode = GR_GL_OBJECT_LINEAR;
|
||||
}
|
||||
|
||||
for (int i = fHWTexGenSettings[unitIdx].fNumComponents; i < components; i++) {
|
||||
GL_CALL(Enable(GR_GL_TEXTURE_GEN_S + i));
|
||||
}
|
||||
for (int i = components; i < fHWTexGenSettings[unitIdx].fNumComponents; i++) {
|
||||
GL_CALL(Disable(GR_GL_TEXTURE_GEN_S + i));
|
||||
}
|
||||
fHWTexGenSettings[unitIdx].fNumComponents = components;
|
||||
|
||||
for (int i = 0; i < components; i++) {
|
||||
GrGLfloat plane[] = {coefficients[0 + 3 * i],
|
||||
coefficients[1 + 3 * i],
|
||||
0,
|
||||
coefficients[2 + 3 * i]};
|
||||
GL_CALL(TexGenfv(GR_GL_S + i, GR_GL_OBJECT_PLANE, plane));
|
||||
}
|
||||
|
||||
GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx,
|
||||
GR_GL_OBJECT_LINEAR,
|
||||
components,
|
||||
coefficients));
|
||||
|
||||
memcpy(fHWTexGenSettings[unitIdx].fCoefficients, coefficients,
|
||||
3 * components * sizeof(GrGLfloat));
|
||||
|
||||
fHWActiveTexGenSets = SkTMax(fHWActiveTexGenSets, unitIdx);
|
||||
}
|
||||
|
||||
void GrGpuGL::enableTexGen(int unitIdx, TexGenComponents components, const SkMatrix& matrix) {
|
||||
|
||||
GrGLfloat coefficients[3 * 3];
|
||||
SkASSERT(this->glCaps().fixedFunctionSupport());
|
||||
SkASSERT(components >= kS_TexGenComponents && components <= kSTR_TexGenComponents);
|
||||
|
||||
coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
|
||||
coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
|
||||
coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
|
||||
|
||||
if (components >= kST_TexGenComponents) {
|
||||
coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
|
||||
coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
|
||||
coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
|
||||
}
|
||||
|
||||
if (components >= kSTR_TexGenComponents) {
|
||||
coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
|
||||
coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
|
||||
coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
|
||||
}
|
||||
|
||||
enableTexGen(unitIdx, components, coefficients);
|
||||
}
|
||||
|
||||
void GrGpuGL::disableUnusedTexGen(int numUsedTexCoordSets) {
|
||||
|
||||
SkASSERT(this->glCaps().fixedFunctionSupport());
|
||||
|
||||
for (int i = numUsedTexCoordSets; i < fHWActiveTexGenSets; i++) {
|
||||
if (0 == fHWTexGenSettings[i].fNumComponents) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this->setTextureUnit(i);
|
||||
for (int j = 0; j < fHWTexGenSettings[i].fNumComponents; j++) {
|
||||
GL_CALL(Disable(GR_GL_TEXTURE_GEN_S + j));
|
||||
}
|
||||
GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
|
||||
fHWTexGenSettings[i].fNumComponents = 0;
|
||||
}
|
||||
|
||||
fHWActiveTexGenSets = SkTMin(fHWActiveTexGenSets, numUsedTexCoordSets);
|
||||
}
|
||||
|
||||
void GrGpuGL::flushMiscFixedFunctionState() {
|
||||
|
||||
const GrDrawState& drawState = this->getDrawState();
|
||||
|
|
|
@ -37,8 +37,19 @@ public:
|
|||
GrGLVersion glVersion() const { return fGLContext.info().version(); }
|
||||
GrGLSLGeneration glslGeneration() const { return fGLContext.info().glslGeneration(); }
|
||||
|
||||
// Used by GrGLProgram to bind necessary textures for GrGLEffects.
|
||||
// Used by GrGLProgram and GrGLTexGenProgramEffects to configure OpenGL state.
|
||||
void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
|
||||
void setProjectionMatrix(const SkMatrix& matrix,
|
||||
const SkISize& renderTargetSize,
|
||||
GrSurfaceOrigin renderTargetOrigin);
|
||||
enum TexGenComponents {
|
||||
kS_TexGenComponents = 1,
|
||||
kST_TexGenComponents = 2,
|
||||
kSTR_TexGenComponents = 3
|
||||
};
|
||||
void enableTexGen(int unitIdx, TexGenComponents, const GrGLfloat* coefficients);
|
||||
void enableTexGen(int unitIdx, TexGenComponents, const SkMatrix& matrix);
|
||||
void disableUnusedTexGen(int numUsedTexCoordSets);
|
||||
|
||||
bool programUnitTest(int maxStages);
|
||||
|
||||
|
@ -213,9 +224,6 @@ private:
|
|||
#endif
|
||||
};
|
||||
|
||||
// sets the matrix for path stenciling (uses the GL fixed pipe matrices)
|
||||
void flushPathStencilMatrix();
|
||||
|
||||
// flushes dithering, color-mask, and face culling stat
|
||||
void flushMiscFixedFunctionState();
|
||||
|
||||
|
@ -432,6 +440,14 @@ private:
|
|||
TriState fHWDitherEnabled;
|
||||
GrRenderTarget* fHWBoundRenderTarget;
|
||||
SkTArray<GrTexture*, true> fHWBoundTextures;
|
||||
|
||||
struct TexGenData {
|
||||
GrGLenum fMode;
|
||||
GrGLint fNumComponents;
|
||||
GrGLfloat fCoefficients[3 * 3];
|
||||
};
|
||||
int fHWActiveTexGenSets;
|
||||
SkTArray<TexGenData, true> fHWTexGenSettings;
|
||||
///@}
|
||||
|
||||
// we record what stencil format worked last time to hopefully exit early
|
||||
|
|
|
@ -210,28 +210,6 @@ void GrGpuGL::abandonResources(){
|
|||
|
||||
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
|
||||
|
||||
void GrGpuGL::flushPathStencilMatrix() {
|
||||
const SkMatrix& viewMatrix = this->getDrawState().getViewMatrix();
|
||||
const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
|
||||
SkISize size;
|
||||
size.set(rt->width(), rt->height());
|
||||
const SkMatrix& vm = this->getDrawState().getViewMatrix();
|
||||
|
||||
if (fHWProjectionMatrixState.fRenderTargetOrigin != rt->origin() ||
|
||||
!fHWProjectionMatrixState.fViewMatrix.cheapEqualTo(viewMatrix) ||
|
||||
fHWProjectionMatrixState.fRenderTargetSize!= size) {
|
||||
|
||||
fHWProjectionMatrixState.fViewMatrix = vm;
|
||||
fHWProjectionMatrixState.fRenderTargetSize = size;
|
||||
fHWProjectionMatrixState.fRenderTargetOrigin = rt->origin();
|
||||
|
||||
GrGLfloat projectionMatrix[4 * 4];
|
||||
fHWProjectionMatrixState.getGLMatrix<4>(projectionMatrix);
|
||||
GL_CALL(MatrixMode(GR_GL_PROJECTION));
|
||||
GL_CALL(LoadMatrixf(projectionMatrix));
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
|
||||
const GrDrawState& drawState = this->getDrawState();
|
||||
|
||||
|
@ -239,7 +217,10 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
|
|||
SkASSERT(NULL != drawState.getRenderTarget());
|
||||
|
||||
if (kStencilPath_DrawType == type) {
|
||||
this->flushPathStencilMatrix();
|
||||
const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
|
||||
SkISize size;
|
||||
size.set(rt->width(), rt->height());
|
||||
this->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
|
||||
} else {
|
||||
this->flushMiscFixedFunctionState();
|
||||
|
||||
|
@ -360,24 +341,40 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
|
|||
GrGLAttribArrayState* attribState =
|
||||
fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
|
||||
|
||||
uint32_t usedAttribArraysMask = 0;
|
||||
const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
|
||||
int vertexAttribCount = this->getDrawState().getVertexAttribCount();
|
||||
for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
|
||||
++vertexAttribIndex, ++vertexAttrib) {
|
||||
if (!fCurrentProgram->hasVertexShader()) {
|
||||
int posIdx = this->getDrawState().positionAttributeIndex();
|
||||
const GrVertexAttrib* vertexArray = this->getDrawState().getVertexAttribs() + posIdx;
|
||||
GrVertexAttribType vertexArrayType = vertexArray->fType;
|
||||
SkASSERT(!GrGLAttribTypeToLayout(vertexArrayType).fNormalized);
|
||||
SkASSERT(GrGLAttribTypeToLayout(vertexArrayType).fCount == 2);
|
||||
attribState->setFixedFunctionVertexArray(this,
|
||||
vbuf,
|
||||
2,
|
||||
GrGLAttribTypeToLayout(vertexArrayType).fType,
|
||||
stride,
|
||||
reinterpret_cast<GrGLvoid*>(
|
||||
vertexOffsetInBytes + vertexArray->fOffset));
|
||||
attribState->disableUnusedArrays(this, 0, true);
|
||||
} else {
|
||||
uint32_t usedAttribArraysMask = 0;
|
||||
const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
|
||||
int vertexAttribCount = this->getDrawState().getVertexAttribCount();
|
||||
for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
|
||||
++vertexAttribIndex, ++vertexAttrib) {
|
||||
|
||||
usedAttribArraysMask |= (1 << vertexAttribIndex);
|
||||
GrVertexAttribType attribType = vertexAttrib->fType;
|
||||
attribState->set(this,
|
||||
vertexAttribIndex,
|
||||
vbuf,
|
||||
GrGLAttribTypeToLayout(attribType).fCount,
|
||||
GrGLAttribTypeToLayout(attribType).fType,
|
||||
GrGLAttribTypeToLayout(attribType).fNormalized,
|
||||
stride,
|
||||
reinterpret_cast<GrGLvoid*>(
|
||||
vertexOffsetInBytes + vertexAttrib->fOffset));
|
||||
usedAttribArraysMask |= (1 << vertexAttribIndex);
|
||||
GrVertexAttribType attribType = vertexAttrib->fType;
|
||||
attribState->set(this,
|
||||
vertexAttribIndex,
|
||||
vbuf,
|
||||
GrGLAttribTypeToLayout(attribType).fCount,
|
||||
GrGLAttribTypeToLayout(attribType).fType,
|
||||
GrGLAttribTypeToLayout(attribType).fNormalized,
|
||||
stride,
|
||||
reinterpret_cast<GrGLvoid*>(
|
||||
vertexOffsetInBytes + vertexAttrib->fOffset));
|
||||
}
|
||||
|
||||
attribState->disableUnusedArrays(this, usedAttribArraysMask, false);
|
||||
}
|
||||
|
||||
attribState->disableUnusedArrays(this, usedAttribArraysMask, false);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ void GrGLProgramDesc::setRandom(SkRandom* random,
|
|||
|
||||
bool dstRead = false;
|
||||
bool fragPos = false;
|
||||
bool vertexCode = false;
|
||||
int numStages = numColorStages + numCoverageStages;
|
||||
for (int s = 0; s < numStages; ++s) {
|
||||
const GrBackendEffectFactory& factory = (*stages[s]->getEffect())->getFactory();
|
||||
|
@ -89,6 +90,9 @@ void GrGLProgramDesc::setRandom(SkRandom* random,
|
|||
if ((*stages[s]->getEffect())->willReadFragmentPosition()) {
|
||||
fragPos = true;
|
||||
}
|
||||
if ((*stages[s]->getEffect())->hasVertexCode()) {
|
||||
vertexCode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dstRead) {
|
||||
|
@ -103,6 +107,11 @@ void GrGLProgramDesc::setRandom(SkRandom* random,
|
|||
header->fFragPosKey = 0;
|
||||
}
|
||||
|
||||
header->fHasVertexCode = vertexCode ||
|
||||
useLocalCoords ||
|
||||
kAttribute_ColorInput == header->fColorInput ||
|
||||
kAttribute_ColorInput == header->fCoverageInput;
|
||||
|
||||
CoverageOutput coverageOutput;
|
||||
bool illegalCoverageOutput;
|
||||
do {
|
||||
|
|
Загрузка…
Ссылка в новой задаче