From f0afd5897be81f8ccf1641a5ffa210df8eacc825 Mon Sep 17 00:00:00 2001 From: "Andon M. Coleman" Date: Mon, 26 Aug 2024 03:27:31 -0400 Subject: [PATCH] Further optimize clipboard access --- src/SKIV.cpp | 12 ++- src/utility/image.cpp | 207 ++++++++++++++++++++++------------------ src/utility/utility.cpp | 14 ++- 3 files changed, 136 insertions(+), 97 deletions(-) diff --git a/src/SKIV.cpp b/src/SKIV.cpp index e62d78d..28685a5 100644 --- a/src/SKIV.cpp +++ b/src/SKIV.cpp @@ -3061,7 +3061,17 @@ wWinMain ( _In_ HINSTANCE hInstance, // duplicate the same processing we're already doing in viewer.cpp if (hotkeyCtrlV && ! ImGui::IsAnyItemActive ( )) // && ! ImGui::IsAnyItemFocused ( ) { - if (OpenClipboard (SKIF_ImGui_hWnd)) + bool clipboard_open = false; + + for (UINT i = 0 ; i < 5 ; ++i) + { + clipboard_open = OpenClipboard (SKIF_ImGui_hWnd); + + if (! clipboard_open) + Sleep (2); + } + + if (clipboard_open) { ClipboardData cbd = ClipboardData_None; diff --git a/src/utility/image.cpp b/src/utility/image.cpp index 22834b7..8c29c0e 100644 --- a/src/utility/image.cpp +++ b/src/utility/image.cpp @@ -1017,32 +1017,43 @@ SKIV_PNG_CopyToClipboard (const DirectX::Image& image, const void *pData, size_t std::ignore = image; std::ignore = data_size; // It's a string, we can compute the size trivially - if (OpenClipboard (SKIF_ImGui_hWnd)) - { - int clpSize = sizeof (DROPFILES); + int clpSize = sizeof (DROPFILES); + + clpSize += sizeof (wchar_t) * static_cast (wcslen ((wchar_t *)pData) + 1); + clpSize += sizeof (wchar_t); + + HDROP hdrop = + (HDROP)GlobalAlloc (GHND, clpSize); - clpSize += sizeof (wchar_t) * static_cast (wcslen ((wchar_t *)pData) + 1); - clpSize += sizeof (wchar_t); + DROPFILES* df = + (DROPFILES *)GlobalLock (hdrop); - HDROP hdrop = - (HDROP)GlobalAlloc (GHND, clpSize); + df->pFiles = sizeof (DROPFILES); + df->fWide = TRUE; - DROPFILES* df = - (DROPFILES *)GlobalLock (hdrop); + wcscpy ((wchar_t*)&df [1], (const wchar_t *)pData); - df->pFiles = sizeof (DROPFILES); - df->fWide = TRUE; + bool clipboard_open = false; + for (UINT i = 0 ; i < 5 ; ++i) + { + clipboard_open = OpenClipboard (SKIF_ImGui_hWnd); - wcscpy ((wchar_t*)&df [1], (const wchar_t *)pData); + if (! clipboard_open) + Sleep (2); + } - GlobalUnlock (hdrop); + if (clipboard_open) + { EmptyClipboard (); SetClipboardData (CF_HDROP, hdrop); CloseClipboard (); + GlobalUnlock (hdrop); return true; } + GlobalUnlock (hdrop); + return false; } @@ -1132,99 +1143,107 @@ using namespace DirectX; PLOG_INFO << "SKIV_Image_TonemapToSDR ( ): FAILED!"; } - if (OpenClipboard (SKIF_ImGui_hWnd)) + const int + _bpc = + (int)(DirectX::BitsPerPixel (pImage->format)), + _width = + (int)( pImage->width), + _height = + (int)( pImage->height); + + DirectX::ScratchImage swizzled_sdr; + // Swizzle the image and handle gamma if necessary + if (pImage->format != DXGI_FORMAT_B8G8R8X8_UNORM_SRGB) { - const int - _bpc = - (int)(DirectX::BitsPerPixel (pImage->format)), - _width = - (int)( pImage->width), - _height = - (int)( pImage->height); - - DirectX::ScratchImage swizzled_sdr; - // Swizzle the image and handle gamma if necessary - if (pImage->format != DXGI_FORMAT_B8G8R8X8_UNORM_SRGB) + if (SUCCEEDED (DirectX::Convert (*pImage, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DirectX::TEX_FILTER_DEFAULT, 0.0f, swizzled_sdr))) { - if (SUCCEEDED (DirectX::Convert (*pImage, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DirectX::TEX_FILTER_DEFAULT, 0.0f, swizzled_sdr))) - { - pImage = swizzled_sdr.GetImage (0,0,0); - } + pImage = swizzled_sdr.GetImage (0,0,0); } - ////SK_ReleaseAssert (pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM || - //// pImage->format == DXGI_FORMAT_B8G8R8A8_UNORM || - //// pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); - - HBITMAP hBitmapCopy = - CreateBitmap ( - _width, _height, 1, - _bpc, pImage->pixels - ); - - BITMAPINFOHEADER - bmh = { }; - bmh.biSize = sizeof (BITMAPINFOHEADER); - bmh.biWidth = _width; - bmh.biHeight = -_height; - bmh.biPlanes = 1; - bmh.biBitCount = (WORD)_bpc; - bmh.biCompression = BI_RGB; - bmh.biXPelsPerMeter = 10; - bmh.biYPelsPerMeter = 10; - - BITMAPINFO - bmi = { }; - bmi.bmiHeader = bmh; - - HDC hdcDIB = - CreateCompatibleDC (GetDC (nullptr)); - - void* bitplane = nullptr; - - HBITMAP - hBitmap = - CreateDIBSection ( hdcDIB, &bmi, DIB_RGB_COLORS, - &bitplane, nullptr, 0 ); - memcpy ( bitplane, - pImage->pixels, - static_cast (_bpc / 8) * - static_cast (_width ) * - static_cast (_height ) - ); - - HDC hdcSrc = CreateCompatibleDC (GetDC (nullptr)); - HDC hdcDst = CreateCompatibleDC (GetDC (nullptr)); - - if ( hBitmap != nullptr && - hBitmapCopy != nullptr ) - { - auto hbmpSrc = (HBITMAP)SelectObject (hdcSrc, hBitmap); - auto hbmpDst = (HBITMAP)SelectObject (hdcDst, hBitmapCopy); + } + ////SK_ReleaseAssert (pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM || + //// pImage->format == DXGI_FORMAT_B8G8R8A8_UNORM || + //// pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); + + HBITMAP hBitmapCopy = + CreateBitmap ( + _width, _height, 1, + _bpc, pImage->pixels + ); + + BITMAPINFOHEADER + bmh = { }; + bmh.biSize = sizeof (BITMAPINFOHEADER); + bmh.biWidth = _width; + bmh.biHeight = -_height; + bmh.biPlanes = 1; + bmh.biBitCount = (WORD)_bpc; + bmh.biCompression = BI_RGB; + bmh.biXPelsPerMeter = 10; + bmh.biYPelsPerMeter = 10; + + BITMAPINFO + bmi = { }; + bmi.bmiHeader = bmh; + + HDC hdcDIB = + CreateCompatibleDC (GetDC (nullptr)); + + void* bitplane = nullptr; + + HBITMAP + hBitmap = + CreateDIBSection ( hdcDIB, &bmi, DIB_RGB_COLORS, + &bitplane, nullptr, 0 ); + memcpy ( bitplane, + pImage->pixels, + static_cast (_bpc / 8) * + static_cast (_width ) * + static_cast (_height ) + ); + + HDC hdcSrc = CreateCompatibleDC (GetDC (nullptr)); + HDC hdcDst = CreateCompatibleDC (GetDC (nullptr)); + + if ( hBitmap != nullptr && + hBitmapCopy != nullptr ) + { + auto hbmpSrc = (HBITMAP)SelectObject (hdcSrc, hBitmap); + auto hbmpDst = (HBITMAP)SelectObject (hdcDst, hBitmapCopy); - BitBlt (hdcDst, 0, 0, _width, - _height, hdcSrc, 0, 0, SRCCOPY); + BitBlt (hdcDst, 0, 0, _width, + _height, hdcSrc, 0, 0, SRCCOPY); - SelectObject (hdcSrc, hbmpSrc); - SelectObject (hdcDst, hbmpDst); + SelectObject (hdcSrc, hbmpSrc); + SelectObject (hdcDst, hbmpDst); + bool clipboard_open = false; + for (UINT i = 0 ; i < 5 ; ++i) + { + clipboard_open = OpenClipboard (SKIF_ImGui_hWnd); + + if (! clipboard_open) + Sleep (2); + } + + if (clipboard_open) + { EmptyClipboard (); SetClipboardData (CF_BITMAP, hBitmapCopy); + CloseClipboard (); } + } - CloseClipboard (); - - DeleteDC (hdcSrc); - DeleteDC (hdcDst); - DeleteDC (hdcDIB); + DeleteDC (hdcSrc); + DeleteDC (hdcDst); + DeleteDC (hdcDIB); - if ( hBitmap != nullptr && - hBitmapCopy != nullptr ) - { - DeleteBitmap (hBitmap); - DeleteBitmap (hBitmapCopy); + if ( hBitmap != nullptr && + hBitmapCopy != nullptr ) + { + DeleteBitmap (hBitmap); + DeleteBitmap (hBitmapCopy); - return true; - } + return true; } } diff --git a/src/utility/utility.cpp b/src/utility/utility.cpp index 87397ec..3cdae4d 100644 --- a/src/utility/utility.cpp +++ b/src/utility/utility.cpp @@ -2336,7 +2336,17 @@ SKIF_Util_SetClipboardData (const std::wstring_view& data) { bool result = false; - if (OpenClipboard (SKIF_ImGui_hWnd)) + bool clipboard_open = false; + + for (UINT i = 0 ; i < 5 ; ++i) + { + clipboard_open = OpenClipboard (SKIF_ImGui_hWnd); + + if (! clipboard_open) + Sleep (2); + } + + if (clipboard_open) { HGLOBAL hGlobal = GlobalAlloc (GMEM_MOVEABLE, (data.size() + 1) * sizeof (wchar_t)); @@ -2347,10 +2357,10 @@ SKIF_Util_SetClipboardData (const std::wstring_view& data) if (pszDestination != nullptr) { memcpy (pszDestination, data.data(), (data.length() + 1) * sizeof (wchar_t)); - GlobalUnlock (hGlobal); EmptyClipboard ( ); result = SetClipboardData (CF_UNICODETEXT, hGlobal); + GlobalUnlock (hGlobal); } if (! result)