changeset 7529:8d90dbdf7ee3

Fix to RT-35173: Implement Alpha test functionality for the embedded platform Reviewed by flar, kcr
author Chien Yang <chien.yang@oracle.com>
date Tue, 15 Jul 2014 16:34:07 -0700
parents c7d3b6f6e2d0
children 92be7aaba96f
files modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java modules/graphics/src/main/jsl-prism/CompileJSL.java modules/graphics/src/main/native-prism-d3d/D3DContext.cc modules/graphics/src/main/native-prism-es2/GLContext.c
diffstat 4 files changed, 114 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java	Tue Jul 15 13:49:04 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java	Tue Jul 15 16:34:07 2014 -0700
@@ -121,12 +121,29 @@
         MaskType.values().length << 4;
     // TODO: need to dispose these when the context is disposed... (RT-27379)
     private final Shader[] stockShaders = new Shader[NUM_STOCK_SHADER_SLOTS];
-    private Shader textureRGBShader;
-    private Shader textureMaskRGBShader;
-    private Shader textureYV12Shader;
-    private Shader textureFirstLCDShader;
-    private Shader textureSecondLCDShader;
-    private Shader superShader;
+    // stockShaders with alpha test
+    private final Shader[] stockATShaders = new Shader[NUM_STOCK_SHADER_SLOTS];
+
+    public enum SpecialShaderType {
+        TEXTURE_RGB          ("Solid_TextureRGB"),
+        TEXTURE_MASK_RGB     ("Mask_TextureRGB"),
+        TEXTURE_YV12         ("Solid_TextureYV12"),
+        TEXTURE_First_LCD    ("Solid_TextureFirstPassLCD"),
+        TEXTURE_SECOND_LCD   ("Solid_TextureSecondPassLCD"),
+        SUPER                ("Mask_TextureSuper");
+         
+        private String name;
+        private SpecialShaderType(String name) {
+            this.name = name;
+        }
+        public String getName() {
+            return name;
+        }
+    }
+    private final Shader[] specialShaders = new Shader[SpecialShaderType.values().length];
+    // specialShaders with alpha test
+    private final Shader[] specialATShaders = new Shader[SpecialShaderType.values().length];
+    
     private Shader externalShader;
 
     private RTTexture lcdBuffer;
@@ -147,7 +164,7 @@
             externalShader = null;
         }
         // the rest of the shaders will be re-validated as they are used
-    }
+   }
 
     public static class State {
         private Shader lastShader;
@@ -203,9 +220,10 @@
         return (maskType.ordinal() << 4) | (paintType << 2) | (paintOption << 0);
     }
 
-    private Shader getPaintShader(MaskType maskType, Paint paint) {
+    private Shader getPaintShader(boolean alphaTest, MaskType maskType, Paint paint) {
         int index = getStockShaderIndex(maskType, paint);
-        Shader shader = stockShaders[index];
+        Shader shaders[] = alphaTest ? stockATShaders : stockShaders;
+        Shader shader = shaders[index];
         if (shader != null && !shader.isValid()) {
             shader.dispose();
             shader = null;
@@ -224,7 +242,10 @@
                     shaderName += "_REPEAT";
                 }
             }
-            shader = stockShaders[index] = factory.createStockShader(shaderName);
+            if (alphaTest) {
+                shaderName += "_AlphaTest";
+            }
+            shader = shaders[index] = factory.createStockShader(shaderName);
         }
         return shader;
     }
@@ -265,74 +286,29 @@
         }
     }
 
