Move GrGLProgram::Desc out of GrGLProgram.

Review URL: https://codereview.chromium.org/12942014

git-svn-id: http://skia.googlecode.com/svn/trunk@8411 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2013-03-27 18:14:57 +00:00
Родитель 04b959abfc
Коммит 31ec7985f2
10 изменённых файлов: 231 добавлений и 201 удалений

Просмотреть файл

@ -168,6 +168,7 @@
'<(skia_src_path)/gpu/gl/GrGLPath.h',
'<(skia_src_path)/gpu/gl/GrGLProgram.cpp',
'<(skia_src_path)/gpu/gl/GrGLProgram.h',
'<(skia_src_path)/gpu/gl/GrGLProgramDesc.h',
'<(skia_src_path)/gpu/gl/GrGLRenderTarget.cpp',
'<(skia_src_path)/gpu/gl/GrGLRenderTarget.h',
'<(skia_src_path)/gpu/gl/GrGLShaderBuilder.cpp',

Просмотреть файл

@ -8,6 +8,8 @@
#ifndef GrTypesPriv_DEFINED
#define GrTypesPriv_DEFINED
#include "SkTArray.h"
/**
* Types of shader-language-specific boxed variables we can create.
* (Currently only GrGLShaderVars, but should be applicable to other shader
@ -24,4 +26,34 @@ enum GrSLType {
kSampler2D_GrSLType
};
/**
* Types used to describe format of vertices in arrays
*/
enum GrVertexAttribType {
kFloat_GrVertexAttribType = 0,
kVec2f_GrVertexAttribType,
kVec3f_GrVertexAttribType,
kVec4f_GrVertexAttribType,
kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
};
static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
struct GrVertexAttrib {
inline void set(GrVertexAttribType type, size_t offset) {
fType = type; fOffset = offset;
}
bool operator==(const GrVertexAttrib& other) const {
return fType == other.fType && fOffset == other.fOffset;
};
bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
GrVertexAttribType fType;
size_t fOffset;
};
template <int N>
class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
#endif

Просмотреть файл

@ -16,6 +16,7 @@
#include "GrStencil.h"
#include "GrTemplates.h"
#include "GrTexture.h"
#include "GrTypesPriv.h"
#include "effects/GrSimpleTextureEffect.h"
#include "SkMatrix.h"
@ -23,36 +24,6 @@
class GrPaint;
/**
* Types used to describe format of vertices in arrays
*/
enum GrVertexAttribType {
kFloat_GrVertexAttribType = 0,
kVec2f_GrVertexAttribType,
kVec3f_GrVertexAttribType,
kVec4f_GrVertexAttribType,
kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
};
static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
struct GrVertexAttrib {
inline void set(GrVertexAttribType type, size_t offset) {
fType = type; fOffset = offset;
}
bool operator==(const GrVertexAttrib& other) const {
return fType == other.fType && fOffset == other.fOffset;
};
bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
GrVertexAttribType fType;
size_t fOffset;
};
template <int N>
class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
/**
* Type used to describe how attributes bind to program usage
*/

Просмотреть файл

