diff -r 85b4d3bded64 -r 8725ccb1a22d jdk/src/windows/native/sun/java2d/d3d/D3DRuntimeTest.cpp --- a/jdk/src/windows/native/sun/java2d/d3d/D3DRuntimeTest.cpp Fri Aug 08 08:52:18 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,537 +0,0 @@ -/* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -#include "dxInit.h" -#include "ddrawUtils.h" -#include "RegistryKey.h" -#include "D3DTestRaster.h" -#include "WindowsFlags.h" -#include "D3DRuntimeTest.h" -#include "D3DSurfaceData.h" -#include "D3DUtils.h" - -#ifdef DEBUG -void TestRasterOutput(byte *rasPtr, int x, int y, int w, int h, - int scanStride, int pixelStride, - TIntTestRaster goldenArray = NULL); -#endif // DEBUG -void PrintD3DCaps(int caps); - -/** - * Test whether we should enable d3d rendering on this device. - * This includes checking whether there were problems creating - * the necessary offscreen surface, problems during any of the - * rendering calls (Blts and d3d lines) and any rendering artifacts - * caused by d3d lines. The rendering artifact tests are - * performed by checking a pre-rendered test pattern (produced - * by our software renderer) against that same pattern rendered - * on this device. If there are any pixels which differ between - * the two patterns we disable d3d line rendering on the device. - * Differences in the test pattern rendering can be caused - * by different rendering algorithms used by our software - * renderer and the driver or hardware on this device. For example, - * some Intel cards (e.g., i815) are known to use polygon renderers - * for their lines, which sometimes result in wide lines. - * The test pattern is stored in d3dTestRaster.h, which is generated - * by a Java test program - * (src/share/test/java2d/VolatileImage/D3DTestPattern/D3DTestPattern.java). - */ - -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; -} - -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; -} - -int TestSetClip(JNIEnv *env, D3DContext *d3dContext, - DDrawSurface *lpPlainSurface) -{ - int testRes = J2D_D3D_FAILURE; - - if (SUCCEEDED(d3dContext->SetRenderTarget(lpPlainSurface))) { - jobject clip = - JNU_CallStaticMethodByName(env, NULL, - "sun/java2d/pipe/Region", - "getInstanceXYWH", - "(IIII)Lsun/java2d/pipe/Region;", - 0, 0, D3D_TEST_RASTER_W, D3D_TEST_RASTER_H).l; - if (!JNU_IsNull(env, clip)) { - if (SUCCEEDED(d3dContext->SetClip(env, clip, JNI_TRUE, - 0, 0, - D3D_TEST_RASTER_W, - D3D_TEST_RASTER_H))) - { - testRes |= J2D_D3D_DEPTH_SURFACE_OK; - } - env->DeleteLocalRef(clip); - } - } - return testRes; -} - -int TestRenderingResults(DDrawSurface *lpPlainSurface, - TIntTestRaster goldenArray) -{ - // Now, check the results of the test raster against our d3d drawing - SurfaceDataRasInfo rasInfo; - if (FAILED(lpPlainSurface->Lock(NULL, &rasInfo, DDLOCK_WAIT, NULL))) { - return J2D_D3D_FAILURE; - } - - byte *rasPtr = (byte*)rasInfo.rasBase; - int pixelStride = rasInfo.pixelStride; - int scanStride = rasInfo.scanStride; - for (int row = 0; row < D3D_TEST_RASTER_H; ++row) { - byte *tmpRasPtr = rasPtr + row * scanStride; - for (int col = 0; col < D3D_TEST_RASTER_W; ++col) { - DWORD pixelVal; - switch (pixelStride) { - case 1: - pixelVal = *tmpRasPtr; - break; - case 2: - pixelVal = *((unsigned short*)tmpRasPtr); - break; - default: - pixelVal = *((unsigned int*)tmpRasPtr); - break; - } - tmpRasPtr += pixelStride; - // The test is simple: if the test raster pixel has value 0, then - // we expect 0 in the d3d surface. If the test raster has a nonzero - // value, then we expect the d3d surface to also have non-zero value. - // All other results represent failure. - int goldenValue = (goldenArray[row][col] & 0x00ffffff); - if ((goldenValue == 0 && pixelVal != 0) || - (goldenValue != 0 && pixelVal == 0)) - { - J2dRlsTraceLn3(J2D_TRACE_WARNING, - "TestRenderingResults: Quality test failed due "\ - "to value %x at (%d, %d)", pixelVal, col, row); -#ifdef DEBUG - // This section is not necessary, but it might be - // nice to know why we are failing D3DTest on some - // systems. If tracing is enabled, this section will - // produce an ascii representation of the test pattern, - // the result on this device, and the pixels that were - // in error. - J2dTraceLn(J2D_TRACE_VERBOSE, "TestRaster:"); - TestRasterOutput((byte*)goldenArray, 0, 0, D3D_TEST_RASTER_W, - D3D_TEST_RASTER_H, D3D_TEST_RASTER_W*4, 4); - J2dTraceLn(J2D_TRACE_VERBOSE, "D3D Raster:"); - TestRasterOutput(rasPtr, 0, 0, D3D_TEST_RASTER_W, - D3D_TEST_RASTER_H, scanStride, pixelStride); - J2dTraceLn(J2D_TRACE_VERBOSE, "Deltas (x indicates problem pixel):"); - TestRasterOutput(rasPtr, 0, 0, D3D_TEST_RASTER_W, - D3D_TEST_RASTER_H, scanStride, pixelStride, - goldenArray); -#endif // DEBUG - lpPlainSurface->Unlock(NULL); - return J2D_D3D_FAILURE; - } - } - } - - lpPlainSurface->Unlock(NULL); - return (J2D_D3D_LINES_OK | J2D_D3D_LINE_CLIPPING_OK); -} - -int TestLineRenderingQuality(JNIEnv *env, D3DContext *d3dContext, - DDrawSurface *lpPlainSurface) -{ - static J2D_XY_C_VERTEX lineVerts[] = { -#ifdef USE_SINGLE_VERTEX_FORMAT - { 0, 0, 0, 0xffffffff, 0.0f, 0.0f }, - { 0, 0, 0, 0xffffffff, 0.0f, 0.0f }, - { 0, 0, 0, 0xffffffff, 0.0f, 0.0f }, - { 0, 0, 0, 0xffffffff, 0.0f, 0.0f }, - { 0, 0, 0, 0xffffffff, 0.0f, 0.0f }, -#else - { 0, 0, 0, 0xffffffff }, // x, y, z, color - { 0, 0, 0, 0xffffffff }, - { 0, 0, 0, 0xffffffff }, - { 0, 0, 0, 0xffffffff }, - { 0, 0, 0, 0xffffffff }, -#endif // USE_SINGLE_VERTEX_FORMAT - }; - IDirect3DDevice7 *d3dDevice = d3dContext->Get3DDevice(); - HRESULT res; - - d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0.0, 0); - - if (FAILED(d3dContext->BeginScene(STATE_RENDEROP))) { - return J2D_D3D_FAILURE; - } - - int i; - - for (i = 0; i < d3dNumTestLines * 4; i += 4) { - lineVerts[0].x = d3dTestLines[i + 0]; - lineVerts[0].y = d3dTestLines[i + 1]; - lineVerts[1].x = d3dTestLines[i + 2]; - lineVerts[1].y = d3dTestLines[i + 3]; - if (FAILED(res = d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, - D3DFVF_J2D_XY_C, - lineVerts, 2, 0))) - { - d3dContext->ForceEndScene(); - return J2D_D3D_FAILURE; - } - // REMIND: needed for the test to pass on ATI some boards - d3dDevice->DrawPrimitive(D3DPT_POINTLIST, D3DFVF_J2D_XY_C, - &(lineVerts[1]), 1, 0); - } - - for (i = 0; i < d3dNumTestRects * 4; i += 4) { - float x1 = d3dTestRects[i + 0]; - float y1 = d3dTestRects[i + 1]; - float x2 = d3dTestRects[i + 2]; - float y2 = d3dTestRects[i + 3]; - D3DU_INIT_VERTEX_PENT_XY(lineVerts, x1, y1, x2, y2); - if (FAILED(res = d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, - D3DFVF_J2D_XY_C, - lineVerts, 5, 0))) - { - d3dContext->ForceEndScene(); - return J2D_D3D_FAILURE; - } - } - d3dContext->ForceEndScene(); - - // REMIND: add rendering of clipped lines - - return TestRenderingResults(lpPlainSurface, d3dTestRaster); -} - -int TestTextureMappingQuality(JNIEnv *env, DDraw *ddObject, - D3DContext *d3dContext, - DDrawSurface *lpPlainSurface) -{ - static J2DLVERTEX quadVerts[4] = { - { 0.0f, 0.0f, 0.0f, 0xffffffff, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0xffffffff, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0xffffffff, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0xffffffff, 0.0f, 0.0f } - }; - - int testRes = TestTextureFormats(d3dContext); - - if (testRes & J2D_D3D_PIXEL_FORMATS_OK) { - - DDrawSurface *lpTexture = - D3DUtils_CreateTexture(env, ddObject, d3dContext, TR_TRANSLUCENT, - D3D_TEXTURE_RASTER_W, D3D_TEXTURE_RASTER_H); - if (lpTexture) { - D3DUtils_UploadIntImageToXRGBTexture(lpTexture, - (int *)srcImageArray, - D3D_TEXTURE_RASTER_W, - D3D_TEXTURE_RASTER_H); - - float u2 = ((float)D3D_TEXTURE_RASTER_W) / - (float)lpTexture->GetDXSurface()->GetWidth(); - float v2 = ((float)D3D_TEXTURE_RASTER_H) / - (float)lpTexture->GetDXSurface()->GetHeight(); - D3DU_INIT_VERTEX_QUAD_UV(quadVerts, 0.0f, 0.0f, u2, v2); - - IDirect3DDevice7 *d3dDevice = d3dContext->Get3DDevice(); - d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0); - - d3dContext->SetAlphaComposite(3/*SrcOver*/, - 1.0f, D3DC_NO_CONTEXT_FLAGS); - d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); - d3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFG_POINT); - - HRESULT res; - if (SUCCEEDED(res = d3dContext->BeginScene(STATE_BLITOP))) { - DXSurface *dxSurface = lpTexture->GetDXSurface(); - if (SUCCEEDED(d3dContext->SetTexture(dxSurface))) { - for (int i = 0; i < d3dNumTextureRects * 4; i += 4) { - float x1 = d3dTextureRects[i + 0]; - float y1 = d3dTextureRects[i + 1]; - float x2 = d3dTextureRects[i + 2]; - float y2 = d3dTextureRects[i + 3]; - D3DU_INIT_VERTEX_QUAD_XY(quadVerts, x1, y1, x2, y2); - d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - D3DFVF_J2DLVERTEX, - quadVerts, 4, 0); - } - } - res = d3dContext->ForceEndScene(); - d3dContext->SetTexture(NULL); - } - // REMIND: at this point we ignore the results of - // the test. - TestRenderingResults(lpPlainSurface, linInterpArray); - if (SUCCEEDED(res)) { - testRes |= (J2D_D3D_TR_TEXTURE_SURFACE_OK | - J2D_D3D_TEXTURE_BLIT_OK | - J2D_D3D_TEXTURE_TRANSFORM_OK); - - // REMIND: add tests for opaque and bitmask textures - testRes |= (J2D_D3D_OP_TEXTURE_SURFACE_OK | - J2D_D3D_BM_TEXTURE_SURFACE_OK); - } - delete lpTexture; - } else { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "TestTextureMappingQuality: "\ - "CreateTexture(TRANSLUCENT) FAILED"); - } - } - return testRes; -} - -int TestD3DDevice(DDraw *ddObject, - D3DContext *d3dContext, - DxCapabilities *dxCaps) -{ - int testRes = TestForBadHardware(dxCaps); - if (!(testRes & J2D_D3D_HW_OK) || !d3dContext) { - return testRes; - } - - D3DDEVICEDESC7 d3dDevDesc; - IDirect3DDevice7 *d3dDevice = d3dContext->Get3DDevice(); - if (d3dDevice == NULL || - FAILED(d3dDevice->GetCaps(&d3dDevDesc)) || - FAILED(D3DUtils_CheckDeviceCaps(&d3dDevDesc))) - { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "TestD3DDevice: device caps testing FAILED"); - return testRes; - } - testRes |= J2D_D3D_DEVICE_OK; - - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - DDrawSurface *lpPlainSurface = - D3DUtils_CreatePlainSurface(env, ddObject, d3dContext, - D3D_TEST_RASTER_W, D3D_TEST_RASTER_H); - if (!lpPlainSurface) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "TestD3DDevice: CreatePlainSurface FAILED"); - return testRes; - } - testRes |= J2D_D3D_PLAIN_SURFACE_OK; - - // Set identity transform - if (FAILED(d3dContext->SetTransform(NULL, 0, 0, 0, 0, 0, 0))) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "TestD3DDevice: SetTransform FAILED"); - delete lpPlainSurface; - return testRes; - } - testRes |= J2D_D3D_SET_TRANSFORM_OK; - - // Test setting the target surface, create depth buffer, and - // clip - testRes |= TestSetClip(env, d3dContext, lpPlainSurface); - if (!(testRes & J2D_D3D_DEPTH_SURFACE_OK)) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "TestD3DDevice: SetClip FAILED"); - delete lpPlainSurface; - return testRes; - } - - // Test drawLines - testRes |= TestLineRenderingQuality(env, d3dContext, lpPlainSurface); - - // Test texture mapping - testRes |= TestTextureMappingQuality(env, ddObject, d3dContext, - lpPlainSurface); - - d3dContext->SetRenderTarget(NULL); - - delete lpPlainSurface; - return testRes; -} - -#ifdef DEBUG -/** - * Output test raster (produced in D3DTest function). Utility - * used in debugging only. Enable by setting J2D_TRACE_LEVEL=J2D_VERBOSE - * prior to running application with debug java. The output from this will - * be seen only if D3DTest fails. - */ -void TestRasterOutput(byte *rasPtr, int x, int y, int w, int h, - int scanStride, int pixelStride, - TIntTestRaster goldenArray) -{ - int goldenValue; - for (int traceRow = y; traceRow < h; ++traceRow) { - byte *tmpRasPtr = rasPtr + traceRow * scanStride; - for (int traceCol = x; traceCol < w; ++traceCol) { - DWORD pixelVal; - switch (pixelStride) { - case 1: - pixelVal = *tmpRasPtr; - break; - case 2: - pixelVal = *((unsigned short*)tmpRasPtr); - break; - default: - pixelVal = *((unsigned int*)tmpRasPtr) & 0x00ffffff; - break; - } - tmpRasPtr += pixelStride; - if (goldenArray == NULL) { - if (pixelVal) { - J2dTrace(J2D_TRACE_VERBOSE, "1"); - } else { - J2dTrace(J2D_TRACE_VERBOSE, "0"); - } - } else { - goldenValue = (goldenArray[traceRow][traceCol] & 0x00ffffff); - if ((goldenValue == 0 && pixelVal != 0) || - (goldenValue != 0 && pixelVal == 0)) - { - J2dTrace(J2D_TRACE_VERBOSE, "x"); - } else { - J2dTrace(J2D_TRACE_VERBOSE, "-"); - } - } - - } - J2dTrace(J2D_TRACE_VERBOSE, "\n"); - } -} -#endif // DEBUG - -void PrintD3DCaps(int caps) -{ - J2dTraceLn(J2D_TRACE_VERBOSE, "{") - if (caps == J2D_D3D_FAILURE) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_FAILURE"); - } else { - if (caps & J2D_D3D_DEPTH_SURFACE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_DEPTH_SURFACE_OK,"); - } - if (caps & J2D_D3D_PLAIN_SURFACE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_PLAIN_SURFACE_OK,"); - } - if (caps & J2D_D3D_OP_TEXTURE_SURFACE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_OP_TEXTURE_SURFACE_OK,"); - } - if (caps & J2D_D3D_BM_TEXTURE_SURFACE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_BM_TEXTURE_SURFACE_OK,"); - } - if (caps & J2D_D3D_TR_TEXTURE_SURFACE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_TR_TEXTURE_SURFACE_OK,"); - } - if (caps & J2D_D3D_OP_RTT_SURFACE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_OP_RTT_SURFACE_OK,"); - } - if (caps & J2D_D3D_LINE_CLIPPING_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_LINE_CLIPPING_OK,"); - } - if (caps & J2D_D3D_LINES_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_LINES_OK,"); - } - if (caps & J2D_D3D_TEXTURE_BLIT_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_TEXTURE_BLIT_OK,"); - } - if (caps & J2D_D3D_TEXTURE_TRANSFORM_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_TEXTURE_TRANSFORM_OK,"); - } - if (caps & J2D_D3D_DEVICE_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_DEVICE_OK,"); - } - if (caps & J2D_D3D_PIXEL_FORMATS_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_SET_TRANSFORM_OK,"); - } - if (caps & J2D_D3D_HW_OK) { - J2dTraceLn(J2D_TRACE_VERBOSE, " J2D_D3D_HW_OK,"); - } - } - J2dTraceLn(J2D_TRACE_VERBOSE, "}"); -}