xref: /aosp_15_r20/external/swiftshader/src/WSI/Win32SurfaceKHR.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "Win32SurfaceKHR.hpp"
16 
17 #include "System/Debug.hpp"
18 #include "Vulkan/VkDeviceMemory.hpp"
19 
20 #include <string.h>
21 
22 namespace {
getWindowSize(HWND hwnd,VkExtent2D & windowSize)23 VkResult getWindowSize(HWND hwnd, VkExtent2D &windowSize)
24 {
25 	RECT clientRect = {};
26 	if(!IsWindow(hwnd) || !GetClientRect(hwnd, &clientRect))
27 	{
28 		windowSize = { 0, 0 };
29 		return VK_ERROR_SURFACE_LOST_KHR;
30 	}
31 
32 	windowSize = { static_cast<uint32_t>(clientRect.right - clientRect.left),
33 		           static_cast<uint32_t>(clientRect.bottom - clientRect.top) };
34 
35 	return VK_SUCCESS;
36 }
37 }  // namespace
38 
39 namespace vk {
40 
Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR * pCreateInfo,void * mem)41 Win32SurfaceKHR::Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem)
42     : hwnd(pCreateInfo->hwnd)
43 {
44 	ASSERT(IsWindow(hwnd) == TRUE);
45 	windowContext = GetDC(hwnd);
46 }
47 
destroySurface(const VkAllocationCallbacks * pAllocator)48 void Win32SurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
49 {
50 	ReleaseDC(hwnd, windowContext);
51 }
52 
ComputeRequiredAllocationSize(const VkWin32SurfaceCreateInfoKHR * pCreateInfo)53 size_t Win32SurfaceKHR::ComputeRequiredAllocationSize(const VkWin32SurfaceCreateInfoKHR *pCreateInfo)
54 {
55 	return 0;
56 }
57 
getSurfaceCapabilities(const void * pSurfaceInfoPNext,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities,void * pSurfaceCapabilitiesPNext) const58 VkResult Win32SurfaceKHR::getSurfaceCapabilities(const void *pSurfaceInfoPNext, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities, void *pSurfaceCapabilitiesPNext) const
59 {
60 	VkExtent2D extent;
61 	VkResult result = getWindowSize(hwnd, extent);
62 	pSurfaceCapabilities->currentExtent = extent;
63 	pSurfaceCapabilities->minImageExtent = extent;
64 	pSurfaceCapabilities->maxImageExtent = extent;
65 
66 	setCommonSurfaceCapabilities(pSurfaceInfoPNext, pSurfaceCapabilities, pSurfaceCapabilitiesPNext);
67 	return VK_SUCCESS;
68 }
69 
attachImage(PresentImage * image)70 void Win32SurfaceKHR::attachImage(PresentImage *image)
71 {
72 	// Nothing to do here, the current implementation based on GDI blits on
73 	// present instead of associating the image with the surface.
74 }
75 
detachImage(PresentImage * image)76 void Win32SurfaceKHR::detachImage(PresentImage *image)
77 {
78 	// Nothing to do here, the current implementation based on GDI blits on
79 	// present instead of associating the image with the surface.
80 }
81 
present(PresentImage * image)82 VkResult Win32SurfaceKHR::present(PresentImage *image)
83 {
84 	VkExtent2D windowExtent = {};
85 	VkResult result = getWindowSize(hwnd, windowExtent);
86 	if(result != VK_SUCCESS)
87 	{
88 		return result;
89 	}
90 
91 	const Image *vkImage = image->getImage();
92 	const VkExtent3D &extent = vkImage->getExtent();
93 	if(windowExtent.width != extent.width || windowExtent.height != extent.height)
94 	{
95 		return VK_ERROR_OUT_OF_DATE_KHR;
96 	}
97 
98 	int stride = vkImage->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
99 	int bytesPerPixel = static_cast<int>(vkImage->getFormat(VK_IMAGE_ASPECT_COLOR_BIT).bytes());
100 
101 	BITMAPINFO bitmapInfo = {};
102 	bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);
103 	bitmapInfo.bmiHeader.biBitCount = bytesPerPixel * 8;
104 	bitmapInfo.bmiHeader.biPlanes = 1;
105 	bitmapInfo.bmiHeader.biHeight = -static_cast<LONG>(extent.height);  // Negative for top-down DIB, origin in upper-left corner
106 	bitmapInfo.bmiHeader.biWidth = stride / bytesPerPixel;
107 	bitmapInfo.bmiHeader.biCompression = BI_RGB;
108 
109 	void *bits = image->getImage()->getTexelPointer({ 0, 0, 0 }, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 });
110 	StretchDIBits(windowContext, 0, 0, extent.width, extent.height, 0, 0, extent.width, extent.height, bits, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
111 
112 	return VK_SUCCESS;
113 }
114 
115 }  // namespace vk
116