APIdia Launch Partner
Top Fields Constructors Methods
com.sun.prism.impl.ps

pack-priv Class PaintHelper

extends Object
Class Inheritance
Imports
java.nio.ByteBuffer, .FloatBuffer, java.util.List, .WeakHashMap, com.sun.javafx.geom.PickRay, .Point2D, .Vec3d, com.sun.javafx.geom.transform.Affine2D, .Affine3D, .AffineBase, .BaseTransform, .NoninvertibleTransformException, com.sun.javafx.sg.prism.NGCamera, .NGPerspectiveCamera, com.sun.prism.Image, .PixelFormat, .ResourceFactory, .Texture, .Texture.Usage, .Texture.WrapMode, com.sun.prism.impl.BufferUtil, com.sun.prism.paint.Color, .Gradient, .ImagePattern, .LinearGradient, .RadialGradient, .Stop, com.sun.prism.ps.Shader, .ShaderGraphics

Field Summary

Modifier and TypeField and Description
private static final ByteBuffer
private static long
private static final Image
private static final float
private static Texture
private static final WeakHashMap<Gradient, Void>
gradientMap

The keySet of this map is used to track the gradients that have a valid entry (offset) in the gradient cache.

private static final int
private static final int
private static Texture
private static final byte[]
private static final Image
private static final float
private static final int
pack-priv static final int
MULTI_MAX_FRACTIONS

The maximum number of gradient "stops" supported by our native fragment shader implementations.

private static final int
MULTI_TEXTURE_SIZE

Make the texture width a power of two value larger than MULTI_MAX_FRACTIONS.

private static Color
private static final int[]
private static final Affine2D
private static final Affine3D
private static final FloatBuffer

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
pack-priv static Texture
pack-priv static AffineBase
getImagePatternTx(ShaderGraphics g, ImagePattern paint, Shader shader, BaseTransform renderTx, float rx, float ry, float rw, float rh)

pack-priv static AffineBase
getLinearGradientTx(LinearGradient paint, Shader shader, BaseTransform renderTx, float rx, float ry, float rw, float rh)

pack-priv static AffineBase
getRadialGradientTx(RadialGradient paint, Shader shader, BaseTransform renderTx, float rx, float ry, float rw, float rh)

pack-priv static Texture
public static int
pack-priv static void
private static void
insertInterpColor(byte[] colors, int index, Color c0, Color c1, float t)

private static float
len(float dx, float dy)

pack-priv static PickRay
project(float x, float y, NGCamera cam, BaseTransform inv, PickRay tmpray, Vec3d tmpvec, Point2D ret)

pack-priv static void
setImagePattern(ShaderGraphics g, Shader shader, ImagePattern paint, float rx, float ry, float rw, float rh)

We use the plane equation to automatically map the ImagePattern image to the geometry being rendered.

pack-priv static void
setLinearGradient(ShaderGraphics g, Shader shader, LinearGradient paint, float rx, float ry, float rw, float rh)

This method uses techniques that are nearly identical to those employed in setGradientPaint() above.

private static void
pack-priv static void
setRadialGradient(ShaderGraphics g, Shader shader, RadialGradient paint, float rx, float ry, float rw, float rh)

This method calculates six m** values and a focus adjustment value that are used by the native fragment shader.

private static void
private static void
stopsToGtexImage(List<Stop> stops, int numStops)

private static void
stopsToImage(List<Stop> stops, int numStops)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

bgraColorsback to summary
private static final ByteBuffer bgraColors
cacheOffsetback to summary
private static long cacheOffset
colorsImgback to summary
private static final Image colorsImg
FULL_TEXEL_Yback to summary
private static final float FULL_TEXEL_Y
gradientCacheTextureback to summary
private static Texture gradientCacheTexture
gradientMapback to summary
private static final WeakHashMap<Gradient, Void> gradientMap

The keySet of this map is used to track the gradients that have a valid entry (offset) in the gradient cache. We need this so that we can invalidate all entries when a device is lost (at which time we recreate the gradient cache textures). This prevents using a stale offset that is no longer valid. The values in this map are unused.

GTEX_CLR_TABLE_MIRRORED_SIZEback to summary
private static final int GTEX_CLR_TABLE_MIRRORED_SIZE
GTEX_CLR_TABLE_SIZEback to summary
private static final int GTEX_CLR_TABLE_SIZE
gtexCacheTextureback to summary
private static Texture gtexCacheTexture
gtexColorsback to summary
private static final byte[] gtexColors
gtexImgback to summary
private static final Image gtexImg
HALF_TEXEL_Yback to summary
private static final float HALF_TEXEL_Y
MULTI_CACHE_SIZEback to summary
private static final int MULTI_CACHE_SIZE
MULTI_MAX_FRACTIONSback to summary
pack-priv static final int MULTI_MAX_FRACTIONS

The maximum number of gradient "stops" supported by our native fragment shader implementations. This value has been empirically determined and capped to allow our native shaders to run on all shader-level graphics hardware, even on the older, more limited GPUs. Even the oldest Nvidia hardware could handle 16, or even 32 fractions without any problem. But the first-generation boards from ATI would fall back into software mode (which is unusably slow) for values larger than 12; it appears that those boards do not have enough native registers to support the number of array accesses required by our gradient shaders. So for now we will cap this value at 12, but we can re-evaluate this in the future as hardware becomes more capable.