-    private Shader getTextureRGBShader() {
-        if (textureRGBShader != null && !textureRGBShader.isValid()) {
-            textureRGBShader.dispose();
-            textureRGBShader = null;
+    private Shader getSpecialShader(BaseGraphics g, SpecialShaderType sst) {
+        // We do alpha test if depth test is enabled
+        boolean alphaTest = g.isDepthTest() && g.isDepthBuffer();
+        Shader shaders[] = alphaTest ? specialATShaders : specialShaders;
+        Shader shader = shaders[sst.ordinal()];
+        if (shader != null && !shader.isValid()) {
+            shader.dispose();
+            shader = null;
         }
-        if (textureRGBShader == null) {
-            textureRGBShader = factory.createStockShader("Solid_TextureRGB");
+        if (shader == null) {
+            String shaderName = sst.getName();
+            if (alphaTest) {
+                shaderName += "_AlphaTest";
+            }
+            shaders[sst.ordinal()] = shader = factory.createStockShader(shaderName);
         }
-        return textureRGBShader;
+        return shader;
     }
 
-    private Shader getTextureMaskRGBShader() {
-        if (textureMaskRGBShader != null && !textureMaskRGBShader.isValid()) {
-            textureMaskRGBShader.dispose();
-            textureMaskRGBShader = null;
-        }
-        if (textureMaskRGBShader == null) {
-            textureMaskRGBShader = factory.createStockShader("Mask_TextureRGB");
-        }
-        return textureMaskRGBShader;
-    }
-
-    private Shader getTextureYV12Shader() {
-        if (textureYV12Shader != null && !textureYV12Shader.isValid()) {
-            textureYV12Shader.dispose();
-            textureYV12Shader = null;
-        }
-        if (textureYV12Shader == null) {
-            textureYV12Shader = factory.createStockShader("Solid_TextureYV12");
-        }
-        return textureYV12Shader;
-    }
-
-    private Shader getTextureFirstPassLCDShader() {
-        if (textureFirstLCDShader != null && !textureFirstLCDShader.isValid()) {
-            textureFirstLCDShader.dispose();
-            textureFirstLCDShader = null;
-        }
-        if (textureFirstLCDShader == null) {
-            textureFirstLCDShader = factory.createStockShader("Solid_TextureFirstPassLCD");
-        }
-        return textureFirstLCDShader;
-    }
-
-    private Shader getTextureSecondPassLCDShader() {
-        if (textureSecondLCDShader != null && !textureSecondLCDShader.isValid()) {
-            textureSecondLCDShader.dispose();
-            textureSecondLCDShader = null;
-        }
-        if (textureSecondLCDShader == null) {
-            textureSecondLCDShader = factory.createStockShader("Solid_TextureSecondPassLCD");
-        }
-        return textureSecondLCDShader;
-    }
-
-    private Shader getSuperShader() {
-        if (superShader != null && !superShader.isValid()) {
-            superShader.dispose();
-            superShader = null;
-        }
-        if (superShader == null) {
-            superShader = factory.createStockShader("Mask_TextureSuper");
-        }
-        return superShader;
-    }
-
+    @Override
     public boolean isSuperShaderEnabled() {
-        return state.lastShader == superShader;
+        return state.lastShader == specialATShaders[SpecialShaderType.SUPER.ordinal()]
+                || state.lastShader == specialShaders[SpecialShaderType.SUPER.ordinal()];
     }
 
     private void updatePerVertexColor(Paint paint, float extraAlpha) {
@@ -464,7 +440,7 @@
                 // Enabling the super shader to be used to render text.
                 // The texture pointed by tex0 is the region cache texture
                 // and it does not affect text rendering
-                shader = getSuperShader();
+                shader = getSpecialShader(g, SpecialShaderType.SUPER);
                 tex0 = factory.getRegionTexture();
                 tex1 = maskTex;
             } else {
@@ -484,7 +460,8 @@
                     tex0 = paintTex;
                     tex1 = null;
                 }
-                shader = getPaintShader(maskType, paint);
+                // We do alpha test if depth test is enabled
+                shader = getPaintShader(g.isDepthTest() && g.isDepthBuffer(), maskType, paint);
             }
             checkState(g, xform, shader, tex0, tex1);
             updatePaintShader(g, shader, maskType, paint, bx, by, bw, bh);
@@ -511,8 +488,8 @@
                                 Texture tex0, Texture tex1, boolean firstPass,
                                 Paint fillColor)
     {
-        Shader shader = firstPass ? getTextureFirstPassLCDShader() :
-                                    getTextureSecondPassLCDShader();
+        Shader shader = firstPass ? getSpecialShader(g, SpecialShaderType.TEXTURE_First_LCD) :
+                                    getSpecialShader(g, SpecialShaderType.TEXTURE_SECOND_LCD);
 
         checkState(g, xform, shader, tex0, tex1);
         updatePerVertexColor(fillColor, g.getExtraAlpha());
@@ -531,7 +508,7 @@
             }
 
             if (externalShader == null) {
-                shader = getTextureYV12Shader();
+                shader = getSpecialShader(g, SpecialShaderType.TEXTURE_YV12);
             } else {
                 shader = externalShader;
             }
@@ -565,10 +542,10 @@
                     // The shader was designed to render many Regions (from the Region
                     // texture cache) and text (from the glyph cache texture) without
                     // changing the state in the context.
-                    shader = getSuperShader();
+                    shader = getSpecialShader(g, SpecialShaderType.SUPER);
                     tex1 = factory.getGlyphTexture();
                 } else {
-                    shader = getTextureRGBShader();
+                    shader = getSpecialShader(g, SpecialShaderType.TEXTURE_RGB);
                 }
                 break;
             case MULTI_YCbCr_420: // Must use multitexture method
