--- old/modules/graphics/src/main/java/com/sun/scenario/effect/impl/state/LinearConvolveKernel.java 2014-02-21 17:02:05.000000000 -0800 +++ new/modules/graphics/src/main/java/com/sun/scenario/effect/impl/state/LinearConvolveKernel.java 2014-02-21 17:02:05.000000000 -0800 @@ -25,15 +25,8 @@ package com.sun.scenario.effect.impl.state; -import java.nio.FloatBuffer; import com.sun.javafx.geom.Rectangle; import com.sun.javafx.geom.transform.BaseTransform; -import com.sun.scenario.effect.Color4f; -import com.sun.scenario.effect.Effect; -import com.sun.scenario.effect.FilterContext; -import com.sun.scenario.effect.ImageData; -import com.sun.scenario.effect.impl.EffectPeer; -import com.sun.scenario.effect.impl.Renderer; /** * The helper class for defining a 1 dimensional linear convolution kernel @@ -42,68 +35,6 @@ * convolutions. */ public abstract class LinearConvolveKernel { - public static final int MAX_KERNEL_SIZE = 128; - - public enum PassType { - /** - * The kernel on this pass will be applied horizontally with - * the kernel centered symmetrically around each pixel. - * The specific conditions indicated by this type are: - * - */ - HORIZONTAL_CENTERED, - - /** - * The kernel on this pass will be applied vertically with - * the kernel centered symmetrically around each pixel. - * The specific conditions indicated by this type are: - * - */ - VERTICAL_CENTERED, - - /** - * The kernel on this pass can be applied in any direction or with - * any kind of offset. - * No assumptions are made about the offset and delta of the kernel - * vector. - */ - GENERAL_VECTOR, - }; - - /** - * Returns the peer sample count for a given kernel size. There are - * only a few peers defined to operate on specific sizes of convolution - * kernel. If there are peers defined only for kernel sizes of 8 and 16 - * and a given effect has a linear convolution kernel with 5 weights, - * then the peer for size 8 will be used and the buffer of weights must - * be padded out to the appropriate size with 0s so that the shader - * constant pool will be fully initialized and the extra unneeded - * convolution samples will be ignored by the 0 weights. - * - * @param ksize the number of computed convolution kernel weights - * @return the number of convolution weights which will be applied by - * the associated peer. - */ - public static int getPeerSize(int ksize) { - if (ksize < 32) return ((ksize + 3) & (~3)); - if (ksize <= MAX_KERNEL_SIZE) return ((ksize + 31) & (~31)); - throw new RuntimeException("No peer available for kernel size: "+ksize); - } - /** * Returns true if this is a LinearConvolveShadow operation, or false * if the operation is a regular LinearConvolve. @@ -115,16 +46,6 @@ } /** - * Returns the number of linear convolution passes the algorithm must make - * to complete its work. Most subclasses will use only 1 or 2 passes - * (typically broken down into a horizontal pass and a vertical pass as - * necessary). - * - * @return the number of passes to be made - */ - public abstract int getNumberOfPasses(); - - /** * Returns true if the entire operation of this linear convolution * would have no effect on the source data. * @@ -135,30 +56,6 @@ } /** - * Returns true if the operation of a particular pass of this linear - * convolution would have no effect on the source data. - * - * @param pass the algorithm pass being performed - * @return true if the given pass is a NOP - */ - public boolean isNop(int pass) { - return false; - } - - /** - * Returns the {@link PassType} that indicates the assumptions that - * can be made in optimizing the application of the kernel on this - * pass. - * - * @param pass the algorithm pass being performed - * @return the {@link PassType} that describes the kernel vector for - * this pass - */ - public PassType getPassType(int pass) { - return PassType.GENERAL_VECTOR; - } - - /** * Returns the size of the output image needed for a given input * image dimensions and a given pass of the algorithm. * @@ -169,51 +66,6 @@ public abstract Rectangle getResultBounds(Rectangle srcdimension, int pass); /** - * Returns the size of the scaled result image needed to hold the output - * for a given input image dimensions and a given pass of the algorithm. - * The image may be further scaled after the shader operation is through - * to obtain the final result bounds. - * This value is only of use to the actual shader to understand exactly - * how much room to allocate for the shader result. - * - * @param srcdimension the bounds of the input image - * @param pass the algorithm pass being performed - * @return the bounds of the result image - */ - public Rectangle getScaledResultBounds(Rectangle srcdimension, int pass) { - return getResultBounds(srcdimension, pass); - } - - /** - * Returns an array of 4 floats used to initialize a float4 Shader - * constant with the relative starting location of the first weight - * in the convolution kernel and the incremental offset between each - * sample to be weighted and convolved. The values are stored in - * the array in the following order: - *
-     *     shadervec.x = vector[0] = incdx // X offset between subsequent samples
-     *     shadervec.y = vector[1] = incdy // Y offset between subsequent samples
-     *     shadervec.z = vector[2] = startdx // X offset to first convolution sample
-     *     shadervec.w = vector[3] = startdy // Y offset to first convolution sample
-     * 
- * These values are used in the shader loop as follows: - *
-     *     samplelocation = outputpixellocation.xy + shadervec.zw;
-     *     for (each weight) {
-     *         sum += weight * sample(samplelocation.xy);
-     *         samplelocation.xy += shadervec.xy;
-     *     }
-     *
-     * @param srcnativedimensions the native dimensions (including unused
-     *                            padding) of the input source
-     * @param pass the pass of the algorithm being performed
-     * @return an array of 4 floats representing
-     *         {@code [ incdx, incdy, startdx, startdy ]}
-     */
-    public abstract float[] getVector(Rectangle srcnativedimensions,
-                                      BaseTransform transform, int pass);
-
-    /**
      * Returns the size of the kernel for a given pass.
      *
      * @param pass the pass of the algorithm being performed
@@ -221,208 +73,5 @@
      */
     public abstract int getKernelSize(int pass);
 
-    /**
-     * Returns the size of the kernel used in the shader for a given pass,
-     * taking into account the scaling specified by the getPow2ScaleXY methods.
-     *
-     * @param pass the pass of the algorithm being performed
-     * @return the size of the kernel for the scaled operation
-     */
-    public int getScaledKernelSize(int pass) {
-        return getKernelSize(pass);
-    }
-
-    /**
-     * Returns the number of power of 2 scales along the X axis.
-     * Positive numbers mean to scale the image larger by the indicated
-     * factors of 2.0.
-     * Negative numbers mean to scale the image smaller by the indicated
-     * factors of 0.5.
-     * Overall the image will be scaled by {@code pow(2.0, getPow2ScaleX())}.
-     * 

- * The kernel specified by the {@link #getWeights()} method will be - * relative to the scale factor recommended by this method. - * This scaling allows larger kernels to be reduced in size to save - * computation if the resolution reduction will not alter the quality - * of the convolution (eg. for blur convolutions). - * - * @return the power of 2.0 by which to scale the source image along the - * X axis. - */ - public int getPow2ScaleX() { - return 0; - } - - /** - * Returns the number of power of 2 scales along the Y axis. - * Positive numbers mean to scale the image larger by the indicated - * factors of 2.0. - * Negative numbers mean to scale the image smaller by the indicated - * factors of 0.5. - * Overall the image will be scaled by {@code pow(2.0, getPow2ScaleY())}. - *

- * The kernel specified by the {@link #getWeights()} method will be - * relative to the scale factor recommended by this method. - * This scaling allows larger kernels to be reduced in size to save - * computation if the resolution reduction will not alter the quality - * of the convolution (eg. for blur convolutions). - * - * @return the power of 2.0 by which to scale the source image along the - * Y axis. - */ - public int getPow2ScaleY() { - return 0; - } - - /** - * A {@link FloatBuffer} padded out to the required size as specified by - * the {@link #getPeerSize()} method. - * - * @param pass the pass of the algorithm being performed - * @return a {@code FloatBuffer} containing the kernel convolution weights - */ - public abstract FloatBuffer getWeights(int pass); - - /** - * Returns the maximum number of valid float4 elements that should be - * referenced from the buffer returned by getWeights() for the given pass. - * - * @param pass the pass of the algorithm being performed - * @return the maximum number of valid float4 elements in the weights buffer - */ - public int getWeightsArrayLength(int pass) { - int ksize = getScaledKernelSize(pass); - int psize = getPeerSize(ksize); - return psize / 4; - } - - final static float[] BLACK_COMPONENTS = - Color4f.BLACK.getPremultipliedRGBComponents(); - - /** - * Returns the color components to be used for a linearly convolved shadow. - * Only the LinearConvolveShadow shader uses this method. State - * subclasses that are only intended to be used with the LinearConvolve - * shader do not need to override this method. - * - * @param pass the pass of the algorithm being performed - * @return the color components for the shadow color for the given pass - */ - public float[] getShadowColorComponents(int pass) { - return BLACK_COMPONENTS; - } - - public EffectPeer getPeer(Renderer r, FilterContext fctx, int pass) { - if (isNop(pass)) { - return null; - } - int ksize = getScaledKernelSize(pass); - int psize = getPeerSize(ksize); - String opname = isShadow() ? "LinearConvolveShadow" : "LinearConvolve"; - return r.getPeerInstance(fctx, opname, psize); - } - - public Rectangle transform(Rectangle clip, - int xpow2scales, int ypow2scales) - { - // Modeled after Renderer.transform(fctx, img, hscale, vscale) - if (clip == null || (xpow2scales | ypow2scales) == 0) { - return clip; - } - clip = new Rectangle(clip); - if (xpow2scales < 0) { - xpow2scales = -xpow2scales; - clip.width = (clip.width + (1 << xpow2scales) - 1) >> xpow2scales; - clip.x >>= xpow2scales; - } else if (xpow2scales > 0) { - clip.width = clip.width << xpow2scales; - clip.x <<= xpow2scales; - } - if (ypow2scales < 0) { - ypow2scales = -ypow2scales; - clip.height = (clip.height + (1 << ypow2scales) - 1) >> ypow2scales; - clip.y >>= ypow2scales; - } else if (ypow2scales > 0) { - clip.height = clip.height << ypow2scales; - clip.y <<= ypow2scales; - } - return clip; - } - - public ImageData filterImageDatas(Effect effect, - FilterContext fctx, - BaseTransform transform, - Rectangle outputClip, - ImageData... inputs) - { - ImageData src = inputs[0]; - src.addref(); - if (isNop()) { - return src; - } - Rectangle approxBounds = inputs[0].getUntransformedBounds(); - int approxW = approxBounds.width; - int approxH = approxBounds.height; - Renderer r = Renderer.getRenderer(fctx, effect, approxW, approxH); - EffectPeer peer0 = getPeer(r, fctx, 0); - EffectPeer peer1 = getPeer(r, fctx, 1); - int hscale = 0; - int vscale = 0; - if (peer0 instanceof LinearConvolvePeer) { - hscale = ((LinearConvolvePeer) peer0).getPow2ScaleX(this); - } - if (peer1 instanceof LinearConvolvePeer) { - vscale = ((LinearConvolvePeer) peer1).getPow2ScaleY(this); - } - Rectangle filterClip = outputClip; - if ((hscale | vscale) != 0) { - src = r.transform(fctx, src, hscale, vscale); - if (!src.validate(fctx)) { - src.unref(); - return src; - } - filterClip = transform(outputClip, hscale, vscale); - } - if (filterClip != null) { - // The inputClip was already grown by the padding when the - // inputs were filtered, but now we need to make sure that - // the peers pass out padded results from the already padded - // input data, so we grow the clip here by the size of the - // scaled kernel padding. - int hgrow = getScaledKernelSize(0) / 2; - int vgrow = getScaledKernelSize(1) / 2; - if ((hgrow | vgrow) != 0) { - if (filterClip == outputClip) { - filterClip = new Rectangle(outputClip); - } - filterClip.grow(hgrow, vgrow); - } - } - if (peer0 != null) { - peer0.setPass(0); - ImageData res = peer0.filter(effect, transform, filterClip, src); - src.unref(); - src = res; - if (!src.validate(fctx)) { - src.unref(); - return src; - } - } - - if (peer1 != null) { - peer1.setPass(1); - ImageData res = peer1.filter(effect, transform, filterClip, src); - src.unref(); - src = res; - if (!src.validate(fctx)) { - src.unref(); - return src; - } - } - - if ((hscale | vscale) != 0) { - src = r.transform(fctx, src, -hscale, -vscale); - } - return src; - } + public abstract LinearConvolveRenderState getRenderState(BaseTransform filtertx); }