0N/A/*
2362N/A * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#ifndef HEADLESS
0N/A
0N/A#include <stdlib.h>
0N/A
0N/A#include "sun_java2d_opengl_OGLSurfaceData.h"
0N/A
0N/A#include "jlong.h"
0N/A#include "jni_util.h"
0N/A#include "OGLSurfaceData.h"
0N/A
0N/A/**
0N/A * The following methods are implemented in the windowing system (i.e. GLX
0N/A * and WGL) source files.
0N/A */
0N/Aextern jlong OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo);
0N/Aextern jboolean OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo);
0N/Aextern void OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo);
0N/A
430N/Avoid OGLSD_SetNativeDimensions(JNIEnv *env, OGLSDOps *oglsdo, jint w, jint h);
430N/A
0N/A/**
0N/A * This table contains the "pixel formats" for all system memory surfaces
0N/A * that OpenGL is capable of handling, indexed by the "PF_" constants defined
0N/A * in OGLSurfaceData.java. These pixel formats contain information that is
0N/A * passed to OpenGL when copying from a system memory ("Sw") surface to
0N/A * an OpenGL "Surface" (via glDrawPixels()) or "Texture" (via glTexImage2D()).
0N/A */
0N/AOGLPixelFormat PixelFormats[] = {
0N/A { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
0N/A 4, 1, 0, }, /* 0 - IntArgb */
0N/A { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
0N/A 4, 1, 1, }, /* 1 - IntArgbPre */
0N/A { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
0N/A 4, 0, 1, }, /* 2 - IntRgb */
0N/A { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
0N/A 4, 0, 1, }, /* 3 - IntRgbx */
0N/A { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
0N/A 4, 0, 1, }, /* 4 - IntBgr */
0N/A { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8,
0N/A 4, 0, 1, }, /* 5 - IntBgrx */
0N/A { GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
0N/A 2, 0, 1, }, /* 6 - Ushort565Rgb */
0N/A { GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
0N/A 2, 0, 1, }, /* 7 - Ushort555Rgb */
0N/A { GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
0N/A 2, 0, 1, }, /* 8 - Ushort555Rgbx*/
0N/A { GL_LUMINANCE, GL_UNSIGNED_BYTE,
0N/A 1, 0, 1, }, /* 9 - ByteGray */
0N/A { GL_LUMINANCE, GL_UNSIGNED_SHORT,
0N/A 2, 0, 1, }, /*10 - UshortGray */
759N/A { GL_BGR, GL_UNSIGNED_BYTE,
759N/A 1, 0, 1, }, /*11 - ThreeByteBgr */};
0N/A
0N/A/**
0N/A * Given a starting value and a maximum limit, returns the first power-of-two
0N/A * greater than the starting value. If the resulting value is greater than
0N/A * the maximum limit, zero is returned.
0N/A */
0N/Ajint
0N/AOGLSD_NextPowerOfTwo(jint val, jint max)
0N/A{
0N/A jint i;
0N/A
0N/A if (val > max) {
0N/A return 0;
0N/A }
0N/A
0N/A for (i = 1; i < val; i *= 2);
0N/A
0N/A return i;
0N/A}
0N/A
0N/A/**
0N/A * Returns true if both given dimensions are a power of two.
0N/A */
0N/Astatic jboolean
0N/AOGLSD_IsPowerOfTwo(jint width, jint height)
0N/A{
0N/A return (((width & (width-1)) | (height & (height-1))) == 0);
0N/A}
0N/A
0N/A/**
0N/A * Initializes an OpenGL texture object.
0N/A *
0N/A * If the isOpaque parameter is JNI_FALSE, then the texture will have a
0N/A * full alpha channel; otherwise, the texture will be opaque (this can
0N/A * help save VRAM when translucency is not needed).
0N/A *
0N/A * If the GL_ARB_texture_non_power_of_two extension is present (texNonPow2
0N/A * is JNI_TRUE), the actual texture is allowed to have non-power-of-two
0N/A * dimensions, and therefore width==textureWidth and height==textureHeight.
0N/A *
0N/A * Failing that, if the GL_ARB_texture_rectangle extension is present
0N/A * (texRect is JNI_TRUE), the actual texture is allowed to have
0N/A * non-power-of-two dimensions, except that instead of using the usual
0N/A * GL_TEXTURE_2D target, we need to use the GL_TEXTURE_RECTANGLE_ARB target.
0N/A * Note that the GL_REPEAT wrapping mode is not allowed with this target,
0N/A * so if that mode is needed (e.g. as is the case in the TexturePaint code)
0N/A * one should pass JNI_FALSE to avoid using this extension. Also note that
0N/A * when the texture target is GL_TEXTURE_RECTANGLE_ARB, texture coordinates
0N/A * must be specified in the range [0,width] and [0,height] rather than
0N/A * [0,1] as is the case with the usual GL_TEXTURE_2D target (so take care)!
0N/A *
0N/A * Otherwise, the actual texture must have power-of-two dimensions, and
0N/A * therefore the textureWidth and textureHeight will be the next
0N/A * power-of-two greater than (or equal to) the requested width and height.
0N/A */
0N/Astatic jboolean
0N/AOGLSD_InitTextureObject(OGLSDOps *oglsdo,
0N/A jboolean isOpaque,
0N/A jboolean texNonPow2, jboolean texRect,
0N/A jint width, jint height)
0N/A{
0N/A GLenum texTarget, texProxyTarget;
4646N/A GLint format = GL_RGBA;
4646N/A GLint size = GL_UNSIGNED_INT_8_8_8_8;
0N/A GLuint texID;
0N/A GLsizei texWidth, texHeight, realWidth, realHeight;
0N/A GLint texMax;
0N/A
0N/A J2dTraceLn4(J2D_TRACE_INFO,
0N/A "OGLSD_InitTextureObject: w=%d h=%d opq=%d nonpow2=%d",
0N/A width, height, isOpaque, texNonPow2);
0N/A
0N/A if (oglsdo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSD_InitTextureObject: ops are null");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A if (texNonPow2) {
0N/A // use non-pow2 dimensions with GL_TEXTURE_2D target
0N/A j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);
0N/A texWidth = (width <= texMax) ? width : 0;
0N/A texHeight = (height <= texMax) ? height : 0;
0N/A texTarget = GL_TEXTURE_2D;
0N/A texProxyTarget = GL_PROXY_TEXTURE_2D;
0N/A } else if (texRect) {
0N/A // use non-pow2 dimensions with GL_TEXTURE_RECTANGLE_ARB target
0N/A j2d_glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texMax);
0N/A texWidth = (width <= texMax) ? width : 0;
0N/A texHeight = (height <= texMax) ? height : 0;
0N/A texTarget = GL_TEXTURE_RECTANGLE_ARB;
0N/A texProxyTarget = GL_PROXY_TEXTURE_RECTANGLE_ARB;
0N/A } else {
0N/A // find the appropriate power-of-two dimensions
0N/A j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);
0N/A texWidth = OGLSD_NextPowerOfTwo(width, texMax);
0N/A texHeight = OGLSD_NextPowerOfTwo(height, texMax);
0N/A texTarget = GL_TEXTURE_2D;
0N/A texProxyTarget = GL_PROXY_TEXTURE_2D;
0N/A }
0N/A
0N/A J2dTraceLn3(J2D_TRACE_VERBOSE,
0N/A " desired texture dimensions: w=%d h=%d max=%d",
0N/A texWidth, texHeight, texMax);
0N/A
0N/A // if either dimension is 0, we cannot allocate a texture with the
0N/A // requested dimensions
0N/A if ((texWidth == 0) || (texHeight == 0)) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSD_InitTextureObject: texture dimensions too large");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A // now use a proxy to determine whether we can create a texture with
0N/A // the calculated power-of-two dimensions and the given internal format
0N/A j2d_glTexImage2D(texProxyTarget, 0, format,
0N/A texWidth, texHeight, 0,
4646N/A format, size, NULL);
0N/A j2d_glGetTexLevelParameteriv(texProxyTarget, 0,
0N/A GL_TEXTURE_WIDTH, &realWidth);
0N/A j2d_glGetTexLevelParameteriv(texProxyTarget, 0,
0N/A GL_TEXTURE_HEIGHT, &realHeight);
0N/A
0N/A // if the requested dimensions and proxy dimensions don't match,
0N/A // we shouldn't attempt to create the texture
0N/A if ((realWidth != texWidth) || (realHeight != texHeight)) {
0N/A J2dRlsTraceLn2(J2D_TRACE_ERROR,
0N/A "OGLSD_InitTextureObject: actual (w=%d h=%d) != requested",
0N/A realWidth, realHeight);
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A // initialize the texture with some dummy data (this allows us to create
0N/A // a texture object once with 2^n dimensions, and then use
0N/A // glTexSubImage2D() to provide further updates)
0N/A j2d_glGenTextures(1, &texID);
0N/A j2d_glBindTexture(texTarget, texID);
0N/A j2d_glTexImage2D(texTarget, 0, format,
0N/A texWidth, texHeight, 0,
4646N/A format, size, NULL);
0N/A
0N/A oglsdo->isOpaque = isOpaque;
0N/A oglsdo->xOffset = 0;
0N/A oglsdo->yOffset = 0;
0N/A oglsdo->width = width;
0N/A oglsdo->height = height;
0N/A oglsdo->textureID = texID;
0N/A oglsdo->textureWidth = texWidth;
0N/A oglsdo->textureHeight = texHeight;
0N/A oglsdo->textureTarget = texTarget;
0N/A OGLSD_INIT_TEXTURE_FILTER(oglsdo, GL_NEAREST);
0N/A OGLSD_RESET_TEXTURE_WRAP(texTarget);
0N/A
0N/A J2dTraceLn3(J2D_TRACE_VERBOSE, " created texture: w=%d h=%d id=%d",
0N/A width, height, texID);
0N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/A/**
0N/A * Initializes an OpenGL texture, using the given width and height as
0N/A * a guide. See OGLSD_InitTextureObject() for more information.
0N/A */
0N/AJNIEXPORT jboolean JNICALL
0N/AJava_sun_java2d_opengl_OGLSurfaceData_initTexture
0N/A (JNIEnv *env, jobject oglsd,
0N/A jlong pData, jboolean isOpaque,
0N/A jboolean texNonPow2, jboolean texRect,
0N/A jint width, jint height)
0N/A{
0N/A OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
0N/A
0N/A J2dTraceLn2(J2D_TRACE_INFO, "OGLSurfaceData_initTexture: w=%d h=%d",
0N/A width, height);
0N/A
0N/A if (oglsdo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initTexture: ops are null");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A /*
0N/A * We only use the GL_ARB_texture_rectangle extension if it is available
0N/A * and the requested bounds are not pow2 (it is probably faster to use
0N/A * GL_TEXTURE_2D for pow2 textures, and besides, our TexturePaint
0N/A * code relies on GL_REPEAT, which is not allowed for
0N/A * GL_TEXTURE_RECTANGLE_ARB targets).
0N/A */
0N/A texRect = texRect && !OGLSD_IsPowerOfTwo(width, height);
0N/A
0N/A if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,
0N/A width, height))
0N/A {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initTexture: could not init texture object");
0N/A return JNI_FALSE;
0N/A }
0N/A
430N/A OGLSD_SetNativeDimensions(env, oglsdo,
430N/A oglsdo->textureWidth, oglsdo->textureHeight);
430N/A
0N/A oglsdo->drawableType = OGLSD_TEXTURE;
0N/A // other fields (e.g. width, height) are set in OGLSD_InitTextureObject()
0N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/A/**
0N/A * Initializes a framebuffer object based on the given textureID and its
0N/A * width/height. This method will iterate through all possible depth formats
0N/A * to find one that is supported by the drivers/hardware. (Since our use of
0N/A * the depth buffer is fairly simplistic, we hope to find a depth format that
0N/A * uses as little VRAM as possible.) If an appropriate depth buffer is found
0N/A * and all attachments are successful (i.e. the framebuffer object is
0N/A * "complete"), then this method will return JNI_TRUE and will initialize
0N/A * the values of fbobjectID and depthID using the IDs created by this method.
0N/A * Otherwise, this method returns JNI_FALSE. Note that the caller is only
0N/A * responsible for deleting the allocated fbobject and depth renderbuffer
0N/A * resources if this method returned JNI_TRUE.
0N/A */
0N/Ajboolean
0N/AOGLSD_InitFBObject(GLuint *fbobjectID, GLuint *depthID,
0N/A GLuint textureID, GLenum textureTarget,
0N/A jint textureWidth, jint textureHeight)
0N/A{
0N/A GLenum depthFormats[] = {
0N/A GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32
0N/A };
0N/A GLuint fboTmpID, depthTmpID;
0N/A jboolean foundDepth = JNI_FALSE;
0N/A int i;
0N/A
0N/A J2dTraceLn3(J2D_TRACE_INFO, "OGLSD_InitFBObject: w=%d h=%d texid=%d",
0N/A textureWidth, textureHeight, textureID);
0N/A
0N/A // initialize framebuffer object
0N/A j2d_glGenFramebuffersEXT(1, &fboTmpID);
0N/A j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboTmpID);
0N/A
0N/A // attach color texture to framebuffer object
0N/A j2d_glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
0N/A GL_COLOR_ATTACHMENT0_EXT,
0N/A textureTarget, textureID, 0);
0N/A
0N/A // attempt to create a depth renderbuffer of a particular format; we
0N/A // will start with the smallest size and then work our way up
0N/A for (i = 0; i < 3; i++) {
0N/A GLenum error, status;
0N/A GLenum depthFormat = depthFormats[i];
0N/A int depthSize = 16 + (i * 8);
0N/A
0N/A // initialize depth renderbuffer
0N/A j2d_glGenRenderbuffersEXT(1, &depthTmpID);
0N/A j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthTmpID);
0N/A j2d_glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat,
0N/A textureWidth, textureHeight);
0N/A
0N/A // creation of depth buffer could potentially fail, so check for error
0N/A error = j2d_glGetError();
0N/A if (error != GL_NO_ERROR) {
0N/A J2dTraceLn2(J2D_TRACE_VERBOSE,
0N/A "OGLSD_InitFBObject: could not create depth buffer: depth=%d error=%x",
0N/A depthSize, error);
0N/A j2d_glDeleteRenderbuffersEXT(1, &depthTmpID);
0N/A continue;
0N/A }
0N/A
0N/A // attach depth renderbuffer to framebuffer object
0N/A j2d_glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
0N/A GL_DEPTH_ATTACHMENT_EXT,
0N/A GL_RENDERBUFFER_EXT, depthTmpID);
0N/A
0N/A // now check for framebuffer "completeness"
0N/A status = j2d_glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
0N/A
0N/A if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
0N/A // we found a valid format, so break out of the loop
0N/A J2dTraceLn1(J2D_TRACE_VERBOSE,
0N/A " framebuffer is complete: depth=%d", depthSize);
0N/A foundDepth = JNI_TRUE;
0N/A break;
0N/A } else {
0N/A // this depth format didn't work, so delete and try another format
0N/A J2dTraceLn2(J2D_TRACE_VERBOSE,
0N/A " framebuffer is incomplete: depth=%d status=%x",
0N/A depthSize, status);
0N/A j2d_glDeleteRenderbuffersEXT(1, &depthTmpID);
0N/A }
0N/A }
0N/A
0N/A // unbind the texture and framebuffer objects (they will be bound again
0N/A // later as needed)
0N/A j2d_glBindTexture(textureTarget, 0);
0N/A j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
0N/A j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
0N/A
0N/A if (!foundDepth) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSD_InitFBObject: could not find valid depth format");
0N/A j2d_glDeleteFramebuffersEXT(1, &fboTmpID);
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A *fbobjectID = fboTmpID;
0N/A *depthID = depthTmpID;
0N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/A/**
0N/A * Initializes a framebuffer object, using the given width and height as
0N/A * a guide. See OGLSD_InitTextureObject() and OGLSD_InitFBObject()
0N/A * for more information.
0N/A */
0N/AJNIEXPORT jboolean JNICALL
0N/AJava_sun_java2d_opengl_OGLSurfaceData_initFBObject
0N/A (JNIEnv *env, jobject oglsd,
0N/A jlong pData, jboolean isOpaque,
0N/A jboolean texNonPow2, jboolean texRect,
0N/A jint width, jint height)
0N/A{
0N/A OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
0N/A GLuint fbobjectID, depthID;
0N/A
0N/A J2dTraceLn2(J2D_TRACE_INFO,
0N/A "OGLSurfaceData_initFBObject: w=%d h=%d",
0N/A width, height);
0N/A
0N/A if (oglsdo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initFBObject: ops are null");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A // initialize color texture object
0N/A if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,
0N/A width, height))
0N/A {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initFBObject: could not init texture object");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A // initialize framebuffer object using color texture created above
0N/A if (!OGLSD_InitFBObject(&fbobjectID, &depthID,
0N/A oglsdo->textureID, oglsdo->textureTarget,
0N/A oglsdo->textureWidth, oglsdo->textureHeight))
0N/A {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initFBObject: could not init fbobject");
0N/A j2d_glDeleteTextures(1, &oglsdo->textureID);
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A oglsdo->drawableType = OGLSD_FBOBJECT;
0N/A // other fields (e.g. width, height) are set in OGLSD_InitTextureObject()
0N/A oglsdo->fbobjectID = fbobjectID;
0N/A oglsdo->depthID = depthID;
0N/A
430N/A OGLSD_SetNativeDimensions(env, oglsdo,
430N/A oglsdo->textureWidth, oglsdo->textureHeight);
430N/A
0N/A // framebuffer objects differ from other OpenGL surfaces in that the
0N/A // value passed to glRead/DrawBuffer() must be GL_COLOR_ATTACHMENTn_EXT,
0N/A // rather than GL_FRONT (or GL_BACK)
0N/A oglsdo->activeBuffer = GL_COLOR_ATTACHMENT0_EXT;
0N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/A/**
0N/A * Initializes a surface in the backbuffer of a given double-buffered
0N/A * onscreen window for use in a BufferStrategy.Flip situation. The bounds of
0N/A * the backbuffer surface should always be kept in sync with the bounds of
0N/A * the underlying native window.
0N/A */
0N/AJNIEXPORT jboolean JNICALL
0N/AJava_sun_java2d_opengl_OGLSurfaceData_initFlipBackbuffer
0N/A (JNIEnv *env, jobject oglsd,
0N/A jlong pData)
0N/A{
0N/A OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_initFlipBackbuffer");
0N/A
0N/A if (oglsdo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initFlipBackbuffer: ops are null");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A if (oglsdo->drawableType == OGLSD_UNDEFINED) {
0N/A if (!OGLSD_InitOGLWindow(env, oglsdo)) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initFlipBackbuffer: could not init window");
0N/A return JNI_FALSE;
0N/A }
0N/A }
0N/A
0N/A if (oglsdo->drawableType != OGLSD_WINDOW) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_initFlipBackbuffer: drawable is not a window");
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A oglsdo->drawableType = OGLSD_FLIP_BACKBUFFER;
0N/A // x/yOffset have already been set in OGLSD_InitOGLWindow()...
0N/A // REMIND: for some reason, flipping won't work properly on IFB unless we
0N/A // explicitly use BACK_LEFT rather than BACK...
0N/A oglsdo->activeBuffer = GL_BACK_LEFT;
0N/A
430N/A OGLSD_SetNativeDimensions(env, oglsdo, oglsdo->width, oglsdo->height);
430N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_java2d_opengl_OGLSurfaceData_getTextureTarget
0N/A (JNIEnv *env, jobject oglsd,
0N/A jlong pData)
0N/A{
0N/A OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_getTextureTarget");
0N/A
0N/A if (oglsdo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLSurfaceData_getTextureTarget: ops are null");
0N/A return 0;
0N/A }
0N/A
0N/A return (jint)oglsdo->textureTarget;
0N/A}
0N/A
430N/AJNIEXPORT jint JNICALL
430N/AJava_sun_java2d_opengl_OGLSurfaceData_getTextureID
430N/A (JNIEnv *env, jobject oglsd,
430N/A jlong pData)
430N/A{
430N/A OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
430N/A
430N/A J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_getTextureID");
430N/A
430N/A if (oglsdo == NULL) {
430N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
430N/A "OGLSurfaceData_getTextureID: ops are null");
430N/A return 0L;
430N/A }
430N/A
430N/A return (jint)oglsdo->textureID;
430N/A}
430N/A
430N/A/**
430N/A * Initializes nativeWidth/Height fields of the surfaceData object with
430N/A * passed arguments.
430N/A */
430N/Avoid
430N/AOGLSD_SetNativeDimensions(JNIEnv *env, OGLSDOps *oglsdo,
430N/A jint width, jint height)
430N/A{
430N/A jobject sdObject;
430N/A
430N/A sdObject = (*env)->NewLocalRef(env, oglsdo->sdOps.sdObject);
430N/A if (sdObject == NULL) {
430N/A return;
430N/A }
430N/A
430N/A JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width);
430N/A JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height);
430N/A
430N/A (*env)->DeleteLocalRef(env, sdObject);
430N/A}
430N/A
0N/A/**
4632N/A * Deletes native OpenGL resources associated with this surface.
0N/A */
0N/Avoid
4632N/AOGLSD_Delete(JNIEnv *env, OGLSDOps *oglsdo)
0N/A{
4632N/A J2dTraceLn1(J2D_TRACE_INFO, "OGLSD_Delete: type=%d",
0N/A oglsdo->drawableType);
0N/A
0N/A if (oglsdo->drawableType == OGLSD_TEXTURE) {
0N/A if (oglsdo->textureID != 0) {
0N/A j2d_glDeleteTextures(1, &oglsdo->textureID);
0N/A oglsdo->textureID = 0;
0N/A }
0N/A } else if (oglsdo->drawableType == OGLSD_FBOBJECT) {
0N/A if (oglsdo->textureID != 0) {
0N/A j2d_glDeleteTextures(1, &oglsdo->textureID);
0N/A oglsdo->textureID = 0;
0N/A }
0N/A if (oglsdo->depthID != 0) {
0N/A j2d_glDeleteRenderbuffersEXT(1, &oglsdo->depthID);
0N/A oglsdo->depthID = 0;
0N/A }
0N/A if (oglsdo->fbobjectID != 0) {
0N/A j2d_glDeleteFramebuffersEXT(1, &oglsdo->fbobjectID);
0N/A oglsdo->fbobjectID = 0;
0N/A }
0N/A } else {
0N/A // dispose windowing system resources (pbuffer, pixmap, etc)
0N/A OGLSD_DestroyOGLSurface(env, oglsdo);
0N/A }
0N/A}
0N/A
0N/A/**
0N/A * This is the implementation of the general DisposeFunc defined in
0N/A * SurfaceData.h and used by the Disposer mechanism. It first flushes all
0N/A * native OpenGL resources and then frees any memory allocated within the
0N/A * native OGLSDOps structure.
0N/A */
0N/Avoid
0N/AOGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
0N/A{
0N/A OGLSDOps *oglsdo = (OGLSDOps *)ops;
0N/A jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo);
0N/A
0N/A JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData",
0N/A "dispose", "(JJ)V",
0N/A ptr_to_jlong(ops), pConfigInfo);
0N/A}
0N/A
0N/A/**
0N/A * This is the implementation of the general surface LockFunc defined in
0N/A * SurfaceData.h.
0N/A */
0N/Ajint
0N/AOGLSD_Lock(JNIEnv *env,
0N/A SurfaceDataOps *ops,
0N/A SurfaceDataRasInfo *pRasInfo,
0N/A jint lockflags)
0N/A{
0N/A JNU_ThrowInternalError(env, "OGLSD_Lock not implemented!");
0N/A return SD_FAILURE;
0N/A}
0N/A
0N/A/**
0N/A * This is the implementation of the general GetRasInfoFunc defined in
0N/A * SurfaceData.h.
0N/A */
0N/Avoid
0N/AOGLSD_GetRasInfo(JNIEnv *env,
0N/A SurfaceDataOps *ops,
0N/A SurfaceDataRasInfo *pRasInfo)
0N/A{
0N/A JNU_ThrowInternalError(env, "OGLSD_GetRasInfo not implemented!");
0N/A}
0N/A
0N/A/**
0N/A * This is the implementation of the general surface UnlockFunc defined in
0N/A * SurfaceData.h.
0N/A */
0N/Avoid
0N/AOGLSD_Unlock(JNIEnv *env,
0N/A SurfaceDataOps *ops,
0N/A SurfaceDataRasInfo *pRasInfo)
0N/A{
0N/A JNU_ThrowInternalError(env, "OGLSD_Unlock not implemented!");
0N/A}
0N/A
0N/A#endif /* !HEADLESS */