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
This commit is contained in:
bsalomon@google.com 2011-03-15 19:09:25 +00:00
parent dc008e1710
commit 080773ca79
11 changed files with 129 additions and 0 deletions

View File

@ -136,6 +136,7 @@ protected:
uint32_t fFlagBits;
GrBlendCoeff fSrcBlend;
GrBlendCoeff fDstBlend;
GrColor fBlendConstant;
GrTexture* fTextures[kNumStages];
GrSamplerState fSamplerStates[kNumStages];
GrRenderTarget* fRenderTarget;
@ -358,6 +359,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
*/

View File

@ -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;

View File

@ -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

View File

@ -89,6 +89,7 @@ public:
};
static size_t BytesPerPixel(PixelConfig);
static bool PixelConfigIsOpaque(PixelConfig);
static bool PixelConfigIsAlphaOnly(PixelConfig);
protected:
GrTexture(int width,

View File

@ -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
};
/**

View File

@ -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);

View File

@ -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;
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -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) {

View File

@ -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

View File

@ -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;
}

View File

@ -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,