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