MULTI_TEXTURE_SIZEback to summary
private static final int MULTI_TEXTURE_SIZE

Make the texture width a power of two value larger than MULTI_MAX_FRACTIONS.

PINKback to summary
private static Color PINK
previousColorsback to summary
private static final int[] previousColors
scratchXform2Dback to summary
private static final Affine2D scratchXform2D
scratchXform3Dback to summary
private static final Affine3D scratchXform3D
stopValsback to summary
private static final FloatBuffer stopVals

Constructor Detail

PaintHelperback to summary
pack-priv PaintHelper()

Method Detail

getGradientTextureback to summary
pack-priv static Texture getGradientTexture(ShaderGraphics g, Gradient paint)
getImagePatternTxback to summary
pack-priv static AffineBase getImagePatternTx(ShaderGraphics g, ImagePattern paint, Shader shader, BaseTransform renderTx, float rx, float ry, float rw, float rh)
getLinearGradientTxback to summary
pack-priv static AffineBase getLinearGradientTx(LinearGradient paint, Shader shader, BaseTransform renderTx, float rx, float ry, float rw, float rh)
getRadialGradientTxback to summary
pack-priv static AffineBase getRadialGradientTx(RadialGradient paint, Shader shader, BaseTransform renderTx, float rx, float ry, float rw, float rh)
getWrapGradientTextureback to summary
pack-priv static Texture getWrapGradientTexture(ShaderGraphics g)
initGradientback to summary
public static int initGradient(Gradient paint)
initGradientTexturesback to summary
pack-priv static void initGradientTextures(ShaderGraphics g)
insertInterpColorback to summary
private static void insertInterpColor(byte[] colors, int index, Color c0, Color c1, float t)
lenback to summary
private static float len(float dx, float dy)
projectback to summary
pack-priv static PickRay project(float x, float y, NGCamera cam, BaseTransform inv, PickRay tmpray, Vec3d tmpvec, Point2D ret)
setImagePatternback to summary
pack-priv static void setImagePattern(ShaderGraphics g, Shader shader, ImagePattern paint, float rx, float ry, float rw, float rh)

We use the plane equation to automatically map the ImagePattern image to the geometry being rendered. The shader uses two separate plane equations that take the (x,y) location (in device space) of the fragment being rendered to calculate (u,v) texture coordinates for that fragment: u = Ax + By + Cz + Dw v = Ex + Fy + Gz + Hw For the 3D case we calculate a perspective vector by projecting rays at various points, can finding the deltas. So we need to calculate appropriate values for the plane equation constants (A,B,D) and (E,F,H) such that {u,v}=0 for the top-left of the ImagePattern's anchor rectangle and {u,v}=1 for the bottom-right of the anchor rectangle. We can easily make the texture image repeat for {u,v} values outside the range [0,1] by using the fract() instruction within the shader. Calculating the plane equation constants is surprisingly simple. We can think of it as an inverse matrix operation that takes device space coordinates and transforms them into user space coordinates that correspond to a location relative to the anchor rectangle. First, we translate and scale the current user space transform by applying the anchor rectangle bounds. We then take the inverse of this affine transform. The rows of the resulting inverse matrix correlate nicely to the plane equation constants we were seeking.

setLinearGradientback to summary
pack-priv static void setLinearGradient(ShaderGraphics g, Shader shader, LinearGradient paint, float rx, float ry, float rw, float rh)

This method uses techniques that are nearly identical to those employed in setGradientPaint() above. The primary difference is that at the native level we use a fragment shader to manually apply the plane equation constants to the current fragment position to calculate the gradient position in the range [0,1] (the native code for GradientPaint does the same, except that it uses OpenGL's automatic texture coordinate generation facilities). We Also, project in the 3D case to create a perspective vector which is used in the fragment shader. One other minor difference worth mentioning is that setGradientPaint() calculates the plane equation constants such that the gradient end points are positioned at 0.25 and 0.75 (for reasons discussed in the comments for that method). In contrast, for LinearGradientPaint we setup the equation constants such that the gradient end points fall at 0.0 and 1.0. The reason for this difference is that in the fragment shader we have more control over how the gradient values are interpreted (depending on the paint's CycleMethod).

setMultiGradientback to summary
private static void setMultiGradient(Shader shader, Gradient paint)
setRadialGradientback to summary
pack-priv static void setRadialGradient(ShaderGraphics g, Shader shader, RadialGradient paint, float rx, float ry, float rw, float rh)

This method calculates six m** values and a focus adjustment value that are used by the native fragment shader. (See LinearGradient Comment for the 3D case.) These techniques are based on a whitepaper by Daniel Rice on radial gradient performance (attached to the bug report for 6521533). One can refer to that document for the complete set of formulas and calculations, but the basic goal is to compose a transform that will convert an (x,y) position in device space into a "u" value that represents the relative distance to the gradient focus point. The resulting value can be used to look up the appropriate color by linearly interpolating between the two nearest colors in the gradient.

setTextureGradientback to summary
private static void setTextureGradient(Shader shader, Gradient paint)
stopsToGtexImageback to summary
private static void stopsToGtexImage(List<Stop> stops, int numStops)
stopsToImageback to summary
private static void stopsToImage(List<Stop> stops, int numStops)