jdk/src/share/native/sun/java2d/opengl/OGLTextRenderer.c
author dcherepanov
Tue, 15 May 2012 15:04:10 +0400
changeset 12652 6fddf8394164
parent 12047 320a714614e9
child 21278 ef8a3a2a72f2
permissions -rw-r--r--
7168550: [macosx] duplicate OGL context state changes related to vertex cache Reviewed-by: bae, swingler
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 5580
diff changeset
     2
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#ifndef HEADLESS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents: 7668
diff changeset
    28
#include <stdlib.h>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include <math.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include <jlong.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "sun_java2d_opengl_OGLTextRenderer.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include "SurfaceData.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
#include "OGLContext.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#include "OGLSurfaceData.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
#include "OGLRenderQueue.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
#include "OGLTextRenderer.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
#include "OGLVertexCache.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
#include "AccelGlyphCache.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
#include "fontscalerdefs.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * The following constants define the inner and outer bounds of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * accelerated glyph cache.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
#define OGLTR_CACHE_WIDTH       512
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#define OGLTR_CACHE_HEIGHT      512
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
#define OGLTR_CACHE_CELL_WIDTH  16
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
#define OGLTR_CACHE_CELL_HEIGHT 16
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * The current "glyph mode" state.  This variable is used to track the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * codepath used to render a particular glyph.  This variable is reset to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * MODE_NOT_INITED at the beginning of every call to OGLTR_DrawGlyphList().
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * As each glyph is rendered, the glyphMode variable is updated to reflect
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * the current mode, so if the current mode is the same as the mode used
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * to render the previous glyph, we can avoid doing costly setup operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * each time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
typedef enum {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    MODE_NOT_INITED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    MODE_USE_CACHE_GRAY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    MODE_USE_CACHE_LCD,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    MODE_NO_CACHE_GRAY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    MODE_NO_CACHE_LCD
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
} GlyphMode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
static GlyphMode glyphMode = MODE_NOT_INITED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * This enum indicates the current state of the hardware glyph cache.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * Initially the CacheStatus is set to CACHE_NOT_INITED, and then it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * set to either GRAY or LCD when the glyph cache is initialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
typedef enum {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    CACHE_NOT_INITED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    CACHE_GRAY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    CACHE_LCD
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
} CacheStatus;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
static CacheStatus cacheStatus = CACHE_NOT_INITED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * This is the one glyph cache.  Once it is initialized as either GRAY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * LCD, it stays in that mode for the duration of the application.  It should
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * be safe to use this one glyph cache for all screens in a multimon
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * environment, since the glyph cache texture is shared between all contexts,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * and (in theory) OpenGL drivers should be smart enough to manage that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * texture across all screens.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
static GlyphCacheInfo *glyphCache = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * The handle to the LCD text fragment program object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
static GLhandleARB lcdTextProgram = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * The size of one of the gamma LUT textures in any one dimension along
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 * the edge, in texels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
#define LUT_EDGE 16
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * These are the texture object handles for the gamma and inverse gamma
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * lookup tables.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
static GLuint gammaLutTextureID = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
static GLuint invGammaLutTextureID = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 * This value tracks the previous LCD contrast setting, so if the contrast
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 * value hasn't changed since the last time the lookup tables were
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 * generated (not very common), then we can skip updating the tables.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
static jint lastLCDContrast = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 * This value tracks the previous LCD rgbOrder setting, so if the rgbOrder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * value has changed since the last time, it indicates that we need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 * invalidate the cache, which may already store glyph images in the reverse
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 * order.  Note that in most real world applications this value will not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * change over the course of the application, but tests like Font2DTest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * allow for changing the ordering at runtime, so we need to handle that case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
static jboolean lastRGBOrder = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
 * This constant defines the size of the tile to use in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
 * OGLTR_DrawLCDGlyphNoCache() method.  See below for more on why we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
 * restrict this value to a particular size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
