jdk/src/java.desktop/windows/native/libawt/java2d/opengl/WGLSurfaceData.c
changeset 31661 a5cb86f2253b
parent 26751 70bac69b37c9
equal deleted inserted replaced
31660:1a4e2e5c15e1 31661:a5cb86f2253b
     1 /*
     1 /*
     2  * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   105     }
   105     }
   106 }
   106 }
   107 
   107 
   108 /**
   108 /**
   109  * This function disposes of any native windowing system resources associated
   109  * This function disposes of any native windowing system resources associated
   110  * with this surface.  For instance, if the given OGLSDOps is of type
   110  * with this surface.
   111  * OGLSD_PBUFFER, this method implementation will destroy the actual pbuffer
       
   112  * surface.
       
   113  */
   111  */
   114 void
   112 void
   115 OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
   113 OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
   116 {
   114 {
   117     WGLSDOps *wglsdo = (WGLSDOps *)oglsdo->privOps;
       
   118 
       
   119     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
   115     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
   120 
   116     // Window is free'd later by AWT code...
   121     if (oglsdo->drawableType == OGLSD_PBUFFER) {
       
   122         if (wglsdo->pbuffer != 0) {
       
   123             if (wglsdo->pbufferDC != 0) {
       
   124                 j2d_wglReleasePbufferDCARB(wglsdo->pbuffer,
       
   125                                            wglsdo->pbufferDC);
       
   126                 wglsdo->pbufferDC = 0;
       
   127             }
       
   128             j2d_wglDestroyPbufferARB(wglsdo->pbuffer);
       
   129             wglsdo->pbuffer = 0;
       
   130         }
       
   131     }
       
   132 }
   117 }
   133 
   118 
   134 /**
   119 /**
   135  * Makes the given context current to its associated "scratch" surface.  If
   120  * Makes the given context current to its associated "scratch" surface.  If
   136  * the operation is successful, this method will return JNI_TRUE; otherwise,
   121  * the operation is successful, this method will return JNI_TRUE; otherwise,
   274     }
   259     }
   275 
   260 
   276     ctxinfo = (WGLCtxInfo *)oglc->ctxInfo;
   261     ctxinfo = (WGLCtxInfo *)oglc->ctxInfo;
   277 
   262 
   278     // get the hdc for the destination surface
   263     // get the hdc for the destination surface
   279     if (dstOps->drawableType == OGLSD_PBUFFER) {
   264     dstHDC = GetDC(dstWGLOps->window);
   280         dstHDC = dstWGLOps->pbufferDC;
       
   281     } else {
       
   282         dstHDC = GetDC(dstWGLOps->window);
       
   283     }
       
   284 
   265 
   285     // get the hdc for the source surface
   266     // get the hdc for the source surface
   286     if (srcOps->drawableType == OGLSD_PBUFFER) {
   267     // the source will always be equal to the destination in this case
   287         srcHDC = srcWGLOps->pbufferDC;
   268     srcHDC = dstHDC;
   288     } else {
       
   289         // the source will always be equal to the destination in this case
       
   290         srcHDC = dstHDC;
       
   291     }
       
   292 
   269 
   293     // REMIND: in theory we should be able to use wglMakeContextCurrentARB()
   270     // REMIND: in theory we should be able to use wglMakeContextCurrentARB()
   294     // even when the src/dst surfaces are the same, but this causes problems
   271     // even when the src/dst surfaces are the same, but this causes problems
   295     // on ATI's drivers (see 6525997); for now we will only use it when the
   272     // on ATI's drivers (see 6525997); for now we will only use it when the
   296     // surfaces are different, otherwise we will use the old
   273     // surfaces are different, otherwise we will use the old
   304         success = j2d_wglMakeCurrent(dstHDC, ctxinfo->context);
   281         success = j2d_wglMakeCurrent(dstHDC, ctxinfo->context);
   305     }
   282     }
   306     if (!success) {
   283     if (!success) {
   307         J2dRlsTraceLn(J2D_TRACE_ERROR,
   284         J2dRlsTraceLn(J2D_TRACE_ERROR,
   308                       "OGLSD_MakeOGLContextCurrent: could not make current");
   285                       "OGLSD_MakeOGLContextCurrent: could not make current");
   309         if (dstOps->drawableType != OGLSD_PBUFFER) {
   286         ReleaseDC(dstWGLOps->window, dstHDC);
   310             ReleaseDC(dstWGLOps->window, dstHDC);
       
   311         }
       
   312         return NULL;
   287         return NULL;
   313     }
   288     }
   314 
   289 
   315     if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
   290     if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
   316         // the GL_EXT_framebuffer_object extension is present, so we
   291         // the GL_EXT_framebuffer_object extension is present, so we
   317         // must bind to the default (windowing system provided)
   292         // must bind to the default (windowing system provided)
   318         // framebuffer
   293         // framebuffer
   319         j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
   294         j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
   320     }
   295     }
   321 
   296 
   322     if (dstOps->drawableType != OGLSD_PBUFFER) {
   297     ReleaseDC(dstWGLOps->window, dstHDC);
   323         ReleaseDC(dstWGLOps->window, dstHDC);
       
   324     }
       
   325 
   298 
   326     return oglc;
   299     return oglc;
   327 }
   300 }
   328 
   301 
   329 /**
   302 /**
   394     oglsdo->height = wbounds.bottom - wbounds.top;
   367     oglsdo->height = wbounds.bottom - wbounds.top;
   395     wglsdo->pbufferDC = 0;
   368     wglsdo->pbufferDC = 0;
   396 
   369 
   397     J2dTraceLn2(J2D_TRACE_VERBOSE, "  created window: w=%d h=%d",
   370     J2dTraceLn2(J2D_TRACE_VERBOSE, "  created window: w=%d h=%d",
   398                 oglsdo->width, oglsdo->height);
   371                 oglsdo->width, oglsdo->height);
   399 
       
   400     return JNI_TRUE;
       
   401 }
       
   402 
       
   403 JNIEXPORT jboolean JNICALL
       
   404 Java_sun_java2d_opengl_WGLSurfaceData_initPbuffer
       
   405     (JNIEnv *env, jobject wglsd,
       
   406      jlong pData, jlong pConfigInfo,
       
   407      jboolean isOpaque,
       
   408      jint width, jint height)
       
   409 {
       
   410     int attrKeys[] = {
       
   411         WGL_MAX_PBUFFER_WIDTH_ARB,
       
   412         WGL_MAX_PBUFFER_HEIGHT_ARB,
       
   413     };
       
   414     int attrVals[2];
       
   415     int pbAttrList[] = { 0 };
       
   416     OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
       
   417     WGLGraphicsConfigInfo *wglInfo =
       
   418         (WGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
       
   419     WGLSDOps *wglsdo;
       
   420     HWND hwnd;
       
   421     HDC hdc, pbufferDC;
       
   422     HPBUFFERARB pbuffer;
       
   423     int maxWidth, maxHeight;
       
   424     int actualWidth, actualHeight;
       
   425 
       
   426     J2dTraceLn3(J2D_TRACE_INFO,
       
   427                 "WGLSurfaceData_initPbuffer: w=%d h=%d opq=%d",
       
   428                 width, height, isOpaque);
       
   429 
       
   430     if (oglsdo == NULL) {
       
   431         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   432             "WGLSurfaceData_initPbuffer: ops are null");
       
   433         return JNI_FALSE;
       
   434     }
       
   435 
       
   436     wglsdo = (WGLSDOps *)oglsdo->privOps;
       
   437     if (wglsdo == NULL) {
       
   438         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   439             "WGLSurfaceData_initPbuffer: wgl ops are null");
       
   440         return JNI_FALSE;
       
   441     }
       
   442 
       
   443     if (wglInfo == NULL) {
       
   444         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   445             "WGLSurfaceData_initPbuffer: wgl config info is null");
       
   446         return JNI_FALSE;
       
   447     }
       
   448 
       
   449     // create a scratch window
       
   450     hwnd = WGLGC_CreateScratchWindow(wglInfo->screen);
       
   451     if (hwnd == 0) {
       
   452         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   453             "WGLSurfaceData_initPbuffer: could not create scratch window");
       
   454         return JNI_FALSE;
       
   455     }
       
   456 
       
   457     // get the HDC for the scratch window
       
   458     hdc = GetDC(hwnd);
       
   459     if (hdc == 0) {
       
   460         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   461             "WGLSurfaceData_initPbuffer: could not get dc for scratch window");
       
   462         DestroyWindow(hwnd);
       
   463         return JNI_FALSE;
       
   464     }
       
   465 
       
   466     // get the maximum allowable pbuffer dimensions
       
   467     j2d_wglGetPixelFormatAttribivARB(hdc, wglInfo->pixfmt, 0, 2,
       
   468                                      attrKeys, attrVals);
       
   469     maxWidth  = attrVals[0];
       
   470     maxHeight = attrVals[1];
       
   471 
       
   472     J2dTraceLn4(J2D_TRACE_VERBOSE,
       
   473                 "  desired pbuffer dimensions: w=%d h=%d maxw=%d maxh=%d",
       
   474                 width, height, maxWidth, maxHeight);
       
   475 
       
   476     // if either dimension is 0 or larger than the maximum, we cannot
       
   477     // allocate a pbuffer with the requested dimensions
       
   478     if (width  == 0 || width  > maxWidth ||
       
   479         height == 0 || height > maxHeight)
       
   480     {
       
   481         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   482             "WGLSurfaceData_initPbuffer: invalid dimensions");
       
   483         ReleaseDC(hwnd, hdc);
       
   484         DestroyWindow(hwnd);
       
   485         return JNI_FALSE;
       
   486     }
       
   487 
       
   488     pbuffer = j2d_wglCreatePbufferARB(hdc, wglInfo->pixfmt,
       
   489                                       width, height, pbAttrList);
       
   490 
       
   491     ReleaseDC(hwnd, hdc);
       
   492     DestroyWindow(hwnd);
       
   493 
       
   494     if (pbuffer == 0) {
       
   495         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   496             "WGLSurfaceData_initPbuffer: could not create wgl pbuffer");
       
   497         return JNI_FALSE;
       
   498     }
       
   499 
       
   500     // note that we get the DC for the pbuffer at creation time, and then
       
   501     // release the DC when the pbuffer is disposed; the WGL_ARB_pbuffer
       
   502     // spec is vague about such things, but from past experience we know
       
   503     // this approach to be more robust than, for example, doing a
       
   504     // Get/ReleasePbufferDC() everytime we make a context current
       
   505     pbufferDC = j2d_wglGetPbufferDCARB(pbuffer);
       
   506     if (pbufferDC == 0) {
       
   507         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   508             "WGLSurfaceData_initPbuffer: could not get dc for pbuffer");
       
   509         j2d_wglDestroyPbufferARB(pbuffer);
       
   510         return JNI_FALSE;
       
   511     }
       
   512 
       
   513     // make sure the actual dimensions match those that we requested
       
   514     j2d_wglQueryPbufferARB(pbuffer, WGL_PBUFFER_WIDTH_ARB, &actualWidth);
       
   515     j2d_wglQueryPbufferARB(pbuffer, WGL_PBUFFER_HEIGHT_ARB, &actualHeight);
       
   516 
       
   517     if (width != actualWidth || height != actualHeight) {
       
   518         J2dRlsTraceLn2(J2D_TRACE_ERROR,
       
   519             "WGLSurfaceData_initPbuffer: actual (w=%d h=%d) != requested",
       
   520                        actualWidth, actualHeight);
       
   521         j2d_wglReleasePbufferDCARB(pbuffer, pbufferDC);
       
   522         j2d_wglDestroyPbufferARB(pbuffer);
       
   523         return JNI_FALSE;
       
   524     }
       
   525 
       
   526     oglsdo->drawableType = OGLSD_PBUFFER;
       
   527     oglsdo->isOpaque = isOpaque;
       
   528     oglsdo->width = width;
       
   529     oglsdo->height = height;
       
   530     wglsdo->pbuffer = pbuffer;
       
   531     wglsdo->pbufferDC = pbufferDC;
       
   532 
       
   533     OGLSD_SetNativeDimensions(env, oglsdo, width, height);
       
   534 
   372 
   535     return JNI_TRUE;
   373     return JNI_TRUE;
   536 }
   374 }
   537 
   375 
   538 void
   376 void