< prev index next >
src/java.desktop/share/native/common/java2d/opengl/OGLTextRenderer.c
Print this page
*** 44,55 ****
* The following constants define the inner and outer bounds of the
* accelerated glyph cache.
*/
#define OGLTR_CACHE_WIDTH 512
#define OGLTR_CACHE_HEIGHT 512
! #define OGLTR_CACHE_CELL_WIDTH 16
! #define OGLTR_CACHE_CELL_HEIGHT 16
/**
* The current "glyph mode" state. This variable is used to track the
* codepath used to render a particular glyph. This variable is reset to
* MODE_NOT_INITED at the beginning of every call to OGLTR_DrawGlyphList().
--- 44,55 ----
* The following constants define the inner and outer bounds of the
* accelerated glyph cache.
*/
#define OGLTR_CACHE_WIDTH 512
#define OGLTR_CACHE_HEIGHT 512
! #define OGLTR_CACHE_CELL_WIDTH 32
! #define OGLTR_CACHE_CELL_HEIGHT 32
/**
* The current "glyph mode" state. This variable is used to track the
* codepath used to render a particular glyph. This variable is reset to
* MODE_NOT_INITED at the beginning of every call to OGLTR_DrawGlyphList().
*** 66,95 ****
MODE_NO_CACHE_LCD
} GlyphMode;
static GlyphMode glyphMode = MODE_NOT_INITED;
/**
! * This enum indicates the current state of the hardware glyph cache.
! * Initially the CacheStatus is set to CACHE_NOT_INITED, and then it is
! * set to either GRAY or LCD when the glyph cache is initialized.
! */
! typedef enum {
! CACHE_NOT_INITED,
! CACHE_GRAY,
! CACHE_LCD
! } CacheStatus;
! static CacheStatus cacheStatus = CACHE_NOT_INITED;
!
! /**
! * This is the one glyph cache. Once it is initialized as either GRAY or
! * LCD, it stays in that mode for the duration of the application. It should
* be safe to use this one glyph cache for all screens in a multimon
* environment, since the glyph cache texture is shared between all contexts,
* and (in theory) OpenGL drivers should be smart enough to manage that
* texture across all screens.
*/
! static GlyphCacheInfo *glyphCache = NULL;
/**
* The handle to the LCD text fragment program object.
*/
static GLhandleARB lcdTextProgram = 0;
--- 66,86 ----
MODE_NO_CACHE_LCD
} GlyphMode;
static GlyphMode glyphMode = MODE_NOT_INITED;
/**
! * There are two separate glyph caches: for AA and for LCD.
! * Once one of them is initialized as either GRAY or LCD, it
! * stays in that mode for the duration of the application. It should
* be safe to use this one glyph cache for all screens in a multimon
* environment, since the glyph cache texture is shared between all contexts,
* and (in theory) OpenGL drivers should be smart enough to manage that
* texture across all screens.
*/
!
! static GlyphCacheInfo *glyphCacheLCD = NULL;
! static GlyphCacheInfo *glyphCacheAA = NULL;
/**
* The handle to the LCD text fragment program object.
*/
static GLhandleARB lcdTextProgram = 0;
*** 136,146 ****
* (OGLTR_CACHED_DEST_WIDTH >= OGLTR_NOCACHE_TILE_SIZE) &&
* (OGLTR_CACHED_DEST_HEIGHT >= OGLTR_CACHE_CELL_HEIGHT) &&
* (OGLTR_CACHED_DEST_HEIGHT >= OGLTR_NOCACHE_TILE_SIZE)
*/
#define OGLTR_CACHED_DEST_WIDTH 512
! #define OGLTR_CACHED_DEST_HEIGHT 32
/**
* The handle to the "cached destination" texture object.
*/
static GLuint cachedDestTextureID = 0;
--- 127,137 ----
* (OGLTR_CACHED_DEST_WIDTH >= OGLTR_NOCACHE_TILE_SIZE) &&
* (OGLTR_CACHED_DEST_HEIGHT >= OGLTR_CACHE_CELL_HEIGHT) &&
* (OGLTR_CACHED_DEST_HEIGHT >= OGLTR_NOCACHE_TILE_SIZE)
*/
#define OGLTR_CACHED_DEST_WIDTH 512
! #define OGLTR_CACHED_DEST_HEIGHT (OGLTR_CACHE_CELL_HEIGHT * 2)
/**
* The handle to the "cached destination" texture object.
*/
static GLuint cachedDestTextureID = 0;
*** 210,248 ****
j2d_glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
OGLTR_CACHE_WIDTH, OGLTR_CACHE_HEIGHT, 0,
pixelFormat, GL_UNSIGNED_BYTE, NULL);
! cacheStatus = (lcdCache ? CACHE_LCD : CACHE_GRAY);
! glyphCache = gcinfo;
return JNI_TRUE;
}
/**
* Adds the given glyph to the glyph cache (texture and data structure)
* associated with the given OGLContext.
*/
static void
! OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder)
{
- GLenum pixelFormat;
CacheCellInfo *ccinfo;
J2dTraceLn(J2D_TRACE_INFO, "OGLTR_AddToGlyphCache");
! if ((glyphCache == NULL) || (glyph->image == NULL)) {
! return;
}
! if (cacheStatus == CACHE_LCD) {
! pixelFormat = rgbOrder ? GL_RGB : GL_BGR;
! } else {
! pixelFormat = GL_LUMINANCE;
}
! AccelGlyphCache_AddGlyph(glyphCache, glyph);
ccinfo = (CacheCellInfo *) glyph->cellInfo;
if (ccinfo != NULL) {
// store glyph image in texture cell
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
--- 201,242 ----
j2d_glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
OGLTR_CACHE_WIDTH, OGLTR_CACHE_HEIGHT, 0,
pixelFormat, GL_UNSIGNED_BYTE, NULL);
! if (lcdCache) {
! glyphCacheLCD = gcinfo;
! } else {
! glyphCacheAA = gcinfo;
! }
return JNI_TRUE;
}
/**
* Adds the given glyph to the glyph cache (texture and data structure)
* associated with the given OGLContext.
*/
static void
! OGLTR_AddToGlyphCache(GlyphInfo *glyph, GLenum pixelFormat)
{
CacheCellInfo *ccinfo;
+ GlyphCacheInfo *gcinfo;
J2dTraceLn(J2D_TRACE_INFO, "OGLTR_AddToGlyphCache");
! if (pixelFormat == GL_LUMINANCE) {
! gcinfo = glyphCacheAA;
! } else {
! gcinfo = glyphCacheLCD;
}
! if ((gcinfo == NULL) || (glyph->image == NULL)) {
! return;
}
! AccelGlyphCache_AddGlyph(gcinfo, glyph);
ccinfo = (CacheCellInfo *) glyph->cellInfo;
if (ccinfo != NULL) {
// store glyph image in texture cell
j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
*** 411,438 ****
/**
* Enables the LCD text shader and updates any related state, such as the
* gamma lookup table textures.
*/
static jboolean
! OGLTR_EnableLCDGlyphModeState(GLuint glyphTextureID, jint contrast)
{
// bind the texture containing glyph data to texture unit 0
j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
j2d_glBindTexture(GL_TEXTURE_2D, glyphTextureID);
// bind the texture tile containing destination data to texture unit 1
j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
if (cachedDestTextureID == 0) {
cachedDestTextureID =
OGLContext_CreateBlitTexture(GL_RGB8, GL_RGB,
OGLTR_CACHED_DEST_WIDTH,
OGLTR_CACHED_DEST_HEIGHT);
if (cachedDestTextureID == 0) {
return JNI_FALSE;
}
}
j2d_glBindTexture(GL_TEXTURE_2D, cachedDestTextureID);
// note that GL_TEXTURE_2D was already enabled for texture unit 0,
// but we need to explicitly enable it for texture unit 1
j2d_glEnable(GL_TEXTURE_2D);
--- 405,439 ----
/**
* Enables the LCD text shader and updates any related state, such as the
* gamma lookup table textures.
*/
static jboolean
! OGLTR_EnableLCDGlyphModeState(GLuint glyphTextureID,
! GLuint dstTextureID,
! jint contrast)
{
// bind the texture containing glyph data to texture unit 0
j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
j2d_glBindTexture(GL_TEXTURE_2D, glyphTextureID);
+ j2d_glEnable(GL_TEXTURE_2D);
// bind the texture tile containing destination data to texture unit 1
j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
+ if (dstTextureID != 0) {
+ j2d_glBindTexture(GL_TEXTURE_2D, dstTextureID);
+ } else {
if (cachedDestTextureID == 0) {
cachedDestTextureID =
OGLContext_CreateBlitTexture(GL_RGB8, GL_RGB,
OGLTR_CACHED_DEST_WIDTH,
OGLTR_CACHED_DEST_HEIGHT);
if (cachedDestTextureID == 0) {
return JNI_FALSE;
}
}
j2d_glBindTexture(GL_TEXTURE_2D, cachedDestTextureID);
+ }
// note that GL_TEXTURE_2D was already enabled for texture unit 0,
// but we need to explicitly enable it for texture unit 1
j2d_glEnable(GL_TEXTURE_2D);
*** 470,487 ****
if (!OGLVertexCache_InitVertexCache(oglc)) {
return;
}
! if (glyphCache == NULL) {
if (!OGLTR_InitGlyphCache(JNI_FALSE)) {
return;
}
}
j2d_glEnable(GL_TEXTURE_2D);
! j2d_glBindTexture(GL_TEXTURE_2D, glyphCache->cacheID);
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// for grayscale/monochrome text, the current OpenGL source color
// is modulated with the glyph image as part of the texture
// application stage, so we use GL_MODULATE here
--- 471,488 ----
if (!OGLVertexCache_InitVertexCache(oglc)) {
return;
}
! if (glyphCacheAA == NULL) {
if (!OGLTR_InitGlyphCache(JNI_FALSE)) {
return;
}
}
j2d_glEnable(GL_TEXTURE_2D);
! j2d_glBindTexture(GL_TEXTURE_2D, glyphCacheAA->cacheID);
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// for grayscale/monochrome text, the current OpenGL source color
// is modulated with the glyph image as part of the texture
// application stage, so we use GL_MODULATE here
*** 520,529 ****
--- 521,531 ----
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
j2d_glUseProgramObjectARB(0);
j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
j2d_glDisable(GL_TEXTURE_2D);
j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
+ j2d_glDisable(GL_TEXTURE_2D);
break;
case MODE_NO_CACHE_GRAY:
case MODE_USE_CACHE_GRAY:
case MODE_NOT_INITED:
*** 545,555 ****
glyphMode = MODE_USE_CACHE_GRAY;
}
if (ginfo->cellInfo == NULL) {
// attempt to add glyph to accelerated glyph cache
! OGLTR_AddToGlyphCache(ginfo, JNI_FALSE);
if (ginfo->cellInfo == NULL) {
// we'll just no-op in the rare case that the cell is NULL
return JNI_TRUE;
}
--- 547,557 ----
glyphMode = MODE_USE_CACHE_GRAY;
}
if (ginfo->cellInfo == NULL) {
// attempt to add glyph to accelerated glyph cache
! OGLTR_AddToGlyphCache(ginfo, GL_LUMINANCE);
if (ginfo->cellInfo == NULL) {
// we'll just no-op in the rare case that the cell is NULL
return JNI_TRUE;
}
*** 705,739 ****
static jboolean
OGLTR_DrawLCDGlyphViaCache(OGLContext *oglc, OGLSDOps *dstOps,
GlyphInfo *ginfo, jint x, jint y,
jint glyphIndex, jint totalGlyphs,
! jboolean rgbOrder, jint contrast)
{
CacheCellInfo *cell;
jint dx1, dy1, dx2, dy2;
jfloat dtx1, dty1, dtx2, dty2;
if (glyphMode != MODE_USE_CACHE_LCD) {
OGLTR_DisableGlyphModeState();
CHECK_PREVIOUS_OP(GL_TEXTURE_2D);
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
! if (glyphCache == NULL) {
if (!OGLTR_InitGlyphCache(JNI_TRUE)) {
return JNI_FALSE;
}
}
if (rgbOrder != lastRGBOrder) {
// need to invalidate the cache in this case; see comments
// for lastRGBOrder above
! AccelGlyphCache_Invalidate(glyphCache);
lastRGBOrder = rgbOrder;
}
! if (!OGLTR_EnableLCDGlyphModeState(glyphCache->cacheID, contrast)) {
return JNI_FALSE;
}
// when a fragment shader is enabled, the texture function state is
// ignored, so the following line is not needed...
--- 707,744 ----
static jboolean
OGLTR_DrawLCDGlyphViaCache(OGLContext *oglc, OGLSDOps *dstOps,
GlyphInfo *ginfo, jint x, jint y,
jint glyphIndex, jint totalGlyphs,
! jboolean rgbOrder, jint contrast,
! GLuint dstTextureID)
{
CacheCellInfo *cell;
jint dx1, dy1, dx2, dy2;
jfloat dtx1, dty1, dtx2, dty2;
if (glyphMode != MODE_USE_CACHE_LCD) {
OGLTR_DisableGlyphModeState();
CHECK_PREVIOUS_OP(GL_TEXTURE_2D);
j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
! if (glyphCacheLCD == NULL) {
if (!OGLTR_InitGlyphCache(JNI_TRUE)) {
return JNI_FALSE;
}
}
if (rgbOrder != lastRGBOrder) {
// need to invalidate the cache in this case; see comments
// for lastRGBOrder above
! AccelGlyphCache_Invalidate(glyphCacheLCD);
lastRGBOrder = rgbOrder;
}
! if (!OGLTR_EnableLCDGlyphModeState(glyphCacheLCD->cacheID,
! dstTextureID, contrast))
! {
return JNI_FALSE;
}
// when a fragment shader is enabled, the texture function state is
// ignored, so the following line is not needed...
*** 748,758 ****
// make sure the glyph cache texture is bound to texture unit 0
j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
// attempt to add glyph to accelerated glyph cache
! OGLTR_AddToGlyphCache(ginfo, rgbOrder);
if (ginfo->cellInfo == NULL) {
// we'll just no-op in the rare case that the cell is NULL
return JNI_TRUE;
}
--- 753,763 ----
// make sure the glyph cache texture is bound to texture unit 0
j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
// attempt to add glyph to accelerated glyph cache
! OGLTR_AddToGlyphCache(ginfo, rgbOrder ? GL_RGB : GL_BGR);
if (ginfo->cellInfo == NULL) {
// we'll just no-op in the rare case that the cell is NULL
return JNI_TRUE;
}
*** 765,784 ****
--- 770,807 ----
dx1 = x;
dy1 = y;
dx2 = dx1 + ginfo->width;
dy2 = dy1 + ginfo->height;
+ if (dstTextureID == 0) {
// copy destination into second cached texture, if necessary
OGLTR_UpdateCachedDestination(dstOps, ginfo,
dx1, dy1, dx2, dy2,
glyphIndex, totalGlyphs);
// texture coordinates of the destination tile
dtx1 = ((jfloat)(dx1 - cachedDestBounds.x1)) / OGLTR_CACHED_DEST_WIDTH;
dty1 = ((jfloat)(cachedDestBounds.y2 - dy1)) / OGLTR_CACHED_DEST_HEIGHT;
dtx2 = ((jfloat)(dx2 - cachedDestBounds.x1)) / OGLTR_CACHED_DEST_WIDTH;
dty2 = ((jfloat)(cachedDestBounds.y2 - dy2)) / OGLTR_CACHED_DEST_HEIGHT;
+ } else {
+ jint gw = ginfo->width;
+ jint gh = ginfo->height;
+
+ // this accounts for lower-left origin of the destination region
+ jint dxadj = dstOps->xOffset + x;
+ jint dyadj = dstOps->yOffset + dstOps->height - (y + gh);
+
+ // update the remaining destination texture coordinates
+ dtx1 =((GLfloat)dxadj) / dstOps->textureWidth;
+ dtx2 = ((GLfloat)dxadj + gw) / dstOps->textureWidth;
+
+ dty1 = ((GLfloat)dyadj + gh) / dstOps->textureHeight;
+ dty2 = ((GLfloat)dyadj) / dstOps->textureHeight;
+
+ j2d_glTextureBarrierNV();
+ }
// render composed texture to the destination surface
j2d_glBegin(GL_QUADS);
j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx1, cell->ty1);
j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
*** 835,845 ****
static jboolean
OGLTR_DrawLCDGlyphNoCache(OGLContext *oglc, OGLSDOps *dstOps,
GlyphInfo *ginfo, jint x, jint y,
jint rowBytesOffset,
! jboolean rgbOrder, jint contrast)
{
GLfloat tx1, ty1, tx2, ty2;
GLfloat dtx1, dty1, dtx2, dty2;
jint tw, th;
jint sx, sy, sw, sh, dxadj, dyadj;
--- 858,869 ----
static jboolean
OGLTR_DrawLCDGlyphNoCache(OGLContext *oglc, OGLSDOps *dstOps,
GlyphInfo *ginfo, jint x, jint y,
jint rowBytesOffset,
! jboolean rgbOrder, jint contrast,
! GLuint dstTextureID)
{
GLfloat tx1, ty1, tx2, ty2;
GLfloat dtx1, dty1, dtx2, dty2;
jint tw, th;
jint sx, sy, sw, sh, dxadj, dyadj;
*** 857,867 ****
if (!OGLContext_InitBlitTileTexture(oglc)) {
return JNI_FALSE;
}
}
! if (!OGLTR_EnableLCDGlyphModeState(oglc->blitTextureID, contrast)) {
return JNI_FALSE;
}
// when a fragment shader is enabled, the texture function state is
// ignored, so the following line is not needed...
--- 881,893 ----
if (!OGLContext_InitBlitTileTexture(oglc)) {
return JNI_FALSE;
}
}
! if (!OGLTR_EnableLCDGlyphModeState(oglc->blitTextureID,
! dstTextureID, contrast))
! {
return JNI_FALSE;
}
// when a fragment shader is enabled, the texture function state is
// ignored, so the following line is not needed...
*** 905,926 ****
// this accounts for lower-left origin of the destination region
dxadj = dstOps->xOffset + x;
dyadj = dstOps->yOffset + dstOps->height - (y + sh);
// copy destination into cached texture tile (the lower-left
// corner of the destination region will be positioned at the
// lower-left corner (0,0) of the texture)
j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0,
dxadj, dyadj,
sw, sh);
-
// update the remaining destination texture coordinates
dtx2 = ((GLfloat)sw) / OGLTR_CACHED_DEST_WIDTH;
dty1 = ((GLfloat)sh) / OGLTR_CACHED_DEST_HEIGHT;
// render composed texture to the destination surface
j2d_glBegin(GL_QUADS);
j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx1, ty1);
j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
--- 931,963 ----
// this accounts for lower-left origin of the destination region
dxadj = dstOps->xOffset + x;
dyadj = dstOps->yOffset + dstOps->height - (y + sh);
+ if (dstTextureID == 0) {
// copy destination into cached texture tile (the lower-left
// corner of the destination region will be positioned at the
// lower-left corner (0,0) of the texture)
j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0,
dxadj, dyadj,
sw, sh);
// update the remaining destination texture coordinates
dtx2 = ((GLfloat)sw) / OGLTR_CACHED_DEST_WIDTH;
dty1 = ((GLfloat)sh) / OGLTR_CACHED_DEST_HEIGHT;
+ } else {
+ // use the destination texture directly
+ // update the remaining destination texture coordinates
+ dtx1 =((GLfloat)dxadj) / ((GLfloat)dstOps->textureWidth);
+ dtx2 = ((GLfloat)dxadj + sw) / ((GLfloat)dstOps->textureWidth);
+
+ dty1 = ((GLfloat)dyadj + sh) / ((GLfloat)dstOps->textureHeight);
+ dty2 = ((GLfloat)dyadj) / ((GLfloat)dstOps->textureHeight);
+
+ j2d_glTextureBarrierNV();
+ }
// render composed texture to the destination surface
j2d_glBegin(GL_QUADS);
j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx1, ty1);
j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
*** 951,960 ****
--- 988,998 ----
jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
jfloat glyphListOrigX, jfloat glyphListOrigY,
unsigned char *images, unsigned char *positions)
{
int glyphCounter;
+ GLuint dstTextureID = 0;
J2dTraceLn(J2D_TRACE_INFO, "OGLTR_DrawGlyphList");
RETURN_IF_NULL(oglc);
RETURN_IF_NULL(dstOps);
*** 964,973 ****
--- 1002,1017 ----
}
glyphMode = MODE_NOT_INITED;
isCachedDestValid = JNI_FALSE;
+ if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_TEXBARRIER) &&
+ dstOps->textureTarget == GL_TEXTURE_2D)
+ {
+ dstTextureID = dstOps->textureID;
+ }
+
for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
jint x, y;
jfloat glyphx, glyphy;
jboolean grayscale, ok;
GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(NEXT_LONG(images));
*** 1001,1012 ****
continue;
}
if (grayscale) {
// grayscale or monochrome glyph data
! if (cacheStatus != CACHE_LCD &&
! ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
{
ok = OGLTR_DrawGrayscaleGlyphViaCache(oglc, ginfo, x, y);
} else {
ok = OGLTR_DrawGrayscaleGlyphNoCache(oglc, ginfo, x, y);
--- 1045,1055 ----
continue;
}
if (grayscale) {
// grayscale or monochrome glyph data
! if (ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
{
ok = OGLTR_DrawGrayscaleGlyphViaCache(oglc, ginfo, x, y);
} else {
ok = OGLTR_DrawGrayscaleGlyphNoCache(oglc, ginfo, x, y);
*** 1022,1044 ****
x += 1;
}
}
if (rowBytesOffset == 0 &&
- cacheStatus != CACHE_GRAY &&
ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
{
ok = OGLTR_DrawLCDGlyphViaCache(oglc, dstOps,
ginfo, x, y,
glyphCounter, totalGlyphs,
! rgbOrder, lcdContrast);
} else {
ok = OGLTR_DrawLCDGlyphNoCache(oglc, dstOps,
ginfo, x, y,
rowBytesOffset,
! rgbOrder, lcdContrast);
}
}
if (!ok) {
break;
--- 1065,1088 ----
x += 1;
}
}
if (rowBytesOffset == 0 &&
ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
{
ok = OGLTR_DrawLCDGlyphViaCache(oglc, dstOps,
ginfo, x, y,
glyphCounter, totalGlyphs,
! rgbOrder, lcdContrast,
! dstTextureID);
} else {
ok = OGLTR_DrawLCDGlyphNoCache(oglc, dstOps,
ginfo, x, y,
rowBytesOffset,
! rgbOrder, lcdContrast,
! dstTextureID);
}
}
if (!ok) {
break;
< prev index next >