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