1b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall/* 2b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * Copyright 2015 The Android Open Source Project 3b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * 4b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * Licensed under the Apache License, Version 2.0 (the "License"); 5b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * you may not use this file except in compliance with the License. 6b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * You may obtain a copy of the License at 7b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * 8b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * http://www.apache.org/licenses/LICENSE-2.0 9b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * 10b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * Unless required by applicable law or agreed to in writing, software 11b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * distributed under the License is distributed on an "AS IS" BASIS, 12b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * See the License for the specific language governing permissions and 14b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall * limitations under the License. 15b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall */ 16b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 17d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#include <algorithm> 18d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 197992781a574b1c52a203e9271772da16f0f06812Jesse Hall#include <grallocusage/GrallocUsageConversion.h> 207823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 216e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa#include <ui/BufferQueueDefs.h> 22d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#include <sync/sync.h> 23e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu#include <utils/StrongPointer.h> 241049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson#include <utils/Vector.h> 25d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 264a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu#include "driver.h" 27d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 285ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// TODO(jessehall): Currently we don't have a good error code for when a native 295ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// window operation fails. Just returning INITIALIZATION_FAILED for now. Later 305ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// versions (post SDK 0.9) of the API/extension have a better error code. 315ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// When updating to that version, audit all error returns. 32622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wunamespace vulkan { 33622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wunamespace driver { 345ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall 35d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hallnamespace { 36d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 3755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hallconst VkSurfaceTransformFlagsKHR kSupportedTransforms = 3855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR | 3955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR | 4055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR | 4155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR | 4255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform. 4355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR | 4455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR | 4555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR | 4655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR | 4755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR; 4855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 4955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse HallVkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransform(int native) { 5055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // Native and Vulkan transforms are isomorphic, but are represented 5155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // differently. Vulkan transforms are built up of an optional horizontal 5255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // mirror, followed by a clockwise 0/90/180/270-degree rotation. Native 5355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // transforms are built up from a horizontal flip, vertical flip, and 5455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // 90-degree rotation, all optional but always in that order. 5555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 5655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // TODO(jessehall): For now, only support pure rotations, not 5755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // flip or flip-and-rotate, until I have more time to test them and build 5855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // sample code. As far as I know we never actually use anything besides 5955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // pure rotations anyway. 6055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 6155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall switch (native) { 6255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case 0: // 0x0 6355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 6455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_H: // 0x1 6555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR; 6655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_V: // 0x2 6755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR; 6855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_ROT_180: // FLIP_H | FLIP_V 6955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR; 7055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_ROT_90: // 0x4 7155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR; 7255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_H | NATIVE_WINDOW_TRANSFORM_ROT_90: 7355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR; 7455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_ROT_90: 7555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR; 7655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_ROT_270: // FLIP_H | FLIP_V | ROT_90 7755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR; 7855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY: 7955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall default: 8055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 8155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall } 8255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall} 8355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 84178b69664a5f56470c143b5930162f285adc83faJesse Hallint InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform) { 85178b69664a5f56470c143b5930162f285adc83faJesse Hall switch (transform) { 86178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR: 87178b69664a5f56470c143b5930162f285adc83faJesse Hall return NATIVE_WINDOW_TRANSFORM_ROT_270; 88178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR: 89178b69664a5f56470c143b5930162f285adc83faJesse Hall return NATIVE_WINDOW_TRANSFORM_ROT_180; 90178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR: 91178b69664a5f56470c143b5930162f285adc83faJesse Hall return NATIVE_WINDOW_TRANSFORM_ROT_90; 92178b69664a5f56470c143b5930162f285adc83faJesse Hall // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform. 93178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR: 94178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_H; 95178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR: 96178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_H | 97178b69664a5f56470c143b5930162f285adc83faJesse Hall // NATIVE_WINDOW_TRANSFORM_ROT_90; 98178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR: 99178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_V; 100178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR: 101178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_V | 102178b69664a5f56470c143b5930162f285adc83faJesse Hall // NATIVE_WINDOW_TRANSFORM_ROT_90; 103178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR: 104178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR: 105178b69664a5f56470c143b5930162f285adc83faJesse Hall default: 106178b69664a5f56470c143b5930162f285adc83faJesse Hall return 0; 107178b69664a5f56470c143b5930162f285adc83faJesse Hall } 108178b69664a5f56470c143b5930162f285adc83faJesse Hall} 109178b69664a5f56470c143b5930162f285adc83faJesse Hall 1108a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottclass TimingInfo { 1118a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott public: 1121049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson TimingInfo() = default; 1131049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson TimingInfo(const VkPresentTimeGOOGLE* qp, uint64_t nativeFrameId) 1142c6355d7a54cb24db3f790e8c9e05fad897a6aecIan Elliott : vals_{qp->presentID, qp->desiredPresentTime, 0, 0, 0}, 1151049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson native_frame_id_(nativeFrameId) {} 1161049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson bool ready() const { 117dc96fdfa58260867c993fff78611220874753201Brian Anderson return (timestamp_desired_present_time_ != 118dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING && 119dc96fdfa58260867c993fff78611220874753201Brian Anderson timestamp_actual_present_time_ != 120dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING && 121dc96fdfa58260867c993fff78611220874753201Brian Anderson timestamp_render_complete_time_ != 122dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING && 123dc96fdfa58260867c993fff78611220874753201Brian Anderson timestamp_composition_latch_time_ != 124dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING); 1258a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 126dc96fdfa58260867c993fff78611220874753201Brian Anderson void calculate(int64_t rdur) { 127dc96fdfa58260867c993fff78611220874753201Brian Anderson bool anyTimestampInvalid = 128dc96fdfa58260867c993fff78611220874753201Brian Anderson (timestamp_actual_present_time_ == 129dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_INVALID) || 130dc96fdfa58260867c993fff78611220874753201Brian Anderson (timestamp_render_complete_time_ == 131dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_INVALID) || 132dc96fdfa58260867c993fff78611220874753201Brian Anderson (timestamp_composition_latch_time_ == 133dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_INVALID); 134dc96fdfa58260867c993fff78611220874753201Brian Anderson if (anyTimestampInvalid) { 135dc96fdfa58260867c993fff78611220874753201Brian Anderson ALOGE("Unexpectedly received invalid timestamp."); 136dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.actualPresentTime = 0; 137dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.earliestPresentTime = 0; 138dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.presentMargin = 0; 139dc96fdfa58260867c993fff78611220874753201Brian Anderson return; 140dc96fdfa58260867c993fff78611220874753201Brian Anderson } 141dc96fdfa58260867c993fff78611220874753201Brian Anderson 142dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.actualPresentTime = 143dc96fdfa58260867c993fff78611220874753201Brian Anderson static_cast<uint64_t>(timestamp_actual_present_time_); 144dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t margin = (timestamp_composition_latch_time_ - 1458a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott timestamp_render_complete_time_); 1468a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // Calculate vals_.earliestPresentTime, and potentially adjust 1478a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // vals_.presentMargin. The initial value of vals_.earliestPresentTime 1488a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // is vals_.actualPresentTime. If we can subtract rdur (the duration 1498a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // of a refresh cycle) from vals_.earliestPresentTime (and also from 1508a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // vals_.presentMargin) and still leave a positive margin, then we can 1518a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // report to the application that it could have presented earlier than 1528a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // it did (per the extension specification). If for some reason, we 1538a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // can do this subtraction repeatedly, we do, since 1548a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // vals_.earliestPresentTime really is supposed to be the "earliest". 155dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t early_time = timestamp_actual_present_time_; 1568a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott while ((margin > rdur) && 1578a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ((early_time - rdur) > timestamp_composition_latch_time_)) { 1588a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott early_time -= rdur; 1598a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott margin -= rdur; 1608a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 161dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.earliestPresentTime = static_cast<uint64_t>(early_time); 162dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.presentMargin = static_cast<uint64_t>(margin); 1638a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 1641049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson void get_values(VkPastPresentationTimingGOOGLE* values) const { 1651049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson *values = vals_; 1661049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 1678a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 1688a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott public: 1691049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson VkPastPresentationTimingGOOGLE vals_ { 0, 0, 0, 0, 0 }; 1708a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 1711049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson uint64_t native_frame_id_ { 0 }; 172dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_desired_present_time_{ NATIVE_WINDOW_TIMESTAMP_PENDING }; 173dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_actual_present_time_ { NATIVE_WINDOW_TIMESTAMP_PENDING }; 174dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_render_complete_time_ { NATIVE_WINDOW_TIMESTAMP_PENDING }; 175dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_composition_latch_time_ 176dc96fdfa58260867c993fff78611220874753201Brian Anderson { NATIVE_WINDOW_TIMESTAMP_PENDING }; 1778a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott}; 1788a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 179d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall// ---------------------------------------------------------------------------- 180d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1811356b0d3179254a7a27e88abb2d2500385469f14Jesse Hallstruct Surface { 182e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu android::sp<ANativeWindow> window; 183dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VkSwapchainKHR swapchain_handle; 1841356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall}; 1851356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 1861356b0d3179254a7a27e88abb2d2500385469f14Jesse HallVkSurfaceKHR HandleFromSurface(Surface* surface) { 1871356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface)); 1881356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 1891356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 1901356b0d3179254a7a27e88abb2d2500385469f14Jesse HallSurface* SurfaceFromHandle(VkSurfaceKHR handle) { 191a3a7a1d37bdfad56245b75edac49f8aceded321dJesse Hall return reinterpret_cast<Surface*>(handle); 1921356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 1931356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 1948a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// Maximum number of TimingInfo structs to keep per swapchain: 1958a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottenum { MAX_TIMING_INFOS = 10 }; 1968a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// Minimum number of frames to look for in the past (so we don't cause 1978a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// syncronous requests to Surface Flinger): 1988a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottenum { MIN_NUM_FRAMES_AGO = 5 }; 1998a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 200d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hallstruct Swapchain { 201ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott Swapchain(Surface& surface_, 202ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott uint32_t num_images_, 203ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott VkPresentModeKHR present_mode) 2044c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott : surface(surface_), 2054c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott num_images(num_images_), 206ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott mailbox_mode(present_mode == VK_PRESENT_MODE_MAILBOX_KHR), 207f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes frame_timestamps_enabled(false), 208f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes shared(present_mode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR || 209f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes present_mode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) { 21062c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott ANativeWindow* window = surface.window.get(); 211be833a27b36149e48f2e1b8bbb2f70dd63428419Ian Elliott native_window_get_refresh_cycle_duration( 21262c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott window, 213dc96fdfa58260867c993fff78611220874753201Brian Anderson &refresh_duration); 2148a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 215d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 2161356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall Surface& surface; 217d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t num_images; 218ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott bool mailbox_mode; 2194c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott bool frame_timestamps_enabled; 220dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t refresh_duration; 221f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes bool shared; 222d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 223d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall struct Image { 224d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {} 225d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkImage image; 226e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu android::sp<ANativeWindowBuffer> buffer; 227d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // The fence is only valid when the buffer is dequeued, and should be 228d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -1 any other time. When valid, we own the fd, and must ensure it is 229d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // closed: either by closing it explicitly when queueing the buffer, 230d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // or by passing ownership e.g. to ANativeWindow::cancelBuffer(). 231d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int dequeue_fence; 232d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall bool dequeued; 2336e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa } images[android::BufferQueueDefs::NUM_BUFFER_SLOTS]; 2348a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 2351049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson android::Vector<TimingInfo> timing; 236d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall}; 237d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 238d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse HallVkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain) { 239d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain)); 240d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} 241d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 242d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse HallSwapchain* SwapchainFromHandle(VkSwapchainKHR handle) { 243a3a7a1d37bdfad56245b75edac49f8aceded321dJesse Hall return reinterpret_cast<Swapchain*>(handle); 244d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} 245d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 246dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hallvoid ReleaseSwapchainImage(VkDevice device, 247dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ANativeWindow* window, 248dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall int release_fence, 249dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall Swapchain::Image& image) { 250dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(release_fence == -1 || image.dequeued, 251dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "ReleaseSwapchainImage: can't provide a release fence for " 252dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "non-dequeued images"); 253dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 254dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (image.dequeued) { 255dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (release_fence >= 0) { 256dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // We get here from vkQueuePresentKHR. The application is 257dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // responsible for creating an execution dependency chain from 258dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // vkAcquireNextImage (dequeue_fence) to vkQueuePresentKHR 259dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // (release_fence), so we can drop the dequeue_fence here. 260dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (image.dequeue_fence >= 0) 261dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall close(image.dequeue_fence); 262dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } else { 263dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // We get here during swapchain destruction, or various serious 264dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // error cases e.g. when we can't create the release_fence during 265dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // vkQueuePresentKHR. In non-error cases, the dequeue_fence should 266dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // have already signalled, since the swapchain images are supposed 267dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // to be idle before the swapchain is destroyed. In error cases, 268dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // there may be rendering in flight to the image, but since we 269dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // weren't able to create a release_fence, waiting for the 270dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // dequeue_fence is about the best we can do. 271dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall release_fence = image.dequeue_fence; 272dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 273dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.dequeue_fence = -1; 274dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 275dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (window) { 276dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall window->cancelBuffer(window, image.buffer.get(), release_fence); 277dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } else { 278dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (release_fence >= 0) { 279dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall sync_wait(release_fence, -1 /* forever */); 280dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall close(release_fence); 281dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 282dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 283dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 284dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.dequeued = false; 285dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 286dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 287dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (image.image) { 288dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall GetData(device).driver.DestroyImage(device, image.image, nullptr); 289dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.image = VK_NULL_HANDLE; 290dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 291dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 292dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.buffer.clear(); 293dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall} 294dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 295dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hallvoid OrphanSwapchain(VkDevice device, Swapchain* swapchain) { 296dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain->surface.swapchain_handle != HandleFromSwapchain(swapchain)) 297dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return; 298dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall for (uint32_t i = 0; i < swapchain->num_images; i++) { 299dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (!swapchain->images[i].dequeued) 300dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i]); 301dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 302dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain->surface.swapchain_handle = VK_NULL_HANDLE; 3038a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott swapchain->timing.clear(); 3048a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott} 3058a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 3068a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottuint32_t get_num_ready_timings(Swapchain& swapchain) { 3071049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (swapchain.timing.size() < MIN_NUM_FRAMES_AGO) { 3081049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson return 0; 3091049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3101049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3118a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott uint32_t num_ready = 0; 3121049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson const size_t num_timings = swapchain.timing.size() - MIN_NUM_FRAMES_AGO + 1; 3138a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott for (uint32_t i = 0; i < num_timings; i++) { 3141049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson TimingInfo& ti = swapchain.timing.editItemAt(i); 3151049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ti.ready()) { 3161049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // This TimingInfo is ready to be reported to the user. Add it 3171049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // to the num_ready. 3181049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson num_ready++; 3191049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson continue; 3201049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3211049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // This TimingInfo is not yet ready to be reported to the user, 3221049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // and so we should look for any available timestamps that 3231049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // might make it ready. 3241049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t desired_present_time = 0; 3251049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t render_complete_time = 0; 3261049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t composition_latch_time = 0; 3271049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t actual_present_time = 0; 3281049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Obtain timestamps: 3291049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int ret = native_window_get_frame_timestamps( 3301049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson swapchain.surface.window.get(), ti.native_frame_id_, 3311049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson &desired_present_time, &render_complete_time, 3321049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson &composition_latch_time, 3331049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&first_composition_start_time, 3341049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&last_composition_start_time, 3351049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&composition_finish_time, 3361049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // TODO(ianelliott): Maybe ask if this one is 3371049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // supported, at startup time (since it may not be 3381049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // supported): 3391049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson &actual_present_time, 3401049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&dequeue_ready_time, 3411049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL /*&reads_done_time*/); 3421049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3431049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ret != android::NO_ERROR) { 3441049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson continue; 3451049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3461049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3471049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Record the timestamp(s) we received, and then see if this TimingInfo 3481049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // is ready to be reported to the user: 349dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_desired_present_time_ = desired_present_time; 350dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_actual_present_time_ = actual_present_time; 351dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_render_complete_time_ = render_complete_time; 352dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_composition_latch_time_ = composition_latch_time; 3531049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3541049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ti.ready()) { 3551049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // The TimingInfo has received enough timestamps, and should now 3561049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // use those timestamps to calculate the info that should be 3571049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // reported to the user: 3581049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson ti.calculate(swapchain.refresh_duration); 3591049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson num_ready++; 3608a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3618a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3628a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott return num_ready; 3638a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott} 3648a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 3658a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// TODO(ianelliott): DEAL WITH RETURN VALUE (e.g. VK_INCOMPLETE)!!! 3668a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottvoid copy_ready_timings(Swapchain& swapchain, 3678a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott uint32_t* count, 3688a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott VkPastPresentationTimingGOOGLE* timings) { 3691049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (swapchain.timing.empty()) { 3701049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson *count = 0; 3711049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson return; 3728a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3731049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3741049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson size_t last_ready = swapchain.timing.size() - 1; 3751049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson while (!swapchain.timing[last_ready].ready()) { 3761049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (last_ready == 0) { 3771049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson *count = 0; 3781049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson return; 3791049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3801049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson last_ready--; 3811049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3821049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3831049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson uint32_t num_copied = 0; 3841049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson size_t num_to_remove = 0; 3851049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson for (uint32_t i = 0; i <= last_ready && num_copied < *count; i++) { 3861049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson const TimingInfo& ti = swapchain.timing[i]; 3871049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ti.ready()) { 3881049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson ti.get_values(&timings[num_copied]); 3898a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott num_copied++; 3908a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3911049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson num_to_remove++; 3928a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3931049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3941049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Discard old frames that aren't ready if newer frames are ready. 3951049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // We don't expect to get the timing info for those old frames. 3961049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson swapchain.timing.removeItemsAt(0, num_to_remove); 3971049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3988a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott *count = num_copied; 399dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall} 400dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 4017d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchterandroid_pixel_format GetNativePixelFormat(VkFormat format) { 4027d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter android_pixel_format native_format = HAL_PIXEL_FORMAT_RGBA_8888; 4037d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter switch (format) { 4047d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R8G8B8A8_UNORM: 4057d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R8G8B8A8_SRGB: 4067d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGBA_8888; 4077d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4087d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R5G6B5_UNORM_PACK16: 4097d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGB_565; 4107d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4117d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R16G16B16A16_SFLOAT: 4127d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGBA_FP16; 4137d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4147d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_A2R10G10B10_UNORM_PACK32: 4157d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGBA_1010102; 4167d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4177d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter default: 4187d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter ALOGV("unsupported swapchain format %d", format); 4197d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4207d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter } 4217d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return native_format; 4227d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter} 4237d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 4247d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchterandroid_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace) { 4257d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter switch (colorspace) { 4267d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: 4277d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB; 4287d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: 4297d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_DISPLAY_P3; 4307d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: 4317d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SCRGB_LINEAR; 4327d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT: 4337d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_DCI_P3_LINEAR; 4347d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: 4357d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_DCI_P3; 4367d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_BT709_LINEAR_EXT: 4377d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB_LINEAR; 4387d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_BT709_NONLINEAR_EXT: 4397d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB; 440c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_BT2020_LINEAR_EXT: 441c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter return HAL_DATASPACE_BT2020_LINEAR; 442c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_HDR10_ST2084_EXT: 4437d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return static_cast<android_dataspace>( 444c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | 445c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_RANGE_FULL); 446c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_DOLBYVISION_EXT: 4477d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return static_cast<android_dataspace>( 4487d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | 4497d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_RANGE_FULL); 450c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_HDR10_HLG_EXT: 451c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter return static_cast<android_dataspace>( 452c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG | 453c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_RANGE_FULL); 4547d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT: 4557d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return static_cast<android_dataspace>( 4567d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_STANDARD_ADOBE_RGB | 4577d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_TRANSFER_LINEAR | HAL_DATASPACE_RANGE_FULL); 4587d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: 4597d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_ADOBE_RGB; 4607d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 4617d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // Pass through is intended to allow app to provide data that is passed 4627d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // to the display system without modification. 4637d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_PASS_THROUGH_EXT: 4647d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_ARBITRARY; 4657d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 4667d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter default: 4677d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // This indicates that we don't know about the 4687d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // dataspace specified and we should indicate that 4697d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // it's unsupported 4707d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_UNKNOWN; 4717d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter } 4727d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter} 4737d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 474d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} // anonymous namespace 475b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 476e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 477622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult CreateAndroidSurfaceKHR( 478f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall VkInstance instance, 479f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, 480f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall const VkAllocationCallbacks* allocator, 481f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall VkSurfaceKHR* out_surface) { 4821f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 4834a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(instance).allocator; 4841f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), 4851f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall alignof(Surface), 4861f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 4871356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (!mem) 4881356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall return VK_ERROR_OUT_OF_HOST_MEMORY; 4891356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall Surface* surface = new (mem) Surface; 490b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 491e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu surface->window = pCreateInfo->window; 492dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall surface->swapchain_handle = VK_NULL_HANDLE; 493b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 4941356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN. 4951356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall int err = 4961356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall native_window_api_connect(surface->window.get(), NATIVE_WINDOW_API_EGL); 4971356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (err != 0) { 4981356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 4991356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // errors and translate them to valid Vulkan result codes? 5001356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err), 5011356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall err); 5021356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall surface->~Surface(); 5031f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, surface); 504762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; 5051356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall } 506b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 5071356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall *out_surface = HandleFromSurface(surface); 508b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 509b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 510b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 511e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 512622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DestroySurfaceKHR(VkInstance instance, 513622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSurfaceKHR surface_handle, 514622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator) { 5151356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall Surface* surface = SurfaceFromHandle(surface_handle); 5161356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (!surface) 5171356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall return; 5181356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL); 51942a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF(surface->swapchain_handle != VK_NULL_HANDLE, 520dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "destroyed VkSurfaceKHR 0x%" PRIx64 521dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall " has active VkSwapchainKHR 0x%" PRIx64, 522dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(surface_handle), 523dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(surface->swapchain_handle)); 5241356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall surface->~Surface(); 5251f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 5264a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(instance).allocator; 5271f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, surface); 5281356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 5291356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 530e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 531622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/, 532622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t /*queue_family*/, 533622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSurfaceKHR /*surface*/, 534622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkBool32* supported) { 5350e74f00af03b7e705774d0dcf69c2ba8ce7a15a8Jesse Hall *supported = VK_TRUE; 536a64292517b1876c4bbe5d3e62c577812f40bd922Jesse Hall return VK_SUCCESS; 5371356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 5381356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 539e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 540622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult GetPhysicalDeviceSurfaceCapabilitiesKHR( 541b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall VkPhysicalDevice /*pdev*/, 542b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall VkSurfaceKHR surface, 543b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall VkSurfaceCapabilitiesKHR* capabilities) { 544d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 5451356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall ANativeWindow* window = SurfaceFromHandle(surface)->window.get(); 546d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 547d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int width, height; 548d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width); 549d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 550d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)", 551d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(-err), err); 552762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 553d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 554d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height); 555d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 556d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)", 557d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(-err), err); 558762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 559d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 560d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 56155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall int transform_hint; 56255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT, &transform_hint); 56355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall if (err != 0) { 56455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)", 56555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall strerror(-err), err); 566762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 56755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall } 56855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 569d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Figure out what the min/max values should be. 570b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->minImageCount = 2; 571b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->maxImageCount = 3; 572d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 573fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall capabilities->currentExtent = 574fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)}; 575fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall 576d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Figure out what the max extent should be. Maximum 577d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // texture dimension maybe? 578b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->minImageExtent = VkExtent2D{1, 1}; 579b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->maxImageExtent = VkExtent2D{4096, 4096}; 580d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 581fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall capabilities->maxImageArrayLayers = 1; 582fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall 58355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall capabilities->supportedTransforms = kSupportedTransforms; 58455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall capabilities->currentTransform = 58555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall TranslateNativeToVulkanTransform(transform_hint); 586d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 587fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall // On Android, window composition is a WindowManager property, not something 588fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall // associated with the bufferqueue. It can't be changed from here. 589fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; 590d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 591d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): I think these are right, but haven't thought hard about 592d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // it. Do we need to query the driver for support of any of these? 593d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // Currently not included: 594d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // - VK_IMAGE_USAGE_DEPTH_STENCIL_BIT: definitely not 595d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT: definitely not 596b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->supportedUsageFlags = 5973fbc856120217247c72fb5ed88500000f3881c45Jesse Hall VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | 5983fbc856120217247c72fb5ed88500000f3881c45Jesse Hall VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | 5993fbc856120217247c72fb5ed88500000f3881c45Jesse Hall VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 600d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 601d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 602b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 603b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 604b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 605e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 606e278daf850a664a1f15c760c64a74d3649b6f812Courtney GoeltzenleuchterVkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, 607e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter VkSurfaceKHR surface_handle, 608622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* count, 609622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSurfaceFormatKHR* formats) { 610e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter const InstanceData& instance_data = GetData(pdev); 611e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter 6121356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // TODO(jessehall): Fill out the set of supported formats. Longer term, add 6131356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // a new gralloc method to query whether a (format, usage) pair is 6141356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // supported, and check that for each gralloc format that corresponds to a 6151356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // Vulkan format. Shorter term, just add a few more formats to the ones 6161356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // hardcoded below. 617d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 618d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall const VkSurfaceFormatKHR kFormats[] = { 6192676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, 6202676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, 6212676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall {VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, 622d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall }; 623d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall const uint32_t kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); 624e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter uint32_t total_num_formats = kNumFormats; 625e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter 626e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter bool wide_color_support = false; 627e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter Surface& surface = *SurfaceFromHandle(surface_handle); 628e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter int err = native_window_get_wide_color_support(surface.window.get(), 629e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter &wide_color_support); 630e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (err) { 631e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter // Not allowed to return a more sensible error code, so do this 632e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter return VK_ERROR_OUT_OF_HOST_MEMORY; 633e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter } 634e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter ALOGV("wide_color_support is: %d", wide_color_support); 635e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter wide_color_support = 636e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter wide_color_support && 637e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace); 638e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter 639e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter const VkSurfaceFormatKHR kWideColorFormats[] = { 640bca34c90fdef4e8132ca34a3f9493ab93c603ae7Courtney Goeltzenleuchter {VK_FORMAT_R16G16B16A16_SFLOAT, 641bca34c90fdef4e8132ca34a3f9493ab93c603ae7Courtney Goeltzenleuchter VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT}, 642e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter {VK_FORMAT_A2R10G10B10_UNORM_PACK32, 643e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}, 644e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter }; 645e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter const uint32_t kNumWideColorFormats = 646e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter sizeof(kWideColorFormats) / sizeof(kWideColorFormats[0]); 647e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (wide_color_support) { 648e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter total_num_formats += kNumWideColorFormats; 649e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter } 650d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 651d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 652d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (formats) { 653e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter uint32_t out_count = 0; 654e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter uint32_t transfer_count = 0; 655e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (*count < total_num_formats) 656d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall result = VK_INCOMPLETE; 657e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter transfer_count = std::min(*count, kNumFormats); 658e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter std::copy(kFormats, kFormats + transfer_count, formats); 659e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter out_count += transfer_count; 660e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (wide_color_support) { 661e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter transfer_count = std::min(*count - out_count, kNumWideColorFormats); 662e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter std::copy(kWideColorFormats, kWideColorFormats + transfer_count, 663e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter formats + out_count); 664e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter out_count += transfer_count; 665e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter } 666e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter *count = out_count; 6677331e228f5089a619a517630351353e88d04c9b5Jesse Hall } else { 668e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter *count = total_num_formats; 669d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 670d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 671b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 672b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 673e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 6742452cf7e653c425191791a4fb546106d6a277654Chris ForbesVkResult GetPhysicalDeviceSurfaceCapabilities2KHR( 6752452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkPhysicalDevice physicalDevice, 6762452cf7e653c425191791a4fb546106d6a277654Chris Forbes const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, 6772452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkSurfaceCapabilities2KHR* pSurfaceCapabilities) { 6782452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkResult result = GetPhysicalDeviceSurfaceCapabilitiesKHR( 6792452cf7e653c425191791a4fb546106d6a277654Chris Forbes physicalDevice, pSurfaceInfo->surface, 6802452cf7e653c425191791a4fb546106d6a277654Chris Forbes &pSurfaceCapabilities->surfaceCapabilities); 6812452cf7e653c425191791a4fb546106d6a277654Chris Forbes 68206bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes VkSurfaceCapabilities2KHR* caps = pSurfaceCapabilities; 68306bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes while (caps->pNext) { 68406bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes caps = reinterpret_cast<VkSurfaceCapabilities2KHR*>(caps->pNext); 68506bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes 68606bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes switch (caps->sType) { 68706bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes case VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR: { 68806bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes VkSharedPresentSurfaceCapabilitiesKHR* shared_caps = 68906bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes reinterpret_cast<VkSharedPresentSurfaceCapabilitiesKHR*>( 69006bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes caps); 69106bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes // Claim same set of usage flags are supported for 69206bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes // shared present modes as for other modes. 69306bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes shared_caps->sharedPresentSupportedUsageFlags = 69406bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes pSurfaceCapabilities->surfaceCapabilities 69506bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes .supportedUsageFlags; 69606bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes } break; 69706bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes 69806bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes default: 69906bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes // Ignore all other extension structs 70006bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes break; 70106bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes } 70206bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes } 70306bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes 7042452cf7e653c425191791a4fb546106d6a277654Chris Forbes return result; 7052452cf7e653c425191791a4fb546106d6a277654Chris Forbes} 7062452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7072452cf7e653c425191791a4fb546106d6a277654Chris ForbesVKAPI_ATTR 7082452cf7e653c425191791a4fb546106d6a277654Chris ForbesVkResult GetPhysicalDeviceSurfaceFormats2KHR( 7092452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkPhysicalDevice physicalDevice, 7102452cf7e653c425191791a4fb546106d6a277654Chris Forbes const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, 7112452cf7e653c425191791a4fb546106d6a277654Chris Forbes uint32_t* pSurfaceFormatCount, 7122452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkSurfaceFormat2KHR* pSurfaceFormats) { 7132452cf7e653c425191791a4fb546106d6a277654Chris Forbes if (!pSurfaceFormats) { 7142452cf7e653c425191791a4fb546106d6a277654Chris Forbes return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, 7152452cf7e653c425191791a4fb546106d6a277654Chris Forbes pSurfaceInfo->surface, 7162452cf7e653c425191791a4fb546106d6a277654Chris Forbes pSurfaceFormatCount, nullptr); 7172452cf7e653c425191791a4fb546106d6a277654Chris Forbes } else { 7182452cf7e653c425191791a4fb546106d6a277654Chris Forbes // temp vector for forwarding; we'll marshal it into the pSurfaceFormats 7192452cf7e653c425191791a4fb546106d6a277654Chris Forbes // after the call. 7202452cf7e653c425191791a4fb546106d6a277654Chris Forbes android::Vector<VkSurfaceFormatKHR> surface_formats; 7212452cf7e653c425191791a4fb546106d6a277654Chris Forbes surface_formats.resize(*pSurfaceFormatCount); 7222452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkResult result = GetPhysicalDeviceSurfaceFormatsKHR( 7232452cf7e653c425191791a4fb546106d6a277654Chris Forbes physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, 7242452cf7e653c425191791a4fb546106d6a277654Chris Forbes &surface_formats.editItemAt(0)); 7252452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7262452cf7e653c425191791a4fb546106d6a277654Chris Forbes if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 7272452cf7e653c425191791a4fb546106d6a277654Chris Forbes // marshal results individually due to stride difference. 7282452cf7e653c425191791a4fb546106d6a277654Chris Forbes // completely ignore any chained extension structs. 7292452cf7e653c425191791a4fb546106d6a277654Chris Forbes uint32_t formats_to_marshal = *pSurfaceFormatCount; 7302452cf7e653c425191791a4fb546106d6a277654Chris Forbes for (uint32_t i = 0u; i < formats_to_marshal; i++) { 7312452cf7e653c425191791a4fb546106d6a277654Chris Forbes pSurfaceFormats[i].surfaceFormat = surface_formats[i]; 7322452cf7e653c425191791a4fb546106d6a277654Chris Forbes } 7332452cf7e653c425191791a4fb546106d6a277654Chris Forbes } 7342452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7352452cf7e653c425191791a4fb546106d6a277654Chris Forbes return result; 7362452cf7e653c425191791a4fb546106d6a277654Chris Forbes } 7372452cf7e653c425191791a4fb546106d6a277654Chris Forbes} 7382452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7392452cf7e653c425191791a4fb546106d6a277654Chris ForbesVKAPI_ATTR 740e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris ForbesVkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev, 741622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSurfaceKHR /*surface*/, 742622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* count, 743622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkPresentModeKHR* modes) { 744e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes android::Vector<VkPresentModeKHR> present_modes; 745e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR); 746e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR); 747e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes 748e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes VkPhysicalDevicePresentationPropertiesANDROID present_properties; 749e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes if (QueryPresentationProperties(pdev, &present_properties)) { 750e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes if (present_properties.sharedImage) { 751e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR); 752e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR); 753e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes } 754e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes } 755e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes 756e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes uint32_t num_modes = uint32_t(present_modes.size()); 757d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 758d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 759d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (modes) { 760e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes if (*count < num_modes) 761d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall result = VK_INCOMPLETE; 762e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes *count = std::min(*count, num_modes); 763e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes std::copy(present_modes.begin(), present_modes.begin() + int(*count), modes); 7647331e228f5089a619a517630351353e88d04c9b5Jesse Hall } else { 765e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes *count = num_modes; 766d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 767d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 768b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 769b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 770e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 771622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult CreateSwapchainKHR(VkDevice device, 772622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkSwapchainCreateInfoKHR* create_info, 773622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator, 774622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR* swapchain_handle) { 775d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 776d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 777d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 7783d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGV("vkCreateSwapchainKHR: surface=0x%" PRIx64 7793d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall " minImageCount=%u imageFormat=%u imageColorSpace=%u" 7803d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall " imageExtent=%ux%u imageUsage=%#x preTransform=%u presentMode=%u" 7813d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall " oldSwapchain=0x%" PRIx64, 7823d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall reinterpret_cast<uint64_t>(create_info->surface), 7833d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->minImageCount, create_info->imageFormat, 7843d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->imageColorSpace, create_info->imageExtent.width, 7853d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->imageExtent.height, create_info->imageUsage, 7863d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->preTransform, create_info->presentMode, 7873d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall reinterpret_cast<uint64_t>(create_info->oldSwapchain)); 7883d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 7891f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 7904a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(device).allocator; 7911f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall 7927d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter android_pixel_format native_pixel_format = 7937d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter GetNativePixelFormat(create_info->imageFormat); 7947d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter android_dataspace native_dataspace = 7957d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter GetNativeDataspace(create_info->imageColorSpace); 7967d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter if (native_dataspace == HAL_DATASPACE_UNKNOWN) { 7977d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter ALOGE( 7987d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter "CreateSwapchainKHR(VkSwapchainCreateInfoKHR.imageColorSpace = %d) " 7997d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter "failed: Unsupported color space", 8007d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter create_info->imageColorSpace); 8017d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return VK_ERROR_INITIALIZATION_FAILED; 8027d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter } 8037d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 80442a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF(create_info->imageArrayLayers != 1, 805dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "swapchain imageArrayLayers=%u not supported", 806715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall create_info->imageArrayLayers); 80742a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF((create_info->preTransform & ~kSupportedTransforms) != 0, 808dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "swapchain preTransform=%#x not supported", 80955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall create_info->preTransform); 81042a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF(!(create_info->presentMode == VK_PRESENT_MODE_FIFO_KHR || 811980ad05eb054386f62395bdf16298581d2a5b09eChris Forbes create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR || 8121d5f68c10560a82fd3278e17e934ee3bff328374Chris Forbes create_info->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR || 8131d5f68c10560a82fd3278e17e934ee3bff328374Chris Forbes create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR), 814dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "swapchain presentMode=%u not supported", 8150ae0dceca1fb83e095d8de6b811aa193def238a0Jesse Hall create_info->presentMode); 816d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 8173d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall Surface& surface = *SurfaceFromHandle(create_info->surface); 8183d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 819dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (surface.swapchain_handle != create_info->oldSwapchain) { 82042a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV("Can't create a swapchain for VkSurfaceKHR 0x%" PRIx64 821dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall " because it already has active swapchain 0x%" PRIx64 822dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall " but VkSwapchainCreateInfo::oldSwapchain=0x%" PRIx64, 823dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(create_info->surface), 824dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(surface.swapchain_handle), 825dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(create_info->oldSwapchain)); 826dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; 827dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 828dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (create_info->oldSwapchain != VK_NULL_HANDLE) 829dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall OrphanSwapchain(device, SwapchainFromHandle(create_info->oldSwapchain)); 830dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 8313d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // -- Reset the native window -- 8323d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // The native window might have been used previously, and had its properties 8333d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // changed from defaults. That will affect the answer we get for queries 8343d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // like MIN_UNDEQUED_BUFFERS. Reset to a known/default state before we 8353d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // attempt such queries. 8363d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 837dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // The native window only allows dequeueing all buffers before any have 838dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // been queued, since after that point at least one is assumed to be in 839dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // non-FREE state at any given time. Disconnecting and re-connecting 840dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // orphans the previous buffers, getting us back to the state where we can 841dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // dequeue all buffers. 842dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall err = native_window_api_disconnect(surface.window.get(), 843dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall NATIVE_WINDOW_API_EGL); 844dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGW_IF(err != 0, "native_window_api_disconnect failed: %s (%d)", 845dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall strerror(-err), err); 846dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall err = 847dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall native_window_api_connect(surface.window.get(), NATIVE_WINDOW_API_EGL); 848dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGW_IF(err != 0, "native_window_api_connect failed: %s (%d)", 849dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall strerror(-err), err); 850dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 8513d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall err = native_window_set_buffer_count(surface.window.get(), 0); 8523d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall if (err != 0) { 8533d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGE("native_window_set_buffer_count(0) failed: %s (%d)", 8543d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall strerror(-err), err); 855762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 8563d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall } 8573d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 8589b7e453d71e9c17477c097f5f28f1b9d3a134998Hrishikesh Manohar int swap_interval = 8599b7e453d71e9c17477c097f5f28f1b9d3a134998Hrishikesh Manohar create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ? 0 : 1; 8609b7e453d71e9c17477c097f5f28f1b9d3a134998Hrishikesh Manohar err = surface.window->setSwapInterval(surface.window.get(), swap_interval); 8613d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall if (err != 0) { 8623d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 8633d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // errors and translate them to valid Vulkan result codes? 8643d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGE("native_window->setSwapInterval(1) failed: %s (%d)", 8653d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall strerror(-err), err); 866762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 8673d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall } 8683d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 869b8042d26de26e9212e62518b39147008937c7729Chris Forbes err = native_window_set_shared_buffer_mode(surface.window.get(), false); 870b8042d26de26e9212e62518b39147008937c7729Chris Forbes if (err != 0) { 871b8042d26de26e9212e62518b39147008937c7729Chris Forbes ALOGE("native_window_set_shared_buffer_mode(false) failed: %s (%d)", 872b8042d26de26e9212e62518b39147008937c7729Chris Forbes strerror(-err), err); 873762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 874b8042d26de26e9212e62518b39147008937c7729Chris Forbes } 875b8042d26de26e9212e62518b39147008937c7729Chris Forbes 876b8042d26de26e9212e62518b39147008937c7729Chris Forbes err = native_window_set_auto_refresh(surface.window.get(), false); 877b8042d26de26e9212e62518b39147008937c7729Chris Forbes if (err != 0) { 878b8042d26de26e9212e62518b39147008937c7729Chris Forbes ALOGE("native_window_set_auto_refresh(false) failed: %s (%d)", 879b8042d26de26e9212e62518b39147008937c7729Chris Forbes strerror(-err), err); 880762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 881b8042d26de26e9212e62518b39147008937c7729Chris Forbes } 882b8042d26de26e9212e62518b39147008937c7729Chris Forbes 883d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Configure the native window -- 884d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 8854a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu const auto& dispatch = GetData(device).driver; 88670f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall 8877d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter err = native_window_set_buffers_format(surface.window.get(), 8887d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_pixel_format); 889517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall if (err != 0) { 890517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 891517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // errors and translate them to valid Vulkan result codes? 892517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall ALOGE("native_window_set_buffers_format(%d) failed: %s (%d)", 8937d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_pixel_format, strerror(-err), err); 894762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 895517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall } 896517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall err = native_window_set_buffers_data_space(surface.window.get(), 8977d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_dataspace); 898517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall if (err != 0) { 899517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 900517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // errors and translate them to valid Vulkan result codes? 901517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall ALOGE("native_window_set_buffers_data_space(%d) failed: %s (%d)", 9027d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_dataspace, strerror(-err), err); 903762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 904517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall } 905517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall 9063dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall err = native_window_set_buffers_dimensions( 9073dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall surface.window.get(), static_cast<int>(create_info->imageExtent.width), 9083dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall static_cast<int>(create_info->imageExtent.height)); 909d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 910d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 911d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 912d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)", 913d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall create_info->imageExtent.width, create_info->imageExtent.height, 914d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(-err), err); 915762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 916d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 917d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 918178b69664a5f56470c143b5930162f285adc83faJesse Hall // VkSwapchainCreateInfo::preTransform indicates the transformation the app 919178b69664a5f56470c143b5930162f285adc83faJesse Hall // applied during rendering. native_window_set_transform() expects the 920178b69664a5f56470c143b5930162f285adc83faJesse Hall // inverse: the transform the app is requesting that the compositor perform 921178b69664a5f56470c143b5930162f285adc83faJesse Hall // during composition. With native windows, pre-transform works by rendering 922178b69664a5f56470c143b5930162f285adc83faJesse Hall // with the same transform the compositor is applying (as in Vulkan), but 923178b69664a5f56470c143b5930162f285adc83faJesse Hall // then requesting the inverse transform, so that when the compositor does 924178b69664a5f56470c143b5930162f285adc83faJesse Hall // it's job the two transforms cancel each other out and the compositor ends 925178b69664a5f56470c143b5930162f285adc83faJesse Hall // up applying an identity transform to the app's buffer. 926178b69664a5f56470c143b5930162f285adc83faJesse Hall err = native_window_set_buffers_transform( 927178b69664a5f56470c143b5930162f285adc83faJesse Hall surface.window.get(), 928178b69664a5f56470c143b5930162f285adc83faJesse Hall InvertTransformToNative(create_info->preTransform)); 929178b69664a5f56470c143b5930162f285adc83faJesse Hall if (err != 0) { 930178b69664a5f56470c143b5930162f285adc83faJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 931178b69664a5f56470c143b5930162f285adc83faJesse Hall // errors and translate them to valid Vulkan result codes? 932178b69664a5f56470c143b5930162f285adc83faJesse Hall ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)", 933178b69664a5f56470c143b5930162f285adc83faJesse Hall InvertTransformToNative(create_info->preTransform), 934178b69664a5f56470c143b5930162f285adc83faJesse Hall strerror(-err), err); 935762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 936178b69664a5f56470c143b5930162f285adc83faJesse Hall } 937178b69664a5f56470c143b5930162f285adc83faJesse Hall 938f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall err = native_window_set_scaling_mode( 9391356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall surface.window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 940f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall if (err != 0) { 941f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 942f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall // errors and translate them to valid Vulkan result codes? 943f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall ALOGE("native_window_set_scaling_mode(SCALE_TO_WINDOW) failed: %s (%d)", 944f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall strerror(-err), err); 945762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 946f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall } 947f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall 94897ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes VkSwapchainImageUsageFlagsANDROID swapchain_image_usage = 0; 94997ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (create_info->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR || 95097ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) { 95197ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes swapchain_image_usage |= VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID; 95297ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes err = native_window_set_shared_buffer_mode(surface.window.get(), true); 95397ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (err != 0) { 95497ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes ALOGE("native_window_set_shared_buffer_mode failed: %s (%d)", strerror(-err), err); 95597ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes return VK_ERROR_SURFACE_LOST_KHR; 95697ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 95797ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 95897ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes 95997ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) { 96097ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes err = native_window_set_auto_refresh(surface.window.get(), true); 96197ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (err != 0) { 96297ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes ALOGE("native_window_set_auto_refresh failed: %s (%d)", strerror(-err), err); 96397ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes return VK_ERROR_SURFACE_LOST_KHR; 96497ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 96597ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 96697ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes 967e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall int query_value; 968e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall err = surface.window->query(surface.window.get(), 969e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 970e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall &query_value); 971e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall if (err != 0 || query_value < 0) { 972d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 973d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 974e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, 975e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall query_value); 976762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 977d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 978e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value); 979d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t num_images = 980d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall (create_info->minImageCount - 1) + min_undequeued_buffers; 9812c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes 9822c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // Lower layer insists that we have at least two buffers. This is wasteful 9832c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // and we'd like to relax it in the shared case, but not all the pieces are 9842c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // in place for that to work yet. Note we only lie to the lower layer-- we 9852c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // don't want to give the app back a swapchain with extra images (which they 9862c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // can't actually use!). 9872c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes err = native_window_set_buffer_count(surface.window.get(), std::max(2u, num_images)); 988d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 989d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 990d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 9913d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGE("native_window_set_buffer_count(%d) failed: %s (%d)", num_images, 9923d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall strerror(-err), err); 993762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 994d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 995d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 99670f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall int gralloc_usage = 0; 9978c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes if (dispatch.GetSwapchainGrallocUsage2ANDROID) { 998d1abd7456e10f46200a90e8a0e5a1a8bef0a388aJesse Hall uint64_t consumer_usage, producer_usage; 999894780b0ac8f3cdb90e52c45f4fe34494131f70bCourtney Goeltzenleuchter result = dispatch.GetSwapchainGrallocUsage2ANDROID( 1000894780b0ac8f3cdb90e52c45f4fe34494131f70bCourtney Goeltzenleuchter device, create_info->imageFormat, create_info->imageUsage, 1001894780b0ac8f3cdb90e52c45f4fe34494131f70bCourtney Goeltzenleuchter swapchain_image_usage, &consumer_usage, &producer_usage); 10028c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes if (result != VK_SUCCESS) { 10038c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result); 1004762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 10058c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes } 1006d1abd7456e10f46200a90e8a0e5a1a8bef0a388aJesse Hall gralloc_usage = 10077992781a574b1c52a203e9271772da16f0f06812Jesse Hall android_convertGralloc1To0Usage(producer_usage, consumer_usage); 10088c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes } else if (dispatch.GetSwapchainGrallocUsageANDROID) { 10091f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall result = dispatch.GetSwapchainGrallocUsageANDROID( 1010f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall device, create_info->imageFormat, create_info->imageUsage, 101170f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall &gralloc_usage); 101270f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall if (result != VK_SUCCESS) { 101370f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result); 1014762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 101570f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall } 101670f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall } 10171356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall err = native_window_set_usage(surface.window.get(), gralloc_usage); 101870f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall if (err != 0) { 101970f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 102070f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall // errors and translate them to valid Vulkan result codes? 102170f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err); 1022762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 102370f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall } 1024d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1025d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Allocate our Swapchain object -- 1026d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // After this point, we must deallocate the swapchain on error. 1027d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 10281f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall void* mem = allocator->pfnAllocation(allocator->pUserData, 10291f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall sizeof(Swapchain), alignof(Swapchain), 10301f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 10311356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (!mem) 1032d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return VK_ERROR_OUT_OF_HOST_MEMORY; 1033ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott Swapchain* swapchain = 1034ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott new (mem) Swapchain(surface, num_images, create_info->presentMode); 1035d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1036d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Dequeue all buffers and create a VkImage for each -- 1037d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // Any failures during or after this must cancel the dequeued buffers. 1038d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1039b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes VkSwapchainImageCreateInfoANDROID swapchain_image_create = { 1040b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes#pragma clang diagnostic push 1041b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes#pragma clang diagnostic ignored "-Wold-style-cast" 1042b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID, 1043b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes#pragma clang diagnostic pop 1044b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .pNext = nullptr, 1045b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .usage = swapchain_image_usage, 1046b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes }; 1047d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkNativeBufferANDROID image_native_buffer = { 1048d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#pragma clang diagnostic push 1049d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#pragma clang diagnostic ignored "-Wold-style-cast" 1050d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID, 1051d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#pragma clang diagnostic pop 1052b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .pNext = &swapchain_image_create, 1053d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall }; 1054d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkImageCreateInfo image_create = { 1055d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 1056d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .pNext = &image_native_buffer, 1057d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .imageType = VK_IMAGE_TYPE_2D, 1058517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall .format = create_info->imageFormat, 1059d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .extent = {0, 0, 1}, 1060d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .mipLevels = 1, 1061a15a4bf4bafd6114ae8f28c2df2fc622cb3baaceJesse Hall .arrayLayers = 1, 1062091ed9e69400edcc549c9b11635d1a305d6b5a83Jesse Hall .samples = VK_SAMPLE_COUNT_1_BIT, 1063d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .tiling = VK_IMAGE_TILING_OPTIMAL, 1064f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall .usage = create_info->imageUsage, 1065d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .flags = 0, 1066f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall .sharingMode = create_info->imageSharingMode, 106703b6fe1b099764c6010c173c1416ea102cdfe5a4Jesse Hall .queueFamilyIndexCount = create_info->queueFamilyIndexCount, 1068d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .pQueueFamilyIndices = create_info->pQueueFamilyIndices, 1069d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall }; 1070d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1071d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (uint32_t i = 0; i < num_images; i++) { 1072d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain::Image& img = swapchain->images[i]; 1073d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1074d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ANativeWindowBuffer* buffer; 10751356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall err = surface.window->dequeueBuffer(surface.window.get(), &buffer, 10761356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall &img.dequeue_fence); 1077d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 1078d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate 1079d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // possible errors and translate them to valid Vulkan result codes? 1080d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dequeueBuffer[%u] failed: %s (%d)", i, strerror(-err), err); 1081762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan result = VK_ERROR_SURFACE_LOST_KHR; 1082d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall break; 1083d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1084e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu img.buffer = buffer; 1085d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall img.dequeued = true; 1086d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1087d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_create.extent = 10883dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall VkExtent3D{static_cast<uint32_t>(img.buffer->width), 10893dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall static_cast<uint32_t>(img.buffer->height), 10903dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall 1}; 1091d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.handle = img.buffer->handle; 1092d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.stride = img.buffer->stride; 1093d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.format = img.buffer->format; 1094d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.usage = img.buffer->usage; 10954744291270cc6c8d0838fab2bc1e954524dbfcbcChris Forbes android_convertGralloc0To1Usage(img.buffer->usage, 10964744291270cc6c8d0838fab2bc1e954524dbfcbcChris Forbes &image_native_buffer.usage2.producer, 10974744291270cc6c8d0838fab2bc1e954524dbfcbcChris Forbes &image_native_buffer.usage2.consumer); 1098d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 109903b6fe1b099764c6010c173c1416ea102cdfe5a4Jesse Hall result = 11001f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall dispatch.CreateImage(device, &image_create, nullptr, &img.image); 1101d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1102d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGD("vkCreateImage w/ native buffer failed: %u", result); 1103d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall break; 1104d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1105d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1106d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1107d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Cancel all buffers, returning them to the queue -- 1108d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // If an error occurred before, also destroy the VkImage and release the 1109d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // buffer reference. Otherwise, we retain a strong reference to the buffer. 1110d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // 1111d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): The error path here is the same as DestroySwapchain, 1112d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // but not the non-error path. Should refactor/unify. 1113e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes if (!swapchain->shared) { 1114e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes for (uint32_t i = 0; i < num_images; i++) { 1115e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes Swapchain::Image& img = swapchain->images[i]; 1116e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes if (img.dequeued) { 1117e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes surface.window->cancelBuffer(surface.window.get(), img.buffer.get(), 1118e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes img.dequeue_fence); 1119e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes img.dequeue_fence = -1; 1120e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes img.dequeued = false; 1121e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes } 1122e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes if (result != VK_SUCCESS) { 1123e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes if (img.image) 1124e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes dispatch.DestroyImage(device, img.image, nullptr); 1125e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes } 1126d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1127d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1128d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1129d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1130d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain->~Swapchain(); 11311f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, swapchain); 1132d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 1133d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1134d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1135dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall surface.swapchain_handle = HandleFromSwapchain(swapchain); 1136dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall *swapchain_handle = surface.swapchain_handle; 1137b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 1138b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1139b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1140e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1141622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DestroySwapchainKHR(VkDevice device, 1142622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR swapchain_handle, 1143622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator) { 11444a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu const auto& dispatch = GetData(device).driver; 1145d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain* swapchain = SwapchainFromHandle(swapchain_handle); 1146d78c2e8a0807ff45db4cb643cc2ef38eafd22551Daniel Koch if (!swapchain) 1147d78c2e8a0807ff45db4cb643cc2ef38eafd22551Daniel Koch return; 114842a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall bool active = swapchain->surface.swapchain_handle == swapchain_handle; 114942a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr; 1150dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 11514c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (swapchain->frame_timestamps_enabled) { 11524c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott native_window_enable_frame_timestamps(window, false); 11534c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 1154dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall for (uint32_t i = 0; i < swapchain->num_images; i++) 1155dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, window, -1, swapchain->images[i]); 115642a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall if (active) 1157dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain->surface.swapchain_handle = VK_NULL_HANDLE; 11581f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 11594a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(device).allocator; 1160d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain->~Swapchain(); 11611f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, swapchain); 1162b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1163b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1164e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1165622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult GetSwapchainImagesKHR(VkDevice, 1166622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR swapchain_handle, 1167622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* count, 1168622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkImage* images) { 1169d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 1170dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGW_IF(swapchain.surface.swapchain_handle != swapchain_handle, 1171dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "getting images for non-active swapchain 0x%" PRIx64 1172dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "; only dequeued image handles are valid", 1173dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(swapchain_handle)); 1174d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 1175d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (images) { 1176d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t n = swapchain.num_images; 1177d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (*count < swapchain.num_images) { 1178d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall n = *count; 1179d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall result = VK_INCOMPLETE; 1180d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1181d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (uint32_t i = 0; i < n; i++) 1182d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall images[i] = swapchain.images[i].image; 11837331e228f5089a619a517630351353e88d04c9b5Jesse Hall *count = n; 11847331e228f5089a619a517630351353e88d04c9b5Jesse Hall } else { 11857331e228f5089a619a517630351353e88d04c9b5Jesse Hall *count = swapchain.num_images; 1186d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1187d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 1188b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1189b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1190e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1191622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult AcquireNextImageKHR(VkDevice device, 1192622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR swapchain_handle, 1193622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint64_t timeout, 1194622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSemaphore semaphore, 1195622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkFence vk_fence, 1196622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* image_index) { 1197d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 11981356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall ANativeWindow* window = swapchain.surface.window.get(); 1199d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result; 1200d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 1201d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1202dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain.surface.swapchain_handle != swapchain_handle) 1203dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return VK_ERROR_OUT_OF_DATE_KHR; 1204dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1205d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGW_IF( 1206d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall timeout != UINT64_MAX, 1207d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall "vkAcquireNextImageKHR: non-infinite timeouts not yet implemented"); 1208d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1209c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes if (swapchain.shared) { 1210c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes // In shared mode, we keep the buffer dequeued all the time, so we don't 1211c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes // want to dequeue a buffer here. Instead, just ask the driver to ensure 1212c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes // the semaphore and fence passed to us will be signalled. 1213c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes *image_index = 0; 1214c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes result = GetData(device).driver.AcquireImageANDROID( 1215c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes device, swapchain.images[*image_index].image, -1, semaphore, vk_fence); 1216c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes return result; 1217c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes } 1218c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes 1219d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ANativeWindowBuffer* buffer; 1220061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall int fence_fd; 1221061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall err = window->dequeueBuffer(window, &buffer, &fence_fd); 1222d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 1223d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1224d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 1225d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err); 1226762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1227d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1228d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1229d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t idx; 1230d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (idx = 0; idx < swapchain.num_images; idx++) { 1231d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (swapchain.images[idx].buffer.get() == buffer) { 1232d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain.images[idx].dequeued = true; 1233061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall swapchain.images[idx].dequeue_fence = fence_fd; 1234d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall break; 1235d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1236d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1237d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (idx == swapchain.num_images) { 1238d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dequeueBuffer returned unrecognized buffer"); 1239061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall window->cancelBuffer(window, buffer, fence_fd); 1240d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return VK_ERROR_OUT_OF_DATE_KHR; 1241d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1242d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1243d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int fence_clone = -1; 1244061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall if (fence_fd != -1) { 1245061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall fence_clone = dup(fence_fd); 1246d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (fence_clone == -1) { 1247d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", 1248d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(errno), errno); 1249061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall sync_wait(fence_fd, -1 /* forever */); 1250d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1251d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1252d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 12534a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu result = GetData(device).driver.AcquireImageANDROID( 12541f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall device, swapchain.images[idx].image, fence_clone, semaphore, vk_fence); 1255d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1256ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // NOTE: we're relying on AcquireImageANDROID to close fence_clone, 1257ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // even if the call fails. We could close it ourselves on failure, but 1258ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // that would create a race condition if the driver closes it on a 1259ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // failure path: some other thread might create an fd with the same 1260ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // number between the time the driver closes it and the time we close 1261ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // it. We must assume one of: the driver *always* closes it even on 1262ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // failure, or *never* closes it on failure. 1263061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall window->cancelBuffer(window, buffer, fence_fd); 1264d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain.images[idx].dequeued = false; 1265d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain.images[idx].dequeue_fence = -1; 1266d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 1267d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1268d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1269d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall *image_index = idx; 1270b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 1271b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1272b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1273dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hallstatic VkResult WorstPresentResult(VkResult a, VkResult b) { 1274dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // See the error ranking for vkQueuePresentKHR at the end of section 29.6 1275dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // (in spec version 1.0.14). 1276dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall static const VkResult kWorstToBest[] = { 1277dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_DEVICE_LOST, 1278dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_SURFACE_LOST_KHR, 1279dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_OUT_OF_DATE_KHR, 1280dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_OUT_OF_DEVICE_MEMORY, 1281dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_OUT_OF_HOST_MEMORY, 1282dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_SUBOPTIMAL_KHR, 1283dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall }; 1284dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall for (auto result : kWorstToBest) { 1285dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (a == result || b == result) 1286dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return result; 1287dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1288dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(a == VK_SUCCESS, "invalid vkQueuePresentKHR result %d", a); 1289dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(b == VK_SUCCESS, "invalid vkQueuePresentKHR result %d", b); 1290dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return a != VK_SUCCESS ? a : b; 1291dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall} 1292dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1293e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1294622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { 1295d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 1296d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d", 1297d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall present_info->sType); 1298d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1299dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VkDevice device = GetData(queue).driver_device; 13004a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu const auto& dispatch = GetData(queue).driver; 1301d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult final_result = VK_SUCCESS; 1302dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1303cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott // Look at the pNext chain for supported extension structs: 13044c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentRegionsKHR* present_regions = nullptr; 13054c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentTimesInfoGOOGLE* present_times = nullptr; 1306cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott const VkPresentRegionsKHR* next = 1307cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext); 1308cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott while (next) { 1309cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott switch (next->sType) { 1310cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: 1311cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott present_regions = next; 1312cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott break; 131314866bbeca1ebcda93f43a3352934889a9f37c2bIan Elliott case VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE: 13144c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott present_times = 13154c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott reinterpret_cast<const VkPresentTimesInfoGOOGLE*>(next); 13164c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott break; 1317cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott default: 1318cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x", 1319cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott next->sType); 1320cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott break; 1321cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1322cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott next = reinterpret_cast<const VkPresentRegionsKHR*>(next->pNext); 1323cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1324cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott ALOGV_IF( 1325cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott present_regions && 1326cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott present_regions->swapchainCount != present_info->swapchainCount, 1327cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount"); 13284c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott ALOGV_IF(present_times && 13294c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott present_times->swapchainCount != present_info->swapchainCount, 13304c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott "VkPresentTimesInfoGOOGLE::swapchainCount != " 13314c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott "VkPresentInfo::swapchainCount"); 1332cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott const VkPresentRegionKHR* regions = 13334c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott (present_regions) ? present_regions->pRegions : nullptr; 13344c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentTimeGOOGLE* times = 13354c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott (present_times) ? present_times->pTimes : nullptr; 1336cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott const VkAllocationCallbacks* allocator = &GetData(device).allocator; 13374c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott android_native_rect_t* rects = nullptr; 1338cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott uint32_t nrects = 0; 1339cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott 1340d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { 1341d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain& swapchain = 134203b6fe1b099764c6010c173c1416ea102cdfe5a4Jesse Hall *SwapchainFromHandle(present_info->pSwapchains[sc]); 1343f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall uint32_t image_idx = present_info->pImageIndices[sc]; 13445ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall Swapchain::Image& img = swapchain.images[image_idx]; 1345ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott const VkPresentRegionKHR* region = 1346ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott (regions && !swapchain.mailbox_mode) ? ®ions[sc] : nullptr; 13474c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentTimeGOOGLE* time = (times) ? ×[sc] : nullptr; 1348dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VkResult swapchain_result = VK_SUCCESS; 1349d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result; 1350d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 1351d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1352d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int fence = -1; 1353275d76c8158c90ec5317b82cb10b094bca2b43cfJesse Hall result = dispatch.QueueSignalReleaseImageANDROID( 1354275d76c8158c90ec5317b82cb10b094bca2b43cfJesse Hall queue, present_info->waitSemaphoreCount, 1355275d76c8158c90ec5317b82cb10b094bca2b43cfJesse Hall present_info->pWaitSemaphores, img.image, &fence); 1356d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1357ab9aeef063119445b59166f781c464c64e3909dbJesse Hall ALOGE("QueueSignalReleaseImageANDROID failed: %d", result); 1358dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result = result; 1359d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1360d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1361dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain.surface.swapchain_handle == 1362dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall present_info->pSwapchains[sc]) { 1363dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ANativeWindow* window = swapchain.surface.window.get(); 1364dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain_result == VK_SUCCESS) { 1365cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (region) { 1366cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott // Process the incremental-present hint for this swapchain: 1367cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott uint32_t rcount = region->rectangleCount; 1368cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (rcount > nrects) { 1369cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott android_native_rect_t* new_rects = 1370cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott static_cast<android_native_rect_t*>( 1371cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott allocator->pfnReallocation( 1372cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott allocator->pUserData, rects, 1373cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott sizeof(android_native_rect_t) * rcount, 1374cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott alignof(android_native_rect_t), 1375cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); 1376cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (new_rects) { 1377cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott rects = new_rects; 1378cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott nrects = rcount; 1379cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } else { 1380cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott rcount = 0; // Ignore the hint for this swapchain 1381cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1382cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1383cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott for (uint32_t r = 0; r < rcount; ++r) { 1384cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (region->pRectangles[r].layer > 0) { 1385cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott ALOGV( 1386cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott "vkQueuePresentKHR ignoring invalid layer " 1387cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott "(%u); using layer 0 instead", 1388cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott region->pRectangles[r].layer); 1389cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1390cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int x = region->pRectangles[r].offset.x; 1391cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int y = region->pRectangles[r].offset.y; 1392cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int width = static_cast<int>( 1393cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott region->pRectangles[r].extent.width); 1394cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int height = static_cast<int>( 1395cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott region->pRectangles[r].extent.height); 1396cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott android_native_rect_t* cur_rect = &rects[r]; 1397cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->left = x; 1398cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->top = y + height; 1399cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->right = x + width; 1400cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->bottom = y; 1401cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1402cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott native_window_set_surface_damage(window, rects, rcount); 1403cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 14044c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (time) { 14054c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (!swapchain.frame_timestamps_enabled) { 14068a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ALOGV( 14078a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "Calling " 14088a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "native_window_enable_frame_timestamps(true)"); 14094c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott native_window_enable_frame_timestamps(window, true); 14104c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott swapchain.frame_timestamps_enabled = true; 14114c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 14121049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 14131049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Record the nativeFrameId so it can be later correlated to 14141049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // this present. 14151049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson uint64_t nativeFrameId = 0; 14161049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson err = native_window_get_next_frame_id( 14171049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson window, &nativeFrameId); 14181049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (err != android::NO_ERROR) { 14191049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson ALOGE("Failed to get next native frame ID."); 14201049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 14211049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 14221049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Add a new timing record with the user's presentID and 14231049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // the nativeFrameId. 14241049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson swapchain.timing.push_back(TimingInfo(time, nativeFrameId)); 14251049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson while (swapchain.timing.size() > MAX_TIMING_INFOS) { 14268a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott swapchain.timing.removeAt(0); 14278a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 14288a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott if (time->desiredPresentTime) { 14298a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // Set the desiredPresentTime: 14308a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ALOGV( 14318a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "Calling " 14328a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "native_window_set_buffers_timestamp(%" PRId64 ")", 14338a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott time->desiredPresentTime); 14348a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott native_window_set_buffers_timestamp( 14358a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott window, 14368a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott static_cast<int64_t>(time->desiredPresentTime)); 14378a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 14384c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 1439fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes 1440dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall err = window->queueBuffer(window, img.buffer.get(), fence); 1441dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // queueBuffer always closes fence, even on error 1442dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (err != 0) { 1443dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // TODO(jessehall): What now? We should probably cancel the 1444dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // buffer, I guess? 1445dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGE("queueBuffer failed: %s (%d)", strerror(-err), err); 1446dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result = WorstPresentResult( 1447dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result, VK_ERROR_OUT_OF_DATE_KHR); 1448dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1449dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (img.dequeue_fence >= 0) { 1450dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall close(img.dequeue_fence); 1451dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall img.dequeue_fence = -1; 1452dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1453dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall img.dequeued = false; 1454fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes 1455fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // If the swapchain is in shared mode, immediately dequeue the 1456fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // buffer so it can be presented again without an intervening 1457fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // call to AcquireNextImageKHR. We expect to get the same buffer 1458fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // back from every call to dequeueBuffer in this mode. 1459fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes if (swapchain.shared && swapchain_result == VK_SUCCESS) { 1460fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes ANativeWindowBuffer* buffer; 1461fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes int fence_fd; 1462fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes err = window->dequeueBuffer(window, &buffer, &fence_fd); 1463fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes if (err != 0) { 1464fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err); 1465fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes swapchain_result = WorstPresentResult(swapchain_result, 1466fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes VK_ERROR_SURFACE_LOST_KHR); 1467fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1468fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes else if (img.buffer != buffer) { 1469fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes ALOGE("got wrong image back for shared swapchain"); 1470fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes swapchain_result = WorstPresentResult(swapchain_result, 1471fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes VK_ERROR_SURFACE_LOST_KHR); 1472fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1473fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes else { 1474fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes img.dequeue_fence = fence_fd; 1475fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes img.dequeued = true; 1476fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1477fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1478dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1479dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain_result != VK_SUCCESS) { 1480dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, window, fence, img); 1481dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall OrphanSwapchain(device, &swapchain); 1482dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1483dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } else { 1484dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, nullptr, fence, img); 1485dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result = VK_ERROR_OUT_OF_DATE_KHR; 1486d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1487d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1488a9e5703e380d9d7f096d177adb792621a1e8d4baJesse Hall if (present_info->pResults) 1489dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall present_info->pResults[sc] = swapchain_result; 1490dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1491dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain_result != final_result) 1492dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall final_result = WorstPresentResult(final_result, swapchain_result); 1493d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1494cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (rects) { 1495cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott allocator->pfnFree(allocator->pUserData, rects); 1496cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1497d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1498d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return final_result; 1499d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} 1500b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 15014c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVKAPI_ATTR 15024c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVkResult GetRefreshCycleDurationGOOGLE( 15034c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkDevice, 150462c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott VkSwapchainKHR swapchain_handle, 15054c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { 150662c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 15074c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkResult result = VK_SUCCESS; 15084c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 1509dc96fdfa58260867c993fff78611220874753201Brian Anderson pDisplayTimingProperties->refreshDuration = 1510dc96fdfa58260867c993fff78611220874753201Brian Anderson static_cast<uint64_t>(swapchain.refresh_duration); 15114c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 15124c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott return result; 15134c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott} 15144c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 15154c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVKAPI_ATTR 15164c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVkResult GetPastPresentationTimingGOOGLE( 15174c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkDevice, 15184c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkSwapchainKHR swapchain_handle, 15194c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott uint32_t* count, 15204c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkPastPresentationTimingGOOGLE* timings) { 15214c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 15224c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott ANativeWindow* window = swapchain.surface.window.get(); 15234c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkResult result = VK_SUCCESS; 15244c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 15254c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (!swapchain.frame_timestamps_enabled) { 15268a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ALOGV("Calling native_window_enable_frame_timestamps(true)"); 15274c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott native_window_enable_frame_timestamps(window, true); 15284c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott swapchain.frame_timestamps_enabled = true; 15294c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 15304c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 15314c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (timings) { 15328a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // TODO(ianelliott): plumb return value (e.g. VK_INCOMPLETE) 15338a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott copy_ready_timings(swapchain, count, timings); 15344c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } else { 15358a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott *count = get_num_ready_timings(swapchain); 15364c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 15374c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 15384c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott return result; 15394c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott} 15404c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 15410f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris ForbesVKAPI_ATTR 15420f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris ForbesVkResult GetSwapchainStatusKHR( 15430f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes VkDevice, 15444e18ba82847bdb31504a1b005370f8df931f959dChris Forbes VkSwapchainKHR swapchain_handle) { 15454e18ba82847bdb31504a1b005370f8df931f959dChris Forbes Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 15460f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes VkResult result = VK_SUCCESS; 15470f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes 15484e18ba82847bdb31504a1b005370f8df931f959dChris Forbes if (swapchain.surface.swapchain_handle != swapchain_handle) { 15494e18ba82847bdb31504a1b005370f8df931f959dChris Forbes return VK_ERROR_OUT_OF_DATE_KHR; 15504e18ba82847bdb31504a1b005370f8df931f959dChris Forbes } 15514e18ba82847bdb31504a1b005370f8df931f959dChris Forbes 15520f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes // TODO(chrisforbes): Implement this function properly 15530f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes 15540f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes return result; 15550f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes} 15560f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes 1557d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney GoeltzenleuchterVKAPI_ATTR void SetHdrMetadataEXT( 1558d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter VkDevice device, 1559d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter uint32_t swapchainCount, 1560d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter const VkSwapchainKHR* pSwapchains, 1561d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter const VkHdrMetadataEXT* pHdrMetadataEXTs) { 1562d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter // TODO: courtneygo: implement actual function 1563d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter (void)device; 1564d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter (void)swapchainCount; 1565d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter (void)pSwapchains; 1566d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter (void)pHdrMetadataEXTs; 1567d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter return; 1568d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter} 1569d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter 1570622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu} // namespace driver 1571b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} // namespace vulkan 1572