diff options
-rw-r--r-- | include/gpu/GrTypes.h | 2 | ||||
-rwxr-xr-x | src/gpu/GrContext.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrDrawState.cpp | 16 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 12 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 22 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 107 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 10 |
8 files changed, 128 insertions, 51 deletions
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 280bf4d40a..f04a734c31 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -667,7 +667,7 @@ enum GrGLBackendState { // View state stands for scissor and viewport kView_GrGLBackendState = 1 << 2, kBlend_GrGLBackendState = 1 << 3, - kMSAAEnable_GrGLBackendState = 1 << 4, + kAA_GrGLBackendState = 1 << 4, kVertex_GrGLBackendState = 1 << 5, kStencil_GrGLBackendState = 1 << 6, kPixelStore_GrGLBackendState = 1 << 7, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 95e0d51cf8..55a9ccf2a8 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -751,6 +751,10 @@ static bool apply_aa_to_rect(GrDrawTarget* target, return false; } + if (0 == strokeWidth && target->willUseHWAALines()) { + return false; + } + #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) if (strokeWidth >= 0) { #endif diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 1b40642251..02c7920f5d 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -339,7 +339,8 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, // (0,1). The same applies when coverage is known to be 0. if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { if (this->getStencil().doesWrite()) { - return kEmitCoverage_BlendOptFlag; + return kDisableBlend_BlendOptFlag | + kEmitCoverage_BlendOptFlag; } else { return kSkipDraw_BlendOptFlag; } @@ -358,14 +359,13 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, if (kOne_GrBlendCoeff == *srcCoeff) { // if there is no coverage and coeffs are (1,0) then we // won't need to read the dst at all, it gets replaced by src - *dstCoeff = kZero_GrBlendCoeff; - return kNone_BlendOpt; + return kDisableBlend_BlendOptFlag; } else if (kZero_GrBlendCoeff == *srcCoeff) { // if the op is "clear" then we don't need to emit a color // or blend, just write transparent black into the dst. *srcCoeff = kOne_GrBlendCoeff; *dstCoeff = kZero_GrBlendCoeff; - return kEmitTransBlack_BlendOptFlag; + return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; } } } else if (this->isCoverageDrawing()) { @@ -399,7 +399,13 @@ GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, return kCoverageAsAlpha_BlendOptFlag; } } - + if (kOne_GrBlendCoeff == *srcCoeff && + kZero_GrBlendCoeff == *dstCoeff && + this->willEffectReadDstColor()) { + // In this case the shader will fully resolve the color, coverage, and dst and we don't + // need blending. + return kDisableBlend_BlendOptFlag; + } return kNone_BlendOpt; } diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 145f462744..c1dd9dcd36 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -521,24 +521,28 @@ public: */ kSkipDraw_BlendOptFlag = 0x1, /** + * Emit the src color, disable HW blending (replace dst with src) + */ + kDisableBlend_BlendOptFlag = 0x2, + /** * The coverage value does not have to be computed separately from alpha, the the output * color can be the modulation of the two. */ - kCoverageAsAlpha_BlendOptFlag = 0x2, + kCoverageAsAlpha_BlendOptFlag = 0x4, /** * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are * "don't cares". */ - kEmitCoverage_BlendOptFlag = 0x4, + kEmitCoverage_BlendOptFlag = 0x8, /** * Emit transparent black instead of the src color, no need to compute coverage. */ - kEmitTransBlack_BlendOptFlag = 0x8, + kEmitTransBlack_BlendOptFlag = 0x10, /** * Flag used to invalidate the cached BlendOptFlags, OptSrcCoeff, and OptDstCoeff cached by * the get BlendOpts function. */ - kInvalid_BlendOptFlag = 0x10, + kInvalid_BlendOptFlag = 0x20, }; GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index d44c6991b4..72204fa14b 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -613,16 +613,24 @@ void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { //////////////////////////////////////////////////////////////////////////////// +bool GrDrawTarget::willUseHWAALines() const { + // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth + // lines tweak the incoming alpha value 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 (!this->caps()->hwAALineSupport() || + !this->getDrawState().isHWAntialiasState()) { + return false; + } + GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts(); + return (GrDrawState::kDisableBlend_BlendOptFlag & opts) && + (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts); +} + bool GrDrawTarget::canApplyCoverage() const { // we can correctly apply coverage if a) we have dual source blending - // or b) one of our blend optimizations applies - // or c) the src/dst coefficients are 1, 0 respectively. - GrBlendCoeff srcCoeff; - GrBlendCoeff dstCoeff; + // or b) one of our blend optimizations applies. return this->caps()->dualSourceBlendingSupport() || - GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true, &srcCoeff, - &dstCoeff) || - (kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); + GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 0c03e34041..c868e56aa7 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -113,6 +113,12 @@ public: } /** + * Given the current draw state and hw support, will HW AA lines be used (if + * a line primitive type is drawn)? + */ + bool willUseHWAALines() const; + + /** * There are three types of "sources" of geometry (vertices and indices) for * draw calls made on the target. When performing an indexed draw, the * indices and vertices can use different source types. Once a source is diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 988b64e679..a0e08e5a00 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -280,8 +280,8 @@ void GrGpuGL::onResetContext(uint32_t resetBits) { GL_CALL(LineWidth(1)); } - if (resetBits & kMSAAEnable_GrGLBackendState) { - fMSAAEnabled = kUnknown_TriState; + if (resetBits & kAA_GrGLBackendState) { + fHWAAState.invalidate(); } fHWActiveTextureUnitIdx = -1; // invalid @@ -2164,20 +2164,45 @@ void GrGpuGL::flushAAState(DrawType type) { const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); if (kGL_GrGLStandard == this->glStandard()) { - if (RT_HAS_MSAA) { + // ES doesn't support toggling GL_MULTISAMPLE and doesn't have + // smooth lines. + // we prefer smooth lines over multisampled lines + bool smoothLines = false; + + if (kDrawLines_DrawType == type) { + smoothLines = this->willUseHWAALines(); + if (smoothLines) { + if (kYes_TriState != fHWAAState.fSmoothLineEnabled) { + GL_CALL(Enable(GR_GL_LINE_SMOOTH)); + fHWAAState.fSmoothLineEnabled = kYes_TriState; + // must disable msaa to use line smoothing + if (RT_HAS_MSAA && + kNo_TriState != fHWAAState.fMSAAEnabled) { + GL_CALL(Disable(GR_GL_MULTISAMPLE)); + fHWAAState.fMSAAEnabled = kNo_TriState; + } + } + } else { + if (kNo_TriState != fHWAAState.fSmoothLineEnabled) { + GL_CALL(Disable(GR_GL_LINE_SMOOTH)); + fHWAAState.fSmoothLineEnabled = kNo_TriState; + } + } + } + if (!smoothLines && RT_HAS_MSAA) { // FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths // convex hulls of each segment appear to get filled. bool enableMSAA = kStencilPath_DrawType == type || this->getDrawState().isHWAntialiasState(); if (enableMSAA) { - if (kYes_TriState != fMSAAEnabled) { + if (kYes_TriState != fHWAAState.fMSAAEnabled) { GL_CALL(Enable(GR_GL_MULTISAMPLE)); - fMSAAEnabled = kYes_TriState; + fHWAAState.fMSAAEnabled = kYes_TriState; } } else { - if (kNo_TriState != fMSAAEnabled) { + if (kNo_TriState != fHWAAState.fMSAAEnabled) { GL_CALL(Disable(GR_GL_MULTISAMPLE)); - fMSAAEnabled = kNo_TriState; + fHWAAState.fMSAAEnabled = kNo_TriState; } } } @@ -2203,36 +2228,52 @@ void GrGpuGL::flushPathStencilSettings(SkPath::FillType fill) { void GrGpuGL::flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { - // any optimization to disable blending should have already been applied and - // tweaked the coeffs to (1, 0). - bool blendOff = kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; - if (blendOff) { - if (kNo_TriState != fHWBlendState.fEnabled) { - GL_CALL(Disable(GR_GL_BLEND)); - fHWBlendState.fEnabled = kNo_TriState; - } - } else { + if (isLines && this->willUseHWAALines()) { if (kYes_TriState != fHWBlendState.fEnabled) { GL_CALL(Enable(GR_GL_BLEND)); fHWBlendState.fEnabled = kYes_TriState; } - if (fHWBlendState.fSrcCoeff != srcCoeff || - fHWBlendState.fDstCoeff != dstCoeff) { - GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], - gXfermodeCoeff2Blend[dstCoeff])); - fHWBlendState.fSrcCoeff = srcCoeff; - fHWBlendState.fDstCoeff = dstCoeff; - } - GrColor blendConst = this->getDrawState().getBlendConstant(); - if ((BlendCoeffReferencesConstant(srcCoeff) || - BlendCoeffReferencesConstant(dstCoeff)) && - (!fHWBlendState.fConstColorValid || - fHWBlendState.fConstColor != blendConst)) { - GrGLfloat c[4]; - GrColorToRGBAFloat(blendConst, c); - GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); - fHWBlendState.fConstColor = blendConst; - fHWBlendState.fConstColorValid = true; + if (kSA_GrBlendCoeff != fHWBlendState.fSrcCoeff || + kISA_GrBlendCoeff != fHWBlendState.fDstCoeff) { + GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_GrBlendCoeff], + gXfermodeCoeff2Blend[kISA_GrBlendCoeff])); + fHWBlendState.fSrcCoeff = kSA_GrBlendCoeff; + fHWBlendState.fDstCoeff = kISA_GrBlendCoeff; + } + } else { + // any optimization to disable blending should + // have already been applied and tweaked the coeffs + // to (1, 0). + bool blendOff = kOne_GrBlendCoeff == srcCoeff && + kZero_GrBlendCoeff == dstCoeff; + if (blendOff) { + if (kNo_TriState != fHWBlendState.fEnabled) { + GL_CALL(Disable(GR_GL_BLEND)); + fHWBlendState.fEnabled = kNo_TriState; + } + } else { + if (kYes_TriState != fHWBlendState.fEnabled) { + GL_CALL(Enable(GR_GL_BLEND)); + fHWBlendState.fEnabled = kYes_TriState; + } + if (fHWBlendState.fSrcCoeff != srcCoeff || + fHWBlendState.fDstCoeff != dstCoeff) { + GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff], + gXfermodeCoeff2Blend[dstCoeff])); + fHWBlendState.fSrcCoeff = srcCoeff; + fHWBlendState.fDstCoeff = dstCoeff; + } + GrColor blendConst = this->getDrawState().getBlendConstant(); + if ((BlendCoeffReferencesConstant(srcCoeff) || + BlendCoeffReferencesConstant(dstCoeff)) && + (!fHWBlendState.fConstColorValid || + fHWBlendState.fConstColor != blendConst)) { + GrGLfloat c[4]; + GrColorToRGBAFloat(blendConst, c); + GL_CALL(BlendColor(c[0], c[1], c[2], c[3])); + fHWBlendState.fConstColor = blendConst; + fHWBlendState.fConstColorValid = true; + } } } } diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 3d84188b19..a8a9727b32 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -443,7 +443,15 @@ private: } } fHWBlendState; - TriState fMSAAEnabled; + struct { + TriState fMSAAEnabled; + TriState fSmoothLineEnabled; + void invalidate() { + fMSAAEnabled = kUnknown_TriState; + fSmoothLineEnabled = kUnknown_TriState; + } + } fHWAAState; + GrGLProgram::MatrixState fHWProjectionMatrixState; |