@ -36,21 +36,13 @@ inline const char* declared_color_output_name() { return "fsColorOut"; }
inline const char* dual_source_output_name() { return "dualSourceOut"; }
}
const GrGLProgram::AttribLayout GrGLProgram::kAttribLayouts[kGrVertexAttribTypeCount] = {
{1, GR_GL_FLOAT, false}, // kFloat_GrVertexAttribType
{2, GR_GL_FLOAT, false}, // kVec2f_GrVertexAttribType
{3, GR_GL_FLOAT, false}, // kVec3f_GrVertexAttribType
{4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType
{4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType
};
void GrGLProgram::BuildDesc(const GrDrawState& drawState,
void GrGLProgramDesc::Build(const GrDrawState& drawState,
bool isPoints,
GrDrawState::BlendOptFlags blendOpts,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff,
const GrGpuGL* gpu,
Desc* desc) {
GrGLProgramDesc* desc) {
// This should already have been caught
GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
@ -94,25 +86,25 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
(!requiresAttributeColors && 0xffffffff == drawState.getColor());
if (colorIsTransBlack) {
desc->fColorInput = Desc::kTransBlack_ColorInput;
desc->fColorInput = kTransBlack_ColorInput;
} else if (colorIsSolidWhite) {
desc->fColorInput = Desc::kSolidWhite_ColorInput;
desc->fColorInput = kSolidWhite_ColorInput;
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) {
desc->fColorInput = Desc::kUniform_ColorInput;
desc->fColorInput = kUniform_ColorInput;
} else {
desc->fColorInput = Desc::kAttribute_ColorInput;
desc->fColorInput = kAttribute_ColorInput;
}
bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState.getCoverage();
if (skipCoverage) {
desc->fCoverageInput = Desc::kTransBlack_ColorInput;
desc->fCoverageInput = kTransBlack_ColorInput;
} else if (covIsSolidWhite) {
desc->fCoverageInput = Desc::kSolidWhite_ColorInput;
desc->fCoverageInput = kSolidWhite_ColorInput;
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) {
desc->fCoverageInput = Desc::kUniform_ColorInput;
desc->fCoverageInput = kUniform_ColorInput;
} else {
desc->fCoverageInput = Desc::kAttribute_ColorInput;
desc->fCoverageInput = kAttribute_ColorInput;
}
int lastEnabledStage = -1;
@ -133,7 +125,7 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
}
}
desc->fDualSrcOutput = Desc::kNone_DualSrcOutput;
desc->fDualSrcOutput = kNone_DualSrcOutput;
// Currently the experimental GS will only work with triangle prims (and it doesn't do anything
// other than pass through values from the VS to the FS anyway).
@ -181,15 +173,15 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
if (kZero_GrBlendCoeff == dstCoeff) {
// write the coverage value to second color
desc->fDualSrcOutput = Desc::kCoverage_DualSrcOutput;
desc->fDualSrcOutput = kCoverage_DualSrcOutput;
desc->fFirstCoverageStage = firstCoverageStage;
} else if (kSA_GrBlendCoeff == dstCoeff) {
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
desc->fDualSrcOutput = Desc::kCoverageISA_DualSrcOutput;
desc->fDualSrcOutput = kCoverageISA_DualSrcOutput;
desc->fFirstCoverageStage = firstCoverageStage;
} else if (kSC_GrBlendCoeff == dstCoeff) {
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
desc->fDualSrcOutput = Desc::kCoverageISC_DualSrcOutput;
desc->fDualSrcOutput = kCoverageISC_DualSrcOutput;
desc->fFirstCoverageStage = firstCoverageStage;
}
}
@ -211,27 +203,28 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
}
#if GR_DEBUG
// verify valid vertex attribute state
// Verify valid vertex attribute state. These assertions should probably be done somewhere
// higher up the callstack
const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs();
GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt);
GrAssert(kAttribLayouts[vertexAttribs[desc->fPositionAttributeIndex].fType].fCount == 2);
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fPositionAttributeIndex].fType).fCount == 2);
if (requiresAttributeColors) {
GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt);
GrAssert(kAttribLayouts[vertexAttribs[desc->fColorAttributeIndex].fType].fCount == 4);
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fColorAttributeIndex].fType).fCount == 4);
}
if (requiresAttributeCoverage) {
GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt);
GrAssert(kAttribLayouts[vertexAttribs[desc->fCoverageAttributeIndex].fType].fCount == 4);
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fCoverageAttributeIndex].fType).fCount == 4);
}
if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2);
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fLocalCoordsAttributeIndex].fType).fCount == 2);
}
#endif
}
GrGLProgram* GrGLProgram::Create(const GrGLContext& gl,
const Desc& desc,
const GrGLProgramDesc& desc,
const GrEffectStage* stages[]) {
GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages));
if (!program->succeeded()) {
@ -242,7 +235,7 @@ GrGLProgram* GrGLProgram::Create(const GrGLContext& gl,
}
GrGLProgram::GrGLProgram(const GrGLContext& gl,
const Desc& desc,
const GrGLProgramDesc& desc,
const GrEffectStage* stages[])
: fContext(gl)
, fUniformManager(gl) {
@ -291,13 +284,13 @@ void GrGLProgram::abandon() {
void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
GrBlendCoeff* dstCoeff) const {
switch (fDesc.fDualSrcOutput) {
case Desc::kNone_DualSrcOutput:
case GrGLProgramDesc::kNone_DualSrcOutput:
break;
// the prog will write a coverage value to the secondary
// output and the dst is blended by one minus that value.
case Desc::kCoverage_DualSrcOutput:
case Desc::kCoverageISA_DualSrcOutput:
case Desc::kCoverageISC_DualSrcOutput:
case GrGLProgramDesc::kCoverage_DualSrcOutput:
case GrGLProgramDesc::kCoverageISA_DualSrcOutput:
case GrGLProgramDesc::kCoverageISC_DualSrcOutput:
*dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
break;
default:
@ -413,24 +406,24 @@ void add_color_filter(GrGLShaderBuilder* builder,
void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
switch (fDesc.fColorInput) {
case GrGLProgram::Desc::kAttribute_ColorInput: {
case GrGLProgramDesc::kAttribute_ColorInput: {
builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME);
const char *vsName, *fsName;
builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
*inColor = fsName;
} break;
case GrGLProgram::Desc::kUniform_ColorInput: {
case GrGLProgramDesc::kUniform_ColorInput: {
const char* name;
fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType, "Color", &name);
*inColor = name;
break;
}
case GrGLProgram::Desc::kTransBlack_ColorInput:
case GrGLProgramDesc::kTransBlack_ColorInput:
GrAssert(!"needComputedColor should be false.");
break;
case GrGLProgram::Desc::kSolidWhite_ColorInput:
case GrGLProgramDesc::kSolidWhite_ColorInput:
break;
default:
GrCrash("Unknown color type.");
@ -497,7 +490,7 @@ const char* GrGLProgram::adjustInColor(const SkString& inColor) const {
if (inColor.size()) {
return inColor.c_str();
} else {
if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) {
if (GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput) {
return GrGLSLOnesVecf(4);
} else {
return GrGLSLZerosVecf(4);
@ -636,7 +629,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// no need to do the color filter if coverage is 0. The output color is scaled by the coverage.
// All the dual source outputs are scaled by the coverage as well.
if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
colorCoeff = SkXfermode::kZero_Coeff;
uniformCoeff = SkXfermode::kZero_Coeff;
}
@ -644,7 +637,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// If we know the final color is going to be all zeros then we can
// simplify the color filter coefficients. needComputedColor will then
// come out false below.
if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) {
if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fColorInput) {
colorCoeff = SkXfermode::kZero_Coeff;
if (SkXfermode::kDC_Coeff == uniformCoeff ||
SkXfermode::kDA_Coeff == uniformCoeff) {
@ -724,7 +717,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// if have all ones or zeros for the "dst" input to the color filter then we
// may be able to make additional optimizations.
if (needColorFilterUniform && needComputedColor && !inColor.size()) {
GrAssert(Desc::kSolidWhite_ColorInput == fDesc.fColorInput);
GrAssert(GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput);
bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff ||
SkXfermode::kIDA_Coeff == uniformCoeff;
if (uniformCoeffIsZero) {
@ -758,20 +751,20 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// compute the partial coverage (coverage stages and edge aa)
SkString inCoverage;
bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput;
bool coverageIsZero = GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput;
// we don't need to compute coverage at all if we know the final shader
// output will be zero and we don't have a dual src blend output.
if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
if (!wroteFragColorZero || GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
if (!coverageIsZero) {
switch (fDesc.fCoverageInput) {
case Desc::kSolidWhite_ColorInput:
case GrGLProgramDesc::kSolidWhite_ColorInput:
// empty string implies solid white
break;
case Desc::kAttribute_ColorInput:
case GrGLProgramDesc::kAttribute_ColorInput:
gen_attribute_coverage(&builder, &inCoverage);
break;
case Desc::kUniform_ColorInput:
case GrGLProgramDesc::kUniform_ColorInput:
this->genUniformCoverage(&builder, &inCoverage);
break;
default:
@ -807,18 +800,18 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
}
}
if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
builder.fFSOutputs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kOut_TypeModifier,
dual_source_output_name());
bool outputIsZero = coverageIsZero;
SkString coeff;
if (!outputIsZero &&
Desc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
GrGLProgramDesc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
if (!inColor.size()) {
outputIsZero = true;
} else {
if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
coeff.printf("(1 - %s.a)", inColor.c_str());
} else {
coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str());
@ -1009,7 +1002,7 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
SharedGLState* sharedState) {
if (!(drawState.getAttribBindings() & GrDrawState::kColor_AttribBindingsBit)) {
switch (fDesc.fColorInput) {
case GrGLProgram::Desc::kAttribute_ColorInput:
case GrGLProgramDesc::kAttribute_ColorInput:
if (sharedState->fConstAttribColor != color) {
// OpenGL ES only supports the float varieties of glVertexAttrib
GrGLfloat c[4];
@ -1018,7 +1011,7 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
sharedState->fConstAttribColor = color;
}
break;
case GrGLProgram::Desc::kUniform_ColorInput:
case GrGLProgramDesc::kUniform_ColorInput:
if (fColor != color) {
// OpenGL ES doesn't support unsigned byte varieties of glUniform
GrGLfloat c[4];
@ -1029,8 +1022,8 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
fColor = color;
}
break;
case GrGLProgram::Desc::kSolidWhite_ColorInput:
case GrGLProgram::Desc::kTransBlack_ColorInput:
case GrGLProgramDesc::kSolidWhite_ColorInput:
case GrGLProgramDesc::kTransBlack_ColorInput:
break;
default:
GrCrash("Unknown color type.");
@ -1043,7 +1036,7 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
SharedGLState* sharedState) {
if (!(drawState.getAttribBindings() & GrDrawState::kCoverage_AttribBindingsBit)) {
switch (fDesc.fCoverageInput) {
case Desc::kAttribute_ColorInput:
case GrGLProgramDesc::kAttribute_ColorInput:
if (sharedState->fConstAttribCoverage != coverage) {
// OpenGL ES only supports the float varieties of glVertexAttrib
GrGLfloat c[4];
@ -1052,7 +1045,7 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
sharedState->fConstAttribCoverage = coverage;
}
break;
case Desc::kUniform_ColorInput:
case GrGLProgramDesc::kUniform_ColorInput:
if (fCoverage != coverage) {
// OpenGL ES doesn't support unsigned byte varieties of glUniform
GrGLfloat c[4];
@ -1063,8 +1056,8 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
fCoverage = coverage;
}
break;
case Desc::kSolidWhite_ColorInput:
case Desc::kTransBlack_ColorInput:
case GrGLProgramDesc::kSolidWhite_ColorInput:
case GrGLProgramDesc::kTransBlack_ColorInput:
break;
default:
GrCrash("Unknown coverage type.");

Просмотреть файл

@ -10,8 +10,8 @@
#define GrGLProgram_DEFINED
#include "GrDrawState.h"
#include "GrGLEffect.h"
#include "GrGLContext.h"
#include "GrGLProgramDesc.h"
#include "GrGLSL.h"
#include "GrGLTexture.h"
#include "GrGLUniformManager.h"
@ -24,10 +24,6 @@ class GrGLEffect;
class GrGLShaderBuilder;
class SkMWCRandom;
// optionally compile the experimental GS code. Set to GR_DEBUG
// so that debug build bots will execute the code.
#define GR_GL_EXPERIMENTAL_GS GR_DEBUG
/**
* This class manages a GPU program and records per-program information.
* We can specify the attribute locations so that they are constant
@ -41,22 +37,8 @@ class GrGLProgram : public GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrGLProgram)
class Desc;
/**
* Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
* output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs.
*/
static void BuildDesc(const GrDrawState&,
bool isPoints,
GrDrawState::BlendOptFlags,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff,
const GrGpuGL* gpu,
Desc* outDesc);
static GrGLProgram* Create(const GrGLContext& gl,
const Desc& desc,
const GrGLProgramDesc& desc,
const GrEffectStage* stages[]);
virtual ~GrGLProgram();
@ -71,7 +53,7 @@ public:
*/
void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
const Desc& getDesc() { return fDesc; }
const GrGLProgramDesc& getDesc() { return fDesc; }
/**
* Gets the GL program ID for this program.
@ -123,88 +105,9 @@ public:
*/
void setData(GrGpuGL*, GrColor color, GrColor coverage, SharedGLState*);
// Parameters that affect code generation
// This structs should be kept compact; it is input to an expensive hash key generator.
class Desc {
public:
Desc() {
// since we use this as part of a key we can't have any uninitialized
// padding
memset(this, 0, sizeof(Desc));
}
// returns this as a uint32_t array to be used as a key in the program cache
const uint32_t* asKey() const {
return reinterpret_cast<const uint32_t*>(this);
}
// For unit testing.
void setRandom(SkMWCRandom*,
const GrGpuGL* gpu,
const GrEffectStage stages[GrDrawState::kNumStages]);
private:
// Specifies where the initial color comes from before the stages are applied.
enum ColorInput {
kSolidWhite_ColorInput,
kTransBlack_ColorInput,
kAttribute_ColorInput,
kUniform_ColorInput,
kColorInputCnt
};
// Dual-src blending makes use of a secondary output color that can be
// used as a per-pixel blend coefficient. This controls whether a
// secondary source is output and what value it holds.
enum DualSrcOutput {
kNone_DualSrcOutput,
kCoverage_DualSrcOutput,
kCoverageISA_DualSrcOutput,
kCoverageISC_DualSrcOutput,
kDualSrcOutputCnt
};
// should the FS discard if the coverage is zero (to avoid stencil manipulation)
bool fDiscardIfZeroCoverage;
// stripped of bits that don't affect program generation
GrAttribBindings fAttribBindings;
/** Non-zero if this stage has an effect */
GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
// To enable experimental geometry shader code (not for use in
// production)
#if GR_GL_EXPERIMENTAL_GS
bool fExperimentalGS;
#endif
uint8_t fColorInput; // casts to enum ColorInput
uint8_t fCoverageInput; // casts to enum ColorInput
uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
int8_t fFirstCoverageStage;
SkBool8 fEmitsPointSize;
uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
int8_t fPositionAttributeIndex;
int8_t fColorAttributeIndex;
int8_t fCoverageAttributeIndex;
int8_t fLocalCoordsAttributeIndex;
friend class GrGLProgram;
};
// Layout information for OpenGL vertex attributes
struct AttribLayout {
GrGLint fCount;
GrGLenum fType;
GrGLboolean fNormalized;
};
static const AttribLayout kAttribLayouts[kGrVertexAttribTypeCount];
private:
GrGLProgram(const GrGLContext& gl,
const Desc& desc,
const GrGLProgramDesc& desc,
const GrEffectStage* stages[]);
bool succeeded() const { return 0 != fProgramID; }
@ -281,7 +184,7 @@ private:
GrGLEffect* fEffects[GrDrawState::kNumStages];
Desc fDesc;
GrGLProgramDesc fDesc;
const GrGLContext& fContext;
GrGLUniformManager fUniformManager;

Просмотреть файл

@ -0,0 +1,104 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrGLProgramDesc_DEFINED
#define GrGLProgramDesc_DEFINED
#include "GrGLEffect.h"
class GrGpuGL;
// optionally compile the experimental GS code. Set to GR_DEBUG so that debug build bots will
// execute the code.
#define GR_GL_EXPERIMENTAL_GS GR_DEBUG
/** This class describes a program to generate. It also serves as a program cache key. The only
thing GL-specific about this is the generation of GrGLEffect::EffectKeys. With some refactoring
it could be made backend-neutral. */
class GrGLProgramDesc {
public:
GrGLProgramDesc() {
// since we use this as part of a key we can't have any uninitialized padding
memset(this, 0, sizeof(GrGLProgramDesc));
}
// Returns this as a uint32_t array to be used as a key in the program cache
const uint32_t* asKey() const {
return reinterpret_cast<const uint32_t*>(this);
}
// For unit testing.
void setRandom(SkMWCRandom*,
const GrGpuGL* gpu,
const GrEffectStage stages[GrDrawState::kNumStages]);
/**
* Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
* output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs.
*/
static void Build(const GrDrawState&,
bool isPoints,
GrDrawState::BlendOptFlags,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff,
const GrGpuGL* gpu,
GrGLProgramDesc* outDesc);
private:
// Specifies where the initial color comes from before the stages are applied.
enum ColorInput {
kSolidWhite_ColorInput,
kTransBlack_ColorInput,
kAttribute_ColorInput,
kUniform_ColorInput,
kColorInputCnt
};
// Dual-src blending makes use of a secondary output color that can be
// used as a per-pixel blend coefficient. This controls whether a
// secondary source is output and what value it holds.
enum DualSrcOutput {
kNone_DualSrcOutput,
kCoverage_DualSrcOutput,
kCoverageISA_DualSrcOutput,
kCoverageISC_DualSrcOutput,
kDualSrcOutputCnt
};
// should the FS discard if the coverage is zero (to avoid stencil manipulation)
bool fDiscardIfZeroCoverage;
// stripped of bits that don't affect program generation
GrAttribBindings fAttribBindings;
/** Non-zero if this stage has an effect */
GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
// To enable experimental geometry shader code (not for use in
// production)
#if GR_GL_EXPERIMENTAL_GS
bool fExperimentalGS;
#endif
uint8_t fColorInput; // casts to enum ColorInput
uint8_t fCoverageInput; // casts to enum ColorInput
uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
int8_t fFirstCoverageStage;
SkBool8 fEmitsPointSize;
uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
int8_t fPositionAttributeIndex;
int8_t fColorAttributeIndex;
int8_t fCoverageAttributeIndex;
int8_t fLocalCoordsAttributeIndex;
// GrGLProgram reads the private fields to generate code.
friend class GrGLProgram;
};
#endif

Просмотреть файл

@ -9,6 +9,8 @@
#define GrGLVertexArray_DEFINED
#include "GrResource.h"
#include "GrTypesPriv.h"
#include "gl/GrGLDefines.h"
#include "gl/GrGLFunctions.h"
#include "SkTArray.h"
@ -17,6 +19,30 @@ class GrGLVertexBuffer;
class GrGLIndexBuffer;
class GrGpuGL;
struct GrGLAttribLayout {
GrGLint fCount;
GrGLenum fType;
GrGLboolean fNormalized;
};
static inline const GrGLAttribLayout& GrGLAttribTypeToLayout(GrVertexAttribType type) {
GrAssert(type >= 0 && type < kGrVertexAttribTypeCount);
static const GrGLAttribLayout kLayouts[kGrVertexAttribTypeCount] = {
{1, GR_GL_FLOAT, false}, // kFloat_GrVertexAttribType
{2, GR_GL_FLOAT, false}, // kVec2f_GrVertexAttribType
{3, GR_GL_FLOAT, false}, // kVec3f_GrVertexAttribType
{4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType
{4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType
};
GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayouts) == kGrVertexAttribTypeCount);
return kLayouts[type];
}
/**
* This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray
* (below) but is separate because it is also used to track the state of vertex array object 0.

Просмотреть файл

@ -163,10 +163,10 @@ private:
~ProgramCache();
void abandon();
GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrEffectStage* stages[]);
GrGLProgram* getProgram(const GrGLProgramDesc& desc, const GrEffectStage* stages[]);
private:
enum {
kKeySize = sizeof(GrGLProgram::Desc),
kKeySize = sizeof(GrGLProgramDesc),
// We may actually have kMaxEntries+1 shaders in the GL context because we create a new
// shader before evicting from the cache.
kMaxEntries = 32

Просмотреть файл

@ -48,7 +48,7 @@ void GrGpuGL::ProgramCache::abandon() {
fCount = 0;
}
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgram::Desc& desc,
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
const GrEffectStage* stages[]) {
Entry newEntry;
newEntry.fKey.setKeyData(desc.asKey());
@ -180,8 +180,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
stages[i] = drawState.isStageEnabled(i) ? &drawState.getStage(i) : NULL;
}
GrGLProgram::Desc desc;
GrGLProgram::BuildDesc(this->getDrawState(),
GrGLProgramDesc desc;
GrGLProgramDesc::Build(this->getDrawState(),
kDrawPoints_DrawType == type,
blendOpts,
srcCoeff,
@ -302,9 +302,9 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
attribState->set(this,
vertexAttribIndex,
vbuf,
GrGLProgram::kAttribLayouts[attribType].fCount,
GrGLProgram::kAttribLayouts[attribType].fType,
GrGLProgram::kAttribLayouts[attribType].fNormalized,
GrGLAttribTypeToLayout(attribType).fCount,
GrGLAttribTypeToLayout(attribType).fType,
GrGLAttribTypeToLayout(attribType).fNormalized,
stride,
reinterpret_cast<GrGLvoid*>(
vertexOffsetInBytes + vertexAttrib->fOffset));

Просмотреть файл

@ -21,9 +21,9 @@
#include "SkRandom.h"
#include "Test.h"
void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
const GrGpuGL* gpu,
const GrEffectStage stages[GrDrawState::kNumStages]) {
void GrGLProgramDesc::setRandom(SkMWCRandom* random,
const GrGpuGL* gpu,
const GrEffectStage stages[GrDrawState::kNumStages]) {
fAttribBindings = 0;
fEmitsPointSize = random->nextBool();
fColorInput = random->nextULessThan(kColorInputCnt);
@ -106,7 +106,7 @@ bool GrGpuGL::programUnitTest(int maxStages) {
}
#endif
GrGLProgram::Desc pdesc;
GrGLProgramDesc pdesc;
GrEffectStage stages[GrDrawState::kNumStages];
int currAttribIndex = GrDrawState::kAttribIndexCount;