@@ -595,7 +572,7 @@
             case BYTE_RGB:
             case BYTE_GRAY:
             case BYTE_APPLE_422: // uses GL_RGBA as internal format
-                shader = getTextureMaskRGBShader();
+                shader = getSpecialShader(g, SpecialShaderType.TEXTURE_MASK_RGB);
                 break;
             case MULTI_YCbCr_420: // Must use multitexture method
             case BYTE_ALPHA:
--- a/modules/graphics/src/main/jsl-prism/CompileJSL.java	Tue Jul 15 13:49:04 2014 -0700
+++ b/modules/graphics/src/main/jsl-prism/CompileJSL.java	Tue Jul 15 16:34:07 2014 -0700
@@ -238,19 +238,20 @@
         return new ShaderInfo(paintName, paintSource, paintTime, inputParams);
     }
 
-    private static void compileColorPaint(JSLCInfo jslcinfo, ShaderInfo maskInfo)
+    private static void compileColorPaint(JSLCInfo jslcinfo, ShaderInfo maskInfo, boolean alphaTest)
         throws Exception
     {
         ShaderInfo colorInfo = getPaintInfo(jslcinfo, "Color");
         String outputName = maskInfo.getName() + "_Color";
-        ShaderInfo fullSource = getFullSource(outputName, maskInfo, colorInfo);
+        ShaderInfo fullSource = getFullSource(outputName, maskInfo, colorInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
     private static void compileGradientPaint(JSLCInfo jslcinfo,
                                              ShaderInfo maskInfo,
                                              PaintType paintType,
-                                             CycleType cycleType)
+                                             CycleType cycleType,
+                                             boolean alphaTest)
         throws Exception
     {
         String paintName = paintType.getName() + "Gradient";
@@ -266,62 +267,63 @@
             maskInfo.getName() + "_" +
             paintName + "_" +
             cycleType.toString();
-        ShaderInfo fullSource = getFullSource(outputName, maskInfo, gradInfo);
+        ShaderInfo fullSource = getFullSource(outputName, maskInfo, gradInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
     private static void compileAlphaGradientPaint(JSLCInfo jslcinfo,
                                                   ShaderInfo maskInfo,
-                                                  PaintType paintType)
+                                                  PaintType paintType,
+                                                  boolean alphaTest)
         throws Exception
     {
         String paintName = paintType.getName() + "Gradient";
         ShaderInfo paintInfo = getPaintInfo(jslcinfo, "AlphaTexture" + paintName, InputParam.TEXCOORD1);
         String outputName = maskInfo.getName() + "_" + paintName;
-        ShaderInfo fullSource = getFullSource(outputName, maskInfo, paintInfo);
+        ShaderInfo fullSource = getFullSource(outputName, maskInfo, paintInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
-    private static void compilePatternPaint(JSLCInfo jslcinfo, ShaderInfo maskInfo)
+    private static void compilePatternPaint(JSLCInfo jslcinfo, ShaderInfo maskInfo, boolean alphaTest)
         throws Exception
     {
         String paintName = "ImagePattern";
         ShaderInfo paintInfo = getPaintInfo(jslcinfo, paintName, InputParam.WINCOORD);
         String outputName = maskInfo.getName() + "_" + paintName;
-        ShaderInfo fullSource = getFullSource(outputName, maskInfo, paintInfo);
+        ShaderInfo fullSource = getFullSource(outputName, maskInfo, paintInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
-    private static void compileAlphaPatternPaint(JSLCInfo jslcinfo, ShaderInfo maskInfo)
+    private static void compileAlphaPatternPaint(JSLCInfo jslcinfo, ShaderInfo maskInfo, boolean alphaTest)
         throws Exception
     {
         String paintName = "ImagePattern";
         ShaderInfo paintInfo = getPaintInfo(jslcinfo, "AlphaTexture" + paintName, InputParam.TEXCOORD1);
         String outputName = maskInfo.getName() + "_" + paintName;
-        ShaderInfo fullSource = getFullSource(outputName, maskInfo, paintInfo);
+        ShaderInfo fullSource = getFullSource(outputName, maskInfo, paintInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
-    private static void compileSolidTexture(JSLCInfo jslcinfo, String suffix)
+    private static void compileSolidTexture(JSLCInfo jslcinfo, String suffix, boolean alphaTest)
         throws Exception
     {
         ShaderInfo maskInfo = getMaskInfo(jslcinfo, MaskType.SOLID);
         ShaderInfo paintInfo = getPaintInfo(jslcinfo, "Texture" + suffix, InputParam.TEXCOORD0);
-        ShaderInfo fullSource = getFullSource("Solid_Texture" + suffix, maskInfo, paintInfo);
+        ShaderInfo fullSource = getFullSource("Solid_Texture" + suffix, maskInfo, paintInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
-    private static void compileMaskTexture(JSLCInfo jslcinfo, String suffix)
+    private static void compileMaskTexture(JSLCInfo jslcinfo, String suffix, boolean alphaTest)
         throws Exception
     {
         ShaderInfo maskInfo = getMaskInfo(jslcinfo, MaskType.SOLID);
         ShaderInfo paintInfo = getPaintInfo(jslcinfo, "MaskTexture" + suffix,
                                             InputParam.TEXCOORD0, InputParam.TEXCOORD1);
-        ShaderInfo fullSource = getFullSource("Mask_Texture" + suffix, maskInfo, paintInfo);
+        ShaderInfo fullSource = getFullSource("Mask_Texture" + suffix, maskInfo, paintInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
-    private static void compileLCDShader(JSLCInfo jslcinfo, String suffix)
+    private static void compileLCDShader(JSLCInfo jslcinfo, String suffix, boolean alphaTest)
         throws Exception
     {
         ShaderInfo maskInfo = getMaskInfo(jslcinfo, MaskType.SOLID);
@@ -329,7 +331,7 @@
                                             InputParam.TEXCOORD0,
                                             InputParam.TEXCOORD1,
                                             InputParam.VERTEXCOLOR);
-        ShaderInfo fullSource = getFullSource("Solid_Texture" + suffix, maskInfo, paintInfo);
+        ShaderInfo fullSource = getFullSource("Solid_Texture" + suffix, maskInfo, paintInfo, alphaTest);
         compileShader(jslcinfo, fullSource);
     }
 
@@ -349,7 +351,8 @@
 
     private static ShaderInfo getFullSource(String outputName,
                                             ShaderInfo maskInfo,
-                                            ShaderInfo paintInfo)
+                                            ShaderInfo paintInfo,
+                                            boolean alphaTest)
         throws Exception
     {
         String maskSource;
@@ -389,8 +392,12 @@
             "%s\n%s\n" +
             "void main()\n" +
             "{\n" +
-            "    color = %s %s " + vertexColor + ";\n" +
-            "}\n";
+            "    color = %s %s " + vertexColor + ";\n";
+        if (alphaTest) {
+            mainTemplate += "    if (color.a == 0.0) discard;\n";
+            outputName += "_AlphaTest";
+        }
+        mainTemplate += "}\n";
         String fullSource =
             String.format(mainTemplate,
                           maskSource, paintSource,
@@ -463,35 +470,39 @@
         nameMap.put(JSLC.OUT_ES2, "prism-es2/build/gensrc/{pkg}/es2/glsl/{name}.frag");
         jslcinfo.parseAllArgs(args);
 
-        // create all the computational Mask+Paint combinations
-        for (MaskType maskType : MaskType.values()) {
-            ShaderInfo maskInfo = getMaskInfo(jslcinfo, maskType);
-            compileColorPaint(jslcinfo, maskInfo);
-            compilePatternPaint(jslcinfo, maskInfo);
-            for (PaintType paintType : PaintType.values()) {
-                for (CycleType cycleType : CycleType.values()) {
-                    compileGradientPaint(jslcinfo, maskInfo, paintType, cycleType);
+        boolean alphaTest = false;
+        for (int i = 0; i < 2; i++) {
+            alphaTest = (i == 0) ? false : true;
+            // create all the computational Mask+Paint combinations
+            for (MaskType maskType : MaskType.values()) {
+                ShaderInfo maskInfo = getMaskInfo(jslcinfo, maskType);
+                compileColorPaint(jslcinfo, maskInfo, alphaTest);
+                compilePatternPaint(jslcinfo, maskInfo, alphaTest);
+                for (PaintType paintType : PaintType.values()) {
+                    for (CycleType cycleType : CycleType.values()) {
+                        compileGradientPaint(jslcinfo, maskInfo, paintType, cycleType, alphaTest);
+                    }
                 }
             }
+
+            // create all the new style AlphaTexture+Paint combinations
+            for (AlphaMaskType maskType : AlphaMaskType.values()) {
+                ShaderInfo maskInfo = getMaskInfo(jslcinfo, maskType);
+                compileColorPaint(jslcinfo, maskInfo, alphaTest);
+                compileAlphaPatternPaint(jslcinfo, maskInfo, alphaTest);
+                for (PaintType paintType : PaintType.values()) {
+                    compileAlphaGradientPaint(jslcinfo, maskInfo, paintType, alphaTest);
+                }
+            }
+
+            // create the basic Solid+Texture* shaders
+            compileSolidTexture(jslcinfo, "RGB", alphaTest);
+            compileMaskTexture(jslcinfo, "RGB", alphaTest);
+            compileMaskTexture(jslcinfo, "Super", alphaTest);
+            compileSolidTexture(jslcinfo, "YV12", alphaTest);
+            compileSolidTexture(jslcinfo, "FirstPassLCD", alphaTest);
+            compileLCDShader(jslcinfo, "SecondPassLCD", alphaTest);
         }
-
-        // create all the new style AlphaTexture+Paint combinations
-        for (AlphaMaskType maskType : AlphaMaskType.values()) {
-            ShaderInfo maskInfo = getMaskInfo(jslcinfo, maskType);
-            compileColorPaint(jslcinfo, maskInfo);
-            compileAlphaPatternPaint(jslcinfo, maskInfo);
-            for (PaintType paintType : PaintType.values()) {
-                compileAlphaGradientPaint(jslcinfo, maskInfo, paintType);
-            }
-        }
-
-        // create the basic Solid+Texture* shaders
-        compileSolidTexture(jslcinfo, "RGB");
-        compileMaskTexture(jslcinfo, "RGB");
-        compileMaskTexture(jslcinfo, "Super");
-        compileSolidTexture(jslcinfo, "YV12");
-        compileSolidTexture(jslcinfo, "FirstPassLCD");
-        compileLCDShader(jslcinfo, "SecondPassLCD");
     }
 }
 
--- a/modules/graphics/src/main/native-prism-d3d/D3DContext.cc	Tue Jul 15 13:49:04 2014 -0700
+++ b/modules/graphics/src/main/native-prism-d3d/D3DContext.cc	Tue Jul 15 16:34:07 2014 -0700
@@ -1055,14 +1055,9 @@
         pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
         pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE);
         pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
-
-        pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
-        pd3dDevice->SetRenderState(D3DRS_ALPHAREF, 0x0);
-        pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
     } else {
         pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
         pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE);
-        pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE);
     }
 
     return D3D_OK;
--- a/modules/graphics/src/main/native-prism-es2/GLContext.c	Tue Jul 15 13:49:04 2014 -0700
+++ b/modules/graphics/src/main/native-prism-es2/GLContext.c	Tue Jul 15 16:34:07 2014 -0700
@@ -132,9 +132,6 @@
     ctxInfo->state.depthWritesEnabled = JNI_FALSE;
     glDepthMask(ctxInfo->state.depthWritesEnabled);
     glDisable(GL_DEPTH_TEST);
-#ifndef IS_EGL
-    glDisable(GL_ALPHA_TEST);
-#endif
 
     if (ctxInfo->state.scissorEnabled) {
         ctxInfo->state.scissorEnabled = JNI_FALSE;
@@ -1241,19 +1238,10 @@
         glDepthFunc(GL_LEQUAL);
         glDepthMask(GL_TRUE);
         ctxInfo->state.depthWritesEnabled = JNI_TRUE;
-#ifndef IS_EGL /* RT-25058 */
-        glEnable(GL_ALPHA_TEST);
-#ifndef ANDROID_NDK
-        glAlphaFunc(GL_NOTEQUAL, 0.0);
-#endif
-#endif
     } else {
         glDisable(GL_DEPTH_TEST);
         glDepthMask(GL_FALSE);
         ctxInfo->state.depthWritesEnabled = JNI_FALSE;
-#ifndef IS_EGL
-        glDisable(GL_ALPHA_TEST);
-#endif
     }
 }