< prev index next >

src/java.desktop/windows/native/libawt/java2d/windows/GDIBlitLoops.cpp

Print this page

        

*** 40,49 **** --- 40,111 ---- RGBQUAD palette[256]; } colors; } BmiType; /* + * Some GDI functions functions will fail if they operate on memory which spans + * virtual allocations as used by modern garbage collectors (ie ZGC). + * So if the call to SetDIBitsToDevice fails, we will re-try it on malloced + * memory rather than the pinned Java heap memory. + * Once Microsoft fix the GDI bug, the small performance penalty of this retry + * will be gone. + */ + static void retryingSetDIBitsToDevice( + HDC hdc, + int xDest, + int yDest, + DWORD w, + DWORD h, + int xSrc, + int ySrc, + UINT StartScan, + UINT cLines, + const VOID *lpvBits, + BITMAPINFO *lpbmi, + UINT ColorUse) { + + #ifdef DEBUG_PERF + LARGE_INTEGER ts1, ts2; + QueryPerformanceCounter(&ts1); + #endif + + int ret = + SetDIBitsToDevice(hdc, xDest, yDest, w, h, + xSrc, ySrc, StartScan, cLines, lpvBits, + lpbmi, ColorUse); + + if (ret != 0 || h == 0) { + #ifdef DEBUG_PERF + QueryPerformanceCounter(&ts2); + printf("success time: %zd\n", (ts2.QuadPart-ts1.QuadPart)); + #endif + return; + } + + size_t size = lpbmi->bmiHeader.biSizeImage; + void* imageData = NULL; + try { + imageData = safe_Malloc(size); + } catch (std::bad_alloc&) { + } + if (imageData == NULL) { + return; + } + memcpy(imageData, lpvBits, size); // this is the most expensive part. + SetDIBitsToDevice(hdc, xDest, yDest, w, h, + xSrc, ySrc, StartScan, cLines, imageData, + lpbmi, ColorUse); + free(imageData); + + #ifdef DEBUG_PERF + QueryPerformanceCounter(&ts2); + printf("with retry time: %zd\n", (ts2.QuadPart-ts1.QuadPart)); + #endif + + }; + + /* * Class: sun_java2d_windows_GDIBlitLoops * Method: nativeBlit * Signature: (Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;IIIIIIZ)V */ JNIEXPORT void JNICALL
*** 125,135 **** // If scanlines are DWORD-aligned (scanStride is a multiple of 4), // then we can do the work much faster. This is due to a constraint // in the way DIBs are structured and parsed by GDI jboolean fastBlt = ((srcInfo.scanStride & 0x03) == 0); - bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = srcInfo.scanStride/srcInfo.pixelStride; // fastBlt copies whole image in one call; else copy line-by-line LONG dwHeight = srcInfo.bounds.y2 - srcInfo.bounds.y1; bmi.bmiHeader.biHeight = (fastBlt) ? -dwHeight : -1; --- 187,196 ----
*** 188,206 **** // from this GDI call, so make sure window still exists if (::IsWindowVisible(dstOps->window)) { // Could also call StretchDIBits. Testing showed slight // performance advantage of SetDIBits instead, so since we // have no need of scaling, might as well use SetDIBits. ! SetDIBitsToDevice(hDC, dstx, dsty, width, height, 0, 0, 0, height, rasBase, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); } } else { // Source scanlines not DWORD-aligned - copy each scanline individually for (int i = 0; i < height; i += 1) { if (::IsWindowVisible(dstOps->window)) { ! SetDIBitsToDevice(hDC, dstx, dsty+i, width, 1, 0, 0, 0, 1, rasBase, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); rasBase = (void*)((char*)rasBase + srcInfo.scanStride); } else { break; --- 249,267 ---- // from this GDI call, so make sure window still exists if (::IsWindowVisible(dstOps->window)) { // Could also call StretchDIBits. Testing showed slight // performance advantage of SetDIBits instead, so since we // have no need of scaling, might as well use SetDIBits. ! retryingSetDIBitsToDevice(hDC, dstx, dsty, width, height, 0, 0, 0, height, rasBase, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); } } else { // Source scanlines not DWORD-aligned - copy each scanline individually for (int i = 0; i < height; i += 1) { if (::IsWindowVisible(dstOps->window)) { ! retryingSetDIBitsToDevice(hDC, dstx, dsty+i, width, 1, 0, 0, 0, 1, rasBase, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); rasBase = (void*)((char*)rasBase + srcInfo.scanStride); } else { break;
< prev index next >