From 74749cd45c29b4f5300e2518f2c2c765ce8ae208 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Wed, 30 Jan 2013 16:12:41 +0000 Subject: [PATCH] Add GrDrawTarget::DrawInfo, combine API for performing indexed/non-indexed draws in subclasses. Review URL: https://codereview.appspot.com/7237045 git-svn-id: http://skia.googlecode.com/svn/trunk@7466 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/GrDrawTarget.cpp | 24 +++-- src/gpu/GrDrawTarget.h | 40 ++++++-- src/gpu/GrGpu.cpp | 35 +------ src/gpu/GrGpu.h | 36 +------- src/gpu/GrInOrderDrawBuffer.cpp | 156 +++++++++++--------------------- src/gpu/GrInOrderDrawBuffer.h | 17 ++-- src/gpu/gl/GrGpuGL.cpp | 64 ++++--------- src/gpu/gl/GrGpuGL.h | 24 ++--- src/gpu/gl/GrGpuGL_program.cpp | 38 +++----- 9 files changed, 158 insertions(+), 276 deletions(-) diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 3898426af0..d2d1d8d347 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -341,20 +341,28 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex, int startIndex, int vertexCount, int indexCount) { - if (indexCount > 0 && - this->checkDraw(type, startVertex, startIndex, - vertexCount, indexCount)) { - this->onDrawIndexed(type, startVertex, startIndex, - vertexCount, indexCount); + if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) { + DrawInfo info; + info.fPrimitiveType = type; + info.fStartVertex = startVertex; + info.fStartIndex = startIndex; + info.fVertexCount = vertexCount; + info.fIndexCount = indexCount; + this->onDraw(info); } } void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, int startVertex, int vertexCount) { - if (vertexCount > 0 && - this->checkDraw(type, startVertex, -1, vertexCount, -1)) { - this->onDrawNonIndexed(type, startVertex, vertexCount); + if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) { + DrawInfo info; + info.fPrimitiveType = type; + info.fStartVertex = startVertex; + info.fStartIndex = 0; + info.fVertexCount = vertexCount; + info.fIndexCount = 0; + this->onDraw(info); } } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 74d820b7f7..2d1ca6cbaf 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -727,6 +727,37 @@ protected: Caps fCaps; + class DrawInfo { + public: + DrawInfo(const DrawInfo& di) { (*this) = di; } + DrawInfo& operator =(const DrawInfo& di) { + fPrimitiveType = di.fPrimitiveType; + fStartVertex = di.fStartVertex; + fStartIndex = di.fStartIndex; + fVertexCount = di.fVertexCount; + fIndexCount = di.fIndexCount; + return *this; + } + + GrPrimitiveType primitiveType() const { return fPrimitiveType; } + int startVertex() const { return fStartVertex; } + int startIndex() const { return fStartIndex; } + int vertexCount() const { return fVertexCount; } + int indexCount() const { return fIndexCount; } + + bool isIndexed() const { return fIndexCount > 0; } + + private: + DrawInfo() {} + friend class GrDrawTarget; + GrPrimitiveType fPrimitiveType; + + int fStartVertex; + int fStartIndex; + int fVertexCount; + int fIndexCount; + }; + private: // A subclass can optionally overload this function to be notified before // vertex and index space is reserved. @@ -748,14 +779,7 @@ private: virtual void geometrySourceWillPush() = 0; virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0; // subclass called to perform drawing - virtual void onDrawIndexed(GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) = 0; - virtual void onDrawNonIndexed(GrPrimitiveType type, - int startVertex, - int vertexCount) = 0; + virtual void onDraw(const DrawInfo&) = 0; virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill) = 0; // helpers for reserving vertex and index space. diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index b32c56aaf6..b0ce7fe82e 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -371,45 +371,18 @@ void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) { fGeomPoolStateStack.pop_back(); } -void GrGpu::onDrawIndexed(GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) { - +void GrGpu::onDraw(const DrawInfo& info) { this->handleDirtyContext(); - - if (!this->setupClipAndFlushState(PrimTypeToDrawType(type))) { + if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()))) { return; } - - int sVertex = startVertex; - int sIndex = startIndex; - setupGeometry(&sVertex, &sIndex, vertexCount, indexCount); - - this->onGpuDrawIndexed(type, sVertex, sIndex, - vertexCount, indexCount); -} - -void GrGpu::onDrawNonIndexed(GrPrimitiveType type, - int startVertex, - int vertexCount) { - this->handleDirtyContext(); - - if (!this->setupClipAndFlushState(PrimTypeToDrawType(type))) { - return; - } - - int sVertex = startVertex; - setupGeometry(&sVertex, NULL, vertexCount, 0); - - this->onGpuDrawNonIndexed(type, sVertex, vertexCount); + this->onGpuDraw(info); } void GrGpu::onStencilPath(const GrPath* path, const SkStrokeRec&, SkPath::FillType fill) { this->handleDirtyContext(); - // TODO: make this more effecient (don't copy and copy back) + // TODO: make this more efficient (don't copy and copy back) GrAutoTRestore asr(this->drawState()->stencil()); this->setStencilPathSettings(*path, fill, this->drawState()->stencil()); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 573ef0a3f8..ebfc60fdd8 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -317,7 +317,7 @@ public: /** * These methods are called by the clip manager's setupClipping function - * which (called as part of GrGpu's implementation of onDraw* and + * which (called as part of GrGpu's implementation of onDraw and * onStencilPath member functions.) The GrGpu subclass should flush the * stencil state to the 3D API in its implementation of flushGraphicsState. */ @@ -454,15 +454,7 @@ private: virtual void onClear(const GrIRect* rect, GrColor color) = 0; // overridden by backend-specific derived class to perform the draw call. - virtual void onGpuDrawIndexed(GrPrimitiveType type, - uint32_t startVertex, - uint32_t startIndex, - uint32_t vertexCount, - uint32_t indexCount) = 0; - - virtual void onGpuDrawNonIndexed(GrPrimitiveType type, - uint32_t vertexCount, - uint32_t numVertices) = 0; + virtual void onGpuDraw(const DrawInfo&) = 0; // when GrDrawTarget::stencilPath is called the draw state's current stencil // settings are ignored. Instead the GrGpu decides the stencil rules // necessary to stencil the path. These are still subject to filtering by @@ -493,24 +485,13 @@ private: // overridden by backend-specific derived class to perform the resolve virtual void onResolveRenderTarget(GrRenderTarget* target) = 0; - // called to program the vertex data, indexCount will be 0 if drawing non- - // indexed geometry. The subclass may adjust the startVertex and/or - // startIndex since it may have already accounted for these in the setup. - virtual void setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount) = 0; - // width and height may be larger than rt (if underlying API allows it). // Should attach the SB to the RT. Returns false if compatible sb could // not be created. - virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt, - int width, - int height) = 0; + virtual bool createStencilBufferForRenderTarget(GrRenderTarget*, int width, int height) = 0; // attaches an existing SB to an existing RT. - virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb, - GrRenderTarget* rt) = 0; + virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer*, GrRenderTarget*) = 0; // The GrGpu typically records the clients requested state and then flushes // deltas from previous state at draw time. This function does the @@ -525,14 +506,7 @@ private: bool attachStencilBufferToRenderTarget(GrRenderTarget* target); // GrDrawTarget overrides - virtual void onDrawIndexed(GrPrimitiveType type, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) SK_OVERRIDE; - virtual void onDrawNonIndexed(GrPrimitiveType type, - int startVertex, - int vertexCount) SK_OVERRIDE; + virtual void onDraw(const DrawInfo&) SK_OVERRIDE; virtual void onStencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 7e83589443..197cf0bac2 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -217,7 +217,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, int vsize = GrDrawState::VertexSize(layout); - Draw& lastDraw = fDraws.back(); + DrawRecord& lastDraw = fDraws.back(); GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer); GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType); @@ -227,10 +227,10 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, GeometryPoolState& poolState = fGeoPoolStateStack.back(); - appendToPreviousDraw = - kDraw_Cmd == fCmds.back() && - lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer && - (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex; + appendToPreviousDraw = kDraw_Cmd == fCmds.back() && + lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer && + (fCurrQuad * 4 + lastDraw.fStartVertex) == + poolState.fPoolStartVertex; if (appendToPreviousDraw) { lastDraw.fVertexCount += 4; @@ -279,7 +279,7 @@ void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type, this->recordState(); } - Draw* draw = NULL; + DrawRecord* draw = NULL; // if the last draw used the same indices/vertices per shape then we // may be able to append to it. if (kDraw_Cmd == fCmds.back() && @@ -371,18 +371,9 @@ void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type, verticesPerInstance, indicesPerInstance); } - } -void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) { - - if (!vertexCount || !indexCount) { - return; - } +void GrInOrderDrawBuffer::onDraw(const DrawInfo& info) { this->resetDrawTracking(); @@ -395,98 +386,49 @@ void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType, this->recordState(); } - Draw* draw = this->recordDraw(); - - draw->fPrimitiveType = primitiveType; - draw->fStartVertex = startVertex; - draw->fStartIndex = startIndex; - draw->fVertexCount = vertexCount; - draw->fIndexCount = indexCount; - + DrawRecord* draw = this->recordDraw(info); draw->fVertexLayout = this->getVertexLayout(); + switch (this->getGeomSrc().fVertexSrc) { - case kBuffer_GeometrySrcType: - draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer; - break; - case kReserved_GeometrySrcType: // fallthrough - case kArray_GeometrySrcType: { - size_t vertexBytes = (vertexCount + startVertex) * - GrDrawState::VertexSize(draw->fVertexLayout); - poolState.fUsedPoolVertexBytes = - GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); - draw->fVertexBuffer = poolState.fPoolVertexBuffer; - draw->fStartVertex += poolState.fPoolStartVertex; - break; - } - default: - GrCrash("unknown geom src type"); + case kBuffer_GeometrySrcType: + draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer; + break; + case kReserved_GeometrySrcType: // fallthrough + case kArray_GeometrySrcType: { + size_t vertexBytes = (info.vertexCount() + info.startVertex()) * + GrDrawState::VertexSize(draw->fVertexLayout); + poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); + draw->fVertexBuffer = poolState.fPoolVertexBuffer; + draw->fStartVertex += poolState.fPoolStartVertex; + break; + } + default: + GrCrash("unknown geom src type"); } draw->fVertexBuffer->ref(); - switch (this->getGeomSrc().fIndexSrc) { - case kBuffer_GeometrySrcType: - draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer; - break; - case kReserved_GeometrySrcType: // fallthrough - case kArray_GeometrySrcType: { - size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t); - poolState.fUsedPoolIndexBytes = - GrMax(poolState.fUsedPoolIndexBytes, indexBytes); - draw->fIndexBuffer = poolState.fPoolIndexBuffer; - draw->fStartIndex += poolState.fPoolStartIndex; - break; + if (info.isIndexed()) { + switch (this->getGeomSrc().fIndexSrc) { + case kBuffer_GeometrySrcType: + draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer; + break; + case kReserved_GeometrySrcType: // fallthrough + case kArray_GeometrySrcType: { + size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t); + poolState.fUsedPoolIndexBytes = GrMax(poolState.fUsedPoolIndexBytes, indexBytes); + draw->fIndexBuffer = poolState.fPoolIndexBuffer; + draw->fStartIndex += poolState.fPoolStartIndex; + break; + } + default: + GrCrash("unknown geom src type"); + } + draw->fIndexBuffer->ref(); + } else { + draw->fIndexBuffer = NULL; } - default: - GrCrash("unknown geom src type"); - } - draw->fIndexBuffer->ref(); } -void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType, - int startVertex, - int vertexCount) { - if (!vertexCount) { - return; - } - - this->resetDrawTracking(); - - GeometryPoolState& poolState = fGeoPoolStateStack.back(); - if (this->needsNewClip()) { - this->recordClip(); - } - if (this->needsNewState()) { - this->recordState(); - } - - Draw* draw = this->recordDraw(); - draw->fPrimitiveType = primitiveType; - draw->fStartVertex = startVertex; - draw->fStartIndex = 0; - draw->fVertexCount = vertexCount; - draw->fIndexCount = 0; - - draw->fVertexLayout = this->getVertexLayout(); - switch (this->getGeomSrc().fVertexSrc) { - case kBuffer_GeometrySrcType: - draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer; - break; - case kReserved_GeometrySrcType: // fallthrough - case kArray_GeometrySrcType: { - size_t vertexBytes = (vertexCount + startVertex) * - GrDrawState::VertexSize(draw->fVertexLayout); - poolState.fUsedPoolVertexBytes = - GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); - draw->fVertexBuffer = poolState.fPoolVertexBuffer; - draw->fStartVertex += poolState.fPoolStartVertex; - break; - } - default: - GrCrash("unknown geom src type"); - } - draw->fVertexBuffer->ref(); - draw->fIndexBuffer = NULL; -} GrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {} @@ -588,7 +530,7 @@ bool GrInOrderDrawBuffer::flushTo(GrDrawTarget* target) { for (int c = 0; c < numCmds; ++c) { switch (fCmds[c]) { case kDraw_Cmd: { - const Draw& draw = fDraws[currDraw]; + const DrawRecord& draw = fDraws[currDraw]; target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer); if (draw.fIndexCount) { target->setIndexSourceToBuffer(draw.fIndexBuffer); @@ -892,11 +834,21 @@ void GrInOrderDrawBuffer::recordState() { fCmds.push_back(kSetState_Cmd); } -GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() { +GrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw() { fCmds.push_back(kDraw_Cmd); return &fDraws.push_back(); } +GrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) { + DrawRecord* record = this->recordDraw(); + record->fPrimitiveType = info.primitiveType(); + record->fStartVertex = info.startVertex(); + record->fVertexCount = info.vertexCount(); + record->fStartIndex = info.startIndex(); + record->fIndexCount = info.indexCount(); + return record; +} + GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() { fCmds.push_back(kStencilPath_Cmd); return &fStencilPaths.push_back(); diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 38cc89032d..353d5bff52 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -120,7 +120,8 @@ private: kClear_Cmd = 5, }; - struct Draw { + // TODO: Make this derive from DrawInfo + struct DrawRecord { GrPrimitiveType fPrimitiveType; int fStartVertex; int fStartIndex; @@ -149,14 +150,7 @@ private: }; // overrides from GrDrawTarget - virtual void onDrawIndexed(GrPrimitiveType primitiveType, - int startVertex, - int startIndex, - int vertexCount, - int indexCount) SK_OVERRIDE; - virtual void onDrawNonIndexed(GrPrimitiveType primitiveType, - int startVertex, - int vertexCount) SK_OVERRIDE; + virtual void onDraw(const DrawInfo&) SK_OVERRIDE; virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; virtual bool onReserveVertexSpace(GrVertexLayout layout, int vertexCount, @@ -186,7 +180,8 @@ private: // these functions record a command void recordState(); void recordClip(); - Draw* recordDraw(); + DrawRecord* recordDraw(); + DrawRecord* recordDraw(const DrawInfo&); StencilPath* recordStencilPath(); Clear* recordClear(); @@ -205,7 +200,7 @@ private: }; SkSTArray fCmds; - GrSTAllocator fDraws; + GrSTAllocator fDraws; GrSTAllocator fStencilPaths; GrSTAllocator fStates; GrSTAllocator fClears; diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index a1a5bee5f2..7ca07a0623 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1606,53 +1606,28 @@ GrGLenum gPrimitiveType2GLMode[] = { #endif #endif -void GrGpuGL::onGpuDrawIndexed(GrPrimitiveType type, - uint32_t startVertex, - uint32_t startIndex, - uint32_t vertexCount, - uint32_t indexCount) { - GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); +void GrGpuGL::onGpuDraw(const DrawInfo& info) { + int extraStartIndexOffset; + this->setupGeometry(info, &extraStartIndexOffset); - GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex); - - GrAssert(NULL != fHWGeometryState.fIndexBuffer); + GrAssert((size_t)info.primitiveType() < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); GrAssert(NULL != fHWGeometryState.fVertexBuffer); - // our setupGeometry better have adjusted this to zero since - // DrawElements always draws from the begining of the arrays for idx 0. - GrAssert(0 == startVertex); - - GL_CALL(DrawElements(gPrimitiveType2GLMode[type], indexCount, - GR_GL_UNSIGNED_SHORT, indices)); -#if SWAP_PER_DRAW - glFlush(); - #if GR_MAC_BUILD - aglSwapBuffers(aglGetCurrentContext()); - int set_a_break_pt_here = 9; - aglSwapBuffers(aglGetCurrentContext()); - #elif GR_WIN32_BUILD - SwapBuf(); - int set_a_break_pt_here = 9; - SwapBuf(); - #endif -#endif -} - -void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type, - uint32_t startVertex, - uint32_t vertexCount) { - GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); - - GrAssert(NULL != fHWGeometryState.fVertexBuffer); - - // our setupGeometry better have adjusted this to zero. - // DrawElements doesn't take an offset so we always adjus the startVertex. - GrAssert(0 == startVertex); - - // pass 0 for parameter first. We have to adjust gl*Pointer() to - // account for startVertex in the DrawElements case. So we always - // rely on setupGeometry to have accounted for startVertex. - GL_CALL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount)); + if (info.isIndexed()) { + GrAssert(NULL != fHWGeometryState.fIndexBuffer); + GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * (info.startIndex() + + extraStartIndexOffset)); + // info.startVertex() was accounted for by setupGeometry. + GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()], + info.indexCount(), + GR_GL_UNSIGNED_SHORT, + indices)); + } else { + // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for + // startVertex in the DrawElements case. So we always rely on setupGeometry to have + // accounted for startVertex. + GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount())); + } #if SWAP_PER_DRAW glFlush(); #if GR_MAC_BUILD @@ -1688,7 +1663,6 @@ const GrStencilSettings& even_odd_nv_path_stencil_settings() { } } - void GrGpuGL::setStencilPathSettings(const GrPath&, SkPath::FillType fill, GrStencilSettings* settings) { diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 0210c6560e..3b8c16fabf 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -96,14 +96,7 @@ private: virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE; - virtual void onGpuDrawIndexed(GrPrimitiveType type, - uint32_t startVertex, - uint32_t startIndex, - uint32_t vertexCount, - uint32_t indexCount) SK_OVERRIDE; - virtual void onGpuDrawNonIndexed(GrPrimitiveType type, - uint32_t vertexCount, - uint32_t numVertices) SK_OVERRIDE; + virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE; virtual void setStencilPathSettings(const GrPath&, SkPath::FillType, @@ -115,22 +108,23 @@ private: virtual void clearStencilClip(const GrIRect& rect, bool insideClip) SK_OVERRIDE; virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; - virtual void setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount) SK_OVERRIDE; const GrGLCaps& glCaps() const { return fGLContextInfo.caps(); } // binds texture unit in GL void setTextureUnit(int unitIdx); - // binds appropriate vertex and index buffers, also returns any extra - // extra verts or indices to offset by. + // Sets up vertex attribute pointers and strides. On return startIndexOffset specifies an + // offset into the index buffer to the first index to be read (in addition to + // info.startIndex()). It accounts for the fact that index buffer pool may have provided space + // in the middle of a larger index buffer. + void setupGeometry(const DrawInfo& info, int* startIndexOffset); + // binds appropriate vertex and index buffers, also returns any extra verts or indices to + // offset by based on how space was allocated in pool VB/IBs. void setBuffers(bool indexed, int* extraVertexOffset, int* extraIndexOffset); // Subclasses should call this to flush the blend state. - // The params should be the final coeffecients to apply + // The params should be the final coefficients to apply // (after any blending optimizations or dual source blending considerations // have been accounted for). void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index d1a60fab2c..d5e8fbdd79 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -340,10 +340,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { #error "unknown GR_TEXT_SCALAR type" #endif -void GrGpuGL::setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount) { +void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) { int newColorOffset; int newCoverageOffset; @@ -352,28 +349,24 @@ void GrGpuGL::setupGeometry(int* startVertex, GrVertexLayout currLayout = this->getVertexLayout(); - GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx( - currLayout, - newTexCoordOffsets, - &newColorOffset, - &newCoverageOffset, - &newEdgeOffset); + GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(currLayout, + newTexCoordOffsets, + &newColorOffset, + &newCoverageOffset, + &newEdgeOffset); int oldColorOffset; int oldCoverageOffset; int oldTexCoordOffsets[GrDrawState::kMaxTexCoords]; int oldEdgeOffset; - GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx( - fHWGeometryState.fVertexLayout, - oldTexCoordOffsets, - &oldColorOffset, - &oldCoverageOffset, - &oldEdgeOffset); - bool indexed = NULL != startIndex; + GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout, + oldTexCoordOffsets, + &oldColorOffset, + &oldCoverageOffset, + &oldEdgeOffset); int extraVertexOffset; - int extraIndexOffset; - this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset); + this->setBuffers(info.isIndexed(), &extraVertexOffset, startIndexOffset); GrGLenum scalarType; bool texCoordNorm; @@ -381,16 +374,11 @@ void GrGpuGL::setupGeometry(int* startVertex, scalarType = TEXT_COORDS_GL_TYPE; texCoordNorm = SkToBool(TEXT_COORDS_ARE_NORMALIZED); } else { -// GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); scalarType = GR_GL_FLOAT; texCoordNorm = false; } - size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride; - *startVertex = 0; - if (indexed) { - *startIndex += extraIndexOffset; - } + size_t vertexOffset = (info.startVertex() + extraVertexOffset) * newStride; // all the Pointers must be set if any of these are true bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||