| |
| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| |
| #ifndef GrContext_impl_DEFINED |
| #define GrContext_impl_DEFINED |
| |
| template <typename POS_SRC, typename TEX_SRC, |
| typename COL_SRC, typename IDX_SRC> |
| inline void GrContext::drawCustomVertices(const GrPaint& paint, |
| GrPrimitiveType primitiveType, |
| const POS_SRC& posSrc, |
| const TEX_SRC* texCoordSrc, |
| const COL_SRC* colorSrc, |
| const IDX_SRC* idxSrc) { |
| |
| GrDrawTarget::AutoReleaseGeometry geo; |
| |
| GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); |
| |
| bool hasTexCoords[GrPaint::kTotalStages] = { |
| NULL != texCoordSrc, // texCoordSrc provides explicit stage 0 coords |
| 0 // remaining stages use positions |
| }; |
| GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); |
| |
| if (NULL != colorSrc) { |
| layout |= GrDrawTarget::kColor_VertexLayoutBit; |
| } |
| |
| int vertexCount = posSrc.count(); |
| int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0; |
| |
| if (!geo.set(target, layout, vertexCount, indexCount)) { |
| GrPrintf("Failed to get space for vertices!"); |
| return; |
| } |
| |
| int texOffsets[GrDrawTarget::kMaxTexCoords]; |
| int colorOffset; |
| int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, |
| texOffsets, |
| &colorOffset); |
| void* curVertex = geo.vertices(); |
| |
| for (int i = 0; i < vertexCount; ++i) { |
| posSrc.writeValue(i, (GrPoint*)curVertex); |
| |
| if (texOffsets[0] > 0) { |
| texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0])); |
| } |
| if (colorOffset > 0) { |
| colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset)); |
| } |
| curVertex = (void*)((intptr_t)curVertex + vsize); |
| } |
| |
| uint16_t* indices = (uint16_t*) geo.indices(); |
| for (int i = 0; i < indexCount; ++i) { |
| idxSrc->writeValue(i, indices + i); |
| } |
| |
| // we don't currently apply offscreen AA to this path. Need improved |
| // management of GrDrawTarget's geometry to avoid copying points per-tile. |
| |
| if (NULL == idxSrc) { |
| target->drawNonIndexed(primitiveType, 0, vertexCount); |
| } else { |
| target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); |
| } |
| } |
| |
| class GrNullTexCoordSource { |
| public: |
| void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); } |
| }; |
| |
| class GrNullColorSource { |
| public: |
| void writeValue(int i, GrColor* dstColor) const { GrAssert(false); } |
| }; |
| |
| class GrNullIndexSource { |
| public: |
| void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); } |
| int count() const { GrAssert(false); return 0; } |
| }; |
| |
| template <typename POS_SRC> |
| inline void GrContext::drawCustomVertices(const GrPaint& paint, |
| GrPrimitiveType primitiveType, |
| const POS_SRC& posSrc) { |
| this->drawCustomVertices<POS_SRC, |
| GrNullTexCoordSource, |
| GrNullColorSource, |
| GrNullIndexSource>(paint, primitiveType, posSrc, |
| NULL, NULL, NULL); |
| } |
| |
| template <typename POS_SRC, typename TEX_SRC> |
| inline void GrContext::drawCustomVertices(const GrPaint& paint, |
| GrPrimitiveType primitiveType, |
| const POS_SRC& posSrc, |
| const TEX_SRC* texCoordSrc) { |
| this->drawCustomVertices<POS_SRC, TEX_SRC, |
| GrNullColorSource, |
| GrNullIndexSource>(paint, primitiveType, posSrc, |
| texCoordSrc, NULL, NULL); |
| } |
| |
| template <typename POS_SRC, typename TEX_SRC, typename COL_SRC> |
| inline void GrContext::drawCustomVertices(const GrPaint& paint, |
| GrPrimitiveType primitiveType, |
| const POS_SRC& posSrc, |
| const TEX_SRC* texCoordSrc, |
| const COL_SRC* colorSrc) { |
| drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC, |
| GrNullIndexSource>(paint, primitiveType, posSrc, |
| texCoordSrc, colorSrc, NULL); |
| } |
| |
| #endif |