diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-03-15 19:09:25 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-03-15 19:09:25 +0000 |
commit | 080773ca79cbdc230730d295441255e9254d76a6 (patch) | |
tree | 549239db566093d9f0a7743f6e67471931142f4e | |
parent | dc008e17104fc544d2b80c09c9835cf173c25b50 (diff) |
Add blend constant color and use it for lcd text common case (no fancy blend or shaded text)
Review URL: http://codereview.appspot.com/4274057/
git-svn-id: http://skia.googlecode.com/svn/trunk@941 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gpu/include/GrDrawTarget.h | 19 | ||||
-rw-r--r-- | gpu/include/GrGLInterface.h | 2 | ||||
-rw-r--r-- | gpu/include/GrGLPlatformIncludes.h | 4 | ||||
-rw-r--r-- | gpu/include/GrTexture.h | 1 | ||||
-rw-r--r-- | gpu/include/GrTypes.h | 6 | ||||
-rw-r--r-- | gpu/src/GrGLInterface.cpp | 1 | ||||
-rw-r--r-- | gpu/src/GrGpu.cpp | 8 | ||||
-rw-r--r-- | gpu/src/GrGpuGL.cpp | 59 | ||||
-rw-r--r-- | gpu/src/GrGpuGL.h | 2 | ||||
-rw-r--r-- | gpu/src/GrGpuGLFixed.cpp | 8 | ||||
-rw-r--r-- | gpu/src/GrTextContext.cpp | 19 |
11 files changed, 129 insertions, 0 deletions
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h index aef5937ea7..35f912b7c4 100644 --- a/gpu/include/GrDrawTarget.h +++ b/gpu/include/GrDrawTarget.h @@ -136,6 +136,7 @@ protected: uint32_t fFlagBits; GrBlendCoeff fSrcBlend; GrBlendCoeff fDstBlend; + GrColor fBlendConstant; GrTexture* fTextures[kNumStages]; GrSamplerState fSamplerStates[kNumStages]; GrRenderTarget* fRenderTarget; @@ -359,6 +360,24 @@ public: void setBlendFunc(GrBlendCoeff srcCoef, GrBlendCoeff dstCoef); /** + * 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; } + + /** * Used to save and restore the GrGpu's drawing state */ struct SavedDrawState { diff --git a/gpu/include/GrGLInterface.h b/gpu/include/GrGLInterface.h index 0c2a2d9bad..0a41905361 100644 --- a/gpu/include/GrGLInterface.h +++ b/gpu/include/GrGLInterface.h @@ -63,6 +63,7 @@ struct GrGLInterface { typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindAttribLocationProc)(GLuint program, GLuint index, const char* name); typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindBufferProc)(GLenum target, GLuint buffer); typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBindTextureProc)(GLenum target, GLuint texture); + typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBlendColorProc)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBlendFuncProc)(GLenum sfactor, GLenum dfactor); typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBufferDataProc)(GLenum target, GLsizei size, const void* data, GLenum usage); typedef GLvoid (GR_GL_FUNCTION_TYPE *GrGLBufferSubDataProc)(GLenum target, GLint offset, GLsizei size, const void* data); @@ -167,6 +168,7 @@ struct GrGLInterface { GrGLBindBufferProc fBindBuffer; GrGLBindTextureProc fBindTexture; GrGLBlendFuncProc fBlendFunc; + GrGLBlendColorProc fBlendColor; GrGLBufferDataProc fBufferData; GrGLBufferSubDataProc fBufferSubData; GrGLClearProc fClear; diff --git a/gpu/include/GrGLPlatformIncludes.h b/gpu/include/GrGLPlatformIncludes.h index 1a4fa40003..978a9926b5 100644 --- a/gpu/include/GrGLPlatformIncludes.h +++ b/gpu/include/GrGLPlatformIncludes.h @@ -335,6 +335,10 @@ #define GL_MULTISAMPLE_BIT 0x20000000 // OpenGL 1.4 Defines +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h index 666aa570f8..0a65ff75ce 100644 --- a/gpu/include/GrTexture.h +++ b/gpu/include/GrTexture.h @@ -89,6 +89,7 @@ public: }; static size_t BytesPerPixel(PixelConfig); static bool PixelConfigIsOpaque(PixelConfig); + static bool PixelConfigIsAlphaOnly(PixelConfig); protected: GrTexture(int width, diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h index 3c137f8891..8e219f7c08 100644 --- a/gpu/include/GrTypes.h +++ b/gpu/include/GrTypes.h @@ -186,6 +186,12 @@ enum GrBlendCoeff { kISA_BlendCoeff, //<! one minus src alpha kDA_BlendCoeff, //<! dst alpha kIDA_BlendCoeff, //<! one minus dst alpha + kConstC_BlendCoeff, //<! constant color + kIConstC_BlendCoeff, //<! one minus constant color + kConstA_BlendCoeff, //<! constant color alpha + kIConstA_BlendCoeff, //<! one minus constant color alpha + + kBlendCoeffCount }; /** diff --git a/gpu/src/GrGLInterface.cpp b/gpu/src/GrGLInterface.cpp index f296be7cb6..fa6aa92f11 100644 --- a/gpu/src/GrGLInterface.cpp +++ b/gpu/src/GrGLInterface.cpp @@ -281,6 +281,7 @@ void GrGLInitializeGLInterface(GrGLInterface* glBindings) { GR_GL_GET_PROC(BindAttribLocation); GR_GL_GET_PROC(BindBuffer); GR_GL_GET_PROC(BindTexture); + GR_GL_GET_PROC(BlendColor); GR_GL_GET_PROC(BufferData); GR_GL_GET_PROC(BufferSubData); GR_GL_GET_PROC(CompileShader); diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp index d41005b531..2d763e299a 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -56,6 +56,14 @@ bool GrTexture::PixelConfigIsOpaque(PixelConfig config) { } } +bool GrTexture::PixelConfigIsAlphaOnly(PixelConfig config) { + switch (config) { + case GrTexture::kAlpha_8_PixelConfig: + return true; + default: + return false; + } +} //////////////////////////////////////////////////////////////////////////////// diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp index 94e9bfd591..f2a2a8f3b0 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -45,8 +45,50 @@ static const GLenum gXfermodeCoeff2Blend[] = { GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, + GL_CONSTANT_COLOR, + GL_ONE_MINUS_CONSTANT_COLOR, + GL_CONSTANT_ALPHA, + GL_ONE_MINUS_CONSTANT_ALPHA, }; +bool GrGpuGL::BlendCoefReferencesConstant(GrBlendCoeff coeff) { + static const bool gCoeffReferencesBlendConst[] = { + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + }; + return gCoeffReferencesBlendConst[coeff]; + GR_STATIC_ASSERT(kBlendCoeffCount == GR_ARRAY_COUNT(gCoeffReferencesBlendConst)); +} + +GR_STATIC_ASSERT(0 == kZero_BlendCoeff); +GR_STATIC_ASSERT(1 == kOne_BlendCoeff); +GR_STATIC_ASSERT(2 == kSC_BlendCoeff); +GR_STATIC_ASSERT(3 == kISC_BlendCoeff); +GR_STATIC_ASSERT(4 == kDC_BlendCoeff); +GR_STATIC_ASSERT(5 == kIDC_BlendCoeff); +GR_STATIC_ASSERT(6 == kSA_BlendCoeff); +GR_STATIC_ASSERT(7 == kISA_BlendCoeff); +GR_STATIC_ASSERT(8 == kDA_BlendCoeff); +GR_STATIC_ASSERT(9 == kIDA_BlendCoeff); +GR_STATIC_ASSERT(10 == kConstC_BlendCoeff); +GR_STATIC_ASSERT(11 == kIConstC_BlendCoeff); +GR_STATIC_ASSERT(12 == kConstA_BlendCoeff); +GR_STATIC_ASSERT(13 == kIConstA_BlendCoeff); + +GR_STATIC_ASSERT(kBlendCoeffCount == GR_ARRAY_COUNT(gXfermodeCoeff2Blend)); + /////////////////////////////////////////////////////////////////////////////// void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture, @@ -458,6 +500,10 @@ void GrGpuGL::resetContext() { // illegal values fHWDrawState.fSrcBlend = (GrBlendCoeff)-1; fHWDrawState.fDstBlend = (GrBlendCoeff)-1; + + fHWDrawState.fBlendConstant = 0x00000000; + GR_GL(BlendColor(0,0,0,0)); + fHWDrawState.fColor = GrColor_ILLEGAL; fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); @@ -1615,6 +1661,19 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { fHWDrawState.fSrcBlend = fCurrDrawState.fSrcBlend; fHWDrawState.fDstBlend = fCurrDrawState.fDstBlend; } + if ((BlendCoefReferencesConstant(fCurrDrawState.fSrcBlend) || + BlendCoefReferencesConstant(fCurrDrawState.fDstBlend)) && + fHWDrawState.fBlendConstant != fCurrDrawState.fBlendConstant) { + + float c[] = { + GrColorUnpackR(fCurrDrawState.fBlendConstant) / 255.f, + GrColorUnpackG(fCurrDrawState.fBlendConstant) / 255.f, + GrColorUnpackB(fCurrDrawState.fBlendConstant) / 255.f, + GrColorUnpackA(fCurrDrawState.fBlendConstant) / 255.f + }; + GR_GL(BlendColor(c[0], c[1], c[2], c[3])); + fHWDrawState.fBlendConstant = fCurrDrawState.fBlendConstant; + } } if (fHWDrawState.fDrawFace != fCurrDrawState.fDrawFace) { diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index a731226cc3..ea0c081cd2 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -132,6 +132,8 @@ protected: static bool TextureMatrixIsIdentity(const GrGLTexture* texture, const GrSamplerState& sampler); + static bool BlendCoefReferencesConstant(GrBlendCoeff coeff); + private: // notify callbacks to update state tracking when related // objects are bound to GL or deleted outside of the class diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp index 695b22c156..afd9bb6c73 100644 --- a/gpu/src/GrGpuGLFixed.cpp +++ b/gpu/src/GrGpuGLFixed.cpp @@ -137,6 +137,14 @@ bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) { } } +#if GR_SUPPORT_GLES1 + if (BlendCoefReferencesConstant(fCurrDrawState.fSrcBlend) || + BlendCoefReferencesConstant(fCurrDrawState.fDstBlend)) { + uimpl("ES1 doesn't support blend constant"); + return false; + } +#endif + if (!flushGLStateCommon(type)) { return false; } diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp index 6819bde4c3..2230af2346 100644 --- a/gpu/src/GrTextContext.cpp +++ b/gpu/src/GrTextContext.cpp @@ -46,6 +46,25 @@ void GrTextContext::flushGlyphs() { int nIndices = fCurrVertex + (fCurrVertex >> 1); GrAssert(fCurrTexture); fDrawTarget->setTexture(TEXT_STAGE, fCurrTexture); + + if (!GrTexture::PixelConfigIsAlphaOnly(fCurrTexture->config())) { + if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff || + kISA_BlendCoeff != fPaint.fDstBlendCoeff || + NULL != fPaint.getTexture()) { + GrPrintf("LCD Text will not draw correctly.\n"); + } + // setup blend so that we get mask * paintColor + (1-mask)*dstColor + 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. + fDrawTarget->setColor(0xffffffff); + } else { + // set back to normal in case we took LCD path previously. + fDrawTarget->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff); + fDrawTarget->setColor(fPaint.fColor); + } + fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexed(kTriangles_PrimitiveType, |