Rolling back r8466.
Not reviewed. git-svn-id: http://skia.googlecode.com/svn/trunk@8467 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
fb495b537f
commit
c7bf2963f0
@ -111,21 +111,6 @@ public:
|
||||
*/
|
||||
void reset() { this->pop_back_n(fCount); }
|
||||
|
||||
/**
|
||||
* Resets to a copy of a C array.
|
||||
*/
|
||||
void reset(const T* array, int count) {
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
fItemArray[i].~T();
|
||||
}
|
||||
int delta = count - fCount;
|
||||
this->checkRealloc(delta);
|
||||
fCount = count;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SkTArrayExt::copy(this, array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of elements in the array.
|
||||
*/
|
||||
|
@ -8,12 +8,12 @@
|
||||
#ifndef GrTypesPriv_DEFINED
|
||||
#define GrTypesPriv_DEFINED
|
||||
|
||||
#include "GrTypes.h"
|
||||
#include "SkTArray.h"
|
||||
|
||||
/**
|
||||
* Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
|
||||
* but should be applicable to other shader languages.)
|
||||
* Types of shader-language-specific boxed variables we can create.
|
||||
* (Currently only GrGLShaderVars, but should be applicable to other shader
|
||||
* languages.)
|
||||
*/
|
||||
enum GrSLType {
|
||||
kVoid_GrSLType,
|
||||
@ -23,43 +23,11 @@ enum GrSLType {
|
||||
kVec4f_GrSLType,
|
||||
kMat33f_GrSLType,
|
||||
kMat44f_GrSLType,
|
||||
kSampler2D_GrSLType,
|
||||
|
||||
kLast_GrSLType = kSampler2D_GrSLType
|
||||
kSampler2D_GrSLType
|
||||
};
|
||||
static const int kGrSLTypeCount = kLast_GrSLType + 1;
|
||||
|
||||
/**
|
||||
* Gets the vector size of the SLType. Returns -1 for void, matrices, and samplers.
|
||||
*/
|
||||
static inline int GrSLTypeVectorCount(GrSLType type) {
|
||||
GrAssert(type >= 0 && type < kGrSLTypeCount);
|
||||
static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1 };
|
||||
return kCounts[type];
|
||||
|
||||
GR_STATIC_ASSERT(0 == kVoid_GrSLType);
|
||||
GR_STATIC_ASSERT(1 == kFloat_GrSLType);
|
||||
GR_STATIC_ASSERT(2 == kVec2f_GrSLType);
|
||||
GR_STATIC_ASSERT(3 == kVec3f_GrSLType);
|
||||
GR_STATIC_ASSERT(4 == kVec4f_GrSLType);
|
||||
GR_STATIC_ASSERT(5 == kMat33f_GrSLType);
|
||||
GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
|
||||
GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
|
||||
GR_STATIC_ASSERT(GR_ARRAY_COUNT(kCounts) == kGrSLTypeCount);
|
||||
}
|
||||
|
||||
static inline GrSLType GrSLFloatVectorType(int count) {
|
||||
GrAssert(count > 0 && count <= 4);
|
||||
return (GrSLType)(count);
|
||||
|
||||
GR_STATIC_ASSERT(kFloat_GrSLType == 1);
|
||||
GR_STATIC_ASSERT(kVec2f_GrSLType == 2);
|
||||
GR_STATIC_ASSERT(kVec3f_GrSLType == 3);
|
||||
GR_STATIC_ASSERT(kVec4f_GrSLType == 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Types used to describe format of vertices in arrays.
|
||||
* Types used to describe format of vertices in arrays
|
||||
*/
|
||||
enum GrVertexAttribType {
|
||||
kFloat_GrVertexAttribType = 0,
|
||||
@ -72,96 +40,20 @@ enum GrVertexAttribType {
|
||||
};
|
||||
static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
|
||||
|
||||
/**
|
||||
* Returns the vector size of the type.
|
||||
*/
|
||||
static inline int GrVertexAttribTypeVectorCount(GrVertexAttribType type) {
|
||||
GrAssert(type >= 0 && type < kGrVertexAttribTypeCount);
|
||||
static const int kCounts[] = { 1, 2, 3, 4, 4 };
|
||||
return kCounts[type];
|
||||
|
||||
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(GR_ARRAY_COUNT(kCounts) == kGrVertexAttribTypeCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the attrib type in bytes.
|
||||
*/
|
||||
static inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
|
||||
GrAssert(type >= 0 && type < kGrVertexAttribTypeCount);
|
||||
static const size_t kSizes[] = {
|
||||
sizeof(float), // kFloat_GrVertexAttribType
|
||||
2*sizeof(float), // kVec2f_GrVertexAttribType
|
||||
3*sizeof(float), // kVec3f_GrVertexAttribType
|
||||
4*sizeof(float), // kVec4f_GrVertexAttribType
|
||||
4*sizeof(char) // kVec4ub_GrVertexAttribType
|
||||
};
|
||||
return kSizes[type];
|
||||
|
||||
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(GR_ARRAY_COUNT(kSizes) == kGrVertexAttribTypeCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Semantic bindings for vertex attributes. kEffect means that the attribute is input to a GrEffect.
|
||||
* Each binding other than kEffect may not appear more than once in the current set of attributes.
|
||||
* kPosition must be appear for exactly one attribute.
|
||||
*/
|
||||
enum GrVertexAttribBinding {
|
||||
kPosition_GrVertexAttribBinding, // required, must have vector count of 2
|
||||
kLocalCoord_GrVertexAttribBinding, // must have vector count of 2
|
||||
kColor_GrVertexAttribBinding, // must have vector count of 4
|
||||
kCoverage_GrVertexAttribBinding, // must have vector count of 4
|
||||
|
||||
kLastFixedFunction_GrVertexAttribBinding = kCoverage_GrVertexAttribBinding,
|
||||
|
||||
kEffect_GrVertexAttribBinding, // vector length must agree with
|
||||
// GrEffect::vertexAttribType() for each effect input to
|
||||
// which the attribute is mapped by GrDrawState::setEffect()
|
||||
kLast_GrVertexAttribBinding = kEffect_GrVertexAttribBinding
|
||||
};
|
||||
|
||||
static const int kGrVertexAttribBindingCnt = kLast_GrVertexAttribBinding + 1;
|
||||
static const int kGrFixedFunctionVertexAttribBindingCnt =
|
||||
kLastFixedFunction_GrVertexAttribBinding + 1;
|
||||
|
||||
static const int GrFixedFunctionVertexAttribVectorCount(GrVertexAttribBinding binding) {
|
||||
GrAssert(binding >= 0 && binding < kGrFixedFunctionVertexAttribBindingCnt);
|
||||
static const int kVecCounts[] = { 2, 2, 4, 4 };
|
||||
|
||||
return kVecCounts[binding];
|
||||
|
||||
GR_STATIC_ASSERT(0 == kPosition_GrVertexAttribBinding);
|
||||
GR_STATIC_ASSERT(1 == kLocalCoord_GrVertexAttribBinding);
|
||||
GR_STATIC_ASSERT(2 == kColor_GrVertexAttribBinding);
|
||||
GR_STATIC_ASSERT(3 == kCoverage_GrVertexAttribBinding);
|
||||
GR_STATIC_ASSERT(kGrFixedFunctionVertexAttribBindingCnt == SK_ARRAY_COUNT(kVecCounts));
|
||||
}
|
||||
|
||||
struct GrVertexAttrib {
|
||||
inline void set(GrVertexAttribType type, size_t offset, GrVertexAttribBinding binding) {
|
||||
fType = type;
|
||||
fOffset = offset;
|
||||
fBinding = binding;
|
||||
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 && fBinding == other.fBinding;
|
||||
return fType == other.fType && fOffset == other.fOffset;
|
||||
};
|
||||
bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
|
||||
|
||||
GrVertexAttribType fType;
|
||||
size_t fOffset;
|
||||
GrVertexAttribBinding fBinding;
|
||||
GrVertexAttribType fType;
|
||||
size_t fOffset;
|
||||
};
|
||||
|
||||
template <int N> class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
|
||||
template <int N>
|
||||
class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
|
||||
|
||||
#endif
|
||||
|
@ -485,10 +485,13 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec4f_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
|
||||
drawState->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
|
||||
|
||||
enum {
|
||||
// the edge effects share this stage with glyph rendering
|
||||
|
@ -507,8 +507,8 @@ bool GrAAHairLinePathRenderer::createGeom(
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec4f_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
SkMatrix viewM = drawState->getViewMatrix();
|
||||
|
||||
@ -522,6 +522,8 @@ bool GrAAHairLinePathRenderer::createGeom(
|
||||
int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
|
||||
|
||||
target->drawState()->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs));
|
||||
target->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
target->drawState()->setAttribBindings(GrDrawState::kDefault_AttribBindings);
|
||||
GrAssert(sizeof(Vertex) == target->getDrawState().getVertexSize());
|
||||
|
||||
if (!arg->set(target, vertCnt, 0)) {
|
||||
|
@ -13,17 +13,15 @@ SK_DEFINE_INST_COUNT(GrAARectRenderer)
|
||||
|
||||
namespace {
|
||||
|
||||
static void aa_rect_attributes(bool useCoverage, const GrVertexAttrib** attribs, int* count) {
|
||||
static const GrVertexAttrib kCoverageAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec4ub_GrVertexAttribType, sizeof(GrPoint), kCoverage_GrVertexAttribBinding},
|
||||
};
|
||||
static const GrVertexAttrib kColorAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding},
|
||||
};
|
||||
*attribs = useCoverage ? kCoverageAttribs : kColorAttribs;
|
||||
*count = 2;
|
||||
static void aa_rect_attributes(bool useCoverage, GrAttribBindings* bindings,
|
||||
GrDrawState::AttribIndex* index) {
|
||||
if (useCoverage) {
|
||||
*bindings = GrDrawState::kCoverage_AttribBindingsBit;
|
||||
*index = GrDrawState::kCoverage_AttribIndex;
|
||||
} else {
|
||||
*bindings = GrDrawState::kColor_AttribBindingsBit;
|
||||
*index = GrDrawState::kColor_AttribIndex;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_inset_fan(GrPoint* pts, size_t stride,
|
||||
@ -130,10 +128,18 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
|
||||
bool useVertexCoverage) {
|
||||
GrDrawState* drawState = target->drawState();
|
||||
|
||||
const GrVertexAttrib* attribs;
|
||||
int attribCount;
|
||||
aa_rect_attributes(useVertexCoverage, &attribs, &attribCount);
|
||||
drawState->setVertexAttribs(attribs, attribCount);
|
||||
// position + color/coverage
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec4ub_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
GrAttribBindings bindings;
|
||||
GrDrawState::AttribIndex attribIndex;
|
||||
aa_rect_attributes(useVertexCoverage, &bindings, &attribIndex);
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribBindings(bindings);
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(attribIndex, 1);
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
|
||||
if (!geo.succeeded()) {
|
||||
@ -206,10 +212,18 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu,
|
||||
return;
|
||||
}
|
||||
|
||||
const GrVertexAttrib* attribs;
|
||||
int attribCount;
|
||||
aa_rect_attributes(useVertexCoverage, &attribs, &attribCount);
|
||||
drawState->setVertexAttribs(attribs, attribCount);
|
||||
// position + color/coverage
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec4ub_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
GrAttribBindings bindings;
|
||||
GrDrawState::AttribIndex attribIndex;
|
||||
aa_rect_attributes(useVertexCoverage, &bindings, &attribIndex);
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribBindings(bindings);
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(attribIndex, 1);
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
|
||||
if (!geo.succeeded()) {
|
||||
|
@ -358,13 +358,17 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
|
||||
drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params);
|
||||
|
||||
// position + local coordinate
|
||||
// position + texture coordinate
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
|
||||
static const GrAttribBindings kAttribBindings = GrDrawState::kLocalCoords_AttribBindingsBit;
|
||||
drawState->setAttribBindings(kAttribBindings);
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, 1);
|
||||
GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
|
||||
|
||||
if (arg.succeeded()) {
|
||||
@ -921,16 +925,19 @@ void GrContext::drawVertices(const GrPaint& paint,
|
||||
GrVertexAttribArray<3> attribs;
|
||||
size_t currentOffset = 0;
|
||||
int colorOffset = -1, texOffset = -1;
|
||||
GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
|
||||
|
||||
// set position attribute
|
||||
GrVertexAttrib currAttrib =
|
||||
{kVec2f_GrVertexAttribType, currentOffset, kPosition_GrVertexAttribBinding};
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
|
||||
GrVertexAttrib currAttrib = {kVec2f_GrVertexAttribType, currentOffset};
|
||||
attribs.push_back(currAttrib);
|
||||
currentOffset += sizeof(GrPoint);
|
||||
|
||||
// set up optional texture coordinate attributes
|
||||
if (NULL != texCoords) {
|
||||
currAttrib.set(kVec2f_GrVertexAttribType, currentOffset, kLocalCoord_GrVertexAttribBinding);
|
||||
bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
|
||||
drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
|
||||
currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
|
||||
attribs.push_back(currAttrib);
|
||||
texOffset = currentOffset;
|
||||
currentOffset += sizeof(GrPoint);
|
||||
@ -938,13 +945,16 @@ void GrContext::drawVertices(const GrPaint& paint,
|
||||
|
||||
// set up optional color attributes
|
||||
if (NULL != colors) {
|
||||
currAttrib.set(kVec4ub_GrVertexAttribType, currentOffset, kColor_GrVertexAttribBinding);
|
||||
bindings |= GrDrawState::kColor_AttribBindingsBit;
|
||||
drawState->setAttribIndex(GrDrawState::kColor_AttribIndex, attribs.count());
|
||||
currAttrib.set(kVec4ub_GrVertexAttribType, currentOffset);
|
||||
attribs.push_back(currAttrib);
|
||||
colorOffset = currentOffset;
|
||||
currentOffset += sizeof(GrColor);
|
||||
}
|
||||
|
||||
drawState->setVertexAttribs(attribs.begin(), attribs.count());
|
||||
drawState->setAttribBindings(bindings);
|
||||
|
||||
size_t vertexSize = drawState->getVertexSize();
|
||||
GrAssert(vertexSize == currentOffset);
|
||||
|
@ -46,15 +46,23 @@ void GrDrawState::setFromPaint(const GrPaint& paint) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const size_t GrDrawState::kVertexAttribSizes[kGrVertexAttribTypeCount] = {
|
||||
sizeof(float), // kFloat_GrVertexAttribType
|
||||
2*sizeof(float), // kVec2_GrVertexAttribType
|
||||
3*sizeof(float), // kVec3_GrVertexAttribType
|
||||
4*sizeof(float), // kVec4_GrVertexAttribType
|
||||
4*sizeof(char) // kCVec4_GrVertexAttribType
|
||||
};
|
||||
|
||||
static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
|
||||
// this works as long as we're 4 byte-aligned
|
||||
#if GR_DEBUG
|
||||
uint32_t overlapCheck = 0;
|
||||
#endif
|
||||
GrAssert(count <= GrDrawState::kMaxVertexAttribCnt);
|
||||
GrAssert(count <= GrDrawState::kVertexAttribCnt);
|
||||
size_t size = 0;
|
||||
for (int index = 0; index < count; ++index) {
|
||||
size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
|
||||
size_t attribSize = GrDrawState::kVertexAttribSizes[attribs[index].fType];
|
||||
size += attribSize;
|
||||
#if GR_DEBUG
|
||||
size_t dwordCount = attribSize >> 2;
|
||||
@ -68,102 +76,163 @@ static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
|
||||
}
|
||||
|
||||
size_t GrDrawState::getVertexSize() const {
|
||||
return vertex_size(fCommon.fVertexAttribs.begin(), fCommon.fVertexAttribs.count());
|
||||
return vertex_size(fVertexAttribs.begin(), fVertexAttribs.count());
|
||||
}
|
||||
|
||||
const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = {
|
||||
0, // position is not reflected in the bindings
|
||||
kColor_AttribBindingsBit,
|
||||
kCoverage_AttribBindingsBit,
|
||||
kLocalCoords_AttribBindingsBit,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
|
||||
GrAssert(count <= kMaxVertexAttribCnt);
|
||||
fCommon.fVertexAttribs.reset(attribs, count);
|
||||
|
||||
// Set all the indices to -1
|
||||
memset(fCommon.fFixedFunctionVertexAttribIndices,
|
||||
0xff,
|
||||
sizeof(fCommon.fFixedFunctionVertexAttribIndices));
|
||||
#if GR_DEBUG
|
||||
uint32_t overlapCheck = 0;
|
||||
#endif
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
|
||||
// The fixed function attribs can only be specified once
|
||||
GrAssert(-1 == fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
|
||||
GrAssert(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
|
||||
GrVertexAttribTypeVectorCount(attribs[i].fType));
|
||||
fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
|
||||
}
|
||||
#if GR_DEBUG
|
||||
size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
|
||||
uint32_t mask = (1 << dwordCount)-1;
|
||||
size_t offsetShift = attribs[i].fOffset >> 2;
|
||||
GrAssert(!(overlapCheck & (mask << offsetShift)));
|
||||
overlapCheck |= (mask << offsetShift);
|
||||
#endif
|
||||
GrAssert(count <= GrDrawState::kVertexAttribCnt);
|
||||
fVertexAttribs.reset();
|
||||
for (int index = 0; index < count; ++index) {
|
||||
fVertexAttribs.push_back(attribs[index]);
|
||||
}
|
||||
// Positions must be specified.
|
||||
GrAssert(-1 != fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDrawState::setDefaultVertexAttribs() {
|
||||
static const GrVertexAttrib kPositionAttrib =
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
|
||||
fCommon.fVertexAttribs.reset(&kPositionAttrib, 1);
|
||||
// set all the fixed function indices to -1 except position.
|
||||
memset(fCommon.fFixedFunctionVertexAttribIndices,
|
||||
0xff,
|
||||
sizeof(fCommon.fFixedFunctionVertexAttribIndices));
|
||||
fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
|
||||
static const GrVertexAttrib kPositionAttrib = {kVec2f_GrVertexAttribType, 0};
|
||||
fVertexAttribs.reset();
|
||||
fVertexAttribs.push_back(kPositionAttrib);
|
||||
|
||||
fCommon.fAttribBindings = kDefault_AttribBindings;
|
||||
|
||||
fAttribIndices[kPosition_AttribIndex] = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawState::validateVertexAttribs() const {
|
||||
// check consistency of effects and attributes
|
||||
GrSLType slTypes[kMaxVertexAttribCnt];
|
||||
for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
|
||||
slTypes[i] = static_cast<GrSLType>(-1);
|
||||
// color and coverage can set indices beyond the standard count
|
||||
static const int kMaxValidAttribIndex = kVertexAttribCnt+2;
|
||||
int attributeTypes[kMaxValidAttribIndex];
|
||||
for (int i = 0; i < kMaxValidAttribIndex; ++i) {
|
||||
attributeTypes[i] = -1;
|
||||
}
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (this->isStageEnabled(s)) {
|
||||
const GrEffectStage& stage = fStages[s];
|
||||
const GrEffectRef* effect = stage.getEffect();
|
||||
// make sure that any attribute indices have the correct binding type, that the attrib
|
||||
// type and effect's shader lang type are compatible, and that attributes shared by
|
||||
// multiple effects use the same shader lang type.
|
||||
const int* attributeIndices = stage.getVertexAttribIndices();
|
||||
int numAttributes = stage.getVertexAttribIndexCount();
|
||||
for (int i = 0; i < numAttributes; ++i) {
|
||||
int attribIndex = attributeIndices[i];
|
||||
if (attribIndex >= fCommon.fVertexAttribs.count() ||
|
||||
kEffect_GrVertexAttribBinding != fCommon.fVertexAttribs[attribIndex].fBinding) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrSLType effectSLType = (*effect)->vertexAttribType(i);
|
||||
GrVertexAttribType attribType = fCommon.fVertexAttribs[attribIndex].fType;
|
||||
int slVecCount = GrSLTypeVectorCount(effectSLType);
|
||||
int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
|
||||
if (slVecCount != attribVecCount ||
|
||||
(-1 != slTypes[attribIndex] && slTypes[attribIndex] != effectSLType)) {
|
||||
return false;
|
||||
}
|
||||
slTypes[attribIndex] = effectSLType;
|
||||
// sentinel to make sure effects don't try to use built-in attributes
|
||||
static const int kBuiltInAttributeType = 10000;
|
||||
|
||||
// check our built-in indices
|
||||
if (fAttribIndices[kPosition_AttribIndex] >= kVertexAttribCnt) {
|
||||
return false;
|
||||
}
|
||||
attributeTypes[fAttribIndices[kPosition_AttribIndex]] = kBuiltInAttributeType;
|
||||
for (int j = kColor_AttribIndex; j <= kCoverage_AttribIndex; ++j) {
|
||||
if (fCommon.fAttribBindings & kAttribIndexMasks[j]) {
|
||||
int attributeIndex = fAttribIndices[j];
|
||||
if (attributeIndex >= kMaxValidAttribIndex) {
|
||||
return false;
|
||||
}
|
||||
// they should not be shared at all
|
||||
if (attributeTypes[attributeIndex] != -1) {
|
||||
return false;
|
||||
}
|
||||
attributeTypes[attributeIndex] = kBuiltInAttributeType;
|
||||
}
|
||||
}
|
||||
if (fCommon.fAttribBindings & kAttribIndexMasks[kLocalCoords_AttribIndex]) {
|
||||
int attributeIndex = fAttribIndices[kLocalCoords_AttribIndex];
|
||||
if (attributeIndex >= kVertexAttribCnt) {
|
||||
return false;
|
||||
}
|
||||
// they should not be shared at all
|
||||
if (attributeTypes[attributeIndex] != -1) {
|
||||
return false;
|
||||
}
|
||||
attributeTypes[attributeIndex] = kBuiltInAttributeType;
|
||||
}
|
||||
|
||||
// now those set by effects
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
const GrEffectStage& stage = fStages[s];
|
||||
const GrEffectRef* effect = stage.getEffect();
|
||||
if (effect == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure that the count in the stage and the effect matches
|
||||
int numAttributes = stage.getVertexAttribIndexCount();
|
||||
if (numAttributes != effect->get()->numVertexAttribs()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure that any shared indices have the same type
|
||||
const int* attributeIndices = stage.getVertexAttribIndices();
|
||||
for (int i = 0; i < numAttributes; ++i) {
|
||||
int attributeIndex = attributeIndices[i];
|
||||
if (attributeIndex >= kVertexAttribCnt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrSLType attributeType = effect->get()->vertexAttribType(i);
|
||||
if (attributeTypes[attributeIndex] != -1 &&
|
||||
attributeTypes[attributeIndex] != attributeType) {
|
||||
return false;
|
||||
}
|
||||
attributeTypes[attributeIndex] = attributeType;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void GrDrawState::VertexAttributesUnitTest() {
|
||||
// not necessarily exhaustive
|
||||
static bool run;
|
||||
if (!run) {
|
||||
run = true;
|
||||
|
||||
GrVertexAttribArray<6> attribs;
|
||||
GrAssert(0 == vertex_size(attribs.begin(), attribs.count()));
|
||||
|
||||
GrVertexAttrib currAttrib = {kFloat_GrVertexAttribType, 0};
|
||||
attribs.push_back(currAttrib);
|
||||
GrAssert(sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs[0].fType = kVec2f_GrVertexAttribType;
|
||||
GrAssert(2*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs[0].fType = kVec3f_GrVertexAttribType;
|
||||
GrAssert(3*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs[0].fType = kVec4f_GrVertexAttribType;
|
||||
GrAssert(4*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs[0].fType = kVec4ub_GrVertexAttribType;
|
||||
GrAssert(4*sizeof(char) == vertex_size(attribs.begin(), attribs.count()));
|
||||
|
||||
currAttrib.set(kVec2f_GrVertexAttribType, attribs[0].fOffset + 4*sizeof(char));
|
||||
attribs.push_back(currAttrib);
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
|
||||
currAttrib.set(kVec3f_GrVertexAttribType, attribs[1].fOffset + 2*sizeof(float));
|
||||
attribs.push_back(currAttrib);
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) ==
|
||||
vertex_size(attribs.begin(), attribs.count()));
|
||||
currAttrib.set(kFloat_GrVertexAttribType, attribs[2].fOffset + 3*sizeof(float));
|
||||
attribs.push_back(currAttrib);
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) ==
|
||||
vertex_size(attribs.begin(), attribs.count()));
|
||||
currAttrib.set(kVec4f_GrVertexAttribType, attribs[3].fOffset + sizeof(float));
|
||||
attribs.push_back(currAttrib);
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) + 4*sizeof(float) ==
|
||||
vertex_size(attribs.begin(), attribs.count()));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawState::srcAlphaWillBeOne() const {
|
||||
bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const {
|
||||
|
||||
uint32_t validComponentFlags;
|
||||
GrColor color;
|
||||
// Check if per-vertex or constant color may have partial alpha
|
||||
if (this->hasColorVertexAttribute()) {
|
||||
if (bindings & kColor_AttribBindingsBit) {
|
||||
validComponentFlags = 0;
|
||||
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
|
||||
} else {
|
||||
@ -209,7 +278,7 @@ bool GrDrawState::srcAlphaWillBeOne() const {
|
||||
return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
|
||||
}
|
||||
|
||||
bool GrDrawState::hasSolidCoverage() const {
|
||||
bool GrDrawState::hasSolidCoverage(GrAttribBindings bindings) const {
|
||||
// If we're drawing coverage directly then coverage is effectively treated as color.
|
||||
if (this->isCoverageDrawing()) {
|
||||
return true;
|
||||
@ -218,7 +287,7 @@ bool GrDrawState::hasSolidCoverage() const {
|
||||
GrColor coverage;
|
||||
uint32_t validComponentFlags;
|
||||
// Initialize to an unknown starting coverage if per-vertex coverage is specified.
|
||||
if (this->hasCoverageVertexAttribute()) {
|
||||
if (bindings & kCoverage_AttribBindingsBit) {
|
||||
validComponentFlags = 0;
|
||||
} else {
|
||||
coverage = fCommon.fCoverage;
|
||||
@ -260,6 +329,7 @@ bool GrDrawState::canTweakAlphaForCoverage() const {
|
||||
GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
||||
GrBlendCoeff* srcCoeff,
|
||||
GrBlendCoeff* dstCoeff) const {
|
||||
GrAttribBindings bindings = this->getAttribBindings();
|
||||
|
||||
GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
|
||||
if (NULL == srcCoeff) {
|
||||
@ -277,14 +347,14 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
||||
*dstCoeff = kOne_GrBlendCoeff;
|
||||
}
|
||||
|
||||
bool srcAIsOne = this->srcAlphaWillBeOne();
|
||||
bool srcAIsOne = this->srcAlphaWillBeOne(bindings);
|
||||
bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
|
||||
(kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
|
||||
bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
|
||||
(kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
|
||||
|
||||
bool covIsZero = !this->isCoverageDrawing() &&
|
||||
!this->hasCoverageVertexAttribute() &&
|
||||
!(bindings & GrDrawState::kCoverage_AttribBindingsBit) &&
|
||||
0 == this->getCoverage();
|
||||
// When coeffs are (0,1) there is no reason to draw at all, unless
|
||||
// stenciling is enabled. Having color writes disabled is effectively
|
||||
@ -301,8 +371,10 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
||||
// check for coverage due to constant coverage, per-vertex coverage, or coverage stage
|
||||
bool hasCoverage = forceCoverage ||
|
||||
0xffffffff != this->getCoverage() ||
|
||||
this->hasCoverageVertexAttribute();
|
||||
for (int s = this->getFirstCoverageStage(); !hasCoverage && s < GrDrawState::kNumStages; ++s) {
|
||||
(bindings & GrDrawState::kCoverage_AttribBindingsBit);
|
||||
for (int s = this->getFirstCoverageStage();
|
||||
!hasCoverage && s < GrDrawState::kNumStages;
|
||||
++s) {
|
||||
if (this->isStageEnabled(s)) {
|
||||
hasCoverage = true;
|
||||
}
|
||||
|
@ -23,6 +23,11 @@
|
||||
#include "SkMatrix.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
/**
|
||||
* Type used to describe how attributes bind to program usage
|
||||
*/
|
||||
typedef int GrAttribBindings;
|
||||
|
||||
class GrDrawState : public GrRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(GrDrawState)
|
||||
@ -40,8 +45,8 @@ public:
|
||||
* coverage rather than as input to the src/dst color blend step.
|
||||
*
|
||||
* The input color to the first enabled color-stage is either the constant color or interpolated
|
||||
* per-vertex colors. The input to the first coverage stage is either a constant coverage
|
||||
* (usually full-coverage) or interpolated per-vertex coverage.
|
||||
* per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
|
||||
* either a constant coverage (usually full-coverage) or interpolated per-vertex coverage.
|
||||
*
|
||||
* See the documentation of kCoverageDrawing_StateBit for information about disabling the
|
||||
* the color / coverage distinction.
|
||||
@ -57,6 +62,9 @@ public:
|
||||
};
|
||||
|
||||
GrDrawState() {
|
||||
#if GR_DEBUG
|
||||
VertexAttributesUnitTest();
|
||||
#endif
|
||||
this->reset();
|
||||
}
|
||||
|
||||
@ -107,72 +115,53 @@ public:
|
||||
////
|
||||
|
||||
enum {
|
||||
kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
|
||||
kVertexAttribCnt = 6,
|
||||
};
|
||||
|
||||
/**
|
||||
* The format of vertices is represented as an array of GrVertexAttribs, with each representing
|
||||
* the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
|
||||
* GrTypesPriv.h).
|
||||
* The format of vertices is represented as an array of vertex attribute
|
||||
* pair, with each pair representing the type of the attribute and the
|
||||
* offset in the vertex structure (see GrVertexAttrib, above).
|
||||
*
|
||||
* The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
|
||||
* setEffect is called.
|
||||
* This will only set up the vertex geometry. To bind the attributes in
|
||||
* the shaders, attribute indices and attribute bindings need to be set
|
||||
* as well.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets vertex attributes for next draw.
|
||||
*
|
||||
* @param attribs the array of vertex attributes to set.
|
||||
* @param count the number of attributes being set, limited to kMaxVertexAttribCnt.
|
||||
* @param count the number of attributes being set.
|
||||
* limited to a count of kVertexAttribCnt.
|
||||
*/
|
||||
void setVertexAttribs(const GrVertexAttrib attribs[], int count);
|
||||
|
||||
const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVertexAttribs.begin(); }
|
||||
int getVertexAttribCount() const { return fCommon.fVertexAttribs.count(); }
|
||||
const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
|
||||
int getVertexAttribCount() const { return fVertexAttribs.count(); }
|
||||
|
||||
size_t getVertexSize() const;
|
||||
|
||||
/**
|
||||
* Sets default vertex attributes for next draw. The default is a single attribute:
|
||||
* {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
|
||||
* Sets default vertex attributes for next draw.
|
||||
*
|
||||
* This will also set default vertex attribute indices and bindings
|
||||
*/
|
||||
void setDefaultVertexAttribs();
|
||||
|
||||
/**
|
||||
* Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
|
||||
* binding does not appear in the current attribs. These bindings should appear only once in
|
||||
* the attrib array.
|
||||
*/
|
||||
|
||||
int positionAttributeIndex() const {
|
||||
return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
|
||||
}
|
||||
int localCoordAttributeIndex() const {
|
||||
return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
|
||||
}
|
||||
int colorVertexAttributeIndex() const {
|
||||
return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
|
||||
}
|
||||
int coverageVertexAttributeIndex() const {
|
||||
return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
|
||||
}
|
||||
|
||||
bool hasLocalCoordAttribute() const {
|
||||
return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
|
||||
}
|
||||
bool hasColorVertexAttribute() const {
|
||||
return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
|
||||
}
|
||||
bool hasCoverageVertexAttribute() const {
|
||||
return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
|
||||
}
|
||||
|
||||
bool validateVertexAttribs() const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers for picking apart vertex attributes
|
||||
|
||||
// helper array to let us check the expected so we know what bound attrib indices
|
||||
// we care about
|
||||
static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
|
||||
|
||||
/**
|
||||
* Accessing positions, local coords, or colors, of a vertex within an array is a hassle
|
||||
* involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit
|
||||
* nicer looking.
|
||||
* Accessing positions, texture coords, or colors, of a vertex within an
|
||||
* array is a hassle involving casts and simple math. These helpers exist
|
||||
* to keep GrDrawTarget clients' code a bit nicer looking.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -229,15 +218,110 @@ public:
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// @name Attribute Bindings
|
||||
////
|
||||
|
||||
/**
|
||||
* The vertex data used by the current program is represented as a bitfield
|
||||
* of flags. Programs always use positions and may also use texture
|
||||
* coordinates, per-vertex colors, per-vertex coverage and edge data. The
|
||||
* local coords accessible by effects may either come from positions or
|
||||
* be specified explicitly.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Additional Bits that can be specified in GrAttribBindings.
|
||||
*/
|
||||
enum AttribBindingsBits {
|
||||
/** explicit local coords are provided (instead of using pre-view-matrix positions) */
|
||||
kLocalCoords_AttribBindingsBit = 0x1,
|
||||
/* program uses colors (GrColor) */
|
||||
kColor_AttribBindingsBit = 0x2,
|
||||
/* program uses coverage (GrColor)
|
||||
*/
|
||||
kCoverage_AttribBindingsBit = 0x4,
|
||||
// for below assert
|
||||
kDummyAttribBindingsBit,
|
||||
kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
|
||||
};
|
||||
// make sure we haven't exceeded the number of bits in GrAttribBindings.
|
||||
GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
|
||||
|
||||
enum AttribBindings {
|
||||
kDefault_AttribBindings = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets attribute bindings for next draw.
|
||||
*
|
||||
* @param bindings the attribute bindings to set.
|
||||
*/
|
||||
void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
|
||||
|
||||
GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers for picking apart attribute bindings
|
||||
|
||||
/**
|
||||
* Determines whether src alpha is guaranteed to be one for all src pixels
|
||||
*/
|
||||
bool srcAlphaWillBeOne() const;
|
||||
bool srcAlphaWillBeOne(GrAttribBindings) const;
|
||||
|
||||
/**
|
||||
* Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
|
||||
*/
|
||||
bool hasSolidCoverage() const;
|
||||
bool hasSolidCoverage(GrAttribBindings) const;
|
||||
|
||||
static void VertexAttributesUnitTest();
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// @name Vertex Attribute Indices
|
||||
////
|
||||
|
||||
/**
|
||||
* Vertex attribute indices map the data set in the vertex attribute array
|
||||
* to the bindings specified in the attribute bindings. Each binding type
|
||||
* has an associated index in the attribute array. This index is used to
|
||||
* look up the vertex attribute data from the array, and potentially as the
|
||||
* attribute index if we're binding attributes in GL.
|
||||
*
|
||||
* Indices which do not have active attribute bindings will be ignored.
|
||||
*/
|
||||
|
||||
enum AttribIndex {
|
||||
kPosition_AttribIndex = 0,
|
||||
kColor_AttribIndex,
|
||||
kCoverage_AttribIndex,
|
||||
kLocalCoords_AttribIndex,
|
||||
|
||||
kLast_AttribIndex = kLocalCoords_AttribIndex
|
||||
};
|
||||
static const int kAttribIndexCount = kLast_AttribIndex + 1;
|
||||
|
||||
// these are used when vertex color and coverage isn't set
|
||||
enum {
|
||||
kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
|
||||
kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers to set attribute indices. These should match the index in the
|
||||
// current attribute index array.
|
||||
|
||||
/**
|
||||
* Sets index for next draw. This is used to look up the offset
|
||||
* from the current vertex attribute array and to bind the attributes.
|
||||
*
|
||||
* @param index the attribute index we're setting
|
||||
* @param value the value of the index
|
||||
*/
|
||||
void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
|
||||
|
||||
int getAttribIndex(AttribIndex index) const { return fAttribIndices[index]; }
|
||||
|
||||
/// @}
|
||||
|
||||
@ -984,6 +1068,15 @@ public:
|
||||
if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
|
||||
return false;
|
||||
}
|
||||
if (fVertexAttribs != s.fVertexAttribs) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < kAttribIndexCount; ++i) {
|
||||
if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
|
||||
fAttribIndices[i] != s.fAttribIndices[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < kNumStages; i++) {
|
||||
bool enabled = this->isStageEnabled(i);
|
||||
if (enabled != s.isStageEnabled(i)) {
|
||||
@ -1000,6 +1093,10 @@ public:
|
||||
GrDrawState& operator= (const GrDrawState& s) {
|
||||
this->setRenderTarget(s.fRenderTarget.get());
|
||||
fCommon = s.fCommon;
|
||||
fVertexAttribs = s.fVertexAttribs;
|
||||
for (int i = 0; i < kAttribIndexCount; i++) {
|
||||
fAttribIndices[i] = s.fAttribIndices[i];
|
||||
}
|
||||
for (int i = 0; i < kNumStages; i++) {
|
||||
if (s.isStageEnabled(i)) {
|
||||
this->fStages[i] = s.fStages[i];
|
||||
@ -1013,44 +1110,33 @@ private:
|
||||
/** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
|
||||
struct CommonState {
|
||||
// These fields are roughly sorted by decreasing likelihood of being different in op==
|
||||
GrColor fColor;
|
||||
SkMatrix fViewMatrix;
|
||||
GrBlendCoeff fSrcBlend;
|
||||
GrBlendCoeff fDstBlend;
|
||||
GrColor fBlendConstant;
|
||||
uint32_t fFlagBits;
|
||||
GrVertexAttribArray<kMaxVertexAttribCnt> fVertexAttribs;
|
||||
GrStencilSettings fStencilSettings;
|
||||
int fFirstCoverageStage;
|
||||
GrColor fCoverage;
|
||||
SkXfermode::Mode fColorFilterMode;
|
||||
GrColor fColorFilterColor;
|
||||
DrawFace fDrawFace;
|
||||
|
||||
// This is simply a different representation of info in fVertexAttribs and thus does
|
||||
// not need to be compared in op==.
|
||||
int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
|
||||
|
||||
GR_STATIC_ASSERT(kGrVertexAttribBindingCnt <= 8*sizeof(uint32_t));
|
||||
|
||||
GrColor fColor;
|
||||
GrAttribBindings fAttribBindings;
|
||||
SkMatrix fViewMatrix;
|
||||
GrBlendCoeff fSrcBlend;
|
||||
GrBlendCoeff fDstBlend;
|
||||
GrColor fBlendConstant;
|
||||
uint32_t fFlagBits;
|
||||
GrStencilSettings fStencilSettings;
|
||||
int fFirstCoverageStage;
|
||||
GrColor fCoverage;
|
||||
SkXfermode::Mode fColorFilterMode;
|
||||
GrColor fColorFilterColor;
|
||||
DrawFace fDrawFace;
|
||||
bool operator== (const CommonState& other) const {
|
||||
bool result = fColor == other.fColor &&
|
||||
fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
|
||||
fSrcBlend == other.fSrcBlend &&
|
||||
fDstBlend == other.fDstBlend &&
|
||||
fBlendConstant == other.fBlendConstant &&
|
||||
fFlagBits == other.fFlagBits &&
|
||||
fVertexAttribs == other.fVertexAttribs &&
|
||||
fStencilSettings == other.fStencilSettings &&
|
||||
fFirstCoverageStage == other.fFirstCoverageStage &&
|
||||
fCoverage == other.fCoverage &&
|
||||
fColorFilterMode == other.fColorFilterMode &&
|
||||
fColorFilterColor == other.fColorFilterColor &&
|
||||
fDrawFace == other.fDrawFace;
|
||||
GrAssert(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices,
|
||||
other.fFixedFunctionVertexAttribIndices,
|
||||
sizeof(fFixedFunctionVertexAttribIndices)));
|
||||
return result;
|
||||
return fColor == other.fColor &&
|
||||
fAttribBindings == other.fAttribBindings &&
|
||||
fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
|
||||
fSrcBlend == other.fSrcBlend &&
|
||||
fDstBlend == other.fDstBlend &&
|
||||
fBlendConstant == other.fBlendConstant &&
|
||||
fFlagBits == other.fFlagBits &&
|
||||
fStencilSettings == other.fStencilSettings &&
|
||||
fFirstCoverageStage == other.fFirstCoverageStage &&
|
||||
fCoverage == other.fCoverage &&
|
||||
fColorFilterMode == other.fColorFilterMode &&
|
||||
fColorFilterColor == other.fColorFilterColor &&
|
||||
fDrawFace == other.fDrawFace;
|
||||
}
|
||||
bool operator!= (const CommonState& other) const { return !(*this == other); }
|
||||
};
|
||||
@ -1083,6 +1169,10 @@ public:
|
||||
// TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
|
||||
fRenderTarget = drawState.fRenderTarget.get();
|
||||
SkSafeRef(fRenderTarget);
|
||||
fVertexAttribs = drawState.fVertexAttribs;
|
||||
for (int i = 0; i < kAttribIndexCount; i++) {
|
||||
fAttribIndices[i] = drawState.fAttribIndices[i];
|
||||
}
|
||||
// Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
|
||||
// ref gets fully unref'ed it will cause the underlying effect to unref its resources
|
||||
// and recycle them to the cache (if no one else is holding a ref to the resources).
|
||||
@ -1096,6 +1186,10 @@ public:
|
||||
GrAssert(fInitialized);
|
||||
drawState->fCommon = fCommon;
|
||||
drawState->setRenderTarget(fRenderTarget);
|
||||
drawState->fVertexAttribs = fVertexAttribs;
|
||||
for (int i = 0; i < kAttribIndexCount; i++) {
|
||||
drawState->fAttribIndices[i] = fAttribIndices[i];
|
||||
}
|
||||
for (int i = 0; i < kNumStages; ++i) {
|
||||
fStages[i].restoreTo(&drawState->fStages[i]);
|
||||
}
|
||||
@ -1105,6 +1199,16 @@ public:
|
||||
if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < kAttribIndexCount; ++i) {
|
||||
if ((i == kPosition_AttribIndex ||
|
||||
state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
|
||||
fAttribIndices[i] != state.fAttribIndices[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (fVertexAttribs != state.fVertexAttribs) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < kNumStages; ++i) {
|
||||
if (!fStages[i].isEqual(state.fStages[i])) {
|
||||
return false;
|
||||
@ -1116,15 +1220,22 @@ public:
|
||||
private:
|
||||
GrRenderTarget* fRenderTarget;
|
||||
CommonState fCommon;
|
||||
int fAttribIndices[kAttribIndexCount];
|
||||
GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
|
||||
GrEffectStage::DeferredStage fStages[kNumStages];
|
||||
|
||||
GR_DEBUGCODE(bool fInitialized;)
|
||||
};
|
||||
|
||||
private:
|
||||
// helper array to let us check the current bindings so we know what bound attrib indices
|
||||
// we care about
|
||||
static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
|
||||
|
||||
SkAutoTUnref<GrRenderTarget> fRenderTarget;
|
||||
CommonState fCommon;
|
||||
int fAttribIndices[kAttribIndexCount];
|
||||
GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
|
||||
GrEffectStage fStages[kNumStages];
|
||||
|
||||
typedef GrRefCnt INHERITED;
|
||||
|
@ -615,15 +615,18 @@ void GrDrawTarget::drawRect(const GrRect& rect,
|
||||
const SkMatrix* matrix,
|
||||
const GrRect* localRect,
|
||||
const SkMatrix* localMatrix) {
|
||||
GrAttribBindings bindings = 0;
|
||||
// position + (optional) texture coord
|
||||
static const GrVertexAttrib kAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
int attribCount = 1;
|
||||
|
||||
if (NULL != localRect) {
|
||||
bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
|
||||
attribCount = 2;
|
||||
this->drawState()->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, 1);
|
||||
}
|
||||
|
||||
GrDrawState::AutoViewMatrixRestore avmr;
|
||||
@ -632,6 +635,8 @@ void GrDrawTarget::drawRect(const GrRect& rect,
|
||||
}
|
||||
|
||||
this->drawState()->setVertexAttribs(kAttribs, attribCount);
|
||||
this->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
this->drawState()->setAttribBindings(bindings);
|
||||
AutoReleaseGeometry geo(this, 4, 0);
|
||||
if (!geo.succeeded()) {
|
||||
GrPrintf("Failed to get space for vertices!\n");
|
||||
|
@ -77,21 +77,22 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
const SkMatrix* matrix,
|
||||
const GrRect* localRect,
|
||||
const SkMatrix* localMatrix) {
|
||||
|
||||
GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
|
||||
GrDrawState::AutoColorRestore acr;
|
||||
|
||||
GrDrawState* drawState = this->drawState();
|
||||
|
||||
GrColor color = drawState->getColor();
|
||||
GrVertexAttribArray<3> attribs;
|
||||
size_t currentOffset = 0;
|
||||
int colorOffset = -1, localOffset = -1;
|
||||
|
||||
// set position attrib
|
||||
static const GrVertexAttrib kPosAttrib =
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
|
||||
attribs.push_back(kPosAttrib);
|
||||
|
||||
size_t currentOffset = sizeof(GrPoint);
|
||||
int colorOffset = -1;
|
||||
int localOffset = -1;
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
|
||||
GrVertexAttrib currAttrib = {kVec2f_GrVertexAttribType, currentOffset};
|
||||
attribs.push_back(currAttrib);
|
||||
currentOffset += sizeof(GrPoint);
|
||||
|
||||
// Using per-vertex colors allows batching across colors. (A lot of rects in a row differing
|
||||
// only in color is a common occurrence in tables). However, having per-vertex colors disables
|
||||
@ -99,11 +100,13 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
// optimizations help determine whether coverage and color can be blended correctly when
|
||||
// dual-source blending isn't available. This comes into play when there is coverage. If colors
|
||||
// were a stage it could take a hint that every vertex's color will be opaque.
|
||||
if (this->caps()->dualSourceBlendingSupport() || drawState->hasSolidCoverage()) {
|
||||
if (this->caps()->dualSourceBlendingSupport() ||
|
||||
drawState->hasSolidCoverage(drawState->getAttribBindings())) {
|
||||
bindings |= GrDrawState::kColor_AttribBindingsBit;
|
||||
drawState->setAttribIndex(GrDrawState::kColor_AttribIndex, attribs.count());
|
||||
currAttrib.set(kVec4ub_GrVertexAttribType, currentOffset);
|
||||
attribs.push_back(currAttrib);
|
||||
colorOffset = currentOffset;
|
||||
GrVertexAttrib colorAttrib =
|
||||
{kVec4ub_GrVertexAttribType, colorOffset, kColor_GrVertexAttribBinding};
|
||||
attribs.push_back(colorAttrib);
|
||||
currentOffset += sizeof(GrColor);
|
||||
// We set the draw state's color to white here. This is done so that any batching performed
|
||||
// in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color
|
||||
@ -113,14 +116,16 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
}
|
||||
|
||||
if (NULL != localRect) {
|
||||
bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
|
||||
drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
|
||||
currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
|
||||
attribs.push_back(currAttrib);
|
||||
localOffset = currentOffset;
|
||||
GrVertexAttrib localCoordAttrib =
|
||||
{kVec2f_GrVertexAttribType, localOffset, kLocalCoord_GrVertexAttribBinding};
|
||||
attribs.push_back(localCoordAttrib);
|
||||
currentOffset += sizeof(GrPoint);
|
||||
}
|
||||
|
||||
drawState->setVertexAttribs(attribs.begin(), attribs.count());
|
||||
drawState->setAttribBindings(bindings);
|
||||
AutoReleaseGeometry geo(this, 4, 0);
|
||||
if (!geo.succeeded()) {
|
||||
GrPrintf("Failed to get space for vertices!\n");
|
||||
|
@ -85,10 +85,11 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec4f_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
GrAssert(sizeof(CircleVertex) == drawState->getVertexSize());
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
|
||||
@ -107,6 +108,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
|
||||
// (kPathMaskStage in GrSWMaskHelper)
|
||||
kEdgeEffectStage = GrPaint::kTotalStages,
|
||||
};
|
||||
drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
|
||||
|
||||
GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked);
|
||||
static const int kCircleEdgeAttrIndex = 1;
|
||||
@ -183,11 +185,12 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding},
|
||||
{kVec4f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint)},
|
||||
{kVec4f_GrVertexAttribType, 2*sizeof(GrPoint)}
|
||||
};
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize());
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
|
||||
@ -206,6 +209,7 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target,
|
||||
// (kPathMaskStage in GrSWMaskHelper)
|
||||
kEdgeEffectStage = GrPaint::kTotalStages,
|
||||
};
|
||||
drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
|
||||
|
||||
GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked);
|
||||
static const int kEllipseCenterAttrIndex = 1;
|
||||
|
@ -194,9 +194,10 @@ HAS_ATLAS:
|
||||
if (NULL == fVertices) {
|
||||
// position + texture coord
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
|
||||
{kVec2f_GrVertexAttribType, 0},
|
||||
{kVec2f_GrVertexAttribType, sizeof(GrPoint)}
|
||||
};
|
||||
static const GrAttribBindings kAttribBindings = 0;
|
||||
|
||||
// If we need to reserve vertices allow the draw target to suggest
|
||||
// a number of verts to reserve and whether to perform a flush.
|
||||
@ -214,6 +215,8 @@ HAS_ATLAS:
|
||||
fDrawTarget = fContext->getTextTarget(fPaint);
|
||||
fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
}
|
||||
fDrawTarget->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
fDrawTarget->drawState()->setAttribBindings(kAttribBindings);
|
||||
fMaxVertices = kDefaultRequestedVerts;
|
||||
// ignore return, no point in flushing again.
|
||||
fDrawTarget->geometryHints(&fMaxVertices, NULL);
|
||||
|
@ -705,17 +705,14 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
|
||||
GL_CALL(BindAttribLocation(fProgramID,
|
||||
fDesc.fPositionAttributeIndex,
|
||||
builder.positionAttribute().c_str()));
|
||||
if (-1 != fDesc.fLocalCoordAttributeIndex) {
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fColorAttributeIndex, COL_ATTR_NAME));
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fCoverageAttributeIndex, COV_ATTR_NAME));
|
||||
|
||||
if (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
|
||||
GL_CALL(BindAttribLocation(fProgramID,
|
||||
fDesc.fLocalCoordAttributeIndex,
|
||||
fDesc.fLocalCoordsAttributeIndex,
|
||||
builder.localCoordsAttribute().c_str()));
|
||||
}
|
||||
if (-1 != fDesc.fColorAttributeIndex) {
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fColorAttributeIndex, COL_ATTR_NAME));
|
||||
}
|
||||
if (-1 != fDesc.fCoverageAttributeIndex) {
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fCoverageAttributeIndex, COV_ATTR_NAME));
|
||||
}
|
||||
|
||||
const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end();
|
||||
for (const GrGLShaderBuilder::AttributePair* attrib = builder.getEffectAttributes().begin();
|
||||
@ -829,7 +826,8 @@ void GrGLProgram::setData(GrGpuGL* gpu,
|
||||
const GrEffectStage& stage = drawState.getStage(s);
|
||||
GrAssert(NULL != stage.getEffect());
|
||||
|
||||
bool explicitLocalCoords = -1 != fDesc.fLocalCoordAttributeIndex;
|
||||
bool explicitLocalCoords =
|
||||
(fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
|
||||
GrDrawEffect drawEffect(stage, explicitLocalCoords);
|
||||
fEffects[s]->setData(fUniformManager, drawEffect);
|
||||
int numSamplers = fUniformHandles.fEffectSamplerUnis[s].count();
|
||||
@ -849,18 +847,15 @@ void GrGLProgram::setData(GrGpuGL* gpu,
|
||||
void GrGLProgram::setColor(const GrDrawState& drawState,
|
||||
GrColor color,
|
||||
SharedGLState* sharedState) {
|
||||
if (!drawState.hasColorVertexAttribute()) {
|
||||
if (!(drawState.getAttribBindings() & GrDrawState::kColor_AttribBindingsBit)) {
|
||||
switch (fDesc.fColorInput) {
|
||||
case GrGLProgramDesc::kAttribute_ColorInput:
|
||||
GrAssert(-1 != fDesc.fColorAttributeIndex);
|
||||
if (sharedState->fConstAttribColor != color ||
|
||||
sharedState->fConstAttribColorIndex != fDesc.fColorAttributeIndex) {
|
||||
if (sharedState->fConstAttribColor != color) {
|
||||
// OpenGL ES only supports the float varieties of glVertexAttrib
|
||||
GrGLfloat c[4];
|
||||
GrColorToRGBAFloat(color, c);
|
||||
GL_CALL(VertexAttrib4fv(fDesc.fColorAttributeIndex, c));
|
||||
sharedState->fConstAttribColor = color;
|
||||
sharedState->fConstAttribColorIndex = fDesc.fColorAttributeIndex;
|
||||
}
|
||||
break;
|
||||
case GrGLProgramDesc::kUniform_ColorInput:
|
||||
@ -873,34 +868,28 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
|
||||
fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
|
||||
fColor = color;
|
||||
}
|
||||
sharedState->fConstAttribColorIndex = -1;
|
||||
break;
|
||||
case GrGLProgramDesc::kSolidWhite_ColorInput:
|
||||
case GrGLProgramDesc::kTransBlack_ColorInput:
|
||||
sharedState->fConstAttribColorIndex = -1;
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unknown color type.");
|
||||
}
|
||||
} else {
|
||||
sharedState->fConstAttribColorIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgram::setCoverage(const GrDrawState& drawState,
|
||||
GrColor coverage,
|
||||
SharedGLState* sharedState) {
|
||||
if (!drawState.hasCoverageVertexAttribute()) {
|
||||
if (!(drawState.getAttribBindings() & GrDrawState::kCoverage_AttribBindingsBit)) {
|
||||
switch (fDesc.fCoverageInput) {
|
||||
case GrGLProgramDesc::kAttribute_ColorInput:
|
||||
if (sharedState->fConstAttribCoverage != coverage ||
|
||||
sharedState->fConstAttribCoverageIndex != fDesc.fCoverageAttributeIndex) {
|
||||
if (sharedState->fConstAttribCoverage != coverage) {
|
||||
// OpenGL ES only supports the float varieties of glVertexAttrib
|
||||
GrGLfloat c[4];
|
||||
GrColorToRGBAFloat(coverage, c);
|
||||
GL_CALL(VertexAttrib4fv(fDesc.fCoverageAttributeIndex, c));
|
||||
sharedState->fConstAttribCoverage = coverage;
|
||||
sharedState->fConstAttribCoverageIndex = fDesc.fCoverageAttributeIndex;
|
||||
}
|
||||
break;
|
||||
case GrGLProgramDesc::kUniform_ColorInput:
|
||||
@ -913,17 +902,13 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
|
||||
fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c);
|
||||
fCoverage = coverage;
|
||||
}
|
||||
sharedState->fConstAttribCoverageIndex = -1;
|
||||
break;
|
||||
case GrGLProgramDesc::kSolidWhite_ColorInput:
|
||||
case GrGLProgramDesc::kTransBlack_ColorInput:
|
||||
sharedState->fConstAttribCoverageIndex = -1;
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unknown coverage type.");
|
||||
}
|
||||
} else {
|
||||
sharedState->fConstAttribCoverageIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,23 +60,18 @@ public:
|
||||
GrGLuint programID() const { return fProgramID; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
* GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state
|
||||
* redundantly.
|
||||
* Some GL state that is relevant to programs is not stored per-program. In particular vertex
|
||||
* attributes are global state. This struct is read and updated by GrGLProgram::setData to
|
||||
* allow us to avoid setting this state redundantly.
|
||||
*/
|
||||
struct SharedGLState {
|
||||
GrColor fConstAttribColor;
|
||||
int fConstAttribColorIndex;
|
||||
GrColor fConstAttribCoverage;
|
||||
int fConstAttribCoverageIndex;
|
||||
|
||||
SharedGLState() { this->invalidate(); }
|
||||
void invalidate() {
|
||||
fConstAttribColor = GrColor_ILLEGAL;
|
||||
fConstAttribColorIndex = -1;
|
||||
fConstAttribCoverage = GrColor_ILLEGAL;
|
||||
fConstAttribCoverageIndex = -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,42 +34,49 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
||||
// bindings in use or other descriptor field settings) it should be set
|
||||
// to a canonical value to avoid duplicate programs with different keys.
|
||||
|
||||
// Must initialize all fields or cache will have false negatives!
|
||||
desc->fAttribBindings = drawState.getAttribBindings();
|
||||
|
||||
desc->fEmitsPointSize = isPoints;
|
||||
|
||||
bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute();
|
||||
bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAttribute();
|
||||
// we only need the local coords if we're actually going to generate effect code
|
||||
bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) &&
|
||||
drawState.hasLocalCoordAttribute();
|
||||
bool requiresAttributeColors =
|
||||
!skipColor && SkToBool(desc->fAttribBindings & GrDrawState::kColor_AttribBindingsBit);
|
||||
bool requiresAttributeCoverage =
|
||||
!skipCoverage && SkToBool(desc->fAttribBindings & GrDrawState::kCoverage_AttribBindingsBit);
|
||||
|
||||
// fColorInput/fCoverageInput records how colors are specified for the program so we strip the
|
||||
// bits from the bindings to avoid false negatives when searching for an existing program in the
|
||||
// cache.
|
||||
desc->fAttribBindings &=
|
||||
~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribBindingsBit);
|
||||
|
||||
desc->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState.getColorFilterMode();
|
||||
|
||||
// no reason to do edge aa or look at per-vertex coverage if coverage is ignored
|
||||
if (skipCoverage) {
|
||||
desc->fAttribBindings &= ~(GrDrawState::kCoverage_AttribBindingsBit);
|
||||
}
|
||||
|
||||
bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
|
||||
bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
|
||||
(!requiresColorAttrib && 0xffffffff == drawState.getColor());
|
||||
(!requiresAttributeColors && 0xffffffff == drawState.getColor());
|
||||
if (colorIsTransBlack) {
|
||||
desc->fColorInput = kTransBlack_ColorInput;
|
||||
} else if (colorIsSolidWhite) {
|
||||
desc->fColorInput = kSolidWhite_ColorInput;
|
||||
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresColorAttrib) {
|
||||
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) {
|
||||
desc->fColorInput = kUniform_ColorInput;
|
||||
} else {
|
||||
desc->fColorInput = kAttribute_ColorInput;
|
||||
}
|
||||
|
||||
bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverage();
|
||||
bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState.getCoverage();
|
||||
|
||||
if (skipCoverage) {
|
||||
desc->fCoverageInput = kTransBlack_ColorInput;
|
||||
} else if (covIsSolidWhite) {
|
||||
desc->fCoverageInput = kSolidWhite_ColorInput;
|
||||
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresCoverageAttrib) {
|
||||
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) {
|
||||
desc->fCoverageInput = kUniform_ColorInput;
|
||||
} else {
|
||||
desc->fCoverageInput = kAttribute_ColorInput;
|
||||
@ -85,7 +92,9 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
||||
lastEnabledStage = s;
|
||||
const GrEffectRef& effect = *drawState.getStage(s).getEffect();
|
||||
const GrBackendEffectFactory& factory = effect->getFactory();
|
||||
GrDrawEffect drawEffect(drawState.getStage(s), requiresLocalCoordAttrib);
|
||||
bool explicitLocalCoords = (drawState.getAttribBindings() &
|
||||
GrDrawState::kLocalCoords_AttribBindingsBit);
|
||||
GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords);
|
||||
desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
|
||||
if (effect->willReadDst()) {
|
||||
readsDst = true;
|
||||
@ -130,7 +139,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
||||
firstCoverageStage = drawState.getFirstCoverageStage();
|
||||
hasCoverage = true;
|
||||
} else {
|
||||
hasCoverage = requiresCoverageAttrib;
|
||||
hasCoverage = requiresAttributeCoverage;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,27 +174,38 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
||||
}
|
||||
}
|
||||
|
||||
desc->fPositionAttributeIndex = drawState.positionAttributeIndex();
|
||||
desc->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex();
|
||||
|
||||
// For constant color and coverage we need an attribute with an index beyond those already set
|
||||
int availableAttributeIndex = drawState.getVertexAttribCount();
|
||||
if (requiresColorAttrib) {
|
||||
desc->fColorAttributeIndex = drawState.colorVertexAttributeIndex();
|
||||
} else if (GrGLProgramDesc::kAttribute_ColorInput == desc->fColorInput) {
|
||||
GrAssert(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
|
||||
desc->fColorAttributeIndex = availableAttributeIndex;
|
||||
availableAttributeIndex++;
|
||||
desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosition_AttribIndex);
|
||||
if (requiresAttributeColors) {
|
||||
desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColor_AttribIndex);
|
||||
} else {
|
||||
desc->fColorAttributeIndex = -1;
|
||||
desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue;
|
||||
}
|
||||
if (requiresAttributeCoverage) {
|
||||
desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kCoverage_AttribIndex);
|
||||
} else {
|
||||
desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribIndexValue;
|
||||
}
|
||||
if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
|
||||
desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState::kLocalCoords_AttribIndex);
|
||||
}
|
||||
|
||||
if (requiresCoverageAttrib) {
|
||||
desc->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex();
|
||||
} else if (GrGLProgramDesc::kAttribute_ColorInput == desc->fCoverageInput) {
|
||||
GrAssert(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
|
||||
desc->fCoverageAttributeIndex = availableAttributeIndex;
|
||||
} else {
|
||||
desc->fCoverageAttributeIndex = -1;
|
||||
#if GR_DEBUG
|
||||
// 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(GrGLAttribTypeToLayout(vertexAttribs[desc->fPositionAttributeIndex].fType).fCount == 2);
|
||||
if (requiresAttributeColors) {
|
||||
GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fColorAttributeIndex].fType).fCount == 4);
|
||||
}
|
||||
if (requiresAttributeCoverage) {
|
||||
GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fCoverageAttributeIndex].fType).fCount == 4);
|
||||
}
|
||||
if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
|
||||
GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fLocalCoordsAttributeIndex].fType).fCount == 2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -39,8 +39,7 @@ public:
|
||||
void setRandom(SkMWCRandom*,
|
||||
const GrGpuGL* gpu,
|
||||
const GrTexture* dummyDstTexture,
|
||||
const GrEffectStage stages[GrDrawState::kNumStages],
|
||||
int currAttribIndex);
|
||||
const GrEffectStage stages[GrDrawState::kNumStages]);
|
||||
|
||||
/**
|
||||
* Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
|
||||
@ -77,34 +76,35 @@ private:
|
||||
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
|
||||
|
||||
// To enable experimental geometry shader code (not for use in
|
||||
// production)
|
||||
#if GR_GL_EXPERIMENTAL_GS
|
||||
bool fExperimentalGS;
|
||||
#endif
|
||||
GrGLShaderBuilder::DstReadKey fDstRead; // set by GrGLShaderBuilder if there
|
||||
// are effects that must read the dst.
|
||||
// Otherwise, 0.
|
||||
|
||||
// should the FS discard if the coverage is zero (to avoid stencil manipulation)
|
||||
SkBool8 fDiscardIfZeroCoverage;
|
||||
|
||||
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 fLocalCoordAttributeIndex;
|
||||
int8_t fColorAttributeIndex;
|
||||
int8_t fCoverageAttributeIndex;
|
||||
int8_t fLocalCoordsAttributeIndex;
|
||||
|
||||
// GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Move all
|
||||
// code generation to GrGLShaderBuilder (and maybe add getters rather than friending).
|
||||
|
@ -67,6 +67,15 @@ bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, const char* nameIfDeclared, G
|
||||
return declaredOutput;
|
||||
}
|
||||
|
||||
GrSLType GrSLFloatVectorType (int count) {
|
||||
GR_STATIC_ASSERT(kFloat_GrSLType == 1);
|
||||
GR_STATIC_ASSERT(kVec2f_GrSLType == 2);
|
||||
GR_STATIC_ASSERT(kVec3f_GrSLType == 3);
|
||||
GR_STATIC_ASSERT(kVec4f_GrSLType == 4);
|
||||
GrAssert(count > 0 && count <= 4);
|
||||
return (GrSLType)(count);
|
||||
}
|
||||
|
||||
const char* GrGLSLVectorHomogCoord(int count) {
|
||||
static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
|
||||
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
|
||||
|
@ -117,7 +117,7 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
|
||||
|
||||
fPositionVar = &fVSAttrs.push_back();
|
||||
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
|
||||
if (-1 != desc.fLocalCoordAttributeIndex) {
|
||||
if (desc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
|
||||
fLocalCoordsVar = &fVSAttrs.push_back();
|
||||
fLocalCoordsVar->set(kVec2f_GrSLType,
|
||||
GrGLShaderVar::kAttribute_TypeModifier,
|
||||
|
@ -180,7 +180,9 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
|
||||
|
||||
fProgramCache = SkNEW_ARGS(ProgramCache, (this->glContext()));
|
||||
|
||||
GrAssert(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt);
|
||||
GrAssert(this->glCaps().maxVertexAttributes() >= GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(this->glCaps().maxVertexAttributes() > GrDrawState::kColorOverrideAttribIndexValue);
|
||||
GrAssert(this->glCaps().maxVertexAttributes() > GrDrawState::kCoverageOverrideAttribIndexValue);
|
||||
|
||||
fLastSuccessfulStencilFmtIdx = 0;
|
||||
if (false) { // avoid bit rot, suppress warning
|
||||
|
@ -77,4 +77,5 @@ void gr_run_unittests() {
|
||||
GR_DEBUGCODE(test_bsearch();)
|
||||
test_binHashKey();
|
||||
GrRedBlackTree<int>::UnitTest();
|
||||
GrDrawState::VertexAttributesUnitTest();
|
||||
}
|
||||
|
@ -24,30 +24,18 @@
|
||||
void GrGLProgramDesc::setRandom(SkMWCRandom* random,
|
||||
const GrGpuGL* gpu,
|
||||
const GrTexture* dstTexture,
|
||||
const GrEffectStage stages[GrDrawState::kNumStages],
|
||||
int currAttribIndex) {
|
||||
const GrEffectStage stages[GrDrawState::kNumStages]) {
|
||||
fAttribBindings = 0;
|
||||
fEmitsPointSize = random->nextBool();
|
||||
|
||||
fPositionAttributeIndex = 0;
|
||||
|
||||
// if the effects have used up all off the available attributes,
|
||||
// don't try to use color or coverage attributes as input
|
||||
do {
|
||||
fColorInput = random->nextULessThan(kColorInputCnt);
|
||||
} while (GrDrawState::kMaxVertexAttribCnt <= currAttribIndex &&
|
||||
kAttribute_ColorInput == fColorInput);
|
||||
fColorAttributeIndex = (fColorInput == kAttribute_ColorInput) ? currAttribIndex++ : -1;
|
||||
|
||||
do {
|
||||
fCoverageInput = random->nextULessThan(kColorInputCnt);
|
||||
} while (GrDrawState::kMaxVertexAttribCnt <= currAttribIndex &&
|
||||
kAttribute_ColorInput == fCoverageInput);
|
||||
fCoverageAttributeIndex = (fCoverageInput == kAttribute_ColorInput) ? currAttribIndex++ : -1;
|
||||
fColorInput = random->nextULessThan(kColorInputCnt);
|
||||
fCoverageInput = random->nextULessThan(kColorInputCnt);
|
||||
|
||||
fColorFilterXfermode = random->nextULessThan(SkXfermode::kCoeffModesCnt);
|
||||
|
||||
fFirstCoverageStage = random->nextULessThan(GrDrawState::kNumStages);
|
||||
|
||||
fAttribBindings |= random->nextBool() ? GrDrawState::kCoverage_AttribBindingsBit : 0;
|
||||
|
||||
#if GR_GL_EXPERIMENTAL_GS
|
||||
fExperimentalGS = gpu->caps()->geometryShaderSupport() && random->nextBool();
|
||||
#endif
|
||||
@ -60,14 +48,18 @@ void GrGLProgramDesc::setRandom(SkMWCRandom* random,
|
||||
fDualSrcOutput = kNone_DualSrcOutput;
|
||||
}
|
||||
|
||||
bool useLocalCoords = random->nextBool() && currAttribIndex < GrDrawState::kMaxVertexAttribCnt;
|
||||
fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1;
|
||||
// use separate tex coords?
|
||||
if (random->nextBool()) {
|
||||
fAttribBindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
|
||||
}
|
||||
|
||||
bool dstRead = false;
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
if (NULL != stages[s].getEffect()) {
|
||||
const GrBackendEffectFactory& factory = (*stages[s].getEffect())->getFactory();
|
||||
GrDrawEffect drawEffect(stages[s], useLocalCoords);
|
||||
bool explicitLocalCoords = (fAttribBindings &
|
||||
GrDrawState::kLocalCoords_AttribBindingsBit);
|
||||
GrDrawEffect drawEffect(stages[s], explicitLocalCoords);
|
||||
fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
|
||||
if ((*stages[s].getEffect())->willReadDst()) {
|
||||
dstRead = true;
|
||||
@ -78,6 +70,22 @@ void GrGLProgramDesc::setRandom(SkMWCRandom* random,
|
||||
if (dstRead) {
|
||||
this->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstTexture, gpu->glCaps());
|
||||
}
|
||||
|
||||
int attributeIndex = 0;
|
||||
fPositionAttributeIndex = attributeIndex;
|
||||
++attributeIndex;
|
||||
if (fColorInput || (fAttribBindings & GrDrawState::kColor_AttribBindingsBit)) {
|
||||
fColorAttributeIndex = attributeIndex;
|
||||
++attributeIndex;
|
||||
}
|
||||
if (fCoverageInput || (fAttribBindings & GrDrawState::kCoverage_AttribBindingsBit)) {
|
||||
fCoverageAttributeIndex = attributeIndex;
|
||||
++attributeIndex;
|
||||
}
|
||||
if (fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
|
||||
fLocalCoordsAttributeIndex = attributeIndex;
|
||||
++attributeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGpuGL::programUnitTest(int maxStages) {
|
||||
@ -110,7 +118,7 @@ bool GrGpuGL::programUnitTest(int maxStages) {
|
||||
GrGLProgramDesc pdesc;
|
||||
GrEffectStage stages[GrDrawState::kNumStages];
|
||||
|
||||
int currAttribIndex = 1; // we need to always leave room for position
|
||||
int currAttribIndex = GrDrawState::kAttribIndexCount;
|
||||
int attribIndices[2];
|
||||
GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
|
||||
for (int s = 0; s < maxStages; ++s) {
|
||||
@ -123,9 +131,10 @@ bool GrGpuGL::programUnitTest(int maxStages) {
|
||||
dummyTextures));
|
||||
int numAttribs = (*effect)->numVertexAttribs();
|
||||
|
||||
// If adding this effect would exceed the max attrib count then generate a
|
||||
// new random effect.
|
||||
if (currAttribIndex + numAttribs > GrDrawState::kMaxVertexAttribCnt) {
|
||||
// If adding this effect would cause to exceed the max attrib count then generate a
|
||||
// new random effect. The explanation for why this check is correct is a bit
|
||||
// convoluted and this code will be removed soon.
|
||||
if (currAttribIndex + numAttribs > GrDrawState::kCoverageOverrideAttribIndexValue) {
|
||||
--s;
|
||||
continue;
|
||||
}
|
||||
@ -136,8 +145,8 @@ bool GrGpuGL::programUnitTest(int maxStages) {
|
||||
}
|
||||
}
|
||||
const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dummyTextures[1];
|
||||
pdesc.setRandom(&random, this, dstTexture, stages, currAttribIndex);
|
||||
|
||||
pdesc.setRandom(&random, this, dstTexture, stages);
|
||||
|
||||
const GrEffectStage* stagePtrs[GrDrawState::kNumStages];
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
stagePtrs[s] = &stages[s];
|
||||
|
Loading…
Reference in New Issue
Block a user