modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java

Print this page

        

@@ -69,10 +69,20 @@
  * backend will create a new State instance for each window, but the D3D
  * backend is free to create a single State instance that can be shared for
  * the entire Screen.
  */
 public abstract class BaseShaderContext extends BaseContext {
+    private static final int CHECK_SHADER    = (0x01     );
+    private static final int CHECK_TRANSFORM = (0x01 << 1);
+    private static final int CHECK_CLIP      = (0x01 << 2);
+    private static final int CHECK_COMPOSITE = (0x01 << 3);
+    private static final int CHECK_PAINT_OP_MASK =
+        (CHECK_SHADER | CHECK_TRANSFORM | CHECK_CLIP | CHECK_COMPOSITE);
+    private static final int CHECK_TEXTURE_OP_MASK =
+        (CHECK_SHADER | CHECK_TRANSFORM | CHECK_CLIP | CHECK_COMPOSITE);
+    private static final int CHECK_CLEAR_OP_MASK =
+        (CHECK_CLIP);
 
     public enum MaskType {
         SOLID          ("Solid"),
         TEXTURE        ("Texture"),
         ALPHA_ONE           ("AlphaOne", true),

@@ -318,10 +328,15 @@
             getVertexBuffer().setPerVertexColor(extraAlpha);
         }
     }
 
     @Override
+    public void validateClearOp(BaseGraphics g) {
+        checkState((BaseShaderGraphics) g, CHECK_CLEAR_OP_MASK, null, null);
+    }
+
+    @Override
     public void validatePaintOp(BaseGraphics g, BaseTransform xform,
                                 Texture maskTex,
                                 float bx, float by, float bw, float bh)
     {
         validatePaintOp((BaseShaderGraphics)g, xform,

@@ -404,12 +419,12 @@
         }
 
         if (externalShader == null) {
             Paint paint = g.getPaint();
             Texture paintTex = null;
-            Texture tex0 = null;
-            Texture tex1 = null;
+            Texture tex0;
+            Texture tex1;
             if (paint.getType().isGradient()) {
                 // we need to flush here in case the paint shader is staying
                 // the same but the paint parameters are changing; we do this
                 // unconditionally for now (in theory we could keep track
                 // of the last validated paint, and the shape bounds in the

@@ -430,11 +445,11 @@
                 flushVertexBuffer();
                 ImagePattern texPaint = (ImagePattern)paint;
                 ResourceFactory rf = g.getResourceFactory();
                 paintTex = rf.getCachedTexture(texPaint.getImage(), Texture.WrapMode.REPEAT);
             }
-            Shader shader = null;
+            Shader shader;
             if (factory.isSuperShaderAllowed() &&
                 paintTex == null &&
                 maskTex == factory.getGlyphTexture())
             {
                 // Enabling the super shader to be used to render text.

@@ -461,18 +476,22 @@
                     tex1 = null;
                 }
                 // We do alpha test if depth test is enabled
                 shader = getPaintShader(g.isDepthTest() && g.isDepthBuffer(), maskType, paint);
             }
-            checkState(g, xform, shader, tex0, tex1);
+            checkState(g, CHECK_PAINT_OP_MASK, xform, shader);
+            setTexture(0, tex0);
+            setTexture(1, tex1);
             updatePaintShader(g, shader, maskType, paint, bx, by, bw, bh);
             updatePerVertexColor(paint, g.getExtraAlpha());
             if (paintTex != null) paintTex.unlock();
             return shader;
         } else {
             // note that paint is assumed to be a simple Color in this case
-            checkState(g, xform, externalShader, maskTex, null);
+            checkState(g, CHECK_PAINT_OP_MASK, xform, externalShader);
+            setTexture(0, maskTex);
+            setTexture(1, null);  // Needed?
             updatePerVertexColor(null, g.getExtraAlpha());
             return externalShader;
         }
     }
 

@@ -489,19 +508,21 @@
                                 Paint fillColor)
     {
         Shader shader = firstPass ? getSpecialShader(g, SpecialShaderType.TEXTURE_First_LCD) :
                                     getSpecialShader(g, SpecialShaderType.TEXTURE_SECOND_LCD);
 
-        checkState(g, xform, shader, tex0, tex1);
+        checkState(g, CHECK_TEXTURE_OP_MASK, xform, shader);
+        setTexture(0, tex0);
+        setTexture(1, tex1);
         updatePerVertexColor(fillColor, g.getExtraAlpha());
         return shader;
     }
 
     Shader validateTextureOp(BaseShaderGraphics g, BaseTransform xform,
                              Texture[] textures, PixelFormat format)
     {
-        Shader shader = null;
+        Shader shader;
 
         if (format == PixelFormat.MULTI_YCbCr_420) {
             // must have at least three textures, any more than four are ignored
             if (textures.length < 3) {
                 return null;

@@ -515,11 +536,16 @@
         } else { // add more multitexture shaders here
             return null;
         }
 
         if (null != shader) {
-            checkState(g, xform, shader, textures);
+            checkState(g, CHECK_TEXTURE_OP_MASK, xform, shader);
+            // clamp to 0..4 textures for now, expand on this later if we need to
+            int texCount = Math.max(0, Math.min(textures.length, 4));
+            for (int index = 0; index < texCount; index++) {
+                setTexture(index, textures[index]);
+            }
             updatePerVertexColor(null, g.getExtraAlpha());
         }
         return shader;
     }
 

@@ -554,11 +580,13 @@
                 throw new InternalError("Pixel format not supported: " + format);
             }
         } else {
             shader = externalShader;
         }
