• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18 
19 #include <android/hardware/graphics/common/1.0/types.h>
20 #include <grallocusage/GrallocUsageConversion.h>
21 #include <graphicsenv/GraphicsEnv.h>
22 #include <hardware/gralloc.h>
23 #include <hardware/gralloc1.h>
24 #include <log/log.h>
25 #include <sync/sync.h>
26 #include <system/window.h>
27 #include <ui/BufferQueueDefs.h>
28 #include <ui/DebugUtils.h>
29 #include <ui/PixelFormat.h>
30 #include <utils/StrongPointer.h>
31 #include <utils/Timers.h>
32 #include <utils/Trace.h>
33 
34 #include <algorithm>
35 #include <unordered_set>
36 #include <vector>
37 
38 #include "driver.h"
39 
40 using android::hardware::graphics::common::V1_0::BufferUsage;
41 
42 namespace vulkan {
43 namespace driver {
44 
45 namespace {
46 
convertGralloc1ToBufferUsage(uint64_t producerUsage,uint64_t consumerUsage)47 static uint64_t convertGralloc1ToBufferUsage(uint64_t producerUsage,
48                                              uint64_t consumerUsage) {
49     static_assert(uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) ==
50                       uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN),
51                   "expected ConsumerUsage and ProducerUsage CPU_READ_OFTEN "
52                   "bits to match");
53     uint64_t merged = producerUsage | consumerUsage;
54     if ((merged & (GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)) ==
55         GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
56         merged &= ~uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN);
57         merged |= BufferUsage::CPU_READ_OFTEN;
58     }
59     if ((merged & (GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) ==
60         GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
61         merged &= ~uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN);
62         merged |= BufferUsage::CPU_WRITE_OFTEN;
63     }
64     return merged;
65 }
66 
67 const VkSurfaceTransformFlagsKHR kSupportedTransforms =
68     VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR |
69     VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
70     VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR |
71     VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
72     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR |
73     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR |
74     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR |
75     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR |
76     VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
77 
TranslateNativeToVulkanTransform(int native)78 VkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransform(int native) {
79     // Native and Vulkan transforms are isomorphic, but are represented
80     // differently. Vulkan transforms are built up of an optional horizontal
81     // mirror, followed by a clockwise 0/90/180/270-degree rotation. Native
82     // transforms are built up from a horizontal flip, vertical flip, and
83     // 90-degree rotation, all optional but always in that order.
84 
85     switch (native) {
86         case 0:
87             return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
88         case NATIVE_WINDOW_TRANSFORM_FLIP_H:
89             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR;
90         case NATIVE_WINDOW_TRANSFORM_FLIP_V:
91             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR;
92         case NATIVE_WINDOW_TRANSFORM_ROT_180:
93             return VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR;
94         case NATIVE_WINDOW_TRANSFORM_ROT_90:
95             return VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR;
96         case NATIVE_WINDOW_TRANSFORM_FLIP_H | NATIVE_WINDOW_TRANSFORM_ROT_90:
97             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR;
98         case NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_ROT_90:
99             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR;
100         case NATIVE_WINDOW_TRANSFORM_ROT_270:
101             return VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR;
102         case NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY:
103         default:
104             return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
105     }
106 }
107 
TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)108 int TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform) {
109     switch (transform) {
110         case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
111             return NATIVE_WINDOW_TRANSFORM_ROT_90;
112         case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
113             return NATIVE_WINDOW_TRANSFORM_ROT_180;
114         case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
115             return NATIVE_WINDOW_TRANSFORM_ROT_270;
116         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
117             return NATIVE_WINDOW_TRANSFORM_FLIP_H;
118         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
119             return NATIVE_WINDOW_TRANSFORM_FLIP_H |
120                    NATIVE_WINDOW_TRANSFORM_ROT_90;
121         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
122             return NATIVE_WINDOW_TRANSFORM_FLIP_V;
123         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
124             return NATIVE_WINDOW_TRANSFORM_FLIP_V |
125                    NATIVE_WINDOW_TRANSFORM_ROT_90;
126         case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
127         case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
128         default:
129             return 0;
130     }
131 }
132 
InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform)133 int InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform) {
134     switch (transform) {
135         case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
136             return NATIVE_WINDOW_TRANSFORM_ROT_270;
137         case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
138             return NATIVE_WINDOW_TRANSFORM_ROT_180;
139         case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
140             return NATIVE_WINDOW_TRANSFORM_ROT_90;
141         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
142             return NATIVE_WINDOW_TRANSFORM_FLIP_H;
143         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
144             return NATIVE_WINDOW_TRANSFORM_FLIP_H |
145                    NATIVE_WINDOW_TRANSFORM_ROT_90;
146         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
147             return NATIVE_WINDOW_TRANSFORM_FLIP_V;
148         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
149             return NATIVE_WINDOW_TRANSFORM_FLIP_V |
150                    NATIVE_WINDOW_TRANSFORM_ROT_90;
151         case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
152         case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
153         default:
154             return 0;
155     }
156 }
157 
158 class TimingInfo {
159    public:
TimingInfo(const VkPresentTimeGOOGLE * qp,uint64_t nativeFrameId)160     TimingInfo(const VkPresentTimeGOOGLE* qp, uint64_t nativeFrameId)
161         : vals_{qp->presentID, qp->desiredPresentTime, 0, 0, 0},
162           native_frame_id_(nativeFrameId) {}
ready() const163     bool ready() const {
164         return (timestamp_desired_present_time_ !=
165                         NATIVE_WINDOW_TIMESTAMP_PENDING &&
166                 timestamp_actual_present_time_ !=
167                         NATIVE_WINDOW_TIMESTAMP_PENDING &&
168                 timestamp_render_complete_time_ !=
169                         NATIVE_WINDOW_TIMESTAMP_PENDING &&
170                 timestamp_composition_latch_time_ !=
171                         NATIVE_WINDOW_TIMESTAMP_PENDING);
172     }
calculate(int64_t rdur)173     void calculate(int64_t rdur) {
174         bool anyTimestampInvalid =
175                 (timestamp_actual_present_time_ ==
176                         NATIVE_WINDOW_TIMESTAMP_INVALID) ||
177                 (timestamp_render_complete_time_ ==
178                         NATIVE_WINDOW_TIMESTAMP_INVALID) ||
179                 (timestamp_composition_latch_time_ ==
180                         NATIVE_WINDOW_TIMESTAMP_INVALID);
181         if (anyTimestampInvalid) {
182             ALOGE("Unexpectedly received invalid timestamp.");
183             vals_.actualPresentTime = 0;
184             vals_.earliestPresentTime = 0;
185             vals_.presentMargin = 0;
186             return;
187         }
188 
189         vals_.actualPresentTime =
190                 static_cast<uint64_t>(timestamp_actual_present_time_);
191         int64_t margin = (timestamp_composition_latch_time_ -
192                            timestamp_render_complete_time_);
193         // Calculate vals_.earliestPresentTime, and potentially adjust
194         // vals_.presentMargin.  The initial value of vals_.earliestPresentTime
195         // is vals_.actualPresentTime.  If we can subtract rdur (the duration
196         // of a refresh cycle) from vals_.earliestPresentTime (and also from
197         // vals_.presentMargin) and still leave a positive margin, then we can
198         // report to the application that it could have presented earlier than
199         // it did (per the extension specification).  If for some reason, we
200         // can do this subtraction repeatedly, we do, since
201         // vals_.earliestPresentTime really is supposed to be the "earliest".
202         int64_t early_time = timestamp_actual_present_time_;
203         while ((margin > rdur) &&
204                ((early_time - rdur) > timestamp_composition_latch_time_)) {
205             early_time -= rdur;
206             margin -= rdur;
207         }
208         vals_.earliestPresentTime = static_cast<uint64_t>(early_time);
209         vals_.presentMargin = static_cast<uint64_t>(margin);
210     }
get_values(VkPastPresentationTimingGOOGLE * values) const211     void get_values(VkPastPresentationTimingGOOGLE* values) const {
212         *values = vals_;
213     }
214 
215    public:
216     VkPastPresentationTimingGOOGLE vals_ { 0, 0, 0, 0, 0 };
217 
218     uint64_t native_frame_id_ { 0 };
219     int64_t timestamp_desired_present_time_{ NATIVE_WINDOW_TIMESTAMP_PENDING };
220     int64_t timestamp_actual_present_time_ { NATIVE_WINDOW_TIMESTAMP_PENDING };
221     int64_t timestamp_render_complete_time_ { NATIVE_WINDOW_TIMESTAMP_PENDING };
222     int64_t timestamp_composition_latch_time_
223             { NATIVE_WINDOW_TIMESTAMP_PENDING };
224 };
225 
226 struct Surface {
227     android::sp<ANativeWindow> window;
228     VkSwapchainKHR swapchain_handle;
229     uint64_t consumer_usage;
230 
231     // Indicate whether this surface has been used by a swapchain, no matter the
232     // swapchain is still current or has been destroyed.
233     bool used_by_swapchain;
234 };
235 
HandleFromSurface(Surface * surface)236 VkSurfaceKHR HandleFromSurface(Surface* surface) {
237     return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
238 }
239 
SurfaceFromHandle(VkSurfaceKHR handle)240 Surface* SurfaceFromHandle(VkSurfaceKHR handle) {
241     return reinterpret_cast<Surface*>(handle);
242 }
243 
244 // Maximum number of TimingInfo structs to keep per swapchain:
245 enum { MAX_TIMING_INFOS = 10 };
246 // Minimum number of frames to look for in the past (so we don't cause
247 // syncronous requests to Surface Flinger):
248 enum { MIN_NUM_FRAMES_AGO = 5 };
249 
IsSharedPresentMode(VkPresentModeKHR mode)250 bool IsSharedPresentMode(VkPresentModeKHR mode) {
251     return mode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
252         mode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR;
253 }
254 
255 struct Swapchain {
Swapchainvulkan::driver::__anonba7038700111::Swapchain256     Swapchain(Surface& surface_,
257               uint32_t num_images_,
258               VkPresentModeKHR present_mode,
259               int pre_transform_,
260               int64_t refresh_duration_)
261         : surface(surface_),
262           num_images(num_images_),
263           mailbox_mode(present_mode == VK_PRESENT_MODE_MAILBOX_KHR),
264           pre_transform(pre_transform_),
265           frame_timestamps_enabled(false),
266           refresh_duration(refresh_duration_),
267           acquire_next_image_timeout(-1),
268           shared(IsSharedPresentMode(present_mode)) {
269     }
270 
get_refresh_durationvulkan::driver::__anonba7038700111::Swapchain271     VkResult get_refresh_duration(uint64_t& outRefreshDuration)
272     {
273         ANativeWindow* window = surface.window.get();
274         int err = native_window_get_refresh_cycle_duration(
275             window,
276             &refresh_duration);
277         if (err != android::OK) {
278             ALOGE("%s:native_window_get_refresh_cycle_duration failed: %s (%d)",
279                 __func__, strerror(-err), err );
280             return VK_ERROR_SURFACE_LOST_KHR;
281         }
282         outRefreshDuration = refresh_duration;
283         return VK_SUCCESS;
284     }
285 
286     Surface& surface;
287     uint32_t num_images;
288     bool mailbox_mode;
289     int pre_transform;
290     bool frame_timestamps_enabled;
291     int64_t refresh_duration;
292     nsecs_t acquire_next_image_timeout;
293     bool shared;
294 
295     struct Image {
Imagevulkan::driver::__anonba7038700111::Swapchain::Image296         Image()
297             : image(VK_NULL_HANDLE),
298               dequeue_fence(-1),
299               release_fence(-1),
300               dequeued(false) {}
301         VkImage image;
302         // If the image is bound to memory, an sp to the underlying gralloc buffer.
303         // Otherwise, nullptr; the image will be bound to memory as part of
304         // AcquireNextImage.
305         android::sp<ANativeWindowBuffer> buffer;
306         // The fence is only valid when the buffer is dequeued, and should be
307         // -1 any other time. When valid, we own the fd, and must ensure it is
308         // closed: either by closing it explicitly when queueing the buffer,
309         // or by passing ownership e.g. to ANativeWindow::cancelBuffer().
310         int dequeue_fence;
311         // This fence is a dup of the sync fd returned from the driver via
312         // vkQueueSignalReleaseImageANDROID upon vkQueuePresentKHR. We must
313         // ensure it is closed upon re-presenting or releasing the image.
314         int release_fence;
315         bool dequeued;
316     } images[android::BufferQueueDefs::NUM_BUFFER_SLOTS];
317 
318     std::vector<TimingInfo> timing;
319 };
320 
HandleFromSwapchain(Swapchain * swapchain)321 VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain) {
322     return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain));
323 }
324 
SwapchainFromHandle(VkSwapchainKHR handle)325 Swapchain* SwapchainFromHandle(VkSwapchainKHR handle) {
326     return reinterpret_cast<Swapchain*>(handle);
327 }
328 
IsFencePending(int fd)329 static bool IsFencePending(int fd) {
330     if (fd < 0)
331         return false;
332 
333     errno = 0;
334     return sync_wait(fd, 0 /* timeout */) == -1 && errno == ETIME;
335 }
336 
ReleaseSwapchainImage(VkDevice device,bool shared_present,ANativeWindow * window,int release_fence,Swapchain::Image & image,bool defer_if_pending)337 void ReleaseSwapchainImage(VkDevice device,
338                            bool shared_present,
339                            ANativeWindow* window,
340                            int release_fence,
341                            Swapchain::Image& image,
342                            bool defer_if_pending) {
343     ATRACE_CALL();
344 
345     ALOG_ASSERT(release_fence == -1 || image.dequeued,
346                 "ReleaseSwapchainImage: can't provide a release fence for "
347                 "non-dequeued images");
348 
349     if (image.dequeued) {
350         if (release_fence >= 0) {
351             // We get here from vkQueuePresentKHR. The application is
352             // responsible for creating an execution dependency chain from
353             // vkAcquireNextImage (dequeue_fence) to vkQueuePresentKHR
354             // (release_fence), so we can drop the dequeue_fence here.
355             if (image.dequeue_fence >= 0)
356                 close(image.dequeue_fence);
357         } else {
358             // We get here during swapchain destruction, or various serious
359             // error cases e.g. when we can't create the release_fence during
360             // vkQueuePresentKHR. In non-error cases, the dequeue_fence should
361             // have already signalled, since the swapchain images are supposed
362             // to be idle before the swapchain is destroyed. In error cases,
363             // there may be rendering in flight to the image, but since we
364             // weren't able to create a release_fence, waiting for the
365             // dequeue_fence is about the best we can do.
366             release_fence = image.dequeue_fence;
367         }
368         image.dequeue_fence = -1;
369 
370         // It's invalid to call cancelBuffer on a shared buffer
371         if (window && !shared_present) {
372             window->cancelBuffer(window, image.buffer.get(), release_fence);
373         } else {
374             if (release_fence >= 0) {
375                 sync_wait(release_fence, -1 /* forever */);
376                 close(release_fence);
377             }
378         }
379         release_fence = -1;
380         image.dequeued = false;
381     }
382 
383     if (defer_if_pending && IsFencePending(image.release_fence))
384         return;
385 
386     if (image.release_fence >= 0) {
387         close(image.release_fence);
388         image.release_fence = -1;
389     }
390 
391     if (image.image) {
392         ATRACE_BEGIN("DestroyImage");
393         GetData(device).driver.DestroyImage(device, image.image, nullptr);
394         ATRACE_END();
395         image.image = VK_NULL_HANDLE;
396     }
397 
398     image.buffer.clear();
399 }
400 
OrphanSwapchain(VkDevice device,Swapchain * swapchain)401 void OrphanSwapchain(VkDevice device, Swapchain* swapchain) {
402     if (swapchain->surface.swapchain_handle != HandleFromSwapchain(swapchain))
403         return;
404     for (uint32_t i = 0; i < swapchain->num_images; i++) {
405         if (!swapchain->images[i].dequeued) {
406             ReleaseSwapchainImage(device, swapchain->shared, nullptr, -1,
407                                   swapchain->images[i], true);
408         }
409     }
410     swapchain->surface.swapchain_handle = VK_NULL_HANDLE;
411     swapchain->timing.clear();
412 }
413 
get_num_ready_timings(Swapchain & swapchain)414 uint32_t get_num_ready_timings(Swapchain& swapchain) {
415     if (swapchain.timing.size() < MIN_NUM_FRAMES_AGO) {
416         return 0;
417     }
418 
419     uint32_t num_ready = 0;
420     const size_t num_timings = swapchain.timing.size() - MIN_NUM_FRAMES_AGO + 1;
421     for (uint32_t i = 0; i < num_timings; i++) {
422         TimingInfo& ti = swapchain.timing[i];
423         if (ti.ready()) {
424             // This TimingInfo is ready to be reported to the user.  Add it
425             // to the num_ready.
426             num_ready++;
427             continue;
428         }
429         // This TimingInfo is not yet ready to be reported to the user,
430         // and so we should look for any available timestamps that
431         // might make it ready.
432         int64_t desired_present_time = 0;
433         int64_t render_complete_time = 0;
434         int64_t composition_latch_time = 0;
435         int64_t actual_present_time = 0;
436         // Obtain timestamps:
437         int err = native_window_get_frame_timestamps(
438             swapchain.surface.window.get(), ti.native_frame_id_,
439             &desired_present_time, &render_complete_time,
440             &composition_latch_time,
441             nullptr,  //&first_composition_start_time,
442             nullptr,  //&last_composition_start_time,
443             nullptr,  //&composition_finish_time,
444             &actual_present_time,
445             nullptr,  //&dequeue_ready_time,
446             nullptr /*&reads_done_time*/);
447 
448         if (err != android::OK) {
449             continue;
450         }
451 
452         // Record the timestamp(s) we received, and then see if this TimingInfo
453         // is ready to be reported to the user:
454         ti.timestamp_desired_present_time_ = desired_present_time;
455         ti.timestamp_actual_present_time_ = actual_present_time;
456         ti.timestamp_render_complete_time_ = render_complete_time;
457         ti.timestamp_composition_latch_time_ = composition_latch_time;
458 
459         if (ti.ready()) {
460             // The TimingInfo has received enough timestamps, and should now
461             // use those timestamps to calculate the info that should be
462             // reported to the user:
463             ti.calculate(swapchain.refresh_duration);
464             num_ready++;
465         }
466     }
467     return num_ready;
468 }
469 
copy_ready_timings(Swapchain & swapchain,uint32_t * count,VkPastPresentationTimingGOOGLE * timings)470 void copy_ready_timings(Swapchain& swapchain,
471                         uint32_t* count,
472                         VkPastPresentationTimingGOOGLE* timings) {
473     if (swapchain.timing.empty()) {
474         *count = 0;
475         return;
476     }
477 
478     size_t last_ready = swapchain.timing.size() - 1;
479     while (!swapchain.timing[last_ready].ready()) {
480         if (last_ready == 0) {
481             *count = 0;
482             return;
483         }
484         last_ready--;
485     }
486 
487     uint32_t num_copied = 0;
488     int32_t num_to_remove = 0;
489     for (uint32_t i = 0; i <= last_ready && num_copied < *count; i++) {
490         const TimingInfo& ti = swapchain.timing[i];
491         if (ti.ready()) {
492             ti.get_values(&timings[num_copied]);
493             num_copied++;
494         }
495         num_to_remove++;
496     }
497 
498     // Discard old frames that aren't ready if newer frames are ready.
499     // We don't expect to get the timing info for those old frames.
500     swapchain.timing.erase(swapchain.timing.begin(),
501                            swapchain.timing.begin() + num_to_remove);
502 
503     *count = num_copied;
504 }
505 
GetNativePixelFormat(VkFormat format)506 android::PixelFormat GetNativePixelFormat(VkFormat format) {
507     android::PixelFormat native_format = android::PIXEL_FORMAT_RGBA_8888;
508     switch (format) {
509         case VK_FORMAT_R8G8B8A8_UNORM:
510         case VK_FORMAT_R8G8B8A8_SRGB:
511             native_format = android::PIXEL_FORMAT_RGBA_8888;
512             break;
513         case VK_FORMAT_R5G6B5_UNORM_PACK16:
514             native_format = android::PIXEL_FORMAT_RGB_565;
515             break;
516         case VK_FORMAT_R16G16B16A16_SFLOAT:
517             native_format = android::PIXEL_FORMAT_RGBA_FP16;
518             break;
519         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
520             native_format = android::PIXEL_FORMAT_RGBA_1010102;
521             break;
522         case VK_FORMAT_R8_UNORM:
523             native_format = android::PIXEL_FORMAT_R_8;
524             break;
525         case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
526             native_format = android::PIXEL_FORMAT_RGBA_10101010;
527             break;
528         default:
529             ALOGV("unsupported swapchain format %d", format);
530             break;
531     }
532     return native_format;
533 }
534 
GetNativeDataspace(VkColorSpaceKHR colorspace,android::PixelFormat pixelFormat)535 android_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace,
536                                      android::PixelFormat pixelFormat) {
537     switch (colorspace) {
538         case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
539             return HAL_DATASPACE_V0_SRGB;
540         case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
541             return HAL_DATASPACE_DISPLAY_P3;
542         case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
543             return HAL_DATASPACE_V0_SCRGB_LINEAR;
544         case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
545             return HAL_DATASPACE_V0_SCRGB;
546         case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
547             return HAL_DATASPACE_DCI_P3_LINEAR;
548         case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
549             return HAL_DATASPACE_DCI_P3;
550         case VK_COLOR_SPACE_BT709_LINEAR_EXT:
551             return HAL_DATASPACE_V0_SRGB_LINEAR;
552         case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
553             return HAL_DATASPACE_V0_SRGB;
554         case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
555             if (pixelFormat == HAL_PIXEL_FORMAT_RGBA_FP16) {
556                 return static_cast<android_dataspace>(
557                     HAL_DATASPACE_STANDARD_BT2020 |
558                     HAL_DATASPACE_TRANSFER_LINEAR |
559                     HAL_DATASPACE_RANGE_EXTENDED);
560             } else {
561                 return HAL_DATASPACE_BT2020_LINEAR;
562             }
563         case VK_COLOR_SPACE_HDR10_ST2084_EXT:
564             return static_cast<android_dataspace>(
565                 HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
566                 HAL_DATASPACE_RANGE_FULL);
567         case VK_COLOR_SPACE_DOLBYVISION_EXT:
568             return static_cast<android_dataspace>(
569                 HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
570                 HAL_DATASPACE_RANGE_FULL);
571         case VK_COLOR_SPACE_HDR10_HLG_EXT:
572             return static_cast<android_dataspace>(HAL_DATASPACE_BT2020_HLG);
573         case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
574             return static_cast<android_dataspace>(
575                 HAL_DATASPACE_STANDARD_ADOBE_RGB |
576                 HAL_DATASPACE_TRANSFER_LINEAR | HAL_DATASPACE_RANGE_FULL);
577         case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
578             return HAL_DATASPACE_ADOBE_RGB;
579 
580         // Pass through is intended to allow app to provide data that is passed
581         // to the display system without modification.
582         case VK_COLOR_SPACE_PASS_THROUGH_EXT:
583             return HAL_DATASPACE_ARBITRARY;
584 
585         default:
586             // This indicates that we don't know about the
587             // dataspace specified and we should indicate that
588             // it's unsupported
589             return HAL_DATASPACE_UNKNOWN;
590     }
591 }
592 
593 }  // anonymous namespace
594 
595 VKAPI_ATTR
CreateAndroidSurfaceKHR(VkInstance instance,const VkAndroidSurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * allocator,VkSurfaceKHR * out_surface)596 VkResult CreateAndroidSurfaceKHR(
597     VkInstance instance,
598     const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
599     const VkAllocationCallbacks* allocator,
600     VkSurfaceKHR* out_surface) {
601     ATRACE_CALL();
602 
603     if (!allocator)
604         allocator = &GetData(instance).allocator;
605     void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface),
606                                          alignof(Surface),
607                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
608     if (!mem)
609         return VK_ERROR_OUT_OF_HOST_MEMORY;
610     Surface* surface = new (mem) Surface;
611 
612     surface->window = pCreateInfo->window;
613     surface->swapchain_handle = VK_NULL_HANDLE;
614     surface->used_by_swapchain = false;
615     int err = native_window_get_consumer_usage(surface->window.get(),
616                                                &surface->consumer_usage);
617     if (err != android::OK) {
618         ALOGE("native_window_get_consumer_usage() failed: %s (%d)",
619               strerror(-err), err);
620         surface->~Surface();
621         allocator->pfnFree(allocator->pUserData, surface);
622         return VK_ERROR_SURFACE_LOST_KHR;
623     }
624 
625     err =
626         native_window_api_connect(surface->window.get(), NATIVE_WINDOW_API_EGL);
627     if (err != android::OK) {
628         ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err),
629               err);
630         surface->~Surface();
631         allocator->pfnFree(allocator->pUserData, surface);
632         return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
633     }
634 
635     *out_surface = HandleFromSurface(surface);
636     return VK_SUCCESS;
637 }
638 
639 VKAPI_ATTR
DestroySurfaceKHR(VkInstance instance,VkSurfaceKHR surface_handle,const VkAllocationCallbacks * allocator)640 void DestroySurfaceKHR(VkInstance instance,
641                        VkSurfaceKHR surface_handle,
642                        const VkAllocationCallbacks* allocator) {
643     ATRACE_CALL();
644 
645     Surface* surface = SurfaceFromHandle(surface_handle);
646     if (!surface)
647         return;
648     native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL);
649     ALOGV_IF(surface->swapchain_handle != VK_NULL_HANDLE,
650              "destroyed VkSurfaceKHR 0x%" PRIx64
651              " has active VkSwapchainKHR 0x%" PRIx64,
652              reinterpret_cast<uint64_t>(surface_handle),
653              reinterpret_cast<uint64_t>(surface->swapchain_handle));
654     surface->~Surface();
655     if (!allocator)
656         allocator = &GetData(instance).allocator;
657     allocator->pfnFree(allocator->pUserData, surface);
658 }
659 
660 VKAPI_ATTR
GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice,uint32_t,VkSurfaceKHR,VkBool32 * supported)661 VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
662                                             uint32_t /*queue_family*/,
663                                             VkSurfaceKHR /*surface_handle*/,
664                                             VkBool32* supported) {
665     *supported = VK_TRUE;
666     return VK_SUCCESS;
667 }
668 
669 VKAPI_ATTR
GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice pdev,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * capabilities)670 VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(
671     VkPhysicalDevice pdev,
672     VkSurfaceKHR surface,
673     VkSurfaceCapabilitiesKHR* capabilities) {
674     ATRACE_CALL();
675 
676     // Implement in terms of GetPhysicalDeviceSurfaceCapabilities2KHR
677 
678     VkPhysicalDeviceSurfaceInfo2KHR info2 = {
679         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
680         nullptr,
681         surface
682     };
683 
684     VkSurfaceCapabilities2KHR caps2 = {
685         VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
686         nullptr,
687         {},
688     };
689 
690     VkResult result = GetPhysicalDeviceSurfaceCapabilities2KHR(pdev, &info2, &caps2);
691     *capabilities = caps2.surfaceCapabilities;
692     return result;
693 }
694 
695 // Does the call-twice and VK_INCOMPLETE handling for querying lists
696 // of things, where we already have the full set built in a vector.
697 template <typename T>
CopyWithIncomplete(std::vector<T> const & things,T * callerPtr,uint32_t * callerCount)698 VkResult CopyWithIncomplete(std::vector<T> const& things,
699         T* callerPtr, uint32_t* callerCount) {
700     VkResult result = VK_SUCCESS;
701     if (callerPtr) {
702         if (things.size() > *callerCount)
703             result = VK_INCOMPLETE;
704         *callerCount = std::min(uint32_t(things.size()), *callerCount);
705         std::copy(things.begin(), things.begin() + *callerCount, callerPtr);
706     } else {
707         *callerCount = things.size();
708     }
709     return result;
710 }
711 
712 VKAPI_ATTR
GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev,VkSurfaceKHR surface_handle,uint32_t * count,VkSurfaceFormatKHR * formats)713 VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev,
714                                             VkSurfaceKHR surface_handle,
715                                             uint32_t* count,
716                                             VkSurfaceFormatKHR* formats) {
717     ATRACE_CALL();
718 
719     const InstanceData& instance_data = GetData(pdev);
720 
721     uint64_t consumer_usage = 0;
722     bool colorspace_ext =
723         instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
724     if (surface_handle == VK_NULL_HANDLE) {
725         ProcHook::Extension surfaceless = ProcHook::GOOGLE_surfaceless_query;
726         bool surfaceless_enabled =
727             instance_data.hook_extensions.test(surfaceless);
728         if (!surfaceless_enabled) {
729             return VK_ERROR_SURFACE_LOST_KHR;
730         }
731         // Support for VK_GOOGLE_surfaceless_query.
732 
733         // TODO(b/203826952): research proper value; temporarily use the
734         // values seen on Pixel
735         consumer_usage = AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY;
736     } else {
737         Surface& surface = *SurfaceFromHandle(surface_handle);
738         consumer_usage = surface.consumer_usage;
739     }
740 
741     AHardwareBuffer_Desc desc = {};
742     desc.width = 1;
743     desc.height = 1;
744     desc.layers = 1;
745     desc.usage = consumer_usage | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
746                  AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
747 
748     // We must support R8G8B8A8
749     std::vector<VkSurfaceFormatKHR> all_formats = {
750         {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
751         {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
752     };
753 
754     if (colorspace_ext) {
755         all_formats.emplace_back(VkSurfaceFormatKHR{
756             VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_PASS_THROUGH_EXT});
757         all_formats.emplace_back(VkSurfaceFormatKHR{
758             VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_PASS_THROUGH_EXT});
759         all_formats.emplace_back(VkSurfaceFormatKHR{
760             VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_BT709_LINEAR_EXT});
761         all_formats.emplace_back(VkSurfaceFormatKHR{
762             VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
763         all_formats.emplace_back(VkSurfaceFormatKHR{
764             VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
765     }
766 
767     // NOTE: Any new formats that are added must be coordinated across different
768     // Android users.  This includes the ANGLE team (a layered implementation of
769     // OpenGL-ES).
770 
771     desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
772     if (AHardwareBuffer_isSupported(&desc)) {
773         all_formats.emplace_back(VkSurfaceFormatKHR{
774             VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
775         if (colorspace_ext) {
776             all_formats.emplace_back(
777                 VkSurfaceFormatKHR{VK_FORMAT_R5G6B5_UNORM_PACK16,
778                                    VK_COLOR_SPACE_PASS_THROUGH_EXT});
779         }
780     }
781 
782     desc.format = AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
783     if (AHardwareBuffer_isSupported(&desc)) {
784         all_formats.emplace_back(VkSurfaceFormatKHR{
785             VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
786         if (colorspace_ext) {
787             all_formats.emplace_back(
788                 VkSurfaceFormatKHR{VK_FORMAT_R16G16B16A16_SFLOAT,
789                                    VK_COLOR_SPACE_PASS_THROUGH_EXT});
790             all_formats.emplace_back(
791                 VkSurfaceFormatKHR{VK_FORMAT_R16G16B16A16_SFLOAT,
792                                    VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT});
793             all_formats.emplace_back(
794                 VkSurfaceFormatKHR{VK_FORMAT_R16G16B16A16_SFLOAT,
795                                    VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT});
796         }
797     }
798 
799     desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
800     if (AHardwareBuffer_isSupported(&desc)) {
801         all_formats.emplace_back(
802             VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
803                                VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
804         if (colorspace_ext) {
805             all_formats.emplace_back(
806                 VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
807                                    VK_COLOR_SPACE_PASS_THROUGH_EXT});
808             all_formats.emplace_back(
809                 VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
810                                    VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
811         }
812     }
813 
814     desc.format = AHARDWAREBUFFER_FORMAT_R8_UNORM;
815     if (AHardwareBuffer_isSupported(&desc)) {
816         if (colorspace_ext) {
817             all_formats.emplace_back(VkSurfaceFormatKHR{
818                 VK_FORMAT_R8_UNORM, VK_COLOR_SPACE_PASS_THROUGH_EXT});
819         }
820     }
821 
822     bool rgba10x6_formats_ext = false;
823     uint32_t exts_count;
824     const auto& driver = GetData(pdev).driver;
825     driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count,
826                                               nullptr);
827     std::vector<VkExtensionProperties> props(exts_count);
828     driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count,
829                                               props.data());
830     for (uint32_t i = 0; i < exts_count; i++) {
831         VkExtensionProperties prop = props[i];
832         if (strcmp(prop.extensionName,
833                    VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME) == 0) {
834             rgba10x6_formats_ext = true;
835         }
836     }
837     desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM;
838     if (AHardwareBuffer_isSupported(&desc) && rgba10x6_formats_ext) {
839         all_formats.emplace_back(
840             VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
841                                VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
842         if (colorspace_ext) {
843             all_formats.emplace_back(
844                 VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
845                                    VK_COLOR_SPACE_PASS_THROUGH_EXT});
846             all_formats.emplace_back(
847                 VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
848                                    VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
849         }
850     }
851 
852     // NOTE: Any new formats that are added must be coordinated across different
853     // Android users.  This includes the ANGLE team (a layered implementation of
854     // OpenGL-ES).
855 
856     return CopyWithIncomplete(all_formats, formats, count);
857 }
858 
859 VKAPI_ATTR
GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)860 VkResult GetPhysicalDeviceSurfaceCapabilities2KHR(
861     VkPhysicalDevice physicalDevice,
862     const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
863     VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
864     ATRACE_CALL();
865 
866     auto surface = pSurfaceInfo->surface;
867     auto capabilities = &pSurfaceCapabilities->surfaceCapabilities;
868 
869     VkSurfacePresentModeEXT const *pPresentMode = nullptr;
870     for (auto pNext = reinterpret_cast<VkBaseInStructure const *>(pSurfaceInfo->pNext);
871             pNext; pNext = reinterpret_cast<VkBaseInStructure const *>(pNext->pNext)) {
872         switch (pNext->sType) {
873             case VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT:
874                 pPresentMode = reinterpret_cast<VkSurfacePresentModeEXT const *>(pNext);
875                 break;
876 
877             default:
878                 break;
879         }
880     }
881 
882     int err;
883     int width, height;
884     int transform_hint;
885     int max_buffer_count;
886     int min_undequeued_buffers;
887     if (surface == VK_NULL_HANDLE) {
888         const InstanceData& instance_data = GetData(physicalDevice);
889         ProcHook::Extension surfaceless = ProcHook::GOOGLE_surfaceless_query;
890         bool surfaceless_enabled =
891             instance_data.hook_extensions.test(surfaceless);
892         if (!surfaceless_enabled) {
893             // It is an error to pass a surface==VK_NULL_HANDLE unless the
894             // VK_GOOGLE_surfaceless_query extension is enabled
895             return VK_ERROR_SURFACE_LOST_KHR;
896         }
897         // Support for VK_GOOGLE_surfaceless_query.  The primary purpose of this
898         // extension for this function is for
899         // VkSurfaceProtectedCapabilitiesKHR::supportsProtected.  The following
900         // four values cannot be known without a surface.  Default values will
901         // be supplied anyway, but cannot be relied upon.
902         width = 0xFFFFFFFF;
903         height = 0xFFFFFFFF;
904         transform_hint = VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
905         capabilities->minImageCount = 0xFFFFFFFF;
906         capabilities->maxImageCount = 0xFFFFFFFF;
907     } else {
908         ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
909 
910         err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
911         if (err != android::OK) {
912             ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
913                   strerror(-err), err);
914             return VK_ERROR_SURFACE_LOST_KHR;
915         }
916         err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
917         if (err != android::OK) {
918             ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
919                   strerror(-err), err);
920             return VK_ERROR_SURFACE_LOST_KHR;
921         }
922 
923         err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT,
924                             &transform_hint);
925         if (err != android::OK) {
926             ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)",
927                   strerror(-err), err);
928             return VK_ERROR_SURFACE_LOST_KHR;
929         }
930 
931         err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT,
932                             &max_buffer_count);
933         if (err != android::OK) {
934             ALOGE("NATIVE_WINDOW_MAX_BUFFER_COUNT query failed: %s (%d)",
935                   strerror(-err), err);
936             return VK_ERROR_SURFACE_LOST_KHR;
937         }
938 
939         err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
940                             &min_undequeued_buffers);
941         if (err != android::OK) {
942             ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
943                   strerror(-err), err);
944             return VK_ERROR_SURFACE_LOST_KHR;
945         }
946 
947         if (pPresentMode && IsSharedPresentMode(pPresentMode->presentMode)) {
948             capabilities->minImageCount = 1;
949             capabilities->maxImageCount = 1;
950         } else if (pPresentMode && pPresentMode->presentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
951             capabilities->minImageCount =
952                 std::min(max_buffer_count, min_undequeued_buffers + 2);
953             capabilities->maxImageCount = static_cast<uint32_t>(max_buffer_count);
954         } else {
955             capabilities->minImageCount =
956                 std::min(max_buffer_count, min_undequeued_buffers + 1);
957             capabilities->maxImageCount = static_cast<uint32_t>(max_buffer_count);
958         }
959     }
960 
961     capabilities->currentExtent =
962         VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
963 
964     // TODO(http://b/134182502): Figure out what the max extent should be.
965     capabilities->minImageExtent = VkExtent2D{1, 1};
966     capabilities->maxImageExtent = VkExtent2D{4096, 4096};
967 
968     if (capabilities->maxImageExtent.height <
969         capabilities->currentExtent.height) {
970         capabilities->maxImageExtent.height =
971             capabilities->currentExtent.height;
972     }
973 
974     if (capabilities->maxImageExtent.width <
975         capabilities->currentExtent.width) {
976         capabilities->maxImageExtent.width = capabilities->currentExtent.width;
977     }
978 
979     capabilities->maxImageArrayLayers = 1;
980 
981     capabilities->supportedTransforms = kSupportedTransforms;
982     capabilities->currentTransform =
983         TranslateNativeToVulkanTransform(transform_hint);
984 
985     // On Android, window composition is a WindowManager property, not something
986     // associated with the bufferqueue. It can't be changed from here.
987     capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
988 
989     capabilities->supportedUsageFlags =
990         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
991         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
992         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
993         VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
994 
995     for (auto pNext = reinterpret_cast<VkBaseOutStructure*>(pSurfaceCapabilities->pNext);
996             pNext; pNext = reinterpret_cast<VkBaseOutStructure*>(pNext->pNext)) {
997 
998         switch (pNext->sType) {
999             case VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR: {
1000                 VkSharedPresentSurfaceCapabilitiesKHR* shared_caps =
1001                     reinterpret_cast<VkSharedPresentSurfaceCapabilitiesKHR*>(pNext);
1002                 // Claim same set of usage flags are supported for
1003                 // shared present modes as for other modes.
1004                 shared_caps->sharedPresentSupportedUsageFlags =
1005                     pSurfaceCapabilities->surfaceCapabilities
1006                         .supportedUsageFlags;
1007             } break;
1008 
1009             case VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR: {
1010                 VkSurfaceProtectedCapabilitiesKHR* protected_caps =
1011                     reinterpret_cast<VkSurfaceProtectedCapabilitiesKHR*>(pNext);
1012                 protected_caps->supportsProtected = VK_TRUE;
1013             } break;
1014 
1015             case VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT: {
1016                 VkSurfacePresentScalingCapabilitiesEXT* scaling_caps =
1017                     reinterpret_cast<VkSurfacePresentScalingCapabilitiesEXT*>(pNext);
1018                 // By default, Android stretches the buffer to fit the window,
1019                 // without preserving aspect ratio. Other modes are technically possible
1020                 // but consult with CoGS team before exposing them here!
1021                 scaling_caps->supportedPresentScaling = VK_PRESENT_SCALING_STRETCH_BIT_EXT;
1022 
1023                 // Since we always scale, we don't support any gravity.
1024                 scaling_caps->supportedPresentGravityX = 0;
1025                 scaling_caps->supportedPresentGravityY = 0;
1026 
1027                 // Scaled image limits are just the basic image limits
1028                 scaling_caps->minScaledImageExtent = capabilities->minImageExtent;
1029                 scaling_caps->maxScaledImageExtent = capabilities->maxImageExtent;
1030             } break;
1031 
1032             case VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT: {
1033                 VkSurfacePresentModeCompatibilityEXT* mode_caps =
1034                     reinterpret_cast<VkSurfacePresentModeCompatibilityEXT*>(pNext);
1035 
1036                 ALOG_ASSERT(pPresentMode,
1037                         "querying VkSurfacePresentModeCompatibilityEXT "
1038                         "requires VkSurfacePresentModeEXT to be provided");
1039                 std::vector<VkPresentModeKHR> compatibleModes;
1040                 compatibleModes.push_back(pPresentMode->presentMode);
1041 
1042                 switch (pPresentMode->presentMode) {
1043                     // Shared modes are both compatible with each other.
1044                     case VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR:
1045                         compatibleModes.push_back(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR);
1046                         break;
1047                     case VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR:
1048                         compatibleModes.push_back(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR);
1049                         break;
1050                     default:
1051                         // Other modes are only compatible with themselves.
1052                         // TODO: consider whether switching between FIFO and MAILBOX is reasonable
1053                         break;
1054                 }
1055 
1056                 // Note: this does not generate VK_INCOMPLETE since we're nested inside
1057                 // a larger query and there would be no way to determine exactly where it came from.
1058                 CopyWithIncomplete(compatibleModes, mode_caps->pPresentModes,
1059                         &mode_caps->presentModeCount);
1060             } break;
1061 
1062             default:
1063                 // Ignore all other extension structs
1064                 break;
1065         }
1066     }
1067 
1068     return VK_SUCCESS;
1069 }
1070 
1071 VKAPI_ATTR
GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)1072 VkResult GetPhysicalDeviceSurfaceFormats2KHR(
1073     VkPhysicalDevice physicalDevice,
1074     const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
1075     uint32_t* pSurfaceFormatCount,
1076     VkSurfaceFormat2KHR* pSurfaceFormats) {
1077     ATRACE_CALL();
1078 
1079     if (!pSurfaceFormats) {
1080         return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice,
1081                                                   pSurfaceInfo->surface,
1082                                                   pSurfaceFormatCount, nullptr);
1083     }
1084 
1085     // temp vector for forwarding; we'll marshal it into the pSurfaceFormats
1086     // after the call.
1087     std::vector<VkSurfaceFormatKHR> surface_formats(*pSurfaceFormatCount);
1088     VkResult result = GetPhysicalDeviceSurfaceFormatsKHR(
1089         physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount,
1090         surface_formats.data());
1091 
1092     if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
1093         return result;
1094     }
1095 
1096     const auto& driver = GetData(physicalDevice).driver;
1097 
1098     // marshal results individually due to stride difference.
1099     uint32_t formats_to_marshal = *pSurfaceFormatCount;
1100     for (uint32_t i = 0u; i < formats_to_marshal; i++) {
1101         pSurfaceFormats[i].surfaceFormat = surface_formats[i];
1102 
1103         // Query the compression properties for the surface format
1104         VkSurfaceFormat2KHR* pSurfaceFormat = &pSurfaceFormats[i];
1105         while (pSurfaceFormat->pNext) {
1106             pSurfaceFormat =
1107                 reinterpret_cast<VkSurfaceFormat2KHR*>(pSurfaceFormat->pNext);
1108             switch (pSurfaceFormat->sType) {
1109                 case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT: {
1110                     VkImageCompressionPropertiesEXT* surfaceCompressionProps =
1111                         reinterpret_cast<VkImageCompressionPropertiesEXT*>(
1112                             pSurfaceFormat);
1113 
1114                     if (surfaceCompressionProps &&
1115                         driver.GetPhysicalDeviceImageFormatProperties2KHR) {
1116                         VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {};
1117                         imageFormatInfo.sType =
1118                             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
1119                         imageFormatInfo.format =
1120                             pSurfaceFormats[i].surfaceFormat.format;
1121                         imageFormatInfo.type = VK_IMAGE_TYPE_2D;
1122                         imageFormatInfo.usage =
1123                             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1124                         imageFormatInfo.pNext = nullptr;
1125 
1126                         VkImageCompressionControlEXT compressionControl = {};
1127                         compressionControl.sType =
1128                             VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT;
1129                         compressionControl.pNext = imageFormatInfo.pNext;
1130                         compressionControl.flags =
1131                             VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT;
1132 
1133                         imageFormatInfo.pNext = &compressionControl;
1134 
1135                         VkImageCompressionPropertiesEXT compressionProps = {};
1136                         compressionProps.sType =
1137                             VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT;
1138                         compressionProps.pNext = nullptr;
1139 
1140                         VkImageFormatProperties2KHR imageFormatProps = {};
1141                         imageFormatProps.sType =
1142                             VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
1143                         imageFormatProps.pNext = &compressionProps;
1144 
1145                         VkResult compressionRes =
1146                             driver.GetPhysicalDeviceImageFormatProperties2KHR(
1147                                 physicalDevice, &imageFormatInfo,
1148                                 &imageFormatProps);
1149                         if (compressionRes == VK_SUCCESS) {
1150                             surfaceCompressionProps->imageCompressionFlags =
1151                                 compressionProps.imageCompressionFlags;
1152                             surfaceCompressionProps
1153                                 ->imageCompressionFixedRateFlags =
1154                                 compressionProps.imageCompressionFixedRateFlags;
1155                         } else {
1156                             return compressionRes;
1157                         }
1158                     }
1159                 } break;
1160 
1161                 default:
1162                     // Ignore all other extension structs
1163                     break;
1164             }
1165         }
1166     }
1167 
1168     return result;
1169 }
1170 
1171 VKAPI_ATTR
GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev,VkSurfaceKHR surface,uint32_t * count,VkPresentModeKHR * modes)1172 VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev,
1173                                                  VkSurfaceKHR surface,
1174                                                  uint32_t* count,
1175                                                  VkPresentModeKHR* modes) {
1176     ATRACE_CALL();
1177 
1178     int err;
1179     int query_value;
1180     std::vector<VkPresentModeKHR> present_modes;
1181     if (surface == VK_NULL_HANDLE) {
1182         const InstanceData& instance_data = GetData(pdev);
1183         ProcHook::Extension surfaceless = ProcHook::GOOGLE_surfaceless_query;
1184         bool surfaceless_enabled =
1185             instance_data.hook_extensions.test(surfaceless);
1186         if (!surfaceless_enabled) {
1187             return VK_ERROR_SURFACE_LOST_KHR;
1188         }
1189         // Support for VK_GOOGLE_surfaceless_query.  The primary purpose of this
1190         // extension for this function is for
1191         // VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR and
1192         // VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR.  We technically cannot
1193         // know if VK_PRESENT_MODE_SHARED_MAILBOX_KHR is supported without a
1194         // surface, and that cannot be relied upon.  Therefore, don't return it.
1195         present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
1196     } else {
1197         ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
1198 
1199         err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1200                             &query_value);
1201         if (err != android::OK || query_value < 0) {
1202             ALOGE(
1203                 "NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d) "
1204                 "value=%d",
1205                 strerror(-err), err, query_value);
1206             return VK_ERROR_SURFACE_LOST_KHR;
1207         }
1208         uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
1209 
1210         err =
1211             window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &query_value);
1212         if (err != android::OK || query_value < 0) {
1213             ALOGE(
1214                 "NATIVE_WINDOW_MAX_BUFFER_COUNT query failed: %s (%d) value=%d",
1215                 strerror(-err), err, query_value);
1216             return VK_ERROR_SURFACE_LOST_KHR;
1217         }
1218         uint32_t max_buffer_count = static_cast<uint32_t>(query_value);
1219 
1220         if (min_undequeued_buffers + 1 < max_buffer_count)
1221             present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR);
1222         present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
1223     }
1224 
1225     VkPhysicalDevicePresentationPropertiesANDROID present_properties;
1226     QueryPresentationProperties(pdev, &present_properties);
1227     if (present_properties.sharedImage) {
1228         present_modes.push_back(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR);
1229         present_modes.push_back(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR);
1230     }
1231 
1232     return CopyWithIncomplete(present_modes, modes, count);
1233 }
1234 
1235 VKAPI_ATTR
GetDeviceGroupPresentCapabilitiesKHR(VkDevice,VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities)1236 VkResult GetDeviceGroupPresentCapabilitiesKHR(
1237     VkDevice,
1238     VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) {
1239     ATRACE_CALL();
1240 
1241     ALOGV_IF(pDeviceGroupPresentCapabilities->sType !=
1242                  VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR,
1243              "vkGetDeviceGroupPresentCapabilitiesKHR: invalid "
1244              "VkDeviceGroupPresentCapabilitiesKHR structure type %d",
1245              pDeviceGroupPresentCapabilities->sType);
1246 
1247     memset(pDeviceGroupPresentCapabilities->presentMask, 0,
1248            sizeof(pDeviceGroupPresentCapabilities->presentMask));
1249 
1250     // assume device group of size 1
1251     pDeviceGroupPresentCapabilities->presentMask[0] = 1 << 0;
1252     pDeviceGroupPresentCapabilities->modes =
1253         VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1254 
1255     return VK_SUCCESS;
1256 }
1257 
1258 VKAPI_ATTR
GetDeviceGroupSurfacePresentModesKHR(VkDevice,VkSurfaceKHR,VkDeviceGroupPresentModeFlagsKHR * pModes)1259 VkResult GetDeviceGroupSurfacePresentModesKHR(
1260     VkDevice,
1261     VkSurfaceKHR,
1262     VkDeviceGroupPresentModeFlagsKHR* pModes) {
1263     ATRACE_CALL();
1264 
1265     *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1266     return VK_SUCCESS;
1267 }
1268 
1269 VKAPI_ATTR
GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)1270 VkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice,
1271                                                VkSurfaceKHR surface,
1272                                                uint32_t* pRectCount,
1273                                                VkRect2D* pRects) {
1274     ATRACE_CALL();
1275 
1276     if (!pRects) {
1277         *pRectCount = 1;
1278     } else {
1279         uint32_t count = std::min(*pRectCount, 1u);
1280         bool incomplete = *pRectCount < 1;
1281 
1282         *pRectCount = count;
1283 
1284         if (incomplete) {
1285             return VK_INCOMPLETE;
1286         }
1287 
1288         int err;
1289         ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
1290 
1291         int width = 0, height = 0;
1292         err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
1293         if (err != android::OK) {
1294             ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
1295                   strerror(-err), err);
1296         }
1297         err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
1298         if (err != android::OK) {
1299             ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)",
1300                   strerror(-err), err);
1301         }
1302 
1303         pRects[0].offset.x = 0;
1304         pRects[0].offset.y = 0;
1305         pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width),
1306                                       static_cast<uint32_t>(height)};
1307     }
1308     return VK_SUCCESS;
1309 }
1310 
DestroySwapchainInternal(VkDevice device,VkSwapchainKHR swapchain_handle,const VkAllocationCallbacks * allocator)1311 static void DestroySwapchainInternal(VkDevice device,
1312                                      VkSwapchainKHR swapchain_handle,
1313                                      const VkAllocationCallbacks* allocator) {
1314     ATRACE_CALL();
1315 
1316     const auto& dispatch = GetData(device).driver;
1317     Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
1318     if (!swapchain) {
1319         return;
1320     }
1321 
1322     bool active = swapchain->surface.swapchain_handle == swapchain_handle;
1323     ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr;
1324 
1325     if (window && swapchain->frame_timestamps_enabled) {
1326         native_window_enable_frame_timestamps(window, false);
1327     }
1328 
1329     for (uint32_t i = 0; i < swapchain->num_images; i++) {
1330         ReleaseSwapchainImage(device, swapchain->shared, window, -1,
1331                               swapchain->images[i], false);
1332     }
1333 
1334     if (active) {
1335         swapchain->surface.swapchain_handle = VK_NULL_HANDLE;
1336     }
1337 
1338     if (!allocator) {
1339         allocator = &GetData(device).allocator;
1340     }
1341 
1342     swapchain->~Swapchain();
1343     allocator->pfnFree(allocator->pUserData, swapchain);
1344 }
1345 
1346 VKAPI_ATTR
CreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkSwapchainKHR * swapchain_handle)1347 VkResult CreateSwapchainKHR(VkDevice device,
1348                             const VkSwapchainCreateInfoKHR* create_info,
1349                             const VkAllocationCallbacks* allocator,
1350                             VkSwapchainKHR* swapchain_handle) {
1351     ATRACE_CALL();
1352 
1353     int err;
1354     VkResult result = VK_SUCCESS;
1355 
1356     ALOGV("vkCreateSwapchainKHR: surface=0x%" PRIx64
1357           " minImageCount=%u imageFormat=%u imageColorSpace=%u"
1358           " imageExtent=%ux%u imageUsage=%#x preTransform=%u presentMode=%u"
1359           " oldSwapchain=0x%" PRIx64,
1360           reinterpret_cast<uint64_t>(create_info->surface),
1361           create_info->minImageCount, create_info->imageFormat,
1362           create_info->imageColorSpace, create_info->imageExtent.width,
1363           create_info->imageExtent.height, create_info->imageUsage,
1364           create_info->preTransform, create_info->presentMode,
1365           reinterpret_cast<uint64_t>(create_info->oldSwapchain));
1366 
1367     if (!allocator)
1368         allocator = &GetData(device).allocator;
1369 
1370     android::PixelFormat native_pixel_format =
1371         GetNativePixelFormat(create_info->imageFormat);
1372     android_dataspace native_dataspace =
1373         GetNativeDataspace(create_info->imageColorSpace, native_pixel_format);
1374     if (native_dataspace == HAL_DATASPACE_UNKNOWN) {
1375         ALOGE(
1376             "CreateSwapchainKHR(VkSwapchainCreateInfoKHR.imageColorSpace = %d) "
1377             "failed: Unsupported color space",
1378             create_info->imageColorSpace);
1379         return VK_ERROR_INITIALIZATION_FAILED;
1380     }
1381 
1382     ALOGV_IF(create_info->imageArrayLayers != 1,
1383              "swapchain imageArrayLayers=%u not supported",
1384              create_info->imageArrayLayers);
1385     ALOGV_IF((create_info->preTransform & ~kSupportedTransforms) != 0,
1386              "swapchain preTransform=%#x not supported",
1387              create_info->preTransform);
1388     ALOGV_IF(!(create_info->presentMode == VK_PRESENT_MODE_FIFO_KHR ||
1389                create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ||
1390                create_info->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
1391                create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR),
1392              "swapchain presentMode=%u not supported",
1393              create_info->presentMode);
1394 
1395     Surface& surface = *SurfaceFromHandle(create_info->surface);
1396 
1397     if (surface.swapchain_handle != create_info->oldSwapchain) {
1398         ALOGV("Can't create a swapchain for VkSurfaceKHR 0x%" PRIx64
1399               " because it already has active swapchain 0x%" PRIx64
1400               " but VkSwapchainCreateInfo::oldSwapchain=0x%" PRIx64,
1401               reinterpret_cast<uint64_t>(create_info->surface),
1402               reinterpret_cast<uint64_t>(surface.swapchain_handle),
1403               reinterpret_cast<uint64_t>(create_info->oldSwapchain));
1404         return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
1405     }
1406     if (create_info->oldSwapchain != VK_NULL_HANDLE)
1407         OrphanSwapchain(device, SwapchainFromHandle(create_info->oldSwapchain));
1408 
1409     // -- Reset the native window --
1410     // The native window might have been used previously, and had its properties
1411     // changed from defaults. That will affect the answer we get for queries
1412     // like MIN_UNDEQUED_BUFFERS. Reset to a known/default state before we
1413     // attempt such queries.
1414 
1415     // The native window only allows dequeueing all buffers before any have
1416     // been queued, since after that point at least one is assumed to be in
1417     // non-FREE state at any given time. Disconnecting and re-connecting
1418     // orphans the previous buffers, getting us back to the state where we can
1419     // dequeue all buffers.
1420     //
1421     // This is not necessary if the surface was never used previously.
1422     //
1423     // TODO(http://b/134186185) recycle swapchain images more efficiently
1424     ANativeWindow* window = surface.window.get();
1425     if (surface.used_by_swapchain) {
1426         err = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
1427         ALOGW_IF(err != android::OK,
1428                  "native_window_api_disconnect failed: %s (%d)", strerror(-err),
1429                  err);
1430         err = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
1431         ALOGW_IF(err != android::OK,
1432                  "native_window_api_connect failed: %s (%d)", strerror(-err),
1433                  err);
1434     }
1435 
1436     err =
1437         window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, nsecs_t{-1});
1438     if (err != android::OK) {
1439         ALOGE("window->perform(SET_DEQUEUE_TIMEOUT) failed: %s (%d)",
1440               strerror(-err), err);
1441         return VK_ERROR_SURFACE_LOST_KHR;
1442     }
1443 
1444     int swap_interval =
1445         create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ? 0 : 1;
1446     err = window->setSwapInterval(window, swap_interval);
1447     if (err != android::OK) {
1448         ALOGE("native_window->setSwapInterval(1) failed: %s (%d)",
1449               strerror(-err), err);
1450         return VK_ERROR_SURFACE_LOST_KHR;
1451     }
1452 
1453     err = native_window_set_shared_buffer_mode(window, false);
1454     if (err != android::OK) {
1455         ALOGE("native_window_set_shared_buffer_mode(false) failed: %s (%d)",
1456               strerror(-err), err);
1457         return VK_ERROR_SURFACE_LOST_KHR;
1458     }
1459 
1460     err = native_window_set_auto_refresh(window, false);
1461     if (err != android::OK) {
1462         ALOGE("native_window_set_auto_refresh(false) failed: %s (%d)",
1463               strerror(-err), err);
1464         return VK_ERROR_SURFACE_LOST_KHR;
1465     }
1466 
1467     // -- Configure the native window --
1468 
1469     const auto& dispatch = GetData(device).driver;
1470 
1471     err = native_window_set_buffers_format(window, native_pixel_format);
1472     if (err != android::OK) {
1473         ALOGE("native_window_set_buffers_format(%s) failed: %s (%d)",
1474               decodePixelFormat(native_pixel_format).c_str(), strerror(-err), err);
1475         return VK_ERROR_SURFACE_LOST_KHR;
1476     }
1477 
1478     /* Respect consumer default dataspace upon HAL_DATASPACE_ARBITRARY. */
1479     if (native_dataspace != HAL_DATASPACE_ARBITRARY) {
1480         err = native_window_set_buffers_data_space(window, native_dataspace);
1481         if (err != android::OK) {
1482             ALOGE("native_window_set_buffers_data_space(%d) failed: %s (%d)",
1483                   native_dataspace, strerror(-err), err);
1484             return VK_ERROR_SURFACE_LOST_KHR;
1485         }
1486     }
1487 
1488     err = native_window_set_buffers_dimensions(
1489         window, static_cast<int>(create_info->imageExtent.width),
1490         static_cast<int>(create_info->imageExtent.height));
1491     if (err != android::OK) {
1492         ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
1493               create_info->imageExtent.width, create_info->imageExtent.height,
1494               strerror(-err), err);
1495         return VK_ERROR_SURFACE_LOST_KHR;
1496     }
1497 
1498     // VkSwapchainCreateInfo::preTransform indicates the transformation the app
1499     // applied during rendering. native_window_set_transform() expects the
1500     // inverse: the transform the app is requesting that the compositor perform
1501     // during composition. With native windows, pre-transform works by rendering
1502     // with the same transform the compositor is applying (as in Vulkan), but
1503     // then requesting the inverse transform, so that when the compositor does
1504     // it's job the two transforms cancel each other out and the compositor ends
1505     // up applying an identity transform to the app's buffer.
1506     err = native_window_set_buffers_transform(
1507         window, InvertTransformToNative(create_info->preTransform));
1508     if (err != android::OK) {
1509         ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
1510               InvertTransformToNative(create_info->preTransform),
1511               strerror(-err), err);
1512         return VK_ERROR_SURFACE_LOST_KHR;
1513     }
1514 
1515     err = native_window_set_scaling_mode(
1516         window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1517     if (err != android::OK) {
1518         ALOGE("native_window_set_scaling_mode(SCALE_TO_WINDOW) failed: %s (%d)",
1519               strerror(-err), err);
1520         return VK_ERROR_SURFACE_LOST_KHR;
1521     }
1522 
1523     VkSwapchainImageUsageFlagsANDROID swapchain_image_usage = 0;
1524     if (IsSharedPresentMode(create_info->presentMode)) {
1525         swapchain_image_usage |= VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID;
1526         err = native_window_set_shared_buffer_mode(window, true);
1527         if (err != android::OK) {
1528             ALOGE("native_window_set_shared_buffer_mode failed: %s (%d)", strerror(-err), err);
1529             return VK_ERROR_SURFACE_LOST_KHR;
1530         }
1531     }
1532 
1533     if (create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {
1534         err = native_window_set_auto_refresh(window, true);
1535         if (err != android::OK) {
1536             ALOGE("native_window_set_auto_refresh failed: %s (%d)", strerror(-err), err);
1537             return VK_ERROR_SURFACE_LOST_KHR;
1538         }
1539     }
1540 
1541     int query_value;
1542     err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1543                         &query_value);
1544     if (err != android::OK || query_value < 0) {
1545         ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
1546               query_value);
1547         return VK_ERROR_SURFACE_LOST_KHR;
1548     }
1549     uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
1550     const auto mailbox_num_images = std::max(3u, create_info->minImageCount);
1551     const auto requested_images =
1552         swap_interval ? create_info->minImageCount : mailbox_num_images;
1553     uint32_t num_images = requested_images - 1 + min_undequeued_buffers;
1554 
1555     // Lower layer insists that we have at least min_undequeued_buffers + 1
1556     // buffers.  This is wasteful and we'd like to relax it in the shared case,
1557     // but not all the pieces are in place for that to work yet.  Note we only
1558     // lie to the lower layer--we don't want to give the app back a swapchain
1559     // with extra images (which they can't actually use!).
1560     uint32_t min_buffer_count = min_undequeued_buffers + 1;
1561     err = native_window_set_buffer_count(
1562         window, std::max(min_buffer_count, num_images));
1563     if (err != android::OK) {
1564         ALOGE("native_window_set_buffer_count(%d) failed: %s (%d)", num_images,
1565               strerror(-err), err);
1566         return VK_ERROR_SURFACE_LOST_KHR;
1567     }
1568 
1569     // In shared mode the num_images must be one regardless of how many
1570     // buffers were allocated for the buffer queue.
1571     if (swapchain_image_usage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID) {
1572         num_images = 1;
1573     }
1574 
1575     void* usage_info_pNext = nullptr;
1576     VkImageCompressionControlEXT image_compression = {};
1577     uint64_t native_usage = 0;
1578     if (dispatch.GetSwapchainGrallocUsage4ANDROID) {
1579         ATRACE_BEGIN("GetSwapchainGrallocUsage4ANDROID");
1580         VkGrallocUsageInfo2ANDROID gralloc_usage_info = {};
1581         gralloc_usage_info.sType =
1582             VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_2_ANDROID;
1583         gralloc_usage_info.format = create_info->imageFormat;
1584         gralloc_usage_info.imageUsage = create_info->imageUsage;
1585         gralloc_usage_info.swapchainImageUsage = swapchain_image_usage;
1586 
1587         // Look through the pNext chain for an image compression control struct
1588         // if one is found AND the appropriate extensions are enabled,
1589         // append it to be the gralloc usage pNext chain
1590         const VkSwapchainCreateInfoKHR* create_infos = create_info;
1591         while (create_infos->pNext) {
1592             create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(
1593                 create_infos->pNext);
1594             switch (create_infos->sType) {
1595                 case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
1596                     const VkImageCompressionControlEXT* compression_infos =
1597                         reinterpret_cast<const VkImageCompressionControlEXT*>(
1598                             create_infos);
1599                     image_compression = *compression_infos;
1600                     image_compression.pNext = nullptr;
1601                     usage_info_pNext = &image_compression;
1602                 } break;
1603 
1604                 default:
1605                     // Ignore all other info structs
1606                     break;
1607             }
1608         }
1609         gralloc_usage_info.pNext = usage_info_pNext;
1610 
1611         result = dispatch.GetSwapchainGrallocUsage4ANDROID(
1612             device, &gralloc_usage_info, &native_usage);
1613         ATRACE_END();
1614         if (result != VK_SUCCESS) {
1615             ALOGE("vkGetSwapchainGrallocUsage4ANDROID failed: %d", result);
1616             return VK_ERROR_SURFACE_LOST_KHR;
1617         }
1618     } else if (dispatch.GetSwapchainGrallocUsage3ANDROID) {
1619         ATRACE_BEGIN("GetSwapchainGrallocUsage3ANDROID");
1620         VkGrallocUsageInfoANDROID gralloc_usage_info = {};
1621         gralloc_usage_info.sType = VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_ANDROID;
1622         gralloc_usage_info.format = create_info->imageFormat;
1623         gralloc_usage_info.imageUsage = create_info->imageUsage;
1624 
1625         // Look through the pNext chain for an image compression control struct
1626         // if one is found AND the appropriate extensions are enabled,
1627         // append it to be the gralloc usage pNext chain
1628         const VkSwapchainCreateInfoKHR* create_infos = create_info;
1629         while (create_infos->pNext) {
1630             create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(
1631                 create_infos->pNext);
1632             switch (create_infos->sType) {
1633                 case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
1634                     const VkImageCompressionControlEXT* compression_infos =
1635                         reinterpret_cast<const VkImageCompressionControlEXT*>(
1636                             create_infos);
1637                     image_compression = *compression_infos;
1638                     image_compression.pNext = nullptr;
1639                     usage_info_pNext = &image_compression;
1640                 } break;
1641 
1642                 default:
1643                     // Ignore all other info structs
1644                     break;
1645             }
1646         }
1647         gralloc_usage_info.pNext = usage_info_pNext;
1648 
1649         result = dispatch.GetSwapchainGrallocUsage3ANDROID(
1650             device, &gralloc_usage_info, &native_usage);
1651         ATRACE_END();
1652         if (result != VK_SUCCESS) {
1653             ALOGE("vkGetSwapchainGrallocUsage3ANDROID failed: %d", result);
1654             return VK_ERROR_SURFACE_LOST_KHR;
1655         }
1656     } else if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
1657         uint64_t consumer_usage, producer_usage;
1658         ATRACE_BEGIN("GetSwapchainGrallocUsage2ANDROID");
1659         result = dispatch.GetSwapchainGrallocUsage2ANDROID(
1660             device, create_info->imageFormat, create_info->imageUsage,
1661             swapchain_image_usage, &consumer_usage, &producer_usage);
1662         ATRACE_END();
1663         if (result != VK_SUCCESS) {
1664             ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result);
1665             return VK_ERROR_SURFACE_LOST_KHR;
1666         }
1667         native_usage =
1668             convertGralloc1ToBufferUsage(producer_usage, consumer_usage);
1669     } else if (dispatch.GetSwapchainGrallocUsageANDROID) {
1670         ATRACE_BEGIN("GetSwapchainGrallocUsageANDROID");
1671         int32_t legacy_usage = 0;
1672         result = dispatch.GetSwapchainGrallocUsageANDROID(
1673             device, create_info->imageFormat, create_info->imageUsage,
1674             &legacy_usage);
1675         ATRACE_END();
1676         if (result != VK_SUCCESS) {
1677             ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
1678             return VK_ERROR_SURFACE_LOST_KHR;
1679         }
1680         native_usage = static_cast<uint64_t>(legacy_usage);
1681     }
1682     native_usage |= surface.consumer_usage;
1683 
1684     bool createProtectedSwapchain = false;
1685     if (create_info->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR) {
1686         createProtectedSwapchain = true;
1687         native_usage |= BufferUsage::PROTECTED;
1688     }
1689     err = native_window_set_usage(window, native_usage);
1690     if (err != android::OK) {
1691         ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err);
1692         return VK_ERROR_SURFACE_LOST_KHR;
1693     }
1694 
1695     int transform_hint;
1696     err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT, &transform_hint);
1697     if (err != android::OK) {
1698         ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)",
1699               strerror(-err), err);
1700         return VK_ERROR_SURFACE_LOST_KHR;
1701     }
1702 
1703     int64_t refresh_duration;
1704     err = native_window_get_refresh_cycle_duration(window, &refresh_duration);
1705     if (err != android::OK) {
1706         ALOGE("native_window_get_refresh_cycle_duration query failed: %s (%d)",
1707               strerror(-err), err);
1708         return VK_ERROR_SURFACE_LOST_KHR;
1709     }
1710     // -- Allocate our Swapchain object --
1711     // After this point, we must deallocate the swapchain on error.
1712 
1713     void* mem = allocator->pfnAllocation(allocator->pUserData,
1714                                          sizeof(Swapchain), alignof(Swapchain),
1715                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1716     if (!mem)
1717         return VK_ERROR_OUT_OF_HOST_MEMORY;
1718     Swapchain* swapchain = new (mem)
1719         Swapchain(surface, num_images, create_info->presentMode,
1720                   TranslateVulkanToNativeTransform(create_info->preTransform),
1721                   refresh_duration);
1722     VkSwapchainImageCreateInfoANDROID swapchain_image_create = {
1723 #pragma clang diagnostic push
1724 #pragma clang diagnostic ignored "-Wold-style-cast"
1725         .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID,
1726 #pragma clang diagnostic pop
1727         .pNext = usage_info_pNext,
1728         .usage = swapchain_image_usage,
1729     };
1730     VkNativeBufferANDROID image_native_buffer = {
1731 #pragma clang diagnostic push
1732 #pragma clang diagnostic ignored "-Wold-style-cast"
1733         .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
1734 #pragma clang diagnostic pop
1735         .pNext = &swapchain_image_create,
1736     };
1737 
1738     VkImageCreateInfo image_create = {
1739         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1740         .pNext = nullptr,
1741         .flags = createProtectedSwapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u,
1742         .imageType = VK_IMAGE_TYPE_2D,
1743         .format = create_info->imageFormat,
1744         .extent = {
1745             create_info->imageExtent.width,
1746             create_info->imageExtent.height,
1747             1
1748         },
1749         .mipLevels = 1,
1750         .arrayLayers = 1,
1751         .samples = VK_SAMPLE_COUNT_1_BIT,
1752         .tiling = VK_IMAGE_TILING_OPTIMAL,
1753         .usage = create_info->imageUsage,
1754         .sharingMode = create_info->imageSharingMode,
1755         .queueFamilyIndexCount = create_info->queueFamilyIndexCount,
1756         .pQueueFamilyIndices = create_info->pQueueFamilyIndices,
1757     };
1758 
1759     // Note: don't do deferred allocation for shared present modes. There's only one buffer
1760     // involved so very little benefit.
1761     if ((create_info->flags & VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT) &&
1762             !IsSharedPresentMode(create_info->presentMode)) {
1763         // Don't want to touch the underlying gralloc buffers yet;
1764         // instead just create unbound VkImages which will later be bound to memory inside
1765         // AcquireNextImage.
1766         VkImageSwapchainCreateInfoKHR image_swapchain_create = {
1767             .sType = VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR,
1768             .pNext = nullptr,
1769             .swapchain = HandleFromSwapchain(swapchain),
1770         };
1771         image_create.pNext = &image_swapchain_create;
1772 
1773         for (uint32_t i = 0; i < num_images; i++) {
1774             Swapchain::Image& img = swapchain->images[i];
1775             img.buffer = nullptr;
1776             img.dequeued = false;
1777 
1778             result = dispatch.CreateImage(device, &image_create, nullptr, &img.image);
1779             if (result != VK_SUCCESS) {
1780                 ALOGD("vkCreateImage w/ for deferred swapchain image failed: %u", result);
1781                 break;
1782             }
1783         }
1784     } else {
1785         // -- Dequeue all buffers and create a VkImage for each --
1786         // Any failures during or after this must cancel the dequeued buffers.
1787 
1788         for (uint32_t i = 0; i < num_images; i++) {
1789             Swapchain::Image& img = swapchain->images[i];
1790 
1791             ANativeWindowBuffer* buffer;
1792             err = window->dequeueBuffer(window, &buffer, &img.dequeue_fence);
1793             if (err != android::OK) {
1794                 ALOGE("dequeueBuffer[%u] failed: %s (%d)", i, strerror(-err), err);
1795                 switch (-err) {
1796                     case ENOMEM:
1797                         result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
1798                         break;
1799                     default:
1800                         result = VK_ERROR_SURFACE_LOST_KHR;
1801                         break;
1802                 }
1803                 break;
1804             }
1805             img.buffer = buffer;
1806             img.dequeued = true;
1807 
1808             image_native_buffer.handle = img.buffer->handle;
1809             image_native_buffer.stride = img.buffer->stride;
1810             image_native_buffer.format = img.buffer->format;
1811             image_native_buffer.usage = int(img.buffer->usage);
1812             android_convertGralloc0To1Usage(int(img.buffer->usage),
1813                 &image_native_buffer.usage2.producer,
1814                 &image_native_buffer.usage2.consumer);
1815             image_native_buffer.usage3 = img.buffer->usage;
1816             image_create.pNext = &image_native_buffer;
1817 
1818             ATRACE_BEGIN("CreateImage");
1819             result =
1820                 dispatch.CreateImage(device, &image_create, nullptr, &img.image);
1821             ATRACE_END();
1822             if (result != VK_SUCCESS) {
1823                 ALOGD("vkCreateImage w/ native buffer failed: %u", result);
1824                 break;
1825             }
1826         }
1827 
1828         // -- Cancel all buffers, returning them to the queue --
1829         // If an error occurred before, also destroy the VkImage and release the
1830         // buffer reference. Otherwise, we retain a strong reference to the buffer.
1831         for (uint32_t i = 0; i < num_images; i++) {
1832             Swapchain::Image& img = swapchain->images[i];
1833             if (img.dequeued) {
1834                 if (!swapchain->shared) {
1835                     window->cancelBuffer(window, img.buffer.get(),
1836                                          img.dequeue_fence);
1837                     img.dequeue_fence = -1;
1838                     img.dequeued = false;
1839                 }
1840             }
1841         }
1842     }
1843 
1844     if (result != VK_SUCCESS) {
1845         DestroySwapchainInternal(device, HandleFromSwapchain(swapchain),
1846                                  allocator);
1847         return result;
1848     }
1849 
1850     if (transform_hint != swapchain->pre_transform) {
1851         // Log that the app is not doing pre-rotation.
1852         android::GraphicsEnv::getInstance().setTargetStats(
1853             android::GpuStatsInfo::Stats::FALSE_PREROTATION);
1854     }
1855 
1856     // Set stats for creating a Vulkan swapchain
1857     android::GraphicsEnv::getInstance().setTargetStats(
1858         android::GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN);
1859 
1860     surface.used_by_swapchain = true;
1861     surface.swapchain_handle = HandleFromSwapchain(swapchain);
1862     *swapchain_handle = surface.swapchain_handle;
1863     return VK_SUCCESS;
1864 }
1865 
1866 VKAPI_ATTR
DestroySwapchainKHR(VkDevice device,VkSwapchainKHR swapchain_handle,const VkAllocationCallbacks * allocator)1867 void DestroySwapchainKHR(VkDevice device,
1868                          VkSwapchainKHR swapchain_handle,
1869                          const VkAllocationCallbacks* allocator) {
1870     ATRACE_CALL();
1871 
1872     DestroySwapchainInternal(device, swapchain_handle, allocator);
1873 }
1874 
1875 VKAPI_ATTR
GetSwapchainImagesKHR(VkDevice,VkSwapchainKHR swapchain_handle,uint32_t * count,VkImage * images)1876 VkResult GetSwapchainImagesKHR(VkDevice,
1877                                VkSwapchainKHR swapchain_handle,
1878                                uint32_t* count,
1879                                VkImage* images) {
1880     ATRACE_CALL();
1881 
1882     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
1883     ALOGW_IF(swapchain.surface.swapchain_handle != swapchain_handle,
1884              "getting images for non-active swapchain 0x%" PRIx64
1885              "; only dequeued image handles are valid",
1886              reinterpret_cast<uint64_t>(swapchain_handle));
1887     VkResult result = VK_SUCCESS;
1888     if (images) {
1889         uint32_t n = swapchain.num_images;
1890         if (*count < swapchain.num_images) {
1891             n = *count;
1892             result = VK_INCOMPLETE;
1893         }
1894         for (uint32_t i = 0; i < n; i++)
1895             images[i] = swapchain.images[i].image;
1896         *count = n;
1897     } else {
1898         *count = swapchain.num_images;
1899     }
1900     return result;
1901 }
1902 
1903 VKAPI_ATTR
AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchain_handle,uint64_t timeout,VkSemaphore semaphore,VkFence vk_fence,uint32_t * image_index)1904 VkResult AcquireNextImageKHR(VkDevice device,
1905                              VkSwapchainKHR swapchain_handle,
1906                              uint64_t timeout,
1907                              VkSemaphore semaphore,
1908                              VkFence vk_fence,
1909                              uint32_t* image_index) {
1910     ATRACE_CALL();
1911 
1912     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
1913     ANativeWindow* window = swapchain.surface.window.get();
1914     VkResult result;
1915     int err;
1916 
1917     if (swapchain.surface.swapchain_handle != swapchain_handle)
1918         return VK_ERROR_OUT_OF_DATE_KHR;
1919 
1920     if (swapchain.shared) {
1921         // In shared mode, we keep the buffer dequeued all the time, so we don't
1922         // want to dequeue a buffer here. Instead, just ask the driver to ensure
1923         // the semaphore and fence passed to us will be signalled.
1924         *image_index = 0;
1925         result = GetData(device).driver.AcquireImageANDROID(
1926                 device, swapchain.images[*image_index].image, -1, semaphore, vk_fence);
1927         return result;
1928     }
1929 
1930     const nsecs_t acquire_next_image_timeout =
1931         timeout > (uint64_t)std::numeric_limits<nsecs_t>::max() ? -1 : timeout;
1932     if (acquire_next_image_timeout != swapchain.acquire_next_image_timeout) {
1933         // Cache the timeout to avoid the duplicate binder cost.
1934         err = window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT,
1935                               acquire_next_image_timeout);
1936         if (err != android::OK) {
1937             ALOGE("window->perform(SET_DEQUEUE_TIMEOUT) failed: %s (%d)",
1938                   strerror(-err), err);
1939             return VK_ERROR_SURFACE_LOST_KHR;
1940         }
1941         swapchain.acquire_next_image_timeout = acquire_next_image_timeout;
1942     }
1943 
1944     ANativeWindowBuffer* buffer;
1945     int fence_fd;
1946     err = window->dequeueBuffer(window, &buffer, &fence_fd);
1947     if (err == android::TIMED_OUT || err == android::INVALID_OPERATION) {
1948         ALOGW("dequeueBuffer timed out: %s (%d)", strerror(-err), err);
1949         return timeout ? VK_TIMEOUT : VK_NOT_READY;
1950     } else if (err != android::OK) {
1951         ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
1952         return VK_ERROR_SURFACE_LOST_KHR;
1953     }
1954 
1955     uint32_t idx;
1956     for (idx = 0; idx < swapchain.num_images; idx++) {
1957         if (swapchain.images[idx].buffer.get() == buffer) {
1958             swapchain.images[idx].dequeued = true;
1959             swapchain.images[idx].dequeue_fence = fence_fd;
1960             break;
1961         }
1962     }
1963 
1964     // If this is a deferred alloc swapchain, this may be the first time we've
1965     // seen a particular buffer. If so, there should be an empty slot. Find it,
1966     // and bind the gralloc buffer to the VkImage for that slot. If there is no
1967     // empty slot, then we dequeued an unexpected buffer. Non-deferred swapchains
1968     // will also take this path, but will never have an empty slot since we
1969     // populated them all upfront.
1970     if (idx == swapchain.num_images) {
1971         for (idx = 0; idx < swapchain.num_images; idx++) {
1972             if (!swapchain.images[idx].buffer) {
1973                 // Note: this structure is technically required for
1974                 // Vulkan correctness, even though the driver is probably going
1975                 // to use everything from the VkNativeBufferANDROID below.
1976                 // This is kindof silly, but it's how we did the ANB
1977                 // side of VK_KHR_swapchain v69, so we're stuck with it unless
1978                 // we want to go tinkering with the ANB spec some more.
1979                 VkBindImageMemorySwapchainInfoKHR bimsi = {
1980                     .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
1981                     .pNext = nullptr,
1982                     .swapchain = swapchain_handle,
1983                     .imageIndex = idx,
1984                 };
1985                 VkNativeBufferANDROID nb = {
1986                     .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
1987                     .pNext = &bimsi,
1988                     .handle = buffer->handle,
1989                     .stride = buffer->stride,
1990                     .format = buffer->format,
1991                     .usage = int(buffer->usage),
1992                 };
1993                 VkBindImageMemoryInfo bimi = {
1994                     .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
1995                     .pNext = &nb,
1996                     .image = swapchain.images[idx].image,
1997                     .memory = VK_NULL_HANDLE,
1998                     .memoryOffset = 0,
1999                 };
2000                 result = GetData(device).driver.BindImageMemory2(device, 1, &bimi);
2001                 if (result != VK_SUCCESS) {
2002                     // This shouldn't really happen. If it does, something is probably
2003                     // unrecoverably wrong with the swapchain and its images. Cancel
2004                     // the buffer and declare the swapchain broken.
2005                     ALOGE("failed to do deferred gralloc buffer bind");
2006                     window->cancelBuffer(window, buffer, fence_fd);
2007                     return VK_ERROR_OUT_OF_DATE_KHR;
2008                 }
2009 
2010                 swapchain.images[idx].dequeued = true;
2011                 swapchain.images[idx].dequeue_fence = fence_fd;
2012                 swapchain.images[idx].buffer = buffer;
2013                 break;
2014             }
2015         }
2016     }
2017 
2018     // The buffer doesn't match any slot. This shouldn't normally happen, but is
2019     // possible if the bufferqueue is reconfigured behind libvulkan's back. If this
2020     // happens, just declare the swapchain to be broken and the app will recreate it.
2021     if (idx == swapchain.num_images) {
2022         ALOGE("dequeueBuffer returned unrecognized buffer");
2023         window->cancelBuffer(window, buffer, fence_fd);
2024         return VK_ERROR_OUT_OF_DATE_KHR;
2025     }
2026 
2027     int fence_clone = -1;
2028     if (fence_fd != -1) {
2029         fence_clone = dup(fence_fd);
2030         if (fence_clone == -1) {
2031             ALOGE("dup(fence) failed, stalling until signalled: %s (%d)",
2032                   strerror(errno), errno);
2033             sync_wait(fence_fd, -1 /* forever */);
2034         }
2035     }
2036 
2037     result = GetData(device).driver.AcquireImageANDROID(
2038         device, swapchain.images[idx].image, fence_clone, semaphore, vk_fence);
2039     if (result != VK_SUCCESS) {
2040         // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
2041         // even if the call fails. We could close it ourselves on failure, but
2042         // that would create a race condition if the driver closes it on a
2043         // failure path: some other thread might create an fd with the same
2044         // number between the time the driver closes it and the time we close
2045         // it. We must assume one of: the driver *always* closes it even on
2046         // failure, or *never* closes it on failure.
2047         window->cancelBuffer(window, buffer, fence_fd);
2048         swapchain.images[idx].dequeued = false;
2049         swapchain.images[idx].dequeue_fence = -1;
2050         return result;
2051     }
2052 
2053     *image_index = idx;
2054     return VK_SUCCESS;
2055 }
2056 
2057 VKAPI_ATTR
AcquireNextImage2KHR(VkDevice device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)2058 VkResult AcquireNextImage2KHR(VkDevice device,
2059                               const VkAcquireNextImageInfoKHR* pAcquireInfo,
2060                               uint32_t* pImageIndex) {
2061     ATRACE_CALL();
2062 
2063     return AcquireNextImageKHR(device, pAcquireInfo->swapchain,
2064                                pAcquireInfo->timeout, pAcquireInfo->semaphore,
2065                                pAcquireInfo->fence, pImageIndex);
2066 }
2067 
WorstPresentResult(VkResult a,VkResult b)2068 static VkResult WorstPresentResult(VkResult a, VkResult b) {
2069     // See the error ranking for vkQueuePresentKHR at the end of section 29.6
2070     // (in spec version 1.0.14).
2071     static const VkResult kWorstToBest[] = {
2072         VK_ERROR_DEVICE_LOST,
2073         VK_ERROR_SURFACE_LOST_KHR,
2074         VK_ERROR_OUT_OF_DATE_KHR,
2075         VK_ERROR_OUT_OF_DEVICE_MEMORY,
2076         VK_ERROR_OUT_OF_HOST_MEMORY,
2077         VK_SUBOPTIMAL_KHR,
2078     };
2079     for (auto result : kWorstToBest) {
2080         if (a == result || b == result)
2081             return result;
2082     }
2083     ALOG_ASSERT(a == VK_SUCCESS, "invalid vkQueuePresentKHR result %d", a);
2084     ALOG_ASSERT(b == VK_SUCCESS, "invalid vkQueuePresentKHR result %d", b);
2085     return a != VK_SUCCESS ? a : b;
2086 }
2087 
2088 // KHR_incremental_present aspect of QueuePresentKHR
SetSwapchainSurfaceDamage(ANativeWindow * window,const VkPresentRegionKHR * pRegion)2089 static void SetSwapchainSurfaceDamage(ANativeWindow *window, const VkPresentRegionKHR *pRegion) {
2090     std::vector<android_native_rect_t> rects(pRegion->rectangleCount);
2091     for (auto i = 0u; i < pRegion->rectangleCount; i++) {
2092         auto const& rect = pRegion->pRectangles[i];
2093         if (rect.layer > 0) {
2094             ALOGV("vkQueuePresentKHR ignoring invalid layer (%u); using layer 0 instead",
2095                 rect.layer);
2096         }
2097 
2098         rects[i].left = rect.offset.x;
2099         rects[i].bottom = rect.offset.y;
2100         rects[i].right = rect.offset.x + rect.extent.width;
2101         rects[i].top = rect.offset.y + rect.extent.height;
2102     }
2103     native_window_set_surface_damage(window, rects.data(), rects.size());
2104 }
2105 
2106 // GOOGLE_display_timing aspect of QueuePresentKHR
SetSwapchainFrameTimestamp(Swapchain & swapchain,const VkPresentTimeGOOGLE * pTime)2107 static void SetSwapchainFrameTimestamp(Swapchain &swapchain, const VkPresentTimeGOOGLE *pTime) {
2108     ANativeWindow *window = swapchain.surface.window.get();
2109 
2110     // We don't know whether the app will actually use GOOGLE_display_timing
2111     // with a particular swapchain until QueuePresent; enable it on the BQ
2112     // now if needed
2113     if (!swapchain.frame_timestamps_enabled) {
2114         ALOGV("Calling native_window_enable_frame_timestamps(true)");
2115         native_window_enable_frame_timestamps(window, true);
2116         swapchain.frame_timestamps_enabled = true;
2117     }
2118 
2119     // Record the nativeFrameId so it can be later correlated to
2120     // this present.
2121     uint64_t nativeFrameId = 0;
2122     int err = native_window_get_next_frame_id(
2123             window, &nativeFrameId);
2124     if (err != android::OK) {
2125         ALOGE("Failed to get next native frame ID.");
2126     }
2127 
2128     // Add a new timing record with the user's presentID and
2129     // the nativeFrameId.
2130     swapchain.timing.emplace_back(pTime, nativeFrameId);
2131     if (swapchain.timing.size() > MAX_TIMING_INFOS) {
2132         swapchain.timing.erase(
2133             swapchain.timing.begin(),
2134             swapchain.timing.begin() + swapchain.timing.size() - MAX_TIMING_INFOS);
2135     }
2136     if (pTime->desiredPresentTime) {
2137         ALOGV(
2138             "Calling native_window_set_buffers_timestamp(%" PRId64 ")",
2139             pTime->desiredPresentTime);
2140         native_window_set_buffers_timestamp(
2141             window,
2142             static_cast<int64_t>(pTime->desiredPresentTime));
2143     }
2144 }
2145 
2146 // EXT_swapchain_maintenance1 present mode change
SetSwapchainPresentMode(ANativeWindow * window,VkPresentModeKHR mode)2147 static bool SetSwapchainPresentMode(ANativeWindow *window, VkPresentModeKHR mode) {
2148     // There is no dynamic switching between non-shared present modes.
2149     // All we support is switching between demand and continuous refresh.
2150     if (!IsSharedPresentMode(mode))
2151         return true;
2152 
2153     int err = native_window_set_auto_refresh(window,
2154             mode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR);
2155     if (err != android::OK) {
2156         ALOGE("native_window_set_auto_refresh() failed: %s (%d)",
2157               strerror(-err), err);
2158         return false;
2159     }
2160 
2161     return true;
2162 }
2163 
PresentOneSwapchain(VkQueue queue,Swapchain & swapchain,uint32_t imageIndex,const VkPresentRegionKHR * pRegion,const VkPresentTimeGOOGLE * pTime,VkFence presentFence,const VkPresentModeKHR * pPresentMode,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores)2164 static VkResult PresentOneSwapchain(
2165         VkQueue queue,
2166         Swapchain& swapchain,
2167         uint32_t imageIndex,
2168         const VkPresentRegionKHR *pRegion,
2169         const VkPresentTimeGOOGLE *pTime,
2170         VkFence presentFence,
2171         const VkPresentModeKHR *pPresentMode,
2172         uint32_t waitSemaphoreCount,
2173         const VkSemaphore *pWaitSemaphores) {
2174 
2175     VkDevice device = GetData(queue).driver_device;
2176     const auto& dispatch = GetData(queue).driver;
2177 
2178     Swapchain::Image& img = swapchain.images[imageIndex];
2179     VkResult swapchain_result = VK_SUCCESS;
2180     VkResult result;
2181     int err;
2182 
2183     // XXX: long standing issue: QueueSignalReleaseImageANDROID consumes the
2184     // wait semaphores, so this doesn't actually work for the multiple swapchain
2185     // case.
2186     int fence = -1;
2187     result = dispatch.QueueSignalReleaseImageANDROID(
2188         queue, waitSemaphoreCount,
2189         pWaitSemaphores, img.image, &fence);
2190     if (result != VK_SUCCESS) {
2191         ALOGE("QueueSignalReleaseImageANDROID failed: %d", result);
2192         swapchain_result = result;
2193     }
2194     if (img.release_fence >= 0)
2195         close(img.release_fence);
2196     img.release_fence = fence < 0 ? -1 : dup(fence);
2197 
2198     if (swapchain.surface.swapchain_handle == HandleFromSwapchain(&swapchain)) {
2199         ANativeWindow* window = swapchain.surface.window.get();
2200         if (swapchain_result == VK_SUCCESS) {
2201 
2202             if (presentFence != VK_NULL_HANDLE) {
2203                 int fence_copy = fence < 0 ? -1 : dup(fence);
2204                 VkImportFenceFdInfoKHR iffi = {
2205                     VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
2206                     nullptr,
2207                     presentFence,
2208                     VK_FENCE_IMPORT_TEMPORARY_BIT,
2209                     VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
2210                     fence_copy,
2211                 };
2212                 if (VK_SUCCESS != dispatch.ImportFenceFdKHR(device, &iffi) && fence_copy >= 0) {
2213                     // ImportFenceFdKHR takes ownership only if it succeeds
2214                     close(fence_copy);
2215                 }
2216             }
2217 
2218             if (pRegion) {
2219                 SetSwapchainSurfaceDamage(window, pRegion);
2220             }
2221             if (pTime) {
2222                 SetSwapchainFrameTimestamp(swapchain, pTime);
2223             }
2224             if (pPresentMode) {
2225                 if (!SetSwapchainPresentMode(window, *pPresentMode))
2226                     swapchain_result = WorstPresentResult(swapchain_result,
2227                         VK_ERROR_SURFACE_LOST_KHR);
2228             }
2229 
2230             err = window->queueBuffer(window, img.buffer.get(), fence);
2231             // queueBuffer always closes fence, even on error
2232             if (err != android::OK) {
2233                 ALOGE("queueBuffer failed: %s (%d)", strerror(-err), err);
2234                 swapchain_result = WorstPresentResult(
2235                     swapchain_result, VK_ERROR_SURFACE_LOST_KHR);
2236             } else {
2237                 if (img.dequeue_fence >= 0) {
2238                     close(img.dequeue_fence);
2239                     img.dequeue_fence = -1;
2240                 }
2241                 img.dequeued = false;
2242             }
2243 
2244             // If the swapchain is in shared mode, immediately dequeue the
2245             // buffer so it can be presented again without an intervening
2246             // call to AcquireNextImageKHR. We expect to get the same buffer
2247             // back from every call to dequeueBuffer in this mode.
2248             if (swapchain.shared && swapchain_result == VK_SUCCESS) {
2249                 ANativeWindowBuffer* buffer;
2250                 int fence_fd;
2251                 err = window->dequeueBuffer(window, &buffer, &fence_fd);
2252                 if (err != android::OK) {
2253                     ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
2254                     swapchain_result = WorstPresentResult(swapchain_result,
2255                         VK_ERROR_SURFACE_LOST_KHR);
2256                 } else if (img.buffer != buffer) {
2257                     ALOGE("got wrong image back for shared swapchain");
2258                     swapchain_result = WorstPresentResult(swapchain_result,
2259                         VK_ERROR_SURFACE_LOST_KHR);
2260                 } else {
2261                     img.dequeue_fence = fence_fd;
2262                     img.dequeued = true;
2263                 }
2264             }
2265         }
2266         if (swapchain_result != VK_SUCCESS) {
2267             OrphanSwapchain(device, &swapchain);
2268         }
2269         // Android will only return VK_SUBOPTIMAL_KHR for vkQueuePresentKHR,
2270         // and only when the window's transform/rotation changes.  Extent
2271         // changes will not cause VK_SUBOPTIMAL_KHR because of the
2272         // application issues that were caused when the following transform
2273         // change was added.
2274         int window_transform_hint;
2275         err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT,
2276                             &window_transform_hint);
2277         if (err != android::OK) {
2278             ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)",
2279                   strerror(-err), err);
2280             swapchain_result = WorstPresentResult(
2281                 swapchain_result, VK_ERROR_SURFACE_LOST_KHR);
2282         }
2283         if (swapchain.pre_transform != window_transform_hint) {
2284             swapchain_result =
2285                 WorstPresentResult(swapchain_result, VK_SUBOPTIMAL_KHR);
2286         }
2287     } else {
2288         ReleaseSwapchainImage(device, swapchain.shared, nullptr, fence,
2289                               img, true);
2290         swapchain_result = VK_ERROR_OUT_OF_DATE_KHR;
2291     }
2292 
2293     return swapchain_result;
2294 }
2295 
2296 VKAPI_ATTR
QueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * present_info)2297 VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
2298     ATRACE_CALL();
2299 
2300     ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
2301              "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d",
2302              present_info->sType);
2303 
2304     VkResult final_result = VK_SUCCESS;
2305 
2306     // Look at the pNext chain for supported extension structs:
2307     const VkPresentRegionsKHR* present_regions = nullptr;
2308     const VkPresentTimesInfoGOOGLE* present_times = nullptr;
2309     const VkSwapchainPresentFenceInfoEXT* present_fences = nullptr;
2310     const VkSwapchainPresentModeInfoEXT* present_modes = nullptr;
2311 
2312     const VkPresentRegionsKHR* next =
2313         reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext);
2314     while (next) {
2315         switch (next->sType) {
2316             case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR:
2317                 present_regions = next;
2318                 break;
2319             case VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE:
2320                 present_times =
2321                     reinterpret_cast<const VkPresentTimesInfoGOOGLE*>(next);
2322                 break;
2323             case VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT:
2324                 present_fences =
2325                     reinterpret_cast<const VkSwapchainPresentFenceInfoEXT*>(next);
2326                 break;
2327             case VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT:
2328                 present_modes =
2329                     reinterpret_cast<const VkSwapchainPresentModeInfoEXT*>(next);
2330                 break;
2331             default:
2332                 ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x",
2333                       next->sType);
2334                 break;
2335         }
2336         next = reinterpret_cast<const VkPresentRegionsKHR*>(next->pNext);
2337     }
2338     ALOGV_IF(
2339         present_regions &&
2340             present_regions->swapchainCount != present_info->swapchainCount,
2341         "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount");
2342     ALOGV_IF(present_times &&
2343                  present_times->swapchainCount != present_info->swapchainCount,
2344              "VkPresentTimesInfoGOOGLE::swapchainCount != "
2345              "VkPresentInfo::swapchainCount");
2346     ALOGV_IF(present_fences &&
2347              present_fences->swapchainCount != present_info->swapchainCount,
2348              "VkSwapchainPresentFenceInfoEXT::swapchainCount != "
2349              "VkPresentInfo::swapchainCount");
2350     ALOGV_IF(present_modes &&
2351              present_modes->swapchainCount != present_info->swapchainCount,
2352              "VkSwapchainPresentModeInfoEXT::swapchainCount != "
2353              "VkPresentInfo::swapchainCount");
2354 
2355     const VkPresentRegionKHR* regions =
2356         (present_regions) ? present_regions->pRegions : nullptr;
2357     const VkPresentTimeGOOGLE* times =
2358         (present_times) ? present_times->pTimes : nullptr;
2359 
2360     for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) {
2361         Swapchain& swapchain =
2362             *SwapchainFromHandle(present_info->pSwapchains[sc]);
2363 
2364         VkResult swapchain_result = PresentOneSwapchain(
2365             queue,
2366             swapchain,
2367             present_info->pImageIndices[sc],
2368             (regions && !swapchain.mailbox_mode) ? &regions[sc] : nullptr,
2369             times ? &times[sc] : nullptr,
2370             present_fences ? present_fences->pFences[sc] : VK_NULL_HANDLE,
2371             present_modes ? &present_modes->pPresentModes[sc] : nullptr,
2372             present_info->waitSemaphoreCount,
2373             present_info->pWaitSemaphores);
2374 
2375         if (present_info->pResults)
2376             present_info->pResults[sc] = swapchain_result;
2377 
2378         if (swapchain_result != final_result)
2379             final_result = WorstPresentResult(final_result, swapchain_result);
2380     }
2381 
2382     return final_result;
2383 }
2384 
2385 VKAPI_ATTR
GetRefreshCycleDurationGOOGLE(VkDevice,VkSwapchainKHR swapchain_handle,VkRefreshCycleDurationGOOGLE * pDisplayTimingProperties)2386 VkResult GetRefreshCycleDurationGOOGLE(
2387     VkDevice,
2388     VkSwapchainKHR swapchain_handle,
2389     VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
2390     ATRACE_CALL();
2391 
2392     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
2393     VkResult result = swapchain.get_refresh_duration(pDisplayTimingProperties->refreshDuration);
2394 
2395     return result;
2396 }
2397 
2398 VKAPI_ATTR
GetPastPresentationTimingGOOGLE(VkDevice,VkSwapchainKHR swapchain_handle,uint32_t * count,VkPastPresentationTimingGOOGLE * timings)2399 VkResult GetPastPresentationTimingGOOGLE(
2400     VkDevice,
2401     VkSwapchainKHR swapchain_handle,
2402     uint32_t* count,
2403     VkPastPresentationTimingGOOGLE* timings) {
2404     ATRACE_CALL();
2405 
2406     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
2407     if (swapchain.surface.swapchain_handle != swapchain_handle) {
2408         return VK_ERROR_OUT_OF_DATE_KHR;
2409     }
2410 
2411     ANativeWindow* window = swapchain.surface.window.get();
2412     VkResult result = VK_SUCCESS;
2413 
2414     if (!swapchain.frame_timestamps_enabled) {
2415         ALOGV("Calling native_window_enable_frame_timestamps(true)");
2416         native_window_enable_frame_timestamps(window, true);
2417         swapchain.frame_timestamps_enabled = true;
2418     }
2419 
2420     if (timings) {
2421         // Get the latest ready timing count before copying, since the copied
2422         // timing info will be erased in copy_ready_timings function.
2423         uint32_t n = get_num_ready_timings(swapchain);
2424         copy_ready_timings(swapchain, count, timings);
2425         // Check the *count here against the recorded ready timing count, since
2426         // *count can be overwritten per spec describes.
2427         if (*count < n) {
2428             result = VK_INCOMPLETE;
2429         }
2430     } else {
2431         *count = get_num_ready_timings(swapchain);
2432     }
2433 
2434     return result;
2435 }
2436 
2437 VKAPI_ATTR
GetSwapchainStatusKHR(VkDevice,VkSwapchainKHR swapchain_handle)2438 VkResult GetSwapchainStatusKHR(
2439     VkDevice,
2440     VkSwapchainKHR swapchain_handle) {
2441     ATRACE_CALL();
2442 
2443     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
2444     VkResult result = VK_SUCCESS;
2445 
2446     if (swapchain.surface.swapchain_handle != swapchain_handle) {
2447         return VK_ERROR_OUT_OF_DATE_KHR;
2448     }
2449 
2450     // TODO(b/143296009): Implement this function properly
2451 
2452     return result;
2453 }
2454 
SetHdrMetadataEXT(VkDevice,uint32_t swapchainCount,const VkSwapchainKHR * pSwapchains,const VkHdrMetadataEXT * pHdrMetadataEXTs)2455 VKAPI_ATTR void SetHdrMetadataEXT(
2456     VkDevice,
2457     uint32_t swapchainCount,
2458     const VkSwapchainKHR* pSwapchains,
2459     const VkHdrMetadataEXT* pHdrMetadataEXTs) {
2460     ATRACE_CALL();
2461 
2462     for (uint32_t idx = 0; idx < swapchainCount; idx++) {
2463         Swapchain* swapchain = SwapchainFromHandle(pSwapchains[idx]);
2464         if (!swapchain)
2465             continue;
2466 
2467         if (swapchain->surface.swapchain_handle != pSwapchains[idx]) continue;
2468 
2469         ANativeWindow* window = swapchain->surface.window.get();
2470 
2471         VkHdrMetadataEXT vulkanMetadata = pHdrMetadataEXTs[idx];
2472         const android_smpte2086_metadata smpteMetdata = {
2473             {vulkanMetadata.displayPrimaryRed.x,
2474              vulkanMetadata.displayPrimaryRed.y},
2475             {vulkanMetadata.displayPrimaryGreen.x,
2476              vulkanMetadata.displayPrimaryGreen.y},
2477             {vulkanMetadata.displayPrimaryBlue.x,
2478              vulkanMetadata.displayPrimaryBlue.y},
2479             {vulkanMetadata.whitePoint.x, vulkanMetadata.whitePoint.y},
2480             vulkanMetadata.maxLuminance,
2481             vulkanMetadata.minLuminance};
2482         native_window_set_buffers_smpte2086_metadata(window, &smpteMetdata);
2483 
2484         const android_cta861_3_metadata cta8613Metadata = {
2485             vulkanMetadata.maxContentLightLevel,
2486             vulkanMetadata.maxFrameAverageLightLevel};
2487         native_window_set_buffers_cta861_3_metadata(window, &cta8613Metadata);
2488     }
2489 
2490     return;
2491 }
2492 
InterceptBindImageMemory2(uint32_t bind_info_count,const VkBindImageMemoryInfo * bind_infos,std::vector<VkNativeBufferANDROID> * out_native_buffers,std::vector<VkBindImageMemoryInfo> * out_bind_infos)2493 static void InterceptBindImageMemory2(
2494     uint32_t bind_info_count,
2495     const VkBindImageMemoryInfo* bind_infos,
2496     std::vector<VkNativeBufferANDROID>* out_native_buffers,
2497     std::vector<VkBindImageMemoryInfo>* out_bind_infos) {
2498     out_native_buffers->clear();
2499     out_bind_infos->clear();
2500 
2501     if (!bind_info_count)
2502         return;
2503 
2504     std::unordered_set<uint32_t> intercepted_indexes;
2505 
2506     for (uint32_t idx = 0; idx < bind_info_count; idx++) {
2507         auto info = reinterpret_cast<const VkBindImageMemorySwapchainInfoKHR*>(
2508             bind_infos[idx].pNext);
2509         while (info &&
2510                info->sType !=
2511                    VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR) {
2512             info = reinterpret_cast<const VkBindImageMemorySwapchainInfoKHR*>(
2513                 info->pNext);
2514         }
2515 
2516         if (!info)
2517             continue;
2518 
2519         ALOG_ASSERT(info->swapchain != VK_NULL_HANDLE,
2520                     "swapchain handle must not be NULL");
2521         const Swapchain* swapchain = SwapchainFromHandle(info->swapchain);
2522         ALOG_ASSERT(
2523             info->imageIndex < swapchain->num_images,
2524             "imageIndex must be less than the number of images in swapchain");
2525 
2526         ANativeWindowBuffer* buffer =
2527             swapchain->images[info->imageIndex].buffer.get();
2528         VkNativeBufferANDROID native_buffer = {
2529 #pragma clang diagnostic push
2530 #pragma clang diagnostic ignored "-Wold-style-cast"
2531             .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
2532 #pragma clang diagnostic pop
2533             .pNext = bind_infos[idx].pNext,
2534             .handle = buffer->handle,
2535             .stride = buffer->stride,
2536             .format = buffer->format,
2537             .usage = int(buffer->usage),
2538         };
2539         // Reserve enough space to avoid letting re-allocation invalidate the
2540         // addresses of the elements inside.
2541         out_native_buffers->reserve(bind_info_count);
2542         out_native_buffers->emplace_back(native_buffer);
2543 
2544         // Reserve the space now since we know how much is needed now.
2545         out_bind_infos->reserve(bind_info_count);
2546         out_bind_infos->emplace_back(bind_infos[idx]);
2547         out_bind_infos->back().pNext = &out_native_buffers->back();
2548 
2549         intercepted_indexes.insert(idx);
2550     }
2551 
2552     if (intercepted_indexes.empty())
2553         return;
2554 
2555     for (uint32_t idx = 0; idx < bind_info_count; idx++) {
2556         if (intercepted_indexes.count(idx))
2557             continue;
2558         out_bind_infos->emplace_back(bind_infos[idx]);
2559     }
2560 }
2561 
2562 VKAPI_ATTR
BindImageMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)2563 VkResult BindImageMemory2(VkDevice device,
2564                           uint32_t bindInfoCount,
2565                           const VkBindImageMemoryInfo* pBindInfos) {
2566     ATRACE_CALL();
2567 
2568     // out_native_buffers is for maintaining the lifecycle of the constructed
2569     // VkNativeBufferANDROID objects inside InterceptBindImageMemory2.
2570     std::vector<VkNativeBufferANDROID> out_native_buffers;
2571     std::vector<VkBindImageMemoryInfo> out_bind_infos;
2572     InterceptBindImageMemory2(bindInfoCount, pBindInfos, &out_native_buffers,
2573                               &out_bind_infos);
2574     return GetData(device).driver.BindImageMemory2(
2575         device, bindInfoCount,
2576         out_bind_infos.empty() ? pBindInfos : out_bind_infos.data());
2577 }
2578 
2579 VKAPI_ATTR
BindImageMemory2KHR(VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)2580 VkResult BindImageMemory2KHR(VkDevice device,
2581                              uint32_t bindInfoCount,
2582                              const VkBindImageMemoryInfo* pBindInfos) {
2583     ATRACE_CALL();
2584 
2585     std::vector<VkNativeBufferANDROID> out_native_buffers;
2586     std::vector<VkBindImageMemoryInfo> out_bind_infos;
2587     InterceptBindImageMemory2(bindInfoCount, pBindInfos, &out_native_buffers,
2588                               &out_bind_infos);
2589     return GetData(device).driver.BindImageMemory2KHR(
2590         device, bindInfoCount,
2591         out_bind_infos.empty() ? pBindInfos : out_bind_infos.data());
2592 }
2593 
2594 VKAPI_ATTR
ReleaseSwapchainImagesEXT(VkDevice,const VkReleaseSwapchainImagesInfoEXT * pReleaseInfo)2595 VkResult ReleaseSwapchainImagesEXT(VkDevice /*device*/,
2596                                    const VkReleaseSwapchainImagesInfoEXT* pReleaseInfo) {
2597     ATRACE_CALL();
2598 
2599     Swapchain& swapchain = *SwapchainFromHandle(pReleaseInfo->swapchain);
2600     ANativeWindow* window = swapchain.surface.window.get();
2601 
2602     // If in shared present mode, don't actually release the image back to the BQ.
2603     // Both sides share it forever.
2604     if (swapchain.shared)
2605         return VK_SUCCESS;
2606 
2607     for (uint32_t i = 0; i < pReleaseInfo->imageIndexCount; i++) {
2608         Swapchain::Image& img = swapchain.images[pReleaseInfo->pImageIndices[i]];
2609         window->cancelBuffer(window, img.buffer.get(), img.dequeue_fence);
2610 
2611         // cancelBuffer has taken ownership of the dequeue fence
2612         img.dequeue_fence = -1;
2613         // if we're still holding a release fence, get rid of it now
2614         if (img.release_fence >= 0) {
2615            close(img.release_fence);
2616            img.release_fence = -1;
2617         }
2618         img.dequeued = false;
2619     }
2620 
2621     return VK_SUCCESS;
2622 }
2623 
2624 }  // namespace driver
2625 }  // namespace vulkan
2626