< prev index next >
src/java.desktop/share/native/common/java2d/opengl/OGLTextRenderer.c
Print this page
@@ -270,11 +270,11 @@
* text. Do not be frightened; it is much easier to understand than the
* equivalent ASM-like fragment program!
*
* The "uniform" variables at the top are initialized once the program is
* linked, and are updated at runtime as needed (e.g. when the source color
- * changes, we will modify the "src_adj" value in OGLTR_UpdateLCDTextColor()).
+ * changes, we will modify the "src_clr" value in OGLTR_UpdateLCDTextColor()).
*
* The "main" function is executed for each "fragment" (or pixel) in the
* glyph image. We have determined that the pow() function can be quite
* slow and it only operates on scalar values, not vectors as we require.
* So instead we build two 3D textures containing gamma (and inverse gamma)
@@ -294,11 +294,11 @@
* And here is the theoretical equation approximated by this shader:
*
* Cr = (Ag*(Cs^Ga) + (1-Ag)*(Cd^Ga)) ^ (1/Ga)
*/
static const char *lcdTextShaderSource =
- "uniform vec3 src_adj;"
+ "uniform vec4 src_clr;"
"uniform sampler2D glyph_tex;"
"uniform sampler2D dst_tex;"
"uniform sampler3D invgamma_tex;"
"uniform sampler3D gamma_tex;"
""
@@ -308,18 +308,24 @@
" vec3 glyph_clr = vec3(texture2D(glyph_tex, gl_TexCoord[0].st));"
" if (glyph_clr == vec3(0.0)) {"
// zero coverage, so skip this fragment
" discard;"
" }"
- // load the RGB value from the corresponding destination pixel
- " vec3 dst_clr = vec3(texture2D(dst_tex, gl_TexCoord[1].st));"
+ // load the RGBA value from the corresponding destination pixel
+ " vec4 dst_clr = vec4(texture2D(dst_tex, gl_TexCoord[1].st));"
+ // blend src and dst colors as SrcOverNoEa
+ " vec3 src_comp = vec3(src_clr.rgb + ((1.0 - src_clr.a) * dst_clr.rgb));"
+ // gamma adjust the blended src color using the invgamma LUT
+ " vec3 src_adj = vec3(texture3D(invgamma_tex, src_comp));"
// gamma adjust the dest color using the invgamma LUT
- " vec3 dst_adj = vec3(texture3D(invgamma_tex, dst_clr.stp));"
+ " vec3 dst_adj = vec3(texture3D(invgamma_tex, dst_clr.rgb));"
// linearly interpolate the three color values
" vec3 result = mix(dst_adj, src_adj, glyph_clr);"
- // gamma re-adjust the resulting color (alpha is always set to 1.0)
- " gl_FragColor = vec4(vec3(texture3D(gamma_tex, result.stp)), 1.0);"
+ // calculate the resulting alpha
+ " dst_clr.a = src_clr.a + (1.0 - src_clr.a) * dst_clr.a;"
+ // gamma re-adjust the resulting color
+ " gl_FragColor = vec4(vec3(texture3D(gamma_tex, result.rgb)), dst_clr.a);"
"}";
/**
* Compiles and links the LCD text shader program. If successful, this
* function returns a handle to the newly created shader program; otherwise
@@ -465,49 +471,28 @@
return JNI_TRUE;
}
/**
- * Updates the current gamma-adjusted source color ("src_adj") of the LCD
- * text shader program. Note that we could calculate this value in the
- * shader (e.g. just as we do for "dst_adj"), but would be unnecessary work
- * (and a measurable performance hit, maybe around 5%) since this value is
- * constant over the entire glyph list. So instead we just calculate the
- * gamma-adjusted value once and update the uniform parameter of the LCD
- * shader as needed.
+ * Updates the current source color ("src_clr") of the LCD text shader program.
*/
static jboolean
OGLTR_UpdateLCDTextColor(jint contrast)
{
- double gamma = ((double)contrast) / 100.0;
- GLfloat radj, gadj, badj;
+ double gamma = 100.0 / ((double)contrast);
GLfloat clr[4];
GLint loc;
J2dTraceLn1(J2D_TRACE_INFO,
"OGLTR_UpdateLCDTextColor: contrast=%d", contrast);
- /*
- * Note: Ideally we would update the "src_adj" uniform parameter only
- * when there is a change in the source color. Fortunately, the cost
- * of querying the current OpenGL color state and updating the uniform
- * value is quite small, and in the common case we only need to do this
- * once per GlyphList, so we gain little from trying to optimize too
- * eagerly here.
- */
-
// get the current OpenGL primary color state
j2d_glGetFloatv(GL_CURRENT_COLOR, clr);
- // gamma adjust the primary color
- radj = (GLfloat)pow(clr[0], gamma);
- gadj = (GLfloat)pow(clr[1], gamma);
- badj = (GLfloat)pow(clr[2], gamma);
-
- // update the "src_adj" parameter of the shader program with this value
- loc = j2d_glGetUniformLocationARB(lcdTextProgram, "src_adj");
- j2d_glUniform3fARB(loc, radj, gadj, badj);
+ // update the "src_clr" parameter of the shader program with this value
+ loc = j2d_glGetUniformLocationARB(lcdTextProgram, "src_clr");
+ j2d_glUniform4fARB(loc, clr[0], clr[1], clr[2], clr[3]);
return JNI_TRUE;
}
/**
< prev index next >