changeset 3543:e23ed8f2acc1 8.0-b89

RT-30106: Multiple errors of creating the framebuffer of some controls, detected at h1080 of 8.0-graphics-scrum on BeagleBoard Committed-by: kcr (on behalf of flar)
author flar <James.Graham@oracle.com>
date Wed, 08 May 2013 11:05:56 -0700
parents 8eb535447b5a
children 675c74a2806a 35919ba76bce
files decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSDrawable.java decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java decora-prism-sw/src/com/sun/scenario/effect/impl/prism/sw/PSWDrawable.java decora-prism-sw/src/com/sun/scenario/effect/impl/prism/sw/PSWRenderer.java decora-runtime/src/com/sun/scenario/effect/impl/ImagePool.java decora-runtime/src/com/sun/scenario/effect/impl/Renderer.java javafx-sg-prism/test/com/sun/javafx/sg/prism/TestGraphics.java prism-common/src/com/sun/prism/ResourceFactory.java prism-d3d/src/com/sun/prism/d3d/D3DResourceFactory.java prism-es2/src/com/sun/prism/es2/ES2RTTexture.java prism-es2/src/com/sun/prism/es2/ES2ResourceFactory.java prism-j2d/src/com/sun/prism/j2d/J2DResourceFactory.java prism-null/src/com/sun/prism/null3d/DummyResourceFactory.java prism-sw/src/com/sun/prism/sw/SWResourceFactory.java
diffstat 14 files changed, 176 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSDrawable.java	Wed May 08 11:12:51 2013 -0400
+++ b/decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSDrawable.java	Wed May 08 11:05:56 2013 -0700
@@ -46,6 +46,18 @@
         return new PPSDrawable(rtt);
     }
 
+    static int getCompatibleWidth(Screen screen, int w) {
+        ResourceFactory factory =
+            GraphicsPipeline.getPipeline().getResourceFactory(screen);
+        return factory.getRTTWidth(w, WrapMode.CLAMP_TO_ZERO);
+    }
+
+    static int getCompatibleHeight(Screen screen, int h) {
+        ResourceFactory factory =
+            GraphicsPipeline.getPipeline().getResourceFactory(screen);
+        return factory.getRTTHeight(h, WrapMode.CLAMP_TO_ZERO);
+    }
+
     static PPSDrawable create(Screen screen, int width, int height) {
         ResourceFactory factory =
             GraphicsPipeline.getPipeline().getResourceFactory(screen);
--- a/decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java	Wed May 08 11:12:51 2013 -0400
+++ b/decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java	Wed May 08 11:05:56 2013 -0700
@@ -150,6 +150,16 @@
     }
 
     @Override
+    public int getCompatibleWidth(int w) {
+        return PPSDrawable.getCompatibleWidth(screen, w);
+    }
+
+    @Override
+    public int getCompatibleHeight(int h) {
+        return PPSDrawable.getCompatibleHeight(screen, h);
+    }
+
+    @Override
     public final PPSDrawable createCompatibleImage(int w, int h) {
         return PPSDrawable.create(screen, w, h);
     }
--- a/decora-prism-sw/src/com/sun/scenario/effect/impl/prism/sw/PSWDrawable.java	Wed May 08 11:12:51 2013 -0400
+++ b/decora-prism-sw/src/com/sun/scenario/effect/impl/prism/sw/PSWDrawable.java	Wed May 08 11:05:56 2013 -0700
@@ -56,6 +56,18 @@
         return new PSWDrawable(rtt, true);
     }
 
