blob: fe9d37ac643503e4c23e9d257fd3c9c17e138726 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#ifndef HEADLESS
27
28#include <stdlib.h>
29
30#include "sun_java2d_opengl_OGLSurfaceData.h"
31
32#include "jlong.h"
33#include "jni_util.h"
34#include "OGLSurfaceData.h"
35
36/**
37 * The following methods are implemented in the windowing system (i.e. GLX
38 * and WGL) source files.
39 */
40extern jlong OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo);
41extern jboolean OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo);
42extern void OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo);
43
44/**
45 * This table contains the "pixel formats" for all system memory surfaces
46 * that OpenGL is capable of handling, indexed by the "PF_" constants defined
47 * in OGLSurfaceData.java. These pixel formats contain information that is
48 * passed to OpenGL when copying from a system memory ("Sw") surface to
49 * an OpenGL "Surface" (via glDrawPixels()) or "Texture" (via glTexImage2D()).
50 */
51OGLPixelFormat PixelFormats[] = {
52 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
53 4, 1, 0, }, /* 0 - IntArgb */
54 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
55 4, 1, 1, }, /* 1 - IntArgbPre */
56 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
57 4, 0, 1, }, /* 2 - IntRgb */
58 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
59 4, 0, 1, }, /* 3 - IntRgbx */
60 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
61 4, 0, 1, }, /* 4 - IntBgr */
62 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8,
63 4, 0, 1, }, /* 5 - IntBgrx */
64 { GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
65 2, 0, 1, }, /* 6 - Ushort565Rgb */
66 { GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
67 2, 0, 1, }, /* 7 - Ushort555Rgb */
68 { GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
69 2, 0, 1, }, /* 8 - Ushort555Rgbx*/
70 { GL_LUMINANCE, GL_UNSIGNED_BYTE,
71 1, 0, 1, }, /* 9 - ByteGray */
72 { GL_LUMINANCE, GL_UNSIGNED_SHORT,
73 2, 0, 1, }, /*10 - UshortGray */
74};
75
76/**
77 * Given a starting value and a maximum limit, returns the first power-of-two
78 * greater than the starting value. If the resulting value is greater than
79 * the maximum limit, zero is returned.
80 */
81jint
82OGLSD_NextPowerOfTwo(jint val, jint max)
83{
84 jint i;
85
86 if (val > max) {
87 return 0;
88 }
89
90 for (i = 1; i < val; i *= 2);
91
92 return i;
93}
94
95/**
96 * Returns true if both given dimensions are a power of two.
97 */
98static jboolean
99OGLSD_IsPowerOfTwo(jint width, jint height)
100{
101 return (((width & (width-1)) | (height & (height-1))) == 0);
102}
103
104/**
105 * Initializes an OpenGL texture object.
106 *
107 * If the isOpaque parameter is JNI_FALSE, then the texture will have a
108 * full alpha channel; otherwise, the texture will be opaque (this can
109 * help save VRAM when translucency is not needed).
110 *
111 * If the GL_ARB_texture_non_power_of_two extension is present (texNonPow2
112 * is JNI_TRUE), the actual texture is allowed to have non-power-of-two
113 * dimensions, and therefore width==textureWidth and height==textureHeight.
114 *
115 * Failing that, if the GL_ARB_texture_rectangle extension is present
116 * (texRect is JNI_TRUE), the actual texture is allowed to have
117 * non-power-of-two dimensions, except that instead of using the usual
118 * GL_TEXTURE_2D target, we need to use the GL_TEXTURE_RECTANGLE_ARB target.
119 * Note that the GL_REPEAT wrapping mode is not allowed with this target,
120 * so if that mode is needed (e.g. as is the case in the TexturePaint code)
121 * one should pass JNI_FALSE to avoid using this extension. Also note that
122 * when the texture target is GL_TEXTURE_RECTANGLE_ARB, texture coordinates
123 * must be specified in the range [0,width] and [0,height] rather than
124 * [0,1] as is the case with the usual GL_TEXTURE_2D target (so take care)!
125 *
126 * Otherwise, the actual texture must have power-of-two dimensions, and
127 * therefore the textureWidth and textureHeight will be the next
128 * power-of-two greater than (or equal to) the requested width and height.
129 */
130static jboolean
131OGLSD_InitTextureObject(OGLSDOps *oglsdo,
132 jboolean isOpaque,
133 jboolean texNonPow2, jboolean texRect,
134 jint width, jint height)
135{
136 GLenum texTarget, texProxyTarget;
137 GLint format = isOpaque ? GL_RGB : GL_RGBA;
138 GLuint texID;
139 GLsizei texWidth, texHeight, realWidth, realHeight;
140 GLint texMax;
141
142 J2dTraceLn4(J2D_TRACE_INFO,
143 "OGLSD_InitTextureObject: w=%d h=%d opq=%d nonpow2=%d",
144 width, height, isOpaque, texNonPow2);
145
146 if (oglsdo == NULL) {
147 J2dRlsTraceLn(J2D_TRACE_ERROR,
148 "OGLSD_InitTextureObject: ops are null");
149 return JNI_FALSE;
150 }
151
152 if (texNonPow2) {
153 // use non-pow2 dimensions with GL_TEXTURE_2D target
154 j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);
155 texWidth = (width <= texMax) ? width : 0;
156 texHeight = (height <= texMax) ? height : 0;
157 texTarget = GL_TEXTURE_2D;
158 texProxyTarget = GL_PROXY_TEXTURE_2D;
159 } else if (texRect) {
160 // use non-pow2 dimensions with GL_TEXTURE_RECTANGLE_ARB target
161 j2d_glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texMax);
162 texWidth = (width <= texMax) ? width : 0;
163 texHeight = (height <= texMax) ? height : 0;
164 texTarget = GL_TEXTURE_RECTANGLE_ARB;
165 texProxyTarget = GL_PROXY_TEXTURE_RECTANGLE_ARB;
166 } else {
167 // find the appropriate power-of-two dimensions
168 j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax);
169 texWidth = OGLSD_NextPowerOfTwo(width, texMax);
170 texHeight = OGLSD_NextPowerOfTwo(height, texMax);
171 texTarget = GL_TEXTURE_2D;
172 texProxyTarget = GL_PROXY_TEXTURE_2D;
173 }
174
175 J2dTraceLn3(J2D_TRACE_VERBOSE,
176 " desired texture dimensions: w=%d h=%d max=%d",
177 texWidth, texHeight, texMax);
178
179 // if either dimension is 0, we cannot allocate a texture with the
180 // requested dimensions
181 if ((texWidth == 0) || (texHeight == 0)) {
182 J2dRlsTraceLn(J2D_TRACE_ERROR,
183 "OGLSD_InitTextureObject: texture dimensions too large");
184 return JNI_FALSE;
185 }
186
187 // now use a proxy to determine whether we can create a texture with
188 // the calculated power-of-two dimensions and the given internal format
189 j2d_glTexImage2D(texProxyTarget, 0, format,
190 texWidth, texHeight, 0,
191 format, GL_UNSIGNED_BYTE, NULL);
192 j2d_glGetTexLevelParameteriv(texProxyTarget, 0,
193 GL_TEXTURE_WIDTH, &realWidth);
194 j2d_glGetTexLevelParameteriv(texProxyTarget, 0,
195 GL_TEXTURE_HEIGHT, &realHeight);
196
197 // if the requested dimensions and proxy dimensions don't match,
198 // we shouldn't attempt to create the texture
199 if ((realWidth != texWidth) || (realHeight != texHeight)) {
200 J2dRlsTraceLn2(J2D_TRACE_ERROR,
201 "OGLSD_InitTextureObject: actual (w=%d h=%d) != requested",
202 realWidth, realHeight);
203 return JNI_FALSE;
204 }
205
206 // initialize the texture with some dummy data (this allows us to create
207 // a texture object once with 2^n dimensions, and then use
208 // glTexSubImage2D() to provide further updates)
209 j2d_glGenTextures(1, &texID);
210 j2d_glBindTexture(texTarget, texID);
211 j2d_glTexImage2D(texTarget, 0, format,
212 texWidth, texHeight, 0,
213 format, GL_UNSIGNED_BYTE, NULL);
214
215 oglsdo->isOpaque = isOpaque;
216 oglsdo->xOffset = 0;
217 oglsdo->yOffset = 0;
218 oglsdo->width = width;
219 oglsdo->height = height;
220 oglsdo->textureID = texID;
221 oglsdo->textureWidth = texWidth;
222 oglsdo->textureHeight = texHeight;
223 oglsdo->textureTarget = texTarget;
224 OGLSD_INIT_TEXTURE_FILTER(oglsdo, GL_NEAREST);
225 OGLSD_RESET_TEXTURE_WRAP(texTarget);
226
227 J2dTraceLn3(J2D_TRACE_VERBOSE, " created texture: w=%d h=%d id=%d",
228 width, height, texID);
229
230 return JNI_TRUE;
231}
232
233/**
234 * Initializes an OpenGL texture, using the given width and height as
235 * a guide. See OGLSD_InitTextureObject() for more information.
236 */
237JNIEXPORT jboolean JNICALL
238Java_sun_java2d_opengl_OGLSurfaceData_initTexture
239 (JNIEnv *env, jobject oglsd,
240 jlong pData, jboolean isOpaque,
241 jboolean texNonPow2, jboolean texRect,
242 jint width, jint height)
243{
244 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
245
246 J2dTraceLn2(J2D_TRACE_INFO, "OGLSurfaceData_initTexture: w=%d h=%d",
247 width, height);
248
249 if (oglsdo == NULL) {
250 J2dRlsTraceLn(J2D_TRACE_ERROR,
251 "OGLSurfaceData_initTexture: ops are null");
252 return JNI_FALSE;
253 }
254
255 /*
256 * We only use the GL_ARB_texture_rectangle extension if it is available
257 * and the requested bounds are not pow2 (it is probably faster to use
258 * GL_TEXTURE_2D for pow2 textures, and besides, our TexturePaint
259 * code relies on GL_REPEAT, which is not allowed for
260 * GL_TEXTURE_RECTANGLE_ARB targets).
261 */
262 texRect = texRect && !OGLSD_IsPowerOfTwo(width, height);
263
264 if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,
265 width, height))
266 {
267 J2dRlsTraceLn(J2D_TRACE_ERROR,
268 "OGLSurfaceData_initTexture: could not init texture object");
269 return JNI_FALSE;
270 }
271
272 oglsdo->drawableType = OGLSD_TEXTURE;
273 // other fields (e.g. width, height) are set in OGLSD_InitTextureObject()
274
275 return JNI_TRUE;
276}
277
278/**
279 * Initializes a framebuffer object based on the given textureID and its
280 * width/height. This method will iterate through all possible depth formats
281 * to find one that is supported by the drivers/hardware. (Since our use of
282 * the depth buffer is fairly simplistic, we hope to find a depth format that
283 * uses as little VRAM as possible.) If an appropriate depth buffer is found
284 * and all attachments are successful (i.e. the framebuffer object is
285 * "complete"), then this method will return JNI_TRUE and will initialize
286 * the values of fbobjectID and depthID using the IDs created by this method.
287 * Otherwise, this method returns JNI_FALSE. Note that the caller is only
288 * responsible for deleting the allocated fbobject and depth renderbuffer
289 * resources if this method returned JNI_TRUE.
290 */
291jboolean
292OGLSD_InitFBObject(GLuint *fbobjectID, GLuint *depthID,
293 GLuint textureID, GLenum textureTarget,
294 jint textureWidth, jint textureHeight)
295{
296 GLenum depthFormats[] = {
297 GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32
298 };
299 GLuint fboTmpID, depthTmpID;
300 jboolean foundDepth = JNI_FALSE;
301 int i;
302
303 J2dTraceLn3(J2D_TRACE_INFO, "OGLSD_InitFBObject: w=%d h=%d texid=%d",
304 textureWidth, textureHeight, textureID);
305
306 // initialize framebuffer object
307 j2d_glGenFramebuffersEXT(1, &fboTmpID);
308 j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboTmpID);
309
310 // attach color texture to framebuffer object
311 j2d_glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
312 GL_COLOR_ATTACHMENT0_EXT,
313 textureTarget, textureID, 0);
314
315 // attempt to create a depth renderbuffer of a particular format; we
316 // will start with the smallest size and then work our way up
317 for (i = 0; i < 3; i++) {
318 GLenum error, status;
319 GLenum depthFormat = depthFormats[i];
320 int depthSize = 16 + (i * 8);
321
322 // initialize depth renderbuffer
323 j2d_glGenRenderbuffersEXT(1, &depthTmpID);
324 j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthTmpID);
325 j2d_glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat,
326 textureWidth, textureHeight);
327
328 // creation of depth buffer could potentially fail, so check for error
329 error = j2d_glGetError();
330 if (error != GL_NO_ERROR) {
331 J2dTraceLn2(J2D_TRACE_VERBOSE,
332 "OGLSD_InitFBObject: could not create depth buffer: depth=%d error=%x",
333 depthSize, error);
334 j2d_glDeleteRenderbuffersEXT(1, &depthTmpID);
335 continue;
336 }
337
338 // attach depth renderbuffer to framebuffer object
339 j2d_glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
340 GL_DEPTH_ATTACHMENT_EXT,
341 GL_RENDERBUFFER_EXT, depthTmpID);
342
343 // now check for framebuffer "completeness"
344 status = j2d_glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
345
346 if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
347 // we found a valid format, so break out of the loop
348 J2dTraceLn1(J2D_TRACE_VERBOSE,
349 " framebuffer is complete: depth=%d", depthSize);
350 foundDepth = JNI_TRUE;
351 break;
352 } else {
353 // this depth format didn't work, so delete and try another format
354 J2dTraceLn2(J2D_TRACE_VERBOSE,
355 " framebuffer is incomplete: depth=%d status=%x",
356 depthSize, status);
357 j2d_glDeleteRenderbuffersEXT(1, &depthTmpID);
358 }
359 }
360
361 // unbind the texture and framebuffer objects (they will be bound again
362 // later as needed)
363 j2d_glBindTexture(textureTarget, 0);
364 j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
365 j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
366
367 if (!foundDepth) {
368 J2dRlsTraceLn(J2D_TRACE_ERROR,
369 "OGLSD_InitFBObject: could not find valid depth format");
370 j2d_glDeleteFramebuffersEXT(1, &fboTmpID);
371 return JNI_FALSE;
372 }
373
374 *fbobjectID = fboTmpID;
375 *depthID = depthTmpID;
376
377 return JNI_TRUE;
378}
379
380/**
381 * Initializes a framebuffer object, using the given width and height as
382 * a guide. See OGLSD_InitTextureObject() and OGLSD_InitFBObject()
383 * for more information.
384 */
385JNIEXPORT jboolean JNICALL
386Java_sun_java2d_opengl_OGLSurfaceData_initFBObject
387 (JNIEnv *env, jobject oglsd,
388 jlong pData, jboolean isOpaque,
389 jboolean texNonPow2, jboolean texRect,
390 jint width, jint height)
391{
392 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
393 GLuint fbobjectID, depthID;
394
395 J2dTraceLn2(J2D_TRACE_INFO,
396 "OGLSurfaceData_initFBObject: w=%d h=%d",
397 width, height);
398
399 if (oglsdo == NULL) {
400 J2dRlsTraceLn(J2D_TRACE_ERROR,
401 "OGLSurfaceData_initFBObject: ops are null");
402 return JNI_FALSE;
403 }
404
405 // initialize color texture object
406 if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect,
407 width, height))
408 {
409 J2dRlsTraceLn(J2D_TRACE_ERROR,
410 "OGLSurfaceData_initFBObject: could not init texture object");
411 return JNI_FALSE;
412 }
413
414 // initialize framebuffer object using color texture created above
415 if (!OGLSD_InitFBObject(&fbobjectID, &depthID,
416 oglsdo->textureID, oglsdo->textureTarget,
417 oglsdo->textureWidth, oglsdo->textureHeight))
418 {
419 J2dRlsTraceLn(J2D_TRACE_ERROR,
420 "OGLSurfaceData_initFBObject: could not init fbobject");
421 j2d_glDeleteTextures(1, &oglsdo->textureID);
422 return JNI_FALSE;
423 }
424
425 oglsdo->drawableType = OGLSD_FBOBJECT;
426 // other fields (e.g. width, height) are set in OGLSD_InitTextureObject()
427 oglsdo->fbobjectID = fbobjectID;
428 oglsdo->depthID = depthID;
429
430 // framebuffer objects differ from other OpenGL surfaces in that the
431 // value passed to glRead/DrawBuffer() must be GL_COLOR_ATTACHMENTn_EXT,
432 // rather than GL_FRONT (or GL_BACK)
433 oglsdo->activeBuffer = GL_COLOR_ATTACHMENT0_EXT;
434
435 return JNI_TRUE;
436}
437
438/**
439 * Initializes a surface in the backbuffer of a given double-buffered
440 * onscreen window for use in a BufferStrategy.Flip situation. The bounds of
441 * the backbuffer surface should always be kept in sync with the bounds of
442 * the underlying native window.
443 */
444JNIEXPORT jboolean JNICALL
445Java_sun_java2d_opengl_OGLSurfaceData_initFlipBackbuffer
446 (JNIEnv *env, jobject oglsd,
447 jlong pData)
448{
449 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
450
451 J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_initFlipBackbuffer");
452
453 if (oglsdo == NULL) {
454 J2dRlsTraceLn(J2D_TRACE_ERROR,
455 "OGLSurfaceData_initFlipBackbuffer: ops are null");
456 return JNI_FALSE;
457 }
458
459 if (oglsdo->drawableType == OGLSD_UNDEFINED) {
460 if (!OGLSD_InitOGLWindow(env, oglsdo)) {
461 J2dRlsTraceLn(J2D_TRACE_ERROR,
462 "OGLSurfaceData_initFlipBackbuffer: could not init window");
463 return JNI_FALSE;
464 }
465 }
466
467 if (oglsdo->drawableType != OGLSD_WINDOW) {
468 J2dRlsTraceLn(J2D_TRACE_ERROR,
469 "OGLSurfaceData_initFlipBackbuffer: drawable is not a window");
470 return JNI_FALSE;
471 }
472
473 oglsdo->drawableType = OGLSD_FLIP_BACKBUFFER;
474 // x/yOffset have already been set in OGLSD_InitOGLWindow()...
475 // REMIND: for some reason, flipping won't work properly on IFB unless we
476 // explicitly use BACK_LEFT rather than BACK...
477 oglsdo->activeBuffer = GL_BACK_LEFT;
478
479 return JNI_TRUE;
480}
481
482JNIEXPORT jint JNICALL
483Java_sun_java2d_opengl_OGLSurfaceData_getTextureTarget
484 (JNIEnv *env, jobject oglsd,
485 jlong pData)
486{
487 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
488
489 J2dTraceLn(J2D_TRACE_INFO, "OGLSurfaceData_getTextureTarget");
490
491 if (oglsdo == NULL) {
492 J2dRlsTraceLn(J2D_TRACE_ERROR,
493 "OGLSurfaceData_getTextureTarget: ops are null");
494 return 0;
495 }
496
497 return (jint)oglsdo->textureTarget;
498}
499
500/**
501 * Disposes of all native resources associated with this surface.
502 */
503void
504OGLSD_Flush(JNIEnv *env, OGLSDOps *oglsdo)
505{
506 J2dTraceLn1(J2D_TRACE_INFO, "OGLSD_Flush: type=%d",
507 oglsdo->drawableType);
508
509 if (oglsdo->drawableType == OGLSD_TEXTURE) {
510 if (oglsdo->textureID != 0) {
511 j2d_glDeleteTextures(1, &oglsdo->textureID);
512 oglsdo->textureID = 0;
513 }
514 } else if (oglsdo->drawableType == OGLSD_FBOBJECT) {
515 if (oglsdo->textureID != 0) {
516 j2d_glDeleteTextures(1, &oglsdo->textureID);
517 oglsdo->textureID = 0;
518 }
519 if (oglsdo->depthID != 0) {
520 j2d_glDeleteRenderbuffersEXT(1, &oglsdo->depthID);
521 oglsdo->depthID = 0;
522 }
523 if (oglsdo->fbobjectID != 0) {
524 j2d_glDeleteFramebuffersEXT(1, &oglsdo->fbobjectID);
525 oglsdo->fbobjectID = 0;
526 }
527 } else {
528 // dispose windowing system resources (pbuffer, pixmap, etc)
529 OGLSD_DestroyOGLSurface(env, oglsdo);
530 }
531}
532
533/**
534 * This is the implementation of the general DisposeFunc defined in
535 * SurfaceData.h and used by the Disposer mechanism. It first flushes all
536 * native OpenGL resources and then frees any memory allocated within the
537 * native OGLSDOps structure.
538 */
539void
540OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
541{
542 OGLSDOps *oglsdo = (OGLSDOps *)ops;
543 jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo);
544
545 JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData",
546 "dispose", "(JJ)V",
547 ptr_to_jlong(ops), pConfigInfo);
548}
549
550/**
551 * This is the implementation of the general surface LockFunc defined in
552 * SurfaceData.h.
553 */
554jint
555OGLSD_Lock(JNIEnv *env,
556 SurfaceDataOps *ops,
557 SurfaceDataRasInfo *pRasInfo,
558 jint lockflags)
559{
560 JNU_ThrowInternalError(env, "OGLSD_Lock not implemented!");
561 return SD_FAILURE;
562}
563
564/**
565 * This is the implementation of the general GetRasInfoFunc defined in
566 * SurfaceData.h.
567 */
568void
569OGLSD_GetRasInfo(JNIEnv *env,
570 SurfaceDataOps *ops,
571 SurfaceDataRasInfo *pRasInfo)
572{
573 JNU_ThrowInternalError(env, "OGLSD_GetRasInfo not implemented!");
574}
575
576/**
577 * This is the implementation of the general surface UnlockFunc defined in
578 * SurfaceData.h.
579 */
580void
581OGLSD_Unlock(JNIEnv *env,
582 SurfaceDataOps *ops,
583 SurfaceDataRasInfo *pRasInfo)
584{
585 JNU_ThrowInternalError(env, "OGLSD_Unlock not implemented!");
586}
587
588#endif /* !HEADLESS */