// static HRESULT D3DPipelineManager::HandleAdaptersChange(HMONITOR *pHMONITORs, UINT monNum) { HRESULT res = S_OK; BOOL bResetD3D = FALSE, bFound; D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance(); RETURN_STATUS_IF_NULL(pHMONITORs, E_FAIL); if (pMgr == NULL) { // NULL pMgr is valid when the pipeline is not enabled or if it hasn't // been created yet return S_OK; } RETURN_STATUS_IF_NULL(pMgr->pAdapters, E_FAIL); RETURN_STATUS_IF_NULL(pMgr->pd3d9, E_FAIL); J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleAdaptersChange"); if (monNum != pMgr->adapterCount) { J2dTraceLn2(J2D_TRACE_VERBOSE, " number of adapters changed (old=%d, new=%d)", pMgr->adapterCount, monNum); bResetD3D = TRUE; } else { for (UINT i = 0; i < pMgr->adapterCount; i++) { HMONITOR hMon = pMgr->pd3d9->GetAdapterMonitor(i); if (hMon == (HMONITOR)0x0) { J2dTraceLn1(J2D_TRACE_VERBOSE, " adapter %d: removed", i); bResetD3D = TRUE; break; } bFound = FALSE; for (UINT mon = 0; mon < monNum; mon++) { if (pHMONITORs[mon] == hMon) { J2dTraceLn3(J2D_TRACE_VERBOSE, " adapter %d: found hmnd[%d]=0x%x", i, mon, hMon); bFound = TRUE; break; } } if (!bFound) { J2dTraceLn2(J2D_TRACE_VERBOSE, " adapter %d: could not find hmnd=0x%x "\ "in the list of new hmnds", i, hMon); bResetD3D = TRUE; break; } } } if (bResetD3D) { J2dTraceLn(J2D_TRACE_VERBOSE, " adapters changed: resetting d3d"); pMgr->ReleaseD3D(); res = pMgr->InitD3D(); } return res; }
/** * Debugging utility: prints information about errors received * during interaction with the registry. */ void RegistryKey::PrintRegistryError(LONG errNum, char *message) { WCHAR errString[255]; int numChars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errNum, 0, errString, 255, NULL); if (numChars == 0) { J2dTraceLn1(J2D_TRACE_ERROR, "problem with formatmessage, err = %d\n", GetLastError()); } J2dTraceLn3(J2D_TRACE_ERROR, "problem with %s, errNum, string = %d, %S\n", message, errNum, errString); }
/** * Initializes the OpenGL transform state by setting the modelview transform * using the given matrix parameters. * * REMIND: it may be worthwhile to add serial id to AffineTransform, so we * could do a quick check to see if the xform has changed since * last time... a simple object compare won't suffice... */ void OGLContext_SetTransform(OGLContext *oglc, jdouble m00, jdouble m10, jdouble m01, jdouble m11, jdouble m02, jdouble m12) { J2dTraceLn(J2D_TRACE_INFO, "OGLContext_SetTransform"); RETURN_IF_NULL(oglc); CHECK_PREVIOUS_OP(OGL_STATE_CHANGE); if (oglc->xformMatrix == NULL) { size_t arrsize = 16 * sizeof(GLdouble); oglc->xformMatrix = (GLdouble *)malloc(arrsize); memset(oglc->xformMatrix, 0, arrsize); oglc->xformMatrix[10] = 1.0; oglc->xformMatrix[15] = 1.0; } // copy values from AffineTransform object into native matrix array oglc->xformMatrix[0] = m00; oglc->xformMatrix[1] = m10; oglc->xformMatrix[4] = m01; oglc->xformMatrix[5] = m11; oglc->xformMatrix[12] = m02; oglc->xformMatrix[13] = m12; J2dTraceLn3(J2D_TRACE_VERBOSE, " [%lf %lf %lf]", oglc->xformMatrix[0], oglc->xformMatrix[4], oglc->xformMatrix[12]); J2dTraceLn3(J2D_TRACE_VERBOSE, " [%lf %lf %lf]", oglc->xformMatrix[1], oglc->xformMatrix[5], oglc->xformMatrix[13]); j2d_glMatrixMode(GL_MODELVIEW); j2d_glLoadMatrixd(oglc->xformMatrix); }
HRESULT D3DResourceManager::CreateRTSurface(UINT width, UINT height, BOOL isOpaque, BOOL isLockable, D3DFORMAT *pFormat/*out*/, D3DResource** ppSurfaceResource/*out*/) { HRESULT res; IDirect3DDevice9 *pd3dDevice; J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateRTSurface"); J2dTraceLn3(J2D_TRACE_VERBOSE, " w=%d h=%d isOpaque=%d", width, height, isOpaque); if (pCtx == NULL || ppSurfaceResource == NULL || (pd3dDevice = pCtx->Get3DDevice()) == NULL) { return E_FAIL; } if (FAILED(res = pd3dDevice->TestCooperativeLevel())) { return res; } D3DPRESENT_PARAMETERS *curParams = pCtx->GetPresentationParams(); D3DFORMAT format = isOpaque ? curParams->BackBufferFormat : D3DFMT_A8R8G8B8; IDirect3DSurface9 *pSurface = NULL; res = pd3dDevice->CreateRenderTarget(width, height, format, D3DMULTISAMPLE_NONE, 0, isLockable, &pSurface, NULL); if (SUCCEEDED(res)) { J2dTraceLn1(J2D_TRACE_VERBOSE, " created RT Surface: 0x%x ", pSurface); if (pFormat != NULL) { *pFormat = format; } *ppSurfaceResource = new D3DResource((IDirect3DResource9*)pSurface); res = AddResource(*ppSurfaceResource); } else { DebugPrintD3DError(res, "D3DRM::CreateRTSurface failed"); ppSurfaceResource = NULL; } return res; }
/** * Returns cell info associated with particular cache from the glyph's list of * cached cells. */ CacheCellInfo * AccelGlyphCache_GetCellInfoForCache(GlyphInfo *glyph, GlyphCacheInfo *cache) { // assert (glyph != NULL && cache != NULL) J2dTraceLn(J2D_TRACE_VERBOSE2, "AccelGlyphCache_GetCellInfoForCache"); if (glyph->cellInfo != NULL) { CacheCellInfo *cellInfo = glyph->cellInfo; do { if (cellInfo->cacheInfo == cache) { J2dTraceLn3(J2D_TRACE_VERBOSE2, " glyph 0x%x: found cell 0x%x for cache 0x%x", glyph, cellInfo, cache); return cellInfo; } cellInfo = cellInfo->nextGCI; } while (cellInfo != NULL); } J2dTraceLn2(J2D_TRACE_VERBOSE2, " glyph 0x%x: no cell for cache 0x%x", glyph, cache); return NULL; }
JNIEXPORT jboolean JNICALL Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer (JNIEnv *env, jobject glxsd, jlong pData, jlong pConfigInfo, jboolean isOpaque, jint width, jint height) { OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); GLXGraphicsConfigInfo *glxinfo = (GLXGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); GLXSDOps *glxsdo; GLXPbuffer pbuffer; int attrlist[] = {GLX_PBUFFER_WIDTH, 0, GLX_PBUFFER_HEIGHT, 0, GLX_PRESERVED_CONTENTS, GL_FALSE, 0}; J2dTraceLn3(J2D_TRACE_INFO, "GLXSurfaceData_initPbuffer: w=%d h=%d opq=%d", width, height, isOpaque); if (oglsdo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXSurfaceData_initPbuffer: ops are null"); return JNI_FALSE; } glxsdo = (GLXSDOps *)oglsdo->privOps; if (glxsdo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXSurfaceData_initPbuffer: glx ops are null"); return JNI_FALSE; } if (glxinfo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXSurfaceData_initPbuffer: glx config info is null"); return JNI_FALSE; } attrlist[1] = width; attrlist[3] = height; surfaceCreationFailed = JNI_FALSE; EXEC_WITH_XERROR_HANDLER( GLXSD_BadAllocXErrHandler, pbuffer = j2d_glXCreatePbuffer(awt_display, glxinfo->fbconfig, attrlist)); if ((pbuffer == 0) || surfaceCreationFailed) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXSurfaceData_initPbuffer: could not create glx pbuffer"); return JNI_FALSE; } oglsdo->drawableType = OGLSD_PBUFFER; oglsdo->isOpaque = isOpaque; oglsdo->width = width; oglsdo->height = height; oglsdo->xOffset = 0; oglsdo->yOffset = 0; glxsdo->drawable = pbuffer; glxsdo->xdrawable = 0; return JNI_TRUE; }
JNIEXPORT jboolean JNICALL Java_sun_java2d_opengl_WGLSurfaceData_initPbuffer (JNIEnv *env, jobject wglsd, jlong pData, jlong pConfigInfo, jboolean isOpaque, jint width, jint height) { int attrKeys[] = { WGL_MAX_PBUFFER_WIDTH_ARB, WGL_MAX_PBUFFER_HEIGHT_ARB, }; int attrVals[2]; int pbAttrList[] = { 0 }; OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); WGLGraphicsConfigInfo *wglInfo = (WGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); WGLSDOps *wglsdo; HWND hwnd; HDC hdc, pbufferDC; HPBUFFERARB pbuffer; int maxWidth, maxHeight; int actualWidth, actualHeight; J2dTraceLn3(J2D_TRACE_INFO, "WGLSurfaceData_initPbuffer: w=%d h=%d opq=%d", width, height, isOpaque); if (oglsdo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: ops are null"); return JNI_FALSE; } wglsdo = (WGLSDOps *)oglsdo->privOps; if (wglsdo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: wgl ops are null"); return JNI_FALSE; } if (wglInfo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: wgl config info is null"); return JNI_FALSE; } // create a scratch window hwnd = WGLGC_CreateScratchWindow(wglInfo->screen); if (hwnd == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: could not create scratch window"); return JNI_FALSE; } // get the HDC for the scratch window hdc = GetDC(hwnd); if (hdc == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: could not get dc for scratch window"); DestroyWindow(hwnd); return JNI_FALSE; } // get the maximum allowable pbuffer dimensions j2d_wglGetPixelFormatAttribivARB(hdc, wglInfo->pixfmt, 0, 2, attrKeys, attrVals); maxWidth = attrVals[0]; maxHeight = attrVals[1]; J2dTraceLn4(J2D_TRACE_VERBOSE, " desired pbuffer dimensions: w=%d h=%d maxw=%d maxh=%d", width, height, maxWidth, maxHeight); // if either dimension is 0 or larger than the maximum, we cannot // allocate a pbuffer with the requested dimensions if (width == 0 || width > maxWidth || height == 0 || height > maxHeight) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: invalid dimensions"); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return JNI_FALSE; } pbuffer = j2d_wglCreatePbufferARB(hdc, wglInfo->pixfmt, width, height, pbAttrList); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); if (pbuffer == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: could not create wgl pbuffer"); return JNI_FALSE; } // note that we get the DC for the pbuffer at creation time, and then // release the DC when the pbuffer is disposed; the WGL_ARB_pbuffer // spec is vague about such things, but from past experience we know // this approach to be more robust than, for example, doing a // Get/ReleasePbufferDC() everytime we make a context current pbufferDC = j2d_wglGetPbufferDCARB(pbuffer); if (pbufferDC == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: could not get dc for pbuffer"); j2d_wglDestroyPbufferARB(pbuffer); return JNI_FALSE; } // make sure the actual dimensions match those that we requested j2d_wglQueryPbufferARB(pbuffer, WGL_PBUFFER_WIDTH_ARB, &actualWidth); j2d_wglQueryPbufferARB(pbuffer, WGL_PBUFFER_HEIGHT_ARB, &actualHeight); if (width != actualWidth || height != actualHeight) { J2dRlsTraceLn2(J2D_TRACE_ERROR, "WGLSurfaceData_initPbuffer: actual (w=%d h=%d) != requested", actualWidth, actualHeight); j2d_wglReleasePbufferDCARB(pbuffer, pbufferDC); j2d_wglDestroyPbufferARB(pbuffer); return JNI_FALSE; } oglsdo->drawableType = OGLSD_PBUFFER; oglsdo->isOpaque = isOpaque; oglsdo->width = width; oglsdo->height = height; wglsdo->pbuffer = pbuffer; wglsdo->pbufferDC = pbufferDC; OGLSD_SetNativeDimensions(env, oglsdo, width, height); return JNI_TRUE; }
/** * Initializes a framebuffer object based on the given textureID and its * width/height. This method will iterate through all possible depth formats * to find one that is supported by the drivers/hardware. (Since our use of * the depth buffer is fairly simplistic, we hope to find a depth format that * uses as little VRAM as possible.) If an appropriate depth buffer is found * and all attachments are successful (i.e. the framebuffer object is * "complete"), then this method will return JNI_TRUE and will initialize * the values of fbobjectID and depthID using the IDs created by this method. * Otherwise, this method returns JNI_FALSE. Note that the caller is only * responsible for deleting the allocated fbobject and depth renderbuffer * resources if this method returned JNI_TRUE. */ jboolean OGLSD_InitFBObject(GLuint *fbobjectID, GLuint *depthID, GLuint textureID, GLenum textureTarget, jint textureWidth, jint textureHeight) { GLenum depthFormats[] = { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 }; GLuint fboTmpID, depthTmpID; jboolean foundDepth = JNI_FALSE; int i; J2dTraceLn3(J2D_TRACE_INFO, "OGLSD_InitFBObject: w=%d h=%d texid=%d", textureWidth, textureHeight, textureID); // initialize framebuffer object j2d_glGenFramebuffersEXT(1, &fboTmpID); j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboTmpID); // attach color texture to framebuffer object j2d_glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textureTarget, textureID, 0); // attempt to create a depth renderbuffer of a particular format; we // will start with the smallest size and then work our way up for (i = 0; i < 3; i++) { GLenum error, status; GLenum depthFormat = depthFormats[i]; int depthSize = 16 + (i * 8); // initialize depth renderbuffer j2d_glGenRenderbuffersEXT(1, &depthTmpID); j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthTmpID); j2d_glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, depthFormat, textureWidth, textureHeight); // creation of depth buffer could potentially fail, so check for error error = j2d_glGetError(); if (error != GL_NO_ERROR) { J2dTraceLn2(J2D_TRACE_VERBOSE, "OGLSD_InitFBObject: could not create depth buffer: depth=%d error=%x", depthSize, error); j2d_glDeleteRenderbuffersEXT(1, &depthTmpID); continue; } // attach depth renderbuffer to framebuffer object j2d_glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthTmpID); // now check for framebuffer "completeness" status = j2d_glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status == GL_FRAMEBUFFER_COMPLETE_EXT) { // we found a valid format, so break out of the loop J2dTraceLn1(J2D_TRACE_VERBOSE, " framebuffer is complete: depth=%d", depthSize); foundDepth = JNI_TRUE; break; } else { // this depth format didn't work, so delete and try another format J2dTraceLn2(J2D_TRACE_VERBOSE, " framebuffer is incomplete: depth=%d status=%x", depthSize, status); j2d_glDeleteRenderbuffersEXT(1, &depthTmpID); } } // unbind the texture and framebuffer objects (they will be bound again // later as needed) j2d_glBindTexture(textureTarget, 0); j2d_glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); if (!foundDepth) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitFBObject: could not find valid depth format"); j2d_glDeleteFramebuffersEXT(1, &fboTmpID); return JNI_FALSE; } *fbobjectID = fboTmpID; *depthID = depthTmpID; return JNI_TRUE; }
/** * Initializes an OpenGL texture object. * * If the isOpaque parameter is JNI_FALSE, then the texture will have a * full alpha channel; otherwise, the texture will be opaque (this can * help save VRAM when translucency is not needed). * * If the GL_ARB_texture_non_power_of_two extension is present (texNonPow2 * is JNI_TRUE), the actual texture is allowed to have non-power-of-two * dimensions, and therefore width==textureWidth and height==textureHeight. * * Failing that, if the GL_ARB_texture_rectangle extension is present * (texRect is JNI_TRUE), the actual texture is allowed to have * non-power-of-two dimensions, except that instead of using the usual * GL_TEXTURE_2D target, we need to use the GL_TEXTURE_RECTANGLE_ARB target. * Note that the GL_REPEAT wrapping mode is not allowed with this target, * so if that mode is needed (e.g. as is the case in the TexturePaint code) * one should pass JNI_FALSE to avoid using this extension. Also note that * when the texture target is GL_TEXTURE_RECTANGLE_ARB, texture coordinates * must be specified in the range [0,width] and [0,height] rather than * [0,1] as is the case with the usual GL_TEXTURE_2D target (so take care)! * * Otherwise, the actual texture must have power-of-two dimensions, and * therefore the textureWidth and textureHeight will be the next * power-of-two greater than (or equal to) the requested width and height. */ static jboolean OGLSD_InitTextureObject(OGLSDOps *oglsdo, jboolean isOpaque, jboolean texNonPow2, jboolean texRect, jint width, jint height) { GLenum texTarget, texProxyTarget; GLint format = isOpaque ? GL_RGB : GL_RGBA; GLuint texID; GLsizei texWidth, texHeight, realWidth, realHeight; GLint texMax; J2dTraceLn4(J2D_TRACE_INFO, "OGLSD_InitTextureObject: w=%d h=%d opq=%d nonpow2=%d", width, height, isOpaque, texNonPow2); if (oglsdo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitTextureObject: ops are null"); return JNI_FALSE; } if (texNonPow2) { // use non-pow2 dimensions with GL_TEXTURE_2D target j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax); texWidth = (width <= texMax) ? width : 0; texHeight = (height <= texMax) ? height : 0; texTarget = GL_TEXTURE_2D; texProxyTarget = GL_PROXY_TEXTURE_2D; } else if (texRect) { // use non-pow2 dimensions with GL_TEXTURE_RECTANGLE_ARB target j2d_glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texMax); texWidth = (width <= texMax) ? width : 0; texHeight = (height <= texMax) ? height : 0; texTarget = GL_TEXTURE_RECTANGLE_ARB; texProxyTarget = GL_PROXY_TEXTURE_RECTANGLE_ARB; } else { // find the appropriate power-of-two dimensions j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texMax); texWidth = OGLSD_NextPowerOfTwo(width, texMax); texHeight = OGLSD_NextPowerOfTwo(height, texMax); texTarget = GL_TEXTURE_2D; texProxyTarget = GL_PROXY_TEXTURE_2D; } J2dTraceLn3(J2D_TRACE_VERBOSE, " desired texture dimensions: w=%d h=%d max=%d", texWidth, texHeight, texMax); // if either dimension is 0, we cannot allocate a texture with the // requested dimensions if ((texWidth == 0) || (texHeight == 0)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitTextureObject: texture dimensions too large"); return JNI_FALSE; } // now use a proxy to determine whether we can create a texture with // the calculated power-of-two dimensions and the given internal format j2d_glTexImage2D(texProxyTarget, 0, format, texWidth, texHeight, 0, format, GL_UNSIGNED_BYTE, NULL); j2d_glGetTexLevelParameteriv(texProxyTarget, 0, GL_TEXTURE_WIDTH, &realWidth); j2d_glGetTexLevelParameteriv(texProxyTarget, 0, GL_TEXTURE_HEIGHT, &realHeight); // if the requested dimensions and proxy dimensions don't match, // we shouldn't attempt to create the texture if ((realWidth != texWidth) || (realHeight != texHeight)) { J2dRlsTraceLn2(J2D_TRACE_ERROR, "OGLSD_InitTextureObject: actual (w=%d h=%d) != requested", realWidth, realHeight); return JNI_FALSE; } // initialize the texture with some dummy data (this allows us to create // a texture object once with 2^n dimensions, and then use // glTexSubImage2D() to provide further updates) j2d_glGenTextures(1, &texID); j2d_glBindTexture(texTarget, texID); j2d_glTexImage2D(texTarget, 0, format, texWidth, texHeight, 0, format, GL_UNSIGNED_BYTE, NULL); oglsdo->isOpaque = isOpaque; oglsdo->xOffset = 0; oglsdo->yOffset = 0; oglsdo->width = width; oglsdo->height = height; oglsdo->textureID = texID; oglsdo->textureWidth = texWidth; oglsdo->textureHeight = texHeight; oglsdo->textureTarget = texTarget; OGLSD_INIT_TEXTURE_FILTER(oglsdo, GL_NEAREST); OGLSD_RESET_TEXTURE_WRAP(texTarget); J2dTraceLn3(J2D_TRACE_VERBOSE, " created texture: w=%d h=%d id=%d", width, height, texID); return JNI_TRUE; }