From: bsalomon@google.com Date: Thu, 8 Dec 2011 16:12:03 +0000 (+0000) Subject: Revert 2830 and 2831. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~17164 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d0835b6ac0003c18147b6e9ca76a497b92d1d40;p=platform%2Fupstream%2FlibSkiaSharp.git Revert 2830 and 2831. git-svn-id: http://skia.googlecode.com/svn/trunk@2832 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index 1806797..e306b67 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -702,8 +702,7 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) { int nBufLines = fLinesIndexBuffer->maxQuads(); while (lines < fLineSegmentCnt) { int n = GrMin(fLineSegmentCnt-lines, nBufLines); - fTarget->drawState()->setVertexEdgeType( - GrDrawState::kHairLine_EdgeType); + fTarget->setVertexEdgeType(GrDrawState::kHairLine_EdgeType); fTarget->drawIndexed(kTriangles_PrimitiveType, kVertsPerLineSeg*lines, // startV 0, // startI @@ -716,8 +715,7 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) { int quads = 0; while (quads < fQuadCnt) { int n = GrMin(fQuadCnt-quads, kNumQuadsInIdxBuffer); - fTarget->drawState()->setVertexEdgeType( - GrDrawState::kHairQuad_EdgeType); + fTarget->setVertexEdgeType(GrDrawState::kHairQuad_EdgeType); fTarget->drawIndexed(kTriangles_PrimitiveType, 4*fLineSegmentCnt + kVertsPerQuad*quads, // startV 0, // startI diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index a792bd1..de80f65 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -217,17 +217,21 @@ void gen_stencil_key_values(const GrStencilBuffer* sb, // It does not reset stage textures/samplers or per-vertex-edge-aa state since // they aren't used unless the vertex layout references them. // It also doesn't set the render target. -void reset_target_state(GrDrawState* drawState) { - drawState->setViewMatrix(GrMatrix::I()); - drawState->setColorFilter(0, SkXfermode::kDst_Mode); - drawState->resetStateFlags(); - drawState->setEdgeAAData(NULL, 0); - drawState->disableStencil(); - drawState->setAlpha(0xFF); - drawState->setBlendFunc(kOne_BlendCoeff, - kZero_BlendCoeff); - drawState->setFirstCoverageStage(GrDrawState::kNumStages); - drawState->setDrawFace(GrDrawState::kBoth_DrawFace); +void reset_target_state(GrDrawTarget* target){ + target->setViewMatrix(GrMatrix::I()); + target->setColorFilter(0, SkXfermode::kDst_Mode); + target->disableState(GrDrawTarget::kDither_StateBit | + GrDrawTarget::kHWAntialias_StateBit | + GrDrawTarget::kClip_StateBit | + GrDrawTarget::kNoColorWrites_StateBit | + GrDrawTarget::kEdgeAAConcave_StateBit); + target->setEdgeAAData(NULL, 0); + target->disableStencil(); + target->setAlpha(0xFF); + target->setBlendFunc(kOne_BlendCoeff, + kZero_BlendCoeff); + target->setFirstCoverageStage(GrDrawState::kNumStages); + target->setDrawFace(GrDrawState::kBoth_DrawFace); } } @@ -348,7 +352,7 @@ GrContext::TextureCacheEntry GrContext::createAndLockTexture(TextureKey key, if (NULL != texture) { GrDrawTarget::AutoStateRestore asr(fGpu); - reset_target_state(fGpu->drawState()); + reset_target_state(fGpu); fGpu->setRenderTarget(texture->asRenderTarget()); fGpu->setTexture(0, clampEntry.texture()); @@ -597,7 +601,7 @@ const GrClip& GrContext::getClip() const { return fGpu->getClip(); } void GrContext::setClip(const GrClip& clip) { fGpu->setClip(clip); - fGpu->drawState()->enableState(GrDrawState::kClip_StateBit); + fGpu->enableState(GrDrawTarget::kClip_StateBit); } void GrContext::setClip(const GrIRect& rect) { @@ -802,13 +806,14 @@ void GrContext::setupOffscreenAAPass1(GrDrawTarget* target, target->enableState(GrDrawTarget::kHWAntialias_StateBit); #endif + GrMatrix transM; int left = boundRect.fLeft + tileX * record->fTileSizeX; int top = boundRect.fTop + tileY * record->fTileSizeY; - GrDrawState* drawState = target->drawState(); - drawState->viewMatrix()->postTranslate(-left * GR_Scalar1, - -top * GR_Scalar1); - drawState->viewMatrix()->postScale(record->fScale * GR_Scalar1, - record->fScale * GR_Scalar1); + transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1); + target->postConcatViewMatrix(transM); + GrMatrix scaleM; + scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1); + target->postConcatViewMatrix(scaleM); int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left : record->fTileSizeX; @@ -1322,7 +1327,7 @@ void GrContext::drawRect(const GrPaint& paint, GrDrawTarget::AutoViewMatrixRestore avmr; if (NULL != matrix) { avmr.set(target); - target->viewMatrix()->preConcat(*matrix); + target->preConcatViewMatrix(*matrix); target->preConcatSamplerMatrices(stageMask, *matrix); } @@ -1346,7 +1351,7 @@ void GrContext::drawRect(const GrPaint& paint, m.postConcat(*matrix); } - target->viewMatrix()->preConcat(m); + target->preConcatViewMatrix(m); target->preConcatSamplerMatrices(stageMask, m); target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); @@ -1373,8 +1378,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, #if GR_STATIC_RECT_VB GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - GrDrawState* drawState = target->drawState(); - + GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); GrDrawTarget::AutoViewMatrixRestore avmr(target); @@ -1386,13 +1390,13 @@ void GrContext::drawRectToRect(const GrPaint& paint, if (NULL != dstMatrix) { m.postConcat(*dstMatrix); } - drawState->viewMatrix()->preConcat(m); + target->preConcatViewMatrix(m); // srcRect refers to first stage int otherStageMask = paint.getActiveStageMask() & (~(1 << GrPaint::kFirstTextureStage)); if (otherStageMask) { - drawState->preConcatSamplerMatrices(otherStageMask, m); + target->preConcatSamplerMatrices(otherStageMask, m); } m.setAll(srcRect.width(), 0, srcRect.fLeft, @@ -1401,7 +1405,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, if (NULL != srcMatrix) { m.postConcat(*srcMatrix); } - drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); + target->preConcatSamplerMatrix(GrPaint::kFirstTextureStage, m); const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); if (NULL == sqVB) { @@ -1777,7 +1781,7 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, GrAssert(NULL != target); GrDrawTarget::AutoStateRestore asr(fGpu); - reset_target_state(fGpu->drawState()); + reset_target_state(fGpu); fGpu->setRenderTarget(target); @@ -1815,7 +1819,7 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { ASSERT_OWNED_RESOURCE(src); GrDrawTarget::AutoStateRestore asr(fGpu); - reset_target_state(fGpu->drawState()); + reset_target_state(fGpu); fGpu->setRenderTarget(dst); GrSamplerState sampler(GrSamplerState::kClamp_WrapMode, GrSamplerState::kNearest_Filter); @@ -1885,7 +1889,7 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, config, buffer, rowBytes, flags); GrDrawTarget::AutoStateRestore asr(fGpu); - reset_target_state(fGpu->drawState()); + reset_target_state(fGpu); GrMatrix matrix; matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); @@ -1916,8 +1920,6 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, void GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { - GrDrawState* drawState = target->drawState(); - for (int i = 0; i < GrPaint::kMaxTextures; ++i) { int s = i + GrPaint::kFirstTextureStage; target->setTexture(s, paint.getTexture(i)); @@ -1934,20 +1936,20 @@ void GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { target->setSamplerState(s, paint.getMaskSampler(i)); } - drawState->setColor(paint.fColor); + target->setColor(paint.fColor); if (paint.fDither) { - drawState->enableState(GrDrawState::kDither_StateBit); + target->enableState(GrDrawTarget::kDither_StateBit); } else { - drawState->disableState(GrDrawState::kDither_StateBit); + target->disableState(GrDrawTarget::kDither_StateBit); } if (paint.fAntiAlias) { - drawState->enableState(GrDrawState::kHWAntialias_StateBit); + target->enableState(GrDrawTarget::kHWAntialias_StateBit); } else { - drawState->disableState(GrDrawState::kHWAntialias_StateBit); + target->disableState(GrDrawTarget::kHWAntialias_StateBit); } - drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); - drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); + target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); + target->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) { GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); @@ -2018,7 +2020,7 @@ void GrContext::setMatrix(const GrMatrix& m) { } void GrContext::concatMatrix(const GrMatrix& m) const { - fGpu->viewMatrix()->preConcat(m); + fGpu->preConcatViewMatrix(m); } static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index cd4e429..197ee06 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -190,8 +190,7 @@ static inline bool single_pass_path(const GrDrawTarget& target, return hint == kConvex_ConvexHint || hint == kNonOverlappingConvexPieces_ConvexHint || (hint == kSameWindingConvexPieces_ConvexHint && - !target.drawWillReadDst() && - !target.getDrawState().isDitherState()); + !target.drawWillReadDst() && !target.isDitherState()); } return false; @@ -389,8 +388,6 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask, GrScalar tol = GR_Scalar1; tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds()); - GrDrawState* drawState = fTarget->drawState(); - // FIXME: It's really dumb that we recreate the verts for a new vertex // layout. We only do that because the GrDrawTarget API doesn't allow // us to change the vertex layout after reserveVertexSpace(). We won't @@ -408,9 +405,9 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask, GrAssert(NULL != fTarget); GrDrawTarget::AutoStateRestore asr(fTarget); - bool colorWritesWereDisabled = drawState->isColorWriteDisabled(); + bool colorWritesWereDisabled = fTarget->isColorWriteDisabled(); // face culling doesn't make sense here - GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace()); + GrAssert(GrDrawState::kBoth_DrawFace == fTarget->getDrawFace()); int passCount = 0; const GrStencilSettings* passes[3]; @@ -506,37 +503,36 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask, { for (int p = 0; p < passCount; ++p) { - drawState->setDrawFace(drawFace[p]); + fTarget->setDrawFace(drawFace[p]); if (NULL != passes[p]) { - drawState->setStencil(*passes[p]); + fTarget->setStencil(*passes[p]); } if (lastPassIsBounds && (p == passCount-1)) { if (!colorWritesWereDisabled) { - drawState->disableState( - GrDrawState::kNoColorWrites_StateBit); + fTarget->disableState(GrDrawTarget::kNoColorWrites_StateBit); } GrRect bounds; if (reverse) { - GrAssert(NULL != drawState->getRenderTarget()); + GrAssert(NULL != fTarget->getRenderTarget()); // draw over the whole world. bounds.setLTRB(0, 0, - GrIntToScalar(drawState->getRenderTarget()->width()), - GrIntToScalar(drawState->getRenderTarget()->height())); + GrIntToScalar(fTarget->getRenderTarget()->width()), + GrIntToScalar(fTarget->getRenderTarget()->height())); GrMatrix vmi; // mapRect through persp matrix may not be correct - if (!drawState->getViewMatrix().hasPerspective() && - drawState->getViewInverse(&vmi)) { + if (!fTarget->getViewMatrix().hasPerspective() && + fTarget->getViewInverse(&vmi)) { vmi.mapRect(&bounds); } else { if (stageMask) { - if (!drawState->getViewInverse(&vmi)) { + if (!fTarget->getViewInverse(&vmi)) { GrPrintf("Could not invert matrix."); return; } - drawState->preConcatSamplerMatrices(stageMask, vmi); + fTarget->preConcatSamplerMatrices(stageMask, vmi); } - drawState->setViewMatrix(GrMatrix::I()); + fTarget->setViewMatrix(GrMatrix::I()); } } else { bounds = fPath->getBounds(); @@ -546,7 +542,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask, fTarget->drawSimpleRect(bounds, NULL, stageMask); } else { if (passCount > 1) { - drawState->enableState(GrDrawState::kNoColorWrites_StateBit); + fTarget->enableState(GrDrawTarget::kNoColorWrites_StateBit); } if (fUseIndexedDraw) { fTarget->drawIndexed(fPrimitiveType, 0, 0, diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 24a48c1..90de1a3 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -10,7 +10,6 @@ #include "GrColor.h" #include "GrMatrix.h" -#include "GrNoncopyable.h" #include "GrSamplerState.h" #include "GrStencil.h" @@ -46,386 +45,13 @@ struct GrDrawState { typedef uint32_t StageMask; GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages); - GrDrawState() { - // make sure any pad is zero for memcmp - // all GrDrawState members should default to something - // valid by the memset - memset(this, 0, sizeof(GrDrawState)); - - // memset exceptions - fColorFilterMode = SkXfermode::kDstIn_Mode; - fFirstCoverageStage = kNumStages; - - // pedantic assertion that our ptrs will - // be NULL (0 ptr is mem addr 0) - GrAssert((intptr_t)(void*)NULL == 0LL); - - GrAssert(fStencilSettings.isDisabled()); - fFirstCoverageStage = kNumStages; - } - - /////////////////////////////////////////////////////////////////////////// - /// @name Color - //// - - /** - * Sets color for next draw to a premultiplied-alpha color. - * - * @param color the color to set. - */ - void setColor(GrColor color) { fColor = color; } - - GrColor getColor() const { return fColor; } - - /** - * Sets the color to be used for the next draw to be - * (r,g,b,a) = (alpha, alpha, alpha, alpha). - * - * @param alpha The alpha value to set as the color. - */ - void setAlpha(uint8_t a) { - this->setColor((a << 24) | (a << 16) | (a << 8) | a); - } - - /** - * Add a color filter that can be represented by a color and a mode. Applied - * after color-computing texture stages. - */ - void setColorFilter(GrColor c, SkXfermode::Mode mode) { - fColorFilterColor = c; - fColorFilterMode = mode; - } - - GrColor getColorFilterColor() const { return fColorFilterColor; } - SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Textures - //// - - /** - * Sets the texture used at the next drawing call - * - * @param stage The texture stage for which the texture will be set - * - * @param texture The texture to set. Can be NULL though there is no - * advantage to settings a NULL texture if doing non-textured drawing - */ - void setTexture(int stage, GrTexture* texture) { - GrAssert((unsigned)stage < kNumStages); - fTextures[stage] = texture; - } - - /** - * Retrieves the currently set texture. - * - * @return The currently set texture. The return value will be NULL if no - * texture has been set, NULL was most recently passed to - * setTexture, or the last setTexture was destroyed. - */ - const GrTexture* getTexture(int stage) const { - GrAssert((unsigned)stage < kNumStages); - return fTextures[stage]; - } - GrTexture* getTexture(int stage) { - GrAssert((unsigned)stage < kNumStages); - return fTextures[stage]; - } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Samplers - //// - - /** - * Returns the current sampler for a stage. - */ - const GrSamplerState& getSampler(int stage) const { - GrAssert((unsigned)stage < kNumStages); - return fSamplers[stage]; - } - - /** - * Writable pointer to a stage's sampler. - */ - GrSamplerState* sampler(int stage) { - GrAssert((unsigned)stage < kNumStages); - return fSamplers + stage; - } - - /** - * Preconcats the matrix of all samplers in the mask with the same matrix. - */ - void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) { - GrAssert(!(stageMask & kIllegalStageMaskBits)); - for (int i = 0; i < kNumStages; ++i) { - if ((1 << i) & stageMask) { - fSamplers[i].preConcatMatrix(matrix); - } - } - } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Coverage / Color Stages - //// - - /** - * A common pattern is to compute a color with the initial stages and then - * modulate that color by a coverage value in later stage(s) (AA, mask- - * filters, glyph mask, etc). Color-filters, xfermodes, etc should be - * computed based on the pre-coverage-modulated color. The division of - * stages between color-computing and coverage-computing is specified by - * this method. Initially this is kNumStages (all stages - * are color-computing). - */ - void setFirstCoverageStage(int firstCoverageStage) { - GrAssert((unsigned)firstCoverageStage <= kNumStages); - fFirstCoverageStage = firstCoverageStage; - } - - /** - * Gets the index of the first coverage-computing stage. - */ - int getFirstCoverageStage() const { - return fFirstCoverageStage; - } - - ///@} - - /////////////////////////////////////////////////////////////////////////// - /// @name Blending - //// - - /** - * Sets the blending function coeffecients. - * - * The blend function will be: - * D' = sat(S*srcCoef + D*dstCoef) - * - * where D is the existing destination color, S is the incoming source - * color, and D' is the new destination color that will be written. sat() - * is the saturation function. - * - * @param srcCoef coeffecient applied to the src color. - * @param dstCoef coeffecient applied to the dst color. - */ - void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { - fSrcBlend = srcCoeff; - fDstBlend = dstCoeff; - #if GR_DEBUG - switch (dstCoeff) { - case kDC_BlendCoeff: - case kIDC_BlendCoeff: - case kDA_BlendCoeff: - case kIDA_BlendCoeff: - GrPrintf("Unexpected dst blend coeff. Won't work correctly with" - "coverage stages.\n"); - break; - default: - break; - } - switch (srcCoeff) { - case kSC_BlendCoeff: - case kISC_BlendCoeff: - case kSA_BlendCoeff: - case kISA_BlendCoeff: - GrPrintf("Unexpected src blend coeff. Won't work correctly with" - "coverage stages.\n"); - break; - default: - break; - } - #endif - } - - GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; } - GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; } - - void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, - GrBlendCoeff* dstBlendCoeff) const { - *srcBlendCoeff = fSrcBlend; - *dstBlendCoeff = fDstBlend; - } - - /** - * Sets the blending function constant referenced by the following blending - * coeffecients: - * kConstC_BlendCoeff - * kIConstC_BlendCoeff - * kConstA_BlendCoeff - * kIConstA_BlendCoeff - * - * @param constant the constant to set - */ - void setBlendConstant(GrColor constant) { fBlendConstant = constant; } - - /** - * Retrieves the last value set by setBlendConstant() - * @return the blending constant value - */ - GrColor getBlendConstant() const { return fBlendConstant; } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name View Matrix - //// - - /** - * Sets the matrix applied to veretx positions. - * - * In the post-view-matrix space the rectangle [0,w]x[0,h] - * fully covers the render target. (w and h are the width and height of the - * the rendertarget.) - */ - void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; } - - /** - * Gets a writable pointer to the view matrix. - */ - GrMatrix* viewMatrix() { return &fViewMatrix; } - - /** - * Multiplies the current view matrix by a matrix - * - * After this call V' = V*m where V is the old view matrix, - * m is the parameter to this function, and V' is the new view matrix. - * (We consider positions to be column vectors so position vector p is - * transformed by matrix X as p' = X*p.) - * - * @param m the matrix used to modify the view matrix. - */ - void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); } - - /** - * Multiplies the current view matrix by a matrix - * - * After this call V' = m*V where V is the old view matrix, - * m is the parameter to this function, and V' is the new view matrix. - * (We consider positions to be column vectors so position vector p is - * transformed by matrix X as p' = X*p.) - * - * @param m the matrix used to modify the view matrix. - */ - void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); } - - /** - * Retrieves the current view matrix - * @return the current view matrix. - */ - const GrMatrix& getViewMatrix() const { return fViewMatrix; } - - /** - * Retrieves the inverse of the current view matrix. - * - * If the current view matrix is invertible, return true, and if matrix - * is non-null, copy the inverse into it. If the current view matrix is - * non-invertible, return false and ignore the matrix parameter. - * - * @param matrix if not null, will receive a copy of the current inverse. - */ - bool getViewInverse(GrMatrix* matrix) const { - // TODO: determine whether we really need to leave matrix unmodified - // at call sites when inversion fails. - GrMatrix inverse; - if (fViewMatrix.invert(&inverse)) { - if (matrix) { - *matrix = inverse; - } - return true; - } - return false; - } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Render Target - //// - - /** - * Sets the rendertarget used at the next drawing call - * - * @param target The render target to set. - */ - void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; } - - /** - * Retrieves the currently set rendertarget. - * - * @return The currently set render target. - */ - const GrRenderTarget* getRenderTarget() const { return fRenderTarget; } - GrRenderTarget* getRenderTarget() { return fRenderTarget; } - - class AutoRenderTargetRestore : public ::GrNoncopyable { - public: - AutoRenderTargetRestore() : fDrawState(NULL) {} - AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) { - this->set(ds, newTarget); - } - ~AutoRenderTargetRestore() { this->set(NULL, NULL); } - void set(GrDrawState* ds, GrRenderTarget* newTarget) { - if (NULL != fDrawState) { - fDrawState->setRenderTarget(fSavedTarget); - } - if (NULL != ds) { - fSavedTarget = ds->getRenderTarget(); - ds->setRenderTarget(newTarget); - } - fDrawState = ds; - } - private: - GrDrawState* fDrawState; - GrRenderTarget* fSavedTarget; + enum DrawFace { + kBoth_DrawFace, + kCCW_DrawFace, + kCW_DrawFace, }; - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Stencil - //// - - /** - * Sets the stencil settings to use for the next draw. - * Changing the clip has the side-effect of possibly zeroing - * out the client settable stencil bits. So multipass algorithms - * using stencil should not change the clip between passes. - * @param settings the stencil settings to use. - */ - void setStencil(const GrStencilSettings& settings) { - fStencilSettings = settings; - } - - /** - * Shortcut to disable stencil testing and ops. - */ - void disableStencil() { - fStencilSettings.setDisabled(); - } - - const GrStencilSettings& getStencil() const { return fStencilSettings; } - - GrStencilSettings* stencil() { return &fStencilSettings; } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - // @name Edge AA - // There are two ways to perform antialiasing using edge equations. One - // is to specify an (linear or quadratic) edge eq per-vertex. This requires - // splitting vertices shared by primitives. - // - // The other is via setEdgeAAData which sets a set of edges and each - // is tested against all the edges. - //// - - /** + /** * When specifying edges as vertex data this enum specifies what type of * edges are in use. The edges are always 4 GrScalars in memory, even when * the edge type requires fewer than 4. @@ -440,19 +66,6 @@ struct GrDrawState { }; /** - * Determines the interpretation per-vertex edge data when the - * 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) { - fVertexEdgeType = type; - } - - VertexEdgeType getVertexEdgeType() const { - return fVertexEdgeType; - } - - /** * The absolute maximum number of edges that may be specified for * a single draw call when performing edge antialiasing. This is used for * the size of several static buffers, so implementations of getMaxEdges() @@ -478,146 +91,53 @@ struct GrDrawState { float fX, fY, fZ; }; - /** - * Sets the edge data required for edge antialiasing. - * - * @param edges 3 * numEdges float values, representing the edge - * equations in Ax + By + C form - */ - void setEdgeAAData(const Edge* edges, int numEdges) { - GrAssert(numEdges <= GrDrawState::kMaxEdges); - memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge)); - fEdgeAANumEdges = numEdges; - } - - int getNumAAEdges() const { return fEdgeAANumEdges; } - - const Edge* getAAEdges() const { return fEdgeAAEdges; } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name State Flags - //// - - /** - * Flags that affect rendering. Controlled using enable/disableState(). All - * default to disabled. - */ - enum StateBits { - /** - * Perform dithering. TODO: Re-evaluate whether we need this bit - */ - kDither_StateBit = 0x01, - /** - * Perform HW anti-aliasing. This means either HW FSAA, if supported - * by the render target, or smooth-line rendering if a line primitive - * is drawn and line smoothing is supported by the 3D API. - */ - kHWAntialias_StateBit = 0x02, - /** - * Draws will respect the clip, otherwise the clip is ignored. - */ - kClip_StateBit = 0x04, - /** - * Disables writing to the color buffer. Useful when performing stencil - * operations. - */ - kNoColorWrites_StateBit = 0x08, - /** - * Modifies the behavior of edge AA specified by setEdgeAA. If set, - * will test edge pairs for convexity when rasterizing. Set this if the - * source polygon is non-convex. - */ - kEdgeAAConcave_StateBit = 0x10, - - // Users of the class may add additional bits to the vector - kDummyStateBit, - kLastPublicStateBit = kDummyStateBit-1, - }; - - void resetStateFlags() { - fFlagBits = 0; - } - - /** - * Enable render state settings. - * - * @param flags bitfield of StateBits specifing the states to enable - */ - void enableState(uint32_t stateBits) { - fFlagBits |= stateBits; - } - - /** - * Disable render state settings. - * - * @param flags bitfield of StateBits specifing the states to disable - */ - void disableState(uint32_t stateBits) { - fFlagBits &= ~(stateBits); - } - - bool isDitherState() const { - return 0 != (fFlagBits & kDither_StateBit); - } - - bool isHWAntialiasState() const { - return 0 != (fFlagBits & kHWAntialias_StateBit); - } - - bool isClipState() const { - return 0 != (fFlagBits & kClip_StateBit); - } - - bool isColorWriteDisabled() const { - return 0 != (fFlagBits & kNoColorWrites_StateBit); - } - - bool isConcaveEdgeAAState() const { - return 0 != (fFlagBits & kEdgeAAConcave_StateBit); - } + GrDrawState() { + // make sure any pad is zero for memcmp + // all GrDrawState members should default to something + // valid by the memset + memset(this, 0, sizeof(GrDrawState)); + + // memset exceptions + fColorFilterXfermode = SkXfermode::kDstIn_Mode; + fFirstCoverageStage = kNumStages; - bool isStateFlagEnabled(uint32_t stateBit) const { - return 0 != (stateBit & fFlagBits); - } + // pedantic assertion that our ptrs will + // be NULL (0 ptr is mem addr 0) + GrAssert((intptr_t)(void*)NULL == 0LL); - void copyStateFlags(const GrDrawState& ds) { - fFlagBits = ds.fFlagBits; + // default stencil setting should be disabled + GrAssert(fStencilSettings.isDisabled()); + fFirstCoverageStage = kNumStages; } - /// @} + uint8_t fFlagBits; + GrBlendCoeff fSrcBlend : 8; + GrBlendCoeff fDstBlend : 8; + DrawFace fDrawFace : 8; + uint8_t fFirstCoverageStage; + SkXfermode::Mode fColorFilterXfermode : 8; + GrColor fBlendConstant; + GrTexture* fTextures[kNumStages]; + GrRenderTarget* fRenderTarget; + GrColor fColor; + GrColor fColorFilterColor; - /////////////////////////////////////////////////////////////////////////// - /// @name Face Culling - //// + GrStencilSettings fStencilSettings; + GrMatrix fViewMatrix; - enum DrawFace { - kBoth_DrawFace, - kCCW_DrawFace, - kCW_DrawFace, - }; + // @{ Data for GrTesselatedPathRenderer + // TODO: currently ignored in copying & comparison for performance. + // Must be considered if GrTesselatedPathRenderer is being used. - /** - * Controls whether clockwise, counterclockwise, or both faces are drawn. - * @param face the face(s) to draw. - */ - void setDrawFace(DrawFace face) { - fDrawFace = face; - } + int fEdgeAANumEdges; + VertexEdgeType fVertexEdgeType; + Edge fEdgeAAEdges[kMaxEdges]; - /** - * Gets whether the target is drawing clockwise, counterclockwise, - * or both faces. - * @return the current draw face(s). - */ - DrawFace getDrawFace() const { - return fDrawFace; - } - - /// @} + // @} - /////////////////////////////////////////////////////////////////////////// + // This field must be last; it will not be copied or compared + // if the corresponding fTexture[] is NULL. + GrSamplerState fSamplerStates[kNumStages]; // Most stages are usually not used, so conditionals here // reduce the expected number of bytes touched by 50%. @@ -626,7 +146,7 @@ struct GrDrawState { for (int i = 0; i < kNumStages; i++) { if (fTextures[i] && - memcmp(&this->fSamplers[i], &s.fSamplers[i], + memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i], sizeof(GrSamplerState))) { return false; } @@ -643,7 +163,7 @@ struct GrDrawState { for (int i = 0; i < kNumStages; i++) { if (s.fTextures[i]) { - memcpy(&this->fSamplers[i], &s.fSamplers[i], + memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i], sizeof(GrSamplerState)); } } @@ -652,36 +172,6 @@ struct GrDrawState { } private: - static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1); - uint8_t fFlagBits; - GrBlendCoeff fSrcBlend : 8; - GrBlendCoeff fDstBlend : 8; - DrawFace fDrawFace : 8; - uint8_t fFirstCoverageStage; - SkXfermode::Mode fColorFilterMode : 8; - GrColor fBlendConstant; - GrTexture* fTextures[kNumStages]; - GrRenderTarget* fRenderTarget; - GrColor fColor; - GrColor fColorFilterColor; - - GrStencilSettings fStencilSettings; - GrMatrix fViewMatrix; - - // @{ Data for GrTesselatedPathRenderer - // TODO: currently ignored in copying & comparison for performance. - // Must be considered if GrTesselatedPathRenderer is being used. - - int fEdgeAANumEdges; - VertexEdgeType fVertexEdgeType; - Edge fEdgeAAEdges[kMaxEdges]; - - // @} - - // This field must be last; it will not be copied or compared - // if the corresponding fTexture[] is NULL. - GrSamplerState fSamplers[kNumStages]; - size_t leadingBytes() const { // Can't use offsetof() with non-POD types, so stuck with pointer math. // TODO: ignores GrTesselatedPathRenderer data structures. We don't @@ -694,3 +184,4 @@ private: }; #endif + diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 2d1563d..7a84262 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -455,6 +455,119 @@ const GrClip& GrDrawTarget::getClip() const { return fClip; } +void GrDrawTarget::setTexture(int stage, GrTexture* tex) { + GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); + fCurrDrawState.fTextures[stage] = tex; +} + +const GrTexture* GrDrawTarget::getTexture(int stage) const { + GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); + return fCurrDrawState.fTextures[stage]; +} + +GrTexture* GrDrawTarget::getTexture(int stage) { + GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); + return fCurrDrawState.fTextures[stage]; +} + +void GrDrawTarget::setRenderTarget(GrRenderTarget* target) { + fCurrDrawState.fRenderTarget = target; +} + +const GrRenderTarget* GrDrawTarget::getRenderTarget() const { + return fCurrDrawState.fRenderTarget; +} + +GrRenderTarget* GrDrawTarget::getRenderTarget() { + return fCurrDrawState.fRenderTarget; +} + +void GrDrawTarget::setViewMatrix(const GrMatrix& m) { + fCurrDrawState.fViewMatrix = m; +} + +void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) { + fCurrDrawState.fViewMatrix.preConcat(matrix); +} + +void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) { + fCurrDrawState.fViewMatrix.postConcat(matrix); +} + +const GrMatrix& GrDrawTarget::getViewMatrix() const { + return fCurrDrawState.fViewMatrix; +} + +bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const { + // Mike: Can we cache this somewhere? + // Brian: Sure, do we use it often? + + GrMatrix inverse; + if (fCurrDrawState.fViewMatrix.invert(&inverse)) { + if (matrix) { + *matrix = inverse; + } + return true; + } + return false; +} + +void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) { + GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); + fCurrDrawState.fSamplerStates[stage] = state; +} + +void GrDrawTarget::enableState(uint32_t bits) { + fCurrDrawState.fFlagBits |= bits; +} + +void GrDrawTarget::disableState(uint32_t bits) { + fCurrDrawState.fFlagBits &= ~(bits); +} + +void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff, + GrBlendCoeff dstCoeff) { + fCurrDrawState.fSrcBlend = srcCoeff; + fCurrDrawState.fDstBlend = dstCoeff; +#if GR_DEBUG + switch (dstCoeff) { + case kDC_BlendCoeff: + case kIDC_BlendCoeff: + case kDA_BlendCoeff: + case kIDA_BlendCoeff: + GrPrintf("Unexpected dst blend coeff. Won't work correctly with" + "coverage stages.\n"); + break; + default: + break; + } + switch (srcCoeff) { + case kSC_BlendCoeff: + case kISC_BlendCoeff: + case kSA_BlendCoeff: + case kISA_BlendCoeff: + GrPrintf("Unexpected src blend coeff. Won't work correctly with" + "coverage stages.\n"); + break; + default: + break; + } +#endif +} + +void GrDrawTarget::setColor(GrColor c) { + fCurrDrawState.fColor = c; +} + +void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) { + fCurrDrawState.fColorFilterColor = c; + fCurrDrawState.fColorFilterXfermode = mode; +} + +void GrDrawTarget::setAlpha(uint8_t a) { + this->setColor((a << 24) | (a << 16) | (a << 8) | a); +} + void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const { state->fState = fCurrDrawState; } @@ -691,8 +804,8 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, return false; } if (GrPixelConfigIsUnpremultiplied(this->getRenderTarget()->config())) { - if (kOne_BlendCoeff != getDrawState().getSrcBlendCoeff() || - kZero_BlendCoeff != getDrawState().getDstBlendCoeff()) { + if (kOne_BlendCoeff != fCurrDrawState.fSrcBlend || + kZero_BlendCoeff != fCurrDrawState.fDstBlend) { return false; } } @@ -704,8 +817,8 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, // a custom bilerp in the shader. Until Skia itself supports unpremul // configs there is no pressure to implement this. if (this->isStageEnabled(s) && - GrPixelConfigIsUnpremultiplied(this->getTexture(s)->config()) && - GrSamplerState::kNearest_Filter != this->getSampler(s).getFilter()) { + GrPixelConfigIsUnpremultiplied(fCurrDrawState.fTextures[s]->config()) && + GrSamplerState::kNearest_Filter != fCurrDrawState.fSamplerStates[s].getFilter()) { return false; } } @@ -748,10 +861,9 @@ bool GrDrawTarget::canTweakAlphaForCoverage() const { * for Cd we find that only 1, ISA, and ISC produce the correct depth * coeffecient in terms of S' and D. */ - GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff(); - return kOne_BlendCoeff == dstCoeff || - kISA_BlendCoeff == dstCoeff || - kISC_BlendCoeff == dstCoeff; + return kOne_BlendCoeff == fCurrDrawState.fDstBlend|| + kISA_BlendCoeff == fCurrDrawState.fDstBlend || + kISC_BlendCoeff == fCurrDrawState.fDstBlend; } @@ -760,21 +872,20 @@ bool GrDrawTarget::srcAlphaWillBeOne() const { // Check if per-vertex or constant color may have partial alpha if ((layout & kColor_VertexLayoutBit) || - 0xff != GrColorUnpackA(this->getColor())) { + 0xff != GrColorUnpackA(fCurrDrawState.fColor)) { return false; } // Check if color filter could introduce an alpha // (TODO: Consider being more aggressive with regards to detecting 0xff // final alpha from color filter). - if (SkXfermode::kDst_Mode != this->getDrawState().getColorFilterMode()) { + if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) { return false; } // Check if a color stage could create a partial alpha - int firstCoverageStage = this->getFirstCoverageStage(); - for (int s = 0; s < firstCoverageStage; ++s) { + for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) { if (StageWillBeUsed(s, layout, fCurrDrawState)) { - GrAssert(NULL != this->getTexture(s)); - GrPixelConfig config = this->getTexture(s)->config(); + GrAssert(NULL != fCurrDrawState.fTextures[s]); + GrPixelConfig config = fCurrDrawState.fTextures[s]->config(); if (!GrPixelConfigIsOpaque(config)) { return false; } @@ -794,12 +905,12 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, if (NULL == srcCoeff) { srcCoeff = &bogusSrcCoeff; } - *srcCoeff = this->getDrawState().getSrcBlendCoeff(); + *srcCoeff = fCurrDrawState.fSrcBlend; if (NULL == dstCoeff) { dstCoeff = &bogusDstCoeff; } - *dstCoeff = this->getDrawState().getDstBlendCoeff(); + *dstCoeff = fCurrDrawState.fDstBlend; // We don't ever expect source coeffecients to reference the source GrAssert(kSA_BlendCoeff != *srcCoeff && @@ -812,7 +923,7 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, kDC_BlendCoeff != *dstCoeff && kIDC_BlendCoeff != *dstCoeff); - if (this->getDrawState().isColorWriteDisabled()) { + if (SkToBool(kNoColorWrites_StateBit & fCurrDrawState.fFlagBits)) { *srcCoeff = kZero_BlendCoeff; *dstCoeff = kOne_BlendCoeff; } @@ -828,7 +939,7 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, // stenciling is enabled. Having color writes disabled is effectively // (0,1). if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne)) { - if (this->getDrawState().getStencil().doesWrite()) { + if (fCurrDrawState.fStencilSettings.doesWrite()) { if (fCaps.fShaderSupport) { return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; @@ -842,10 +953,10 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, // check for coverage due to edge aa or coverage texture stage bool hasCoverage = forceCoverage || - this->getDrawState().getNumAAEdges() > 0 || + fCurrDrawState.fEdgeAANumEdges > 0 || (layout & kCoverage_VertexLayoutBit) || (layout & kEdge_VertexLayoutBit); - for (int s = this->getFirstCoverageStage(); + for (int s = fCurrDrawState.fFirstCoverageStage; !hasCoverage && s < GrDrawState::kNumStages; ++s) { if (StageWillBeUsed(s, layout, fCurrDrawState)) { @@ -912,7 +1023,7 @@ bool GrDrawTarget::willUseHWAALines() const { // but not in a premul-alpha way. So we only use them when our alpha // is 0xff and tweaking the color for partial coverage is OK if (!fCaps.fHWAALineSupport || - !(this->getDrawState().isHWAntialiasState())) { + !(kHWAntialias_StateBit & fCurrDrawState.fFlagBits)) { return false; } BlendOptFlags opts = this->getBlendOpts(); @@ -932,6 +1043,16 @@ bool GrDrawTarget::drawWillReadDst() const { this->getBlendOpts()); } +/////////////////////////////////////////////////////////////////////////////// + +void GrDrawTarget::setEdgeAAData(const GrDrawState::Edge* edges, int numEdges) { + GrAssert(numEdges <= GrDrawState::kMaxEdges); + memcpy(fCurrDrawState.fEdgeAAEdges, edges, + numEdges * sizeof(GrDrawState::Edge)); + fCurrDrawState.fEdgeAANumEdges = numEdges; +} + + //////////////////////////////////////////////////////////////////////////////// void GrDrawTarget::drawRect(const GrRect& rect, @@ -947,13 +1068,13 @@ void GrDrawTarget::drawRect(const GrRect& rect, return; } - SetRectVertices(rect, matrix, srcRects, + SetRectVertices(rect, matrix, srcRects, srcMatrices, layout, geo.vertices()); drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); } -GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask, +GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask, const GrRect* srcRects[]) { GrVertexLayout layout = 0; @@ -1062,7 +1183,7 @@ GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw( if (fViewMatrix.invert(&invVM)) { for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (fStageMask & (1 << s)) { - fSamplerMatrices[s] = target->getSampler(s).getMatrix(); + fSamplerMatrices[s] = target->getSamplerMatrix(s); } } target->preConcatSamplerMatrices(fStageMask, invVM); @@ -1078,8 +1199,7 @@ GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() { fDrawTarget->setViewMatrix(fViewMatrix); for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (fStageMask & (1 << s)) { - GrSamplerState* sampler = fDrawTarget->drawState()->sampler(s); - sampler->setMatrix(fSamplerMatrices[s]); + fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]); } } } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index b72fb3a..4bd9eee 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -57,9 +57,62 @@ public: int fMaxTextureSize; }; - // for convenience typedef GrDrawState::StageMask StageMask; + /** + * Flags that affect rendering. Controlled using enable/disableState(). All + * default to disabled. + */ + enum StateBits { + /** + * Perform dithering. TODO: Re-evaluate whether we need this bit + */ + kDither_StateBit = 0x01, + /** + * Perform HW anti-aliasing. This means either HW FSAA, if supported + * by the render target, or smooth-line rendering if a line primitive + * is drawn and line smoothing is supported by the 3D API. + */ + kHWAntialias_StateBit = 0x02, + /** + * Draws will respect the clip, otherwise the clip is ignored. + */ + kClip_StateBit = 0x04, + /** + * Disables writing to the color buffer. Useful when performing stencil + * operations. + */ + kNoColorWrites_StateBit = 0x08, + /** + * Modifies the behavior of edge AA specified by setEdgeAA. If set, + * will test edge pairs for convexity when rasterizing. Set this if the + * source polygon is non-convex. + */ + kEdgeAAConcave_StateBit = 0x10, + // subclass may use additional bits internally + kDummyStateBit, + kLastPublicStateBit = kDummyStateBit-1 + }; + + /** + * Sets the stencil settings to use for the next draw. + * Changing the clip has the side-effect of possibly zeroing + * out the client settable stencil bits. So multipass algorithms + * using stencil should not change the clip between passes. + * @param settings the stencil settings to use. + */ + void setStencil(const GrStencilSettings& settings) { + fCurrDrawState.fStencilSettings = settings; + } + + /** + * Shortcut to disable stencil testing and ops. + */ + void disableStencil() { + fCurrDrawState.fStencilSettings.setDisabled(); + } + +public: /////////////////////////////////////////////////////////////////////////// GrDrawTarget(); @@ -88,6 +141,285 @@ public: const GrClip& getClip() const; /** + * Sets the texture used at the next drawing call + * + * @param stage The texture stage for which the texture will be set + * + * @param texture The texture to set. Can be NULL though there is no advantage + * to settings a NULL texture if doing non-textured drawing + */ + void setTexture(int stage, GrTexture* texture); + + /** + * Retrieves the currently set texture. + * + * @return The currently set texture. The return value will be NULL if no + * texture has been set, NULL was most recently passed to + * setTexture, or the last setTexture was destroyed. + */ + const GrTexture* getTexture(int stage) const; + GrTexture* getTexture(int stage); + + /** + * Sets the rendertarget used at the next drawing call + * + * @param target The render target to set. + */ + void setRenderTarget(GrRenderTarget* target); + + /** + * Retrieves the currently set rendertarget. + * + * @return The currently set render target. + */ + const GrRenderTarget* getRenderTarget() const; + GrRenderTarget* getRenderTarget(); + + /** + * Sets the sampler state for a stage used in subsequent draws. + * + * The sampler state determines how texture coordinates are + * intepretted and used to sample the texture. + * + * @param stage the stage of the sampler to set + * @param samplerState Specifies the sampler state. + */ + void setSamplerState(int stage, const GrSamplerState& samplerState); + + /** + * Concats the matrix of a stage's sampler. + * + * @param stage the stage of the sampler to set + * @param matrix the matrix to concat + */ + void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) { + GrAssert(stage >= 0 && stage < GrDrawState::kNumStages); + fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix); + } + + /** + * Shortcut for preConcatSamplerMatrix on all stages in mask with same + * matrix + */ + void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) { + for (int i = 0; i < GrDrawState::kNumStages; ++i) { + if ((1 << i) & stageMask) { + this->preConcatSamplerMatrix(i, matrix); + } + } + } + + /** + * Shortcut for preConcatSamplerMatrix on all enabled stages in mask with + * same matrix + * + * @param stage the stage of the sampler to set + * @param matrix the matrix to concat + */ + void preConcatEnabledSamplerMatrices(const GrMatrix& matrix) { + StageMask stageMask = this->enabledStages(); + this->preConcatSamplerMatrices(stageMask, matrix); + } + + /** + * Gets the matrix of a stage's sampler + * + * @param stage the stage to of sampler to get + * @return the sampler state's matrix + */ + const GrMatrix& getSamplerMatrix(int stage) const { + return fCurrDrawState.fSamplerStates[stage].getMatrix(); + } + + /** + * Sets the matrix of a stage's sampler + * + * @param stage the stage of sampler set + * @param matrix the matrix to set + */ + void setSamplerMatrix(int stage, const GrMatrix& matrix) { + fCurrDrawState.fSamplerStates[stage].setMatrix(matrix); + } + + /** + * Sets the matrix applied to veretx positions. + * + * In the post-view-matrix space the rectangle [0,w]x[0,h] + * fully covers the render target. (w and h are the width and height of the + * the rendertarget.) + * + * @param m the matrix used to transform the vertex positions. + */ + void setViewMatrix(const GrMatrix& m); + + /** + * Multiplies the current view matrix by a matrix + * + * After this call V' = V*m where V is the old view matrix, + * m is the parameter to this function, and V' is the new view matrix. + * (We consider positions to be column vectors so position vector p is + * transformed by matrix X as p' = X*p.) + * + * @param m the matrix used to modify the view matrix. + */ + void preConcatViewMatrix(const GrMatrix& m); + + /** + * Multiplies the current view matrix by a matrix + * + * After this call V' = m*V where V is the old view matrix, + * m is the parameter to this function, and V' is the new view matrix. + * (We consider positions to be column vectors so position vector p is + * transformed by matrix X as p' = X*p.) + * + * @param m the matrix used to modify the view matrix. + */ + void postConcatViewMatrix(const GrMatrix& m); + + /** + * Retrieves the current view matrix + * @return the current view matrix. + */ + const GrMatrix& getViewMatrix() const; + + /** + * Retrieves the inverse of the current view matrix. + * + * If the current view matrix is invertible, return true, and if matrix + * is non-null, copy the inverse into it. If the current view matrix is + * non-invertible, return false and ignore the matrix parameter. + * + * @param matrix if not null, will receive a copy of the current inverse. + */ + bool getViewInverse(GrMatrix* matrix) const; + + /** + * Sets color for next draw to a premultiplied-alpha color. + * + * @param the color to set. + */ + void setColor(GrColor); + + /** + * Gets the currently set color. + * @return the current color. + */ + GrColor getColor() const { return fCurrDrawState.fColor; } + + /** + * Add a color filter that can be represented by a color and a mode. + */ + void setColorFilter(GrColor, SkXfermode::Mode); + + /** + * Sets the color to be used for the next draw to be + * (r,g,b,a) = (alpha, alpha, alpha, alpha). + * + * @param alpha The alpha value to set as the color. + */ + void setAlpha(uint8_t alpha); + + /** + * Controls whether clockwise, counterclockwise, or both faces are drawn. + * @param face the face(s) to draw. + */ + void setDrawFace(GrDrawState::DrawFace face) { + fCurrDrawState.fDrawFace = face; + } + + /** + * A common pattern is to compute a color with the initial stages and then + * modulate that color by a coverage value in later stage(s) (AA, mask- + * filters, glyph mask, etc). Color-filters, xfermodes, etc should be + * computed based on the pre-coverage-modulated color. The division of + * stages between color-computing and coverage-computing is specified by + * this method. Initially this is GrDrawState::kNumStages (all stages + * are color-computing). + */ + void setFirstCoverageStage(int firstCoverageStage) { + fCurrDrawState.fFirstCoverageStage = firstCoverageStage; + } + + /** + * Gets the index of the first coverage-computing stage. + */ + int getFirstCoverageStage() const { + return fCurrDrawState.fFirstCoverageStage; + } + + /** + * Gets whether the target is drawing clockwise, counterclockwise, + * or both faces. + * @return the current draw face(s). + */ + GrDrawState::DrawFace getDrawFace() const { + return fCurrDrawState.fDrawFace; + } + + /** + * Enable render state settings. + * + * @param flags bitfield of StateBits specifing the states to enable + */ + void enableState(uint32_t stateBits); + + /** + * Disable render state settings. + * + * @param flags bitfield of StateBits specifing the states to disable + */ + void disableState(uint32_t stateBits); + + bool isDitherState() const { + return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit); + } + + bool isHWAntialiasState() const { + return 0 != (fCurrDrawState.fFlagBits & kHWAntialias_StateBit); + } + + bool isClipState() const { + return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit); + } + + bool isColorWriteDisabled() const { + return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit); + } + + /** + * Sets the blending function coeffecients. + * + * The blend function will be: + * D' = sat(S*srcCoef + D*dstCoef) + * + * where D is the existing destination color, S is the incoming source + * color, and D' is the new destination color that will be written. sat() + * is the saturation function. + * + * @param srcCoef coeffecient applied to the src color. + * @param dstCoef coeffecient applied to the dst color. + */ + void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); + + /** + * Sets the blending function constant referenced by the following blending + * coeffecients: + * kConstC_BlendCoeff + * kIConstC_BlendCoeff + * kConstA_BlendCoeff + * kIConstA_BlendCoeff + * + * @param constant the constant to set + */ + void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; } + + /** + * Retrieves the last value set by setBlendConstant() + * @return the blending constant value + */ + GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; } + + /** * Determines if blending will require a read of a dst given the current * state set on the draw target * @@ -116,6 +448,15 @@ public: */ bool canTweakAlphaForCoverage() const; + /** + * Determines the interpretation per-vertex edge data when the + * kEdge_VertexLayoutBit is set (see below). When per-vertex edges are not + * specified the value of this setting has no effect. + */ + void setVertexEdgeType(GrDrawState::VertexEdgeType type) { + fCurrDrawState.fVertexEdgeType = type; + } + /** * Given the current draw state, vertex layout, and hw support, will HW AA * lines be used (if line primitive type is drawn)? (Note that lines are @@ -123,70 +464,13 @@ public: */ bool willUseHWAALines() const; - const GrDrawState& getDrawState() const { return fCurrDrawState; } - GrDrawState* drawState() { return &fCurrDrawState; } - - // Convenience Pass-thrus to GrDrawState. These are likely candidates for - // removal. - void setViewMatrix(const GrMatrix& m) { - this->drawState()->setViewMatrix(m); - } - GrMatrix* viewMatrix() { - return this->drawState()->viewMatrix(); - } - const GrMatrix& getViewMatrix() const { - return this->getDrawState().getViewMatrix(); - } - bool getViewInverse(GrMatrix* inv) const { - return this->getDrawState().getViewInverse(inv); - } - void setRenderTarget(GrRenderTarget* renderTarget) { - this->drawState()->setRenderTarget(renderTarget); - } - const GrRenderTarget* getRenderTarget() const { - return this->getDrawState().getRenderTarget(); - } - GrRenderTarget* getRenderTarget() { - return this->drawState()->getRenderTarget(); - } - void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { - this->drawState()->setBlendFunc(srcCoeff, dstCoeff); - } - void setTexture(int stage, GrTexture* texture) { - this->drawState()->setTexture(stage, texture); - } - const GrTexture* getTexture(int stage) const { - return this->getDrawState().getTexture(stage); - } - GrTexture* getTexture(int stage) { - return this->drawState()->getTexture(stage); - } - // THIS WILL BE REMOVED AND REPLACED WITH DIRECT ACCESS TO SAMPLER - // IN A COMING REVISION. - void setSamplerState(int stage, const GrSamplerState& sampler) { - *(this->drawState()->sampler(stage)) = sampler; - } - const GrSamplerState& getSampler(int stage) const { - return this->getDrawState().getSampler(stage); - } - void preConcatSamplerMatrices(StageMask stageMask, - const GrMatrix& m) { - this->drawState()->preConcatSamplerMatrices(stageMask, m); - } - GrColor getColor() const { return this->getDrawState().getColor(); } - void setColor(GrColor color) { this->drawState()->setColor(color); } - void setFirstCoverageStage(int firstCoverageStage) { - this->drawState()->setFirstCoverageStage(firstCoverageStage); - } - int getFirstCoverageStage() const { - return this->getDrawState().getFirstCoverageStage(); - } - void setDrawFace(const GrDrawState::DrawFace face) { - this->drawState()->setDrawFace(face); - } - GrDrawState::DrawFace getDrawFace() const { - return this->getDrawState().getDrawFace(); - } + /** + * Sets the edge data required for edge antialiasing. + * + * @param edges 3 * 6 float values, representing the edge + * equations in Ax + By + C form + */ + void setEdgeAAData(const GrDrawState::Edge* edges, int numEdges); /** * Used to save and restore the GrGpu's drawing state @@ -611,7 +895,7 @@ public: } AutoViewMatrixRestore(GrDrawTarget* target) - : fDrawTarget(target), fMatrix(target->getViewMatrix()) { + : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) { GrAssert(NULL != target); } @@ -643,14 +927,13 @@ public: */ class AutoDeviceCoordDraw : ::GrNoncopyable { public: - AutoDeviceCoordDraw(GrDrawTarget* target, - GrDrawState::StageMask stageMask); + AutoDeviceCoordDraw(GrDrawTarget* target, StageMask stageMask); ~AutoDeviceCoordDraw(); private: - GrDrawTarget* fDrawTarget; - GrMatrix fViewMatrix; - GrMatrix fSamplerMatrices[GrDrawState::kNumStages]; - GrDrawState::StageMask fStageMask; + GrDrawTarget* fDrawTarget; + GrMatrix fViewMatrix; + GrMatrix fSamplerMatrices[GrDrawState::kNumStages]; + int fStageMask; }; //////////////////////////////////////////////////////////////////////////// @@ -996,8 +1279,7 @@ protected: // given a vertex layout and a draw state, will a stage be used? static bool StageWillBeUsed(int stage, GrVertexLayout layout, const GrDrawState& state) { - return NULL != state.getTexture(stage) && - VertexUsesStage(stage, layout); + return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout); } bool isStageEnabled(int stage) const { @@ -1055,7 +1337,7 @@ protected: // Helpers for drawRect, protected so subclasses that override drawRect // can use them. - static GrVertexLayout GetRectVertexLayout(StageMask stageMask, + static GrVertexLayout GetRectVertexLayout(StageMask stageEnableBitfield, const GrRect* srcRects[]); static void SetRectVertices(const GrRect& rect, diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 4c0594b..1583630 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -185,10 +185,10 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { // We used to clear down in the GL subclass using a special purpose // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported // FBO status. - GrRenderTarget* oldRT = this->getRenderTarget(); - this->setRenderTarget(rt); + GrRenderTarget* oldRT = fCurrDrawState.fRenderTarget; + fCurrDrawState.fRenderTarget = rt; this->clearStencil(); - this->setRenderTarget(oldRT); + fCurrDrawState.fRenderTarget = oldRT; return true; } else { return false; @@ -530,17 +530,16 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { const GrIRect* r = NULL; GrIRect clipRect; - GrRenderTarget* rt = this->getRenderTarget(); - // GrDrawTarget should have filtered this for us - GrAssert(NULL != rt); + GrAssert(NULL != fCurrDrawState.fRenderTarget); - if (this->getDrawState().isClipState()) { + if (fCurrDrawState.fFlagBits & kClip_StateBit) { + GrRenderTarget& rt = *fCurrDrawState.fRenderTarget; GrRect bounds; GrRect rtRect; rtRect.setLTRB(0, 0, - GrIntToScalar(rt->width()), GrIntToScalar(rt->height())); + GrIntToScalar(rt.width()), GrIntToScalar(rt.height())); if (fClip.hasConservativeBounds()) { bounds = fClip.getConservativeBounds(); if (!bounds.intersect(rtRect)) { @@ -561,17 +560,15 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { !bounds.isEmpty(); // TODO: dynamically attach a SB when needed. - GrStencilBuffer* stencilBuffer = rt->getStencilBuffer(); + GrStencilBuffer* stencilBuffer = rt.getStencilBuffer(); if (fClipInStencil && NULL == stencilBuffer) { return false; } - GrDrawState* drawState = this->drawState(); - if (fClipInStencil && - stencilBuffer->mustRenderClip(fClip, rt->width(), rt->height())) { + stencilBuffer->mustRenderClip(fClip, rt.width(), rt.height())) { - stencilBuffer->setLastClip(fClip, rt->width(), rt->height()); + stencilBuffer->setLastClip(fClip, rt.width(), rt.height()); // we set the current clip to the bounds so that our recursive // draws are scissored to them. We use the copy of the complex clip @@ -586,9 +583,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { this->setViewMatrix(GrMatrix::I()); this->flushScissor(NULL); #if !VISUALIZE_COMPLEX_CLIP - drawState->enableState(GrDrawState::kNoColorWrites_StateBit); + this->enableState(kNoColorWrites_StateBit); #else - drawState->disableState(GrDrawState::kNoColorWrites_StateBit); + this->disableState(kNoColorWrites_StateBit); #endif int count = clip.getElementCount(); int clipBit = stencilBuffer->bits(); @@ -609,7 +606,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { GrPathFill fill; bool fillInverted; // enabled at bottom of loop - drawState->disableState(kModifyStencilClip_StateBit); + this->disableState(kModifyStencilClip_StateBit); bool canRenderDirectToStencil; // can the clip element be drawn // directly to the stencil buffer @@ -667,11 +664,11 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { }; SET_RANDOM_COLOR if (kRect_ClipType == clip.getElementType(c)) { - drawState->setStencil(gDrawToStencil); + this->setStencil(gDrawToStencil); this->drawSimpleRect(clip.getRect(c), NULL, 0); } else { if (canRenderDirectToStencil) { - drawState->setStencil(gDrawToStencil); + this->setStencil(gDrawToStencil); pr->drawPath(0); } else { pr->drawPathToStencil(); @@ -681,9 +678,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { // now we modify the clip bit by rendering either the clip // element directly or a bounding rect of the entire clip. - drawState->enableState(kModifyStencilClip_StateBit); + this->enableState(kModifyStencilClip_StateBit); for (int p = 0; p < passes; ++p) { - drawState->setStencil(stencilSettings[p]); + this->setStencil(stencilSettings[p]); if (canDrawDirectToClip) { if (kRect_ClipType == clip.getElementType(c)) { SET_RANDOM_COLOR diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 7b705e4..11bf153 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -327,8 +327,8 @@ public: } protected: - enum PrivateDrawStateBits { - kFirstBit = (GrDrawState::kLastPublicStateBit << 1), + enum PrivateStateBits { + kFirstBit = (kLastPublicStateBit << 1), kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify // stencil bits used for diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp index 5df1ed1..9f7e4ec 100644 --- a/src/gpu/GrGpuGL.cpp +++ b/src/gpu/GrGpuGL.cpp @@ -480,7 +480,7 @@ void GrGpuGL::onResetContext() { GL_CALL(Disable(GR_GL_CULL_FACE)); GL_CALL(FrontFace(GR_GL_CCW)); - fHWDrawState.setDrawFace(GrDrawState::kBoth_DrawFace); + fHWDrawState.fDrawFace = GrDrawState::kBoth_DrawFace; GL_CALL(Disable(GR_GL_DITHER)); if (kDesktop_GrGLBinding == this->glBinding()) { @@ -492,7 +492,7 @@ void GrGpuGL::onResetContext() { } GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); - fHWDrawState.resetStateFlags(); + fHWDrawState.fFlagBits = 0; // we only ever use lines in hairline mode GL_CALL(LineWidth(1)); @@ -502,22 +502,23 @@ void GrGpuGL::onResetContext() { // illegal values //fHWDrawState.fSrcBlend = (GrBlendCoeff)(uint8_t)-1; - fHWDrawState.setBlendFunc((GrBlendCoeff)-1, (GrBlendCoeff)-1); - fHWDrawState.setBlendConstant(0x00000000); + fHWDrawState.fSrcBlend = (GrBlendCoeff)0xFF; + fHWDrawState.fDstBlend = (GrBlendCoeff)(uint8_t)-1; + + fHWDrawState.fBlendConstant = 0x00000000; GL_CALL(BlendColor(0,0,0,0)); - fHWDrawState.setColor(GrColor_ILLEGAL); + fHWDrawState.fColor = GrColor_ILLEGAL; - fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix()); + fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); for (int s = 0; s < GrDrawState::kNumStages; ++s) { - fHWDrawState.setTexture(s, NULL); - GrSamplerState* sampler = fHWDrawState.sampler(s); - sampler->setRadial2Params(-GR_ScalarMax, - -GR_ScalarMax, - true); - sampler->setMatrix(GrMatrix::InvalidMatrix()); - sampler->setConvolutionParams(0, NULL, NULL); + fHWDrawState.fTextures[s] = NULL; + fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax, + -GR_ScalarMax, + true); + fHWDrawState.fSamplerStates[s].setMatrix(GrMatrix::InvalidMatrix()); + fHWDrawState.fSamplerStates[s].setConvolutionParams(0, NULL, NULL); } fHWBounds.fScissorRect.invalidate(); @@ -525,7 +526,7 @@ void GrGpuGL::onResetContext() { GL_CALL(Disable(GR_GL_SCISSOR_TEST)); fHWBounds.fViewportRect.invalidate(); - fHWDrawState.stencil()->invalidate(); + fHWDrawState.fStencilSettings.invalidate(); fHWStencilClip = false; fClipInStencil = false; @@ -535,7 +536,7 @@ void GrGpuGL::onResetContext() { fHWGeometryState.fArrayPtrsDirty = true; GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); - fHWDrawState.setRenderTarget(NULL); + fHWDrawState.fRenderTarget = NULL; // we assume these values if (this->glCaps().fUnpackRowLengthSupport) { @@ -1190,7 +1191,7 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb; GrGLuint rb = glsb->renderbufferID(); - fHWDrawState.setRenderTarget(NULL); + fHWDrawState.fRenderTarget = NULL; GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, @@ -1275,9 +1276,9 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) { } void GrGpuGL::flushScissor(const GrIRect* rect) { - GrAssert(this->getRenderTarget() != NULL); + GrAssert(NULL != fCurrDrawState.fRenderTarget); const GrGLIRect& vp = - ((GrGLRenderTarget*)this->getRenderTarget())->getViewport(); + ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport(); GrGLIRect scissor; if (NULL != rect) { @@ -1306,17 +1307,15 @@ void GrGpuGL::flushScissor(const GrIRect* rect) { } void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { - const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); // parent class should never let us get here with no RT - GrAssert(rt != NULL); - + GrAssert(NULL != fCurrDrawState.fRenderTarget); GrIRect clippedRect; if (NULL != rect) { // flushScissor expects rect to be clipped to the target. clippedRect = *rect; - GrIRect rtRect = SkIRect::MakeWH(rt->width(), - rt->height()); + GrIRect rtRect = SkIRect::MakeWH(fCurrDrawState.fRenderTarget->width(), + fCurrDrawState.fRenderTarget->height()); if (clippedRect.intersect(rtRect)) { rect = &clippedRect; } else { @@ -1330,7 +1329,7 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { static const GrGLfloat scale255 = 1.f / 255.f; a = GrColorUnpackA(color) * scale255; GrGLfloat scaleRGB = scale255; - if (GrPixelConfigIsUnpremultiplied(rt->config())) { + if (GrPixelConfigIsUnpremultiplied(fCurrDrawState.fRenderTarget->config())) { scaleRGB *= a; } r = GrColorUnpackR(color) * scaleRGB; @@ -1338,13 +1337,13 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { b = GrColorUnpackB(color) * scaleRGB; GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); - fHWDrawState.disableState(GrDrawState::kNoColorWrites_StateBit); + fHWDrawState.fFlagBits &= ~kNoColorWrites_StateBit; GL_CALL(ClearColor(r, g, b, a)); GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); } void GrGpuGL::clearStencil() { - if (NULL == this->getRenderTarget()) { + if (NULL == fCurrDrawState.fRenderTarget) { return; } @@ -1357,17 +1356,17 @@ void GrGpuGL::clearStencil() { GL_CALL(StencilMask(0xffffffff)); GL_CALL(ClearStencil(0)); GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); - fHWDrawState.stencil()->invalidate(); + fHWDrawState.fStencilSettings.invalidate(); } void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) { - GrRenderTarget* rt = this->getRenderTarget(); - GrAssert(NULL != rt); + GrAssert(NULL != fCurrDrawState.fRenderTarget); // this should only be called internally when we know we have a // stencil buffer. - GrAssert(NULL != rt->getStencilBuffer()); - GrGLint stencilBitCount = rt->getStencilBuffer()->bits(); + GrAssert(NULL != fCurrDrawState.fRenderTarget->getStencilBuffer()); + GrGLint stencilBitCount = + fCurrDrawState.fRenderTarget->getStencilBuffer()->bits(); #if 0 GrAssert(stencilBitCount > 0); GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); @@ -1390,7 +1389,7 @@ void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) { GL_CALL(StencilMask(clipStencilMask)); GL_CALL(ClearStencil(value)); GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); - fHWDrawState.stencil()->invalidate(); + fHWDrawState.fStencilSettings.invalidate(); } void GrGpuGL::onForceRenderTargetFlush() { @@ -1446,12 +1445,13 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target, // resolve the render target if necessary GrGLRenderTarget* tgt = static_cast(target); - GrDrawState::AutoRenderTargetRestore arr; + GrAutoTPtrValueRestore autoTargetRestore; switch (tgt->getResolveType()) { case GrGLRenderTarget::kCantResolve_ResolveType: return false; case GrGLRenderTarget::kAutoResolves_ResolveType: - arr.set(this->drawState(), target); + autoTargetRestore.save(&fCurrDrawState.fRenderTarget); + fCurrDrawState.fRenderTarget = target; this->flushRenderTarget(&GrIRect::EmptyIRect()); break; case GrGLRenderTarget::kCanResolve_ResolveType: @@ -1549,11 +1549,10 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target, void GrGpuGL::flushRenderTarget(const GrIRect* bound) { - GrAssert(this->getRenderTarget() != NULL); + GrAssert(NULL != fCurrDrawState.fRenderTarget); - GrGLRenderTarget* rt = - static_cast(this->getRenderTarget()); - if (fHWDrawState.getRenderTarget() != rt) { + GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget; + if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) { GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); #if GR_COLLECT_STATS ++fStats.fRenderTargetChngCnt; @@ -1566,7 +1565,7 @@ void GrGpuGL::flushRenderTarget(const GrIRect* bound) { } #endif fDirtyFlags.fRenderTargetChanged = true; - fHWDrawState.setRenderTarget(rt); + fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget; const GrGLIRect& vp = rt->getViewport(); if (fHWBounds.fViewportRect != vp) { vp.pushToGLViewport(this->glInterface()); @@ -1683,7 +1682,7 @@ void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) { #endif // make sure we go through flushRenderTarget() since we've modified // the bound DRAW FBO ID. - fHWDrawState.setRenderTarget(NULL); + fHWDrawState.fRenderTarget = NULL; const GrGLIRect& vp = rt->getViewport(); const GrIRect dirtyRect = rt->getResolveRect(); GrGLIRect r; @@ -1755,24 +1754,21 @@ GR_STATIC_ASSERT(6 == kZero_StencilOp); GR_STATIC_ASSERT(7 == kInvert_StencilOp); void GrGpuGL::flushStencil() { - const GrDrawState& drawState = this->getDrawState(); - const GrStencilSettings* settings = &drawState.getStencil(); + const GrStencilSettings* settings = &fCurrDrawState.fStencilSettings; // use stencil for clipping if clipping is enabled and the clip // has been written into the stencil. - bool stencilClip = fClipInStencil && drawState.isClipState(); - - bool modifyingStencilClip = drawState.isStateFlagEnabled( - kModifyStencilClip_StateBit); + bool stencilClip = fClipInStencil && + (kClip_StateBit & fCurrDrawState.fFlagBits); bool stencilChange = fHWStencilClip != stencilClip || - fHWDrawState.getStencil() != *settings || - (fHWDrawState.isStateFlagEnabled(kModifyStencilClip_StateBit) != - modifyingStencilClip); + fHWDrawState.fStencilSettings != *settings || + ((fHWDrawState.fFlagBits & kModifyStencilClip_StateBit) != + (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit)); if (stencilChange) { // we can't simultaneously perform stencil-clipping and modify the stencil clip - GrAssert(!stencilClip || !drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)); + GrAssert(!stencilClip || !(fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit)); if (settings->isDisabled()) { if (stencilClip) { @@ -1797,14 +1793,15 @@ void GrGpuGL::flushStencil() { } #endif int stencilBits = 0; - GrStencilBuffer* stencilBuffer = - drawState.getRenderTarget()->getStencilBuffer(); + GrStencilBuffer* stencilBuffer = + fCurrDrawState.fRenderTarget->getStencilBuffer(); if (NULL != stencilBuffer) { stencilBits = stencilBuffer->bits(); } // TODO: dynamically attach a stencil buffer GrAssert(stencilBits || - (GrStencilSettings::gDisabled == *settings)); + (GrStencilSettings::gDisabled == + fCurrDrawState.fStencilSettings)); GrGLuint clipStencilMask = 0; GrGLuint userStencilMask = ~0; @@ -1818,7 +1815,7 @@ void GrGpuGL::flushStencil() { unsigned int frontWriteMask = settings->fFrontWriteMask; GrGLenum frontFunc; - if (modifyingStencilClip) { + if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) { GrAssert(settings->fFrontFunc < kBasicStencilFuncCount); frontFunc = grToGLStencilFunc[settings->fFrontFunc]; @@ -1850,7 +1847,7 @@ void GrGpuGL::flushStencil() { unsigned int backWriteMask = settings->fBackWriteMask; - if (modifyingStencilClip) { + if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) { GrAssert(settings->fBackFunc < kBasicStencilFuncCount); backFunc = grToGLStencilFunc[settings->fBackFunc]; } else { @@ -1888,7 +1885,7 @@ void GrGpuGL::flushStencil() { grToGLStencilOp[settings->fFrontPassOp])); } } - *fHWDrawState.stencil() = *settings; + fHWDrawState.fStencilSettings = fCurrDrawState.fStencilSettings; fHWStencilClip = stencilClip; } } @@ -1900,8 +1897,6 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) { // we prefer smooth lines over multisampled lines // msaa should be disabled if drawing smooth lines. - - GrRenderTarget* rt = this->getRenderTarget(); if (GrIsPrimTypeLines(type)) { bool smooth = this->willUseHWAALines(); if (!fHWAAState.fSmoothLineEnabled && smooth) { @@ -1911,13 +1906,13 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) { GL_CALL(Disable(GR_GL_LINE_SMOOTH)); fHWAAState.fSmoothLineEnabled = false; } - if (rt->isMultisampled() && + if (fCurrDrawState.fRenderTarget->isMultisampled() && fHWAAState.fMSAAEnabled) { GL_CALL(Disable(GR_GL_MULTISAMPLE)); fHWAAState.fMSAAEnabled = false; } - } else if (rt->isMultisampled() && - this->getDrawState().isHWAntialiasState() != + } else if (fCurrDrawState.fRenderTarget->isMultisampled() && + SkToBool(kHWAntialias_StateBit & fCurrDrawState.fFlagBits) != fHWAAState.fMSAAEnabled) { if (fHWAAState.fMSAAEnabled) { GL_CALL(Disable(GR_GL_MULTISAMPLE)); @@ -1938,11 +1933,12 @@ void GrGpuGL::flushBlend(GrPrimitiveType type, GL_CALL(Enable(GR_GL_BLEND)); fHWBlendDisabled = false; } - if (kSA_BlendCoeff != fHWDrawState.getSrcBlendCoeff() || - kISA_BlendCoeff != fHWDrawState.getDstBlendCoeff()) { + if (kSA_BlendCoeff != fHWDrawState.fSrcBlend || + kISA_BlendCoeff != fHWDrawState.fDstBlend) { GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_BlendCoeff], gXfermodeCoeff2Blend[kISA_BlendCoeff])); - fHWDrawState.setBlendFunc(kSA_BlendCoeff, kISA_BlendCoeff); + fHWDrawState.fSrcBlend = kSA_BlendCoeff; + fHWDrawState.fDstBlend = kISA_BlendCoeff; } } else { // any optimization to disable blending should @@ -1959,25 +1955,25 @@ void GrGpuGL::flushBlend(GrPrimitiveType type, fHWBlendDisabled = blendOff; } if (!blendOff) { - if (fHWDrawState.getSrcBlendCoeff() != srcCoeff || - fHWDrawState.getDstBlendCoeff() != dstCoeff) { + if (fHWDrawState.fSrcBlend != srcCoeff || + fHWDrawState.fDstBlend != dstCoeff) { GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], gXfermodeCoeff2Blend[dstCoeff])); - fHWDrawState.setBlendFunc(srcCoeff, dstCoeff); + fHWDrawState.fSrcBlend = srcCoeff; + fHWDrawState.fDstBlend = dstCoeff; } - GrColor blendConstant = this->getDrawState().getBlendConstant(); if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff)) && - fHWDrawState.getBlendConstant() != blendConstant) { + fHWDrawState.fBlendConstant != fCurrDrawState.fBlendConstant) { float c[] = { - GrColorUnpackR(blendConstant) / 255.f, - GrColorUnpackG(blendConstant) / 255.f, - GrColorUnpackB(blendConstant) / 255.f, - GrColorUnpackA(blendConstant) / 255.f + GrColorUnpackR(fCurrDrawState.fBlendConstant) / 255.f, + GrColorUnpackG(fCurrDrawState.fBlendConstant) / 255.f, + GrColorUnpackB(fCurrDrawState.fBlendConstant) / 255.f, + GrColorUnpackA(fCurrDrawState.fBlendConstant) / 255.f }; GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); - fHWDrawState.setBlendConstant(blendConstant); + fHWDrawState.fBlendConstant = fCurrDrawState.fBlendConstant; } } } @@ -2037,13 +2033,12 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { // GrGpu::setupClipAndFlushState should have already checked this // and bailed if not true. - GrAssert(this->getRenderTarget() != NULL); + GrAssert(NULL != fCurrDrawState.fRenderTarget); for (int s = 0; s < GrDrawState::kNumStages; ++s) { // bind texture and set sampler state if (this->isStageEnabled(s)) { - GrGLTexture* nextTexture = - static_cast(this->drawState()->getTexture(s)); + GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTextures[s]; // true for now, but maybe not with GrEffect. GrAssert(NULL != nextTexture); @@ -2057,20 +2052,20 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { resolveRenderTarget(texRT); } - if (fHWDrawState.getTexture(s) != nextTexture) { + if (fHWDrawState.fTextures[s] != nextTexture) { setTextureUnit(s); GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID())); #if GR_COLLECT_STATS ++fStats.fTextureChngCnt; #endif //GrPrintf("---- bindtexture %d\n", nextTexture->textureID()); - fHWDrawState.setTexture(s, nextTexture); + fHWDrawState.fTextures[s] = nextTexture; // The texture matrix has to compensate for texture width/height // and NPOT-embedded-in-POT fDirtyFlags.fTextureChangedMask |= (1 << s); } - const GrSamplerState& sampler = this->getSampler(s); + const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; ResetTimestamp timestamp; const GrGLTexture::TexParams& oldTexParams = nextTexture->getCachedTexParams(×tamp); @@ -2122,7 +2117,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { GrIRect* rect = NULL; GrIRect clipBounds; - if (this->getDrawState().isClipState() && + if ((fCurrDrawState.fFlagBits & kClip_StateBit) && fClip.hasConservativeBounds()) { fClip.getConservativeBounds().roundOut(&clipBounds); rect = &clipBounds; @@ -2130,19 +2125,19 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { this->flushRenderTarget(rect); this->flushAAState(type); - if (this->getDrawState().isDitherState() != - fHWDrawState.isDitherState()) { - if (this->getDrawState().isDitherState()) { + if ((fCurrDrawState.fFlagBits & kDither_StateBit) != + (fHWDrawState.fFlagBits & kDither_StateBit)) { + if (fCurrDrawState.fFlagBits & kDither_StateBit) { GL_CALL(Enable(GR_GL_DITHER)); } else { GL_CALL(Disable(GR_GL_DITHER)); } } - if (this->getDrawState().isColorWriteDisabled() != - fHWDrawState.isColorWriteDisabled()) { + if ((fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) != + (fHWDrawState.fFlagBits & kNoColorWrites_StateBit)) { GrGLenum mask; - if (this->getDrawState().isColorWriteDisabled()) { + if (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) { mask = GR_GL_FALSE; } else { mask = GR_GL_TRUE; @@ -2150,8 +2145,8 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { GL_CALL(ColorMask(mask, mask, mask, mask)); } - if (fHWDrawState.getDrawFace() != this->getDrawFace()) { - switch (this->getDrawFace()) { + if (fHWDrawState.fDrawFace != fCurrDrawState.fDrawFace) { + switch (fCurrDrawState.fDrawFace) { case GrDrawState::kCCW_DrawFace: GL_CALL(Enable(GR_GL_CULL_FACE)); GL_CALL(CullFace(GR_GL_BACK)); @@ -2166,27 +2161,24 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { default: GrCrash("Unknown draw face."); } - fHWDrawState.setDrawFace(this->getDrawFace()); + fHWDrawState.fDrawFace = fCurrDrawState.fDrawFace; } #if GR_DEBUG // check for circular rendering for (int s = 0; s < GrDrawState::kNumStages; ++s) { GrAssert(!this->isStageEnabled(s) || - NULL == this->getRenderTarget() || - NULL == this->getTexture(s) || - this->getTexture(s)->asRenderTarget() != - this->getRenderTarget()); + NULL == fCurrDrawState.fRenderTarget || + NULL == fCurrDrawState.fTextures[s] || + fCurrDrawState.fTextures[s]->asRenderTarget() != + fCurrDrawState.fRenderTarget); } #endif - this->flushStencil(); - - // the flushStencil() function called above detecs a change in the - // kModifyStencilClip_StateBit flag. Therefore this copy must happen after - // flushStencil() - fHWDrawState.copyStateFlags(this->getDrawState()); + flushStencil(); + // flushStencil may look at the private state bits, so keep it before this. + fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits; return true; } @@ -2218,22 +2210,22 @@ void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) { void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { GrAssert(NULL != renderTarget); - if (this->getRenderTarget() == renderTarget) { - this->setRenderTarget(NULL); + if (fCurrDrawState.fRenderTarget == renderTarget) { + fCurrDrawState.fRenderTarget = NULL; } - if (this->getRenderTarget() == renderTarget) { - fHWDrawState.setRenderTarget(NULL); + if (fHWDrawState.fRenderTarget == renderTarget) { + fHWDrawState.fRenderTarget = NULL; } } void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { for (int s = 0; s < GrDrawState::kNumStages; ++s) { - if (this->getTexture(s) == texture) { - this->setTexture(s, NULL); + if (fCurrDrawState.fTextures[s] == texture) { + fCurrDrawState.fTextures[s] = NULL; } - if (fHWDrawState.getTexture(s) == texture) { + if (fHWDrawState.fTextures[s] == texture) { // deleting bound texture does implied bind to 0 - this->setTexture(s, NULL); + fHWDrawState.fTextures[s] = NULL; } } } diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp index 5109a10..9018a4e 100644 --- a/src/gpu/GrGpuGLShaders.cpp +++ b/src/gpu/GrGpuGLShaders.cpp @@ -343,7 +343,7 @@ const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) { if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) { - return fHWDrawState.getSampler(stage).getMatrix(); + return fHWDrawState.fSamplerStates[stage].getMatrix(); } else { return fProgramData->fTextureMatrices[stage]; } @@ -351,9 +351,9 @@ const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) { void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) { GrAssert(fProgramData); - if (GrGLProgram::kSetAsAttribute == + if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) { - fHWDrawState.sampler(stage)->setMatrix(matrix); + fHWDrawState.fSamplerStates[stage].setMatrix(matrix); } else { fProgramData->fTextureMatrices[stage] = matrix; } @@ -388,68 +388,47 @@ void GrGpuGLShaders::onResetContext() { } void GrGpuGLShaders::flushViewMatrix() { + GrAssert(NULL != fCurrDrawState.fRenderTarget); + GrMatrix m; + m.setAll( + GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1, + 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1, + 0, 0, GrMatrix::I()[8]); + m.setConcat(m, fCurrDrawState.fViewMatrix); + + // ES doesn't allow you to pass true to the transpose param, + // so do our own transpose + GrGLfloat mt[] = { + GrScalarToFloat(m[GrMatrix::kMScaleX]), + GrScalarToFloat(m[GrMatrix::kMSkewY]), + GrScalarToFloat(m[GrMatrix::kMPersp0]), + GrScalarToFloat(m[GrMatrix::kMSkewX]), + GrScalarToFloat(m[GrMatrix::kMScaleY]), + GrScalarToFloat(m[GrMatrix::kMPersp1]), + GrScalarToFloat(m[GrMatrix::kMTransX]), + GrScalarToFloat(m[GrMatrix::kMTransY]), + GrScalarToFloat(m[GrMatrix::kMPersp2]) + }; - const GrMatrix* hwViewMatrix; - // If we are using a uniform for the matrix then the cached value is - // stored with each program. If we are using an attribute than it is global - // to all programs. - if (GrGLProgram::kSetAsAttribute == + if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fViewMatrixUni) { - hwViewMatrix = &fHWDrawState.getViewMatrix(); + int baseIdx = GrGLProgram::ViewMatrixAttributeIdx(); + GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0)); + GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3)); + GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6)); } else { - hwViewMatrix = &fProgramData->fViewMatrix; - } - - if (*hwViewMatrix != this->getViewMatrix()) { - - GrRenderTarget* rt = this->getRenderTarget(); - GrAssert(NULL != rt); - GrMatrix m; - m.setAll( - GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1, - 0,-GrIntToScalar(2) / rt->height(), GR_Scalar1, - 0, 0, GrMatrix::I()[8]); - m.setConcat(m, this->getViewMatrix()); - - // ES doesn't allow you to pass true to the transpose param, - // so do our own transpose - GrGLfloat mt[] = { - GrScalarToFloat(m[GrMatrix::kMScaleX]), - GrScalarToFloat(m[GrMatrix::kMSkewY]), - GrScalarToFloat(m[GrMatrix::kMPersp0]), - GrScalarToFloat(m[GrMatrix::kMSkewX]), - GrScalarToFloat(m[GrMatrix::kMScaleY]), - GrScalarToFloat(m[GrMatrix::kMPersp1]), - GrScalarToFloat(m[GrMatrix::kMTransX]), - GrScalarToFloat(m[GrMatrix::kMTransY]), - GrScalarToFloat(m[GrMatrix::kMPersp2]) - }; - - if (GrGLProgram::kSetAsAttribute == - fProgramData->fUniLocations.fViewMatrixUni) { - int baseIdx = GrGLProgram::ViewMatrixAttributeIdx(); - GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0)); - GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3)); - GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6)); - } else { - GrAssert(GrGLProgram::kUnusedUniform != - fProgramData->fUniLocations.fViewMatrixUni); - GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni, - 1, false, mt)); - } - if (GrGLProgram::kSetAsAttribute == - fProgramData->fUniLocations.fViewMatrixUni) { - fHWDrawState.setViewMatrix(this->getViewMatrix()); - } else { - fProgramData->fViewMatrix = this->getViewMatrix(); - } + GrAssert(GrGLProgram::kUnusedUniform != + fProgramData->fUniLocations.fViewMatrixUni); + GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni, + 1, false, mt)); } } void GrGpuGLShaders::flushTextureDomain(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni; if (GrGLProgram::kUnusedUniform != uni) { - const GrRect &texDom = this->getSampler(s).getTextureDomain(); + const GrRect &texDom = + fCurrDrawState.fSamplerStates[s].getTextureDomain(); if (((1 << s) & fDirtyFlags.fTextureChangedMask) || fProgramData->fTextureDomain[s] != texDom) { @@ -463,7 +442,7 @@ void GrGpuGLShaders::flushTextureDomain(int s) { GrScalarToFloat(texDom.bottom()) }; - GrGLTexture* texture = (GrGLTexture*) this->getTexture(s); + GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; GrGLTexture::Orientation orientation = texture->orientation(); // vertical flip if necessary @@ -482,18 +461,19 @@ void GrGpuGLShaders::flushTextureDomain(int s) { void GrGpuGLShaders::flushTextureMatrix(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni; - GrGLTexture* texture = (GrGLTexture*) this->getTexture(s); + GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; if (NULL != texture) { - const GrMatrix& hwMat = fHWDrawState.getSampler(s).getMatrix(); - const GrMatrix& currMat = this->getSampler(s).getMatrix(); if (GrGLProgram::kUnusedUniform != uni && (((1 << s) & fDirtyFlags.fTextureChangedMask) || - hwMat != currMat)) { + getHWSamplerMatrix(s) != getSamplerMatrix(s))) { - GrAssert(NULL != texture); + GrAssert(NULL != fCurrDrawState.fTextures[s]); + + GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; - GrMatrix m = currMat; - GrSamplerState::SampleMode mode = this->getSampler(s).getSampleMode(); + GrMatrix m = getSamplerMatrix(s); + GrSamplerState::SampleMode mode = + fCurrDrawState.fSamplerStates[s].getSampleMode(); AdjustTextureMatrix(texture, mode, &m); // ES doesn't allow you to pass true to the transpose param, @@ -519,7 +499,7 @@ void GrGpuGLShaders::flushTextureMatrix(int s) { } else { GL_CALL(UniformMatrix3fv(uni, 1, false, mt)); } - this->recordHWSamplerMatrix(s, currMat); + recordHWSamplerMatrix(s, getSamplerMatrix(s)); } } } @@ -527,7 +507,7 @@ void GrGpuGLShaders::flushTextureMatrix(int s) { void GrGpuGLShaders::flushRadial2(int s) { const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni; - const GrSamplerState& sampler = fCurrDrawState.getSampler(s); + const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; if (GrGLProgram::kUnusedUniform != uni && (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() || fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() || @@ -559,7 +539,7 @@ void GrGpuGLShaders::flushRadial2(int s) { } void GrGpuGLShaders::flushConvolution(int s) { - const GrSamplerState& sampler = this->getSampler(s); + const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni; if (GrGLProgram::kUnusedUniform != kernelUni) { GL_CALL(Uniform1fv(kernelUni, sampler.getKernelWidth(), @@ -574,7 +554,7 @@ void GrGpuGLShaders::flushConvolution(int s) { void GrGpuGLShaders::flushTexelSize(int s) { const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni; if (GrGLProgram::kUnusedUniform != uni) { - GrGLTexture* texture = (GrGLTexture*) this->getTexture(s); + GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; if (texture->width() != fProgramData->fTextureWidth[s] || texture->height() != fProgramData->fTextureHeight[s]) { @@ -590,14 +570,13 @@ void GrGpuGLShaders::flushTexelSize(int s) { void GrGpuGLShaders::flushEdgeAAData() { const int& uni = fProgramData->fUniLocations.fEdgesUni; if (GrGLProgram::kUnusedUniform != uni) { - - int count = this->getDrawState().getNumAAEdges(); + int count = fCurrDrawState.fEdgeAANumEdges; GrDrawState::Edge edges[GrDrawState::kMaxEdges]; // Flip the edges in Y float height = - static_cast(this->getRenderTarget()->height()); + static_cast(fCurrDrawState.fRenderTarget->height()); for (int i = 0; i < count; ++i) { - edges[i] = this->getDrawState().getAAEdges()[i]; + edges[i] = fCurrDrawState.fEdgeAAEdges[i]; float b = edges[i].fY; edges[i].fY = -b; edges[i].fZ += b * height; @@ -620,16 +599,16 @@ void GrGpuGLShaders::flushColor(GrColor color) { if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) { // color will be specified per-vertex as an attribute // invalidate the const vertex attrib color - fHWDrawState.setColor(GrColor_ILLEGAL); + fHWDrawState.fColor = GrColor_ILLEGAL; } else { switch (desc.fColorInput) { case ProgramDesc::kAttribute_ColorInput: - if (fHWDrawState.getColor() != color) { + if (fHWDrawState.fColor != color) { // OpenGL ES only supports the float varities of glVertexAttrib float c[] = GR_COLOR_TO_VEC4(color); GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c)); - fHWDrawState.setColor(color); + fHWDrawState.fColor = color; } break; case ProgramDesc::kUniform_ColorInput: @@ -650,13 +629,13 @@ void GrGpuGLShaders::flushColor(GrColor color) { GrCrash("Unknown color type."); } } - GrColor filterColor = this->getDrawState().getColorFilterColor(); - int uni = fProgramData->fUniLocations.fColorFilterUni; - if (uni != GrGLProgram::kUnusedUniform && - fProgramData->fColorFilterColor != filterColor) { - float c[] = GR_COLOR_TO_VEC4(filterColor); - GL_CALL(Uniform4fv(uni, 1, c)); - fProgramData->fColorFilterColor = filterColor; + if (fProgramData->fUniLocations.fColorFilterUni + != GrGLProgram::kUnusedUniform + && fProgramData->fColorFilterColor + != fCurrDrawState.fColorFilterColor) { + float c[] = GR_COLOR_TO_VEC4(fCurrDrawState.fColorFilterColor); + GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c)); + fProgramData->fColorFilterColor = fCurrDrawState.fColorFilterColor; } } @@ -669,7 +648,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { if (fDirtyFlags.fRenderTargetChanged) { // our coords are in pixel space and the GL matrices map to NDC // so if the viewport changed, our matrix is now wrong. - fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix()); + fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); // we assume all shader matrices may be wrong after viewport changes fProgramCache->invalidateViewMatrices(); } @@ -701,11 +680,22 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { } else if (blendOpts & kEmitCoverage_BlendOptFlag) { color = 0xffffffff; } else { - color = this->getColor(); + color = fCurrDrawState.fColor; } this->flushColor(color); - this->flushViewMatrix(); + GrMatrix* currViewMatrix; + if (GrGLProgram::kSetAsAttribute == + fProgramData->fUniLocations.fViewMatrixUni) { + currViewMatrix = &fHWDrawState.fViewMatrix; + } else { + currViewMatrix = &fProgramData->fViewMatrix; + } + + if (*currViewMatrix != fCurrDrawState.fViewMatrix) { + flushViewMatrix(); + *currViewMatrix = fCurrDrawState.fViewMatrix; + } for (int s = 0; s < GrDrawState::kNumStages; ++s) { this->flushTextureMatrix(s); @@ -719,7 +709,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { this->flushTextureDomain(s); } this->flushEdgeAAData(); - this->resetDirtyFlags(); + resetDirtyFlags(); return true; } @@ -866,7 +856,6 @@ void GrGpuGLShaders::setupGeometry(int* startVertex, void GrGpuGLShaders::buildProgram(GrPrimitiveType type, BlendOptFlags blendOpts, GrBlendCoeff dstCoeff) { - const GrDrawState& drawState = this->getDrawState(); ProgramDesc& desc = fCurrentProgram.fProgramDesc; // This should already have been caught @@ -896,7 +885,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, desc.fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : - drawState.getColorFilterMode(); + fCurrDrawState.fColorFilterXfermode; // no reason to do edge aa or look at per-vertex coverage if coverage is // ignored @@ -908,7 +897,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag); bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) || (!requiresAttributeColors && - 0xffffffff == this->getColor()); + 0xffffffff == fCurrDrawState.fColor); if (GR_AGGRESSIVE_SHADER_OPTS && colorIsTransBlack) { desc.fColorInput = ProgramDesc::kTransBlack_ColorInput; } else if (GR_AGGRESSIVE_SHADER_OPTS && colorIsSolidWhite) { @@ -919,15 +908,16 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, desc.fColorInput = ProgramDesc::kAttribute_ColorInput; } - desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges(); + desc.fEdgeAANumEdges = skipCoverage ? 0 : fCurrDrawState.fEdgeAANumEdges; desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 && - drawState.isConcaveEdgeAAState(); + SkToBool(fCurrDrawState.fFlagBits & + kEdgeAAConcave_StateBit); int lastEnabledStage = -1; if (!skipCoverage && (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit)) { - desc.fVertexEdgeType = drawState.getVertexEdgeType(); + desc.fVertexEdgeType = fCurrDrawState.fVertexEdgeType; } else { // use canonical value when not set to avoid cache misses desc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType; @@ -939,19 +929,19 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, stage.fOptFlags = 0; stage.setEnabled(this->isStageEnabled(s)); - bool skip = s < drawState.getFirstCoverageStage() ? skipColor : - skipCoverage; + bool skip = s < fCurrDrawState.fFirstCoverageStage ? skipColor : + skipCoverage; if (!skip && stage.isEnabled()) { lastEnabledStage = s; - GrGLTexture* texture = (GrGLTexture*) drawState.getTexture(s); + GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; GrAssert(NULL != texture); - const GrSamplerState& sampler = drawState.getSampler(s); + const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; // we matrix to invert when orientation is TopDown, so make sure // we aren't in that case before flagging as identity. if (TextureMatrixIsIdentity(texture, sampler)) { stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit; - } else if (!drawState.getSampler(s).getMatrix().hasPerspective()) { + } else if (!getSamplerMatrix(s).hasPerspective()) { stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit; } switch (sampler.getSampleMode()) { @@ -1034,7 +1024,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, } } - if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) { + if (GrPixelConfigIsUnpremultiplied(fCurrDrawState.fRenderTarget->config())) { desc.fOutputPM = ProgramDesc::kNo_OutputPM; } else { desc.fOutputPM = ProgramDesc::kYes_OutputPM; @@ -1056,9 +1046,9 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, // immaterial. int firstCoverageStage = GrDrawState::kNumStages; desc.fFirstCoverageStage = GrDrawState::kNumStages; - bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage; + bool hasCoverage = fCurrDrawState.fFirstCoverageStage <= lastEnabledStage; if (hasCoverage) { - firstCoverageStage = drawState.getFirstCoverageStage(); + firstCoverageStage = fCurrDrawState.fFirstCoverageStage; } // other coverage inputs diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 829d9f0..340cff1 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -102,7 +102,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, // simply because the clip has changed if the clip doesn't affect // the rect. bool disabledClip = false; - if (this->getDrawState().isClipState() && fClip.isRect()) { + if (this->isClipState() && fClip.isRect()) { GrRect clipRect = fClip.getRect(0); // If the clip rect touches the edge of the viewport, extended it @@ -132,7 +132,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, } } if (insideClip) { - this->drawState()->disableState(GrDrawState::kClip_StateBit); + this->disableState(kClip_StateBit); disabledClip = true; } } @@ -176,7 +176,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, fLastRectVertexLayout = layout; } if (disabledClip) { - this->drawState()->disableState(GrDrawState::kClip_StateBit); + this->enableState(kClip_StateBit); } } else { INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices); @@ -328,9 +328,9 @@ void GrInOrderDrawBuffer::reset() { for (uint32_t i = 0; i < numStates; ++i) { const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]); for (int s = 0; s < GrDrawState::kNumStages; ++s) { - GrSafeUnref(dstate.getTexture(s)); + GrSafeUnref(dstate.fTextures[s]); } - GrSafeUnref(dstate.getRenderTarget()); + GrSafeUnref(dstate.fRenderTarget); } int numDraws = fDraws.count(); for (int d = 0; d < numDraws; ++d) { @@ -594,14 +594,14 @@ bool GrInOrderDrawBuffer::needsNewState() const { void GrInOrderDrawBuffer::pushState() { for (int s = 0; s < GrDrawState::kNumStages; ++s) { - GrSafeRef(fCurrDrawState.getTexture(s)); + GrSafeRef(fCurrDrawState.fTextures[s]); } - GrSafeRef(fCurrDrawState.getRenderTarget()); + GrSafeRef(fCurrDrawState.fRenderTarget); this->saveCurrentDrawState(&fStates.push_back()); } bool GrInOrderDrawBuffer::needsNewClip() const { - if (this->getDrawState().isClipState()) { + if (fCurrDrawState.fFlagBits & kClip_StateBit) { if (fClips.empty() || (fClipSet && fClips.back() != fClip)) { return true; } diff --git a/src/gpu/GrTesselatedPathRenderer.cpp b/src/gpu/GrTesselatedPathRenderer.cpp index 5834dfd..b6612d1 100644 --- a/src/gpu/GrTesselatedPathRenderer.cpp +++ b/src/gpu/GrTesselatedPathRenderer.cpp @@ -471,7 +471,7 @@ FINISHED: if (count <= maxEdges) { // All edges fit; upload all edges and draw all verts as a fan fTarget->setVertexSourceToArray(layout, base, count); - fTarget->drawState()->setEdgeAAData(&edges[0], count); + fTarget->setEdgeAAData(&edges[0], count); fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); } else { // Upload "maxEdges" edges and verts at a time, and draw as @@ -481,11 +481,11 @@ FINISHED: base[i] = base[0]; int size = GR_CT_MIN(count - i, maxEdges); fTarget->setVertexSourceToArray(layout, &base[i], size); - fTarget->drawState()->setEdgeAAData(&edges[i], size); + fTarget->setEdgeAAData(&edges[i], size); fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size); } } - fTarget->drawState()->setEdgeAAData(NULL, 0); + fTarget->setEdgeAAData(NULL, 0); } else { fTarget->setVertexSourceToArray(layout, base, count); fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); @@ -534,7 +534,7 @@ FINISHED: } // Draw the resulting polys and upload their edge data. - fTarget->drawState()->enableState(GrDrawState::kEdgeAAConcave_StateBit); + fTarget->enableState(GrDrawTarget::kEdgeAAConcave_StateBit); const GrPointArray& vertices = ptess.vertices(); const GrIndexArray& indices = ptess.indices(); const GrDrawState::Edge* edges = ptess.edges(); @@ -567,13 +567,12 @@ FINISHED: tri_edges[t++] = edge4; tri_edges[t++] = edge5; } - fTarget->drawState()->setEdgeAAData(&tri_edges[0], t); + fTarget->setEdgeAAData(&tri_edges[0], t); fTarget->setVertexSourceToArray(layout, &tri_verts[0], 3); fTarget->drawNonIndexed(kTriangles_PrimitiveType, 0, 3); } - fTarget->drawState()->setEdgeAAData(NULL, 0); - fTarget->drawState()->disableState( - GrDrawState::kEdgeAAConcave_StateBit); + fTarget->setEdgeAAData(NULL, 0); + fTarget->disableState(GrDrawTarget::kEdgeAAConcave_StateBit); return; } diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index ef98487..4b78d4a 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -25,7 +25,6 @@ enum { void GrTextContext::flushGlyphs() { if (fCurrVertex > 0) { GrDrawTarget::AutoStateRestore asr(fDrawTarget); - GrDrawState* drawState = fDrawTarget->drawState(); // setup our sampler state for our text texture/atlas GrSamplerState::Filter filter; @@ -42,7 +41,6 @@ void GrTextContext::flushGlyphs() { int nIndices = fCurrVertex + (fCurrVertex >> 1); GrAssert(fCurrTexture); fDrawTarget->setTexture(kGlyphMaskStage, fCurrTexture); - drawState->setTexture(kGlyphMaskStage, fCurrTexture); if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) { if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff || @@ -51,15 +49,15 @@ void GrTextContext::flushGlyphs() { GrPrintf("LCD Text will not draw correctly.\n"); } // setup blend so that we get mask * paintColor + (1-mask)*dstColor - drawState->setBlendConstant(fPaint.fColor); - drawState->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff); + fDrawTarget->setBlendConstant(fPaint.fColor); + fDrawTarget->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff); // don't modulate by the paint's color in the frag since we're // already doing it via the blend const. - drawState->setColor(0xffffffff); + fDrawTarget->setColor(0xffffffff); } else { // set back to normal in case we took LCD path previously. - drawState->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff); - drawState->setColor(fPaint.fColor); + fDrawTarget->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff); + fDrawTarget->setColor(fPaint.fColor); } fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());