aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-15 19:09:25 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-15 19:09:25 +0000
commit080773ca79cbdc230730d295441255e9254d76a6 (patch)
tree549239db566093d9f0a7743f6e67471931142f4e
parentdc008e17104fc544d2b80c09c9835cf173c25b50 (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.h19
-rw-r--r--gpu/include/GrGLInterface.h2
-rw-r--r--gpu/include/GrGLPlatformIncludes.h4
-rw-r--r--gpu/include/GrTexture.h1
-rw-r--r--gpu/include/GrTypes.h6
-rw-r--r--gpu/src/GrGLInterface.cpp1
-rw-r--r--gpu/src/GrGpu.cpp8
-rw-r--r--gpu/src/GrGpuGL.cpp59
-rw-r--r--gpu/src/GrGpuGL.h2
-rw-r--r--gpu/src/GrGpuGLFixed.cpp8
-rw-r--r--gpu/src/GrTextContext.cpp19
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,