1 /*
2 * Copyright (c) 2011, 2012, 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
93 CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
94 #if USE_NSVIEW_FOR_SCRATCH
95 [ctxinfo->context makeCurrentContext];
96 [ctxinfo->context setView: ctxinfo->scratchSurface];
97 #else
98 [ctxinfo->context clearDrawable];
99 [ctxinfo->context makeCurrentContext];
100 [ctxinfo->context setPixelBuffer: ctxinfo->scratchSurface
101 cubeMapFace: 0
102 mipMapLevel: 0
103 currentVirtualScreen: [ctxinfo->context currentVirtualScreen]];
104 #endif
105
106 JNF_COCOA_EXIT(env);
107
108 return JNI_TRUE;
109 }
110
111 /**
112 * This function disposes of any native windowing system resources associated
113 * with this surface. For instance, if the given OGLSDOps is of type
114 * OGLSD_PBUFFER, this method implementation will destroy the actual pbuffer
115 * surface.
116 */
117 void
118 OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
119 {
120 J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
121
122 JNF_COCOA_ENTER(env);
123
124 CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
125 if (oglsdo->drawableType == OGLSD_PBUFFER) {
126 if (oglsdo->textureID != 0) {
127 j2d_glDeleteTextures(1, &oglsdo->textureID);
128 oglsdo->textureID = 0;
129 }
130 if (cglsdo->pbuffer != NULL) {
131 [cglsdo->pbuffer release];
132 cglsdo->pbuffer = NULL;
133 }
134 } else if (oglsdo->drawableType == OGLSD_WINDOW) {
135 // detach the NSView from the NSOpenGLContext
136 CGLGraphicsConfigInfo *cglInfo = cglsdo->configInfo;
137 OGLContext *oglc = cglInfo->context;
138 CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
139 [ctxinfo->context clearDrawable];
140 }
141
142 oglsdo->drawableType = OGLSD_UNDEFINED;
143
144 JNF_COCOA_EXIT(env);
145 }
146
147 /**
148 * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo
149 * associated with the given OGLSDOps. This method can be called from
150 * shared code to retrieve the native GraphicsConfig data in a platform-
151 * independent manner.
152 */
153 jlong
154 OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
260 // already current to some drawable, we will make it current to
261 // its scratch surface)
262 if (oglc != currentContext) {
263 if (!CGLSD_MakeCurrentToScratch(env, oglc)) {
264 return NULL;
265 }
266 }
267
268 // now bind to the fbobject associated with the destination surface;
269 // this means that all rendering will go into the fbobject destination
270 // (note that we unbind the currently bound texture first; this is
271 // recommended procedure when binding an fbobject)
272 j2d_glBindTexture(GL_TEXTURE_2D, 0);
273 j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dstOps->fbobjectID);
274
275 return oglc;
276 }
277
278 JNF_COCOA_ENTER(env);
279
280 // set the current surface
281 if (dstOps->drawableType == OGLSD_PBUFFER) {
282 // REMIND: pbuffers are not fully tested yet...
283 [ctxinfo->context clearDrawable];
284 [ctxinfo->context makeCurrentContext];
285 [ctxinfo->context setPixelBuffer: dstCGLOps->pbuffer
286 cubeMapFace: 0
287 mipMapLevel: 0
288 currentVirtualScreen: [ctxinfo->context currentVirtualScreen]];
289 } else {
290 CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps;
291 NSView *nsView = (NSView *)cglsdo->peerData;
292
293 if ([ctxinfo->context view] != nsView) {
294 [ctxinfo->context makeCurrentContext];
295 [ctxinfo->context setView: nsView];
296 }
297 }
298
299 if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
300 // the GL_EXT_framebuffer_object extension is present, so we
301 // must bind to the default (windowing system provided)
302 // framebuffer
303 j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
304 }
305
306 if ((srcOps != dstOps) && (srcOps->drawableType == OGLSD_PBUFFER)) {
307 // bind pbuffer to the render texture object (since we are preparing
308 // to copy from the pbuffer)
309 CGLSDOps *srcCGLOps = (CGLSDOps *)srcOps->privOps;
310 j2d_glBindTexture(GL_TEXTURE_2D, srcOps->textureID);
311 [ctxinfo->context
312 setTextureImageToPixelBuffer: srcCGLOps->pbuffer
313 colorBuffer: GL_FRONT];
314 }
315
316 JNF_COCOA_EXIT(env);
317
318 return oglc;
319 }
320
321 /**
322 * This function initializes a native window surface and caches the window
323 * bounds in the given OGLSDOps. Returns JNI_TRUE if the operation was
324 * successful; JNI_FALSE otherwise.
325 */
326 jboolean
327 OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
328 {
329 J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow");
330
331 if (oglsdo == NULL) {
332 J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: ops are null");
333 return JNI_FALSE;
334 }
335
447
448 if (cglsdo->configInfo == NULL) {
449 free(cglsdo);
450 JNU_ThrowNullPointerException(env, "Config info is null in initOps");
451 }
452 }
453
454 JNIEXPORT void JNICALL
455 Java_sun_java2d_opengl_CGLSurfaceData_clearWindow
456 (JNIEnv *env, jobject cglsd)
457 {
458 J2dTraceLn(J2D_TRACE_INFO, "CGLSurfaceData_clearWindow");
459
460 OGLSDOps *oglsdo = (OGLSDOps*) SurfaceData_GetOps(env, cglsd);
461 CGLSDOps *cglsdo = (CGLSDOps*) oglsdo->privOps;
462
463 cglsdo->peerData = NULL;
464 cglsdo->layer = NULL;
465 }
466
467 JNIEXPORT jboolean JNICALL
468 Java_sun_java2d_opengl_CGLSurfaceData_initPbuffer
469 (JNIEnv *env, jobject cglsd,
470 jlong pData, jlong pConfigInfo, jboolean isOpaque,
471 jint width, jint height)
472 {
473 J2dTraceLn3(J2D_TRACE_INFO, "CGLSurfaceData_initPbuffer: w=%d h=%d opq=%d", width, height, isOpaque);
474
475 OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
476 if (oglsdo == NULL) {
477 J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLSurfaceData_initPbuffer: ops are null");
478 return JNI_FALSE;
479 }
480
481 CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
482 if (cglsdo == NULL) {
483 J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLSurfaceData_initPbuffer: cgl ops are null");
484 return JNI_FALSE;
485 }
486
487 CGLGraphicsConfigInfo *cglInfo = (CGLGraphicsConfigInfo *)
488 jlong_to_ptr(pConfigInfo);
489 if (cglInfo == NULL) {
490 J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLSurfaceData_initPbuffer: cgl config info is null");
491 return JNI_FALSE;
492 }
493
494 // find the maximum allowable texture dimensions (this value ultimately
495 // determines our maximum pbuffer size)
496 int pbMax = 0;
497 j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &pbMax);
498
499 int pbWidth = 0;
500 int pbHeight = 0;
501 if (OGLC_IS_CAP_PRESENT(cglInfo->context, CAPS_TEXNONPOW2)) {
502 // use non-power-of-two dimensions directly
503 pbWidth = (width <= pbMax) ? width : 0;
504 pbHeight = (height <= pbMax) ? height : 0;
505 } else {
506 // find the appropriate power-of-two dimensions
507 pbWidth = OGLSD_NextPowerOfTwo(width, pbMax);
508 pbHeight = OGLSD_NextPowerOfTwo(height, pbMax);
509 }
510
511 J2dTraceLn3(J2D_TRACE_VERBOSE, " desired pbuffer dimensions: w=%d h=%d max=%d", pbWidth, pbHeight, pbMax);
512
513 // if either dimension is 0, we cannot allocate a pbuffer/texture with the
514 // requested dimensions
515 if (pbWidth == 0 || pbHeight == 0) {
516 J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLSurfaceData_initPbuffer: dimensions too large");
517 return JNI_FALSE;
518 }
519
520 int format = isOpaque ? GL_RGB : GL_RGBA;
521
522 JNF_COCOA_ENTER(env);
523
524 cglsdo->pbuffer =
525 [[NSOpenGLPixelBuffer alloc]
526 initWithTextureTarget: GL_TEXTURE_2D
527 textureInternalFormat: format
528 textureMaxMipMapLevel: 0
529 pixelsWide: pbWidth
530 pixelsHigh: pbHeight];
531 if (cglsdo->pbuffer == nil) {
532 J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLSurfaceData_initPbuffer: could not create pbuffer");
533 return JNI_FALSE;
534 }
535
536 // make sure the actual dimensions match those that we requested
537 GLsizei actualWidth = [cglsdo->pbuffer pixelsWide];
538 GLsizei actualHeight = [cglsdo->pbuffer pixelsHigh];
539 if (actualWidth != pbWidth || actualHeight != pbHeight) {
540 J2dRlsTraceLn2(J2D_TRACE_ERROR, "CGLSurfaceData_initPbuffer: actual (w=%d h=%d) != requested", actualWidth, actualHeight);
541 [cglsdo->pbuffer release];
542 return JNI_FALSE;
543 }
544
545 GLuint texID = 0;
546 j2d_glGenTextures(1, &texID);
547 j2d_glBindTexture(GL_TEXTURE_2D, texID);
548
549 oglsdo->drawableType = OGLSD_PBUFFER;
550 oglsdo->isOpaque = isOpaque;
551 oglsdo->width = width;
552 oglsdo->height = height;
553 oglsdo->textureID = texID;
554 oglsdo->textureWidth = pbWidth;
555 oglsdo->textureHeight = pbHeight;
556 oglsdo->activeBuffer = GL_FRONT;
557 oglsdo->needsInit = JNI_TRUE;
558
559 OGLSD_INIT_TEXTURE_FILTER(oglsdo, GL_NEAREST);
560
561 JNF_COCOA_EXIT(env);
562
563 return JNI_TRUE;
564 }
565
566 #pragma mark -
567 #pragma mark "--- CGLSurfaceData methods - Mac OS X specific ---"
568
569 // Must be called on the QFT...
570 JNIEXPORT void JNICALL
571 Java_sun_java2d_opengl_CGLSurfaceData_validate
572 (JNIEnv *env, jobject jsurfacedata,
573 jint xoff, jint yoff, jint width, jint height, jboolean isOpaque)
574 {
575 J2dTraceLn2(J2D_TRACE_INFO, "CGLSurfaceData_validate: w=%d h=%d", width, height);
576
577 OGLSDOps *oglsdo = (OGLSDOps*)SurfaceData_GetOps(env, jsurfacedata);
578 oglsdo->needsInit = JNI_TRUE;
579 oglsdo->xOffset = xoff;
580 oglsdo->yOffset = yoff;
581
582 oglsdo->width = width;
583 oglsdo->height = height;
584 oglsdo->isOpaque = isOpaque;
585
|
1 /*
2 * Copyright (c) 2011, 2015, 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
93 CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
94 #if USE_NSVIEW_FOR_SCRATCH
95 [ctxinfo->context makeCurrentContext];
96 [ctxinfo->context setView: ctxinfo->scratchSurface];
97 #else
98 [ctxinfo->context clearDrawable];
99 [ctxinfo->context makeCurrentContext];
100 [ctxinfo->context setPixelBuffer: ctxinfo->scratchSurface
101 cubeMapFace: 0
102 mipMapLevel: 0
103 currentVirtualScreen: [ctxinfo->context currentVirtualScreen]];
104 #endif
105
106 JNF_COCOA_EXIT(env);
107
108 return JNI_TRUE;
109 }
110
111 /**
112 * This function disposes of any native windowing system resources associated
113 * with this surface.
114 */
115 void
116 OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
117 {
118 J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
119
120 JNF_COCOA_ENTER(env);
121
122 CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
123 if (oglsdo->drawableType == OGLSD_WINDOW) {
124 // detach the NSView from the NSOpenGLContext
125 CGLGraphicsConfigInfo *cglInfo = cglsdo->configInfo;
126 OGLContext *oglc = cglInfo->context;
127 CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
128 [ctxinfo->context clearDrawable];
129 }
130
131 oglsdo->drawableType = OGLSD_UNDEFINED;
132
133 JNF_COCOA_EXIT(env);
134 }
135
136 /**
137 * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo
138 * associated with the given OGLSDOps. This method can be called from
139 * shared code to retrieve the native GraphicsConfig data in a platform-
140 * independent manner.
141 */
142 jlong
143 OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
249 // already current to some drawable, we will make it current to
250 // its scratch surface)
251 if (oglc != currentContext) {
252 if (!CGLSD_MakeCurrentToScratch(env, oglc)) {
253 return NULL;
254 }
255 }
256
257 // now bind to the fbobject associated with the destination surface;
258 // this means that all rendering will go into the fbobject destination
259 // (note that we unbind the currently bound texture first; this is
260 // recommended procedure when binding an fbobject)
261 j2d_glBindTexture(GL_TEXTURE_2D, 0);
262 j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dstOps->fbobjectID);
263
264 return oglc;
265 }
266
267 JNF_COCOA_ENTER(env);
268
269 CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps;
270 NSView *nsView = (NSView *)cglsdo->peerData;
271
272 if ([ctxinfo->context view] != nsView) {
273 [ctxinfo->context makeCurrentContext];
274 [ctxinfo->context setView: nsView];
275 }
276
277 if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
278 // the GL_EXT_framebuffer_object extension is present, so we
279 // must bind to the default (windowing system provided)
280 // framebuffer
281 j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
282 }
283
284 JNF_COCOA_EXIT(env);
285
286 return oglc;
287 }
288
289 /**
290 * This function initializes a native window surface and caches the window
291 * bounds in the given OGLSDOps. Returns JNI_TRUE if the operation was
292 * successful; JNI_FALSE otherwise.
293 */
294 jboolean
295 OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
296 {
297 J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow");
298
299 if (oglsdo == NULL) {
300 J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: ops are null");
301 return JNI_FALSE;
302 }
303
415
416 if (cglsdo->configInfo == NULL) {
417 free(cglsdo);
418 JNU_ThrowNullPointerException(env, "Config info is null in initOps");
419 }
420 }
421
422 JNIEXPORT void JNICALL
423 Java_sun_java2d_opengl_CGLSurfaceData_clearWindow
424 (JNIEnv *env, jobject cglsd)
425 {
426 J2dTraceLn(J2D_TRACE_INFO, "CGLSurfaceData_clearWindow");
427
428 OGLSDOps *oglsdo = (OGLSDOps*) SurfaceData_GetOps(env, cglsd);
429 CGLSDOps *cglsdo = (CGLSDOps*) oglsdo->privOps;
430
431 cglsdo->peerData = NULL;
432 cglsdo->layer = NULL;
433 }
434
435 #pragma mark -
436 #pragma mark "--- CGLSurfaceData methods - Mac OS X specific ---"
437
438 // Must be called on the QFT...
439 JNIEXPORT void JNICALL
440 Java_sun_java2d_opengl_CGLSurfaceData_validate
441 (JNIEnv *env, jobject jsurfacedata,
442 jint xoff, jint yoff, jint width, jint height, jboolean isOpaque)
443 {
444 J2dTraceLn2(J2D_TRACE_INFO, "CGLSurfaceData_validate: w=%d h=%d", width, height);
445
446 OGLSDOps *oglsdo = (OGLSDOps*)SurfaceData_GetOps(env, jsurfacedata);
447 oglsdo->needsInit = JNI_TRUE;
448 oglsdo->xOffset = xoff;
449 oglsdo->yOffset = yoff;
450
451 oglsdo->width = width;
452 oglsdo->height = height;
453 oglsdo->isOpaque = isOpaque;
454
|