src/java.desktop/share/native/common/java2d/opengl/OGLPaints.c
author ihse
Sat, 03 Mar 2018 08:21:47 +0100
branchihse-warnings-cflags-branch
changeset 56230 489867818774
parent 47216 71c04702a3d5
permissions -rw-r--r--
No longer disable E_OLD_STYLE_FUNC_DEF.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2007, 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
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
#include <jlong.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "sun_java2d_SunGraphics2D.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "sun_java2d_pipe_BufferedPaints.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include "OGLPaints.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
#include "OGLContext.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#include "OGLRenderQueue.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
#include "OGLSurfaceData.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
OGLPaints_ResetPaint(OGLContext *oglc)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    jubyte ea;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_ResetPaint");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  state=%d", oglc->paintState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    RESET_PREVIOUS_OP();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    if (oglc->useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
        // switch to texture unit 1, where paint state is currently enabled
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    switch (oglc->paintState) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    case sun_java2d_SunGraphics2D_PAINT_GRADIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
        j2d_glDisable(GL_TEXTURE_1D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
        j2d_glDisable(GL_TEXTURE_GEN_S);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    case sun_java2d_SunGraphics2D_PAINT_TEXTURE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        // Note: The texture object used in SetTexturePaint() will
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
        // still be bound at this point, so it is safe to call the following.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        OGLSD_RESET_TEXTURE_WRAP(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
        j2d_glDisable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        j2d_glDisable(GL_TEXTURE_GEN_S);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        j2d_glDisable(GL_TEXTURE_GEN_T);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    case sun_java2d_SunGraphics2D_PAINT_LIN_GRADIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    case sun_java2d_SunGraphics2D_PAINT_RAD_GRADIENT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        j2d_glUseProgramObjectARB(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        j2d_glDisable(GL_TEXTURE_1D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    case sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    if (oglc->useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        // restore control to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // set each component of the current color state to the extra alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    // value, which will effectively apply the extra alpha to each fragment
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    // in paint/texturing operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    ea = (jubyte)(oglc->extraAlpha * 0xff + 0.5f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    j2d_glColor4ub(ea, ea, ea, ea);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    oglc->pixel = (ea << 24) | (ea << 16) | (ea << 8) | (ea << 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    oglc->r = ea;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    oglc->g = ea;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    oglc->b = ea;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    oglc->a = ea;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    oglc->useMask = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    oglc->paintState = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
OGLPaints_SetColor(OGLContext *oglc, jint pixel)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    jubyte r, g, b, a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    J2dTraceLn1(J2D_TRACE_INFO, "OGLPaints_SetColor: pixel=%08x", pixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    // glColor*() is allowed within glBegin()/glEnd() pairs, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    // no need to reset the current op state here unless the paint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // state really needs to be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    if (oglc->paintState > sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        OGLPaints_ResetPaint(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    // store the raw (unmodified) pixel value, which may be used for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    // special operations later
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    oglc->pixel = pixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    if (oglc->compState != sun_java2d_SunGraphics2D_COMP_XOR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        r = (jubyte)(pixel >> 16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        g = (jubyte)(pixel >>  8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        b = (jubyte)(pixel >>  0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        a = (jubyte)(pixel >> 24);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        J2dTraceLn4(J2D_TRACE_VERBOSE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                    "  updating color: r=%02x g=%02x b=%02x a=%02x",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                    r, g, b, a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        pixel ^= oglc->xorPixel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        r = (jubyte)(pixel >> 16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        g = (jubyte)(pixel >>  8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        b = (jubyte)(pixel >>  0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        a = 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        J2dTraceLn4(J2D_TRACE_VERBOSE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                    "  updating xor color: r=%02x g=%02x b=%02x xorpixel=%08x",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                    r, g, b, oglc->xorPixel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    j2d_glColor4ub(r, g, b, a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    oglc->r = r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    oglc->g = g;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    oglc->b = b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    oglc->a = a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    oglc->useMask = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    oglc->paintState = sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
/************************* GradientPaint support ****************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
static GLuint gradientTexID = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
static void
56230
489867818774 No longer disable E_OLD_STYLE_FUNC_DEF.
ihse
parents: 47216
diff changeset
   156
OGLPaints_InitGradientTexture(void)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    GLclampf priority = 1.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_InitGradientTexture");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    j2d_glGenTextures(1, &gradientTexID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    j2d_glBindTexture(GL_TEXTURE_1D, gradientTexID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    j2d_glPrioritizeTextures(1, &gradientTexID, &priority);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    j2d_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    j2d_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    j2d_glTexImage1D(GL_TEXTURE_1D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                     GL_RGBA8, 2, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
OGLPaints_SetGradientPaint(OGLContext *oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                           jboolean useMask, jboolean cyclic,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                           jdouble p0, jdouble p1, jdouble p3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                           jint pixel1, jint pixel2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    GLdouble texParams[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    GLuint pixels[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_SetGradientPaint");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    OGLPaints_ResetPaint(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    texParams[0] = p0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    texParams[1] = p1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    texParams[2] = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    texParams[3] = p3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    pixels[0] = pixel1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    pixels[1] = pixel2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        // set up the paint on texture unit 1 (instead of the usual unit 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        j2d_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        // texture unit 0 is already active; we can use the helper macro here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    if (gradientTexID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        OGLPaints_InitGradientTexture();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    j2d_glEnable(GL_TEXTURE_1D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    j2d_glEnable(GL_TEXTURE_GEN_S);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    j2d_glBindTexture(GL_TEXTURE_1D, gradientTexID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    j2d_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                        cyclic ? GL_REPEAT : GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    j2d_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    j2d_glTexGendv(GL_S, GL_OBJECT_PLANE, texParams);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    j2d_glTexSubImage1D(GL_TEXTURE_1D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                        0, 2, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        // restore control to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    // oglc->pixel has been set appropriately in OGLPaints_ResetPaint()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    oglc->useMask = useMask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    oglc->paintState = sun_java2d_SunGraphics2D_PAINT_GRADIENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
/************************** TexturePaint support ****************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
OGLPaints_SetTexturePaint(OGLContext *oglc,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                          jboolean useMask,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                          jlong pSrcOps, jboolean filter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                          jdouble xp0, jdouble xp1, jdouble xp3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                          jdouble yp0, jdouble yp1, jdouble yp3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    OGLSDOps *srcOps = (OGLSDOps *)jlong_to_ptr(pSrcOps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    GLdouble xParams[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    GLdouble yParams[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    GLint hint = (filter ? GL_LINEAR : GL_NEAREST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_SetTexturePaint");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    RETURN_IF_NULL(srcOps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    OGLPaints_ResetPaint(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    xParams[0] = xp0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    xParams[1] = xp1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    xParams[2] = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    xParams[3] = xp3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    yParams[0] = yp0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    yParams[1] = yp1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    yParams[2] = 0.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    yParams[3] = yp3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * Note that we explicitly use GL_TEXTURE_2D below rather than using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * srcOps->textureTarget.  This is because the texture wrap mode employed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * here (GL_REPEAT) is not available for GL_TEXTURE_RECTANGLE_ARB targets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * The setup code in OGLPaints.Texture.isPaintValid() and in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * OGLSurfaceData.initTexture() ensures that we only get here for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * GL_TEXTURE_2D targets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        // set up the paint on texture unit 1 (instead of the usual unit 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        j2d_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        // texture unit 0 is already active; we can use the helper macro here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        OGLC_UPDATE_TEXTURE_FUNCTION(oglc, GL_MODULATE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    j2d_glEnable(GL_TEXTURE_2D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    j2d_glEnable(GL_TEXTURE_GEN_S);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    j2d_glEnable(GL_TEXTURE_GEN_T);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    j2d_glBindTexture(GL_TEXTURE_2D, srcOps->textureID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    OGLSD_UPDATE_TEXTURE_FILTER(srcOps, hint);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    OGLSD_UPDATE_TEXTURE_WRAP(GL_TEXTURE_2D, GL_REPEAT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    j2d_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    j2d_glTexGendv(GL_S, GL_OBJECT_PLANE, xParams);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    j2d_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    j2d_glTexGendv(GL_T, GL_OBJECT_PLANE, yParams);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        // restore control to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    // oglc->pixel has been set appropriately in OGLPaints_ResetPaint()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    oglc->useMask = useMask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    oglc->paintState = sun_java2d_SunGraphics2D_PAINT_TEXTURE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
/****************** Shared MultipleGradientPaint support ********************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
 * These constants are identical to those defined in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
 * MultipleGradientPaint.CycleMethod enum; they are copied here for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
 * convenience (ideally we would pull them directly from the Java level,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
 * but that entails more hassle than it is worth).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
#define CYCLE_NONE    0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
#define CYCLE_REFLECT 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
#define CYCLE_REPEAT  2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
 * The following constants are flags that can be bitwise-or'ed together
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
 * to control how the MultipleGradientPaint shader source code is generated:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
 *   MULTI_CYCLE_METHOD
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
 *     Placeholder for the CycleMethod enum constant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
 *   MULTI_LARGE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
 *     If set, use the (slower) shader that supports a larger number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
 *     gradient colors; otherwise, use the optimized codepath.  See
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
 *     the MAX_FRACTIONS_SMALL/LARGE constants below for more details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
 *   MULTI_USE_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
 *     If set, apply the alpha mask value from texture unit 0 to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
 *     final color result (only used in the MaskFill case).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
 *   MULTI_LINEAR_RGB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
 *     If set, convert the linear RGB result back into the sRGB color space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
#define MULTI_CYCLE_METHOD (3 << 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
#define MULTI_LARGE        (1 << 2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
#define MULTI_USE_MASK     (1 << 3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
#define MULTI_LINEAR_RGB   (1 << 4)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
 * This value determines the size of the array of programs for each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
 * MultipleGradientPaint type.  This value reflects the maximum value that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
 * can be represented by performing a bitwise-or of all the MULTI_*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
 * constants defined above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
#define MAX_PROGRAMS 32
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
/** Evaluates to true if the given bit is set on the local flags variable. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
#define IS_SET(flagbit) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    (((flags) & (flagbit)) != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
/** Composes the given parameters as flags into the given flags variable.*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
#define COMPOSE_FLAGS(flags, cycleMethod, large, useMask, linear) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    do {                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        flags |= ((cycleMethod) & MULTI_CYCLE_METHOD);     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        if (large)   flags |= MULTI_LARGE;                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        if (useMask) flags |= MULTI_USE_MASK;              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        if (linear)  flags |= MULTI_LINEAR_RGB;            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
/** Extracts the CycleMethod enum value from the given flags variable. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
#define EXTRACT_CYCLE_METHOD(flags) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    ((flags) & MULTI_CYCLE_METHOD)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
 * The maximum number of gradient "stops" supported by the fragment shader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
 * and related code.  When the MULTI_LARGE flag is set, we will use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
 * MAX_FRACTIONS_LARGE; otherwise, we use MAX_FRACTIONS_SMALL.  By having
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
 * two separate values, we can have one highly optimized shader (SMALL) that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
 * supports only a few fractions/colors, and then another, less optimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
 * shader that supports more stops.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
#define MAX_FRACTIONS sun_java2d_pipe_BufferedPaints_MULTI_MAX_FRACTIONS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
#define MAX_FRACTIONS_LARGE MAX_FRACTIONS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
#define MAX_FRACTIONS_SMALL 4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
 * The maximum number of gradient colors supported by all of the gradient
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
 * fragment shaders.  Note that this value must be a power of two, as it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
 * determines the size of the 1D texture created below.  It also must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
 * greater than or equal to MAX_FRACTIONS (there is no strict requirement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
 * that the two values be equal).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
#define MAX_COLORS 16
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
 * The handle to the gradient color table texture object used by the shaders.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
static GLuint multiGradientTexID = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
 * This is essentially a template of the shader source code that can be used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
 * for either LinearGradientPaint or RadialGradientPaint.  It includes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
 * structure and some variables that are common to each; the remaining
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
 * code snippets (for CycleMethod, ColorSpaceType, and mask modulation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
 * are filled in prior to compiling the shader at runtime depending on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
 * paint parameters.  See OGLPaints_CreateMultiGradProgram() for more details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
static const char *multiGradientShaderSource =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    // gradient texture size (in texels)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    "const int TEXTURE_SIZE = %d;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    // maximum number of fractions/colors supported by this shader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    "const int MAX_FRACTIONS = %d;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    // size of a single texel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    "const float FULL_TEXEL = (1.0 / float(TEXTURE_SIZE));"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
    // size of half of a single texel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    "const float HALF_TEXEL = (FULL_TEXEL / 2.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    // texture containing the gradient colors
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    "uniform sampler1D colors;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    // array of gradient stops/fractions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    "uniform float fractions[MAX_FRACTIONS];"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    // array of scale factors (one for each interval)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    "uniform float scaleFactors[MAX_FRACTIONS-1];"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    // (placeholder for mask variable)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    "%s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    // (placeholder for Linear/RadialGP-specific variables)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    "%s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    "void main(void)"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    "{"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    "    float dist;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
         // (placeholder for Linear/RadialGradientPaint-specific code)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    "    %s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    "    float tc;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
         // (placeholder for CycleMethod-specific code)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    "    %s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
         // calculate interpolated color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    "    vec4 result = texture1D(colors, tc);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
         // (placeholder for ColorSpace conversion code)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    "    %s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
         // (placeholder for mask modulation code)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    "    %s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
         // modulate with gl_Color in order to apply extra alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    "    gl_FragColor = result * gl_Color;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    "}";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
 * This code takes a "dist" value as input (as calculated earlier by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
 * LGP/RGP-specific code) in the range [0,1] and produces a texture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
 * coordinate value "tc" that represents the position of the chosen color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
 * in the one-dimensional gradient texture (also in the range [0,1]).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
 * One naive way to implement this would be to iterate through the fractions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
 * to figure out in which interval "dist" falls, and then compute the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
 * relative distance between the two nearest stops.  This approach would
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
 * require an "if" check on every iteration, and it is best to avoid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
 * conditionals in fragment shaders for performance reasons.  Also, one might
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
 * be tempted to use a break statement to jump out of the loop once the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
 * interval was found, but break statements (and non-constant loop bounds)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
 * are not natively available on most graphics hardware today, so that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
 * a non-starter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
 * The more optimal approach used here avoids these issues entirely by using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
 * an accumulation function that is equivalent to the process described above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
 * The scaleFactors array is pre-initialized at enable time as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
 *     scaleFactors[i] = 1.0 / (fractions[i+1] - fractions[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
 * For each iteration, we subtract fractions[i] from dist and then multiply
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
 * that value by scaleFactors[i].  If we are within the target interval,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
 * this value will be a fraction in the range [0,1] indicating the relative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
 * distance between fraction[i] and fraction[i+1].  If we are below the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
 * target interval, this value will be negative, so we clamp it to zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
 * to avoid accumulating any value.  If we are above the target interval,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
 * the value will be greater than one, so we clamp it to one.  Upon exiting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
 * the loop, we will have accumulated zero or more 1.0's and a single
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
 * fractional value.  This accumulated value tells us the position of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
 * fragment color in the one-dimensional gradient texture, i.e., the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
 * texcoord called "tc".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
static const char *texCoordCalcCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    "int i;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    "float relFraction = 0.0;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    "for (i = 0; i < MAX_FRACTIONS-1; i++) {"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    "    relFraction +="
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    "        clamp((dist - fractions[i]) * scaleFactors[i], 0.0, 1.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    "}"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    // we offset by half a texel so that we find the linearly interpolated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    // color between the two texel centers of interest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    "tc = HALF_TEXEL + (FULL_TEXEL * relFraction);";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
/** Code for NO_CYCLE that gets plugged into the CycleMethod placeholder. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
static const char *noCycleCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    "if (dist <= 0.0) {"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    "    tc = 0.0;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    "} else if (dist >= 1.0) {"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    "    tc = 1.0;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    "} else {"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
         // (placeholder for texcoord calculation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    "    %s"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    "}";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
/** Code for REFLECT that gets plugged into the CycleMethod placeholder. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
static const char *reflectCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    "dist = 1.0 - (abs(fract(dist * 0.5) - 0.5) * 2.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    // (placeholder for texcoord calculation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    "%s";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
/** Code for REPEAT that gets plugged into the CycleMethod placeholder. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
static const char *repeatCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    "dist = fract(dist);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    // (placeholder for texcoord calculation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    "%s";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
static void
56230
489867818774 No longer disable E_OLD_STYLE_FUNC_DEF.
ihse
parents: 47216
diff changeset
   503
OGLPaints_InitMultiGradientTexture(void)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    GLclampf priority = 1.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_InitMultiGradientTexture");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    j2d_glGenTextures(1, &multiGradientTexID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    j2d_glBindTexture(GL_TEXTURE_1D, multiGradientTexID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    j2d_glPrioritizeTextures(1, &multiGradientTexID, &priority);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    j2d_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    j2d_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    j2d_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    j2d_glTexImage1D(GL_TEXTURE_1D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                     GL_RGBA8, MAX_COLORS, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
 * Compiles and links the MultipleGradientPaint shader program.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
 * successful, this function returns a handle to the newly created
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
 * shader program; otherwise returns 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
static GLhandleARB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
OGLPaints_CreateMultiGradProgram(jint flags,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                                 char *paintVars, char *distCode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
    GLhandleARB multiGradProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
    char *maskVars = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    char *maskCode = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    char *colorSpaceCode = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    char cycleCode[1500];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    char finalSource[3000];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    jint cycleMethod = EXTRACT_CYCLE_METHOD(flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    jint maxFractions = IS_SET(MULTI_LARGE) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        MAX_FRACTIONS_LARGE : MAX_FRACTIONS_SMALL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_CreateMultiGradProgram");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
    if (IS_SET(MULTI_USE_MASK)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
         * This code modulates the calculated result color with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
         * corresponding alpha value from the alpha mask texture active
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
         * on texture unit 0.  Only needed when useMask is true (i.e., only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
         * for MaskFill operations).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        maskVars = "uniform sampler2D mask;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        maskCode = "result *= texture2D(mask, gl_TexCoord[0].st);";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
         * REMIND: This is really wacky, but the gradient shaders will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
         * produce completely incorrect results on ATI hardware (at least
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
         * on first-gen (R300-based) boards) if the shader program does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
         * try to access texture coordinates by using a gl_TexCoord[*]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
         * variable.  This problem really should be addressed by ATI, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
         * in the meantime it seems we can workaround the issue by inserting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
         * a benign operation that accesses gl_TexCoord[0].  Note that we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
         * only need to do this for ATI boards and only in the !useMask case,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
         * because the useMask case already does access gl_TexCoord[1] and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
         * is therefore not affected by this driver bug.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        const char *vendor = (const char *)j2d_glGetString(GL_VENDOR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        if (vendor != NULL && strncmp(vendor, "ATI", 3) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            maskCode = "dist = gl_TexCoord[0].s;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    if (IS_SET(MULTI_LINEAR_RGB)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
         * This code converts a single pixel in linear RGB space back
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
         * into sRGB (note: this code was adapted from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
         * MultipleGradientPaintContext.convertLinearRGBtoSRGB() method).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        colorSpaceCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            "result.rgb = 1.055 * pow(result.rgb, vec3(0.416667)) - 0.055;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    if (cycleMethod == CYCLE_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        sprintf(cycleCode, noCycleCode, texCoordCalcCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    } else if (cycleMethod == CYCLE_REFLECT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        sprintf(cycleCode, reflectCode, texCoordCalcCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    } else { // (cycleMethod == CYCLE_REPEAT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        sprintf(cycleCode, repeatCode, texCoordCalcCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    // compose the final source code string from the various pieces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    sprintf(finalSource, multiGradientShaderSource,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            MAX_COLORS, maxFractions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            maskVars, paintVars, distCode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            cycleCode, colorSpaceCode, maskCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    multiGradProgram = OGLContext_CreateFragmentProgram(finalSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    if (multiGradProgram == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        J2dRlsTraceLn(J2D_TRACE_ERROR,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            "OGLPaints_CreateMultiGradProgram: error creating program");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    // "use" the program object temporarily so that we can set the uniforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    j2d_glUseProgramObjectARB(multiGradProgram);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    // set the "uniform" texture unit bindings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    if (IS_SET(MULTI_USE_MASK)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        loc = j2d_glGetUniformLocationARB(multiGradProgram, "mask");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        j2d_glUniform1iARB(loc, 0); // texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        loc = j2d_glGetUniformLocationARB(multiGradProgram, "colors");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        j2d_glUniform1iARB(loc, 1); // texture unit 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        loc = j2d_glGetUniformLocationARB(multiGradProgram, "colors");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        j2d_glUniform1iARB(loc, 0); // texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    // "unuse" the program object; it will be re-bound later as needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    j2d_glUseProgramObjectARB(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    if (multiGradientTexID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        OGLPaints_InitMultiGradientTexture();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    return multiGradProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
 * Called from the OGLPaints_SetLinear/RadialGradientPaint() methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
 * in order to setup the fraction/color values that are common to both.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
OGLPaints_SetMultiGradientPaint(GLhandleARB multiGradProgram,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                                jint numStops,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                                void *pFractions, void *pPixels)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    jint maxFractions = (numStops > MAX_FRACTIONS_SMALL) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        MAX_FRACTIONS_LARGE : MAX_FRACTIONS_SMALL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    GLfloat scaleFactors[MAX_FRACTIONS-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    GLfloat *fractions = (GLfloat *)pFractions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    GLint *pixels = (GLint *)pPixels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    // enable the MultipleGradientPaint shader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    j2d_glUseProgramObjectARB(multiGradProgram);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    // update the "uniform" fraction values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    loc = j2d_glGetUniformLocationARB(multiGradProgram, "fractions");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    if (numStops < maxFractions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        // fill the remainder of the fractions array with all zeros to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        // prevent using garbage values from previous paints
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        GLfloat allZeros[MAX_FRACTIONS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        memset(allZeros, 0, sizeof(GLfloat)*MAX_FRACTIONS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        j2d_glUniform1fvARB(loc, maxFractions, allZeros);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    j2d_glUniform1fvARB(loc, numStops, fractions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    // update the "uniform" scale values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    loc = j2d_glGetUniformLocationARB(multiGradProgram, "scaleFactors");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    for (i = 0; i < numStops-1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        // calculate a scale factor for each interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        scaleFactors[i] = 1.0f / (fractions[i+1] - fractions[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    for (; i < maxFractions-1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        // fill remaining scale factors with zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        scaleFactors[i] = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    j2d_glUniform1fvARB(loc, maxFractions-1, scaleFactors);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
    // update the texture containing the gradient colors
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    j2d_glEnable(GL_TEXTURE_1D);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    j2d_glBindTexture(GL_TEXTURE_1D, multiGradientTexID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    j2d_glTexSubImage1D(GL_TEXTURE_1D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                        0, numStops,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                        GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                        pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    if (numStops < MAX_COLORS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        // when we don't have enough colors to fill the entire color gradient,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        // we have to replicate the last color in the right-most texel for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        // the NO_CYCLE case where the texcoord is sometimes forced to 1.0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        j2d_glTexSubImage1D(GL_TEXTURE_1D, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                            MAX_COLORS-1, 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                            GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                            pixels+(numStops-1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
/********************** LinearGradientPaint support *************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
 * The handles to the LinearGradientPaint fragment program objects.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
 * index to the array should be a bitwise-or'ing of the MULTI_* flags defined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
 * above.  Note that most applications will likely need to initialize one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
 * or two of these elements, so the array is usually sparsely populated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
static GLhandleARB linearGradPrograms[MAX_PROGRAMS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
 * Compiles and links the LinearGradientPaint shader program.  If successful,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
 * this function returns a handle to the newly created shader program;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
 * otherwise returns 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
static GLhandleARB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
OGLPaints_CreateLinearGradProgram(jint flags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    char *paintVars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    char *distCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    J2dTraceLn1(J2D_TRACE_INFO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                "OGLPaints_CreateLinearGradProgram",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
     * To simplify the code and to make it easier to upload a number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
     * uniform values at once, we pack a bunch of scalar (float) values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
     * into vec3 values below.  Here's how the values are related:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
     *   params.x = p0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     *   params.y = p1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     *   params.z = p3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     *   yoff = dstOps->yOffset + dstOps->height
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    paintVars =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        "uniform vec3 params;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        "uniform float yoff;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    distCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        // note that gl_FragCoord is in window space relative to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        // lower-left corner, so we have to flip the y-coordinate here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        "vec3 fragCoord = vec3(gl_FragCoord.x, yoff-gl_FragCoord.y, 1.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        "dist = dot(params, fragCoord);";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    return OGLPaints_CreateMultiGradProgram(flags, paintVars, distCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
OGLPaints_SetLinearGradientPaint(OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                                 jboolean useMask, jboolean linear,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                                 jint cycleMethod, jint numStops,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                                 jfloat p0, jfloat p1, jfloat p3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                                 void *fractions, void *pixels)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
    GLhandleARB linearGradProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    jboolean large = (numStops > MAX_FRACTIONS_SMALL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    jint flags = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_SetLinearGradientPaint");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    RETURN_IF_NULL(dstOps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    OGLPaints_ResetPaint(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    COMPOSE_FLAGS(flags, cycleMethod, large, useMask, linear);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        // set up the paint on texture unit 1 (instead of the usual unit 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    // no need to set GL_MODULATE here (it is ignored when shader is enabled)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    // locate/initialize the shader program for the given flags
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    if (linearGradPrograms[flags] == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        linearGradPrograms[flags] = OGLPaints_CreateLinearGradProgram(flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        if (linearGradPrograms[flags] == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            // shouldn't happen, but just in case...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    linearGradProgram = linearGradPrograms[flags];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    // update the common "uniform" values (fractions and colors)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    OGLPaints_SetMultiGradientPaint(linearGradProgram,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                                    numStops, fractions, pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    // update the other "uniform" values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
    loc = j2d_glGetUniformLocationARB(linearGradProgram, "params");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    j2d_glUniform3fARB(loc, p0, p1, p3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    loc = j2d_glGetUniformLocationARB(linearGradProgram, "yoff");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    j2d_glUniform1fARB(loc, (GLfloat)(dstOps->yOffset + dstOps->height));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        // restore control to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    // oglc->pixel has been set appropriately in OGLPaints_ResetPaint()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    oglc->useMask = useMask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    oglc->paintState = sun_java2d_SunGraphics2D_PAINT_LIN_GRADIENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
/********************** RadialGradientPaint support *************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
 * The handles to the RadialGradientPaint fragment program objects.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
 * index to the array should be a bitwise-or'ing of the MULTI_* flags defined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
 * above.  Note that most applications will likely need to initialize one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
 * or two of these elements, so the array is usually sparsely populated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
static GLhandleARB radialGradPrograms[MAX_PROGRAMS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
 * Compiles and links the RadialGradientPaint shader program.  If successful,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
 * this function returns a handle to the newly created shader program;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
 * otherwise returns 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
static GLhandleARB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
OGLPaints_CreateRadialGradProgram(jint flags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    char *paintVars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    char *distCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    J2dTraceLn1(J2D_TRACE_INFO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                "OGLPaints_CreateRadialGradProgram",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     * To simplify the code and to make it easier to upload a number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
     * uniform values at once, we pack a bunch of scalar (float) values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
     * into vec3 and vec4 values below.  Here's how the values are related:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
     *   m0.x = m00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
     *   m0.y = m01
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     *   m0.z = m02
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
     *   m1.x = m10
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
     *   m1.y = m11
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
     *   m1.z = m12
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     *   precalc.x = focusX
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     *   precalc.y = yoff = dstOps->yOffset + dstOps->height
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
     *   precalc.z = 1.0 - (focusX * focusX)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
     *   precalc.w = 1.0 / precalc.z
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    paintVars =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        "uniform vec3 m0;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        "uniform vec3 m1;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        "uniform vec4 precalc;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
     * The following code is derived from Daniel Rice's whitepaper on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
     * radial gradient performance (attached to the bug report for 6521533).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
     * Refer to that document as well as the setup code in the Java-level
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
     * BufferedPaints.setRadialGradientPaint() method for more details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    distCode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        // note that gl_FragCoord is in window space relative to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        // lower-left corner, so we have to flip the y-coordinate here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        "vec3 fragCoord ="
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        "    vec3(gl_FragCoord.x, precalc.y - gl_FragCoord.y, 1.0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        "float x = dot(fragCoord, m0);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        "float y = dot(fragCoord, m1);"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        "float xfx = x - precalc.x;"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        "dist = (precalc.x*xfx + sqrt(xfx*xfx + y*y*precalc.z))*precalc.w;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    return OGLPaints_CreateMultiGradProgram(flags, paintVars, distCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
OGLPaints_SetRadialGradientPaint(OGLContext *oglc, OGLSDOps *dstOps,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                                 jboolean useMask, jboolean linear,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                                 jint cycleMethod, jint numStops,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                                 jfloat m00, jfloat m01, jfloat m02,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                                 jfloat m10, jfloat m11, jfloat m12,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                                 jfloat focusX,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                                 void *fractions, void *pixels)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    GLhandleARB radialGradProgram;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
    GLint loc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
    GLfloat yoff, denom, inv_denom;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    jboolean large = (numStops > MAX_FRACTIONS_SMALL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    jint flags = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
    J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_SetRadialGradientPaint");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
    RETURN_IF_NULL(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    RETURN_IF_NULL(dstOps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
    OGLPaints_ResetPaint(oglc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
    COMPOSE_FLAGS(flags, cycleMethod, large, useMask, linear);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
        // set up the paint on texture unit 1 (instead of the usual unit 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        j2d_glActiveTextureARB(GL_TEXTURE1_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    // no need to set GL_MODULATE here (it is ignored when shader is enabled)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
    // locate/initialize the shader program for the given flags
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
    if (radialGradPrograms[flags] == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        radialGradPrograms[flags] = OGLPaints_CreateRadialGradProgram(flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
        if (radialGradPrograms[flags] == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
            // shouldn't happen, but just in case...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    radialGradProgram = radialGradPrograms[flags];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    // update the common "uniform" values (fractions and colors)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    OGLPaints_SetMultiGradientPaint(radialGradProgram,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                                    numStops, fractions, pixels);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    // update the other "uniform" values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    loc = j2d_glGetUniformLocationARB(radialGradProgram, "m0");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    j2d_glUniform3fARB(loc, m00, m01, m02);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    loc = j2d_glGetUniformLocationARB(radialGradProgram, "m1");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    j2d_glUniform3fARB(loc, m10, m11, m12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    // pack a few unrelated, precalculated values into a single vec4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    yoff = (GLfloat)(dstOps->yOffset + dstOps->height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    denom = 1.0f - (focusX * focusX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
    inv_denom = 1.0f / denom;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    loc = j2d_glGetUniformLocationARB(radialGradProgram, "precalc");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    j2d_glUniform4fARB(loc, focusX, yoff, denom, inv_denom);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    if (useMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        // restore control to texture unit 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
        j2d_glActiveTextureARB(GL_TEXTURE0_ARB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
    // oglc->pixel has been set appropriately in OGLPaints_ResetPaint()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    oglc->useMask = useMask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    oglc->paintState = sun_java2d_SunGraphics2D_PAINT_RAD_GRADIENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
#endif /* !HEADLESS */