зеркало из https://github.com/mozilla/moz-skia.git
Revert r7901 & r7899 to allow DEPS roll
git-svn-id: http://skia.googlecode.com/svn/trunk@7909 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
2b1b8c083b
Коммит
af3a3b9fb1
|
@ -36,25 +36,12 @@ bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,
|
|||
android::uirenderer::PathRenderer::ConvexPathVertices(origPath, stroke, antiAlias, NULL,
|
||||
&vertices);
|
||||
|
||||
// set vertex attributes depending on anti-alias
|
||||
GrDrawState* drawState = target->drawState();
|
||||
if (antiAlias) {
|
||||
// position + coverage
|
||||
GrVertexAttrib attribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec4ub_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
drawState->setVertexAttribs(attribs, SK_ARRAY_COUNT(attribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(GrDrawState::kCoverage_AttribIndex, 1);
|
||||
drawState->setAttribBindings(GrDrawState::kCoverage_AttribBindingsBit);
|
||||
} else {
|
||||
drawState->setDefaultVertexAttribs();
|
||||
}
|
||||
// set vertex layout depending on anti-alias
|
||||
GrVertexLayout layout = antiAlias ? GrDrawState::kCoverage_VertexLayoutBit : 0;
|
||||
|
||||
// allocate our vert buffer
|
||||
int vertCount = vertices.getSize();
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, vertCount, 0);
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, layout, vertCount, 0);
|
||||
if (!geo.succeeded()) {
|
||||
GrPrintf("Failed to get space for vertices!\n");
|
||||
return false;
|
||||
|
@ -62,7 +49,6 @@ bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,
|
|||
|
||||
// copy android verts to our vertex buffer
|
||||
if (antiAlias) {
|
||||
GrAssert(sizeof(ColorVertex) == drawState->getVertexSize());
|
||||
ColorVertex* outVert = reinterpret_cast<ColorVertex*>(geo.vertices());
|
||||
android::uirenderer::AlphaVertex* inVert =
|
||||
reinterpret_cast<android::uirenderer::AlphaVertex*>(vertices.getBuffer());
|
||||
|
@ -77,7 +63,7 @@ bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,
|
|||
++inVert;
|
||||
}
|
||||
} else {
|
||||
size_t vsize = drawState->getVertexSize();
|
||||
size_t vsize = GrDrawState::VertexSize(layout);
|
||||
size_t copySize = vsize*vertCount;
|
||||
memcpy(geo.vertices(), vertices.getBuffer(), copySize);
|
||||
}
|
||||
|
|
|
@ -111,11 +111,11 @@ bool GrStrokePathRenderer::onDrawPath(const SkPath& origPath,
|
|||
|
||||
// Allocate vertices
|
||||
const int nbQuads = origPath.countPoints() + 1; // Could be "-1" if path is not closed
|
||||
GrVertexLayout layout = 0; // Just 3D points
|
||||
const int extraVerts = isMiter || isBevel ? 1 : 0;
|
||||
const int maxVertexCount = nbQuads * (4 + extraVerts);
|
||||
const int maxIndexCount = nbQuads * (6 + extraVerts * 3); // Each extra vert adds a triangle
|
||||
target->drawState()->setDefaultVertexAttribs();
|
||||
GrDrawTarget::AutoReleaseGeometry arg(target, maxVertexCount, maxIndexCount);
|
||||
GrDrawTarget::AutoReleaseGeometry arg(target, layout, maxVertexCount, maxIndexCount);
|
||||
if (!arg.succeeded()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ bool GrStrokePathRenderer::onDrawPath(const SkPath& origPath,
|
|||
// Transform the path into a list of triangles
|
||||
SkPath::Iter iter(origPath, false);
|
||||
SkPoint pts[4];
|
||||
const SkScalar radius = SkScalarMul(width, 0.5f);
|
||||
const SkScalar radius = SkScalarMul(width, 0.5);
|
||||
SkPoint *firstPt = verts, *lastPt = NULL;
|
||||
SkVector firstDir, dir;
|
||||
firstDir.set(0, 0);
|
||||
|
|
|
@ -223,19 +223,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
T* begin() {
|
||||
return fItemArray;
|
||||
}
|
||||
const T* begin() const {
|
||||
return fItemArray;
|
||||
}
|
||||
T* end() {
|
||||
return fItemArray ? fItemArray + fCount : NULL;
|
||||
}
|
||||
const T* end() const {
|
||||
return fItemArray ? fItemArray + fCount : NULL;;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the i^th element.
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
|
||||
private:
|
||||
GrPaint fPaint;
|
||||
GrVertexLayout fVertexLayout;
|
||||
GrContext* fContext;
|
||||
GrDrawTarget* fDrawTarget;
|
||||
|
||||
|
|
|
@ -194,6 +194,12 @@ typedef intptr_t GrBackendContext;
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Type used to describe format of vertices in arrays
|
||||
* Values are defined in GrDrawTarget
|
||||
*/
|
||||
typedef int GrVertexLayout;
|
||||
|
||||
/**
|
||||
* Geometric primitives used for drawing.
|
||||
*/
|
||||
|
|
|
@ -453,6 +453,9 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
|
|||
}
|
||||
const SkMatrix* vm = &adcd.getOriginalMatrix();
|
||||
|
||||
GrVertexLayout layout = 0;
|
||||
layout |= GrDrawState::kEdge_VertexLayoutBit;
|
||||
|
||||
// We use the fact that SkPath::transform path does subdivision based on
|
||||
// perspective. Otherwise, we apply the view matrix when copying to the
|
||||
// segment representation.
|
||||
|
@ -478,22 +481,11 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
|
|||
return false;
|
||||
}
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec4f_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
static const GrAttribBindings bindings = GrDrawState::kEdge_AttribBindingsBit;
|
||||
|
||||
drawState->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(GrDrawState::kEdge_AttribIndex, 1);
|
||||
drawState->setAttribBindings(bindings);
|
||||
drawState->setVertexLayout(layout);
|
||||
GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount);
|
||||
if (!arg.succeeded()) {
|
||||
return false;
|
||||
}
|
||||
GrAssert(sizeof(QuadVertex) == drawState->getVertexSize());
|
||||
verts = reinterpret_cast<QuadVertex*>(arg.vertices());
|
||||
idxs = reinterpret_cast<uint16_t*>(arg.indices());
|
||||
|
||||
|
|
|
@ -495,20 +495,15 @@ bool GrAAHairLinePathRenderer::createGeom(
|
|||
int* lineCnt,
|
||||
int* quadCnt,
|
||||
GrDrawTarget::AutoReleaseGeometry* arg) {
|
||||
GrDrawState* drawState = target->drawState();
|
||||
int rtHeight = drawState->getRenderTarget()->height();
|
||||
const GrDrawState& drawState = target->getDrawState();
|
||||
int rtHeight = drawState.getRenderTarget()->height();
|
||||
|
||||
GrIRect devClipBounds;
|
||||
target->getClip()->getConservativeBounds(drawState->getRenderTarget(),
|
||||
target->getClip()->getConservativeBounds(drawState.getRenderTarget(),
|
||||
&devClipBounds);
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec4f_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
static const GrAttribBindings kBindings = GrDrawState::kEdge_AttribBindingsBit;
|
||||
SkMatrix viewM = drawState->getViewMatrix();
|
||||
GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit;
|
||||
SkMatrix viewM = drawState.getViewMatrix();
|
||||
|
||||
PREALLOC_PTARRAY(128) lines;
|
||||
PREALLOC_PTARRAY(128) quads;
|
||||
|
@ -519,10 +514,7 @@ bool GrAAHairLinePathRenderer::createGeom(
|
|||
*lineCnt = lines.count() / 2;
|
||||
int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
|
||||
|
||||
target->drawState()->setVertexAttribs(kAttribs, SK_ARRAY_COUNT(kAttribs));
|
||||
target->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
target->drawState()->setAttribIndex(GrDrawState::kEdge_AttribIndex, 1);
|
||||
target->drawState()->setAttribBindings(kBindings);
|
||||
target->drawState()->setVertexLayout(layout);
|
||||
GrAssert(sizeof(Vertex) == target->getDrawState().getVertexSize());
|
||||
|
||||
if (!arg->set(target, vertCnt, 0)) {
|
||||
|
|
|
@ -13,15 +13,14 @@ SK_DEFINE_INST_COUNT(GrAARectRenderer)
|
|||
|
||||
namespace {
|
||||
|
||||
static void aa_rect_attributes(bool useCoverage, GrAttribBindings* bindings,
|
||||
GrDrawState::AttribIndex* index) {
|
||||
static GrVertexLayout aa_rect_layout(bool useCoverage) {
|
||||
GrVertexLayout layout = 0;
|
||||
if (useCoverage) {
|
||||
*bindings = GrDrawState::kCoverage_AttribBindingsBit;
|
||||
*index = GrDrawState::kCoverage_AttribIndex;
|
||||
layout |= GrDrawState::kCoverage_VertexLayoutBit;
|
||||
} else {
|
||||
*bindings = GrDrawState::kColor_AttribBindingsBit;
|
||||
*index = GrDrawState::kColor_AttribIndex;
|
||||
layout |= GrDrawState::kColor_VertexLayoutBit;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
static void set_inset_fan(GrPoint* pts, size_t stride,
|
||||
|
@ -30,12 +29,6 @@ static void set_inset_fan(GrPoint* pts, size_t stride,
|
|||
r.fRight - dx, r.fBottom - dy, stride);
|
||||
}
|
||||
|
||||
// position + color/coverage
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec4ub_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void GrAARectRenderer::reset() {
|
||||
|
@ -132,15 +125,8 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
|
|||
GrDrawTarget* target,
|
||||
const GrRect& devRect,
|
||||
bool useVertexCoverage) {
|
||||
GrDrawState* drawState = target->drawState();
|
||||
|
||||
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);
|
||||
GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
|
||||
target->drawState()->setVertexLayout(layout);
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
|
||||
if (!geo.succeeded()) {
|
||||
|
@ -155,8 +141,7 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
|
|||
}
|
||||
|
||||
intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
|
||||
size_t vsize = drawState->getVertexSize();
|
||||
GrAssert(sizeof(GrPoint) + sizeof(GrColor) == vsize);
|
||||
size_t vsize = target->getDrawState().getVertexSize();
|
||||
|
||||
GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
|
||||
GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
|
||||
|
@ -192,8 +177,6 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu,
|
|||
const GrRect& devRect,
|
||||
const GrVec& devStrokeSize,
|
||||
bool useVertexCoverage) {
|
||||
GrDrawState* drawState = target->drawState();
|
||||
|
||||
const SkScalar& dx = devStrokeSize.fX;
|
||||
const SkScalar& dy = devStrokeSize.fY;
|
||||
const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
|
||||
|
@ -212,14 +195,8 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu,
|
|||
this->fillAARect(gpu, target, r, useVertexCoverage);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
|
||||
target->drawState()->setVertexLayout(layout);
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
|
||||
if (!geo.succeeded()) {
|
||||
|
@ -233,8 +210,7 @@ void GrAARectRenderer::strokeAARect(GrGpu* gpu,
|
|||
}
|
||||
|
||||
intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
|
||||
size_t vsize = drawState->getVertexSize();
|
||||
GrAssert(sizeof(GrPoint) + sizeof(GrColor) == vsize);
|
||||
size_t vsize = target->getDrawState().getVertexSize();
|
||||
|
||||
// We create vertices for four nested rectangles. There are two ramps from 0 to full
|
||||
// coverage, one on the exterior of the stroke and the other on the interior.
|
||||
|
|
|
@ -352,16 +352,8 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc,
|
|||
GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering);
|
||||
drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params);
|
||||
|
||||
// position + texture coordinate
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
static const GrAttribBindings kAttribBindings = GrDrawState::ExplicitTexCoordAttribBindingsBit(0);
|
||||
drawState->setAttribBindings(kAttribBindings);
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
|
||||
static const GrVertexLayout layout = GrDrawState::StageTexCoordVertexLayoutBit(0);
|
||||
drawState->setVertexLayout(layout);
|
||||
GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0);
|
||||
|
||||
if (arg.succeeded()) {
|
||||
|
@ -786,7 +778,7 @@ void GrContext::drawRect(const GrPaint& paint,
|
|||
// unitSquareVertexBuffer()
|
||||
|
||||
static const int worstCaseVertCount = 10;
|
||||
target->drawState()->setDefaultVertexAttribs();
|
||||
target->drawState()->setVertexLayout(GrDrawState::kDefault_VertexLayout);
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0);
|
||||
|
||||
if (!geo.succeeded()) {
|
||||
|
@ -829,7 +821,7 @@ void GrContext::drawRect(const GrPaint& paint,
|
|||
}
|
||||
|
||||
GrDrawState* drawState = target->drawState();
|
||||
target->drawState()->setDefaultVertexAttribs();
|
||||
drawState->setVertexLayout(GrDrawState::kDefault_VertexLayout);
|
||||
target->setVertexSourceToBuffer(sqVB);
|
||||
SkMatrix m;
|
||||
m.setAll(rect.width(), 0, rect.fLeft,
|
||||
|
@ -895,7 +887,7 @@ void GrContext::drawRectToRect(const GrPaint& paint,
|
|||
GrPrintf("Failed to create static rect vb.\n");
|
||||
return;
|
||||
}
|
||||
drawState->setDefaultVertexAttribs();
|
||||
drawState->setVertexLayout(GrDrawState::kDefault_VertexLayout);
|
||||
target->setVertexSourceToBuffer(sqVB);
|
||||
target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
|
||||
#else
|
||||
|
@ -920,55 +912,37 @@ void GrContext::drawVertices(const GrPaint& paint,
|
|||
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW);
|
||||
GrDrawState::AutoStageDisable atr(fDrawState);
|
||||
|
||||
GrDrawState* drawState = target->drawState();
|
||||
|
||||
GrVertexAttribArray<3> attribs;
|
||||
size_t currentOffset = 0;
|
||||
int colorOffset = -1, texOffset = -1;
|
||||
GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
|
||||
|
||||
// set position attribute
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
|
||||
attribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, currentOffset));
|
||||
currentOffset += sizeof(GrPoint);
|
||||
|
||||
// set up optional texture coordinate attributes
|
||||
GrVertexLayout layout = 0;
|
||||
if (NULL != texCoords) {
|
||||
bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(0);
|
||||
drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, attribs.count());
|
||||
attribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, currentOffset));
|
||||
texOffset = currentOffset;
|
||||
currentOffset += sizeof(GrPoint);
|
||||
layout |= GrDrawState::StageTexCoordVertexLayoutBit(0);
|
||||
}
|
||||
|
||||
// set up optional color attributes
|
||||
if (NULL != colors) {
|
||||
bindings |= GrDrawState::kColor_AttribBindingsBit;
|
||||
drawState->setAttribIndex(GrDrawState::kColor_AttribIndex, attribs.count());
|
||||
attribs.push_back(GrVertexAttrib(kVec4ub_GrVertexAttribType, currentOffset));
|
||||
colorOffset = currentOffset;
|
||||
currentOffset += sizeof(GrColor);
|
||||
layout |= GrDrawState::kColor_VertexLayoutBit;
|
||||
}
|
||||
target->drawState()->setVertexLayout(layout);
|
||||
|
||||
drawState->setVertexAttribs(attribs.begin(), attribs.count());
|
||||
drawState->setAttribBindings(bindings);
|
||||
|
||||
size_t vertexSize = drawState->getVertexSize();
|
||||
GrAssert(vertexSize == currentOffset);
|
||||
int vertexSize = target->getDrawState().getVertexSize();
|
||||
if (sizeof(GrPoint) != vertexSize) {
|
||||
if (!geo.set(target, vertexCount, 0)) {
|
||||
GrPrintf("Failed to get space for vertices!\n");
|
||||
return;
|
||||
}
|
||||
int texOffset;
|
||||
int colorOffset;
|
||||
GrDrawState::VertexSizeAndOffsets(layout,
|
||||
&texOffset,
|
||||
&colorOffset,
|
||||
NULL,
|
||||
NULL);
|
||||
void* curVertex = geo.vertices();
|
||||
|
||||
for (int i = 0; i < vertexCount; ++i) {
|
||||
*((GrPoint*)curVertex) = positions[i];
|
||||
|
||||
if (texOffset >= 0) {
|
||||
if (texOffset > 0) {
|
||||
*(GrPoint*)((intptr_t)curVertex + texOffset) = texCoords[i];
|
||||
}
|
||||
if (colorOffset >= 0) {
|
||||
if (colorOffset > 0) {
|
||||
*(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
|
||||
}
|
||||
curVertex = (void*)((intptr_t)curVertex + vertexSize);
|
||||
|
@ -1071,17 +1045,8 @@ void GrContext::internalDrawOval(const GrPaint& paint,
|
|||
return;
|
||||
}
|
||||
|
||||
// position + edge
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec4f_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
static const GrAttribBindings kAttributeBindings = GrDrawState::kEdge_AttribBindingsBit;
|
||||
|
||||
drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
drawState->setAttribIndex(GrDrawState::kEdge_AttribIndex, 1);
|
||||
drawState->setAttribBindings(kAttributeBindings);
|
||||
GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit;
|
||||
drawState->setVertexLayout(layout);
|
||||
GrAssert(sizeof(CircleVertex) == drawState->getVertexSize());
|
||||
|
||||
GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
|
||||
|
|
|
@ -211,6 +211,7 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path,
|
|||
return false;
|
||||
}
|
||||
|
||||
GrVertexLayout layout = 0;
|
||||
bool indexed = contourCnt > 1;
|
||||
|
||||
const bool isHairline = stroke.isHairlineStyle();
|
||||
|
@ -232,7 +233,7 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path,
|
|||
}
|
||||
}
|
||||
|
||||
target->drawState()->setDefaultVertexAttribs();
|
||||
target->drawState()->setVertexLayout(layout);
|
||||
if (!arg->set(target, maxPts, maxIdxs)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -57,150 +57,270 @@ namespace {
|
|||
* they were just a series of immediate->memory moves.)
|
||||
*
|
||||
*/
|
||||
void gen_tex_coord_mask(GrAttribBindings* texCoordMask) {
|
||||
void gen_tex_coord_mask(GrVertexLayout* texCoordMask) {
|
||||
*texCoordMask = 0;
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
*texCoordMask |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s);
|
||||
*texCoordMask |= GrDrawState::StageTexCoordVertexLayoutBit(s);
|
||||
}
|
||||
}
|
||||
|
||||
const GrAttribBindings kTexCoord_AttribBindingsMask = (1 << GrDrawState::kNumStages)-1;
|
||||
const GrVertexLayout kTexCoordMask = (1 << GrDrawState::kNumStages)-1;
|
||||
|
||||
inline int num_tex_coords(GrVertexLayout layout) {
|
||||
return (kTexCoordMask & layout) ? 1 : 0;
|
||||
}
|
||||
|
||||
} //unnamed namespace
|
||||
|
||||
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 const size_t kVec2Size = sizeof(GrPoint);
|
||||
|
||||
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::kAttribIndexCount);
|
||||
size_t size = 0;
|
||||
for (int index = 0; index < count; ++index) {
|
||||
size_t attribSize = GrDrawState::kVertexAttribSizes[attribs[index].fType];
|
||||
size += attribSize;
|
||||
#if GR_DEBUG
|
||||
size_t dwordCount = attribSize >> 2;
|
||||
uint32_t mask = (1 << dwordCount)-1;
|
||||
size_t offsetShift = attribs[index].fOffset >> 2;
|
||||
GrAssert(!(overlapCheck & (mask << offsetShift)));
|
||||
overlapCheck |= (mask << offsetShift);
|
||||
#endif
|
||||
size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) {
|
||||
size_t size = kVec2Size; // position
|
||||
size += num_tex_coords(vertexLayout) * kVec2Size;
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
size += sizeof(GrColor);
|
||||
}
|
||||
if (vertexLayout & kCoverage_VertexLayoutBit) {
|
||||
size += sizeof(GrColor);
|
||||
}
|
||||
if (vertexLayout & kEdge_VertexLayoutBit) {
|
||||
size += 4 * sizeof(SkScalar);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t GrDrawState::getVertexSize() const {
|
||||
return vertex_size(fVertexAttribs.begin(), fVertexAttribs.count());
|
||||
}
|
||||
|
||||
const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = {
|
||||
0, // position is not reflected in the bindings
|
||||
kColor_AttribBindingsBit,
|
||||
kCoverage_AttribBindingsBit,
|
||||
kEdge_AttribBindingsBit,
|
||||
kTexCoord_AttribBindingsMask
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
|
||||
GrAssert(count <= GrDrawState::kAttribIndexCount);
|
||||
fVertexAttribs.reset();
|
||||
for (int index = 0; index < count; ++index) {
|
||||
fVertexAttribs.push_back(attribs[index]);
|
||||
/**
|
||||
* Functions for computing offsets of various components from the layout
|
||||
* bitfield.
|
||||
*
|
||||
* Order of vertex components:
|
||||
* Position
|
||||
* Tex Coord
|
||||
* Color
|
||||
* Coverage
|
||||
*/
|
||||
|
||||
int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) {
|
||||
if (!StageUsesTexCoords(vertexLayout, stageIdx)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return kVec2Size;
|
||||
}
|
||||
|
||||
int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) {
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
return kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) {
|
||||
if (vertexLayout & kCoverage_VertexLayoutBit) {
|
||||
int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1);
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
offset += sizeof(GrColor);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) {
|
||||
// edge pts are after the pos, tex coords, and color
|
||||
if (vertexLayout & kEdge_VertexLayoutBit) {
|
||||
int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
offset += sizeof(GrColor);
|
||||
}
|
||||
if (vertexLayout & kCoverage_VertexLayoutBit) {
|
||||
offset += sizeof(GrColor);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GrDrawState::VertexSizeAndOffsets(
|
||||
GrVertexLayout vertexLayout,
|
||||
int* texCoordOffset,
|
||||
int* colorOffset,
|
||||
int* coverageOffset,
|
||||
int* edgeOffset) {
|
||||
int size = kVec2Size; // position
|
||||
|
||||
if (kTexCoordMask & vertexLayout) {
|
||||
if (NULL != texCoordOffset) {
|
||||
*texCoordOffset = size;
|
||||
}
|
||||
size += kVec2Size;
|
||||
} else {
|
||||
if (NULL != texCoordOffset) {
|
||||
*texCoordOffset = -1;
|
||||
}
|
||||
}
|
||||
if (kColor_VertexLayoutBit & vertexLayout) {
|
||||
if (NULL != colorOffset) {
|
||||
*colorOffset = size;
|
||||
}
|
||||
size += sizeof(GrColor);
|
||||
} else {
|
||||
if (NULL != colorOffset) {
|
||||
*colorOffset = -1;
|
||||
}
|
||||
}
|
||||
if (kCoverage_VertexLayoutBit & vertexLayout) {
|
||||
if (NULL != coverageOffset) {
|
||||
*coverageOffset = size;
|
||||
}
|
||||
size += sizeof(GrColor);
|
||||
} else {
|
||||
if (NULL != coverageOffset) {
|
||||
*coverageOffset = -1;
|
||||
}
|
||||
}
|
||||
if (kEdge_VertexLayoutBit & vertexLayout) {
|
||||
if (NULL != edgeOffset) {
|
||||
*edgeOffset = size;
|
||||
}
|
||||
size += 4 * sizeof(SkScalar);
|
||||
} else {
|
||||
if (NULL != edgeOffset) {
|
||||
*edgeOffset = -1;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int GrDrawState::VertexSizeAndOffsetsByStage(
|
||||
GrVertexLayout vertexLayout,
|
||||
int texCoordOffsetsByStage[GrDrawState::kNumStages],
|
||||
int* colorOffset,
|
||||
int* coverageOffset,
|
||||
int* edgeOffset) {
|
||||
|
||||
int texCoordOffset;
|
||||
int size = VertexSizeAndOffsets(vertexLayout,
|
||||
&texCoordOffset,
|
||||
colorOffset,
|
||||
coverageOffset,
|
||||
edgeOffset);
|
||||
if (NULL != texCoordOffsetsByStage) {
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
texCoordOffsetsByStage[s] = StageUsesTexCoords(vertexLayout, s) ?
|
||||
texCoordOffset : 0;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDrawState::setDefaultVertexAttribs() {
|
||||
fVertexAttribs.reset();
|
||||
fVertexAttribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, 0));
|
||||
|
||||
fCommon.fAttribBindings = kDefault_AttribBindings;
|
||||
|
||||
fAttribIndices[kPosition_AttribIndex] = 0;
|
||||
bool GrDrawState::VertexUsesTexCoords(GrVertexLayout vertexLayout) {
|
||||
return SkToBool(kTexCoordMask & vertexLayout);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawState::AttributesBindExplicitTexCoords(GrAttribBindings attribBindings) {
|
||||
return SkToBool(kTexCoord_AttribBindingsMask & attribBindings);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDrawState::VertexAttributesUnitTest() {
|
||||
void GrDrawState::VertexLayoutUnitTest() {
|
||||
// Ensure that our tex coord mask is correct
|
||||
GrAttribBindings texCoordMask;
|
||||
GrVertexLayout texCoordMask;
|
||||
gen_tex_coord_mask(&texCoordMask);
|
||||
GrAssert(texCoordMask == kTexCoord_AttribBindingsMask);
|
||||
GrAssert(texCoordMask == kTexCoordMask);
|
||||
|
||||
// not necessarily exhaustive
|
||||
static bool run;
|
||||
if (!run) {
|
||||
run = true;
|
||||
|
||||
GrVertexAttribArray<6> attribs;
|
||||
GrAssert(0 == vertex_size(attribs.begin(), attribs.count()));
|
||||
|
||||
attribs.push_back(GrVertexAttrib(kFloat_GrVertexAttribType, 0));
|
||||
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()));
|
||||
|
||||
attribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, attribs[0].fOffset + 4*sizeof(char)));
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) == vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs.push_back(GrVertexAttrib(kVec3f_GrVertexAttribType, attribs[1].fOffset + 2*sizeof(float)));
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) ==
|
||||
vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs.push_back(GrVertexAttrib(kFloat_GrVertexAttribType, attribs[2].fOffset + 3*sizeof(float)));
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) ==
|
||||
vertex_size(attribs.begin(), attribs.count()));
|
||||
attribs.push_back(GrVertexAttrib(kVec4f_GrVertexAttribType, attribs[3].fOffset + sizeof(float)));
|
||||
GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(float) + 4*sizeof(float) ==
|
||||
vertex_size(attribs.begin(), attribs.count()));
|
||||
|
||||
GrAttribBindings tcMask = 0;
|
||||
GrAssert(!AttributesBindExplicitTexCoords(0));
|
||||
GrVertexLayout tcMask = 0;
|
||||
GrAssert(!VertexUsesTexCoords(0));
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
tcMask |= ExplicitTexCoordAttribBindingsBit(s);
|
||||
GrAssert(AttributesBindExplicitTexCoords(tcMask));
|
||||
GrAssert(StageBindsExplicitTexCoords(tcMask, s));
|
||||
tcMask |= StageTexCoordVertexLayoutBit(s);
|
||||
GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
|
||||
GrAssert(VertexUsesTexCoords(tcMask));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
|
||||
GrAssert(StageUsesTexCoords(tcMask, s));
|
||||
for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
|
||||
GrAssert(!StageBindsExplicitTexCoords(tcMask, s2));
|
||||
GrAssert(!StageUsesTexCoords(tcMask, s2));
|
||||
|
||||
#if GR_DEBUG
|
||||
GrVertexLayout posAsTex = tcMask;
|
||||
#endif
|
||||
GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
|
||||
GrAssert(!StageUsesTexCoords(posAsTex, s2));
|
||||
GrAssert(-1 == VertexEdgeOffset(posAsTex));
|
||||
}
|
||||
GrAssert(-1 == VertexEdgeOffset(tcMask));
|
||||
GrAssert(-1 == VertexColorOffset(tcMask));
|
||||
GrAssert(-1 == VertexCoverageOffset(tcMask));
|
||||
#if GR_DEBUG
|
||||
GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
|
||||
#endif
|
||||
GrAssert(-1 == VertexCoverageOffset(withColor));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
|
||||
GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
|
||||
#if GR_DEBUG
|
||||
GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
|
||||
#endif
|
||||
GrAssert(-1 == VertexColorOffset(withEdge));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
|
||||
GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
|
||||
#if GR_DEBUG
|
||||
GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
|
||||
#endif
|
||||
GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
|
||||
GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
|
||||
GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
|
||||
#if GR_DEBUG
|
||||
GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
|
||||
#endif
|
||||
GrAssert(-1 == VertexColorOffset(withCoverage));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
|
||||
GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
|
||||
#if GR_DEBUG
|
||||
GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
|
||||
kColor_VertexLayoutBit;
|
||||
#endif
|
||||
GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
|
||||
GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
|
||||
GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
|
||||
}
|
||||
GrAssert(kTexCoordMask == tcMask);
|
||||
|
||||
int stageOffsets[GrDrawState::kNumStages];
|
||||
int colorOffset;
|
||||
int edgeOffset;
|
||||
int coverageOffset;
|
||||
int size;
|
||||
size = VertexSizeAndOffsetsByStage(tcMask,
|
||||
stageOffsets, &colorOffset,
|
||||
&coverageOffset, &edgeOffset);
|
||||
GrAssert(2*sizeof(GrPoint) == size);
|
||||
GrAssert(-1 == colorOffset);
|
||||
GrAssert(-1 == coverageOffset);
|
||||
GrAssert(-1 == edgeOffset);
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
GrAssert(sizeof(GrPoint) == stageOffsets[s]);
|
||||
GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
|
||||
}
|
||||
GrAssert(kTexCoord_AttribBindingsMask == tcMask);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawState::StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx) {
|
||||
return SkToBool(bindings & ExplicitTexCoordAttribBindingsBit(stageIdx));
|
||||
bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
|
||||
return SkToBool(layout & StageTexCoordVertexLayoutBit(stageIdx));
|
||||
}
|
||||
|
||||
bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const {
|
||||
bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {
|
||||
|
||||
uint32_t validComponentFlags;
|
||||
GrColor color;
|
||||
// Check if per-vertex or constant color may have partial alpha
|
||||
if (bindings & kColor_AttribBindingsBit) {
|
||||
if (layout & kColor_VertexLayoutBit) {
|
||||
validComponentFlags = 0;
|
||||
color = 0; // not strictly necessary but we get false alarms from tools about uninit.
|
||||
} else {
|
||||
|
@ -246,7 +366,7 @@ bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const {
|
|||
return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
|
||||
}
|
||||
|
||||
bool GrDrawState::hasSolidCoverage(GrAttribBindings bindings) const {
|
||||
bool GrDrawState::hasSolidCoverage(GrVertexLayout layout) const {
|
||||
// If we're drawing coverage directly then coverage is effectively treated as color.
|
||||
if (this->isCoverageDrawing()) {
|
||||
return true;
|
||||
|
@ -255,7 +375,7 @@ bool GrDrawState::hasSolidCoverage(GrAttribBindings bindings) const {
|
|||
GrColor coverage;
|
||||
uint32_t validComponentFlags;
|
||||
// Initialize to an unknown starting coverage if per-vertex coverage is specified.
|
||||
if (bindings & kCoverage_AttribBindingsBit) {
|
||||
if (layout & kCoverage_VertexLayoutBit) {
|
||||
validComponentFlags = 0;
|
||||
} else {
|
||||
coverage = fCommon.fCoverage;
|
||||
|
@ -297,7 +417,7 @@ bool GrDrawState::canTweakAlphaForCoverage() const {
|
|||
GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
||||
GrBlendCoeff* srcCoeff,
|
||||
GrBlendCoeff* dstCoeff) const {
|
||||
GrAttribBindings bindings = this->getAttribBindings();
|
||||
GrVertexLayout layout = this->getVertexLayout();
|
||||
|
||||
GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
|
||||
if (NULL == srcCoeff) {
|
||||
|
@ -315,14 +435,14 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
|||
*dstCoeff = kOne_GrBlendCoeff;
|
||||
}
|
||||
|
||||
bool srcAIsOne = this->srcAlphaWillBeOne(bindings);
|
||||
bool srcAIsOne = this->srcAlphaWillBeOne(layout);
|
||||
bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
|
||||
(kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
|
||||
bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
|
||||
(kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
|
||||
|
||||
bool covIsZero = !this->isCoverageDrawing() &&
|
||||
!(bindings & GrDrawState::kCoverage_AttribBindingsBit) &&
|
||||
!(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
|
||||
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
|
||||
|
@ -340,8 +460,8 @@ GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
|
|||
// edge aa or coverage stage
|
||||
bool hasCoverage = forceCoverage ||
|
||||
0xffffffff != this->getCoverage() ||
|
||||
(bindings & GrDrawState::kCoverage_AttribBindingsBit) ||
|
||||
(bindings & GrDrawState::kEdge_AttribBindingsBit);
|
||||
(layout & GrDrawState::kCoverage_VertexLayoutBit) ||
|
||||
(layout & GrDrawState::kEdge_VertexLayoutBit);
|
||||
for (int s = this->getFirstCoverageStage();
|
||||
!hasCoverage && s < GrDrawState::kNumStages;
|
||||
++s) {
|
||||
|
|
|
@ -23,41 +23,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 {
|
||||
GrVertexAttrib() {}
|
||||
GrVertexAttrib(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
|
||||
*/
|
||||
typedef int GrAttribBindings;
|
||||
|
||||
class GrDrawState : public GrRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(GrDrawState)
|
||||
|
@ -67,7 +32,7 @@ public:
|
|||
* GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
|
||||
* output from the previous enabled stage and a position. The position is either derived from
|
||||
* the interpolated vertex positions or explicit per-vertex coords, depending upon the
|
||||
* GrAttribBindings used to draw.
|
||||
* GrVertexLayout used to draw.
|
||||
*
|
||||
* The stages are divided into two sets, color-computing and coverage-computing. The final color
|
||||
* stage produces the final pixel color. The coverage-computing stages function exactly as the
|
||||
|
@ -75,7 +40,7 @@ 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, depending upon GrAttribBindings. The input to the first coverage stage is
|
||||
* per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is
|
||||
* either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
|
||||
* edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
|
||||
* GrEffect).
|
||||
|
@ -94,7 +59,7 @@ public:
|
|||
|
||||
GrDrawState() {
|
||||
#if GR_DEBUG
|
||||
VertexAttributesUnitTest();
|
||||
VertexLayoutUnitTest();
|
||||
#endif
|
||||
this->reset();
|
||||
}
|
||||
|
@ -117,9 +82,8 @@ public:
|
|||
|
||||
fRenderTarget.reset(NULL);
|
||||
|
||||
this->setDefaultVertexAttribs();
|
||||
|
||||
fCommon.fColor = 0xffffffff;
|
||||
fCommon.fVertexLayout = kDefault_VertexLayout;
|
||||
fCommon.fViewMatrix.reset();
|
||||
fCommon.fSrcBlend = kOne_GrBlendCoeff;
|
||||
fCommon.fDstBlend = kZero_GrBlendCoeff;
|
||||
|
@ -143,50 +107,193 @@ public:
|
|||
void setFromPaint(const GrPaint& paint);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// @name Vertex Attributes
|
||||
/// @name Vertex Layout
|
||||
////
|
||||
|
||||
enum {
|
||||
kVertexAttribCnt = 6,
|
||||
/**
|
||||
* The format of vertices is represented as a bitfield of flags.
|
||||
* Flags that indicate the layout of vertex data. Vertices always contain
|
||||
* positions and may also contain texture coordinates, per-vertex colors,
|
||||
* and per-vertex coverage. Each stage can use any texture coordinates as
|
||||
* its input texture coordinates or it may use the positions as texture
|
||||
* coordinates.
|
||||
*
|
||||
* If no texture coordinates are specified for a stage then the stage is
|
||||
* disabled.
|
||||
*
|
||||
* The order in memory is always (position, texture coords, color, coverage)
|
||||
* with any unused fields omitted.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generates a bit indicating that a texture stage uses texture coordinates
|
||||
*
|
||||
* @param stageIdx the stage that will use texture coordinates.
|
||||
*
|
||||
* @return the bit to add to a GrVertexLayout bitfield.
|
||||
*/
|
||||
static int StageTexCoordVertexLayoutBit(int stageIdx) {
|
||||
GrAssert(stageIdx < kNumStages);
|
||||
return (1 << stageIdx);
|
||||
}
|
||||
|
||||
static bool StageUsesTexCoords(GrVertexLayout layout, int stageIdx);
|
||||
|
||||
private:
|
||||
// non-stage bits start at this index.
|
||||
static const int STAGE_BIT_CNT = kNumStages;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Additional Bits that can be specified in GrVertexLayout.
|
||||
*/
|
||||
enum VertexLayoutBits {
|
||||
/* vertices have colors (GrColor) */
|
||||
kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
|
||||
/* vertices have coverage (GrColor)
|
||||
*/
|
||||
kCoverage_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
|
||||
/* Each vertex specificies an edge. Distance to the edge is used to
|
||||
* compute a coverage. See GrDrawState::setVertexEdgeType().
|
||||
*/
|
||||
kEdge_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 2),
|
||||
// for below assert
|
||||
kDummyVertexLayoutBit,
|
||||
kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
|
||||
};
|
||||
// make sure we haven't exceeded the number of bits in GrVertexLayout.
|
||||
GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
|
||||
|
||||
enum VertexLayout {
|
||||
kDefault_VertexLayout = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* Sets vertex layout for next draw.
|
||||
*
|
||||
* 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.
|
||||
* @param layout the vertex layout to set.
|
||||
*/
|
||||
void setVertexLayout(GrVertexLayout layout) { fCommon.fVertexLayout = layout; }
|
||||
|
||||
/**
|
||||
* 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 a count of kVertexAttribCnt.
|
||||
*/
|
||||
void setVertexAttribs(const GrVertexAttrib attribs[], int count);
|
||||
GrVertexLayout getVertexLayout() const { return fCommon.fVertexLayout; }
|
||||
size_t getVertexSize() const { return VertexSize(fCommon.fVertexLayout); }
|
||||
|
||||
const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
|
||||
int getVertexAttribCount() const { return fVertexAttribs.count(); }
|
||||
|
||||
size_t getVertexSize() const;
|
||||
|
||||
/**
|
||||
* Sets default vertex attributes for next draw.
|
||||
*
|
||||
* This will also set default vertex attribute indices and bindings
|
||||
*/
|
||||
void setDefaultVertexAttribs();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers for picking apart vertex attributes
|
||||
// Helpers for picking apart vertex layouts
|
||||
|
||||
// helper array to let us check the expected so we know what bound attrib indices
|
||||
// we care about
|
||||
static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
|
||||
/**
|
||||
* Helper function to compute the size of a vertex from a vertex layout
|
||||
* @return size of a single vertex.
|
||||
*/
|
||||
static size_t VertexSize(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the offset of texture coordinates in a vertex
|
||||
* @return offset of texture coordinates in vertex layout or 0 if positions
|
||||
* are used as texture coordinates for the stage.
|
||||
*/
|
||||
static int VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the offset of the color in a vertex
|
||||
* @return offset of color in vertex layout or -1 if the
|
||||
* layout has no color.
|
||||
*/
|
||||
static int VertexColorOffset(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the offset of the coverage in a vertex
|
||||
* @return offset of coverage in vertex layout or -1 if the
|
||||
* layout has no coverage.
|
||||
*/
|
||||
static int VertexCoverageOffset(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the offset of the edge pts in a vertex
|
||||
* @return offset of edge in vertex layout or -1 if the
|
||||
* layout has no edge.
|
||||
*/
|
||||
static int VertexEdgeOffset(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to determine if vertex layout contains explicit texture
|
||||
* coordinates.
|
||||
*
|
||||
* @param vertexLayout layout to query
|
||||
*
|
||||
* @return true if vertex specifies texture coordinates,
|
||||
* false otherwise.
|
||||
*/
|
||||
static bool VertexUsesTexCoords(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the size of each vertex and the offsets of
|
||||
* texture coordinates and color.
|
||||
*
|
||||
* @param vertexLayout the layout to query
|
||||
* @param texCoordOffset after return it is the offset of the
|
||||
* tex coord index in the vertex or -1 if
|
||||
* tex coords aren't used. (optional)
|
||||
* @param colorOffset after return it is the offset of the
|
||||
* color field in each vertex, or -1 if
|
||||
* there aren't per-vertex colors. (optional)
|
||||
* @param coverageOffset after return it is the offset of the
|
||||
* coverage field in each vertex, or -1 if
|
||||
* there aren't per-vertex coeverages.
|
||||
* (optional)
|
||||
* @param edgeOffset after return it is the offset of the
|
||||
* edge eq field in each vertex, or -1 if
|
||||
* there aren't per-vertex edge equations.
|
||||
* (optional)
|
||||
* @return size of a single vertex
|
||||
*/
|
||||
static int VertexSizeAndOffsets(GrVertexLayout vertexLayout,
|
||||
int *texCoordOffset,
|
||||
int *colorOffset,
|
||||
int *coverageOffset,
|
||||
int* edgeOffset);
|
||||
|
||||
/**
|
||||
* Helper function to compute the size of each vertex and the offsets of
|
||||
* texture coordinates and color. Determines tex coord offsets by stage
|
||||
* rather than by index. (Each stage can be mapped to any t.c. index
|
||||
* by StageTexCoordVertexLayoutBit.) If a stage uses positions for
|
||||
* tex coords then that stage's offset will be 0 (positions are always at 0).
|
||||
*
|
||||
* @param vertexLayout the layout to query
|
||||
* @param texCoordOffsetsByStage after return it is the offset of each
|
||||
* tex coord index in the vertex or -1 if
|
||||
* index isn't used. (optional)
|
||||
* @param colorOffset after return it is the offset of the
|
||||
* color field in each vertex, or -1 if
|
||||
* there aren't per-vertex colors.
|
||||
* (optional)
|
||||
* @param coverageOffset after return it is the offset of the
|
||||
* coverage field in each vertex, or -1 if
|
||||
* there aren't per-vertex coeverages.
|
||||
* (optional)
|
||||
* @param edgeOffset after return it is the offset of the
|
||||
* edge eq field in each vertex, or -1 if
|
||||
* there aren't per-vertex edge equations.
|
||||
* (optional)
|
||||
* @return size of a single vertex
|
||||
*/
|
||||
static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
|
||||
int texCoordOffsetsByStage[kNumStages],
|
||||
int* colorOffset,
|
||||
int* coverageOffset,
|
||||
int* edgeOffset);
|
||||
|
||||
/**
|
||||
* Determines whether src alpha is guaranteed to be one for all src pixels
|
||||
*/
|
||||
bool srcAlphaWillBeOne(GrVertexLayout) const;
|
||||
|
||||
/**
|
||||
* Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
|
||||
*/
|
||||
bool hasSolidCoverage(GrVertexLayout) const;
|
||||
|
||||
/**
|
||||
* Accessing positions, texture coords, or colors, of a vertex within an
|
||||
|
@ -197,7 +304,7 @@ public:
|
|||
/**
|
||||
* Gets a pointer to a GrPoint of a vertex's position or texture
|
||||
* coordinate.
|
||||
* @param vertices the vertex array
|
||||
* @param vertices the vetex array
|
||||
* @param vertexIndex the index of the vertex in the array
|
||||
* @param vertexSize the size of each vertex in the array
|
||||
* @param offset the offset in bytes of the vertex component.
|
||||
|
@ -246,140 +353,7 @@ public:
|
|||
vertexIndex * vertexSize);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// @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. Each
|
||||
* stage can use the explicit texture coordinates as its input texture
|
||||
* coordinates or it may use the positions as texture coordinates.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generates a bit indicating that a texture stage uses texture coordinates
|
||||
*
|
||||
* @param stageIdx the stage that will use texture coordinates.
|
||||
*
|
||||
* @return the bit to add to a GrAttribBindings bitfield.
|
||||
*/
|
||||
static int ExplicitTexCoordAttribBindingsBit(int stageIdx) {
|
||||
GrAssert(stageIdx < kNumStages);
|
||||
return (1 << stageIdx);
|
||||
}
|
||||
|
||||
static bool StageBindsExplicitTexCoords(GrAttribBindings bindings, int stageIdx);
|
||||
|
||||
/**
|
||||
* Additional Bits that can be specified in GrAttribBindings.
|
||||
*/
|
||||
enum AttribBindingsBits {
|
||||
/* program uses colors (GrColor) */
|
||||
kColor_AttribBindingsBit = 1 << (kNumStages + 0),
|
||||
/* program uses coverage (GrColor)
|
||||
*/
|
||||
kCoverage_AttribBindingsBit = 1 << (kNumStages + 1),
|
||||
/* program uses edge data. Distance to the edge is used to
|
||||
* compute a coverage. See GrDrawState::setVertexEdgeType().
|
||||
*/
|
||||
kEdge_AttribBindingsBit = 1 << (kNumStages + 2),
|
||||
// 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
|
||||
|
||||
/**
|
||||
* Helper function to determine if program uses explicit texture
|
||||
* coordinates.
|
||||
*
|
||||
* @param bindings attribute bindings to query
|
||||
*
|
||||
* @return true if program uses texture coordinates,
|
||||
* false otherwise.
|
||||
*/
|
||||
static bool AttributesBindExplicitTexCoords(GrAttribBindings bindings);
|
||||
|
||||
/**
|
||||
* Determines whether src alpha is guaranteed to be one for all src pixels
|
||||
*/
|
||||
bool srcAlphaWillBeOne(GrAttribBindings) const;
|
||||
|
||||
/**
|
||||
* Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
|
||||
*/
|
||||
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,
|
||||
kEdge_AttribIndex,
|
||||
kTexCoord_AttribIndex,
|
||||
|
||||
kLast_AttribIndex = kTexCoord_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]; }
|
||||
static void VertexLayoutUnitTest();
|
||||
|
||||
/// @}
|
||||
|
||||
|
@ -1030,7 +1004,7 @@ public:
|
|||
|
||||
/**
|
||||
* Determines the interpretation per-vertex edge data when the
|
||||
* kEdge_AttribBindingsBit is set (see GrDrawTarget). When per-vertex edges
|
||||
* kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
|
||||
* are not specified the value of this setting has no effect.
|
||||
*/
|
||||
void setVertexEdgeType(VertexEdgeType type) {
|
||||
|
@ -1185,25 +1159,13 @@ public:
|
|||
return (NULL != fStages[s].getEffect());
|
||||
}
|
||||
|
||||
// Most stages are usually not used, so conditionals here
|
||||
// reduce the expected number of bytes touched by 50%.
|
||||
bool operator ==(const GrDrawState& s) const {
|
||||
if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
|
||||
return false;
|
||||
}
|
||||
if (fVertexAttribs.count() != s.fVertexAttribs.count()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < fVertexAttribs.count(); ++i) {
|
||||
if (fVertexAttribs[i] != s.fVertexAttribs[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < kAttribIndexCount; ++i) {
|
||||
if ((i == kPosition_AttribIndex ||
|
||||
s.fCommon.fAttribBindings & kAttribIndexMasks[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)) {
|
||||
|
@ -1220,10 +1182,6 @@ 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];
|
||||
|
@ -1238,7 +1196,7 @@ private:
|
|||
struct CommonState {
|
||||
// These fields are roughly sorted by decreasing likelihood of being different in op==
|
||||
GrColor fColor;
|
||||
GrAttribBindings fAttribBindings;
|
||||
GrVertexLayout fVertexLayout;
|
||||
SkMatrix fViewMatrix;
|
||||
GrBlendCoeff fSrcBlend;
|
||||
GrBlendCoeff fDstBlend;
|
||||
|
@ -1253,7 +1211,7 @@ private:
|
|||
DrawFace fDrawFace;
|
||||
bool operator== (const CommonState& other) const {
|
||||
return fColor == other.fColor &&
|
||||
fAttribBindings == other.fAttribBindings &&
|
||||
fVertexLayout == other.fVertexLayout &&
|
||||
fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
|
||||
fSrcBlend == other.fSrcBlend &&
|
||||
fDstBlend == other.fDstBlend &&
|
||||
|
@ -1298,10 +1256,6 @@ 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).
|
||||
|
@ -1315,10 +1269,6 @@ 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]);
|
||||
}
|
||||
|
@ -1328,20 +1278,6 @@ 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.count() != state.fVertexAttribs.count()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < fVertexAttribs.count(); ++i)
|
||||
if (fVertexAttribs[i] != state.fVertexAttribs[i]) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < kNumStages; ++i) {
|
||||
if (!fStages[i].isEqual(state.fStages[i])) {
|
||||
return false;
|
||||
|
@ -1353,22 +1289,14 @@ 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;
|
||||
|
|
|
@ -530,19 +530,11 @@ void GrDrawTarget::drawRect(const GrRect& rect,
|
|||
const GrRect* srcRect,
|
||||
const SkMatrix* srcMatrix,
|
||||
int stage) {
|
||||
GrAttribBindings bindings = 0;
|
||||
GrVertexLayout layout = 0;
|
||||
uint32_t explicitCoordMask = 0;
|
||||
// position + (optional) texture coord
|
||||
static const GrVertexAttrib kAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
int attribCount = 1;
|
||||
|
||||
if (NULL != srcRect) {
|
||||
bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(stage);
|
||||
attribCount = 2;
|
||||
this->drawState()->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
|
||||
layout |= GrDrawState::StageTexCoordVertexLayoutBit(stage);
|
||||
explicitCoordMask = (1 << stage);
|
||||
}
|
||||
|
||||
|
@ -551,27 +543,31 @@ void GrDrawTarget::drawRect(const GrRect& rect,
|
|||
avmr.set(this->drawState(), *matrix, explicitCoordMask);
|
||||
}
|
||||
|
||||
this->drawState()->setVertexAttribs(kAttribs, attribCount);
|
||||
this->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
this->drawState()->setAttribBindings(bindings);
|
||||
this->drawState()->setVertexLayout(layout);
|
||||
AutoReleaseGeometry geo(this, 4, 0);
|
||||
if (!geo.succeeded()) {
|
||||
GrPrintf("Failed to get space for vertices!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t vsize = this->drawState()->getVertexSize();
|
||||
int stageOffsets[GrDrawState::kNumStages];
|
||||
int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets, NULL, NULL, NULL);
|
||||
geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
|
||||
if (NULL != srcRect) {
|
||||
GrAssert(attribCount == 2);
|
||||
|
||||
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
|
||||
if (explicitCoordMask & (1 << i)) {
|
||||
GrAssert(0 != stageOffsets[i]);
|
||||
GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
|
||||
kAttribs[1].fOffset);
|
||||
stageOffsets[i]);
|
||||
coords->setRectFan(srcRect->fLeft, srcRect->fTop,
|
||||
srcRect->fRight, srcRect->fBottom,
|
||||
vsize);
|
||||
if (NULL != srcMatrix) {
|
||||
srcMatrix->mapPointsWithStride(coords, vsize, 4);
|
||||
}
|
||||
} else {
|
||||
GrAssert(0 == stageOffsets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
|
||||
|
|
|
@ -78,20 +78,9 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
|||
const SkMatrix* srcMatrix,
|
||||
int stage) {
|
||||
|
||||
GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
|
||||
GrVertexLayout layout = 0;
|
||||
GrDrawState::AutoColorRestore acr;
|
||||
|
||||
GrDrawState* drawState = this->drawState();
|
||||
|
||||
GrColor color = drawState->getColor();
|
||||
GrVertexAttribArray<3> attribs;
|
||||
size_t currentOffset = 0;
|
||||
int colorOffset = -1, texOffset = -1;
|
||||
|
||||
// set position attrib
|
||||
drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
|
||||
attribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, currentOffset));
|
||||
currentOffset += sizeof(GrPoint);
|
||||
GrColor color = this->drawState()->getColor();
|
||||
|
||||
// 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
|
||||
|
@ -100,31 +89,22 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
|||
// 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->getCaps().dualSourceBlendingSupport() ||
|
||||
drawState->hasSolidCoverage(drawState->getAttribBindings())) {
|
||||
bindings |= GrDrawState::kColor_AttribBindingsBit;
|
||||
drawState->setAttribIndex(GrDrawState::kColor_AttribIndex, attribs.count());
|
||||
attribs.push_back(GrVertexAttrib(kVec4ub_GrVertexAttribType, currentOffset));
|
||||
colorOffset = currentOffset;
|
||||
currentOffset += sizeof(GrColor);
|
||||
this->getDrawState().hasSolidCoverage(this->getDrawState().getVertexLayout())) {
|
||||
layout |= GrDrawState::kColor_VertexLayoutBit;;
|
||||
// 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
|
||||
// mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the
|
||||
// constant color in its op== when the kColor layout bit is set and then we can remove this.
|
||||
acr.set(drawState, 0xFFFFFFFF);
|
||||
acr.set(this->drawState(), 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
uint32_t explicitCoordMask = 0;
|
||||
if (NULL != srcRect) {
|
||||
bindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(stage);
|
||||
drawState->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, attribs.count());
|
||||
attribs.push_back(GrVertexAttrib(kVec2f_GrVertexAttribType, currentOffset));
|
||||
texOffset = currentOffset;
|
||||
currentOffset += sizeof(GrPoint);
|
||||
layout |= GrDrawState::StageTexCoordVertexLayoutBit(stage);
|
||||
explicitCoordMask = (1 << stage);
|
||||
}
|
||||
|
||||
drawState->setVertexAttribs(attribs.begin(), attribs.count());
|
||||
drawState->setAttribBindings(bindings);
|
||||
this->drawState()->setVertexLayout(layout);
|
||||
AutoReleaseGeometry geo(this, 4, 0);
|
||||
if (!geo.succeeded()) {
|
||||
GrPrintf("Failed to get space for vertices!\n");
|
||||
|
@ -138,17 +118,18 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
|||
} else {
|
||||
combinedMatrix.reset();
|
||||
}
|
||||
combinedMatrix.postConcat(drawState->getViewMatrix());
|
||||
combinedMatrix.postConcat(this->drawState()->getViewMatrix());
|
||||
// When the caller has provided an explicit source rect for a stage then we don't want to
|
||||
// modify that stage's matrix. Otherwise if the effect is generating its source rect from
|
||||
// the vertex positions then we have to account for the view matrix change.
|
||||
GrDrawState::AutoDeviceCoordDraw adcd(drawState, explicitCoordMask);
|
||||
GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask);
|
||||
if (!adcd.succeeded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t vsize = drawState->getVertexSize();
|
||||
GrAssert(vsize == currentOffset);
|
||||
int stageOffsets[GrDrawState::kNumStages], colorOffset;
|
||||
int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets,
|
||||
&colorOffset, NULL, NULL);
|
||||
|
||||
geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
|
||||
combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4);
|
||||
|
@ -158,16 +139,20 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
|||
// unnecessary clipping in our onDraw().
|
||||
get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);
|
||||
|
||||
if (texOffset >= 0) {
|
||||
GrAssert(explicitCoordMask != 0);
|
||||
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
|
||||
if (explicitCoordMask & (1 << i)) {
|
||||
GrAssert(0 != stageOffsets[i]);
|
||||
GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
|
||||
texOffset);
|
||||
stageOffsets[i]);
|
||||
coords->setRectFan(srcRect->fLeft, srcRect->fTop,
|
||||
srcRect->fRight, srcRect->fBottom,
|
||||
vsize);
|
||||
if (NULL != srcMatrix) {
|
||||
srcMatrix->mapPointsWithStride(coords, vsize, 4);
|
||||
}
|
||||
} else {
|
||||
GrAssert(0 == stageOffsets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (colorOffset >= 0) {
|
||||
|
@ -180,9 +165,6 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
|||
|
||||
this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
|
||||
this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
|
||||
|
||||
// to ensure that stashing the drawState ptr is valid
|
||||
GrAssert(this->drawState() == drawState);
|
||||
}
|
||||
|
||||
bool GrInOrderDrawBuffer::quickInsideClip(const SkRect& devBounds) {
|
||||
|
|
|
@ -92,6 +92,8 @@ GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(
|
|||
|
||||
fVertices = NULL;
|
||||
fMaxVertices = 0;
|
||||
|
||||
fVertexLayout = GrDrawState::StageTexCoordVertexLayoutBit(kGlyphMaskStage);
|
||||
}
|
||||
|
||||
GrTextContext::~GrTextContext() {
|
||||
|
@ -187,20 +189,13 @@ HAS_ATLAS:
|
|||
}
|
||||
|
||||
if (NULL == fVertices) {
|
||||
// position + texture coord
|
||||
static const GrVertexAttrib kVertexAttribs[] = {
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, 0),
|
||||
GrVertexAttrib(kVec2f_GrVertexAttribType, sizeof(GrPoint))
|
||||
};
|
||||
static const GrAttribBindings kAttribBindings = GrDrawState::ExplicitTexCoordAttribBindingsBit(kGlyphMaskStage);
|
||||
|
||||
// If we need to reserve vertices allow the draw target to suggest
|
||||
// a number of verts to reserve and whether to perform a flush.
|
||||
fMaxVertices = kMinRequestedVerts;
|
||||
bool flush = false;
|
||||
fDrawTarget = fContext->getTextTarget(fPaint);
|
||||
if (NULL != fDrawTarget) {
|
||||
fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
fDrawTarget->drawState()->setVertexLayout(fVertexLayout);
|
||||
flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
|
||||
}
|
||||
if (flush) {
|
||||
|
@ -208,11 +203,8 @@ HAS_ATLAS:
|
|||
fContext->flush();
|
||||
// flushGlyphs() will reset fDrawTarget to NULL.
|
||||
fDrawTarget = fContext->getTextTarget(fPaint);
|
||||
fDrawTarget->drawState()->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
|
||||
fDrawTarget->drawState()->setVertexLayout(fVertexLayout);
|
||||
}
|
||||
fDrawTarget->drawState()->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
|
||||
fDrawTarget->drawState()->setAttribIndex(GrDrawState::kTexCoord_AttribIndex, 1);
|
||||
fDrawTarget->drawState()->setAttribBindings(kAttribBindings);
|
||||
fMaxVertices = kDefaultRequestedVerts;
|
||||
// ignore return, no point in flushing again.
|
||||
fDrawTarget->geometryHints(&fMaxVertices, NULL);
|
||||
|
@ -230,7 +222,6 @@ HAS_ATLAS:
|
|||
GrTCast<void**>(&fVertices),
|
||||
NULL);
|
||||
GrAlwaysAssert(success);
|
||||
GrAssert(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize());
|
||||
}
|
||||
|
||||
GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
|
||||
|
|
|
@ -35,14 +35,6 @@ 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,
|
||||
bool isPoints,
|
||||
GrDrawState::BlendOptFlags blendOpts,
|
||||
|
@ -60,24 +52,24 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
|
|||
GrDrawState::kEmitCoverage_BlendOptFlag));
|
||||
|
||||
// The descriptor is used as a cache key. Thus when a field of the
|
||||
// descriptor will not affect program generation (because of the attribute
|
||||
// bindings in use or other descriptor field settings) it should be set
|
||||
// descriptor will not affect program generation (because of the vertex
|
||||
// layout 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->fVertexLayout = drawState.getVertexLayout();
|
||||
|
||||
desc->fEmitsPointSize = isPoints;
|
||||
|
||||
bool requiresAttributeColors = !skipColor &&
|
||||
SkToBool(desc->fAttribBindings & GrDrawState::kColor_AttribBindingsBit);
|
||||
SkToBool(desc->fVertexLayout & GrDrawState::kColor_VertexLayoutBit);
|
||||
bool requiresAttributeCoverage = !skipCoverage &&
|
||||
SkToBool(desc->fAttribBindings & GrDrawState::kCoverage_AttribBindingsBit);
|
||||
SkToBool(desc->fVertexLayout & GrDrawState::kCoverage_VertexLayoutBit);
|
||||
|
||||
// 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
|
||||
// bits from the layout to avoid false negatives when searching for an existing program in the
|
||||
// cache.
|
||||
desc->fAttribBindings &= ~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribBindingsBit);
|
||||
desc->fVertexLayout &= ~(GrDrawState::kColor_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit);
|
||||
|
||||
desc->fColorFilterXfermode = skipColor ?
|
||||
SkXfermode::kDst_Mode :
|
||||
|
@ -85,8 +77,8 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
|
|||
|
||||
// no reason to do edge aa or look at per-vertex coverage if coverage is ignored
|
||||
if (skipCoverage) {
|
||||
desc->fAttribBindings &= ~(GrDrawState::kEdge_AttribBindingsBit |
|
||||
GrDrawState::kCoverage_AttribBindingsBit);
|
||||
desc->fVertexLayout &= ~(GrDrawState::kEdge_VertexLayoutBit |
|
||||
GrDrawState::kCoverage_VertexLayoutBit);
|
||||
}
|
||||
|
||||
bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
|
||||
|
@ -116,7 +108,7 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
|
|||
|
||||
int lastEnabledStage = -1;
|
||||
|
||||
if (!skipCoverage && (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit)) {
|
||||
if (!skipCoverage && (desc->fVertexLayout & GrDrawState::kEdge_VertexLayoutBit)) {
|
||||
desc->fVertexEdgeType = drawState.getVertexEdgeType();
|
||||
desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite();
|
||||
} else {
|
||||
|
@ -163,7 +155,7 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
|
|||
// other coverage inputs
|
||||
if (!hasCoverage) {
|
||||
hasCoverage = requiresAttributeCoverage ||
|
||||
(desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit);
|
||||
(desc->fVertexLayout & GrDrawState::kEdge_VertexLayoutBit);
|
||||
}
|
||||
|
||||
if (hasCoverage) {
|
||||
|
@ -190,43 +182,6 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosition_AttribIndex);
|
||||
if (requiresAttributeColors) {
|
||||
desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColor_AttribIndex);
|
||||
} else {
|
||||
desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue;
|
||||
}
|
||||
if (requiresAttributeCoverage) {
|
||||
desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kCoverage_AttribIndex);
|
||||
} else {
|
||||
desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribIndexValue;
|
||||
}
|
||||
desc->fEdgeAttributeIndex = drawState.getAttribIndex(GrDrawState::kEdge_AttribIndex);
|
||||
desc->fTexCoordAttributeIndex = drawState.getAttribIndex(GrDrawState::kTexCoord_AttribIndex);
|
||||
|
||||
#if GR_DEBUG
|
||||
// verify valid vertex attribute state
|
||||
const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs();
|
||||
GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(kAttribLayouts[vertexAttribs[desc->fPositionAttributeIndex].fType].fCount == 2);
|
||||
if (requiresAttributeColors) {
|
||||
GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(kAttribLayouts[vertexAttribs[desc->fColorAttributeIndex].fType].fCount == 4);
|
||||
}
|
||||
if (requiresAttributeCoverage) {
|
||||
GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(kAttribLayouts[vertexAttribs[desc->fCoverageAttributeIndex].fType].fCount == 4);
|
||||
}
|
||||
if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
|
||||
GrAssert(desc->fEdgeAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(kAttribLayouts[vertexAttribs[desc->fEdgeAttributeIndex].fType].fCount == 4);
|
||||
}
|
||||
if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
|
||||
GrAssert(desc->fTexCoordAttributeIndex < GrDrawState::kVertexAttribCnt);
|
||||
GrAssert(kAttribLayouts[vertexAttribs[desc->fTexCoordAttributeIndex].fType].fCount == 2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
GrGLProgram* GrGLProgram::Create(const GrGLContext& gl,
|
||||
|
@ -411,7 +366,7 @@ void add_color_filter(SkString* fsCode, const char * outputVar,
|
|||
|
||||
bool GrGLProgram::genEdgeCoverage(SkString* coverageVar,
|
||||
GrGLShaderBuilder* builder) const {
|
||||
if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
|
||||
if (fDesc.fVertexLayout & GrDrawState::kEdge_VertexLayoutBit) {
|
||||
const char *vsName, *fsName;
|
||||
builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName);
|
||||
builder->fVSAttrs.push_back().set(kVec4f_GrSLType,
|
||||
|
@ -690,7 +645,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
|
|||
GrAssert(0 == fProgramID);
|
||||
|
||||
GrGLShaderBuilder builder(fContext.info(), fUniformManager);
|
||||
const GrAttribBindings& attribBindings = fDesc.fAttribBindings;
|
||||
const uint32_t& layout = fDesc.fVertexLayout;
|
||||
|
||||
#if GR_GL_EXPERIMENTAL_GS
|
||||
builder.fUsesGS = fDesc.fExperimentalGS;
|
||||
|
@ -771,7 +726,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
|
|||
}
|
||||
|
||||
// add texture coordinates that are used to the list of vertex attr decls
|
||||
if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) {
|
||||
if (GrDrawState::VertexUsesTexCoords(layout)) {
|
||||
builder.fVSAttrs.push_back().set(kVec2f_GrSLType,
|
||||
GrGLShaderVar::kAttribute_TypeModifier,
|
||||
TEX_ATTR_NAME);
|
||||
|
@ -793,7 +748,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
|
|||
|
||||
const char* inCoords;
|
||||
// figure out what our input coords are
|
||||
if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
|
||||
if (!GrDrawState::StageUsesTexCoords(layout, s)) {
|
||||
inCoords = builder.positionAttribute().c_str();
|
||||
} else {
|
||||
// must have input tex coordinates if stage is enabled.
|
||||
|
@ -887,7 +842,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
|
|||
|
||||
const char* inCoords;
|
||||
// figure out what our input coords are
|
||||
if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
|
||||
if (!GrDrawState::StageUsesTexCoords(layout, s)) {
|
||||
inCoords = builder.positionAttribute().c_str();
|
||||
} else {
|
||||
// must have input tex coordinates if stage is
|
||||
|
@ -1011,17 +966,12 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil
|
|||
|
||||
// Bind the attrib locations to same values for all shaders
|
||||
GL_CALL(BindAttribLocation(fProgramID,
|
||||
fDesc.fPositionAttributeIndex,
|
||||
kPositionAttributeIndex,
|
||||
builder.positionAttribute().c_str()));
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fColorAttributeIndex, COL_ATTR_NAME));
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fCoverageAttributeIndex, COV_ATTR_NAME));
|
||||
|
||||
if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fEdgeAttributeIndex, EDGE_ATTR_NAME));
|
||||
}
|
||||
if (GrDrawState::AttributesBindExplicitTexCoords(fDesc.fAttribBindings)) {
|
||||
GL_CALL(BindAttribLocation(fProgramID, fDesc.fTexCoordAttributeIndex, TEX_ATTR_NAME));
|
||||
}
|
||||
GL_CALL(BindAttribLocation(fProgramID, kTexCoordAttributeIndex, TEX_ATTR_NAME));
|
||||
GL_CALL(BindAttribLocation(fProgramID, kColorAttributeIndex, COL_ATTR_NAME));
|
||||
GL_CALL(BindAttribLocation(fProgramID, kCoverageAttributeIndex, COV_ATTR_NAME));
|
||||
GL_CALL(BindAttribLocation(fProgramID, kEdgeAttributeIndex, EDGE_ATTR_NAME));
|
||||
|
||||
GL_CALL(LinkProgram(fProgramID));
|
||||
|
||||
|
@ -1110,14 +1060,14 @@ void GrGLProgram::setData(GrGpuGL* gpu,
|
|||
void GrGLProgram::setColor(const GrDrawState& drawState,
|
||||
GrColor color,
|
||||
SharedGLState* sharedState) {
|
||||
if (!(drawState.getAttribBindings() & GrDrawState::kColor_AttribBindingsBit)) {
|
||||
if (!(drawState.getVertexLayout() & GrDrawState::kColor_VertexLayoutBit)) {
|
||||
switch (fDesc.fColorInput) {
|
||||
case GrGLProgram::Desc::kAttribute_ColorInput:
|
||||
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));
|
||||
GL_CALL(VertexAttrib4fv(kColorAttributeIndex, c));
|
||||
sharedState->fConstAttribColor = color;
|
||||
}
|
||||
break;
|
||||
|
@ -1144,14 +1094,14 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
|
|||
void GrGLProgram::setCoverage(const GrDrawState& drawState,
|
||||
GrColor coverage,
|
||||
SharedGLState* sharedState) {
|
||||
if (!(drawState.getAttribBindings() & GrDrawState::kCoverage_AttribBindingsBit)) {
|
||||
if (!(drawState.getVertexLayout() & GrDrawState::kCoverage_VertexLayoutBit)) {
|
||||
switch (fDesc.fCoverageInput) {
|
||||
case Desc::kAttribute_ColorInput:
|
||||
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));
|
||||
GL_CALL(VertexAttrib4fv(kCoverageAttributeIndex, c));
|
||||
sharedState->fConstAttribCoverage = coverage;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -78,6 +78,17 @@ public:
|
|||
*/
|
||||
GrGLuint programID() const { return fProgramID; }
|
||||
|
||||
/**
|
||||
* Attribute indices. These should not overlap.
|
||||
*/
|
||||
enum {
|
||||
kPositionAttributeIndex = 0,
|
||||
kColorAttributeIndex = 1,
|
||||
kCoverageAttributeIndex = 2,
|
||||
kEdgeAttributeIndex = 3,
|
||||
kTexCoordAttributeIndex = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -171,7 +182,7 @@ public:
|
|||
bool fDiscardIfOutsideEdge;
|
||||
|
||||
// stripped of bits that don't affect program generation
|
||||
GrAttribBindings fAttribBindings;
|
||||
GrVertexLayout fVertexLayout;
|
||||
|
||||
/** Non-zero if this stage has an effect */
|
||||
GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
|
||||
|
@ -188,23 +199,9 @@ public:
|
|||
SkBool8 fEmitsPointSize;
|
||||
uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
|
||||
|
||||
int8_t fPositionAttributeIndex;
|
||||
int8_t fColorAttributeIndex;
|
||||
int8_t fCoverageAttributeIndex;
|
||||
int8_t fEdgeAttributeIndex;
|
||||
int8_t fTexCoordAttributeIndex;
|
||||
|
||||
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,
|
||||
|
|
|
@ -182,10 +182,6 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
|
|||
|
||||
fHWGeometryState.setMaxAttribArrays(this->glCaps().maxVertexAttributes());
|
||||
|
||||
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
|
||||
fbo_test(this->glInterface(), 0, 0);
|
||||
|
|
|
@ -215,29 +215,82 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
|
|||
|
||||
void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
|
||||
|
||||
GrGLsizei stride = this->getDrawState().getVertexSize();
|
||||
int colorOffset;
|
||||
int coverageOffset;
|
||||
int texCoordOffset;
|
||||
int edgeOffset;
|
||||
|
||||
GrVertexLayout currLayout = this->getDrawState().getVertexLayout();
|
||||
|
||||
GrGLsizei stride = GrDrawState::VertexSizeAndOffsets(currLayout,
|
||||
&texCoordOffset,
|
||||
&colorOffset,
|
||||
&coverageOffset,
|
||||
&edgeOffset);
|
||||
|
||||
size_t vertexOffset;
|
||||
GrGLVertexBuffer* vb= this->setBuffers(info.isIndexed(), &vertexOffset, indexOffsetInBytes);
|
||||
vertexOffset += stride * info.startVertex();
|
||||
|
||||
uint32_t usedAttribArraysMask = 0;
|
||||
const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
|
||||
int vertexAttribCount = this->getDrawState().getVertexAttribCount();
|
||||
for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
|
||||
++vertexAttribIndex, ++vertexAttrib) {
|
||||
|
||||
usedAttribArraysMask |= (1 << vertexAttribIndex);
|
||||
GrVertexAttribType attribType = vertexAttrib->fType;
|
||||
uint32_t usedAttribArraysMask = (1 << GrGLProgram::kPositionAttributeIndex);
|
||||
fHWGeometryState.setAttribArray(this,
|
||||
vertexAttribIndex,
|
||||
GrGLProgram::kPositionAttributeIndex,
|
||||
vb,
|
||||
GrGLProgram::kAttribLayouts[attribType].fCount,
|
||||
GrGLProgram::kAttribLayouts[attribType].fType,
|
||||
GrGLProgram::kAttribLayouts[attribType].fNormalized,
|
||||
2,
|
||||
GR_GL_FLOAT,
|
||||
false,
|
||||
stride,
|
||||
reinterpret_cast<GrGLvoid*>(
|
||||
vertexOffset + vertexAttrib->fOffset));
|
||||
reinterpret_cast<GrGLvoid*>(vertexOffset));
|
||||
if (texCoordOffset > 0) {
|
||||
usedAttribArraysMask |= (1 << GrGLProgram::kTexCoordAttributeIndex);
|
||||
GrGLvoid* texCoordPtr = reinterpret_cast<GrGLvoid*>(vertexOffset + texCoordOffset);
|
||||
fHWGeometryState.setAttribArray(this,
|
||||
GrGLProgram::kTexCoordAttributeIndex,
|
||||
vb,
|
||||
2,
|
||||
GR_GL_FLOAT,
|
||||
false,
|
||||
stride,
|
||||
texCoordPtr);
|
||||
}
|
||||
|
||||
if (colorOffset > 0) {
|
||||
usedAttribArraysMask |= (1 << GrGLProgram::kColorAttributeIndex);
|
||||
GrGLvoid* colorPtr = reinterpret_cast<GrGLvoid*>(vertexOffset + colorOffset);
|
||||
fHWGeometryState.setAttribArray(this,
|
||||
GrGLProgram::kColorAttributeIndex,
|
||||
vb,
|
||||
4,
|
||||
GR_GL_UNSIGNED_BYTE,
|
||||
true,
|
||||
stride,
|
||||
colorPtr);
|
||||
}
|
||||
|
||||
if (coverageOffset > 0) {
|
||||
usedAttribArraysMask |= (1 << GrGLProgram::kCoverageAttributeIndex);
|
||||
GrGLvoid* coveragePtr = reinterpret_cast<GrGLvoid*>(vertexOffset + coverageOffset);
|
||||
fHWGeometryState.setAttribArray(this,
|
||||
GrGLProgram::kCoverageAttributeIndex,
|
||||
vb,
|
||||
4,
|
||||
GR_GL_UNSIGNED_BYTE,
|
||||
true,
|
||||
stride,
|
||||
coveragePtr);
|
||||
}
|
||||
|
||||
if (edgeOffset > 0) {
|
||||
usedAttribArraysMask |= (1 << GrGLProgram::kEdgeAttributeIndex);
|
||||
GrGLvoid* edgePtr = reinterpret_cast<GrGLvoid*>(vertexOffset + edgeOffset);
|
||||
fHWGeometryState.setAttribArray(this,
|
||||
GrGLProgram::kEdgeAttributeIndex,
|
||||
vb,
|
||||
4,
|
||||
GR_GL_FLOAT,
|
||||
false,
|
||||
stride,
|
||||
edgePtr);
|
||||
}
|
||||
|
||||
fHWGeometryState.disableUnusedAttribArrays(this, usedAttribArraysMask);
|
||||
|
|
|
@ -75,5 +75,5 @@ void gr_run_unittests() {
|
|||
test_bsearch();
|
||||
test_binHashKey();
|
||||
GrRedBlackTree<int>::UnitTest();
|
||||
GrDrawState::VertexAttributesUnitTest();
|
||||
GrDrawState::VertexLayoutUnitTest();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
|
||||
const GrGpuGL* gpu,
|
||||
const GrEffectStage stages[GrDrawState::kNumStages]) {
|
||||
fAttribBindings = 0;
|
||||
fVertexLayout = 0;
|
||||
fEmitsPointSize = random->nextBool();
|
||||
fColorInput = random->nextULessThan(kColorInputCnt);
|
||||
fCoverageInput = random->nextULessThan(kColorInputCnt);
|
||||
|
@ -32,7 +32,7 @@ void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
|
|||
|
||||
fFirstCoverageStage = random->nextULessThan(GrDrawState::kNumStages);
|
||||
|
||||
fAttribBindings |= random->nextBool() ? GrDrawState::kCoverage_AttribBindingsBit : 0;
|
||||
fVertexLayout |= random->nextBool() ? GrDrawState::kCoverage_VertexLayoutBit : 0;
|
||||
|
||||
#if GR_GL_EXPERIMENTAL_GS
|
||||
fExperimentalGS = gpu->getCaps().geometryShaderSupport() && random->nextBool();
|
||||
|
@ -40,7 +40,7 @@ void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
|
|||
|
||||
bool edgeAA = random->nextBool();
|
||||
if (edgeAA) {
|
||||
fAttribBindings |= GrDrawState::kEdge_AttribBindingsBit;
|
||||
fVertexLayout |= GrDrawState::kEdge_VertexLayoutBit;
|
||||
if (gpu->getCaps().shaderDerivativeSupport()) {
|
||||
fVertexEdgeType = (GrDrawState::VertexEdgeType)
|
||||
random->nextULessThan(GrDrawState::kVertexEdgeTypeCnt);
|
||||
|
@ -64,31 +64,11 @@ void GrGLProgram::Desc::setRandom(SkMWCRandom* random,
|
|||
fEffectKeys[s] = factory.glEffectKey(stages[s], gpu->glCaps());
|
||||
// use separate tex coords?
|
||||
if (!useOnce && random->nextBool()) {
|
||||
fAttribBindings |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s);
|
||||
fVertexLayout |= GrDrawState::StageTexCoordVertexLayoutBit(s);
|
||||
useOnce = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::kEdge_AttribBindingsBit) {
|
||||
fEdgeAttributeIndex = attributeIndex;
|
||||
++attributeIndex;
|
||||
}
|
||||
if (GrDrawState::AttributesBindExplicitTexCoords(fAttribBindings)) {
|
||||
fTexCoordAttributeIndex = attributeIndex;
|
||||
++attributeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGpuGL::programUnitTest(int maxStages) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче