xref: /aosp_15_r20/external/swiftshader/src/WSI/WaylandSurfaceKHR.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2020 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "WaylandSurfaceKHR.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include "libWaylandClient.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkDeviceMemory.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkImage.hpp"
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker #include <string.h>
22*03ce13f7SAndroid Build Coastguard Worker #include <sys/mman.h>
23*03ce13f7SAndroid Build Coastguard Worker #include <unistd.h>
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker namespace vk {
26*03ce13f7SAndroid Build Coastguard Worker 
isSupported()27*03ce13f7SAndroid Build Coastguard Worker bool WaylandSurfaceKHR::isSupported()
28*03ce13f7SAndroid Build Coastguard Worker {
29*03ce13f7SAndroid Build Coastguard Worker 	return libWaylandClient.isPresent();
30*03ce13f7SAndroid Build Coastguard Worker }
31*03ce13f7SAndroid Build Coastguard Worker 
wl_registry_handle_global(void * data,struct wl_registry * registry,unsigned int name,const char * interface,unsigned int version)32*03ce13f7SAndroid Build Coastguard Worker static void wl_registry_handle_global(void *data, struct wl_registry *registry, unsigned int name, const char *interface, unsigned int version)
33*03ce13f7SAndroid Build Coastguard Worker {
34*03ce13f7SAndroid Build Coastguard Worker 	struct wl_shm **pshm = (struct wl_shm **)data;
35*03ce13f7SAndroid Build Coastguard Worker 	if(!strcmp(interface, "wl_shm"))
36*03ce13f7SAndroid Build Coastguard Worker 	{
37*03ce13f7SAndroid Build Coastguard Worker 		*pshm = static_cast<struct wl_shm *>(libWaylandClient->wl_registry_bind(registry, name, libWaylandClient->wl_shm_interface, 1));
38*03ce13f7SAndroid Build Coastguard Worker 	}
39*03ce13f7SAndroid Build Coastguard Worker }
40*03ce13f7SAndroid Build Coastguard Worker 
wl_registry_handle_global_remove(void * data,struct wl_registry * registry,unsigned int name)41*03ce13f7SAndroid Build Coastguard Worker static void wl_registry_handle_global_remove(void *data, struct wl_registry *registry, unsigned int name)
42*03ce13f7SAndroid Build Coastguard Worker {
43*03ce13f7SAndroid Build Coastguard Worker }
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker static const struct wl_registry_listener wl_registry_listener = { wl_registry_handle_global, wl_registry_handle_global_remove };
46*03ce13f7SAndroid Build Coastguard Worker 
WaylandSurfaceKHR(const VkWaylandSurfaceCreateInfoKHR * pCreateInfo,void * mem)47*03ce13f7SAndroid Build Coastguard Worker WaylandSurfaceKHR::WaylandSurfaceKHR(const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, void *mem)
48*03ce13f7SAndroid Build Coastguard Worker     : display(pCreateInfo->display)
49*03ce13f7SAndroid Build Coastguard Worker     , surface(pCreateInfo->surface)
50*03ce13f7SAndroid Build Coastguard Worker {
51*03ce13f7SAndroid Build Coastguard Worker 	struct wl_registry *registry = libWaylandClient->wl_display_get_registry(display);
52*03ce13f7SAndroid Build Coastguard Worker 	libWaylandClient->wl_registry_add_listener(registry, &wl_registry_listener, &shm);
53*03ce13f7SAndroid Build Coastguard Worker 	libWaylandClient->wl_display_dispatch(display);
54*03ce13f7SAndroid Build Coastguard Worker }
55*03ce13f7SAndroid Build Coastguard Worker 
destroySurface(const VkAllocationCallbacks * pAllocator)56*03ce13f7SAndroid Build Coastguard Worker void WaylandSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
57*03ce13f7SAndroid Build Coastguard Worker {
58*03ce13f7SAndroid Build Coastguard Worker }
59*03ce13f7SAndroid Build Coastguard Worker 
ComputeRequiredAllocationSize(const VkWaylandSurfaceCreateInfoKHR * pCreateInfo)60*03ce13f7SAndroid Build Coastguard Worker size_t WaylandSurfaceKHR::ComputeRequiredAllocationSize(const VkWaylandSurfaceCreateInfoKHR *pCreateInfo)
61*03ce13f7SAndroid Build Coastguard Worker {
62*03ce13f7SAndroid Build Coastguard Worker 	return 0;
63*03ce13f7SAndroid Build Coastguard Worker }
64*03ce13f7SAndroid Build Coastguard Worker 
getSurfaceCapabilities(const void * pSurfaceInfoPNext,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities,void * pSurfaceCapabilitiesPNext) const65*03ce13f7SAndroid Build Coastguard Worker VkResult WaylandSurfaceKHR::getSurfaceCapabilities(const void *pSurfaceInfoPNext, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities, void *pSurfaceCapabilitiesPNext) const
66*03ce13f7SAndroid Build Coastguard Worker {
67*03ce13f7SAndroid Build Coastguard Worker 	pSurfaceCapabilities->currentExtent = { 0xFFFFFFFF, 0xFFFFFFFF };
68*03ce13f7SAndroid Build Coastguard Worker 	pSurfaceCapabilities->minImageExtent = { 1, 1 };
69*03ce13f7SAndroid Build Coastguard Worker 	pSurfaceCapabilities->maxImageExtent = { 0xFFFFFFFF, 0xFFFFFFFF };
70*03ce13f7SAndroid Build Coastguard Worker 
71*03ce13f7SAndroid Build Coastguard Worker 	setCommonSurfaceCapabilities(pSurfaceInfoPNext, pSurfaceCapabilities, pSurfaceCapabilitiesPNext);
72*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
73*03ce13f7SAndroid Build Coastguard Worker }
74*03ce13f7SAndroid Build Coastguard Worker 
attachImage(PresentImage * image)75*03ce13f7SAndroid Build Coastguard Worker void WaylandSurfaceKHR::attachImage(PresentImage *image)
76*03ce13f7SAndroid Build Coastguard Worker {
77*03ce13f7SAndroid Build Coastguard Worker 	WaylandImage *wlImage = new WaylandImage;
78*03ce13f7SAndroid Build Coastguard Worker 	char path[] = "/tmp/XXXXXX";
79*03ce13f7SAndroid Build Coastguard Worker 	int fd = mkstemp(path);
80*03ce13f7SAndroid Build Coastguard Worker 	const VkExtent3D &extent = image->getImage()->getExtent();
81*03ce13f7SAndroid Build Coastguard Worker 	int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
82*03ce13f7SAndroid Build Coastguard Worker 	assert(ftruncate(fd, extent.height * stride) == 0);
83*03ce13f7SAndroid Build Coastguard Worker 	struct wl_shm_pool *pool = libWaylandClient->wl_shm_create_pool(shm, fd, extent.height * stride);
84*03ce13f7SAndroid Build Coastguard Worker 	wlImage->buffer = libWaylandClient->wl_shm_pool_create_buffer(pool, 0, extent.width, extent.height, stride, WL_SHM_FORMAT_XRGB8888);
85*03ce13f7SAndroid Build Coastguard Worker 	wlImage->data = static_cast<uint8_t *>(mmap(NULL, extent.height * stride, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
86*03ce13f7SAndroid Build Coastguard Worker 	libWaylandClient->wl_shm_pool_destroy(pool);
87*03ce13f7SAndroid Build Coastguard Worker 	close(fd);
88*03ce13f7SAndroid Build Coastguard Worker 	imageMap[image] = wlImage;
89*03ce13f7SAndroid Build Coastguard Worker }
90*03ce13f7SAndroid Build Coastguard Worker 
detachImage(PresentImage * image)91*03ce13f7SAndroid Build Coastguard Worker void WaylandSurfaceKHR::detachImage(PresentImage *image)
92*03ce13f7SAndroid Build Coastguard Worker {
93*03ce13f7SAndroid Build Coastguard Worker 	auto it = imageMap.find(image);
94*03ce13f7SAndroid Build Coastguard Worker 	if(it != imageMap.end())
95*03ce13f7SAndroid Build Coastguard Worker 	{
96*03ce13f7SAndroid Build Coastguard Worker 		WaylandImage *wlImage = it->second;
97*03ce13f7SAndroid Build Coastguard Worker 		const VkExtent3D &extent = image->getImage()->getExtent();
98*03ce13f7SAndroid Build Coastguard Worker 		int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
99*03ce13f7SAndroid Build Coastguard Worker 		munmap(wlImage->data, extent.height * stride);
100*03ce13f7SAndroid Build Coastguard Worker 		libWaylandClient->wl_buffer_destroy(wlImage->buffer);
101*03ce13f7SAndroid Build Coastguard Worker 		delete wlImage;
102*03ce13f7SAndroid Build Coastguard Worker 		imageMap.erase(it);
103*03ce13f7SAndroid Build Coastguard Worker 	}
104*03ce13f7SAndroid Build Coastguard Worker }
105*03ce13f7SAndroid Build Coastguard Worker 
present(PresentImage * image)106*03ce13f7SAndroid Build Coastguard Worker VkResult WaylandSurfaceKHR::present(PresentImage *image)
107*03ce13f7SAndroid Build Coastguard Worker {
108*03ce13f7SAndroid Build Coastguard Worker 	auto it = imageMap.find(image);
109*03ce13f7SAndroid Build Coastguard Worker 	if(it != imageMap.end())
110*03ce13f7SAndroid Build Coastguard Worker 	{
111*03ce13f7SAndroid Build Coastguard Worker 		WaylandImage *wlImage = it->second;
112*03ce13f7SAndroid Build Coastguard Worker 		const VkExtent3D &extent = image->getImage()->getExtent();
113*03ce13f7SAndroid Build Coastguard Worker 		int bufferRowPitch = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
114*03ce13f7SAndroid Build Coastguard Worker 		image->getImage()->copyTo(reinterpret_cast<uint8_t *>(wlImage->data), bufferRowPitch);
115*03ce13f7SAndroid Build Coastguard Worker 		libWaylandClient->wl_surface_attach(surface, wlImage->buffer, 0, 0);
116*03ce13f7SAndroid Build Coastguard Worker 		libWaylandClient->wl_surface_damage(surface, 0, 0, extent.width, extent.height);
117*03ce13f7SAndroid Build Coastguard Worker 		libWaylandClient->wl_surface_commit(surface);
118*03ce13f7SAndroid Build Coastguard Worker 		libWaylandClient->wl_display_roundtrip(display);
119*03ce13f7SAndroid Build Coastguard Worker 		libWaylandClient->wl_display_sync(display);
120*03ce13f7SAndroid Build Coastguard Worker 	}
121*03ce13f7SAndroid Build Coastguard Worker 
122*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
123*03ce13f7SAndroid Build Coastguard Worker }
124*03ce13f7SAndroid Build Coastguard Worker 
125*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
126