void D3DInitializer::D3DAdapterInitializer::InitImpl() { J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) started", adapter); D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance(); if (pMgr == NULL) { return; } D3DContext *pd3dContext; pMgr->GetD3DContext(adapter, &pd3dContext); J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) finished", adapter); }
D3DPipelineManager * D3DPipelineManager::CreateInstance(void) { if (!IsD3DEnabled() || FAILED((D3DPipelineManager::CheckOSVersion())) || FAILED((D3DPipelineManager::GDICheckForBadHardware()))) { return NULL; } if (pMgr == NULL) { pMgr = new D3DPipelineManager(); if (FAILED(pMgr->InitD3D())) { SAFE_DELETE(pMgr); } } else { // this should never happen so to be on the safe side do not // use this unexpected pointer, do not try to release it, just null // it out and fail safely J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::CreateInstance: unexpected instance: 0x%x,"\ " abort.", pMgr); pMgr = NULL; } return pMgr; }
HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal, D3DContext **ppd3dContext) { J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetD3DContext"); HRESULT res = S_OK; if (adapterOrdinal < 0 || adapterOrdinal >= adapterCount || pAdapters == NULL || pAdapters[adapterOrdinal].state == CONTEXT_INIT_FAILED) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::GetD3DContext: invalid parameters or "\ "failed init for adapter %d", adapterOrdinal); *ppd3dContext = NULL; return E_FAIL; } if (pAdapters[adapterOrdinal].state == CONTEXT_NOT_INITED) { D3DContext *pCtx = NULL; if (pAdapters[adapterOrdinal].pd3dContext != NULL) { J2dTraceLn1(J2D_TRACE_ERROR, " non-null context in "\ "uninitialized adapter %d", adapterOrdinal); res = E_FAIL; } else { J2dTraceLn1(J2D_TRACE_VERBOSE, " initializing context for adapter %d",adapterOrdinal); if (SUCCEEDED(res = D3DEnabledOnAdapter(adapterOrdinal))) { res = D3DContext::CreateInstance(pd3d9, adapterOrdinal, &pCtx); if (FAILED(res)) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::GetD3DContext: failed to create context "\ "for adapter=%d", adapterOrdinal); } } else { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::GetContext: no d3d on adapter %d",adapterOrdinal); } } pAdapters[adapterOrdinal].state = SUCCEEDED(res) ? CONTEXT_CREATED : CONTEXT_INIT_FAILED; pAdapters[adapterOrdinal].pd3dContext = pCtx; } *ppd3dContext = pAdapters[adapterOrdinal].pd3dContext; return res; }
void D3DInitializer::CleanImpl(bool reInit) { J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DInitializer::CleanImpl (%s)", reInit ? "RELAUNCH" : "normal"); D3DPipelineManager::DeleteInstance(); if (bComInitialized) { CoUninitialize(); } }
HWND D3DPipelineManager::CreateDefaultFocusWindow() { UINT adapterOrdinal = D3DADAPTER_DEFAULT; J2dTraceLn1(J2D_TRACE_INFO, "D3DPPLM::CreateDefaultFocusWindow: adapter=%d", adapterOrdinal); if (defaultFocusWindow != 0) { J2dRlsTraceLn(J2D_TRACE_WARNING, "D3DPPLM::CreateDefaultFocusWindow: "\ "existing default focus window!"); return defaultFocusWindow; } WNDCLASS wc; ZeroMemory(&wc, sizeof(WNDCLASS)); wc.hInstance = GetModuleHandle(NULL); wc.lpfnWndProc = DefWindowProc; wc.lpszClassName = L"D3DFocusWindow"; if (RegisterClass(&wc) == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "D3DPPLM::CreateDefaultFocusWindow: "\ "error registering window class"); return 0; } MONITORINFO mi; ZeroMemory(&mi, sizeof(MONITORINFO)); mi.cbSize = sizeof(MONITORINFO); HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal); if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::CreateDefaultFocusWindow: "\ "error getting monitor info for adapter=%d", adapterOrdinal); return 0; } HWND hWnd = CreateWindow(L"D3DFocusWindow", L"D3DFocusWindow", 0, mi.rcMonitor.left, mi.rcMonitor.top, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL); if (hWnd == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "D3DPPLM::CreateDefaultFocusWindow: CreateWindow failed"); } else { J2dTraceLn2(J2D_TRACE_INFO, " Created default focus window %x for adapter %d", hWnd, adapterOrdinal); defaultFocusWindow = hWnd; } return hWnd; }
/* * Class: sun_java2d_cmm_lcms_LCMS * Method: freeProfile * Signature: (J)V */ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile (JNIEnv *env, jobject obj, jlong id) { storeID_t sProf; sProf.j = id; if (cmsCloseProfile(sProf.pf) == 0) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)" "== 0", id); JNU_ThrowByName(env, "java/awt/color/CMMException", "Cannot close profile"); } }
int TestTextureFormats(D3DContext *d3dContext) { int testRes = J2D_D3D_FAILURE; D3DTextureTable &table = d3dContext->GetTextureTable(); int pfExists; // Check that there's at least one valid pixel format // for each transparency type (opaque, bitmask, translucent) for (int t = TR_OPAQUE_IDX; t < TR_MAX_IDX; t++) { pfExists = FALSE; for (int d = DEPTH16_IDX; d < DEPTH_MAX_IDX; d++) { if (table[t][d].pfType != PF_INVALID) { pfExists = TRUE; break; } } if (pfExists == FALSE) { // couldn't find a pixel formap for this transparency type J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DTest::TestTextureFormats no texture formats"\ " for %d transparency", t); break; } } // we must have ARGB texture format (may be used for text rendering) if (pfExists == TRUE && table[TR_TRANSLUCENT_IDX][DEPTH32_IDX].pfType == PF_INT_ARGB) { testRes |= J2D_D3D_PIXEL_FORMATS_OK; } else { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DTest::TestTextureFormats: FAILED pfType=%d", table[TR_TRANSLUCENT_IDX][DEPTH32_IDX].pfType); } return testRes; }
/** * Attempts to initialize GLX and the core OpenGL library. For this method * to return JNI_TRUE, the following must be true: * - libGL must be loaded successfully (via dlopen) * - all function symbols from libGL must be available and loaded properly * - the GLX extension must be available through X11 * - client GLX version must be >= 1.3 * If any of these requirements are not met, this method will return * JNI_FALSE, indicating there is no hope of using GLX/OpenGL for any * GraphicsConfig in the environment. */ static jboolean GLXGC_InitGLX() { int errorbase, eventbase; const char *version; J2dRlsTraceLn(J2D_TRACE_INFO, "GLXGC_InitGLX"); if (!OGLFuncs_OpenLibrary()) { return JNI_FALSE; } if (!OGLFuncs_InitPlatformFuncs() || !OGLFuncs_InitBaseFuncs() || !OGLFuncs_InitExtFuncs()) { OGLFuncs_CloseLibrary(); return JNI_FALSE; } if (!j2d_glXQueryExtension(awt_display, &errorbase, &eventbase)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGC_InitGLX: GLX extension is not present"); OGLFuncs_CloseLibrary(); return JNI_FALSE; } version = j2d_glXGetClientString(awt_display, GLX_VERSION); if (version == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGC_InitGLX: could not query GLX version"); OGLFuncs_CloseLibrary(); return JNI_FALSE; } // we now only verify that the client GLX version is >= 1.3 (if the // server does not support GLX 1.3, then we will find that out later // when we attempt to create a GLXFBConfig) J2dRlsTraceLn1(J2D_TRACE_INFO, "GLXGC_InitGLX: client GLX version=%s", version); if (!((version[0] == '1' && version[2] >= '3') || (version[0] > '1'))) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGC_InitGLX: invalid GLX version; 1.3 is required"); OGLFuncs_CloseLibrary(); return JNI_FALSE; } return JNI_TRUE; }
HRESULT D3DPipelineManager::D3DEnabledOnAdapter(UINT adapter) { HRESULT res; D3DDISPLAYMODE dm; res = pd3d9->GetAdapterDisplayMode(adapter, &dm); RETURN_STATUS_IF_FAILED(res); res = pd3d9->CheckDeviceType(adapter, devType, dm.Format, dm.Format, TRUE); if (FAILED(res)) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::D3DEnabledOnAdapter: no " \ "suitable d3d device on adapter %d", adapter); } return res; }
/* * Class: sun_java2d_d3d_D3DGraphicsDevice * Method: getDeviceCapsNative * Signature: (I)I */ JNIEXPORT jint JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_getDeviceCapsNative (JNIEnv *env, jclass d3dsdc, jint gdiScreen) { D3DPipelineManager *pMgr; D3DContext *pCtx; UINT adapter; J2dRlsTraceLn(J2D_TRACE_INFO, "D3DGD_getDeviceCapsNative"); pMgr = D3DPipelineManager::GetInstance(); RETURN_STATUS_IF_NULL(pMgr, CAPS_EMPTY); adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen); if (FAILED(pMgr->GetD3DContext(adapter, &pCtx))) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DGD_getDeviceCapsNative: device %d disabled", adapter); return CAPS_EMPTY; } return pCtx->GetContextCaps(); }
/** * Returns JNI_TRUE only if all of the following conditions are met: * - the GL_ARB_fragment_shader extension is available * - the LCD text shader codepath has been enabled via the system property * - the hardware supports the minimum number of texture units */ static jboolean OGLContext_IsLCDShaderSupportAvailable(JNIEnv *env, jboolean fragShaderAvailable) { jboolean isLCDShaderEnabled = JNI_FALSE; GLint maxTexUnits; J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsLCDShaderSupportAvailable"); // first see if the fragment shader extension is available if (!fragShaderAvailable) { return JNI_FALSE; } // next see if the lcdshader system property has been enabled isLCDShaderEnabled = JNU_GetStaticFieldByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData", "isLCDShaderEnabled", "Z").z; if (!isLCDShaderEnabled) { J2dRlsTraceLn(J2D_TRACE_INFO, "OGLContext_IsLCDShaderSupportAvailable: disabled via flag"); return JNI_FALSE; } // finally, check to see if the hardware supports the required number // of texture units j2d_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &maxTexUnits); if (maxTexUnits < 2) { J2dRlsTraceLn1(J2D_TRACE_INFO, "OGLContext_IsLCDShaderSupportAvailable: not enough tex units (%d)", maxTexUnits); } J2dRlsTraceLn(J2D_TRACE_INFO, "OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported"); return JNI_TRUE; }
/** * Returns the X11 VisualID that corresponds to the best GLXFBConfig for the * given screen. If no valid visual could be found, this method returns zero. * Note that this method will attempt to initialize GLX (and all the * necessary function symbols) if it has not been already. The AWT_LOCK * must be acquired before calling this method. */ VisualID GLXGC_FindBestVisual(JNIEnv *env, jint screen) { GLXFBConfig fbc; XVisualInfo *xvi; VisualID visualid; J2dRlsTraceLn1(J2D_TRACE_INFO, "GLXGC_FindBestVisual: scn=%d", screen); if (!GLXGC_IsGLXAvailable()) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGC_FindBestVisual: could not initialize GLX"); return 0; } fbc = GLXGC_InitFBConfig(env, screen, 0); if (fbc == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGC_FindBestVisual: could not find best visual"); return 0; } xvi = j2d_glXGetVisualFromFBConfig(awt_display, fbc); if (xvi == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGC_FindBestVisual: could not get visual for fbconfig"); return 0; } visualid = xvi->visualid; XFree(xvi); J2dRlsTraceLn2(J2D_TRACE_INFO, "GLXGC_FindBestVisual: chose 0x%x as the best visual for screen %d", visualid, screen); return visualid; }
int TestForBadHardware(DxCapabilities *dxCaps) { // Check this device against a list of bad d3d devices and // disable as necessary static WCHAR *badDeviceStrings[] = { L"Trident Video Accelerator", L"RAGE PRO", L"RAGE XL", L"Rage Fury", }; static int numBadDevices = 4; WCHAR *dxDeviceName = dxCaps->GetDeviceName(); for (int i = 0; i < numBadDevices; ++i) { if (wcsstr(dxDeviceName, badDeviceStrings[i]) != NULL) { // REMIND: For now, we disable d3d for all operations because // of one bad d3d device in the system. This is because we // should avoid registering the d3d rendering loops at the // Java level since we cannot use d3d at the native level. // A real fix would instead understand the difference between // a surface that could handle d3d native rendering and one // that could not and would use the appropriate rendering loop // so that disabling d3d on simply one device would be // sufficient. // Note that this disable-all approach is okay for now because // the single bad device (Trident) that triggers this error // is generally found on laptops, where multiple graphics // devices are not even possible, so disabling d3d for all // devices is equivalent to disabling d3d for this single // device. J2dRlsTraceLn1(J2D_TRACE_ERROR, "TestForBadHardware: Found match: %S. Test FAILED", badDeviceStrings[i]); return J2D_D3D_FAILURE; } } return J2D_D3D_HW_OK; }
/** * Determines whether the WGL pipeline can be used for a given GraphicsConfig * provided its screen number and visual ID. If the minimum requirements are * met, the native WGLGraphicsConfigInfo structure is initialized for this * GraphicsConfig with the necessary information (pixel format, etc.) * and a pointer to this structure is returned as a jlong. If * initialization fails at any point, zero is returned, indicating that WGL * cannot be used for this GraphicsConfig (we should fallback on the existing * DX pipeline). */ JNIEXPORT jlong JNICALL Java_sun_java2d_opengl_WGLGraphicsConfig_getWGLConfigInfo(JNIEnv *env, jclass wglgc, jint screennum, jint pixfmt) { OGLContext *oglc; PIXELFORMATDESCRIPTOR pfd; HWND hwnd; HDC hdc; HGLRC context; HPBUFFERARB scratch; HDC scratchDC; WGLGraphicsConfigInfo *wglinfo; const unsigned char *versionstr; const char *extstr; jint caps = CAPS_EMPTY; int attrKeys[] = { WGL_DOUBLE_BUFFER_ARB, WGL_ALPHA_BITS_ARB }; int attrVals[2]; J2dRlsTraceLn(J2D_TRACE_INFO, "WGLGraphicsConfig_getWGLConfigInfo"); // initialize GL/WGL extension functions if (!WGLGC_InitExtFuncs(screennum)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not init ext funcs"); return 0L; } // create a scratch window hwnd = WGLGC_CreateScratchWindow(screennum); if (hwnd == 0) { return 0L; } // get the HDC for the scratch window hdc = GetDC(hwnd); if (hdc == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not get dc for scratch window"); DestroyWindow(hwnd); return 0L; } if (pixfmt == 0) { // find an appropriate pixel format pixfmt = WGLGC_GetPixelFormatForDC(hdc); if (pixfmt == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not find appropriate pixfmt"); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } } if (sharedContext == 0) { // create the one shared context sharedContext = WGLGC_CreateContext(screennum, pixfmt); if (sharedContext == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not create shared context"); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } } // set the pixel format for the scratch window if (!SetPixelFormat(hdc, pixfmt, &pfd)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsconfig_getWGLConfigInfo: error setting pixel format"); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } // create the HGLRC (context) for this WGLGraphicsConfig context = j2d_wglCreateContext(hdc); if (context == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not create WGL context"); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } // REMIND: when using wglShareLists, the two contexts must use an // identical pixel format... if (!j2d_wglShareLists(sharedContext, context)) { J2dRlsTraceLn(J2D_TRACE_WARNING, "WGLGraphicsConfig_getWGLConfigInfo: unable to share lists"); } // make the context current so that we can query the OpenGL version // and extension strings if (!j2d_wglMakeCurrent(hdc, context)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not make temp context current"); j2d_wglDeleteContext(context); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } // get version and extension strings versionstr = j2d_glGetString(GL_VERSION); extstr = j2d_wglGetExtensionsStringARB(hdc); OGLContext_GetExtensionInfo(env, &caps); J2dRlsTraceLn1(J2D_TRACE_INFO, "WGLGraphicsConfig_getWGLConfigInfo: OpenGL version=%s", (versionstr == NULL) ? "null" : (char *)versionstr); if (!OGLContext_IsVersionSupported(versionstr)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: OpenGL 1.2 is required"); j2d_wglMakeCurrent(NULL, NULL); j2d_wglDeleteContext(context); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } // check for required WGL extensions if (!OGLContext_IsExtensionAvailable(extstr, "WGL_ARB_pbuffer") || !OGLContext_IsExtensionAvailable(extstr, "WGL_ARB_make_current_read")|| !OGLContext_IsExtensionAvailable(extstr, "WGL_ARB_pixel_format")) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: required ext(s) unavailable"); j2d_wglMakeCurrent(NULL, NULL); j2d_wglDeleteContext(context); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0L; } // get config-specific capabilities j2d_wglGetPixelFormatAttribivARB(hdc, pixfmt, 0, 2, attrKeys, attrVals); if (attrVals[0]) { caps |= CAPS_DOUBLEBUFFERED; } if (attrVals[1] > 0) { caps |= CAPS_STORED_ALPHA; } // create the scratch pbuffer scratch = j2d_wglCreatePbufferARB(hdc, pixfmt, 1, 1, NULL); // destroy the temporary resources j2d_wglMakeCurrent(NULL, NULL); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); if (scratch == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not create scratch surface"); j2d_wglDeleteContext(context); return 0L; } // get the HDC for the scratch pbuffer scratchDC = j2d_wglGetPbufferDCARB(scratch); if (scratchDC == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not get hdc for scratch surface"); j2d_wglDeleteContext(context); j2d_wglDestroyPbufferARB(scratch); return 0L; } // initialize the OGLContext, which wraps the pixfmt and HGLRC (context) oglc = WGLGC_InitOGLContext(pixfmt, context, scratch, scratchDC, caps); if (oglc == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not create oglc"); j2d_wglDeleteContext(context); j2d_wglReleasePbufferDCARB(scratch, scratchDC); j2d_wglDestroyPbufferARB(scratch); return 0L; } J2dTraceLn(J2D_TRACE_VERBOSE, "WGLGraphicsConfig_getWGLConfigInfo: finished checking dependencies"); // create the WGLGraphicsConfigInfo record for this config wglinfo = (WGLGraphicsConfigInfo *)malloc(sizeof(WGLGraphicsConfigInfo)); if (wglinfo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGraphicsConfig_getWGLConfigInfo: could not allocate memory for wglinfo"); WGLGC_DestroyOGLContext(oglc); return 0L; } wglinfo->screen = screennum; wglinfo->pixfmt = pixfmt; wglinfo->context = oglc; return ptr_to_jlong(wglinfo); }
/** * Returns a pixel format identifier that is suitable for Java 2D's needs * (must have a depth buffer, support for pbuffers, etc). This method will * iterate through all pixel formats (if any) that match the requested * attributes and will attempt to find a pixel format with a minimal combined * depth+stencil buffer. Note that we currently only need depth capabilities * (for shape clipping purposes), but wglChoosePixelFormatARB() will often * return a list of pixel formats with the largest depth buffer (and stencil) * sizes at the top of the list. Therefore, we scan through the whole list * to find the most VRAM-efficient pixel format. If no appropriate pixel * format can be found, this method returns 0. */ static int WGLGC_GetPixelFormatForDC(HDC hdc) { int attrs[] = { WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_DEPTH_BITS_ARB, 16, // anything >= 16 will work for us 0 }; int pixfmts[32]; int chosenPixFmt = 0; int nfmts, i; // this is the initial minimum value for the combined depth+stencil size // (we initialize it to some absurdly high value; realistic values will // be much less than this number) int minDepthPlusStencil = 512; J2dRlsTraceLn(J2D_TRACE_INFO, "WGLGC_GetPixelFormatForDC"); // find all pixel formats (maximum of 32) with the provided attributes if (!j2d_wglChoosePixelFormatARB(hdc, attrs, NULL, 32, pixfmts, &nfmts)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGC_GetPixelFormatForDC: error choosing pixel format"); return 0; } if (nfmts <= 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGC_GetPixelFormatForDC: no pixel formats found"); return 0; } J2dRlsTraceLn(J2D_TRACE_VERBOSE, " candidate pixel formats:"); // iterate through the list of pixel formats, looking for the one that // meets our requirements while keeping the combined depth+stencil sizes // to a minimum for (i = 0; i < nfmts; i++) { int attrKeys[] = { WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_DOUBLE_BUFFER_ARB, WGL_ALPHA_BITS_ARB }; int attrVals[4]; int pixfmt = pixfmts[i]; int depth, stencil, db, alpha; j2d_wglGetPixelFormatAttribivARB(hdc, pixfmt, 0, 4, attrKeys, attrVals); depth = attrVals[0]; stencil = attrVals[1]; db = attrVals[2]; alpha = attrVals[3]; J2dRlsTrace5(J2D_TRACE_VERBOSE, "[V] pixfmt=%d db=%d alpha=%d depth=%d stencil=%d valid=", pixfmt, db, alpha, depth, stencil); if ((depth + stencil) < minDepthPlusStencil) { J2dRlsTrace(J2D_TRACE_VERBOSE, "true\n"); minDepthPlusStencil = depth + stencil; chosenPixFmt = pixfmt; } else { J2dRlsTrace(J2D_TRACE_VERBOSE, "false (large depth)\n"); } } if (chosenPixFmt == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "WGLGC_GetPixelFormatForDC: could not find appropriate pixfmt"); return 0; } J2dRlsTraceLn1(J2D_TRACE_INFO, "WGLGC_GetPixelFormatForDC: chose %d as the best pixel format", chosenPixFmt); return chosenPixFmt; }
/* * Class: sun_java2d_d3d_D3DSurfaceData * Method: initOffScreenSurface * Signature: (JJJIIII)I */ JNIEXPORT jint JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initOffScreenSurface (JNIEnv *env, jobject sData, jlong pCtx, jlong pData, jlong parentPdata, jint width, jint height, jint d3dSurfaceType, jint screen) { Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData); D3DContext *pd3dc = (D3DContext *)jlong_to_ptr(pCtx); J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOffScreenSurface"); J2dTraceLn4(J2D_TRACE_VERBOSE, " width=%-4d height=%-4d type=%-3d scr=%-3d", width, height, d3dSurfaceType, screen); // REMIND: ideally this should be done in initOps if (d3dSurfaceType == D3D_ATTACHED_SURFACE) { wsdo->sdOps.Dispose = Win32BBSD_Dispose; } if (init_D3DSDO(env, wsdo, width, height, d3dSurfaceType, screen) == JNI_FALSE) { SurfaceData_ThrowInvalidPipeException(env, "Can't create offscreen surface"); return PF_INVALID; } HMONITOR hMon = (HMONITOR)wsdo->device->GetMonitor(); DDrawObjectStruct *ddInstance = GetDDInstanceForDevice(hMon); if (!ddInstance || !ddInstance->valid || !pd3dc) { return PF_INVALID; } if (d3dSurfaceType == D3D_ATTACHED_SURFACE) { // REMIND: still using the old path. ideally the creation of attached // surface shoudld be done in the same way as other types of surfaces, // that is, in D3DContext::CreateSurface, but we really don't use // anything from D3DContext to get an attached surface, so this // was left here. Win32SDOps *wsdo_parent = (Win32SDOps *)jlong_to_ptr(parentPdata); // we're being explicit here: requesting backbuffer, and render target DDrawSurface* pNew = wsdo_parent->lpSurface == NULL ? NULL : wsdo_parent->lpSurface-> GetDDAttachedSurface(DDSCAPS_BACKBUFFER|DDSCAPS_3DDEVICE); if (pNew == NULL || FAILED(pd3dc->AttachDepthBuffer(pNew->GetDXSurface()))) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DSD_initSurface: GetAttachedSurface for parent"\ " wsdo_parent->lpSurface=0x%x failed", wsdo_parent->lpSurface); if (pNew != NULL) { delete pNew; } SurfaceData_ThrowInvalidPipeException(env, "Can't create attached offscreen surface"); return PF_INVALID; } wsdo->lpSurface = pNew; wsdo->ddInstance = ddInstance; J2dTraceLn2(J2D_TRACE_VERBOSE, "D3DSD_initSurface: created attached surface: "\ "wsdo->lpSurface=0x%x for parent "\ "wsdo_parent->lpSurface=0x%x", wsdo->lpSurface, wsdo_parent->lpSurface); // we don't care about pixel format for non-texture surfaces return PF_INVALID; } DXSurface *dxSurface = NULL; jint pf = PF_INVALID; HRESULT res; if (SUCCEEDED(res = pd3dc->CreateSurface(env, wsdo->w, wsdo->h, wsdo->depth, wsdo->transparency, d3dSurfaceType, &dxSurface, &pf))) { // REMIND: put all the error-handling stuff here from // DDCreateOffScreenSurface wsdo->lpSurface = new DDrawSurface(ddInstance->ddObject, dxSurface); wsdo->surfacePuntData.lpSurfaceVram = wsdo->lpSurface; wsdo->ddInstance = ddInstance; // the dimensions of the surface may be adjusted in case of // textures wsdo->w = dxSurface->GetWidth(); wsdo->h = dxSurface->GetHeight(); J2dTraceLn1(J2D_TRACE_VERBOSE, "D3DSurfaceData_initSurface: created surface: "\ "wsdo->lpSurface=0x%x", wsdo->lpSurface); } else { DebugPrintDirectDrawError(res, "D3DSurfaceData_initSurface: "\ "CreateSurface failed"); // REMIND: should use some other way to signal that // surface creation was unsuccessful SurfaceData_ThrowInvalidPipeException(env, "Can't create offscreen surf"); } return pf; }
LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig, void *data, size_t size) { LCMSBOOL isNew; int i, idx, delta, count; LPBYTE padChars[3] = {0, 0, 0}; LPBYTE beforeBuf, afterBuf, ptr; size_t beforeSize, afterSize; icUInt32Number profileSize, temp; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; isNew = FALSE; idx = _cmsSearchTag(Icc, sig, FALSE); if (idx < 0) { isNew = TRUE; idx = Icc->TagCount++; if (Icc->TagCount >= MAX_TABLE_TAG) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "_cmsModifyTagData: Too many tags " "(%d)\n", Icc->TagCount); Icc->TagCount = MAX_TABLE_TAG-1; return FALSE; } } /* Read in size from header */ Icc->Seek(Icc, 0); Icc->Read(&profileSize, sizeof(icUInt32Number), 1, Icc); AdjustEndianess32((LPBYTE) &profileSize); /* Compute the change in profile size */ if (isNew) { delta = sizeof(icTag) + ALIGNLONG(size); } else { delta = ALIGNLONG(size) - ALIGNLONG(Icc->TagSizes[idx]); } /* Add tag to internal structures */ ptr = malloc(size); if (ptr == NULL) { if(isNew) { Icc->TagCount--; } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: ptr == NULL"); return FALSE; } /* We change the size of Icc here only if we know it'll actually * grow: if Icc is about to shrink we must wait until we've read * the previous data. */ if (delta > 0) { if (!Icc->Grow(Icc, delta)) { free(ptr); if(isNew) { Icc->TagCount--; } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: Icc->Grow() == FALSE"); return FALSE; } } /* Compute size of tag data before/after the modified tag */ beforeSize = ((isNew)?profileSize:Icc->TagOffsets[idx]) - Icc->TagOffsets[0]; if (Icc->TagCount == (idx + 1)) { afterSize = 0; } else { afterSize = profileSize - Icc->TagOffsets[idx+1]; } /* Make copies of the data before/after the modified tag */ if (beforeSize > 0) { beforeBuf = malloc(beforeSize); if (!beforeBuf) { if(isNew) { Icc->TagCount--; } free(ptr); J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: beforeBuf == NULL"); return FALSE; } Icc->Seek(Icc, Icc->TagOffsets[0]); Icc->Read(beforeBuf, beforeSize, 1, Icc); } if (afterSize > 0) { afterBuf = malloc(afterSize); if (!afterBuf) { free(ptr); if(isNew) { Icc->TagCount--; } if (beforeSize > 0) { free(beforeBuf); } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: afterBuf == NULL"); return FALSE; } Icc->Seek(Icc, Icc->TagOffsets[idx+1]); Icc->Read(afterBuf, afterSize, 1, Icc); } CopyMemory(ptr, data, size); Icc->TagSizes[idx] = size; Icc->TagNames[idx] = sig; if (Icc->TagPtrs[idx]) { free(Icc->TagPtrs[idx]); } Icc->TagPtrs[idx] = ptr; if (isNew) { Icc->TagOffsets[idx] = profileSize; } /* Update the profile size in the header */ profileSize += delta; Icc->Seek(Icc, 0); temp = TransportValue32(profileSize); Icc->Write(Icc, sizeof(icUInt32Number), &temp); /* Shrink Icc, if needed. */ if (delta < 0) { if (!Icc->Grow(Icc, delta)) { free(ptr); if(isNew) { Icc->TagCount--; } J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: Icc->Grow() == FALSE"); return FALSE; } } /* Adjust tag offsets: if the tag is new, we must account for the new tag table entry; otherwise, only those tags after the modified tag are changed (by delta) */ if (isNew) { for (i = 0; i < Icc->TagCount; ++i) { Icc->TagOffsets[i] += sizeof(icTag); } } else { for (i = idx+1; i < Icc->TagCount; ++i) { Icc->TagOffsets[i] += delta; } } /* Write out a new tag table */ count = 0; for (i = 0; i < Icc->TagCount; ++i) { if (Icc->TagNames[i] != 0) { ++count; } } Icc->Seek(Icc, sizeof(icHeader)); temp = TransportValue32(count); Icc->Write(Icc, sizeof(icUInt32Number), &temp); for (i = 0; i < Icc->TagCount; ++i) { if (Icc->TagNames[i] != 0) { icTag tag; tag.sig = TransportValue32(Icc->TagNames[i]); tag.offset = TransportValue32((icInt32Number) Icc->TagOffsets[i]); tag.size = TransportValue32((icInt32Number) Icc->TagSizes[i]); Icc->Write(Icc, sizeof(icTag), &tag); } } /* Write unchanged data before the modified tag */ if (beforeSize > 0) { Icc->Write(Icc, beforeSize, beforeBuf); free(beforeBuf); } /* Write modified tag data */ Icc->Write(Icc, size, data); if (size % 4) { Icc->Write(Icc, 4 - (size % 4), padChars); } /* Write unchanged data after the modified tag */ if (afterSize > 0) { Icc->Write(Icc, afterSize, afterBuf); free(afterBuf); } return TRUE; }
/** * Determines whether the GLX pipeline can be used for a given GraphicsConfig * provided its screen number and visual ID. If the minimum requirements are * met, the native GLXGraphicsConfigInfo structure is initialized for this * GraphicsConfig with the necessary information (GLXFBConfig, etc.) * and a pointer to this structure is returned as a jlong. If * initialization fails at any point, zero is returned, indicating that GLX * cannot be used for this GraphicsConfig (we should fallback on the existing * X11 pipeline). */ JNIEXPORT jlong JNICALL Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo(JNIEnv *env, jclass glxgc, jint screennum, jint visnum) { #ifndef HEADLESS OGLContext *oglc; GLXFBConfig fbconfig; GLXContext context; GLXPbuffer scratch; GLXGraphicsConfigInfo *glxinfo; jint caps = CAPS_EMPTY; int db, alpha; const unsigned char *versionstr; J2dRlsTraceLn(J2D_TRACE_INFO, "GLXGraphicsConfig_getGLXConfigInfo"); if (usingXinerama) { // when Xinerama is enabled, the screen ID needs to be 0 screennum = 0; } fbconfig = GLXGC_InitFBConfig(env, screennum, (VisualID)visnum); if (fbconfig == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: could not create fbconfig"); return 0L; } if (sharedContext == 0) { // create the one shared context sharedContext = j2d_glXCreateNewContext(awt_display, fbconfig, GLX_RGBA_TYPE, 0, GL_TRUE); if (sharedContext == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: could not create shared context"); return 0L; } } // create the GLXContext for this GLXGraphicsConfig context = j2d_glXCreateNewContext(awt_display, fbconfig, GLX_RGBA_TYPE, sharedContext, GL_TRUE); if (context == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: could not create GLX context"); return 0L; } // this is pretty sketchy, but it seems to be the easiest way to create // some form of GLXDrawable using only the display and a GLXFBConfig // (in order to make the context current for checking the version, // extensions, etc)... scratch = GLXGC_InitScratchPbuffer(fbconfig); if (scratch == 0) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: could not create scratch pbuffer"); j2d_glXDestroyContext(awt_display, context); return 0L; } // the context must be made current before we can query the // version and extension strings j2d_glXMakeContextCurrent(awt_display, scratch, scratch, context); #ifdef __sparc /* * 6438225: The software rasterizer used by Sun's OpenGL libraries * for certain boards has quality issues, and besides, performance * of these boards is not high enough to justify the use of the * OpenGL-based Java 2D pipeline. If we detect one of the following * boards via the GL_RENDERER string, just give up: * - FFB[2[+]] ("Creator[3D]") * - PGX-series ("m64") * - AFB ("Elite3D") */ { const char *renderer = (const char *)j2d_glGetString(GL_RENDERER); J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "GLXGraphicsConfig_getGLXConfigInfo: detected renderer (%s)", (renderer == NULL) ? "null" : renderer); if (renderer == NULL || strncmp(renderer, "Creator", 7) == 0 || strncmp(renderer, "SUNWm64", 7) == 0 || strncmp(renderer, "Elite", 5) == 0) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: unsupported board (%s)", (renderer == NULL) ? "null" : renderer); j2d_glXMakeContextCurrent(awt_display, None, None, NULL); j2d_glXDestroyPbuffer(awt_display, scratch); j2d_glXDestroyContext(awt_display, context); return 0L; } } #endif /* __sparc */ versionstr = j2d_glGetString(GL_VERSION); OGLContext_GetExtensionInfo(env, &caps); // destroy the temporary resources j2d_glXMakeContextCurrent(awt_display, None, None, NULL); J2dRlsTraceLn1(J2D_TRACE_INFO, "GLXGraphicsConfig_getGLXConfigInfo: OpenGL version=%s", (versionstr == NULL) ? "null" : (char *)versionstr); if (!OGLContext_IsVersionSupported(versionstr)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: OpenGL 1.2 is required"); j2d_glXDestroyPbuffer(awt_display, scratch); j2d_glXDestroyContext(awt_display, context); return 0L; } // get config-specific capabilities j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_DOUBLEBUFFER, &db); if (db) { caps |= CAPS_DOUBLEBUFFERED; } j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_ALPHA_SIZE, &alpha); if (alpha > 0) { caps |= CAPS_STORED_ALPHA; } // initialize the OGLContext, which wraps the GLXFBConfig and GLXContext oglc = GLXGC_InitOGLContext(fbconfig, context, scratch, caps); if (oglc == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: could not create oglc"); j2d_glXDestroyPbuffer(awt_display, scratch); j2d_glXDestroyContext(awt_display, context); return 0L; } J2dTraceLn(J2D_TRACE_VERBOSE, "GLXGraphicsConfig_getGLXConfigInfo: finished checking dependencies"); // create the GLXGraphicsConfigInfo record for this config glxinfo = (GLXGraphicsConfigInfo *)malloc(sizeof(GLXGraphicsConfigInfo)); if (glxinfo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "GLXGraphicsConfig_getGLXConfigInfo: could not allocate memory for glxinfo"); GLXGC_DestroyOGLContext(oglc); return 0L; } glxinfo->screen = screennum; glxinfo->visual = visnum; glxinfo->context = oglc; glxinfo->fbconfig = fbconfig; return ptr_to_jlong(glxinfo); #else return 0L; #endif /* !HEADLESS */ }
JNIEXPORT void JNICALL Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer (JNIEnv *env, jobject oglrq, jlong buf, jint limit) { jboolean sync = JNI_FALSE; unsigned char *b, *end; J2dTraceLn1(J2D_TRACE_INFO, "OGLRenderQueue_flushBuffer: limit=%d", limit); b = (unsigned char *)jlong_to_ptr(buf); if (b == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLRenderQueue_flushBuffer: cannot get direct buffer address"); return; } INIT_PREVIOUS_OP(); end = b + limit; while (b < end) { jint opcode = NEXT_INT(b); J2dTraceLn2(J2D_TRACE_VERBOSE, "OGLRenderQueue_flushBuffer: opcode=%d, rem=%d", opcode, (end-b)); switch (opcode) { // draw ops case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE: { jint x1 = NEXT_INT(b); jint y1 = NEXT_INT(b); jint x2 = NEXT_INT(b); jint y2 = NEXT_INT(b); OGLRenderer_DrawLine(oglc, x1, y1, x2, y2); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); OGLRenderer_DrawRect(oglc, x, y, w, h); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY: { jint nPoints = NEXT_INT(b); jboolean isClosed = NEXT_BOOLEAN(b); jint transX = NEXT_INT(b); jint transY = NEXT_INT(b); jint *xPoints = (jint *)b; jint *yPoints = ((jint *)b) + nPoints; OGLRenderer_DrawPoly(oglc, nPoints, isClosed, transX, transY, xPoints, yPoints); SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); // Note that we could use GL_POINTS here, but the common // use case for DRAW_PIXEL is when rendering a Path2D, // which will consist of a mix of DRAW_PIXEL and DRAW_LINE // calls. So to improve batching we use GL_LINES here, // even though it requires an extra vertex per pixel. CONTINUE_IF_NULL(oglc); CHECK_PREVIOUS_OP(GL_LINES); j2d_glVertex2i(x, y); j2d_glVertex2i(x+1, y+1); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES: { jint count = NEXT_INT(b); OGLRenderer_DrawScanlines(oglc, count, (jint *)b); SKIP_BYTES(b, count * BYTES_PER_SCANLINE); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); jfloat lwr21 = NEXT_FLOAT(b); jfloat lwr12 = NEXT_FLOAT(b); OGLRenderer_DrawParallelogram(oglc, x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); jfloat lwr21 = NEXT_FLOAT(b); jfloat lwr12 = NEXT_FLOAT(b); OGLRenderer_DrawAAParallelogram(oglc, dstOps, x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12); } break; // fill ops case sun_java2d_pipe_BufferedOpCodes_FILL_RECT: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); OGLRenderer_FillRect(oglc, x, y, w, h); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS: { jint count = NEXT_INT(b); OGLRenderer_FillSpans(oglc, count, (jint *)b); SKIP_BYTES(b, count * BYTES_PER_SPAN); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); OGLRenderer_FillParallelogram(oglc, x11, y11, dx21, dy21, dx12, dy12); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); OGLRenderer_FillAAParallelogram(oglc, dstOps, x11, y11, dx21, dy21, dx12, dy12); } break; // text-related ops case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST: { jint numGlyphs = NEXT_INT(b); jint packedParams = NEXT_INT(b); jfloat glyphListOrigX = NEXT_FLOAT(b); jfloat glyphListOrigY = NEXT_FLOAT(b); jboolean usePositions = EXTRACT_BOOLEAN(packedParams, OFFSET_POSITIONS); jboolean subPixPos = EXTRACT_BOOLEAN(packedParams, OFFSET_SUBPIXPOS); jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams, OFFSET_RGBORDER); jint lcdContrast = EXTRACT_BYTE(packedParams, OFFSET_CONTRAST); unsigned char *images = b; unsigned char *positions; jint bytesPerGlyph; if (usePositions) { positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE); bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH; } else { positions = NULL; bytesPerGlyph = BYTES_PER_GLYPH_IMAGE; } OGLTR_DrawGlyphList(env, oglc, dstOps, numGlyphs, usePositions, subPixPos, rgbOrder, lcdContrast, glyphListOrigX, glyphListOrigY, images, positions); SKIP_BYTES(b, numGlyphs * bytesPerGlyph); } break; // copy-related ops case sun_java2d_pipe_BufferedOpCodes_COPY_AREA: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); jint dx = NEXT_INT(b); jint dy = NEXT_INT(b); OGLBlitLoops_CopyArea(env, oglc, dstOps, x, y, w, h, dx, dy); } break; case sun_java2d_pipe_BufferedOpCodes_BLIT: { jint packedParams = NEXT_INT(b); jint sx1 = NEXT_INT(b); jint sy1 = NEXT_INT(b); jint sx2 = NEXT_INT(b); jint sy2 = NEXT_INT(b); jdouble dx1 = NEXT_DOUBLE(b); jdouble dy1 = NEXT_DOUBLE(b); jdouble dx2 = NEXT_DOUBLE(b); jdouble dy2 = NEXT_DOUBLE(b); jlong pSrc = NEXT_LONG(b); jlong pDst = NEXT_LONG(b); jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT); jboolean texture = EXTRACT_BOOLEAN(packedParams, OFFSET_TEXTURE); jboolean rtt = EXTRACT_BOOLEAN(packedParams, OFFSET_RTT); jboolean xform = EXTRACT_BOOLEAN(packedParams, OFFSET_XFORM); jboolean isoblit = EXTRACT_BOOLEAN(packedParams, OFFSET_ISOBLIT); if (isoblit) { OGLBlitLoops_IsoBlit(env, oglc, pSrc, pDst, xform, hint, texture, rtt, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } else { jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE); OGLBlitLoops_Blit(env, oglc, pSrc, pDst, xform, hint, srctype, texture, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } } break; case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT: { jint sx = NEXT_INT(b); jint sy = NEXT_INT(b); jint dx = NEXT_INT(b); jint dy = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); jint dsttype = NEXT_INT(b); jlong pSrc = NEXT_LONG(b); jlong pDst = NEXT_LONG(b); OGLBlitLoops_SurfaceToSwBlit(env, oglc, pSrc, pDst, dsttype, sx, sy, dx, dy, w, h); } break; case sun_java2d_pipe_BufferedOpCodes_MASK_FILL: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); jint maskoff = NEXT_INT(b); jint maskscan = NEXT_INT(b); jint masklen = NEXT_INT(b); unsigned char *pMask = (masklen > 0) ? b : NULL; OGLMaskFill_MaskFill(oglc, x, y, w, h, maskoff, maskscan, masklen, pMask); SKIP_BYTES(b, masklen); } break; case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT: { jint dstx = NEXT_INT(b); jint dsty = NEXT_INT(b); jint width = NEXT_INT(b); jint height = NEXT_INT(b); jint masklen = width * height * sizeof(jint); OGLMaskBlit_MaskBlit(env, oglc, dstx, dsty, width, height, b); SKIP_BYTES(b, masklen); } break; // state-related ops case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP: { jint x1 = NEXT_INT(b); jint y1 = NEXT_INT(b); jint x2 = NEXT_INT(b); jint y2 = NEXT_INT(b); OGLContext_SetRectClip(oglc, dstOps, x1, y1, x2, y2); } break; case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP: { OGLContext_BeginShapeClip(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS: { jint count = NEXT_INT(b); OGLRenderer_FillSpans(oglc, count, (jint *)b); SKIP_BYTES(b, count * BYTES_PER_SPAN); } break; case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP: { OGLContext_EndShapeClip(oglc, dstOps); } break; case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP: { OGLContext_ResetClip(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE: { jint rule = NEXT_INT(b); jfloat extraAlpha = NEXT_FLOAT(b); jint flags = NEXT_INT(b); OGLContext_SetAlphaComposite(oglc, rule, extraAlpha, flags); } break; case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE: { jint xorPixel = NEXT_INT(b); OGLContext_SetXorComposite(oglc, xorPixel); } break; case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE: { OGLContext_ResetComposite(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM: { jdouble m00 = NEXT_DOUBLE(b); jdouble m10 = NEXT_DOUBLE(b); jdouble m01 = NEXT_DOUBLE(b); jdouble m11 = NEXT_DOUBLE(b); jdouble m02 = NEXT_DOUBLE(b); jdouble m12 = NEXT_DOUBLE(b); OGLContext_SetTransform(oglc, m00, m10, m01, m11, m02, m12); } break; case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM: { OGLContext_ResetTransform(oglc); } break; // context-related ops case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES: { jlong pSrc = NEXT_LONG(b); jlong pDst = NEXT_LONG(b); if (oglc != NULL) { RESET_PREVIOUS_OP(); } oglc = OGLContext_SetSurfaces(env, pSrc, pDst); dstOps = (OGLSDOps *)jlong_to_ptr(pDst); } break; case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE: { jlong pConfigInfo = NEXT_LONG(b); if (oglc != NULL) { RESET_PREVIOUS_OP(); } oglc = OGLSD_SetScratchSurface(env, pConfigInfo); dstOps = NULL; } break; case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE: { jlong pData = NEXT_LONG(b); OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); if (oglsdo != NULL) { CONTINUE_IF_NULL(oglc); RESET_PREVIOUS_OP(); OGLSD_Delete(env, oglsdo); } } break; case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE: { jlong pData = NEXT_LONG(b); OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); if (oglsdo != NULL) { CONTINUE_IF_NULL(oglc); RESET_PREVIOUS_OP(); OGLSD_Delete(env, oglsdo); if (oglsdo->privOps != NULL) { free(oglsdo->privOps); } } } break; case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG: { jlong pConfigInfo = NEXT_LONG(b); CONTINUE_IF_NULL(oglc); RESET_PREVIOUS_OP(); OGLGC_DestroyOGLGraphicsConfig(pConfigInfo); // the previous method will call glX/wglMakeCurrent(None), // so we should nullify the current oglc and dstOps to avoid // calling glFlush() (or similar) while no context is current oglc = NULL; dstOps = NULL; } break; case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT: { // flush just in case there are any pending operations in // the hardware pipe if (oglc != NULL) { RESET_PREVIOUS_OP(); j2d_glFlush(); } // invalidate the references to the current context and // destination surface that are maintained at the native level oglc = NULL; dstOps = NULL; } break; case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE: { j2d_glPushAttrib(GL_ALL_ATTRIB_BITS); j2d_glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); j2d_glMatrixMode(GL_MODELVIEW); j2d_glPushMatrix(); j2d_glMatrixMode(GL_PROJECTION); j2d_glPushMatrix(); j2d_glMatrixMode(GL_TEXTURE); j2d_glPushMatrix(); } break; case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE: { j2d_glPopAttrib(); j2d_glPopClientAttrib(); j2d_glMatrixMode(GL_MODELVIEW); j2d_glPopMatrix(); j2d_glMatrixMode(GL_PROJECTION); j2d_glPopMatrix(); j2d_glMatrixMode(GL_TEXTURE); j2d_glPopMatrix(); } break; case sun_java2d_pipe_BufferedOpCodes_SYNC: { sync = JNI_TRUE; } break; // multibuffering ops case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS: { jlong window = NEXT_LONG(b); if (oglc != NULL) { RESET_PREVIOUS_OP(); } OGLSD_SwapBuffers(env, window); } break; // special no-op (mainly used for achieving 8-byte alignment) case sun_java2d_pipe_BufferedOpCodes_NOOP: break; // paint-related ops case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT: { OGLPaints_ResetPaint(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_COLOR: { jint pixel = NEXT_INT(b); OGLPaints_SetColor(oglc, pixel); } break; case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT: { jboolean useMask= NEXT_BOOLEAN(b); jboolean cyclic = NEXT_BOOLEAN(b); jdouble p0 = NEXT_DOUBLE(b); jdouble p1 = NEXT_DOUBLE(b); jdouble p3 = NEXT_DOUBLE(b); jint pixel1 = NEXT_INT(b); jint pixel2 = NEXT_INT(b); OGLPaints_SetGradientPaint(oglc, useMask, cyclic, p0, p1, p3, pixel1, pixel2); } break; case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT: { jboolean useMask = NEXT_BOOLEAN(b); jboolean linear = NEXT_BOOLEAN(b); jint cycleMethod = NEXT_INT(b); jint numStops = NEXT_INT(b); jfloat p0 = NEXT_FLOAT(b); jfloat p1 = NEXT_FLOAT(b); jfloat p3 = NEXT_FLOAT(b); void *fractions, *pixels; fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); OGLPaints_SetLinearGradientPaint(oglc, dstOps, useMask, linear, cycleMethod, numStops, p0, p1, p3, fractions, pixels); } break; case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT: { jboolean useMask = NEXT_BOOLEAN(b); jboolean linear = NEXT_BOOLEAN(b); jint numStops = NEXT_INT(b); jint cycleMethod = NEXT_INT(b); jfloat m00 = NEXT_FLOAT(b); jfloat m01 = NEXT_FLOAT(b); jfloat m02 = NEXT_FLOAT(b); jfloat m10 = NEXT_FLOAT(b); jfloat m11 = NEXT_FLOAT(b); jfloat m12 = NEXT_FLOAT(b); jfloat focusX = NEXT_FLOAT(b); void *fractions, *pixels; fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); OGLPaints_SetRadialGradientPaint(oglc, dstOps, useMask, linear, cycleMethod, numStops, m00, m01, m02, m10, m11, m12, focusX, fractions, pixels); } break; case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT: { jboolean useMask= NEXT_BOOLEAN(b); jboolean filter = NEXT_BOOLEAN(b); jlong pSrc = NEXT_LONG(b); jdouble xp0 = NEXT_DOUBLE(b); jdouble xp1 = NEXT_DOUBLE(b); jdouble xp3 = NEXT_DOUBLE(b); jdouble yp0 = NEXT_DOUBLE(b); jdouble yp1 = NEXT_DOUBLE(b); jdouble yp3 = NEXT_DOUBLE(b); OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter, xp0, xp1, xp3, yp0, yp1, yp3); } break; // BufferedImageOp-related ops case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP: { jlong pSrc = NEXT_LONG(b); jboolean edgeZero = NEXT_BOOLEAN(b); jint kernelWidth = NEXT_INT(b); jint kernelHeight = NEXT_INT(b); OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero, kernelWidth, kernelHeight, b); SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat)); } break; case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP: { OGLBufImgOps_DisableConvolveOp(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP: { jlong pSrc = NEXT_LONG(b); jboolean nonPremult = NEXT_BOOLEAN(b); jint numFactors = 4; unsigned char *scaleFactors = b; unsigned char *offsets = (b + numFactors * sizeof(jfloat)); OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult, scaleFactors, offsets); SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2); } break; case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP: { OGLBufImgOps_DisableRescaleOp(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP: { jlong pSrc = NEXT_LONG(b); jboolean nonPremult = NEXT_BOOLEAN(b); jboolean shortData = NEXT_BOOLEAN(b); jint numBands = NEXT_INT(b); jint bandLength = NEXT_INT(b); jint offset = NEXT_INT(b); jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte); void *tableValues = b; OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData, numBands, bandLength, offset, tableValues); SKIP_BYTES(b, numBands * bandLength * bytesPerElem); } break; case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP: { OGLBufImgOps_DisableLookupOp(oglc); } break; default: J2dRlsTraceLn1(J2D_TRACE_ERROR, "OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode); if (oglc != NULL) { RESET_PREVIOUS_OP(); } return; } } if (oglc != NULL) { RESET_PREVIOUS_OP(); if (sync) { j2d_glFinish(); } else { j2d_glFlush(); } OGLSD_Flush(env); } }
HRESULT D3DPipelineManager::CheckAdaptersInfo() { D3DADAPTER_IDENTIFIER9 aid; UINT failedAdaptersCount = 0; J2dRlsTraceLn(J2D_TRACE_INFO, "CheckAdaptersInfo"); J2dRlsTraceLn(J2D_TRACE_INFO, "------------------"); for (UINT Adapter = 0; Adapter < adapterCount; Adapter++) { if (FAILED(pd3d9->GetAdapterIdentifier(Adapter, 0, &aid))) { pAdapters[Adapter].state = CONTEXT_INIT_FAILED; failedAdaptersCount++; continue; } J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Ordinal : %d", Adapter); J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Handle : 0x%x", pd3d9->GetAdapterMonitor(Adapter)); J2dRlsTraceLn1(J2D_TRACE_INFO, "Description : %s", aid.Description); J2dRlsTraceLn2(J2D_TRACE_INFO, "GDI Name, Driver : %s, %s", aid.DeviceName, aid.Driver); J2dRlsTraceLn1(J2D_TRACE_INFO, "Vendor Id : 0x%04x", aid.VendorId); J2dRlsTraceLn1(J2D_TRACE_INFO, "Device Id : 0x%04x", aid.DeviceId); J2dRlsTraceLn1(J2D_TRACE_INFO, "SubSys Id : 0x%x", aid.SubSysId); J2dRlsTraceLn4(J2D_TRACE_INFO, "Driver Version : %d.%d.%d.%d", HIWORD(aid.DriverVersion.HighPart), LOWORD(aid.DriverVersion.HighPart), HIWORD(aid.DriverVersion.LowPart), LOWORD(aid.DriverVersion.LowPart)); J2dRlsTrace3(J2D_TRACE_INFO, "[I] GUID : {%08X-%04X-%04X-", aid.DeviceIdentifier.Data1, aid.DeviceIdentifier.Data2, aid.DeviceIdentifier.Data3); J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X-%02X%02X", aid.DeviceIdentifier.Data4[0], aid.DeviceIdentifier.Data4[1], aid.DeviceIdentifier.Data4[2], aid.DeviceIdentifier.Data4[3]); J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X%02X%02X}\n", aid.DeviceIdentifier.Data4[4], aid.DeviceIdentifier.Data4[5], aid.DeviceIdentifier.Data4[6], aid.DeviceIdentifier.Data4[7]); if (FAILED(CheckForBadHardware(aid.VendorId, aid.DeviceId, aid.DriverVersion.QuadPart)) || FAILED(CheckDeviceCaps(Adapter)) || FAILED(D3DEnabledOnAdapter(Adapter))) { pAdapters[Adapter].state = CONTEXT_INIT_FAILED; failedAdaptersCount++; } J2dRlsTraceLn(J2D_TRACE_INFO, "------------------"); } if (failedAdaptersCount == adapterCount) { J2dRlsTraceLn(J2D_TRACE_ERROR, "D3DPPLM::CheckAdaptersInfo: no suitable adapters found"); return E_FAIL; } return S_OK; }
/* * Class: sun_java2d_d3d_D3DGraphicsDevice * Method: configDisplayModeNative * Signature: (IJIIII)V */ JNIEXPORT void JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_configDisplayModeNative (JNIEnv *env, jclass gdc, jint gdiScreen, jlong window, jint width, jint height, jint bitDepth, jint refreshRate) { HRESULT res; D3DPipelineManager *pMgr; D3DContext *pCtx; D3DPRESENT_PARAMETERS newParams, *pCurParams; UINT adapter; J2dTraceLn(J2D_TRACE_INFO, "D3DGD_configDisplayModeNative"); RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance()); adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen); if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) { D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination()); return; } pCurParams = pCtx->GetPresentationParams(); newParams = *pCurParams; newParams.BackBufferWidth = width; newParams.BackBufferHeight = height; newParams.FullScreen_RefreshRateInHz = refreshRate; newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; // we leave the swap effect so that it's more likely // to be the one user selected initially // newParams.SwapEffect = D3DSWAPEFFECT_DISCARD; if (bitDepth == 32) { newParams.BackBufferFormat = D3DFMT_X8R8G8B8; } else if (bitDepth == 16) { UINT modeNum; D3DDISPLAYMODE mode; IDirect3D9 *pd3d9; UINT modesCount; RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject()); modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_R5G6B5); if (modesCount == 0) { modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_X1R5G5B5); } newParams.BackBufferFormat = D3DFMT_UNKNOWN; for (modeNum = 0; modeNum < modesCount; modeNum++) { if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, D3DFMT_R5G6B5, modeNum, &mode))) { if (mode.Width == width && mode.Height == height && mode.RefreshRate == refreshRate) { // prefer 565 over 555 if (mode.Format == D3DFMT_R5G6B5) { newParams.BackBufferFormat = D3DFMT_R5G6B5; break; } else if (mode.Format == D3DFMT_X1R5G5B5) { newParams.BackBufferFormat = D3DFMT_X1R5G5B5; } } } } if (newParams.BackBufferFormat == D3DFMT_UNKNOWN) { J2dRlsTraceLn(J2D_TRACE_ERROR, "D3DGD_configDisplayModeNative: no 16-bit formats"); return; } } else { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DGD_configDisplayModeNative: unsupported depth: %d", bitDepth); return; } J2dTraceLn4(J2D_TRACE_VERBOSE, " changing to dm: %dx%dx%d@%d", newParams.BackBufferWidth, newParams.BackBufferHeight, bitDepth, refreshRate); J2dTraceLn1(J2D_TRACE_VERBOSE, " selected backbuffer format: %d", newParams.BackBufferFormat); res = pCtx->ConfigureContext(&newParams); if (SUCCEEDED(res)) { // the full screen window doesn't receive WM_SIZE event when // the display mode changes (it does get resized though) so we need to // generate the event ourselves ::SendMessage(newParams.hDeviceWindow, WM_SIZE, width, height); } D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination()); }
HRESULT D3DPipelineManager::CheckDeviceCaps(UINT adapter) { HRESULT res; D3DCAPS9 d3dCaps; J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckDeviceCaps"); res = pd3d9->GetDeviceCaps(adapter, devType, &d3dCaps); RETURN_STATUS_IF_FAILED(res); CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_DRAWPRIMTLVERTEX); // by requiring hardware tnl we are hoping for better drivers quality if (!IsD3DForced()) { // fail if not hw tnl unless d3d was forced CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWTRANSFORMANDLIGHT); } if (d3dCaps.DeviceType == D3DDEVTYPE_HAL) { CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWRASTERIZATION); } CHECK_CAP(d3dCaps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST); CHECK_CAP(d3dCaps.Caps3, D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD); CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE); CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_BLENDOP); CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_MASKZ); CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_ALWAYS); CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_LESS); CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ZERO); CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ONE); CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_SRCALPHA); CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_DESTALPHA); CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVSRCALPHA); CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA); CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ZERO); CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ONE); CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_SRCALPHA); CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_DESTALPHA); CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA); CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVDESTALPHA); CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP); CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP); CHECK_CAP(d3dCaps.TextureOpCaps, D3DTEXOPCAPS_MODULATE); if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(2,0) && !IsD3DForced()) { J2dRlsTraceLn1(J2D_TRACE_ERROR, "D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\ "(pixel shaders 2.0 required)", adapter); return E_FAIL; } J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DPPLM::CheckDeviceCaps: adapter %d: Passed", adapter); return S_OK; }