// This method fills int the four vertices for drawing 'rect'. // matrix - is applied to each vertex // srcRects - provide the uvs for each vertex // srcMatrices - are applied to the corresponding 'srcRect' // color - vertex color (replicated in each vertex) // layout - specifies which uvs and/or color are present // vertices - storage for the resulting vertices // Note: the color parameter will only be used when kColor_VertexLayoutBit // is present in 'layout' void GrDrawTarget::SetRectVertices(const GrRect& rect, const SkMatrix* matrix, const GrRect* srcRects[], const SkMatrix* srcMatrices[], GrColor color, GrVertexLayout layout, void* vertices) { #if GR_DEBUG // check that the layout and srcRects agree for (int i = 0; i < GrDrawState::kNumStages; ++i) { if (VertexTexCoordsForStage(i, layout) >= 0) { GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]); } else { GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]); } } #endif int stageOffsets[GrDrawState::kNumStages], colorOffset; int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset, NULL, NULL); GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize); if (NULL != matrix) { matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4); } for (int i = 0; i < GrDrawState::kNumStages; ++i) { if (stageOffsets[i] > 0) { GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + stageOffsets[i]); coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, srcRects[i]->fRight, srcRects[i]->fBottom, vsize); if (NULL != srcMatrices && NULL != srcMatrices[i]) { srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); } } } if (layout & kColor_VertexLayoutBit) { GrColor* vertCol = GrTCast<GrColor*>(GrTCast<intptr_t>(vertices) + colorOffset); for (int i = 0; i < 4; ++i) { *vertCol = color; vertCol = (GrColor*) ((intptr_t) vertCol + vsize); } } }
void GrGpu::setIndexSourceToArrayHelper(const void* indexArray, int indexCount) { GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount); prepareIndexPool(); #if GR_DEBUG bool success = #endif fIndexPool->appendIndices(indexCount, indexArray, &fCurrPoolIndexBuffer, &fCurrPoolStartIndex); GR_DEBUGASSERT(success); }
void GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) { this->prepareIndexPool(); GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); #if GR_DEBUG bool success = #endif fIndexPool->appendIndices(indexCount, indexArray, &geomPoolState.fPoolIndexBuffer, &geomPoolState.fPoolStartIndex); ++fIndexPoolUseCnt; GR_DEBUGASSERT(success); }
void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray, int indexCount) { GeometryPoolState& poolState = fGeoPoolStateStack.back(); GrAssert(0 == poolState.fUsedPoolIndexBytes); #if GR_DEBUG bool success = #endif fIndexPool.appendIndices(indexCount, indexArray, &poolState.fPoolIndexBuffer, &poolState.fPoolStartIndex); GR_DEBUGASSERT(success); }
void GrGpu::setVertexSourceToArrayHelper(const void* vertexArray, int vertexCount) { GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount); prepareVertexPool(); #if GR_DEBUG bool success = #endif fVertexPool->appendVertices(fGeometrySrc.fVertexLayout, vertexCount, vertexArray, &fCurrPoolVertexBuffer, &fCurrPoolStartVertex); GR_DEBUGASSERT(success); }
void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) { this->prepareVertexPool(); GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); #if GR_DEBUG bool success = #endif fVertexPool->appendVertices(this->getVertexSize(), vertexCount, vertexArray, &geomPoolState.fPoolVertexBuffer, &geomPoolState.fPoolStartVertex); ++fVertexPoolUseCnt; GR_DEBUGASSERT(success); }
GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu) { if (NULL == fAAStrokeRectIndexBuffer) { fAAStrokeRectIndexBuffer = gpu->createIndexBuffer(sizeof(gStrokeAARectIdx), false); if (NULL != fAAStrokeRectIndexBuffer) { #if GR_DEBUG bool updated = #endif fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, sizeof(gStrokeAARectIdx)); GR_DEBUGASSERT(updated); } } return fAAStrokeRectIndexBuffer; }
void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) { GeometryPoolState& poolState = fGeoPoolStateStack.back(); GrAssert(0 == poolState.fUsedPoolVertexBytes); #if GR_DEBUG bool success = #endif fVertexPool.appendVertices(this->getVertexSize(), vertexCount, vertexArray, &poolState.fPoolVertexBuffer, &poolState.fPoolStartVertex); GR_DEBUGASSERT(success); }
bool GrGLProgram::genProgram(GrGLProgram::CachedData* programData) const { ShaderCodeSegments segments; const uint32_t& layout = fProgramDesc.fVertexLayout; programData->fUniLocations.reset(); SkXfermode::Coeff colorCoeff, uniformCoeff; // The rest of transfer mode color filters have not been implemented if (fProgramDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { GR_DEBUGCODE(bool success =) SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> (fProgramDesc.fColorFilterXfermode), &uniformCoeff, &colorCoeff); GR_DEBUGASSERT(success); } else {
bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { GrAssert(0 == fProgramID); GrGLShaderBuilder builder(fContextInfo, fUniformManager); const uint32_t& layout = fDesc.fVertexLayout; #if GR_GL_EXPERIMENTAL_GS builder.fUsesGS = fDesc.fExperimentalGS; #endif SkXfermode::Coeff colorCoeff, uniformCoeff; // The rest of transfer mode color filters have not been implemented if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { GR_DEBUGCODE(bool success =) SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> (fDesc.fColorFilterXfermode), &uniformCoeff, &colorCoeff); GR_DEBUGASSERT(success); } else {
bool GrTesselatedPathRenderer::onDrawPath(const SkPath& path, GrPathFill fill, const GrVec* translate, GrDrawTarget* target, GrDrawState::StageMask stageMask, bool antiAlias) { GrDrawTarget::AutoStateRestore asr(target); GrDrawState* drawState = target->drawState(); // face culling doesn't make sense here GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace()); GrMatrix viewM = drawState->getViewMatrix(); GrScalar tol = GR_Scalar1; tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds()); GrScalar tolSqd = GrMul(tol, tol); int subpathCnt; int maxPts = GrPathUtils::worstCasePointCount(path, &subpathCnt, tol); GrVertexLayout layout = 0; for (int s = 0; s < GrDrawState::kNumStages; ++s) { if ((1 << s) & stageMask) { layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); } } bool inverted = GrIsFillInverted(fill); if (inverted) { maxPts += 4; subpathCnt++; } if (maxPts > USHRT_MAX) { return false; } SkAutoSTMalloc<8, GrPoint> baseMem(maxPts); GrPoint* base = baseMem; GrPoint* vert = base; GrPoint* subpathBase = base; SkAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt); GrPoint pts[4]; SkPath::Iter iter(path, false); bool first = true; int subpath = 0; for (;;) { switch (iter.next(pts)) { case kMove_PathCmd: if (!first) { subpathVertCount[subpath] = vert-subpathBase; subpathBase = vert; ++subpath; } *vert = pts[0]; vert++; break; case kLine_PathCmd: *vert = pts[1]; vert++; break; case kQuadratic_PathCmd: { GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], tolSqd, &vert, GrPathUtils::quadraticPointCount(pts, tol)); break; } case kCubic_PathCmd: { GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], tolSqd, &vert, GrPathUtils::cubicPointCount(pts, tol)); break; } case kClose_PathCmd: break; case kEnd_PathCmd: subpathVertCount[subpath] = vert-subpathBase; ++subpath; // this could be only in debug goto FINISHED; } first = false; } FINISHED: if (NULL != translate && 0 != translate->fX && 0 != translate->fY) { for (int i = 0; i < vert - base; i++) { base[i].offset(translate->fX, translate->fY); } } if (inverted) { GrRect bounds; GrAssert(NULL != drawState->getRenderTarget()); bounds.setLTRB(0, 0, GrIntToScalar(drawState->getRenderTarget()->width()), GrIntToScalar(drawState->getRenderTarget()->height())); GrMatrix vmi; if (drawState->getViewInverse(&vmi)) { vmi.mapRect(&bounds); } *vert++ = GrPoint::Make(bounds.fLeft, bounds.fTop); *vert++ = GrPoint::Make(bounds.fLeft, bounds.fBottom); *vert++ = GrPoint::Make(bounds.fRight, bounds.fBottom); *vert++ = GrPoint::Make(bounds.fRight, bounds.fTop); subpathVertCount[subpath++] = 4; } GrAssert(subpath == subpathCnt); GrAssert((vert - base) <= maxPts); size_t count = vert - base; if (count < 3) { return true; } if (subpathCnt == 1 && !inverted && path.isConvex()) { if (antiAlias) { GrEdgeArray edges; GrMatrix inverse, matrix = drawState->getViewMatrix(); drawState->getViewInverse(&inverse); count = computeEdgesAndIntersect(matrix, inverse, base, count, &edges, 0.0f); size_t maxEdges = target->getMaxEdges(); if (count == 0) { return true; } if (count <= maxEdges) { // All edges fit; upload all edges and draw all verts as a fan target->setVertexSourceToArray(layout, base, count); drawState->setEdgeAAData(&edges[0], count); target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); } else { // Upload "maxEdges" edges and verts at a time, and draw as // separate fans for (size_t i = 0; i < count - 2; i += maxEdges - 2) { edges[i] = edges[0]; base[i] = base[0]; int size = GR_CT_MIN(count - i, maxEdges); target->setVertexSourceToArray(layout, &base[i], size); drawState->setEdgeAAData(&edges[i], size); target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size); } } drawState->setEdgeAAData(NULL, 0); } else { target->setVertexSourceToArray(layout, base, count); target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); } return true; } if (antiAlias) { // Run the tesselator once to get the boundaries. GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fill)); btess.addVertices(base, subpathVertCount, subpathCnt); GrMatrix inverse, matrix = drawState->getViewMatrix(); if (!drawState->getViewInverse(&inverse)) { return false; } if (btess.vertices().count() > USHRT_MAX) { return false; } // Inflate the boundary, and run the tesselator again to generate // interior polys. const GrPointArray& contourPoints = btess.contourPoints(); const GrIndexArray& contours = btess.contours(); GrEdgePolygonTess ptess(contourPoints.count(), GLU_TESS_WINDING_NONZERO, matrix); size_t i = 0; Sk_gluTessBeginPolygon(ptess.tess(), &ptess); for (int contour = 0; contour < contours.count(); ++contour) { int count = contours[contour]; GrEdgeArray edges; int newCount = computeEdgesAndIntersect(matrix, inverse, &btess.contourPoints()[i], count, &edges, 1.0f); Sk_gluTessBeginContour(ptess.tess()); for (int j = 0; j < newCount; j++) { ptess.addVertex(contourPoints[i + j], ptess.vertices().count()); } i += count; Sk_gluTessEndContour(ptess.tess()); } Sk_gluTessEndPolygon(ptess.tess()); if (ptess.vertices().count() > USHRT_MAX) { return false; } // Draw the resulting polys and upload their edge data. drawState->enableState(GrDrawState::kEdgeAAConcave_StateBit); const GrPointArray& vertices = ptess.vertices(); const GrIndexArray& indices = ptess.indices(); const GrDrawState::Edge* edges = ptess.edges(); GR_DEBUGASSERT(indices.count() % 3 == 0); for (int i = 0; i < indices.count(); i += 3) { GrPoint tri_verts[3]; int index0 = indices[i]; int index1 = indices[i + 1]; int index2 = indices[i + 2]; tri_verts[0] = vertices[index0]; tri_verts[1] = vertices[index1]; tri_verts[2] = vertices[index2]; GrDrawState::Edge tri_edges[6]; int t = 0; const GrDrawState::Edge& edge0 = edges[index0 * 2]; const GrDrawState::Edge& edge1 = edges[index0 * 2 + 1]; const GrDrawState::Edge& edge2 = edges[index1 * 2]; const GrDrawState::Edge& edge3 = edges[index1 * 2 + 1]; const GrDrawState::Edge& edge4 = edges[index2 * 2]; const GrDrawState::Edge& edge5 = edges[index2 * 2 + 1]; if (validEdge(edge0) && validEdge(edge1)) { tri_edges[t++] = edge0; tri_edges[t++] = edge1; } if (validEdge(edge2) && validEdge(edge3)) { tri_edges[t++] = edge2; tri_edges[t++] = edge3; } if (validEdge(edge4) && validEdge(edge5)) { tri_edges[t++] = edge4; tri_edges[t++] = edge5; } drawState->setEdgeAAData(&tri_edges[0], t); target->setVertexSourceToArray(layout, &tri_verts[0], 3); target->drawNonIndexed(kTriangles_PrimitiveType, 0, 3); } drawState->setEdgeAAData(NULL, 0); drawState->disableState(GrDrawState::kEdgeAAConcave_StateBit); return true; } GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fill)); ptess.addVertices(base, subpathVertCount, subpathCnt); const GrPointArray& vertices = ptess.vertices(); const GrIndexArray& indices = ptess.indices(); if (indices.count() > 0) { target->setVertexSourceToArray(layout, vertices.begin(), vertices.count()); target->setIndexSourceToArray(indices.begin(), indices.count()); target->drawIndexed(kTriangles_PrimitiveType, 0, 0, vertices.count(), indices.count()); } return true; }
virtual void begin(GLenum type) { GR_DEBUGASSERT(type == GL_TRIANGLES); int count = fVertices.count() * 2; fEdges = new GrDrawState::Edge[count]; memset(fEdges, 0, count * sizeof(GrDrawState::Edge)); }
virtual void begin(GLenum type) { GR_DEBUGASSERT(type == GL_TRIANGLES); }