+    static int getCompatibleWidth(Screen screen, int w) {
+        ResourceFactory factory =
+            GraphicsPipeline.getPipeline().getResourceFactory(screen);
+        return factory.getRTTWidth(w, WrapMode.CLAMP_TO_ZERO);
+    }
+
+    static int getCompatibleHeight(Screen screen, int h) {
+        ResourceFactory factory =
+            GraphicsPipeline.getPipeline().getResourceFactory(screen);
+        return factory.getRTTHeight(h, WrapMode.CLAMP_TO_ZERO);
+    }
+
     static PSWDrawable create(Screen screen, int width, int height) {
         ResourceFactory factory =
             GraphicsPipeline.getPipeline().getResourceFactory(screen);
--- a/decora-prism-sw/src/com/sun/scenario/effect/impl/prism/sw/PSWRenderer.java	Wed May 08 11:12:51 2013 -0400
+++ b/decora-prism-sw/src/com/sun/scenario/effect/impl/prism/sw/PSWRenderer.java	Wed May 08 11:05:56 2013 -0700
@@ -192,6 +192,24 @@
     }
 
     @Override
+    public int getCompatibleWidth(int w) {
+        if (screen != null) {
+            return PSWDrawable.getCompatibleWidth(screen, w);
+        } else {
+            return resourceFactory.getRTTWidth(w, WrapMode.CLAMP_TO_EDGE);
+        }
+    }
+
+    @Override
+    public int getCompatibleHeight(int h) {
+        if (screen != null) {
+            return PSWDrawable.getCompatibleHeight(screen, h);
+        } else {
+            return resourceFactory.getRTTHeight(h, WrapMode.CLAMP_TO_EDGE);
+        }
+    }
+
+    @Override
     public final PSWDrawable createCompatibleImage(int w, int h) {
         if (screen != null) {
             return PSWDrawable.create(screen, w, h);
--- a/decora-runtime/src/com/sun/scenario/effect/impl/ImagePool.java	Wed May 08 11:12:51 2013 -0400
+++ b/decora-runtime/src/com/sun/scenario/effect/impl/ImagePool.java	Wed May 08 11:05:56 2013 -0700
@@ -116,6 +116,11 @@
         // Allocate images rounded up to the nearest quantum size threshold.
         w = ((w + QUANT - 1) / QUANT) * QUANT;
         h = ((h + QUANT - 1) / QUANT) * QUANT;
+
+        // Adjust allocation sizes for platform requirements (pow2 etc.)
+        w = renderer.getCompatibleWidth(w);
+        h = renderer.getCompatibleHeight(h);
+
         numAccessed++;
         pixelsAccessed += ((long) w) * h;
         // first look for an already cached image of sufficient size,
--- a/decora-runtime/src/com/sun/scenario/effect/impl/Renderer.java	Wed May 08 11:12:51 2013 -0400
+++ b/decora-runtime/src/com/sun/scenario/effect/impl/Renderer.java	Wed May 08 11:05:56 2013 -0700
@@ -114,6 +114,8 @@
      */
     public abstract AccelType getAccelType();
 
+    public abstract int getCompatibleWidth(int w);
+    public abstract int getCompatibleHeight(int h);
     public abstract Filterable createCompatibleImage(int w, int h);
 
     public Filterable getCompatibleImage(int w, int h) {
--- a/javafx-sg-prism/test/com/sun/javafx/sg/prism/TestGraphics.java	Wed May 08 11:12:51 2013 -0400
+++ b/javafx-sg-prism/test/com/sun/javafx/sg/prism/TestGraphics.java	Wed May 08 11:05:56 2013 -0700
@@ -174,6 +174,8 @@
         @Override public int getMaximumTextureSize() { return 0; }
         @Override public Texture createMaskTexture(int width, int height, Texture.WrapMode wrapMode) { return null; }
         @Override public Texture createFloatTexture(int width, int height) { return null; }
+        @Override public int getRTTWidth(int w, WrapMode wrapMode) { return w; }
+        @Override public int getRTTHeight(int h, WrapMode wrapMode) { return h; }
         @Override public RTTexture createRTTexture(final int width, final int height, Texture.WrapMode wrapMode) {
             return new RTTexture() {
                 @Override public int[] getPixels() { return new int[0]; }
--- a/prism-common/src/com/sun/prism/ResourceFactory.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-common/src/com/sun/prism/ResourceFactory.java	Wed May 08 11:05:56 2013 -0700
@@ -149,6 +149,9 @@
      */
     public int getMaximumTextureSize();
 
+    public int getRTTWidth(int w, Texture.WrapMode wrapMode);
+    public int getRTTHeight(int h, Texture.WrapMode wrapMode);
+
     public Texture createMaskTexture(int width, int height, Texture.WrapMode wrapMode);
     public Texture createFloatTexture(int width, int height);
     public RTTexture createRTTexture(int width, int height, Texture.WrapMode wrapMode);
--- a/prism-d3d/src/com/sun/prism/d3d/D3DResourceFactory.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-d3d/src/com/sun/prism/d3d/D3DResourceFactory.java	Wed May 08 11:05:56 2013 -0700
@@ -228,6 +228,30 @@
         }
     }
 
+    public int getRTTWidth(int w, WrapMode wrapMode) {
+        // D3DRTTexture returns the requested dimension as the content dimension
+        // so the answer here is just "w" despite the fact that a pow2 adjustment
+        // is made for the actual allocation.  Typically, D3D supports non-pow2
+        // textures on every implementation so the pow2 code below is not really
+        // encountered in practice anyway (it's only supported for "debugging").
+//        if (PrismSettings.forcePow2) {
+//            w = nextPowerOfTwo(w, Integer.MAX_VALUE);
+//        }
+        return w;
+    }
+
+    public int getRTTHeight(int h, WrapMode wrapMode) {
+        // D3DRTTexture returns the requested dimension as the content dimension
+        // so the answer here is just "h" despite the fact that a pow2 adjustment
+        // is made for the actual allocation.  Typically, D3D supports non-pow2
+        // textures on every implementation so the pow2 code below is not really
+        // encountered in practice anyway (it's only supported for "debugging").
+//        if (PrismSettings.forcePow2) {
+//            h = nextPowerOfTwo(h, Integer.MAX_VALUE);
+//        }
+        return h;
+    }
+
     @Override
     public D3DRTTexture createRTTexture(int width, int height, WrapMode wrapMode) {
         if (PrismSettings.verbose && context.isLost()) {
--- a/prism-es2/src/com/sun/prism/es2/ES2RTTexture.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-es2/src/com/sun/prism/es2/ES2RTTexture.java	Wed May 08 11:05:56 2013 -0700
@@ -74,6 +74,61 @@
         texData.setDepthBufferID(dbID);
     }
 
+    static int getCompatibleDimension(ES2Context context, int dim, WrapMode wrapMode) {
+        GLContext glContext = context.getGLContext();
+        boolean pad;
+        switch (wrapMode) {
+            case CLAMP_NOT_NEEDED:
+                pad = false;
+                break;
+            case CLAMP_TO_ZERO:
+                pad = !glContext.canClampToZero();
+                break;
+            default:
+            case CLAMP_TO_EDGE:
+            case REPEAT:
+                throw new IllegalArgumentException("wrap mode not supported for RT textures: "+wrapMode);
+            case CLAMP_TO_EDGE_SIMULATED:
+            case CLAMP_TO_ZERO_SIMULATED:
+            case REPEAT_SIMULATED:
+                throw new IllegalArgumentException("Cannot request simulated wrap mode: "+wrapMode);
+        }
+
+        int paddedDim = pad ? dim + 2 : dim;
+
+        int maxSize = glContext.getMaxTextureSize();
+        int texDim;
+        if (glContext.canCreateNonPowTwoTextures()) {
+            texDim = (paddedDim <= maxSize) ? paddedDim : 0;
+        } else {
+            texDim = nextPowerOfTwo(paddedDim, maxSize);
+        }
+
+        if (texDim == 0) {
+            throw new RuntimeException(
+                    "Requested texture dimension (" + dim + ") "
+                    + "requires dimension (" + texDim + ") "
+                    + "that exceeds maximum texture size (" + maxSize + ")");
+        }
+
+        // make sure the texture is not smaller than minimum size
+        texDim = Math.max(texDim, PrismSettings.minRTTSize);
+
+        // Note that ES2Context will set the viewport to the content
+        // region of a RenderTarget (to ensure that we don't render into
+        // the padded area of transparent pixels, if present).  Since
+        // RTTextures are frequently recycled (i.e., reused by Decora) it
+        // is imperative that we initialize the content region of the
+        // RTTexture to be the physical size of the FBO modulo the padded
+        // region.  (Suppose the caller asks for a 110x220 RTTexture, but
+        // nonpow2 textures aren't supported; in this case, we will actually
+        // create a 128x256 FBO.  If later that RTTexture gets reused for
+        // a caller expecting to use 126x240 pixels, the viewport will be
+        // setup correctly because it will set to the content region, or
+        // 128x256 in this case, assuming no padding.)
+        return pad ? texDim - 2 : texDim;
+    }
+
     static ES2RTTexture create(ES2Context context, int w, int h, WrapMode wrapMode) {
         // Normally we would use GL_CLAMP_TO_BORDER with a transparent border
         // color to implement our CLAMP_TO_ZERO edge mode, but unfortunately
--- a/prism-es2/src/com/sun/prism/es2/ES2ResourceFactory.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-es2/src/com/sun/prism/es2/ES2ResourceFactory.java	Wed May 08 11:05:56 2013 -0700
@@ -93,6 +93,14 @@
         return ES2Texture.create(context, frame);
     }
 
+    public int getRTTWidth(int w, WrapMode wrapMode) {
+        return ES2RTTexture.getCompatibleDimension(context, w, wrapMode);
+    }
+
+    public int getRTTHeight(int h, WrapMode wrapMode) {
+        return ES2RTTexture.getCompatibleDimension(context, h, wrapMode);
+    }
+
     public RTTexture createRTTexture(int width, int height, WrapMode wrapMode) {
         return ES2RTTexture.create(context, width, height, wrapMode);
     }
--- a/prism-j2d/src/com/sun/prism/j2d/J2DResourceFactory.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-j2d/src/com/sun/prism/j2d/J2DResourceFactory.java	Wed May 08 11:05:56 2013 -0700
@@ -84,6 +84,14 @@
         return J2DPresentable.create(pState, this);
     }
 
+    public int getRTTWidth(int w, WrapMode wrapMode) {
+        return w;
+    }
+
+    public int getRTTHeight(int h, WrapMode wrapMode) {
+        return h;
+    }
+
     public RTTexture createRTTexture(int width, int height, WrapMode wrapMode) {
         J2DTexturePool pool = J2DTexturePool.instance;
         long size = pool.estimateRTTextureSize(width, height, false);
--- a/prism-null/src/com/sun/prism/null3d/DummyResourceFactory.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-null/src/com/sun/prism/null3d/DummyResourceFactory.java	Wed May 08 11:05:56 2013 -0700
@@ -71,6 +71,14 @@
         return new DummyTexture(context, format, wrapMode, w, h);
     }
 
+    public int getRTTWidth(int w, WrapMode wrapMode) {
+        return w;
+    }
+
+    public int getRTTHeight(int h, WrapMode wrapMode) {
+        return h;
+    }
+
     @Override
     public RTTexture createRTTexture(int width, int height, WrapMode wrapMode) {
         return new DummyRTTexture(context, wrapMode, width, height);
--- a/prism-sw/src/com/sun/prism/sw/SWResourceFactory.java	Wed May 08 11:12:51 2013 -0400
+++ b/prism-sw/src/com/sun/prism/sw/SWResourceFactory.java	Wed May 08 11:05:56 2013 -0700
@@ -109,7 +109,15 @@
         }
         return new SWPresentable(pstate, this);
     }
-            
+
+    public int getRTTWidth(int w, WrapMode wrapMode) {
+        return w;
+    }
+
+    public int getRTTHeight(int h, WrapMode wrapMode) {
+        return h;
+    }
+
     @Override public RTTexture createRTTexture(int width, int height,
                                                WrapMode wrapMode)
     {