diff options
Diffstat (limited to 'src/share/native/sun/java2d/opengl/OGLVertexCache.c')
-rw-r--r-- | src/share/native/sun/java2d/opengl/OGLVertexCache.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/share/native/sun/java2d/opengl/OGLVertexCache.c b/src/share/native/sun/java2d/opengl/OGLVertexCache.c index cd2d60c3a0..53c9a8a652 100644 --- a/src/share/native/sun/java2d/opengl/OGLVertexCache.c +++ b/src/share/native/sun/java2d/opengl/OGLVertexCache.c @@ -27,9 +27,11 @@ #include <stdlib.h> #include <string.h> +#include <float.h> #include "sun_java2d_SunGraphics2D.h" +#include "jni_util.h" #include "OGLPaints.h" #include "OGLVertexCache.h" @@ -39,11 +41,28 @@ typedef struct _J2DVertex { jfloat dx, dy; } J2DVertex; +// Multitexture vertex +typedef struct _J2DMTVertex { + jfloat dx, dy; + jfloat tx0, ty0; + jfloat tx1, ty1; +} J2DMTVertex; + static J2DVertex *vertexCache = NULL; static jint vertexCacheIndex = 0; +static J2DMTVertex *mtVertexCache = NULL; +static jboolean mtVertexCacheEnabled = JNI_FALSE; +static jboolean mtUseTxtBarrier = JNI_FALSE; +static jint evenLCDGlyphInd = 0; +static jint oddLCDGlyphInd = ODD_LCD_GLYPHS_OFFSET; +static jint lcdGlyphInd = 0; +static jfloat evenOx2 = FLT_MIN; +static jfloat oddOx2 = FLT_MIN; + static GLuint maskCacheTexID = 0; static jint maskCacheIndex = 0; +static void OGLMTVertexCache_flush(jint mask); #define OGLVC_ADD_VERTEX(TX, TY, R, G, B, A, DX, DY) \ do { \ @@ -66,6 +85,25 @@ static jint maskCacheIndex = 0; OGLVC_ADD_VERTEX(TX1, TY2, R, G, B, A, DX1, DY2); \ } while (0) +#define OGLMTVC_ADD_VERTEX(IND, DX, DY, TX0, TY0, TX1, TY1) \ + do { \ + J2DMTVertex *v = &mtVertexCache[IND++]; \ + v->dx = DX; \ + v->dy = DY; \ + v->tx0 = TX0; \ + v->ty0 = TY0; \ + v->tx1 = TX1; \ + v->ty1 = TY1; \ + } while (0) + +#define OGLMTVC_ADD_QUAD(IND, DX1, DY1, DX2, DY2, TX1, TY1, TX2, TY2, DTX1, DTY1, DTX2, DTY2) \ + do { \ + OGLMTVC_ADD_VERTEX((IND), DX1, DY1, TX1, TY1, DTX1, DTY1); \ + OGLMTVC_ADD_VERTEX((IND), DX2, DY1, TX2, TY1, DTX2, DTY1); \ + OGLMTVC_ADD_VERTEX((IND), DX2, DY2, TX2, TY2, DTX2, DTY2); \ + OGLMTVC_ADD_VERTEX((IND), DX1, DY2, TX1, TY2, DTX1, DTY2); \ + } while (0) + jboolean OGLVertexCache_InitVertexCache(OGLContext *oglc) { @@ -287,4 +325,97 @@ OGLVertexCache_AddGlyphQuad(OGLContext *oglc, oglc->r, oglc->g, oglc->b, oglc->a); } +jboolean OGLMTVertexCache_enable(OGLContext *oglc, jboolean useTxtBarrier) { + mtUseTxtBarrier = useTxtBarrier; + if (mtVertexCache == NULL) { + mtVertexCache = (J2DMTVertex *)malloc(OGLMTVC_MAX_INDEX * sizeof(J2DMTVertex)); + if (mtVertexCache == NULL) { + return JNI_FALSE; + } + } + + if (!mtVertexCacheEnabled) { + oglc->vertexCacheEnabled = JNI_FALSE; + + j2d_glVertexPointer(2, GL_FLOAT, sizeof(J2DMTVertex), &mtVertexCache[0].dx); + j2d_glEnableClientState(GL_VERTEX_ARRAY); + j2d_glClientActiveTexture(GL_TEXTURE1_ARB); + j2d_glTexCoordPointer(2, GL_FLOAT, sizeof(J2DMTVertex), &mtVertexCache[0].tx1); + j2d_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + j2d_glClientActiveTexture(GL_TEXTURE0_ARB); + j2d_glTexCoordPointer(2, GL_FLOAT, sizeof(J2DMTVertex), &mtVertexCache[0].tx0); + j2d_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + mtVertexCacheEnabled = JNI_TRUE; + evenLCDGlyphInd = 0; + oddLCDGlyphInd = ODD_LCD_GLYPHS_OFFSET; + lcdGlyphInd = 0; + } + + return JNI_TRUE; +} +void OGLMTVertexCache_disable() { + if (mtVertexCacheEnabled) { + OGLMTVertexCache_flush(OGLMTVC_FLUSH_ALL); + mtVertexCacheEnabled = JNI_FALSE; + } +} + +void OGLMTVertexCache_flush(jint mask) { + if (mtVertexCacheEnabled) { + if ((mask & OGLMTVC_FLUSH_EVEN) && evenLCDGlyphInd > 0) { + if (mtUseTxtBarrier) { + // TextureBarrierNV() will guarantee that writes have completed + // and caches have been invalidated before subsequent Draws are + // executed + j2d_glTextureBarrierNV(); + evenOx2 = FLT_MIN; + } + j2d_glDrawArrays(GL_QUADS, 0, evenLCDGlyphInd); + evenLCDGlyphInd = 0; + } + + if ((mask & OGLMTVC_FLUSH_ODD) && oddLCDGlyphInd > ODD_LCD_GLYPHS_OFFSET) { + if (mtUseTxtBarrier) { + // See the comment above + j2d_glTextureBarrierNV(); + oddOx2 = FLT_MIN; + } + j2d_glDrawArrays(GL_QUADS, ODD_LCD_GLYPHS_OFFSET, + oddLCDGlyphInd - ODD_LCD_GLYPHS_OFFSET); + oddLCDGlyphInd = ODD_LCD_GLYPHS_OFFSET; + } + } +} + +void OGLMTVertexCache_addGlyphQuad(jfloat dx1, jfloat dy1, + jfloat dx2, jfloat dy2, + jfloat tx1, jfloat ty1, + jfloat tx2, jfloat ty2, + jfloat dtx1, jfloat dty1, + jfloat dtx2, jfloat dty2) +{ + jint* ind; + if (lcdGlyphInd & 0x1) { + if (oddLCDGlyphInd >= OGLMTVC_MAX_INDEX || + (mtUseTxtBarrier && oddOx2 >= dx1)) + { + OGLMTVertexCache_flush(OGLMTVC_FLUSH_ODD); + } else if (mtUseTxtBarrier) { + oddOx2 = dx2; + } + ind = &oddLCDGlyphInd; + } else { + if (evenLCDGlyphInd >= ODD_LCD_GLYPHS_OFFSET || + (mtUseTxtBarrier && evenOx2 >= dx1)) + { + OGLMTVertexCache_flush(OGLMTVC_FLUSH_EVEN); + } else if (mtUseTxtBarrier) { + evenOx2 = dx2; + } + ind = &evenLCDGlyphInd; + } + lcdGlyphInd++; + OGLMTVC_ADD_QUAD(*ind, dx1, dy1, dx2, dy2, tx1, ty1, tx2, ty2, dtx1, dty1, dtx2, dty2); +} + #endif /* !HEADLESS */ |