-        checkState(g, xform, shader, tex0, tex1);
+        checkState(g, CHECK_TEXTURE_OP_MASK, xform, shader);
+        setTexture(0, tex0);
+        setTexture(1, tex1);
         updatePerVertexColor(null, g.getExtraAlpha());
         return shader;
     }
 
     Shader validateMaskTextureOp(BaseShaderGraphics g, BaseTransform xform,

@@ -580,11 +608,13 @@
                 throw new InternalError("Pixel format not supported: " + format);
             }
         } else {
             shader = externalShader;
         }
-        checkState(g, xform, shader, tex0, tex1);
+        checkState(g, CHECK_TEXTURE_OP_MASK, xform, shader);
+        setTexture(0, tex0);
+        setTexture(1, tex1);
         updatePerVertexColor(null, g.getExtraAlpha());
         return shader;
     }
 
     void setExternalShader(BaseShaderGraphics g, Shader shader) {

@@ -607,95 +637,56 @@
         }
         externalShader = shader;
     }
 
     private void checkState(BaseShaderGraphics g,
+                            int checkFlags,
                             BaseTransform xform,
-                            Shader shader,
-                            Texture tex0, Texture tex1)
+                            Shader shader)
     {
         setRenderTarget(g);
 
-        setTexture(0, tex0);
-        setTexture(1, tex1);
-
+        if ((checkFlags & CHECK_SHADER) != 0) {
         if (shader != state.lastShader) {
             flushVertexBuffer();
             shader.enable();
             state.lastShader = shader;
             // the transform matrix is part of the state of each shader
             // (in ES2 at least), so we need to make sure the transform
             // is updated for the current shader by setting isXformValid=false
             state.isXformValid = false;
+                checkFlags |= CHECK_TRANSFORM;
         }
-
-        if (!state.isXformValid || !xform.equals(state.lastTransform)) {
-            flushVertexBuffer();
-            updateShaderTransform(shader, xform);
-            state.lastTransform.setTransform(xform);
-            state.isXformValid = true;
-        }
-
-        Rectangle clip = g.getClipRectNoClone();
-        if (clip != state.lastClip) {
-            flushVertexBuffer();
-            updateClipRect(clip);
-            state.lastClip = clip;
-        }
-
-        CompositeMode mode = g.getCompositeMode();
-        if (mode != state.lastComp) {
-            flushVertexBuffer();
-            updateCompositeMode(mode);
-            state.lastComp = mode;
-        }
-    }
-
-    private void checkState(BaseShaderGraphics g,
-                            BaseTransform xform,
-                            Shader shader,
-                            Texture[] textures)
-    {
-        setRenderTarget(g);
-
-        // clamp to 0..4 textures for now, expand on this later if we need to
-        int texCount = Math.max(0, Math.min(textures.length, 4));
-        for (int index = 0; index < texCount; index++) {
-            setTexture(index, textures[index]);
-        }
-
-        if (shader != state.lastShader) {
-            flushVertexBuffer();
-            shader.enable();
-            state.lastShader = shader;
-            // the transform matrix is part of the state of each shader
-            // (in ES2 at least), so we need to make sure the transform
-            // is updated for the current shader by setting isXformValid=false
-            state.isXformValid = false;
         }
 
+        if ((checkFlags & CHECK_TRANSFORM) != 0) {
         if (!state.isXformValid || !xform.equals(state.lastTransform)) {
             flushVertexBuffer();
             updateShaderTransform(shader, xform);
             state.lastTransform.setTransform(xform);
             state.isXformValid = true;
         }
+        }
 
+        if ((checkFlags & CHECK_CLIP) != 0) {
         Rectangle clip = g.getClipRectNoClone();
         if (clip != state.lastClip) {
             flushVertexBuffer();
             updateClipRect(clip);
             state.lastClip = clip;
         }
+        }
 
+        if ((checkFlags & CHECK_COMPOSITE) != 0) {
         CompositeMode mode = g.getCompositeMode();
         if (mode != state.lastComp) {
             flushVertexBuffer();
             updateCompositeMode(mode);
             state.lastComp = mode;
         }
     }
+    }
 
     private void setTexture(int texUnit, Texture tex) {
         if (tex != null) tex.assertLocked();
         if (tex != state.lastTextures[texUnit]) {
             flushVertexBuffer();

@@ -719,10 +710,11 @@
             lcdBuffer.dispose();
             lcdBuffer = null;
         }
     }
 
+    @Override
     public RTTexture getLCDBuffer() {
         return lcdBuffer;
     }
 
     //Current RenderTarget is undefined after this method.