Win32SurfaceKHR: use StretchDIBits to replace StrectchBlt. Use StretchDIBits to copy pixels in PresentImage to the output window directly. It avoids allocating extra memory and one pixel copy to DIBSection. Bug: chromium:1280715 Change-Id: I87e019ef0b33ad86d548a5549ab1ff5b87f9d130 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/62828 Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com> Commit-Queue: Peng Huang <penghuang@chromium.org> Tested-by: Peng Huang <penghuang@chromium.org>
diff --git a/src/WSI/Win32SurfaceKHR.cpp b/src/WSI/Win32SurfaceKHR.cpp index cf495c8..6c5a728 100644 --- a/src/WSI/Win32SurfaceKHR.cpp +++ b/src/WSI/Win32SurfaceKHR.cpp
@@ -43,15 +43,11 @@ { ASSERT(IsWindow(hwnd) == TRUE); windowContext = GetDC(hwnd); - bitmapContext = CreateCompatibleDC(windowContext); - lazyCreateFrameBuffer(); } void Win32SurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator) { - destroyFrameBuffer(); ReleaseDC(hwnd, windowContext); - DeleteDC(bitmapContext); } size_t Win32SurfaceKHR::ComputeRequiredAllocationSize(const VkWin32SurfaceCreateInfoKHR *pCreateInfo) @@ -85,87 +81,35 @@ VkResult Win32SurfaceKHR::present(PresentImage *image) { - // Recreate frame buffer in case window size has changed - VkResult result = lazyCreateFrameBuffer(); + VkExtent2D windowExtent = {}; + VkResult result = getWindowSize(hwnd, windowExtent); if(result != VK_SUCCESS) { return result; } - if(!framebuffer) - { - // e.g. window width or height is 0 - return VK_SUCCESS; - } - - const VkExtent3D &extent = image->getImage()->getExtent(); - + const Image *vkImage = image->getImage(); + const VkExtent3D &extent = vkImage->getExtent(); if(windowExtent.width != extent.width || windowExtent.height != extent.height) { return VK_ERROR_OUT_OF_DATE_KHR; } - image->getImage()->copyTo(reinterpret_cast<uint8_t *>(framebuffer), bitmapRowPitch); - - StretchBlt(windowContext, 0, 0, extent.width, extent.height, bitmapContext, 0, 0, extent.width, extent.height, SRCCOPY); - - return VK_SUCCESS; -} - -VkResult Win32SurfaceKHR::lazyCreateFrameBuffer() -{ - VkExtent2D currWindowExtent; - VkResult result = getWindowSize(hwnd, currWindowExtent); - if(result != VK_SUCCESS) - { - destroyFrameBuffer(); - return result; - } - - if(currWindowExtent.width == windowExtent.width && currWindowExtent.height == windowExtent.height) - { - return VK_SUCCESS; - } - - windowExtent = currWindowExtent; - - if(framebuffer) - { - destroyFrameBuffer(); - } - - if(windowExtent.width == 0 || windowExtent.height == 0) - { - return VK_SUCCESS; - } + int stride = vkImage->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0); + int bytesPerPixel = static_cast<int>(vkImage->getFormat(VK_IMAGE_ASPECT_COLOR_BIT).bytes()); BITMAPINFO bitmapInfo = {}; bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO); - bitmapInfo.bmiHeader.biBitCount = 32; + bitmapInfo.bmiHeader.biBitCount = bytesPerPixel * 8; bitmapInfo.bmiHeader.biPlanes = 1; - bitmapInfo.bmiHeader.biHeight = -static_cast<LONG>(windowExtent.height); // Negative for top-down DIB, origin in upper-left corner - bitmapInfo.bmiHeader.biWidth = windowExtent.width; + bitmapInfo.bmiHeader.biHeight = -static_cast<LONG>(extent.height); // Negative for top-down DIB, origin in upper-left corner + bitmapInfo.bmiHeader.biWidth = stride / bytesPerPixel; bitmapInfo.bmiHeader.biCompression = BI_RGB; - bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &framebuffer, 0, 0); - ASSERT(bitmap != NULL); - SelectObject(bitmapContext, bitmap); - - BITMAP header; - int status = GetObject(bitmap, sizeof(BITMAP), &header); - ASSERT(status != 0); - bitmapRowPitch = static_cast<int>(header.bmWidthBytes); + void *bits = image->getImage()->getTexelPointer({ 0, 0, 0 }, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }); + StretchDIBits(windowContext, 0, 0, extent.width, extent.height, 0, 0, extent.width, extent.height, bits, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); return VK_SUCCESS; } -void Win32SurfaceKHR::destroyFrameBuffer() -{ - SelectObject(bitmapContext, NULL); - DeleteObject(bitmap); - bitmap = {}; - bitmapRowPitch = 0; - framebuffer = nullptr; -} - } // namespace vk \ No newline at end of file
diff --git a/src/WSI/Win32SurfaceKHR.hpp b/src/WSI/Win32SurfaceKHR.hpp index 254cbcb..7d859b6 100644 --- a/src/WSI/Win32SurfaceKHR.hpp +++ b/src/WSI/Win32SurfaceKHR.hpp
@@ -25,8 +25,6 @@ #include <Windows.h> #include <vulkan/vulkan_win32.h> -#include <map> - namespace vk { class Win32SurfaceKHR : public SurfaceKHR, public ObjectBase<Win32SurfaceKHR, VkSurfaceKHR> @@ -45,18 +43,10 @@ VkResult present(PresentImage *image) override; private: - VkResult lazyCreateFrameBuffer(); - void destroyFrameBuffer(); - const HWND hwnd; HDC windowContext = {}; HDC bitmapContext = {}; - VkExtent2D windowExtent = {}; - - HBITMAP bitmap = {}; - unsigned int bitmapRowPitch = 0; - void *framebuffer = nullptr; }; } // namespace vk