#define OGLTR_NOCACHE_TILE_SIZE 32
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
 * These constants define the size of the "cached destination" texture.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
 * This texture is only used when rendering LCD-optimized text, as that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
 * codepath needs direct access to the destination.  There is no way to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
 * access the framebuffer directly from an OpenGL shader, so we need to first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
 * copy the destination region corresponding to a particular glyph into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
 * this cached texture, and then that texture will be accessed inside the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
 * shader.  Copying the destination into this cached texture can be a very
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
 * expensive operation (accounting for about half the rendering time for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
 * LCD text), so to mitigate this cost we try to bulk read a horizontal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
 * region of the destination at a time.  (These values are empirically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * derived for the common case where text runs horizontally.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * Note: It is assumed in various calculations below that:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 *     (OGLTR_CACHED_DEST_WIDTH  >= OGLTR_CACHE_CELL_WIDTH)  &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 *     (OGLTR_CACHED_DEST_WIDTH  >= OGLTR_NOCACHE_TILE_SIZE) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
 *     (OGLTR_CACHED_DEST_HEIGHT >= OGLTR_CACHE_CELL_HEIGHT) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
 *     (OGLTR_CACHED_DEST_HEIGHT >= OGLTR_NOCACHE_TILE_SIZE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
#define OGLTR_CACHED_DEST_WIDTH  512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
#define OGLTR_CACHED_DEST_HEIGHT 32
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
 * The handle to the "cached destination" texture object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
static GLuint cachedDestTextureID = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
 * The current bounds of the "cached destination" texture, in destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
 * coordinate space.  The width/height of these bounds will not exceed the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
 * OGLTR_CACHED_DEST_WIDTH/HEIGHT values defined above.  These bounds are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
 * only considered valid when the isCachedDestValid flag is JNI_TRUE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
static SurfaceDataBounds cachedDestBounds;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
 * This flag indicates whether the "cached destination" texture contains
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
 * valid data.  This flag is reset to JNI_FALSE at the beginning of every
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
 * call to OGLTR_DrawGlyphList().  Once we copy valid destination data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
 * into the cached texture, this flag is set to JNI_TRUE.  This way, we can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
 * limit the number of times we need to copy destination data, which is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
 * very costly operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
static jboolean isCachedDestValid = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
 * The bounds of the previously rendered LCD glyph, in destination
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
 * coordinate space.  We use these bounds to determine whether the glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
 * currently being rendered overlaps the previously rendered glyph (i.e.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
 * its bounding box intersects that of the previously rendered glyph).  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
 * so, we need to re-read the destination area associated with that previous
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
 * glyph so that we can correctly blend with the actual destination data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
static SurfaceDataBounds previousGlyphBounds;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
 * Initializes the one glyph cache (texture and data structure).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
 * If lcdCache is JNI_TRUE, the texture will contain RGB data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
 * otherwise we will simply store the grayscale/monochrome glyph images
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
 * as intensity values (which work well with the GL_MODULATE function).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
OGLTR_InitGlyphCache(jboolean lcdCache)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    GlyphCacheInfo *gcinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    GLclampf priority = 1.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    GLenum internalFormat = lcdCache ? GL_RGB8 : GL_INTENSITY8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    GLenum pixelFormat = lcdCache ? GL_RGB : GL_LUMINANCE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_InitGlyphCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    // init glyph cache data structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    gcinfo = AccelGlyphCache_Init(OGLTR_CACHE_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                                  OGLTR_CACHE_HEIGHT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                                  OGLTR_CACHE_CELL_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                                  OGLTR_CACHE_CELL_HEIGHT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                                  OGLVertexCache_FlushVertexCache);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    if (gcinfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                      "OGLTR_InitGlyphCache: could not init OGL glyph cache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    // init cache texture object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    j2d_glGenTextures(1, &gcinfo->cacheID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    j2d_glBindTexture(GL_TEXTURE_2D, gcinfo->cacheID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    j2d_glPrioritizeTextures(1, &gcinfo->cacheID, &priority);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    j2d_glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                     OGLTR_CACHE_WIDTH, OGLTR_CACHE_HEIGHT, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                     pixelFormat, GL_UNSIGNED_BYTE, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    cacheStatus = (lcdCache ? CACHE_LCD : CACHE_GRAY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    glyphCache = gcinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
 * Adds the given glyph to the glyph cache (texture and data structure)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
 * associated with the given OGLContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    GLenum pixelFormat;
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   242
    CacheCellInfo *ccinfo;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_AddToGlyphCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    if ((glyphCache == NULL) || (glyph->image == NULL)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    if (cacheStatus == CACHE_LCD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        pixelFormat = rgbOrder ? GL_RGB : GL_BGR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        pixelFormat = GL_LUMINANCE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    AccelGlyphCache_AddGlyph(glyphCache, glyph);
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   257
    ccinfo = (CacheCellInfo *) glyph->cellInfo;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   259
    if (ccinfo != NULL) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        // store glyph image in texture cell
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   262
                            ccinfo->x, ccinfo->y,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                            glyph->width, glyph->height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                            pixelFormat, GL_UNSIGNED_BYTE, glyph->image);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
 * This is the GLSL fragment shader source code for rendering LCD-optimized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
 * text.  Do not be frightened; it is much easier to understand than the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
 * equivalent ASM-like fragment program!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
 * The "uniform" variables at the top are initialized once the program is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
 * linked, and are updated at runtime as needed (e.g. when the source color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
 * changes, we will modify the "src_adj" value in OGLTR_UpdateLCDTextColor()).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
 * The "main" function is executed for each "fragment" (or pixel) in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
 * glyph image.  We have determined that the pow() function can be quite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
 * slow and it only operates on scalar values, not vectors as we require.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
 * So instead we build two 3D textures containing gamma (and inverse gamma)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
 * lookup tables that allow us to approximate a component-wise pow() function
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
 * with a single 3D texture lookup.  This approach is at least 2x faster
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
 * than the equivalent pow() calls.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
 * The variables involved in the equation can be expressed as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
 *   Cs = Color component of the source (foreground color) [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
 *   Cd = Color component of the destination (background color) [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
 *   Cr = Color component to be written to the destination [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
 *   Ag = Glyph alpha (aka intensity or coverage) [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
 *   Ga = Gamma adjustment in the range [1.0, 2.5]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
 *   (^ means raised to the power)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
 * And here is the theoretical equation approximated by this shader:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
 *            Cr = (Ag*(Cs^Ga) + (1-Ag)*(Cd^Ga)) ^ (1/Ga)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
static const char *lcdTextShaderSource =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    "uniform vec3 src_adj;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    "uniform sampler2D glyph_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    "uniform sampler2D dst_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    "uniform sampler3D invgamma_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    "uniform sampler3D gamma_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    "void main(void)"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    "{"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
         // load the RGB value from the glyph image at the current texcoord
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    "    vec3 glyph_clr = vec3(texture2D(glyph_tex, gl_TexCoord[0].st));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    "    if (glyph_clr == vec3(0.0)) {"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
             // zero coverage, so skip this fragment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    "        discard;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    "    }"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
         // load the RGB value from the corresponding destination pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    "    vec3 dst_clr = vec3(texture2D(dst_tex, gl_TexCoord[1].st));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
         // gamma adjust the dest color using the invgamma LUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    "    vec3 dst_adj = vec3(texture3D(invgamma_tex, dst_clr.stp));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
         // linearly interpolate the three color values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    "    vec3 result = mix(dst_adj, src_adj, glyph_clr);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
         // gamma re-adjust the resulting color (alpha is always set to 1.0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    "    gl_FragColor = vec4(vec3(texture3D(gamma_tex, result.stp)), 1.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    "}";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
 * Compiles and links the LCD text shader program.  If successful, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
 * function returns a handle to the newly created shader program; otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
 * returns 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
static GLhandleARB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
OGLTR_CreateLCDTextProgram()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    GLhandleARB lcdTextProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_CreateLCDTextProgram");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    lcdTextProgram = OGLContext_CreateFragmentProgram(lcdTextShaderSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    if (lcdTextProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                      "OGLTR_CreateLCDTextProgram: error creating program");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    // "use" the program object temporarily so that we can set the uniforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    j2d_glUseProgramObjectARB(lcdTextProgram);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    // set the "uniform" values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "glyph_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    j2d_glUniform1iARB(loc, 0); // texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "dst_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    j2d_glUniform1iARB(loc, 1); // texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "invgamma_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    j2d_glUniform1iARB(loc, 2); // texture unit 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "gamma_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    j2d_glUniform1iARB(loc, 3); // texture unit 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    // "unuse" the program object; it will be re-bound later as needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    j2d_glUseProgramObjectARB(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    return lcdTextProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
 * Initializes a 3D texture object for use as a three-dimensional gamma
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
 * lookup table.  Note that the wrap mode is initialized to GL_LINEAR so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
 * that the table will interpolate adjacent values when the index falls
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
 * somewhere in between.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
static GLuint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
OGLTR_InitGammaLutTexture()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    GLuint lutTextureID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    j2d_glGenTextures(1, &lutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    j2d_glBindTexture(GL_TEXTURE_3D, lutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    return lutTextureID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
 * Updates the lookup table in the given texture object with the float
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
 * values in the given system memory buffer.  Note that we could use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
 * glTexSubImage3D() when updating the texture after its first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
 * initialization, but since we're updating the entire table (with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
 * power-of-two dimensions) and this is a relatively rare event, we'll
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
 * just stick with glTexImage3D().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
OGLTR_UpdateGammaLutTexture(GLuint texID, GLfloat *lut, jint size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    j2d_glBindTexture(GL_TEXTURE_3D, texID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    j2d_glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                     size, size, size, 0, GL_RGB, GL_FLOAT, lut);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
 * (Re)Initializes the gamma lookup table textures.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
 * The given contrast value is an int in the range [100, 250] which we will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
 * then scale to fit in the range [1.0, 2.5].  We create two LUTs, one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
 * that essentially calculates pow(x, gamma) and the other calculates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
 * pow(x, 1/gamma).  These values are replicated in all three dimensions, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
 * given a single 3D texture coordinate (typically this will be a triplet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
 * in the form (r,g,b)), the 3D texture lookup will return an RGB triplet:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
 *     (pow(r,g), pow(y,g), pow(z,g)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
 * where g is either gamma or 1/gamma, depending on the table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
OGLTR_UpdateLCDTextContrast(jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    double gamma = ((double)contrast) / 100.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    double ig = gamma;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    double g = 1.0 / ig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    GLfloat lut[LUT_EDGE][LUT_EDGE][LUT_EDGE][3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    GLfloat invlut[LUT_EDGE][LUT_EDGE][LUT_EDGE][3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    int min = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    int max = LUT_EDGE - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    int x, y, z;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    J2dTraceLn1(J2D_TRACE_INFO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                "OGLTR_UpdateLCDTextContrast: contrast=%d", contrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    for (z = min; z <= max; z++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        double zval = ((double)z) / max;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        GLfloat gz = (GLfloat)pow(zval, g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        GLfloat igz = (GLfloat)pow(zval, ig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        for (y = min; y <= max; y++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            double yval = ((double)y) / max;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            GLfloat gy = (GLfloat)pow(yval, g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            GLfloat igy = (GLfloat)pow(yval, ig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            for (x = min; x <= max; x++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                double xval = ((double)x) / max;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                GLfloat gx = (GLfloat)pow(xval, g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                GLfloat igx = (GLfloat)pow(xval, ig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                lut[z][y][x][0] = gx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                lut[z][y][x][1] = gy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                lut[z][y][x][2] = gz;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                invlut[z][y][x][0] = igx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                invlut[z][y][x][1] = igy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                invlut[z][y][x][2] = igz;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    if (gammaLutTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        gammaLutTextureID = OGLTR_InitGammaLutTexture();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    OGLTR_UpdateGammaLutTexture(gammaLutTextureID, (GLfloat *)lut, LUT_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    if (invGammaLutTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        invGammaLutTextureID = OGLTR_InitGammaLutTexture();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    OGLTR_UpdateGammaLutTexture(invGammaLutTextureID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                                (GLfloat *)invlut, LUT_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
 * Updates the current gamma-adjusted source color ("src_adj") of the LCD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
 * text shader program.  Note that we could calculate this value in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
 * shader (e.g. just as we do for "dst_adj"), but would be unnecessary work
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
 * (and a measurable performance hit, maybe around 5%) since this value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
 * constant over the entire glyph list.  So instead we just calculate the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
 * gamma-adjusted value once and update the uniform parameter of the LCD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
 * shader as needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
OGLTR_UpdateLCDTextColor(jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    double gamma = ((double)contrast) / 100.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    GLfloat radj, gadj, badj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    GLfloat clr[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    J2dTraceLn1(J2D_TRACE_INFO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                "OGLTR_UpdateLCDTextColor: contrast=%d", contrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     * Note: Ideally we would update the "src_adj" uniform parameter only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     * when there is a change in the source color.  Fortunately, the cost
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * of querying the current OpenGL color state and updating the uniform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * value is quite small, and in the common case we only need to do this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * once per GlyphList, so we gain little from trying to optimize too
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * eagerly here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    // get the current OpenGL primary color state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    j2d_glGetFloatv(GL_CURRENT_COLOR, clr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    // gamma adjust the primary color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    radj = (GLfloat)pow(clr[0], gamma);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    gadj = (GLfloat)pow(clr[1], gamma);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    badj = (GLfloat)pow(clr[2], gamma);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    // update the "src_adj" parameter of the shader program with this value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "src_adj");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    j2d_glUniform3fARB(loc, radj, gadj, badj);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
 * Enables the LCD text shader and updates any related state, such as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
 * gamma lookup table textures.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
OGLTR_EnableLCDGlyphModeState(GLuint glyphTextureID, jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    // bind the texture containing glyph data to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    j2d_glBindTexture(GL_TEXTURE_2D, glyphTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    // bind the texture tile containing destination data to texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    if (cachedDestTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        cachedDestTextureID =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            OGLContext_CreateBlitTexture(GL_RGB8, GL_RGB,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                                         OGLTR_CACHED_DEST_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                                         OGLTR_CACHED_DEST_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        if (cachedDestTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    j2d_glBindTexture(GL_TEXTURE_2D, cachedDestTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    // note that GL_TEXTURE_2D was already enabled for texture unit 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    // but we need to explicitly enable it for texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    j2d_glEnable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    // create the LCD text shader, if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
    if (lcdTextProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        lcdTextProgram = OGLTR_CreateLCDTextProgram();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        if (lcdTextProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    // enable the LCD text shader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
    j2d_glUseProgramObjectARB(lcdTextProgram);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    // update the current contrast settings, if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    if (lastLCDContrast != contrast) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        if (!OGLTR_UpdateLCDTextContrast(contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        lastLCDContrast = contrast;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    // update the current color settings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    if (!OGLTR_UpdateLCDTextColor(contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    // bind the gamma LUT textures
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    j2d_glActiveTextureARB(GL_TEXTURE2_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    j2d_glBindTexture(GL_TEXTURE_3D, invGammaLutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    j2d_glEnable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    j2d_glActiveTextureARB(GL_TEXTURE3_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    j2d_glBindTexture(GL_TEXTURE_3D, gammaLutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    j2d_glEnable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
OGLTR_EnableGlyphVertexCache(OGLContext *oglc)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_EnableGlyphVertexCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
12652
6fddf8394164 7168550: [macosx] duplicate OGL context state changes related to vertex cache
dcherepanov
parents: 12047
diff changeset
   581
    if (!OGLVertexCache_InitVertexCache(oglc)) {
6fddf8394164 7168550: [macosx] duplicate OGL context state changes related to vertex cache
dcherepanov
parents: 12047
diff changeset
   582
        return;
6fddf8394164 7168550: [macosx] duplicate OGL context state changes related to vertex cache
dcherepanov
parents: 12047
diff changeset
   583
    }
6fddf8394164 7168550: [macosx] duplicate OGL context state changes related to vertex cache
dcherepanov
parents: 12047
diff changeset
   584
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    if (glyphCache == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        if (!OGLTR_InitGlyphCache(JNI_FALSE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    j2d_glEnable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    j2d_glBindTexture(GL_TEXTURE_2D, glyphCache->cacheID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    // for grayscale/monochrome text, the current OpenGL source color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    // is modulated with the glyph image as part of the texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    // application stage, so we use GL_MODULATE here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
OGLTR_DisableGlyphVertexCache(OGLContext *oglc)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_DisableGlyphVertexCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    OGLVertexCache_FlushVertexCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    OGLVertexCache_RestoreColorState(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    j2d_glDisable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
 * Disables any pending state associated with the current "glyph mode".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
OGLTR_DisableGlyphModeState()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    switch (glyphMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    case MODE_NO_CACHE_LCD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        /* FALLTHROUGH */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    case MODE_USE_CACHE_LCD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        j2d_glUseProgramObjectARB(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        j2d_glActiveTextureARB(GL_TEXTURE3_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        j2d_glDisable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        j2d_glActiveTextureARB(GL_TEXTURE2_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        j2d_glDisable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        j2d_glDisable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    case MODE_NO_CACHE_GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    case MODE_USE_CACHE_GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    case MODE_NOT_INITED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
OGLTR_DrawGrayscaleGlyphViaCache(OGLContext *oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                                 GlyphInfo *ginfo, jint x, jint y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    CacheCellInfo *cell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    jfloat x1, y1, x2, y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    if (glyphMode != MODE_USE_CACHE_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        CHECK_PREVIOUS_OP(OGL_STATE_GLYPH_OP);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        glyphMode = MODE_USE_CACHE_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        // attempt to add glyph to accelerated glyph cache
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        OGLTR_AddToGlyphCache(ginfo, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            // we'll just no-op in the rare case that the cell is NULL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   672
    cell = (CacheCellInfo *) (ginfo->cellInfo);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    cell->timesRendered++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    x1 = (jfloat)x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    y1 = (jfloat)y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    x2 = x1 + ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    y2 = y1 + ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    OGLVertexCache_AddGlyphQuad(oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                                cell->tx1, cell->ty1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                                cell->tx2, cell->ty2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                                x1, y1, x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
 * Evaluates to true if the rectangle defined by gx1/gy1/gx2/gy2 is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
 * inside outerBounds.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
#define INSIDE(gx1, gy1, gx2, gy2, outerBounds) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    (((gx1) >= outerBounds.x1) && ((gy1) >= outerBounds.y1) && \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     ((gx2) <= outerBounds.x2) && ((gy2) <= outerBounds.y2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
 * Evaluates to true if the rectangle defined by gx1/gy1/gx2/gy2 intersects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
 * the rectangle defined by bounds.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
#define INTERSECTS(gx1, gy1, gx2, gy2, bounds) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    ((bounds.x2 > (gx1)) && (bounds.y2 > (gy1)) && \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     (bounds.x1 < (gx2)) && (bounds.y1 < (gy2)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
 * This method checks to see if the given LCD glyph bounds fall within the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
 * cached destination texture bounds.  If so, this method can return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
 * immediately.  If not, this method will copy a chunk of framebuffer data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
 * into the cached destination texture and then update the current cached
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
 * destination bounds before returning.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
OGLTR_UpdateCachedDestination(OGLSDOps *dstOps, GlyphInfo *ginfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                              jint gx1, jint gy1, jint gx2, jint gy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                              jint glyphIndex, jint totalGlyphs)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    jint dx1, dy1, dx2, dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
    jint dx1adj, dy1adj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
    if (isCachedDestValid && INSIDE(gx1, gy1, gx2, gy2, cachedDestBounds)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        // glyph is already within the cached destination bounds; no need
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        // to read back the entire destination region again, but we do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        // need to see if the current glyph overlaps the previous glyph...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        if (INTERSECTS(gx1, gy1, gx2, gy2, previousGlyphBounds)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            // the current glyph overlaps the destination region touched
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            // by the previous glyph, so now we need to read back the part
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            // of the destination corresponding to the previous glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
            dx1 = previousGlyphBounds.x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            dy1 = previousGlyphBounds.y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            dx2 = previousGlyphBounds.x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            dy2 = previousGlyphBounds.y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            // this accounts for lower-left origin of the destination region
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            dx1adj = dstOps->xOffset + dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            dy1adj = dstOps->yOffset + dstOps->height - dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            // copy destination into subregion of cached texture tile:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            //   dx1-cachedDestBounds.x1 == +xoffset from left side of texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            //   cachedDestBounds.y2-dy2 == +yoffset from bottom of texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                                    dx1 - cachedDestBounds.x1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                                    cachedDestBounds.y2 - dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                                    dx1adj, dy1adj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                                    dx2-dx1, dy2-dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        jint remainingWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        // destination region is not valid, so we need to read back a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        // chunk of the destination into our cached texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        // position the upper-left corner of the destination region on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        // "top" line of glyph list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        // REMIND: this isn't ideal; it would be better if we had some idea
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        //         of the bounding box of the whole glyph list (this is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        //         do-able, but would require iterating through the whole
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        //         list up front, which may present its own problems)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        dx1 = gx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        dy1 = gy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        if (ginfo->advanceX > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            // estimate the width based on our current position in the glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            // list and using the x advance of the current glyph (this is just
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            // a quick and dirty heuristic; if this is a "thin" glyph image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            // then we're likely to underestimate, and if it's "thick" then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            // may end up reading back more than we need to)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            remainingWidth =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                (jint)(ginfo->advanceX * (totalGlyphs - glyphIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            if (remainingWidth > OGLTR_CACHED_DEST_WIDTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                remainingWidth = OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            } else if (remainingWidth < ginfo->width) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                // in some cases, the x-advance may be slightly smaller
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                // than the actual width of the glyph; if so, adjust our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                // estimate so that we can accomodate the entire glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                remainingWidth = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            // a negative advance is possible when rendering rotated text,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            // in which case it is difficult to estimate an appropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            // region for readback, so we will pick a region that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            // encompasses just the current glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            remainingWidth = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        dx2 = dx1 + remainingWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        // estimate the height (this is another sloppy heuristic; we'll
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        // make the cached destination region tall enough to encompass most
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        // glyphs that are small enough to fit in the glyph cache, and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        // we add a little something extra to account for descenders
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        dy2 = dy1 + OGLTR_CACHE_CELL_HEIGHT + 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        // this accounts for lower-left origin of the destination region
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        dx1adj = dstOps->xOffset + dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        dy1adj = dstOps->yOffset + dstOps->height - dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        // copy destination into cached texture tile (the lower-left corner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        // of the destination region will be positioned at the lower-left
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        // corner (0,0) of the texture)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                                0, 0, dx1adj, dy1adj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                                dx2-dx1, dy2-dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        // update the cached bounds and mark it valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        cachedDestBounds.x1 = dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        cachedDestBounds.y1 = dy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        cachedDestBounds.x2 = dx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        cachedDestBounds.y2 = dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        isCachedDestValid = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    // always update the previous glyph bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
    previousGlyphBounds.x1 = gx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    previousGlyphBounds.y1 = gy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
    previousGlyphBounds.x2 = gx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    previousGlyphBounds.y2 = gy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
OGLTR_DrawLCDGlyphViaCache(OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                           GlyphInfo *ginfo, jint x, jint y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                           jint glyphIndex, jint totalGlyphs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                           jboolean rgbOrder, jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    CacheCellInfo *cell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
    jint dx1, dy1, dx2, dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    jfloat dtx1, dty1, dtx2, dty2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    if (glyphMode != MODE_USE_CACHE_LCD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        CHECK_PREVIOUS_OP(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        if (glyphCache == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
            if (!OGLTR_InitGlyphCache(JNI_TRUE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        if (rgbOrder != lastRGBOrder) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            // need to invalidate the cache in this case; see comments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            // for lastRGBOrder above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            AccelGlyphCache_Invalidate(glyphCache);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            lastRGBOrder = rgbOrder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        if (!OGLTR_EnableLCDGlyphModeState(glyphCache->cacheID, contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        // when a fragment shader is enabled, the texture function state is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        // ignored, so the following line is not needed...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        // OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        glyphMode = MODE_USE_CACHE_LCD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        // rowBytes will always be a multiple of 3, so the following is safe
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, ginfo->rowBytes / 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        // make sure the glyph cache texture is bound to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
        // attempt to add glyph to accelerated glyph cache
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        OGLTR_AddToGlyphCache(ginfo, rgbOrder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
            // we'll just no-op in the rare case that the cell is NULL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   875
    cell = (CacheCellInfo *) (ginfo->cellInfo);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
    cell->timesRendered++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
    // location of the glyph in the destination's coordinate space
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
    dx1 = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    dy1 = y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
    dx2 = dx1 + ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
    dy2 = dy1 + ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    // copy destination into second cached texture, if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    OGLTR_UpdateCachedDestination(dstOps, ginfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                                  dx1, dy1, dx2, dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                                  glyphIndex, totalGlyphs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    // texture coordinates of the destination tile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
    dtx1 = ((jfloat)(dx1 - cachedDestBounds.x1)) / OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    dty1 = ((jfloat)(cachedDestBounds.y2 - dy1)) / OGLTR_CACHED_DEST_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
    dtx2 = ((jfloat)(dx2 - cachedDestBounds.x1)) / OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    dty2 = ((jfloat)(cachedDestBounds.y2 - dy2)) / OGLTR_CACHED_DEST_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    // render composed texture to the destination surface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    j2d_glBegin(GL_QUADS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx1, cell->ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
    j2d_glVertex2i(dx1, dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx2, cell->ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    j2d_glVertex2i(dx2, dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx2, cell->ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    j2d_glVertex2i(dx2, dy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx1, cell->ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    j2d_glVertex2i(dx1, dy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
    j2d_glEnd();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
OGLTR_DrawGrayscaleGlyphNoCache(OGLContext *oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                                GlyphInfo *ginfo, jint x, jint y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
    jint tw, th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    jint sx, sy, sw, sh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    jint x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    jint w = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    jint h = ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
    if (glyphMode != MODE_NO_CACHE_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        CHECK_PREVIOUS_OP(OGL_STATE_MASK_OP);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
        glyphMode = MODE_NO_CACHE_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
    x0 = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    tw = OGLVC_MASK_CACHE_TILE_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    th = OGLVC_MASK_CACHE_TILE_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    for (sy = 0; sy < h; sy += th, y += th) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        x = x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        sh = ((sy + th) > h) ? (h - sy) : th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        for (sx = 0; sx < w; sx += tw, x += tw) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
            sw = ((sx + tw) > w) ? (w - sx) : tw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            OGLVertexCache_AddMaskQuad(oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
                                       sx, sy, x, y, sw, sh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
                                       w, ginfo->image);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
OGLTR_DrawLCDGlyphNoCache(OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
                          GlyphInfo *ginfo, jint x, jint y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
                          jint rowBytesOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
                          jboolean rgbOrder, jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
    GLfloat tx1, ty1, tx2, ty2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    GLfloat dtx1, dty1, dtx2, dty2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
    jint tw, th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    jint sx, sy, sw, sh, dxadj, dyadj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    jint x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
    jint w = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
    jint h = ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
    GLenum pixelFormat = rgbOrder ? GL_RGB : GL_BGR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    if (glyphMode != MODE_NO_CACHE_LCD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        CHECK_PREVIOUS_OP(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
        if (oglc->blitTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
            if (!OGLContext_InitBlitTileTexture(oglc)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
                return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        if (!OGLTR_EnableLCDGlyphModeState(oglc->blitTextureID, contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        // when a fragment shader is enabled, the texture function state is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        // ignored, so the following line is not needed...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
        // OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
        glyphMode = MODE_NO_CACHE_LCD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    // rowBytes will always be a multiple of 3, so the following is safe
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, ginfo->rowBytes / 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
    x0 = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    tx1 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    ty1 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    dtx1 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    dty2 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    tw = OGLTR_NOCACHE_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
    th = OGLTR_NOCACHE_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
    for (sy = 0; sy < h; sy += th, y += th) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
        x = x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        sh = ((sy + th) > h) ? (h - sy) : th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        for (sx = 0; sx < w; sx += tw, x += tw) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
            sw = ((sx + tw) > w) ? (w - sx) : tw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
            // update the source pointer offsets
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
            j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
            // copy LCD mask into glyph texture tile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                                0, 0, sw, sh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
                                pixelFormat, GL_UNSIGNED_BYTE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                                ginfo->image + rowBytesOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
            // update the lower-right glyph texture coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            tx2 = ((GLfloat)sw) / OGLC_BLIT_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
            ty2 = ((GLfloat)sh) / OGLC_BLIT_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            // this accounts for lower-left origin of the destination region
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
            dxadj = dstOps->xOffset + x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
            dyadj = dstOps->yOffset + dstOps->height - (y + sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
            // copy destination into cached texture tile (the lower-left
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            // corner of the destination region will be positioned at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            // lower-left corner (0,0) of the texture)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
            j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
                                    0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                                    dxadj, dyadj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                                    sw, sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            // update the remaining destination texture coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            dtx2 = ((GLfloat)sw) / OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            dty1 = ((GLfloat)sh) / OGLTR_CACHED_DEST_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
            // render composed texture to the destination surface
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
            j2d_glBegin(GL_QUADS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx1, ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            j2d_glVertex2i(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx2, ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            j2d_glVertex2i(x + sw, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx2, ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
            j2d_glVertex2i(x + sw, y + sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx1, ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            j2d_glVertex2i(x, y + sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
            j2d_glEnd();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
// see DrawGlyphList.c for more on this macro...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
#define FLOOR_ASSIGN(l, r) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
    if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
OGLTR_DrawGlyphList(JNIEnv *env, OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                    jint totalGlyphs, jboolean usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                    jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                    jfloat glyphListOrigX, jfloat glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                    unsigned char *images, unsigned char *positions)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    int glyphCounter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_DrawGlyphList");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
    RETURN_IF_NULL(dstOps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    RETURN_IF_NULL(images);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
    if (usePositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
        RETURN_IF_NULL(positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
    glyphMode = MODE_NOT_INITED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
    isCachedDestValid = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
    for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
        jint x, y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        jfloat glyphx, glyphy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        jboolean grayscale, ok;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
        GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(NEXT_LONG(images));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
        if (ginfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
            // this shouldn't happen, but if it does we'll just break out...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
            J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                          "OGLTR_DrawGlyphList: glyph info is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
        grayscale = (ginfo->rowBytes == ginfo->width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        if (usePositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            jfloat posx = NEXT_FLOAT(positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            jfloat posy = NEXT_FLOAT(positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            glyphx = glyphListOrigX + posx + ginfo->topLeftX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
            glyphy = glyphListOrigY + posy + ginfo->topLeftY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
            FLOOR_ASSIGN(x, glyphx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
            FLOOR_ASSIGN(y, glyphy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
            glyphx = glyphListOrigX + ginfo->topLeftX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
            glyphy = glyphListOrigY + ginfo->topLeftY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
            FLOOR_ASSIGN(x, glyphx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
            FLOOR_ASSIGN(y, glyphy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
            glyphListOrigX += ginfo->advanceX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
            glyphListOrigY += ginfo->advanceY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
        if (ginfo->image == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
            continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
        if (grayscale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
            // grayscale or monochrome glyph data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
            if (cacheStatus != CACHE_LCD &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
                ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                ok = OGLTR_DrawGrayscaleGlyphViaCache(oglc, ginfo, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
                ok = OGLTR_DrawGrayscaleGlyphNoCache(oglc, ginfo, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
            // LCD-optimized glyph data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
            jint rowBytesOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
            if (subPixPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
                jint frac = (jint)((glyphx - x) * 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                if (frac != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                    rowBytesOffset = 3 - frac;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                    x += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
            if (rowBytesOffset == 0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
                cacheStatus != CACHE_GRAY &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
                ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                ok = OGLTR_DrawLCDGlyphViaCache(oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                                                ginfo, x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                                                glyphCounter, totalGlyphs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                                                rgbOrder, lcdContrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
                ok = OGLTR_DrawLCDGlyphNoCache(oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                                               ginfo, x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                                               rowBytesOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                                               rgbOrder, lcdContrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
        if (!ok) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
Java_sun_java2d_opengl_OGLTextRenderer_drawGlyphList
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
    (JNIEnv *env, jobject self,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
     jint numGlyphs, jboolean usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
     jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
     jfloat glyphListOrigX, jfloat glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
     jlongArray imgArray, jfloatArray posArray)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    unsigned char *images;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    J2dTraceLn(J2D_TRACE_INFO, "OGLTextRenderer_drawGlyphList");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    images = (unsigned char *)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        (*env)->GetPrimitiveArrayCritical(env, imgArray, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
    if (images != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        OGLContext *oglc = OGLRenderQueue_GetCurrentContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        OGLSDOps *dstOps = OGLRenderQueue_GetCurrentDestination();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
        if (usePositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
            unsigned char *positions = (unsigned char *)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                (*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
            if (positions != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                OGLTR_DrawGlyphList(env, oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                                    numGlyphs, usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                                    subPixPos, rgbOrder, lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                                    glyphListOrigX, glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                                    images, positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
                (*env)->ReleasePrimitiveArrayCritical(env, posArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                                                      positions, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            OGLTR_DrawGlyphList(env, oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                                numGlyphs, usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                                subPixPos, rgbOrder, lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                                glyphListOrigX, glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
                                images, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
        // 6358147: reset current state, and ensure rendering is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
        // flushed to dest
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
        if (oglc != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            RESET_PREVIOUS_OP();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            j2d_glFlush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
        (*env)->ReleasePrimitiveArrayCritical(env, imgArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                                              images, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
#endif /* !HEADLESS */