jdk/src/share/native/sun/java2d/opengl/OGLTextRenderer.c
author michaelm
Tue, 06 Mar 2012 20:34:38 +0000
changeset 12047 320a714614e9
parent 7668 d4a77089c587
child 12652 6fddf8394164
permissions -rw-r--r--
7113349: Initial changeset for Macosx port to jdk Reviewed-by: jjh, alanb, dholmes, anthony, ohrstrom, ksrini, jrose, weijun, smarks Contributed-by: Alan Bateman <alan.bateman@oracle.com>, Alexander Potochkin <alexander.potochkin@oracle.com>, Alexander Zuev <alexander.zuev@oracle.com>, Andrew Brygin <andrew.brygin@oracle.com>, Artem Ananiev <artem.ananiev@oracle.com>, Alex Strange <astrange@apple.com>, Bino George <bino@apple.com>, Christine Lu <christine.lu@oracle.com>, David Katleman <david.katleman@oracle.com>, David Durrence <david_durrence@apple.com>, Dmitry Cherepanov <dmitry.cherepanov@oracle.com>, Greg Lewis <glewis@eyesbeyond.com>, Kevin Miller <kevin_m_miller@apple.com>, Kurt Miller <kurt@intricatesoftware.com>, Landon Fuller <landonf@plausiblelabs.com>, Leonid Romanov <leonid.romanov@oracle.com>, Loefty Walkowiak <loefty@apple.com>, Mark Reinhold <mark.reinhold@oracle.com>, Naoto Sato <naoto.sato@oracle.com>, Philip Race <philip.race@oracle.com>, Roger Hoover <rhoover@apple.com>, Scott Kovatch <scott.kovatch@oracle.com>, Sergey ByloKhov <sergey.bylokhov@oracle.com>, Mike Swingler <swingler@apple.com>, Tomas Hurka <tomas.hurka@oracle.com>
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 vertex cache (if it hasn't been already)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    if (!OGLVertexCache_InitVertexCache()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    // init glyph cache data structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    gcinfo = AccelGlyphCache_Init(OGLTR_CACHE_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                                  OGLTR_CACHE_HEIGHT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                                  OGLTR_CACHE_CELL_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                                  OGLTR_CACHE_CELL_HEIGHT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                                  OGLVertexCache_FlushVertexCache);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    if (gcinfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                      "OGLTR_InitGlyphCache: could not init OGL glyph cache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    // init cache texture object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    j2d_glGenTextures(1, &gcinfo->cacheID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    j2d_glBindTexture(GL_TEXTURE_2D, gcinfo->cacheID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    j2d_glPrioritizeTextures(1, &gcinfo->cacheID, &priority);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    j2d_glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                     OGLTR_CACHE_WIDTH, OGLTR_CACHE_HEIGHT, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                     pixelFormat, GL_UNSIGNED_BYTE, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    cacheStatus = (lcdCache ? CACHE_LCD : CACHE_GRAY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    glyphCache = gcinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
 * Adds the given glyph to the glyph cache (texture and data structure)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
 * associated with the given OGLContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
OGLTR_AddToGlyphCache(GlyphInfo *glyph, jboolean rgbOrder)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    GLenum pixelFormat;
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   247
    CacheCellInfo *ccinfo;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_AddToGlyphCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    if ((glyphCache == NULL) || (glyph->image == NULL)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    if (cacheStatus == CACHE_LCD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        pixelFormat = rgbOrder ? GL_RGB : GL_BGR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        pixelFormat = GL_LUMINANCE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    AccelGlyphCache_AddGlyph(glyphCache, glyph);
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   262
    ccinfo = (CacheCellInfo *) glyph->cellInfo;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   264
    if (ccinfo != NULL) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        // store glyph image in texture cell
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   267
                            ccinfo->x, ccinfo->y,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                            glyph->width, glyph->height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                            pixelFormat, GL_UNSIGNED_BYTE, glyph->image);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
 * This is the GLSL fragment shader source code for rendering LCD-optimized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
 * text.  Do not be frightened; it is much easier to understand than the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
 * equivalent ASM-like fragment program!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
 * The "uniform" variables at the top are initialized once the program is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
 * linked, and are updated at runtime as needed (e.g. when the source color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
 * changes, we will modify the "src_adj" value in OGLTR_UpdateLCDTextColor()).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
 * The "main" function is executed for each "fragment" (or pixel) in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
 * glyph image.  We have determined that the pow() function can be quite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
 * slow and it only operates on scalar values, not vectors as we require.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
 * So instead we build two 3D textures containing gamma (and inverse gamma)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
 * lookup tables that allow us to approximate a component-wise pow() function
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
 * with a single 3D texture lookup.  This approach is at least 2x faster
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
 * than the equivalent pow() calls.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
 * The variables involved in the equation can be expressed as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
 *   Cs = Color component of the source (foreground color) [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
 *   Cd = Color component of the destination (background color) [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
 *   Cr = Color component to be written to the destination [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
 *   Ag = Glyph alpha (aka intensity or coverage) [0.0, 1.0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
 *   Ga = Gamma adjustment in the range [1.0, 2.5]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
 *   (^ means raised to the power)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
 * And here is the theoretical equation approximated by this shader:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
 *            Cr = (Ag*(Cs^Ga) + (1-Ag)*(Cd^Ga)) ^ (1/Ga)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
static const char *lcdTextShaderSource =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    "uniform vec3 src_adj;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    "uniform sampler2D glyph_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    "uniform sampler2D dst_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    "uniform sampler3D invgamma_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    "uniform sampler3D gamma_tex;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    "void main(void)"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    "{"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
         // load the RGB value from the glyph image at the current texcoord
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    "    vec3 glyph_clr = vec3(texture2D(glyph_tex, gl_TexCoord[0].st));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    "    if (glyph_clr == vec3(0.0)) {"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
             // zero coverage, so skip this fragment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    "        discard;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    "    }"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
         // load the RGB value from the corresponding destination pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    "    vec3 dst_clr = vec3(texture2D(dst_tex, gl_TexCoord[1].st));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
         // gamma adjust the dest color using the invgamma LUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    "    vec3 dst_adj = vec3(texture3D(invgamma_tex, dst_clr.stp));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
         // linearly interpolate the three color values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    "    vec3 result = mix(dst_adj, src_adj, glyph_clr);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
         // gamma re-adjust the resulting color (alpha is always set to 1.0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    "    gl_FragColor = vec4(vec3(texture3D(gamma_tex, result.stp)), 1.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    "}";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
 * Compiles and links the LCD text shader program.  If successful, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
 * function returns a handle to the newly created shader program; otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
 * returns 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
static GLhandleARB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
OGLTR_CreateLCDTextProgram()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    GLhandleARB lcdTextProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_CreateLCDTextProgram");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    lcdTextProgram = OGLContext_CreateFragmentProgram(lcdTextShaderSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    if (lcdTextProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                      "OGLTR_CreateLCDTextProgram: error creating program");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    // "use" the program object temporarily so that we can set the uniforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    j2d_glUseProgramObjectARB(lcdTextProgram);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    // set the "uniform" values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "glyph_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    j2d_glUniform1iARB(loc, 0); // texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "dst_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    j2d_glUniform1iARB(loc, 1); // texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "invgamma_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    j2d_glUniform1iARB(loc, 2); // texture unit 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "gamma_tex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    j2d_glUniform1iARB(loc, 3); // texture unit 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
    // "unuse" the program object; it will be re-bound later as needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    j2d_glUseProgramObjectARB(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    return lcdTextProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
 * Initializes a 3D texture object for use as a three-dimensional gamma
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
 * lookup table.  Note that the wrap mode is initialized to GL_LINEAR so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
 * that the table will interpolate adjacent values when the index falls
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
 * somewhere in between.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
static GLuint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
OGLTR_InitGammaLutTexture()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    GLuint lutTextureID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    j2d_glGenTextures(1, &lutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    j2d_glBindTexture(GL_TEXTURE_3D, lutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    j2d_glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    return lutTextureID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
 * Updates the lookup table in the given texture object with the float
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
 * values in the given system memory buffer.  Note that we could use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
 * glTexSubImage3D() when updating the texture after its first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
 * initialization, but since we're updating the entire table (with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
 * power-of-two dimensions) and this is a relatively rare event, we'll
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
 * just stick with glTexImage3D().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
OGLTR_UpdateGammaLutTexture(GLuint texID, GLfloat *lut, jint size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    j2d_glBindTexture(GL_TEXTURE_3D, texID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    j2d_glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                     size, size, size, 0, GL_RGB, GL_FLOAT, lut);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
 * (Re)Initializes the gamma lookup table textures.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
 * The given contrast value is an int in the range [100, 250] which we will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
 * then scale to fit in the range [1.0, 2.5].  We create two LUTs, one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
 * that essentially calculates pow(x, gamma) and the other calculates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
 * pow(x, 1/gamma).  These values are replicated in all three dimensions, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
 * given a single 3D texture coordinate (typically this will be a triplet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
 * in the form (r,g,b)), the 3D texture lookup will return an RGB triplet:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
 *     (pow(r,g), pow(y,g), pow(z,g)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
 * where g is either gamma or 1/gamma, depending on the table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
OGLTR_UpdateLCDTextContrast(jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    double gamma = ((double)contrast) / 100.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    double ig = gamma;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    double g = 1.0 / ig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    GLfloat lut[LUT_EDGE][LUT_EDGE][LUT_EDGE][3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    GLfloat invlut[LUT_EDGE][LUT_EDGE][LUT_EDGE][3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    int min = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    int max = LUT_EDGE - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    int x, y, z;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    J2dTraceLn1(J2D_TRACE_INFO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                "OGLTR_UpdateLCDTextContrast: contrast=%d", contrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    for (z = min; z <= max; z++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        double zval = ((double)z) / max;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        GLfloat gz = (GLfloat)pow(zval, g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        GLfloat igz = (GLfloat)pow(zval, ig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        for (y = min; y <= max; y++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            double yval = ((double)y) / max;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            GLfloat gy = (GLfloat)pow(yval, g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            GLfloat igy = (GLfloat)pow(yval, ig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            for (x = min; x <= max; x++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                double xval = ((double)x) / max;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                GLfloat gx = (GLfloat)pow(xval, g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                GLfloat igx = (GLfloat)pow(xval, ig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                lut[z][y][x][0] = gx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                lut[z][y][x][1] = gy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                lut[z][y][x][2] = gz;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                invlut[z][y][x][0] = igx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                invlut[z][y][x][1] = igy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                invlut[z][y][x][2] = igz;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    if (gammaLutTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        gammaLutTextureID = OGLTR_InitGammaLutTexture();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    OGLTR_UpdateGammaLutTexture(gammaLutTextureID, (GLfloat *)lut, LUT_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    if (invGammaLutTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        invGammaLutTextureID = OGLTR_InitGammaLutTexture();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    OGLTR_UpdateGammaLutTexture(invGammaLutTextureID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                                (GLfloat *)invlut, LUT_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
 * Updates the current gamma-adjusted source color ("src_adj") of the LCD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
 * text shader program.  Note that we could calculate this value in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
 * shader (e.g. just as we do for "dst_adj"), but would be unnecessary work
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
 * (and a measurable performance hit, maybe around 5%) since this value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
 * constant over the entire glyph list.  So instead we just calculate the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
 * gamma-adjusted value once and update the uniform parameter of the LCD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
 * shader as needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
OGLTR_UpdateLCDTextColor(jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    double gamma = ((double)contrast) / 100.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    GLfloat radj, gadj, badj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    GLfloat clr[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    J2dTraceLn1(J2D_TRACE_INFO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                "OGLTR_UpdateLCDTextColor: contrast=%d", contrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * Note: Ideally we would update the "src_adj" uniform parameter only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * when there is a change in the source color.  Fortunately, the cost
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * of querying the current OpenGL color state and updating the uniform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * value is quite small, and in the common case we only need to do this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     * once per GlyphList, so we gain little from trying to optimize too
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * eagerly here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    // get the current OpenGL primary color state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    j2d_glGetFloatv(GL_CURRENT_COLOR, clr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    // gamma adjust the primary color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    radj = (GLfloat)pow(clr[0], gamma);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    gadj = (GLfloat)pow(clr[1], gamma);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    badj = (GLfloat)pow(clr[2], gamma);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    // update the "src_adj" parameter of the shader program with this value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    loc = j2d_glGetUniformLocationARB(lcdTextProgram, "src_adj");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    j2d_glUniform3fARB(loc, radj, gadj, badj);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
 * Enables the LCD text shader and updates any related state, such as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
 * gamma lookup table textures.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
OGLTR_EnableLCDGlyphModeState(GLuint glyphTextureID, jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    // bind the texture containing glyph data to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
    j2d_glBindTexture(GL_TEXTURE_2D, glyphTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
    // bind the texture tile containing destination data to texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
    if (cachedDestTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        cachedDestTextureID =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            OGLContext_CreateBlitTexture(GL_RGB8, GL_RGB,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                                         OGLTR_CACHED_DEST_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                                         OGLTR_CACHED_DEST_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        if (cachedDestTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
    j2d_glBindTexture(GL_TEXTURE_2D, cachedDestTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
    // note that GL_TEXTURE_2D was already enabled for texture unit 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    // but we need to explicitly enable it for texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
    j2d_glEnable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
    // create the LCD text shader, if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    if (lcdTextProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        lcdTextProgram = OGLTR_CreateLCDTextProgram();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        if (lcdTextProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    // enable the LCD text shader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
    j2d_glUseProgramObjectARB(lcdTextProgram);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
    // update the current contrast settings, if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    if (lastLCDContrast != contrast) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        if (!OGLTR_UpdateLCDTextContrast(contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        lastLCDContrast = contrast;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    // update the current color settings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    if (!OGLTR_UpdateLCDTextColor(contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    // bind the gamma LUT textures
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    j2d_glActiveTextureARB(GL_TEXTURE2_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
    j2d_glBindTexture(GL_TEXTURE_3D, invGammaLutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    j2d_glEnable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    j2d_glActiveTextureARB(GL_TEXTURE3_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    j2d_glBindTexture(GL_TEXTURE_3D, gammaLutTextureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    j2d_glEnable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
OGLTR_EnableGlyphVertexCache(OGLContext *oglc)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_EnableGlyphVertexCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    if (glyphCache == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        if (!OGLTR_InitGlyphCache(JNI_FALSE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    j2d_glEnable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    j2d_glBindTexture(GL_TEXTURE_2D, glyphCache->cacheID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    // for grayscale/monochrome text, the current OpenGL source color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    // is modulated with the glyph image as part of the texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    // application stage, so we use GL_MODULATE here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
OGLTR_DisableGlyphVertexCache(OGLContext *oglc)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_DisableGlyphVertexCache");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    OGLVertexCache_FlushVertexCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    OGLVertexCache_RestoreColorState(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    j2d_glDisable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
 * Disables any pending state associated with the current "glyph mode".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
OGLTR_DisableGlyphModeState()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    switch (glyphMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    case MODE_NO_CACHE_LCD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        /* FALLTHROUGH */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    case MODE_USE_CACHE_LCD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        j2d_glUseProgramObjectARB(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        j2d_glActiveTextureARB(GL_TEXTURE3_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        j2d_glDisable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        j2d_glActiveTextureARB(GL_TEXTURE2_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        j2d_glDisable(GL_TEXTURE_3D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        j2d_glDisable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    case MODE_NO_CACHE_GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    case MODE_USE_CACHE_GRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    case MODE_NOT_INITED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
OGLTR_DrawGrayscaleGlyphViaCache(OGLContext *oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                                 GlyphInfo *ginfo, jint x, jint y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    CacheCellInfo *cell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    jfloat x1, y1, x2, y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    if (glyphMode != MODE_USE_CACHE_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        CHECK_PREVIOUS_OP(OGL_STATE_GLYPH_OP);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        glyphMode = MODE_USE_CACHE_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        // attempt to add glyph to accelerated glyph cache
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        OGLTR_AddToGlyphCache(ginfo, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            // we'll just no-op in the rare case that the cell is NULL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   673
    cell = (CacheCellInfo *) (ginfo->cellInfo);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    cell->timesRendered++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    x1 = (jfloat)x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    y1 = (jfloat)y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    x2 = x1 + ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    y2 = y1 + ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    OGLVertexCache_AddGlyphQuad(oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                                cell->tx1, cell->ty1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                                cell->tx2, cell->ty2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                                x1, y1, x2, y2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
 * Evaluates to true if the rectangle defined by gx1/gy1/gx2/gy2 is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
 * inside outerBounds.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
#define INSIDE(gx1, gy1, gx2, gy2, outerBounds) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    (((gx1) >= outerBounds.x1) && ((gy1) >= outerBounds.y1) && \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     ((gx2) <= outerBounds.x2) && ((gy2) <= outerBounds.y2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
 * Evaluates to true if the rectangle defined by gx1/gy1/gx2/gy2 intersects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
 * the rectangle defined by bounds.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
#define INTERSECTS(gx1, gy1, gx2, gy2, bounds) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    ((bounds.x2 > (gx1)) && (bounds.y2 > (gy1)) && \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     (bounds.x1 < (gx2)) && (bounds.y1 < (gy2)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
 * This method checks to see if the given LCD glyph bounds fall within the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
 * cached destination texture bounds.  If so, this method can return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
 * immediately.  If not, this method will copy a chunk of framebuffer data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
 * into the cached destination texture and then update the current cached
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
 * destination bounds before returning.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
OGLTR_UpdateCachedDestination(OGLSDOps *dstOps, GlyphInfo *ginfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                              jint gx1, jint gy1, jint gx2, jint gy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                              jint glyphIndex, jint totalGlyphs)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
    jint dx1, dy1, dx2, dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    jint dx1adj, dy1adj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    if (isCachedDestValid && INSIDE(gx1, gy1, gx2, gy2, cachedDestBounds)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        // glyph is already within the cached destination bounds; no need
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        // to read back the entire destination region again, but we do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        // need to see if the current glyph overlaps the previous glyph...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        if (INTERSECTS(gx1, gy1, gx2, gy2, previousGlyphBounds)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            // the current glyph overlaps the destination region touched
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            // by the previous glyph, so now we need to read back the part
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
            // of the destination corresponding to the previous glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            dx1 = previousGlyphBounds.x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            dy1 = previousGlyphBounds.y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            dx2 = previousGlyphBounds.x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            dy2 = previousGlyphBounds.y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            // this accounts for lower-left origin of the destination region
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            dx1adj = dstOps->xOffset + dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            dy1adj = dstOps->yOffset + dstOps->height - dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            // copy destination into subregion of cached texture tile:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            //   dx1-cachedDestBounds.x1 == +xoffset from left side of texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            //   cachedDestBounds.y2-dy2 == +yoffset from bottom of texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                                    dx1 - cachedDestBounds.x1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                                    cachedDestBounds.y2 - dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                                    dx1adj, dy1adj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                                    dx2-dx1, dy2-dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        jint remainingWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        // destination region is not valid, so we need to read back a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        // chunk of the destination into our cached texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        // position the upper-left corner of the destination region on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        // "top" line of glyph list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        // REMIND: this isn't ideal; it would be better if we had some idea
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        //         of the bounding box of the whole glyph list (this is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        //         do-able, but would require iterating through the whole
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        //         list up front, which may present its own problems)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        dx1 = gx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        dy1 = gy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        if (ginfo->advanceX > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            // estimate the width based on our current position in the glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            // list and using the x advance of the current glyph (this is just
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            // a quick and dirty heuristic; if this is a "thin" glyph image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            // then we're likely to underestimate, and if it's "thick" then we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            // may end up reading back more than we need to)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            remainingWidth =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                (jint)(ginfo->advanceX * (totalGlyphs - glyphIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            if (remainingWidth > OGLTR_CACHED_DEST_WIDTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                remainingWidth = OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            } else if (remainingWidth < ginfo->width) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                // in some cases, the x-advance may be slightly smaller
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                // than the actual width of the glyph; if so, adjust our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                // estimate so that we can accomodate the entire glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                remainingWidth = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            // a negative advance is possible when rendering rotated text,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            // in which case it is difficult to estimate an appropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            // region for readback, so we will pick a region that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            // encompasses just the current glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            remainingWidth = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        dx2 = dx1 + remainingWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        // estimate the height (this is another sloppy heuristic; we'll
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        // make the cached destination region tall enough to encompass most
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        // glyphs that are small enough to fit in the glyph cache, and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        // we add a little something extra to account for descenders
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        dy2 = dy1 + OGLTR_CACHE_CELL_HEIGHT + 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        // this accounts for lower-left origin of the destination region
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        dx1adj = dstOps->xOffset + dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        dy1adj = dstOps->yOffset + dstOps->height - dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        // copy destination into cached texture tile (the lower-left corner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        // of the destination region will be positioned at the lower-left
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        // corner (0,0) of the texture)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
        j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                                0, 0, dx1adj, dy1adj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                                dx2-dx1, dy2-dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        // update the cached bounds and mark it valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        cachedDestBounds.x1 = dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        cachedDestBounds.y1 = dy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        cachedDestBounds.x2 = dx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        cachedDestBounds.y2 = dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        isCachedDestValid = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
    // always update the previous glyph bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    previousGlyphBounds.x1 = gx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
    previousGlyphBounds.y1 = gy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    previousGlyphBounds.x2 = gx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
    previousGlyphBounds.y2 = gy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
OGLTR_DrawLCDGlyphViaCache(OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                           GlyphInfo *ginfo, jint x, jint y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                           jint glyphIndex, jint totalGlyphs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                           jboolean rgbOrder, jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
    CacheCellInfo *cell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    jint dx1, dy1, dx2, dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
    jfloat dtx1, dty1, dtx2, dty2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    if (glyphMode != MODE_USE_CACHE_LCD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        CHECK_PREVIOUS_OP(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        if (glyphCache == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            if (!OGLTR_InitGlyphCache(JNI_TRUE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
        if (rgbOrder != lastRGBOrder) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            // need to invalidate the cache in this case; see comments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            // for lastRGBOrder above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            AccelGlyphCache_Invalidate(glyphCache);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            lastRGBOrder = rgbOrder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        if (!OGLTR_EnableLCDGlyphModeState(glyphCache->cacheID, contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        // when a fragment shader is enabled, the texture function state is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        // ignored, so the following line is not needed...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        // OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        glyphMode = MODE_USE_CACHE_LCD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
    if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        // rowBytes will always be a multiple of 3, so the following is safe
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, ginfo->rowBytes / 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        // make sure the glyph cache texture is bound to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        // attempt to add glyph to accelerated glyph cache
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
        OGLTR_AddToGlyphCache(ginfo, rgbOrder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        if (ginfo->cellInfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            // we'll just no-op in the rare case that the cell is NULL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
5579
1a5e995a710b 6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents: 2
diff changeset
   876
    cell = (CacheCellInfo *) (ginfo->cellInfo);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
    cell->timesRendered++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
    // location of the glyph in the destination's coordinate space
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    dx1 = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
    dy1 = y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
    dx2 = dx1 + ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    dy2 = dy1 + ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    // copy destination into second cached texture, if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
    OGLTR_UpdateCachedDestination(dstOps, ginfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                                  dx1, dy1, dx2, dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                                  glyphIndex, totalGlyphs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
    // texture coordinates of the destination tile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    dtx1 = ((jfloat)(dx1 - cachedDestBounds.x1)) / OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
    dty1 = ((jfloat)(cachedDestBounds.y2 - dy1)) / OGLTR_CACHED_DEST_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    dtx2 = ((jfloat)(dx2 - cachedDestBounds.x1)) / OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    dty2 = ((jfloat)(cachedDestBounds.y2 - dy2)) / OGLTR_CACHED_DEST_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    // render composed texture to the destination surface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    j2d_glBegin(GL_QUADS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx1, cell->ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    j2d_glVertex2i(dx1, dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx2, cell->ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    j2d_glVertex2i(dx2, dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx2, cell->ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    j2d_glVertex2i(dx2, dy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, cell->tx1, cell->ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
    j2d_glVertex2i(dx1, dy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    j2d_glEnd();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
OGLTR_DrawGrayscaleGlyphNoCache(OGLContext *oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                                GlyphInfo *ginfo, jint x, jint y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    jint tw, th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    jint sx, sy, sw, sh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    jint x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    jint w = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    jint h = ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    if (glyphMode != MODE_NO_CACHE_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
        CHECK_PREVIOUS_OP(OGL_STATE_MASK_OP);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
        glyphMode = MODE_NO_CACHE_GRAY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    x0 = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    tw = OGLVC_MASK_CACHE_TILE_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    th = OGLVC_MASK_CACHE_TILE_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
    for (sy = 0; sy < h; sy += th, y += th) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        x = x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        sh = ((sy + th) > h) ? (h - sy) : th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
        for (sx = 0; sx < w; sx += tw, x += tw) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
            sw = ((sx + tw) > w) ? (w - sx) : tw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            OGLVertexCache_AddMaskQuad(oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
                                       sx, sy, x, y, sw, sh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
                                       w, ginfo->image);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
OGLTR_DrawLCDGlyphNoCache(OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
                          GlyphInfo *ginfo, jint x, jint y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
                          jint rowBytesOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
                          jboolean rgbOrder, jint contrast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    GLfloat tx1, ty1, tx2, ty2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
    GLfloat dtx1, dty1, dtx2, dty2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    jint tw, th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    jint sx, sy, sw, sh, dxadj, dyadj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
    jint x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
    jint w = ginfo->width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
    jint h = ginfo->height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    GLenum pixelFormat = rgbOrder ? GL_RGB : GL_BGR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    if (glyphMode != MODE_NO_CACHE_LCD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        CHECK_PREVIOUS_OP(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
        j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        if (oglc->blitTextureID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
            if (!OGLContext_InitBlitTileTexture(oglc)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
                return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
        if (!OGLTR_EnableLCDGlyphModeState(oglc->blitTextureID, contrast)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
            return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        // when a fragment shader is enabled, the texture function state is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
        // ignored, so the following line is not needed...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
        // OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        glyphMode = MODE_NO_CACHE_LCD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    // rowBytes will always be a multiple of 3, so the following is safe
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
    j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, ginfo->rowBytes / 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    x0 = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    tx1 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    ty1 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    dtx1 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    dty2 = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
    tw = OGLTR_NOCACHE_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    th = OGLTR_NOCACHE_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    for (sy = 0; sy < h; sy += th, y += th) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        x = x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
        sh = ((sy + th) > h) ? (h - sy) : th;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        for (sx = 0; sx < w; sx += tw, x += tw) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
            sw = ((sx + tw) > w) ? (w - sx) : tw;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
            // update the source pointer offsets
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
            j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            // copy LCD mask into glyph texture tile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
            j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
                                0, 0, sw, sh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                                pixelFormat, GL_UNSIGNED_BYTE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                                ginfo->image + rowBytesOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            // update the lower-right glyph texture coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
            tx2 = ((GLfloat)sw) / OGLC_BLIT_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
            ty2 = ((GLfloat)sh) / OGLC_BLIT_TILE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
            // this accounts for lower-left origin of the destination region
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
            dxadj = dstOps->xOffset + x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
            dyadj = dstOps->yOffset + dstOps->height - (y + sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            // copy destination into cached texture tile (the lower-left
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            // corner of the destination region will be positioned at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            // lower-left corner (0,0) of the texture)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
            j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
            j2d_glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                                    0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                                    dxadj, dyadj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                                    sw, sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            // update the remaining destination texture coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            dtx2 = ((GLfloat)sw) / OGLTR_CACHED_DEST_WIDTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            dty1 = ((GLfloat)sh) / OGLTR_CACHED_DEST_HEIGHT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
            // render composed texture to the destination surface
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            j2d_glBegin(GL_QUADS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx1, ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            j2d_glVertex2i(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx2, ty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
            j2d_glVertex2i(x + sw, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx2, ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx2, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            j2d_glVertex2i(x + sw, y + sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            j2d_glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx1, ty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            j2d_glMultiTexCoord2fARB(GL_TEXTURE1_ARB, dtx1, dty2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
            j2d_glVertex2i(x, y + sh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
            j2d_glEnd();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
// see DrawGlyphList.c for more on this macro...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
#define FLOOR_ASSIGN(l, r) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
    if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
OGLTR_DrawGlyphList(JNIEnv *env, OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                    jint totalGlyphs, jboolean usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                    jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                    jfloat glyphListOrigX, jfloat glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                    unsigned char *images, unsigned char *positions)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
    int glyphCounter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
    J2dTraceLn(J2D_TRACE_INFO, "OGLTR_DrawGlyphList");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    RETURN_IF_NULL(dstOps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
    RETURN_IF_NULL(images);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
    if (usePositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
        RETURN_IF_NULL(positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
    glyphMode = MODE_NOT_INITED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
    isCachedDestValid = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
    for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        jint x, y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        jfloat glyphx, glyphy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
        jboolean grayscale, ok;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
        GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(NEXT_LONG(images));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
        if (ginfo == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
            // this shouldn't happen, but if it does we'll just break out...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
            J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
                          "OGLTR_DrawGlyphList: glyph info is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        grayscale = (ginfo->rowBytes == ginfo->width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        if (usePositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            jfloat posx = NEXT_FLOAT(positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            jfloat posy = NEXT_FLOAT(positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
            glyphx = glyphListOrigX + posx + ginfo->topLeftX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
            glyphy = glyphListOrigY + posy + ginfo->topLeftY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
            FLOOR_ASSIGN(x, glyphx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
            FLOOR_ASSIGN(y, glyphy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
            glyphx = glyphListOrigX + ginfo->topLeftX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
            glyphy = glyphListOrigY + ginfo->topLeftY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
            FLOOR_ASSIGN(x, glyphx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
            FLOOR_ASSIGN(y, glyphy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
            glyphListOrigX += ginfo->advanceX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            glyphListOrigY += ginfo->advanceY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        if (ginfo->image == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
            continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
        if (grayscale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
            // grayscale or monochrome glyph data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
            if (cacheStatus != CACHE_LCD &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                ok = OGLTR_DrawGrayscaleGlyphViaCache(oglc, ginfo, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
                ok = OGLTR_DrawGrayscaleGlyphNoCache(oglc, ginfo, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
            // LCD-optimized glyph data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
            jint rowBytesOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
            if (subPixPos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                jint frac = (jint)((glyphx - x) * 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                if (frac != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                    rowBytesOffset = 3 - frac;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                    x += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            if (rowBytesOffset == 0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
                cacheStatus != CACHE_GRAY &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
                ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                ok = OGLTR_DrawLCDGlyphViaCache(oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                                                ginfo, x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                                                glyphCounter, totalGlyphs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
                                                rgbOrder, lcdContrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                ok = OGLTR_DrawLCDGlyphNoCache(oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                                               ginfo, x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                                               rowBytesOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                                               rgbOrder, lcdContrast);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
        if (!ok) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
    OGLTR_DisableGlyphModeState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
Java_sun_java2d_opengl_OGLTextRenderer_drawGlyphList
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
    (JNIEnv *env, jobject self,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
     jint numGlyphs, jboolean usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
     jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
     jfloat glyphListOrigX, jfloat glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
     jlongArray imgArray, jfloatArray posArray)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
    unsigned char *images;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
    J2dTraceLn(J2D_TRACE_INFO, "OGLTextRenderer_drawGlyphList");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
    images = (unsigned char *)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
        (*env)->GetPrimitiveArrayCritical(env, imgArray, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
    if (images != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        OGLContext *oglc = OGLRenderQueue_GetCurrentContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
        OGLSDOps *dstOps = OGLRenderQueue_GetCurrentDestination();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
        if (usePositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
            unsigned char *positions = (unsigned char *)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                (*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
            if (positions != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                OGLTR_DrawGlyphList(env, oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                                    numGlyphs, usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                                    subPixPos, rgbOrder, lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                                    glyphListOrigX, glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
                                    images, positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                (*env)->ReleasePrimitiveArrayCritical(env, posArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                                                      positions, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            OGLTR_DrawGlyphList(env, oglc, dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                                numGlyphs, usePositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                                subPixPos, rgbOrder, lcdContrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
                                glyphListOrigX, glyphListOrigY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
                                images, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
        // 6358147: reset current state, and ensure rendering is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
        // flushed to dest
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
        if (oglc != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            RESET_PREVIOUS_OP();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
            j2d_glFlush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
        (*env)->ReleasePrimitiveArrayCritical(env, imgArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                                              images, JNI_ABORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
#endif /* !HEADLESS */