modules/graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderContext.java
Print this page
*** 69,78 ****
--- 69,88 ----
* 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,327 ****
--- 328,342 ----
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,415 ****
}
if (externalShader == null) {
Paint paint = g.getPaint();
Texture paintTex = null;
! Texture tex0 = null;
! Texture tex1 = null;
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
--- 419,430 ----
}
if (externalShader == null) {
Paint paint = g.getPaint();
Texture paintTex = 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,440 ****
flushVertexBuffer();
ImagePattern texPaint = (ImagePattern)paint;
ResourceFactory rf = g.getResourceFactory();
paintTex = rf.getCachedTexture(texPaint.getImage(), Texture.WrapMode.REPEAT);
}
! Shader shader = null;
if (factory.isSuperShaderAllowed() &&
paintTex == null &&
maskTex == factory.getGlyphTexture())
{
// Enabling the super shader to be used to render text.
--- 445,455 ----
flushVertexBuffer();
ImagePattern texPaint = (ImagePattern)paint;
ResourceFactory rf = g.getResourceFactory();
paintTex = rf.getCachedTexture(texPaint.getImage(), Texture.WrapMode.REPEAT);
}
! Shader shader;
if (factory.isSuperShaderAllowed() &&
paintTex == null &&
maskTex == factory.getGlyphTexture())
{
// Enabling the super shader to be used to render text.
*** 461,478 ****
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);
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);
updatePerVertexColor(null, g.getExtraAlpha());
return externalShader;
}
}
--- 476,497 ----
tex1 = null;
}
// We do alpha test if depth test is enabled
shader = getPaintShader(g.isDepthTest() && g.isDepthBuffer(), maskType, paint);
}
! 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, CHECK_PAINT_OP_MASK, xform, externalShader);
! setTexture(0, maskTex);
! setTexture(1, null); // Needed?
updatePerVertexColor(null, g.getExtraAlpha());
return externalShader;
}
}
*** 489,507 ****
Paint fillColor)
{
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());
return shader;
}
Shader validateTextureOp(BaseShaderGraphics g, BaseTransform xform,
Texture[] textures, PixelFormat format)
{
! Shader shader = null;
if (format == PixelFormat.MULTI_YCbCr_420) {
// must have at least three textures, any more than four are ignored
if (textures.length < 3) {
return null;
--- 508,528 ----
Paint fillColor)
{
Shader shader = firstPass ? getSpecialShader(g, SpecialShaderType.TEXTURE_First_LCD) :
getSpecialShader(g, SpecialShaderType.TEXTURE_SECOND_LCD);
! 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;
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,525 ****
} else { // add more multitexture shaders here
return null;
}
if (null != shader) {
! checkState(g, xform, shader, textures);
updatePerVertexColor(null, g.getExtraAlpha());
}
return shader;
}
--- 536,551 ----
} else { // add more multitexture shaders here
return null;
}
if (null != shader) {
! 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,564 ****
throw new InternalError("Pixel format not supported: " + format);
}
} else {
shader = externalShader;
}
! checkState(g, xform, shader, tex0, tex1);
updatePerVertexColor(null, g.getExtraAlpha());
return shader;
}
Shader validateMaskTextureOp(BaseShaderGraphics g, BaseTransform xform,
--- 580,592 ----
throw new InternalError("Pixel format not supported: " + format);
}
} else {
shader = externalShader;
}
! 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,590 ****
throw new InternalError("Pixel format not supported: " + format);
}
} else {
shader = externalShader;
}
! checkState(g, xform, shader, tex0, tex1);
updatePerVertexColor(null, g.getExtraAlpha());
return shader;
}
void setExternalShader(BaseShaderGraphics g, Shader shader) {
--- 608,620 ----
throw new InternalError("Pixel format not supported: " + format);
}
} else {
shader = externalShader;
}
! 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,701 ****
}
externalShader = shader;
}
private void checkState(BaseShaderGraphics g,
BaseTransform xform,
! Shader shader,
! Texture tex0, Texture tex1)
{
setRenderTarget(g);
! setTexture(0, tex0);
! setTexture(1, tex1);
!
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 (!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 (!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 setTexture(int texUnit, Texture tex) {
if (tex != null) tex.assertLocked();
if (tex != state.lastTextures[texUnit]) {
flushVertexBuffer();
--- 637,692 ----
}
externalShader = shader;
}
private void checkState(BaseShaderGraphics g,
+ int checkFlags,
BaseTransform xform,
! Shader shader)
{
setRenderTarget(g);
! 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 ((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,728 ****
--- 710,720 ----
lcdBuffer.dispose();
lcdBuffer = null;
}
}
+ @Override
public RTTexture getLCDBuffer() {
return lcdBuffer;
}
//Current RenderTarget is undefined after this method.