blob: e990cf4fc5effeb7934b68307e01ac0702a94d87 [file] [log] [blame]
Jesse Hallb1352bc2015-09-04 16:12:33 -07001/*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jesse Halld7b994a2015-09-07 14:17:37 -070017#include <algorithm>
Jesse Halld7b994a2015-09-07 14:17:37 -070018
19#include <gui/BufferQueue.h>
Jesse Hallb1352bc2015-09-04 16:12:33 -070020#include <log/log.h>
Jesse Halld7b994a2015-09-07 14:17:37 -070021#include <sync/sync.h>
Chia-I Wue8e689f2016-04-18 08:21:31 +080022#include <utils/StrongPointer.h>
Jesse Halld7b994a2015-09-07 14:17:37 -070023
Chia-I Wu4a6a9162016-03-26 07:17:34 +080024#include "driver.h"
Jesse Halld7b994a2015-09-07 14:17:37 -070025
Jesse Hall5ae3abb2015-10-08 14:00:22 -070026// TODO(jessehall): Currently we don't have a good error code for when a native
27// window operation fails. Just returning INITIALIZATION_FAILED for now. Later
28// versions (post SDK 0.9) of the API/extension have a better error code.
29// When updating to that version, audit all error returns.
Chia-I Wu62262232016-03-26 07:06:44 +080030namespace vulkan {
31namespace driver {
Jesse Hall5ae3abb2015-10-08 14:00:22 -070032
Jesse Halld7b994a2015-09-07 14:17:37 -070033namespace {
34
Jesse Hall55bc0972016-02-23 16:43:29 -080035const VkSurfaceTransformFlagsKHR kSupportedTransforms =
36 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR |
37 VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
38 VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR |
39 VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
40 // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform.
41 // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR |
42 // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR |
43 // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR |
44 // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR |
45 VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
46
47VkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransform(int native) {
48 // Native and Vulkan transforms are isomorphic, but are represented
49 // differently. Vulkan transforms are built up of an optional horizontal
50 // mirror, followed by a clockwise 0/90/180/270-degree rotation. Native
51 // transforms are built up from a horizontal flip, vertical flip, and
52 // 90-degree rotation, all optional but always in that order.
53
54 // TODO(jessehall): For now, only support pure rotations, not
55 // flip or flip-and-rotate, until I have more time to test them and build
56 // sample code. As far as I know we never actually use anything besides
57 // pure rotations anyway.
58
59 switch (native) {
60 case 0: // 0x0
61 return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
62 // case NATIVE_WINDOW_TRANSFORM_FLIP_H: // 0x1
63 // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR;
64 // case NATIVE_WINDOW_TRANSFORM_FLIP_V: // 0x2
65 // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR;
66 case NATIVE_WINDOW_TRANSFORM_ROT_180: // FLIP_H | FLIP_V
67 return VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR;
68 case NATIVE_WINDOW_TRANSFORM_ROT_90: // 0x4
69 return VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR;
70 // case NATIVE_WINDOW_TRANSFORM_FLIP_H | NATIVE_WINDOW_TRANSFORM_ROT_90:
71 // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR;
72 // case NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_ROT_90:
73 // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR;
74 case NATIVE_WINDOW_TRANSFORM_ROT_270: // FLIP_H | FLIP_V | ROT_90
75 return VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR;
76 case NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY:
77 default:
78 return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
79 }
80}
81
Jesse Hall178b6962016-02-24 15:39:50 -080082int InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform) {
83 switch (transform) {
84 case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
85 return NATIVE_WINDOW_TRANSFORM_ROT_270;
86 case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
87 return NATIVE_WINDOW_TRANSFORM_ROT_180;
88 case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
89 return NATIVE_WINDOW_TRANSFORM_ROT_90;
90 // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform.
91 // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
92 // return NATIVE_WINDOW_TRANSFORM_FLIP_H;
93 // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
94 // return NATIVE_WINDOW_TRANSFORM_FLIP_H |
95 // NATIVE_WINDOW_TRANSFORM_ROT_90;
96 // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
97 // return NATIVE_WINDOW_TRANSFORM_FLIP_V;
98 // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
99 // return NATIVE_WINDOW_TRANSFORM_FLIP_V |
100 // NATIVE_WINDOW_TRANSFORM_ROT_90;
101 case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
102 case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
103 default:
104 return 0;
105 }
106}
107
Jesse Halld7b994a2015-09-07 14:17:37 -0700108// ----------------------------------------------------------------------------
109
Jesse Hall1356b0d2015-11-23 17:24:58 -0800110struct Surface {
Chia-I Wue8e689f2016-04-18 08:21:31 +0800111 android::sp<ANativeWindow> window;
Jesse Hall1356b0d2015-11-23 17:24:58 -0800112};
113
114VkSurfaceKHR HandleFromSurface(Surface* surface) {
115 return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
116}
117
118Surface* SurfaceFromHandle(VkSurfaceKHR handle) {
Jesse Halla3a7a1d2015-11-24 11:37:23 -0800119 return reinterpret_cast<Surface*>(handle);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800120}
121
122struct Swapchain {
123 Swapchain(Surface& surface_, uint32_t num_images_)
124 : surface(surface_), num_images(num_images_) {}
125
126 Surface& surface;
Jesse Halld7b994a2015-09-07 14:17:37 -0700127 uint32_t num_images;
128
129 struct Image {
130 Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {}
131 VkImage image;
Chia-I Wue8e689f2016-04-18 08:21:31 +0800132 android::sp<ANativeWindowBuffer> buffer;
Jesse Halld7b994a2015-09-07 14:17:37 -0700133 // The fence is only valid when the buffer is dequeued, and should be
134 // -1 any other time. When valid, we own the fd, and must ensure it is
135 // closed: either by closing it explicitly when queueing the buffer,
136 // or by passing ownership e.g. to ANativeWindow::cancelBuffer().
137 int dequeue_fence;
138 bool dequeued;
139 } images[android::BufferQueue::NUM_BUFFER_SLOTS];
140};
141
142VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain) {
143 return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain));
144}
145
146Swapchain* SwapchainFromHandle(VkSwapchainKHR handle) {
Jesse Halla3a7a1d2015-11-24 11:37:23 -0800147 return reinterpret_cast<Swapchain*>(handle);
Jesse Halld7b994a2015-09-07 14:17:37 -0700148}
149
150} // anonymous namespace
Jesse Hallb1352bc2015-09-04 16:12:33 -0700151
Jesse Halle1b12782015-11-30 11:27:32 -0800152VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800153VkResult CreateAndroidSurfaceKHR(
Jesse Hallf9fa9a52016-01-08 16:08:51 -0800154 VkInstance instance,
155 const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
156 const VkAllocationCallbacks* allocator,
157 VkSurfaceKHR* out_surface) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800158 if (!allocator)
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800159 allocator = &GetData(instance).allocator;
Jesse Hall1f91d392015-12-11 16:28:44 -0800160 void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface),
161 alignof(Surface),
162 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800163 if (!mem)
164 return VK_ERROR_OUT_OF_HOST_MEMORY;
165 Surface* surface = new (mem) Surface;
Jesse Hallb1352bc2015-09-04 16:12:33 -0700166
Chia-I Wue8e689f2016-04-18 08:21:31 +0800167 surface->window = pCreateInfo->window;
Jesse Hallb1352bc2015-09-04 16:12:33 -0700168
Jesse Hall1356b0d2015-11-23 17:24:58 -0800169 // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN.
170 int err =
171 native_window_api_connect(surface->window.get(), NATIVE_WINDOW_API_EGL);
172 if (err != 0) {
173 // TODO(jessehall): Improve error reporting. Can we enumerate possible
174 // errors and translate them to valid Vulkan result codes?
175 ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err),
176 err);
177 surface->~Surface();
Jesse Hall1f91d392015-12-11 16:28:44 -0800178 allocator->pfnFree(allocator->pUserData, surface);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800179 return VK_ERROR_INITIALIZATION_FAILED;
180 }
Jesse Hallb1352bc2015-09-04 16:12:33 -0700181
Jesse Hall1356b0d2015-11-23 17:24:58 -0800182 *out_surface = HandleFromSurface(surface);
Jesse Hallb1352bc2015-09-04 16:12:33 -0700183 return VK_SUCCESS;
184}
185
Jesse Halle1b12782015-11-30 11:27:32 -0800186VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800187void DestroySurfaceKHR(VkInstance instance,
188 VkSurfaceKHR surface_handle,
189 const VkAllocationCallbacks* allocator) {
Jesse Hall1356b0d2015-11-23 17:24:58 -0800190 Surface* surface = SurfaceFromHandle(surface_handle);
191 if (!surface)
192 return;
193 native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL);
194 surface->~Surface();
Jesse Hall1f91d392015-12-11 16:28:44 -0800195 if (!allocator)
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800196 allocator = &GetData(instance).allocator;
Jesse Hall1f91d392015-12-11 16:28:44 -0800197 allocator->pfnFree(allocator->pUserData, surface);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800198}
199
Jesse Halle1b12782015-11-30 11:27:32 -0800200VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800201VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
202 uint32_t /*queue_family*/,
203 VkSurfaceKHR /*surface*/,
204 VkBool32* supported) {
Jesse Hall0e74f002015-11-30 11:37:59 -0800205 *supported = VK_TRUE;
Jesse Halla6429252015-11-29 18:59:42 -0800206 return VK_SUCCESS;
Jesse Hall1356b0d2015-11-23 17:24:58 -0800207}
208
Jesse Halle1b12782015-11-30 11:27:32 -0800209VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800210VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(
Jesse Hallb00daad2015-11-29 19:46:20 -0800211 VkPhysicalDevice /*pdev*/,
212 VkSurfaceKHR surface,
213 VkSurfaceCapabilitiesKHR* capabilities) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700214 int err;
Jesse Hall1356b0d2015-11-23 17:24:58 -0800215 ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
Jesse Halld7b994a2015-09-07 14:17:37 -0700216
217 int width, height;
218 err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
219 if (err != 0) {
220 ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
221 strerror(-err), err);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700222 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700223 }
224 err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
225 if (err != 0) {
226 ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
227 strerror(-err), err);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700228 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700229 }
230
Jesse Hall55bc0972016-02-23 16:43:29 -0800231 int transform_hint;
232 err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT, &transform_hint);
233 if (err != 0) {
234 ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)",
235 strerror(-err), err);
236 return VK_ERROR_INITIALIZATION_FAILED;
237 }
238
Jesse Halld7b994a2015-09-07 14:17:37 -0700239 // TODO(jessehall): Figure out what the min/max values should be.
Jesse Hallb00daad2015-11-29 19:46:20 -0800240 capabilities->minImageCount = 2;
241 capabilities->maxImageCount = 3;
Jesse Halld7b994a2015-09-07 14:17:37 -0700242
Jesse Hallfe2662d2016-02-09 13:26:59 -0800243 capabilities->currentExtent =
244 VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
245
Jesse Halld7b994a2015-09-07 14:17:37 -0700246 // TODO(jessehall): Figure out what the max extent should be. Maximum
247 // texture dimension maybe?
Jesse Hallb00daad2015-11-29 19:46:20 -0800248 capabilities->minImageExtent = VkExtent2D{1, 1};
249 capabilities->maxImageExtent = VkExtent2D{4096, 4096};
Jesse Halld7b994a2015-09-07 14:17:37 -0700250
Jesse Hallfe2662d2016-02-09 13:26:59 -0800251 capabilities->maxImageArrayLayers = 1;
252
Jesse Hall55bc0972016-02-23 16:43:29 -0800253 capabilities->supportedTransforms = kSupportedTransforms;
254 capabilities->currentTransform =
255 TranslateNativeToVulkanTransform(transform_hint);
Jesse Halld7b994a2015-09-07 14:17:37 -0700256
Jesse Hallfe2662d2016-02-09 13:26:59 -0800257 // On Android, window composition is a WindowManager property, not something
258 // associated with the bufferqueue. It can't be changed from here.
259 capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
Jesse Halld7b994a2015-09-07 14:17:37 -0700260
261 // TODO(jessehall): I think these are right, but haven't thought hard about
262 // it. Do we need to query the driver for support of any of these?
263 // Currently not included:
264 // - VK_IMAGE_USAGE_GENERAL: maybe? does this imply cpu mappable?
265 // - VK_IMAGE_USAGE_DEPTH_STENCIL_BIT: definitely not
266 // - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT: definitely not
Jesse Hallb00daad2015-11-29 19:46:20 -0800267 capabilities->supportedUsageFlags =
Jesse Hall3fbc8562015-11-29 22:10:52 -0800268 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
269 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
270 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
Jesse Halld7b994a2015-09-07 14:17:37 -0700271 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
272
Jesse Hallb1352bc2015-09-04 16:12:33 -0700273 return VK_SUCCESS;
274}
275
Jesse Halle1b12782015-11-30 11:27:32 -0800276VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800277VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice /*pdev*/,
278 VkSurfaceKHR /*surface*/,
279 uint32_t* count,
280 VkSurfaceFormatKHR* formats) {
Jesse Hall1356b0d2015-11-23 17:24:58 -0800281 // TODO(jessehall): Fill out the set of supported formats. Longer term, add
282 // a new gralloc method to query whether a (format, usage) pair is
283 // supported, and check that for each gralloc format that corresponds to a
284 // Vulkan format. Shorter term, just add a few more formats to the ones
285 // hardcoded below.
Jesse Halld7b994a2015-09-07 14:17:37 -0700286
287 const VkSurfaceFormatKHR kFormats[] = {
288 {VK_FORMAT_R8G8B8A8_UNORM, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
289 {VK_FORMAT_R8G8B8A8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
Jesse Hall517274a2016-02-10 00:07:18 -0800290 {VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
Jesse Halld7b994a2015-09-07 14:17:37 -0700291 };
292 const uint32_t kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
293
294 VkResult result = VK_SUCCESS;
295 if (formats) {
296 if (*count < kNumFormats)
297 result = VK_INCOMPLETE;
298 std::copy(kFormats, kFormats + std::min(*count, kNumFormats), formats);
299 }
300 *count = kNumFormats;
301 return result;
Jesse Hallb1352bc2015-09-04 16:12:33 -0700302}
303
Jesse Halle1b12782015-11-30 11:27:32 -0800304VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800305VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice /*pdev*/,
306 VkSurfaceKHR /*surface*/,
307 uint32_t* count,
308 VkPresentModeKHR* modes) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700309 const VkPresentModeKHR kModes[] = {
310 VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
311 };
312 const uint32_t kNumModes = sizeof(kModes) / sizeof(kModes[0]);
313
314 VkResult result = VK_SUCCESS;
315 if (modes) {
316 if (*count < kNumModes)
317 result = VK_INCOMPLETE;
318 std::copy(kModes, kModes + std::min(*count, kNumModes), modes);
319 }
320 *count = kNumModes;
321 return result;
Jesse Hallb1352bc2015-09-04 16:12:33 -0700322}
323
Jesse Halle1b12782015-11-30 11:27:32 -0800324VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800325VkResult CreateSwapchainKHR(VkDevice device,
326 const VkSwapchainCreateInfoKHR* create_info,
327 const VkAllocationCallbacks* allocator,
328 VkSwapchainKHR* swapchain_handle) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700329 int err;
330 VkResult result = VK_SUCCESS;
331
Jesse Hall1f91d392015-12-11 16:28:44 -0800332 if (!allocator)
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800333 allocator = &GetData(device).allocator;
Jesse Hall1f91d392015-12-11 16:28:44 -0800334
Jesse Hall715b86a2016-01-16 16:34:29 -0800335 ALOGV_IF(create_info->imageArrayLayers != 1,
336 "Swapchain imageArrayLayers (%u) != 1 not supported",
337 create_info->imageArrayLayers);
Jesse Halld7b994a2015-09-07 14:17:37 -0700338
Jesse Halld7b994a2015-09-07 14:17:37 -0700339 ALOGE_IF(create_info->imageColorSpace != VK_COLORSPACE_SRGB_NONLINEAR_KHR,
340 "color spaces other than SRGB_NONLINEAR not yet implemented");
341 ALOGE_IF(create_info->oldSwapchain,
342 "swapchain re-creation not yet implemented");
Jesse Hall55bc0972016-02-23 16:43:29 -0800343 ALOGE_IF((create_info->preTransform & ~kSupportedTransforms) != 0,
344 "swapchain preTransform %d not supported",
345 create_info->preTransform);
Jesse Hall0ae0dce2016-02-09 22:13:34 -0800346 ALOGW_IF(!(create_info->presentMode == VK_PRESENT_MODE_FIFO_KHR ||
347 create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR),
348 "swapchain present mode %d not supported",
349 create_info->presentMode);
Jesse Halld7b994a2015-09-07 14:17:37 -0700350
351 // -- Configure the native window --
Jesse Halld7b994a2015-09-07 14:17:37 -0700352
Jesse Hall1356b0d2015-11-23 17:24:58 -0800353 Surface& surface = *SurfaceFromHandle(create_info->surface);
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800354 const auto& dispatch = GetData(device).driver;
Jesse Hall70f93352015-11-04 09:41:31 -0800355
Jesse Hall517274a2016-02-10 00:07:18 -0800356 int native_format = HAL_PIXEL_FORMAT_RGBA_8888;
357 switch (create_info->imageFormat) {
358 case VK_FORMAT_R8G8B8A8_UNORM:
359 case VK_FORMAT_R8G8B8A8_SRGB:
360 native_format = HAL_PIXEL_FORMAT_RGBA_8888;
361 break;
362 case VK_FORMAT_R5G6B5_UNORM_PACK16:
363 native_format = HAL_PIXEL_FORMAT_RGB_565;
364 break;
365 default:
366 ALOGE("unsupported swapchain format %d", create_info->imageFormat);
367 break;
368 }
369 err = native_window_set_buffers_format(surface.window.get(), native_format);
370 if (err != 0) {
371 // TODO(jessehall): Improve error reporting. Can we enumerate possible
372 // errors and translate them to valid Vulkan result codes?
373 ALOGE("native_window_set_buffers_format(%d) failed: %s (%d)",
374 native_format, strerror(-err), err);
375 return VK_ERROR_INITIALIZATION_FAILED;
376 }
377 err = native_window_set_buffers_data_space(surface.window.get(),
378 HAL_DATASPACE_SRGB_LINEAR);
379 if (err != 0) {
380 // TODO(jessehall): Improve error reporting. Can we enumerate possible
381 // errors and translate them to valid Vulkan result codes?
382 ALOGE("native_window_set_buffers_data_space(%d) failed: %s (%d)",
383 HAL_DATASPACE_SRGB_LINEAR, strerror(-err), err);
384 return VK_ERROR_INITIALIZATION_FAILED;
385 }
386
Jesse Hall3dd678a2016-01-08 21:52:01 -0800387 err = native_window_set_buffers_dimensions(
388 surface.window.get(), static_cast<int>(create_info->imageExtent.width),
389 static_cast<int>(create_info->imageExtent.height));
Jesse Halld7b994a2015-09-07 14:17:37 -0700390 if (err != 0) {
391 // TODO(jessehall): Improve error reporting. Can we enumerate possible
392 // errors and translate them to valid Vulkan result codes?
393 ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
394 create_info->imageExtent.width, create_info->imageExtent.height,
395 strerror(-err), err);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700396 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700397 }
398
Jesse Hall178b6962016-02-24 15:39:50 -0800399 // VkSwapchainCreateInfo::preTransform indicates the transformation the app
400 // applied during rendering. native_window_set_transform() expects the
401 // inverse: the transform the app is requesting that the compositor perform
402 // during composition. With native windows, pre-transform works by rendering
403 // with the same transform the compositor is applying (as in Vulkan), but
404 // then requesting the inverse transform, so that when the compositor does
405 // it's job the two transforms cancel each other out and the compositor ends
406 // up applying an identity transform to the app's buffer.
407 err = native_window_set_buffers_transform(
408 surface.window.get(),
409 InvertTransformToNative(create_info->preTransform));
410 if (err != 0) {
411 // TODO(jessehall): Improve error reporting. Can we enumerate possible
412 // errors and translate them to valid Vulkan result codes?
413 ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
414 InvertTransformToNative(create_info->preTransform),
415 strerror(-err), err);
416 return VK_ERROR_INITIALIZATION_FAILED;
417 }
418
Jesse Hallf64ca122015-11-03 16:11:10 -0800419 err = native_window_set_scaling_mode(
Jesse Hall1356b0d2015-11-23 17:24:58 -0800420 surface.window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
Jesse Hallf64ca122015-11-03 16:11:10 -0800421 if (err != 0) {
422 // TODO(jessehall): Improve error reporting. Can we enumerate possible
423 // errors and translate them to valid Vulkan result codes?
424 ALOGE("native_window_set_scaling_mode(SCALE_TO_WINDOW) failed: %s (%d)",
425 strerror(-err), err);
Jesse Hallf64ca122015-11-03 16:11:10 -0800426 return VK_ERROR_INITIALIZATION_FAILED;
427 }
428
Jesse Halle6080bf2016-02-28 20:58:50 -0800429 int query_value;
430 err = surface.window->query(surface.window.get(),
431 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
432 &query_value);
433 if (err != 0 || query_value < 0) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700434 // TODO(jessehall): Improve error reporting. Can we enumerate possible
435 // errors and translate them to valid Vulkan result codes?
Jesse Halle6080bf2016-02-28 20:58:50 -0800436 ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
437 query_value);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700438 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700439 }
Jesse Halle6080bf2016-02-28 20:58:50 -0800440 uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
Jesse Hall0ae0dce2016-02-09 22:13:34 -0800441 // The MIN_UNDEQUEUED_BUFFERS query doesn't know whether we'll be using
442 // async mode or not, and assumes not. But in async mode, the BufferQueue
443 // requires an extra undequeued buffer.
444 // See BufferQueueCore::getMinUndequeuedBufferCountLocked().
445 if (create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR)
446 min_undequeued_buffers += 1;
447
Jesse Halld7b994a2015-09-07 14:17:37 -0700448 uint32_t num_images =
449 (create_info->minImageCount - 1) + min_undequeued_buffers;
Jesse Hall1356b0d2015-11-23 17:24:58 -0800450 err = native_window_set_buffer_count(surface.window.get(), num_images);
Jesse Halld7b994a2015-09-07 14:17:37 -0700451 if (err != 0) {
452 // TODO(jessehall): Improve error reporting. Can we enumerate possible
453 // errors and translate them to valid Vulkan result codes?
454 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
455 err);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700456 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700457 }
458
Jesse Hall70f93352015-11-04 09:41:31 -0800459 int gralloc_usage = 0;
460 // TODO(jessehall): Remove conditional once all drivers have been updated
Jesse Hall1f91d392015-12-11 16:28:44 -0800461 if (dispatch.GetSwapchainGrallocUsageANDROID) {
462 result = dispatch.GetSwapchainGrallocUsageANDROID(
Jesse Hallf4ab2b12015-11-30 16:04:55 -0800463 device, create_info->imageFormat, create_info->imageUsage,
Jesse Hall70f93352015-11-04 09:41:31 -0800464 &gralloc_usage);
465 if (result != VK_SUCCESS) {
466 ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
Jesse Hall70f93352015-11-04 09:41:31 -0800467 return VK_ERROR_INITIALIZATION_FAILED;
468 }
469 } else {
470 gralloc_usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
471 }
Jesse Hall1356b0d2015-11-23 17:24:58 -0800472 err = native_window_set_usage(surface.window.get(), gralloc_usage);
Jesse Hall70f93352015-11-04 09:41:31 -0800473 if (err != 0) {
474 // TODO(jessehall): Improve error reporting. Can we enumerate possible
475 // errors and translate them to valid Vulkan result codes?
476 ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err);
Jesse Hall70f93352015-11-04 09:41:31 -0800477 return VK_ERROR_INITIALIZATION_FAILED;
478 }
Jesse Halld7b994a2015-09-07 14:17:37 -0700479
Jesse Hall0ae0dce2016-02-09 22:13:34 -0800480 err = surface.window->setSwapInterval(
481 surface.window.get(),
482 create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ? 0 : 1);
483 if (err != 0) {
484 // TODO(jessehall): Improve error reporting. Can we enumerate possible
485 // errors and translate them to valid Vulkan result codes?
486 ALOGE("native_window->setSwapInterval failed: %s (%d)", strerror(-err),
487 err);
488 return VK_ERROR_INITIALIZATION_FAILED;
489 }
490
Jesse Halld7b994a2015-09-07 14:17:37 -0700491 // -- Allocate our Swapchain object --
492 // After this point, we must deallocate the swapchain on error.
493
Jesse Hall1f91d392015-12-11 16:28:44 -0800494 void* mem = allocator->pfnAllocation(allocator->pUserData,
495 sizeof(Swapchain), alignof(Swapchain),
496 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800497 if (!mem)
Jesse Halld7b994a2015-09-07 14:17:37 -0700498 return VK_ERROR_OUT_OF_HOST_MEMORY;
Jesse Hall1356b0d2015-11-23 17:24:58 -0800499 Swapchain* swapchain = new (mem) Swapchain(surface, num_images);
Jesse Halld7b994a2015-09-07 14:17:37 -0700500
501 // -- Dequeue all buffers and create a VkImage for each --
502 // Any failures during or after this must cancel the dequeued buffers.
503
504 VkNativeBufferANDROID image_native_buffer = {
Jesse Halld7b994a2015-09-07 14:17:37 -0700505#pragma clang diagnostic push
506#pragma clang diagnostic ignored "-Wold-style-cast"
507 .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
508#pragma clang diagnostic pop
509 .pNext = nullptr,
510 };
511 VkImageCreateInfo image_create = {
512 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
513 .pNext = &image_native_buffer,
514 .imageType = VK_IMAGE_TYPE_2D,
Jesse Hall517274a2016-02-10 00:07:18 -0800515 .format = create_info->imageFormat,
Jesse Halld7b994a2015-09-07 14:17:37 -0700516 .extent = {0, 0, 1},
517 .mipLevels = 1,
Jesse Halla15a4bf2015-11-19 22:48:02 -0800518 .arrayLayers = 1,
Jesse Hall091ed9e2015-11-30 00:55:29 -0800519 .samples = VK_SAMPLE_COUNT_1_BIT,
Jesse Halld7b994a2015-09-07 14:17:37 -0700520 .tiling = VK_IMAGE_TILING_OPTIMAL,
Jesse Hallf4ab2b12015-11-30 16:04:55 -0800521 .usage = create_info->imageUsage,
Jesse Halld7b994a2015-09-07 14:17:37 -0700522 .flags = 0,
Jesse Hallf4ab2b12015-11-30 16:04:55 -0800523 .sharingMode = create_info->imageSharingMode,
Jesse Hall03b6fe12015-11-24 12:44:21 -0800524 .queueFamilyIndexCount = create_info->queueFamilyIndexCount,
Jesse Halld7b994a2015-09-07 14:17:37 -0700525 .pQueueFamilyIndices = create_info->pQueueFamilyIndices,
526 };
527
Jesse Halld7b994a2015-09-07 14:17:37 -0700528 for (uint32_t i = 0; i < num_images; i++) {
529 Swapchain::Image& img = swapchain->images[i];
530
531 ANativeWindowBuffer* buffer;
Jesse Hall1356b0d2015-11-23 17:24:58 -0800532 err = surface.window->dequeueBuffer(surface.window.get(), &buffer,
533 &img.dequeue_fence);
Jesse Halld7b994a2015-09-07 14:17:37 -0700534 if (err != 0) {
535 // TODO(jessehall): Improve error reporting. Can we enumerate
536 // possible errors and translate them to valid Vulkan result codes?
537 ALOGE("dequeueBuffer[%u] failed: %s (%d)", i, strerror(-err), err);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700538 result = VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700539 break;
540 }
Chia-I Wue8e689f2016-04-18 08:21:31 +0800541 img.buffer = buffer;
Jesse Halld7b994a2015-09-07 14:17:37 -0700542 img.dequeued = true;
543
544 image_create.extent =
Jesse Hall3dd678a2016-01-08 21:52:01 -0800545 VkExtent3D{static_cast<uint32_t>(img.buffer->width),
546 static_cast<uint32_t>(img.buffer->height),
547 1};
Jesse Halld7b994a2015-09-07 14:17:37 -0700548 image_native_buffer.handle = img.buffer->handle;
549 image_native_buffer.stride = img.buffer->stride;
550 image_native_buffer.format = img.buffer->format;
551 image_native_buffer.usage = img.buffer->usage;
552
Jesse Hall03b6fe12015-11-24 12:44:21 -0800553 result =
Jesse Hall1f91d392015-12-11 16:28:44 -0800554 dispatch.CreateImage(device, &image_create, nullptr, &img.image);
Jesse Halld7b994a2015-09-07 14:17:37 -0700555 if (result != VK_SUCCESS) {
556 ALOGD("vkCreateImage w/ native buffer failed: %u", result);
557 break;
558 }
559 }
560
561 // -- Cancel all buffers, returning them to the queue --
562 // If an error occurred before, also destroy the VkImage and release the
563 // buffer reference. Otherwise, we retain a strong reference to the buffer.
564 //
565 // TODO(jessehall): The error path here is the same as DestroySwapchain,
566 // but not the non-error path. Should refactor/unify.
567 for (uint32_t i = 0; i < num_images; i++) {
568 Swapchain::Image& img = swapchain->images[i];
569 if (img.dequeued) {
Jesse Hall1356b0d2015-11-23 17:24:58 -0800570 surface.window->cancelBuffer(surface.window.get(), img.buffer.get(),
571 img.dequeue_fence);
Jesse Halld7b994a2015-09-07 14:17:37 -0700572 img.dequeue_fence = -1;
573 img.dequeued = false;
574 }
575 if (result != VK_SUCCESS) {
576 if (img.image)
Jesse Hall1f91d392015-12-11 16:28:44 -0800577 dispatch.DestroyImage(device, img.image, nullptr);
Jesse Halld7b994a2015-09-07 14:17:37 -0700578 }
579 }
580
581 if (result != VK_SUCCESS) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700582 swapchain->~Swapchain();
Jesse Hall1f91d392015-12-11 16:28:44 -0800583 allocator->pfnFree(allocator->pUserData, swapchain);
Jesse Halld7b994a2015-09-07 14:17:37 -0700584 return result;
585 }
586
587 *swapchain_handle = HandleFromSwapchain(swapchain);
Jesse Hallb1352bc2015-09-04 16:12:33 -0700588 return VK_SUCCESS;
589}
590
Jesse Halle1b12782015-11-30 11:27:32 -0800591VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800592void DestroySwapchainKHR(VkDevice device,
593 VkSwapchainKHR swapchain_handle,
594 const VkAllocationCallbacks* allocator) {
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800595 const auto& dispatch = GetData(device).driver;
Jesse Halld7b994a2015-09-07 14:17:37 -0700596 Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
Chia-I Wue8e689f2016-04-18 08:21:31 +0800597 const android::sp<ANativeWindow>& window = swapchain->surface.window;
Jesse Halld7b994a2015-09-07 14:17:37 -0700598
599 for (uint32_t i = 0; i < swapchain->num_images; i++) {
600 Swapchain::Image& img = swapchain->images[i];
601 if (img.dequeued) {
602 window->cancelBuffer(window.get(), img.buffer.get(),
603 img.dequeue_fence);
604 img.dequeue_fence = -1;
605 img.dequeued = false;
606 }
607 if (img.image) {
Jesse Hall1f91d392015-12-11 16:28:44 -0800608 dispatch.DestroyImage(device, img.image, nullptr);
Jesse Halld7b994a2015-09-07 14:17:37 -0700609 }
610 }
611
Jesse Hall1f91d392015-12-11 16:28:44 -0800612 if (!allocator)
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800613 allocator = &GetData(device).allocator;
Jesse Halld7b994a2015-09-07 14:17:37 -0700614 swapchain->~Swapchain();
Jesse Hall1f91d392015-12-11 16:28:44 -0800615 allocator->pfnFree(allocator->pUserData, swapchain);
Jesse Hallb1352bc2015-09-04 16:12:33 -0700616}
617
Jesse Halle1b12782015-11-30 11:27:32 -0800618VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800619VkResult GetSwapchainImagesKHR(VkDevice,
620 VkSwapchainKHR swapchain_handle,
621 uint32_t* count,
622 VkImage* images) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700623 Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
624 VkResult result = VK_SUCCESS;
625 if (images) {
626 uint32_t n = swapchain.num_images;
627 if (*count < swapchain.num_images) {
628 n = *count;
629 result = VK_INCOMPLETE;
630 }
631 for (uint32_t i = 0; i < n; i++)
632 images[i] = swapchain.images[i].image;
633 }
634 *count = swapchain.num_images;
635 return result;
Jesse Hallb1352bc2015-09-04 16:12:33 -0700636}
637
Jesse Halle1b12782015-11-30 11:27:32 -0800638VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800639VkResult AcquireNextImageKHR(VkDevice device,
640 VkSwapchainKHR swapchain_handle,
641 uint64_t timeout,
642 VkSemaphore semaphore,
643 VkFence vk_fence,
644 uint32_t* image_index) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700645 Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800646 ANativeWindow* window = swapchain.surface.window.get();
Jesse Halld7b994a2015-09-07 14:17:37 -0700647 VkResult result;
648 int err;
649
650 ALOGW_IF(
651 timeout != UINT64_MAX,
652 "vkAcquireNextImageKHR: non-infinite timeouts not yet implemented");
653
654 ANativeWindowBuffer* buffer;
Jesse Hall06193802015-12-03 16:12:51 -0800655 int fence_fd;
656 err = window->dequeueBuffer(window, &buffer, &fence_fd);
Jesse Halld7b994a2015-09-07 14:17:37 -0700657 if (err != 0) {
658 // TODO(jessehall): Improve error reporting. Can we enumerate possible
659 // errors and translate them to valid Vulkan result codes?
660 ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700661 return VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700662 }
663
664 uint32_t idx;
665 for (idx = 0; idx < swapchain.num_images; idx++) {
666 if (swapchain.images[idx].buffer.get() == buffer) {
667 swapchain.images[idx].dequeued = true;
Jesse Hall06193802015-12-03 16:12:51 -0800668 swapchain.images[idx].dequeue_fence = fence_fd;
Jesse Halld7b994a2015-09-07 14:17:37 -0700669 break;
670 }
671 }
672 if (idx == swapchain.num_images) {
673 ALOGE("dequeueBuffer returned unrecognized buffer");
Jesse Hall06193802015-12-03 16:12:51 -0800674 window->cancelBuffer(window, buffer, fence_fd);
Jesse Halld7b994a2015-09-07 14:17:37 -0700675 return VK_ERROR_OUT_OF_DATE_KHR;
Jesse Halld7b994a2015-09-07 14:17:37 -0700676 }
677
678 int fence_clone = -1;
Jesse Hall06193802015-12-03 16:12:51 -0800679 if (fence_fd != -1) {
680 fence_clone = dup(fence_fd);
Jesse Halld7b994a2015-09-07 14:17:37 -0700681 if (fence_clone == -1) {
682 ALOGE("dup(fence) failed, stalling until signalled: %s (%d)",
683 strerror(errno), errno);
Jesse Hall06193802015-12-03 16:12:51 -0800684 sync_wait(fence_fd, -1 /* forever */);
Jesse Halld7b994a2015-09-07 14:17:37 -0700685 }
686 }
687
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800688 result = GetData(device).driver.AcquireImageANDROID(
Jesse Hall1f91d392015-12-11 16:28:44 -0800689 device, swapchain.images[idx].image, fence_clone, semaphore, vk_fence);
Jesse Halld7b994a2015-09-07 14:17:37 -0700690 if (result != VK_SUCCESS) {
Jesse Hallab9aeef2015-11-04 10:56:20 -0800691 // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
692 // even if the call fails. We could close it ourselves on failure, but
693 // that would create a race condition if the driver closes it on a
694 // failure path: some other thread might create an fd with the same
695 // number between the time the driver closes it and the time we close
696 // it. We must assume one of: the driver *always* closes it even on
697 // failure, or *never* closes it on failure.
Jesse Hall06193802015-12-03 16:12:51 -0800698 window->cancelBuffer(window, buffer, fence_fd);
Jesse Halld7b994a2015-09-07 14:17:37 -0700699 swapchain.images[idx].dequeued = false;
700 swapchain.images[idx].dequeue_fence = -1;
701 return result;
702 }
703
704 *image_index = idx;
Jesse Hallb1352bc2015-09-04 16:12:33 -0700705 return VK_SUCCESS;
706}
707
Jesse Halle1b12782015-11-30 11:27:32 -0800708VKAPI_ATTR
Chia-I Wu62262232016-03-26 07:06:44 +0800709VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
Jesse Halld7b994a2015-09-07 14:17:37 -0700710 ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
711 "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d",
712 present_info->sType);
Jesse Halld7b994a2015-09-07 14:17:37 -0700713 ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL");
714
Chia-I Wu4a6a9162016-03-26 07:17:34 +0800715 const auto& dispatch = GetData(queue).driver;
Jesse Halld7b994a2015-09-07 14:17:37 -0700716 VkResult final_result = VK_SUCCESS;
717 for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) {
718 Swapchain& swapchain =
Jesse Hall03b6fe12015-11-24 12:44:21 -0800719 *SwapchainFromHandle(present_info->pSwapchains[sc]);
Jesse Hall1356b0d2015-11-23 17:24:58 -0800720 ANativeWindow* window = swapchain.surface.window.get();
Jesse Hallf4ab2b12015-11-30 16:04:55 -0800721 uint32_t image_idx = present_info->pImageIndices[sc];
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700722 Swapchain::Image& img = swapchain.images[image_idx];
Jesse Halld7b994a2015-09-07 14:17:37 -0700723 VkResult result;
724 int err;
725
Jesse Halld7b994a2015-09-07 14:17:37 -0700726 int fence = -1;
Jesse Hall275d76c2016-01-08 22:39:16 -0800727 result = dispatch.QueueSignalReleaseImageANDROID(
728 queue, present_info->waitSemaphoreCount,
729 present_info->pWaitSemaphores, img.image, &fence);
Jesse Halld7b994a2015-09-07 14:17:37 -0700730 if (result != VK_SUCCESS) {
Jesse Hallab9aeef2015-11-04 10:56:20 -0800731 ALOGE("QueueSignalReleaseImageANDROID failed: %d", result);
Jesse Halla9e57032015-11-30 01:03:10 -0800732 if (present_info->pResults)
733 present_info->pResults[sc] = result;
Jesse Halld7b994a2015-09-07 14:17:37 -0700734 if (final_result == VK_SUCCESS)
735 final_result = result;
736 // TODO(jessehall): What happens to the buffer here? Does the app
737 // still own it or not, i.e. should we cancel the buffer? Hard to
738 // do correctly without synchronizing, though I guess we could wait
739 // for the queue to idle.
740 continue;
741 }
742
Jesse Hall1356b0d2015-11-23 17:24:58 -0800743 err = window->queueBuffer(window, img.buffer.get(), fence);
Jesse Halld7b994a2015-09-07 14:17:37 -0700744 if (err != 0) {
745 // TODO(jessehall): What now? We should probably cancel the buffer,
746 // I guess?
747 ALOGE("queueBuffer failed: %s (%d)", strerror(-err), err);
Jesse Halla9e57032015-11-30 01:03:10 -0800748 if (present_info->pResults)
749 present_info->pResults[sc] = result;
Jesse Halld7b994a2015-09-07 14:17:37 -0700750 if (final_result == VK_SUCCESS)
Jesse Hall5ae3abb2015-10-08 14:00:22 -0700751 final_result = VK_ERROR_INITIALIZATION_FAILED;
Jesse Halld7b994a2015-09-07 14:17:37 -0700752 continue;
753 }
754
755 if (img.dequeue_fence != -1) {
756 close(img.dequeue_fence);
757 img.dequeue_fence = -1;
758 }
759 img.dequeued = false;
Jesse Halla9e57032015-11-30 01:03:10 -0800760
761 if (present_info->pResults)
762 present_info->pResults[sc] = VK_SUCCESS;
Jesse Halld7b994a2015-09-07 14:17:37 -0700763 }
764
765 return final_result;
766}
Jesse Hallb1352bc2015-09-04 16:12:33 -0700767
Chia-I Wu62262232016-03-26 07:06:44 +0800768} // namespace driver
Jesse Hallb1352bc2015-09-04 16:12:33 -0700769} // namespace vulkan