Path: blob/master/src/java.desktop/share/native/common/java2d/opengl/OGLSurfaceData.c
41159 views
/*1* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#ifndef HEADLESS2627#include <stdlib.h>2829#include "sun_java2d_opengl_OGLSurfaceData.h"3031#include "jlong.h"32#include "jni_util.h"33#include "OGLSurfaceData.h"3435/**36* The following methods are implemented in the windowing system (i.e. GLX37* and WGL) source files.38*/39extern jboolean OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo);40extern void OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo);4142void OGLSD_SetNativeDimensions(JNIEnv *env, OGLSDOps *oglsdo, jint w, jint h);4344/**45* This table contains the "pixel formats" for all system memory surfaces46* that OpenGL is capable of handling, indexed by the "PF_" constants defined47* in OGLSurfaceData.java. These pixel formats contain information that is48* passed to OpenGL when copying from a system memory ("Sw") surface to49* an OpenGL "Surface" (via glDrawPixels()) or "Texture" (via glTexImage2D()).50*/51OGLPixelFormat PixelFormats[] = {52{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,534, 1, 0, }, /* 0 - IntArgb */54{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,554, 1, 1, }, /* 1 - IntArgbPre */56{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,574, 0, 1, }, /* 2 - IntRgb */58{ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,594, 0, 1, }, /* 3 - IntRgbx */60{ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,614, 0, 1, }, /* 4 - IntBgr */62{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8,634, 0, 1, }, /* 5 - IntBgrx */64{ GL_RGB, GL_UNSIGNED_SHORT_5_6_5,652, 0, 1, }, /* 6 - Ushort565Rgb */66{ GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,672, 0, 1, }, /* 7 - Ushort555Rgb */68{ GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,692, 0, 1, }, /* 8 - Ushort555Rgbx*/70{ GL_LUMINANCE, GL_UNSIGNED_BYTE,711, 0, 1, }, /* 9 - ByteGray */72{ GL_LUMINANCE, GL_UNSIGNED_SHORT,732, 0, 1, }, /*10 - UshortGray */74{ GL_BGR, GL_UNSIGNED_BYTE,751, 0, 1, }, /*11 - ThreeByteBgr */};7677/**78* Given a starting value and a maximum limit, returns the first power-of-two79* greater than the starting value. If the resulting value is greater than80* the maximum limit, zero is returned.81*/82jint83OGLSD_NextPowerOfTwo(jint val, jint max)84{85jint i;8687if (val > max) {88return 0;89}9091for (i = 1; i < val; i *= 2);9293return i;94}9596/**97* Returns true if both given dimensions are a power of two.98*/99static jboolean100OGLSD_IsPowerOfTwo(jint width, jint height)101{102return (((width & (width-1)) | (height & (height-1))) == 0);103}104105/**106* Initializes an OpenGL texture object.107*108* If the isOpaque parameter is JNI_FALSE, then the texture will have a109* full alpha channel; otherwise, the texture will be opaque (this can110* help save VRAM when translucency is not needed).111*112* If the GL_ARB_texture_non_power_of_two extension is present (texNonPow2113* is JNI_TRUE), the actual texture is allowed to have non-power-of-two114* dimensions, and therefore width==textureWidth and height==textureHeight.115*116* Failing that, if the GL_ARB_texture_rectangle extension is present117* (texRect is JNI_TRUE), the actual texture is allowed to have118* non-power-of-two dimensions, except that instead of using the usual119* GL_TEXTURE_2D target, we need to use the GL_TEXTURE_RECTANGLE_ARB target.120* Note that the GL_REPEAT wrapping mode is not allowed with this target,121* so if that mode is needed (e.g. as is the case in the TexturePaint code)122* one should pass JNI_FALSE to avoid using this extension. Also note that123* when the texture target is GL_TEXTURE_RECTANGLE_ARB, texture coordinates124* must be specified in the range [0,width] and [0,height] rather than125* [0,1] as is the case with the usual GL_TEXTURE_2D target (so take care)!126*127* Otherwise, the actual texture must have power-of-two dimensions, and128* therefore the textureWidth and textureHeight will be the next129* power-of-two greater than (or equal to) the requested width and height.130*/131static jboolean132OGLSD_InitTextureObject(OGLSDOps *oglsdo,133jboolean isOpaque,134jboolean texNonPow2, jboolean texRect,135jint width, jint height)136{137GLenum texTarget, texProxyTarget;138GLint format = GL_RGBA;139GLint size = GL_UNSIGNED_INT_8_8_8_8;140GLuint texID;141GLsizei texWidth, texHeight, realWidth, realHeight;142GLint texMax;143144J2dTraceLn4(J2D_TRACE_INFO,145"OGLSD_InitTextureObject: w=%d h=%d opq=%d nonpow2=%d",146width, height, isOpaque, texNonPow2);147148if (oglsdo == NULL) {149J2dRlsTraceLn(J2D_TRACE_ERROR,150"OGLSD_InitTextureObject: ops are null");151return JNI_FALSE;152}153154if (texNonPow2) {155// use non-pow2 dimensions with GL_TEXTURE_2D target156j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);157texWidth = (width <= texMax) ? width : 0;158texHeight = (height <= texMax) ? height : 0;159texTarget = GL_TEXTURE_2D;160texProxyTarget = GL_PROXY_TEXTURE_2D;161} else if (texRect) {162// use non-pow2 dimensions with GL_TEXTURE_RECTANGLE_ARB target163j2d_glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texMax);164texWidth = (width <= texMax) ? width : 0;165texHeight = (height <= texMax) ? height : 0;166texTarget = GL_TEXTURE_RECTANGLE_ARB;167texProxyTarget = GL_PROXY_TEXTURE_RECTANGLE_ARB;168} else {169// find the appropriate power-of-two dimensions170j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);171texWidth = OGLSD_NextPowerOfTwo(width, texMax);172texHeight = OGLSD_NextPowerOfTwo(height, texMax);173texTarget = GL_TEXTURE_2D;174texProxyTarget = GL_PROXY_TEXTURE_2D;175}176177J2dTraceLn3(J2D_TRACE_VERBOSE,178" desired texture dimensions: w=%d h=%d max=%d",179texWidth, texHeight, texMax);180181// if either dimension is 0, we cannot allocate a texture with the182// requested dimensions183if ((texWidth == 0) || (texHeight == 0)) {184J2dRlsTraceLn(J2D_TRACE_ERROR,185"OGLSD_InitTextureObject: texture dimensions too large");186return JNI_FALSE;187}188189// now use a proxy to determine whether we can create a texture with190// the calculated power-of-two dimensions and the given internal format191j2d_glTexImage2D(texProxyTarget, 0, format,192texWidth, texHeight, 0,193format, size, NULL);194j2d_glGetTexLevelParameteriv(texProxyTarget, 0,195GL_TEXTURE_WIDTH, &realWidth);196j2d_glGetTexLevelParameteriv(texProxyTarget, 0,197GL_TEXTURE_HEIGHT, &realHeight);198199// if the requested dimensions and proxy dimensions don't match,200// we shouldn't attempt to create the texture201if ((realWidth != texWidth) || (realHeight != texHeight)) {202J2dRlsTraceLn2(J2D_TRACE_ERROR,203"OGLSD_InitTextureObject: actual (w=%d h=%d) != requested",204realWidth, realHeight);205return JNI_FALSE;206}207208// initialize the texture with some dummy data (this allows us to create209// a texture object once with 2^n dimensions, and then use210// glTexSubImage2D() to provide further updates)211j2d_glGenTextures(1, &texID);212j2d_glBindTexture(texTarget, texID);213j2d_glTexImage2D(texTarget, 0, format,214texWidth, texHeight, 0,215format, size, NULL);216217oglsdo->isOpaque = isOpaque;218oglsdo->xOffset = 0;219oglsdo->yOffset = 0;220oglsdo->width = width;221oglsdo->height = height;222oglsdo->textureID = texID;223oglsdo->textureWidth = texWidth;224oglsdo->textureHeight = texHeight;225oglsdo->textureTarget = texTarget;226OGLSD_INIT_TEXTURE_FILTER(oglsdo, GL_NEAREST);227OGLSD_RESET_TEXTURE_WRAP(texTarget);228229J2dTraceLn3(J2D_TRACE_VERBOSE, " created texture: w=%d h=%d id=%d",230width, height, texID);231232return JNI_TRUE;233}234235/**236* Initializes an OpenGL texture, using the given width and height as237* a guide. See OGLSD_InitTextureObject() for more information.238*/239JNIEXPORT jboolean JNICALL240Java_sun_java2d_opengl_OGLSurfaceData_initTexture241(JNIEnv *env, jobject oglsd,242jlong pData, jboolean isOpaque,243jboolean texNonPow2, jboolean texRect,244jint width, jint height)245{246OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);247248J2dTraceLn2(J2D_TRACE_INFO, "OGLSurfaceData_initTexture: w=%d h=%d",249width, height);250251if (oglsdo == NULL) {252J2dRlsTraceLn(J2D_TRACE_ERROR,253"OGLSurfaceData_initTexture: ops are null");254return JNI_FALSE;255}256257/*258* We only use the GL_ARB_texture_rectangle extension if it is available259* and the requested bounds are not pow2 (it is probably faster to use260* GL_TEXTURE_2D for pow2 textures, and besides, our TexturePaint261* code relies on GL_REPEAT, which is not allowed for262* GL_TEXTURE_RECTANGLE_ARB targets).263*/264texRect = texRect && !OGLSD_IsPowerOfTwo(width, height);265266if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,267width, height))268{269J2dRlsTraceLn(J2D_TRACE_ERROR,270"OGLSurfaceData_initTexture: could not init texture object");271return JNI_FALSE;272}273274OGLSD_SetNativeDimensions(env, oglsdo,275oglsdo->textureWidth, oglsdo->textureHeight);276277oglsdo->drawableType = OGLSD_TEXTURE;278// other fields (e.g. width, height) are set in OGLSD_InitTextureObject()279280return JNI_TRUE;281}282283/**284* Initializes a framebuffer object based on the given textureID and its285* width/height. This method will iterate through all possible depth formats286* to find one that is supported by the drivers/hardware. (Since our use of287* the depth buffer is fairly simplistic, we hope to find a depth format that288* uses as little VRAM as possible.) If an appropriate depth buffer is found289* and all attachments are successful (i.e. the framebuffer object is290* "complete"), then this method will return JNI_TRUE and will initialize291* the values of fbobjectID and depthID using the IDs created by this method.292* Otherwise, this method returns JNI_FALSE. Note that the caller is only293* responsible for deleting the allocated fbobject and depth renderbuffer294* resources if this method returned JNI_TRUE.295*/296jboolean297OGLSD_InitFBObject(GLuint *fbobjectID, GLuint *depthID,298GLuint textureID, GLenum textureTarget,299jint textureWidth, jint textureHeight)300{301GLenum depthFormats[] = {302GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32303};304GLuint fboTmpID, depthTmpID;305jboolean foundDepth = JNI_FALSE;306int i;307308J2dTraceLn3(J2D_TRACE_INFO, "OGLSD_InitFBObject: w=%d h=%d texid=%d",309textureWidth, textureHeight, textureID);310311// initialize framebuffer object312j2d_glGenFramebuffersEXT(1, &fboTmpID);313j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboTmpID);314315// attach color texture to framebuffer object316j2d_glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,317GL_COLOR_ATTACHMENT0_EXT,318textureTarget, textureID, 0);319320// attempt to create a depth renderbuffer of a particular format; we321// will start with the smallest size and then work our way up322for (i = 0; i < 3; i++) {323GLenum error, status;324GLenum depthFormat = depthFormats[i];325int depthSize = 16 + (i * 8);326327// initialize depth renderbuffer328j2d_glGenRenderbuffersEXT(1, &depthTmpID);329j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthTmpID);330j2d_glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat,331textureWidth, textureHeight);332333// creation of depth buffer could potentially fail, so check for error334error = j2d_glGetError();335if (error != GL_NO_ERROR) {336J2dTraceLn2(J2D_TRACE_VERBOSE,337"OGLSD_InitFBObject: could not create depth buffer: depth=%d error=%x",338depthSize, error);339j2d_glDeleteRenderbuffersEXT(1, &depthTmpID);340continue;341}342343// attach depth renderbuffer to framebuffer object344j2d_glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,345GL_DEPTH_ATTACHMENT_EXT,346GL_RENDERBUFFER_EXT, depthTmpID);347348// now check for framebuffer "completeness"349status = j2d_glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);350351if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {352// we found a valid format, so break out of the loop353J2dTraceLn1(J2D_TRACE_VERBOSE,354" framebuffer is complete: depth=%d", depthSize);355foundDepth = JNI_TRUE;356break;357} else {358// this depth format didn't work, so delete and try another format359J2dTraceLn2(J2D_TRACE_VERBOSE,360" framebuffer is incomplete: depth=%d status=%x",361depthSize, status);362j2d_glDeleteRenderbuffersEXT(1, &depthTmpID);363}364}365366// unbind the texture and framebuffer objects (they will be bound again367// later as needed)368j2d_glBindTexture(textureTarget, 0);369j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);370j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);371372if (!foundDepth) {373J2dRlsTraceLn(J2D_TRACE_ERROR,374"OGLSD_InitFBObject: could not find valid depth format");375j2d_glDeleteFramebuffersEXT(1, &fboTmpID);376return JNI_FALSE;377}378379*fbobjectID = fboTmpID;380*depthID = depthTmpID;381382return JNI_TRUE;383}384385/**386* Initializes a framebuffer object, using the given width and height as387* a guide. See OGLSD_InitTextureObject() and OGLSD_InitFBObject()388* for more information.389*/390JNIEXPORT jboolean JNICALL391Java_sun_java2d_opengl_OGLSurfaceData_initFBObject392(JNIEnv *env, jobject oglsd,393jlong pData, jboolean isOpaque,394jboolean texNonPow2, jboolean texRect,395jint width, jint height)396{397OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);398GLuint fbobjectID, depthID;399400J2dTraceLn2(J2D_TRACE_INFO,401"OGLSurfaceData_initFBObject: w=%d h=%d",402width, height);403404if (oglsdo == NULL) {405J2dRlsTraceLn(J2D_TRACE_ERROR,406"OGLSurfaceData_initFBObject: ops are null");407return JNI_FALSE;408}409410// initialize color texture object411if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,412width, height))413{414J2dRlsTraceLn(J2D_TRACE_ERROR,415"OGLSurfaceData_initFBObject: could not init texture object");416return JNI_FALSE;417}418419// initialize framebuffer object using color texture created above420if (!OGLSD_InitFBObject(&fbobjectID, &depthID,421oglsdo->textureID, oglsdo->textureTarget,422oglsdo->textureWidth, oglsdo->textureHeight))423{424J2dRlsTraceLn(J2D_TRACE_ERROR,425"OGLSurfaceData_initFBObject: could not init fbobject");426j2d_glDeleteTextures(1, &oglsdo->textureID);427return JNI_FALSE;428}429430oglsdo->drawableType = OGLSD_FBOBJECT;431// other fields (e.g. width, height) are set in OGLSD_InitTextureObject()432oglsdo->fbobjectID = fbobjectID;433oglsdo->depthID = depthID;434435OGLSD_SetNativeDimensions(env, oglsdo,436oglsdo->textureWidth, oglsdo->textureHeight);437438// framebuffer objects differ from other OpenGL surfaces in that the439// value passed to glRead/DrawBuffer() must be GL_COLOR_ATTACHMENTn_EXT,440// rather than GL_FRONT (or GL_BACK)441oglsdo->activeBuffer = GL_COLOR_ATTACHMENT0_EXT;442443return JNI_TRUE;444}445446/**447* Initializes a surface in the backbuffer of a given double-buffered448* onscreen window for use in a BufferStrategy.Flip situation. The bounds of449* the backbuffer surface should always be kept in sync with the bounds of450* the underlying native window.451*/452JNIEXPORT jboolean JNICALL453Java_sun_java2d_opengl_OGLSurfaceData_initFlipBackbuffer454(JNIEnv *env, jobject oglsd,455jlong pData)456{457OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);458459J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_initFlipBackbuffer");460461if (oglsdo == NULL) {462J2dRlsTraceLn(J2D_TRACE_ERROR,463"OGLSurfaceData_initFlipBackbuffer: ops are null");464return JNI_FALSE;465}466467if (oglsdo->drawableType == OGLSD_UNDEFINED) {468if (!OGLSD_InitOGLWindow(env, oglsdo)) {469J2dRlsTraceLn(J2D_TRACE_ERROR,470"OGLSurfaceData_initFlipBackbuffer: could not init window");471return JNI_FALSE;472}473}474475if (oglsdo->drawableType != OGLSD_WINDOW) {476J2dRlsTraceLn(J2D_TRACE_ERROR,477"OGLSurfaceData_initFlipBackbuffer: drawable is not a window");478return JNI_FALSE;479}480481oglsdo->drawableType = OGLSD_FLIP_BACKBUFFER;482// x/yOffset have already been set in OGLSD_InitOGLWindow()...483// REMIND: for some reason, flipping won't work properly on IFB unless we484// explicitly use BACK_LEFT rather than BACK...485oglsdo->activeBuffer = GL_BACK_LEFT;486487OGLSD_SetNativeDimensions(env, oglsdo, oglsdo->width, oglsdo->height);488489return JNI_TRUE;490}491492JNIEXPORT jint JNICALL493Java_sun_java2d_opengl_OGLSurfaceData_getTextureTarget494(JNIEnv *env, jobject oglsd,495jlong pData)496{497OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);498499J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_getTextureTarget");500501if (oglsdo == NULL) {502J2dRlsTraceLn(J2D_TRACE_ERROR,503"OGLSurfaceData_getTextureTarget: ops are null");504return 0;505}506507return (jint)oglsdo->textureTarget;508}509510JNIEXPORT jint JNICALL511Java_sun_java2d_opengl_OGLSurfaceData_getTextureID512(JNIEnv *env, jobject oglsd,513jlong pData)514{515OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);516517J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_getTextureID");518519if (oglsdo == NULL) {520J2dRlsTraceLn(J2D_TRACE_ERROR,521"OGLSurfaceData_getTextureID: ops are null");522return 0L;523}524525return (jint)oglsdo->textureID;526}527528/**529* Initializes nativeWidth/Height fields of the surfaceData object with530* passed arguments.531*/532void533OGLSD_SetNativeDimensions(JNIEnv *env, OGLSDOps *oglsdo,534jint width, jint height)535{536jobject sdObject;537538sdObject = (*env)->NewLocalRef(env, oglsdo->sdOps.sdObject);539if (sdObject == NULL) {540return;541}542543JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width);544if (!((*env)->ExceptionOccurred(env))) {545JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height);546}547548(*env)->DeleteLocalRef(env, sdObject);549}550551/**552* Deletes native OpenGL resources associated with this surface.553*/554void555OGLSD_Delete(JNIEnv *env, OGLSDOps *oglsdo)556{557J2dTraceLn1(J2D_TRACE_INFO, "OGLSD_Delete: type=%d",558oglsdo->drawableType);559560if (oglsdo->drawableType == OGLSD_TEXTURE) {561if (oglsdo->textureID != 0) {562j2d_glDeleteTextures(1, &oglsdo->textureID);563oglsdo->textureID = 0;564}565} else if (oglsdo->drawableType == OGLSD_FBOBJECT) {566if (oglsdo->textureID != 0) {567j2d_glDeleteTextures(1, &oglsdo->textureID);568oglsdo->textureID = 0;569}570if (oglsdo->depthID != 0) {571j2d_glDeleteRenderbuffersEXT(1, &oglsdo->depthID);572oglsdo->depthID = 0;573}574if (oglsdo->fbobjectID != 0) {575j2d_glDeleteFramebuffersEXT(1, &oglsdo->fbobjectID);576oglsdo->fbobjectID = 0;577}578} else {579// dispose windowing system resources (pbuffer, pixmap, etc)580OGLSD_DestroyOGLSurface(env, oglsdo);581}582}583584/**585* This is the implementation of the general DisposeFunc defined in586* SurfaceData.h and used by the Disposer mechanism. It first flushes all587* native OpenGL resources and then frees any memory allocated within the588* native OGLSDOps structure.589*/590void591OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)592{593OGLSDOps *oglsdo = (OGLSDOps *)ops;594jobject graphicsConfig = oglsdo->graphicsConfig;595596JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData",597"dispose",598"(JLsun/java2d/opengl/OGLGraphicsConfig;)V",599ptr_to_jlong(ops), graphicsConfig);600(*env)->DeleteGlobalRef(env, graphicsConfig);601oglsdo->graphicsConfig = NULL;602}603604/**605* This is the implementation of the general surface LockFunc defined in606* SurfaceData.h.607*/608jint609OGLSD_Lock(JNIEnv *env,610SurfaceDataOps *ops,611SurfaceDataRasInfo *pRasInfo,612jint lockflags)613{614JNU_ThrowInternalError(env, "OGLSD_Lock not implemented!");615return SD_FAILURE;616}617618/**619* This is the implementation of the general GetRasInfoFunc defined in620* SurfaceData.h.621*/622void623OGLSD_GetRasInfo(JNIEnv *env,624SurfaceDataOps *ops,625SurfaceDataRasInfo *pRasInfo)626{627JNU_ThrowInternalError(env, "OGLSD_GetRasInfo not implemented!");628}629630/**631* This is the implementation of the general surface UnlockFunc defined in632* SurfaceData.h.633*/634void635OGLSD_Unlock(JNIEnv *env,636SurfaceDataOps *ops,637SurfaceDataRasInfo *pRasInfo)638{639JNU_ThrowInternalError(env, "OGLSD_Unlock not implemented!");640}641642#endif /* !HEADLESS */643644645