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> 256a3c05bcfab588fd99dd8d619a53d15374e99507Mathias Agopian#include <system/window.h> 26f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch#include <android/hardware/graphics/common/1.0/types.h> 27d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 284a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu#include "driver.h" 29d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 30f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Kochusing android::hardware::graphics::common::V1_0::BufferUsage; 31f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 325ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// TODO(jessehall): Currently we don't have a good error code for when a native 335ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// window operation fails. Just returning INITIALIZATION_FAILED for now. Later 345ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// versions (post SDK 0.9) of the API/extension have a better error code. 355ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall// When updating to that version, audit all error returns. 36622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wunamespace vulkan { 37622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wunamespace driver { 385ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall 39d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hallnamespace { 40d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 4155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hallconst VkSurfaceTransformFlagsKHR kSupportedTransforms = 4255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR | 4355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR | 4455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR | 4555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR | 4655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform. 4755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR | 4855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR | 4955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR | 5055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR | 5155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR; 5255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 5355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse HallVkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransform(int native) { 5455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // Native and Vulkan transforms are isomorphic, but are represented 5555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // differently. Vulkan transforms are built up of an optional horizontal 5655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // mirror, followed by a clockwise 0/90/180/270-degree rotation. Native 5755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // transforms are built up from a horizontal flip, vertical flip, and 5855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // 90-degree rotation, all optional but always in that order. 5955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 6055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // TODO(jessehall): For now, only support pure rotations, not 6155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // flip or flip-and-rotate, until I have more time to test them and build 6255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // sample code. As far as I know we never actually use anything besides 6355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // pure rotations anyway. 6455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 6555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall switch (native) { 6655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case 0: // 0x0 6755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 6855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_H: // 0x1 6955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR; 7055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_V: // 0x2 7155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR; 7255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_ROT_180: // FLIP_H | FLIP_V 7355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR; 7455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_ROT_90: // 0x4 7555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR; 7655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_H | NATIVE_WINDOW_TRANSFORM_ROT_90: 7755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR; 7855bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // case NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_ROT_90: 7955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall // return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR; 8055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_ROT_270: // FLIP_H | FLIP_V | ROT_90 8155bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR; 8255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall case NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY: 8355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall default: 8455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 8555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall } 8655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall} 8755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 88178b69664a5f56470c143b5930162f285adc83faJesse Hallint InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform) { 89178b69664a5f56470c143b5930162f285adc83faJesse Hall switch (transform) { 90178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR: 91178b69664a5f56470c143b5930162f285adc83faJesse Hall return NATIVE_WINDOW_TRANSFORM_ROT_270; 92178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR: 93178b69664a5f56470c143b5930162f285adc83faJesse Hall return NATIVE_WINDOW_TRANSFORM_ROT_180; 94178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR: 95178b69664a5f56470c143b5930162f285adc83faJesse Hall return NATIVE_WINDOW_TRANSFORM_ROT_90; 96178b69664a5f56470c143b5930162f285adc83faJesse Hall // TODO(jessehall): See TODO in TranslateNativeToVulkanTransform. 97178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR: 98178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_H; 99178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR: 100178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_H | 101178b69664a5f56470c143b5930162f285adc83faJesse Hall // NATIVE_WINDOW_TRANSFORM_ROT_90; 102178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR: 103178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_V; 104178b69664a5f56470c143b5930162f285adc83faJesse Hall // case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR: 105178b69664a5f56470c143b5930162f285adc83faJesse Hall // return NATIVE_WINDOW_TRANSFORM_FLIP_V | 106178b69664a5f56470c143b5930162f285adc83faJesse Hall // NATIVE_WINDOW_TRANSFORM_ROT_90; 107178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR: 108178b69664a5f56470c143b5930162f285adc83faJesse Hall case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR: 109178b69664a5f56470c143b5930162f285adc83faJesse Hall default: 110178b69664a5f56470c143b5930162f285adc83faJesse Hall return 0; 111178b69664a5f56470c143b5930162f285adc83faJesse Hall } 112178b69664a5f56470c143b5930162f285adc83faJesse Hall} 113178b69664a5f56470c143b5930162f285adc83faJesse Hall 1148a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottclass TimingInfo { 1158a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott public: 1161049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson TimingInfo() = default; 1171049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson TimingInfo(const VkPresentTimeGOOGLE* qp, uint64_t nativeFrameId) 1182c6355d7a54cb24db3f790e8c9e05fad897a6aecIan Elliott : vals_{qp->presentID, qp->desiredPresentTime, 0, 0, 0}, 1191049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson native_frame_id_(nativeFrameId) {} 1201049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson bool ready() const { 121dc96fdfa58260867c993fff78611220874753201Brian Anderson return (timestamp_desired_present_time_ != 122dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING && 123dc96fdfa58260867c993fff78611220874753201Brian Anderson timestamp_actual_present_time_ != 124dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING && 125dc96fdfa58260867c993fff78611220874753201Brian Anderson timestamp_render_complete_time_ != 126dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING && 127dc96fdfa58260867c993fff78611220874753201Brian Anderson timestamp_composition_latch_time_ != 128dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_PENDING); 1298a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 130dc96fdfa58260867c993fff78611220874753201Brian Anderson void calculate(int64_t rdur) { 131dc96fdfa58260867c993fff78611220874753201Brian Anderson bool anyTimestampInvalid = 132dc96fdfa58260867c993fff78611220874753201Brian Anderson (timestamp_actual_present_time_ == 133dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_INVALID) || 134dc96fdfa58260867c993fff78611220874753201Brian Anderson (timestamp_render_complete_time_ == 135dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_INVALID) || 136dc96fdfa58260867c993fff78611220874753201Brian Anderson (timestamp_composition_latch_time_ == 137dc96fdfa58260867c993fff78611220874753201Brian Anderson NATIVE_WINDOW_TIMESTAMP_INVALID); 138dc96fdfa58260867c993fff78611220874753201Brian Anderson if (anyTimestampInvalid) { 139dc96fdfa58260867c993fff78611220874753201Brian Anderson ALOGE("Unexpectedly received invalid timestamp."); 140dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.actualPresentTime = 0; 141dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.earliestPresentTime = 0; 142dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.presentMargin = 0; 143dc96fdfa58260867c993fff78611220874753201Brian Anderson return; 144dc96fdfa58260867c993fff78611220874753201Brian Anderson } 145dc96fdfa58260867c993fff78611220874753201Brian Anderson 146dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.actualPresentTime = 147dc96fdfa58260867c993fff78611220874753201Brian Anderson static_cast<uint64_t>(timestamp_actual_present_time_); 148dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t margin = (timestamp_composition_latch_time_ - 1498a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott timestamp_render_complete_time_); 1508a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // Calculate vals_.earliestPresentTime, and potentially adjust 1518a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // vals_.presentMargin. The initial value of vals_.earliestPresentTime 1528a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // is vals_.actualPresentTime. If we can subtract rdur (the duration 1538a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // of a refresh cycle) from vals_.earliestPresentTime (and also from 1548a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // vals_.presentMargin) and still leave a positive margin, then we can 1558a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // report to the application that it could have presented earlier than 1568a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // it did (per the extension specification). If for some reason, we 1578a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // can do this subtraction repeatedly, we do, since 1588a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // vals_.earliestPresentTime really is supposed to be the "earliest". 159dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t early_time = timestamp_actual_present_time_; 1608a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott while ((margin > rdur) && 1618a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ((early_time - rdur) > timestamp_composition_latch_time_)) { 1628a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott early_time -= rdur; 1638a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott margin -= rdur; 1648a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 165dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.earliestPresentTime = static_cast<uint64_t>(early_time); 166dc96fdfa58260867c993fff78611220874753201Brian Anderson vals_.presentMargin = static_cast<uint64_t>(margin); 1678a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 1681049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson void get_values(VkPastPresentationTimingGOOGLE* values) const { 1691049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson *values = vals_; 1701049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 1718a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 1728a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott public: 1731049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson VkPastPresentationTimingGOOGLE vals_ { 0, 0, 0, 0, 0 }; 1748a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 1751049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson uint64_t native_frame_id_ { 0 }; 176dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_desired_present_time_{ NATIVE_WINDOW_TIMESTAMP_PENDING }; 177dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_actual_present_time_ { NATIVE_WINDOW_TIMESTAMP_PENDING }; 178dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_render_complete_time_ { NATIVE_WINDOW_TIMESTAMP_PENDING }; 179dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t timestamp_composition_latch_time_ 180dc96fdfa58260867c993fff78611220874753201Brian Anderson { NATIVE_WINDOW_TIMESTAMP_PENDING }; 1818a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott}; 1828a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 183d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall// ---------------------------------------------------------------------------- 184d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1851356b0d3179254a7a27e88abb2d2500385469f14Jesse Hallstruct Surface { 186e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu android::sp<ANativeWindow> window; 187dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VkSwapchainKHR swapchain_handle; 1886435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang uint64_t consumer_usage; 1891356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall}; 1901356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 1911356b0d3179254a7a27e88abb2d2500385469f14Jesse HallVkSurfaceKHR HandleFromSurface(Surface* surface) { 1921356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface)); 1931356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 1941356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 1951356b0d3179254a7a27e88abb2d2500385469f14Jesse HallSurface* SurfaceFromHandle(VkSurfaceKHR handle) { 196a3a7a1d37bdfad56245b75edac49f8aceded321dJesse Hall return reinterpret_cast<Surface*>(handle); 1971356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 1981356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 1998a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// Maximum number of TimingInfo structs to keep per swapchain: 2008a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottenum { MAX_TIMING_INFOS = 10 }; 2018a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// Minimum number of frames to look for in the past (so we don't cause 2028a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// syncronous requests to Surface Flinger): 2038a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottenum { MIN_NUM_FRAMES_AGO = 5 }; 2048a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 205d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hallstruct Swapchain { 206ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott Swapchain(Surface& surface_, 207ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott uint32_t num_images_, 208ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott VkPresentModeKHR present_mode) 2094c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott : surface(surface_), 2104c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott num_images(num_images_), 211ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott mailbox_mode(present_mode == VK_PRESENT_MODE_MAILBOX_KHR), 212f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes frame_timestamps_enabled(false), 213f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes shared(present_mode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR || 214f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes present_mode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) { 21562c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott ANativeWindow* window = surface.window.get(); 216be833a27b36149e48f2e1b8bbb2f70dd63428419Ian Elliott native_window_get_refresh_cycle_duration( 21762c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott window, 218dc96fdfa58260867c993fff78611220874753201Brian Anderson &refresh_duration); 2198a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 220d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 2211356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall Surface& surface; 222d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t num_images; 223ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott bool mailbox_mode; 2244c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott bool frame_timestamps_enabled; 225dc96fdfa58260867c993fff78611220874753201Brian Anderson int64_t refresh_duration; 226f883564b397bb97b793ccd04be89e4137ab1acd2Chris Forbes bool shared; 227d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 228d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall struct Image { 229d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {} 230d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkImage image; 231e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu android::sp<ANativeWindowBuffer> buffer; 232d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // The fence is only valid when the buffer is dequeued, and should be 233d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -1 any other time. When valid, we own the fd, and must ensure it is 234d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // closed: either by closing it explicitly when queueing the buffer, 235d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // or by passing ownership e.g. to ANativeWindow::cancelBuffer(). 236d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int dequeue_fence; 237d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall bool dequeued; 2386e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa } images[android::BufferQueueDefs::NUM_BUFFER_SLOTS]; 2398a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 2401049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson android::Vector<TimingInfo> timing; 241d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall}; 242d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 243d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse HallVkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain) { 244d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain)); 245d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} 246d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 247d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse HallSwapchain* SwapchainFromHandle(VkSwapchainKHR handle) { 248a3a7a1d37bdfad56245b75edac49f8aceded321dJesse Hall return reinterpret_cast<Swapchain*>(handle); 249d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} 250d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 251dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hallvoid ReleaseSwapchainImage(VkDevice device, 252dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ANativeWindow* window, 253dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall int release_fence, 254dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall Swapchain::Image& image) { 255dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(release_fence == -1 || image.dequeued, 256dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "ReleaseSwapchainImage: can't provide a release fence for " 257dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "non-dequeued images"); 258dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 259dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (image.dequeued) { 260dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (release_fence >= 0) { 261dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // We get here from vkQueuePresentKHR. The application is 262dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // responsible for creating an execution dependency chain from 263dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // vkAcquireNextImage (dequeue_fence) to vkQueuePresentKHR 264dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // (release_fence), so we can drop the dequeue_fence here. 265dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (image.dequeue_fence >= 0) 266dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall close(image.dequeue_fence); 267dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } else { 268dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // We get here during swapchain destruction, or various serious 269dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // error cases e.g. when we can't create the release_fence during 270dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // vkQueuePresentKHR. In non-error cases, the dequeue_fence should 271dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // have already signalled, since the swapchain images are supposed 272dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // to be idle before the swapchain is destroyed. In error cases, 273dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // there may be rendering in flight to the image, but since we 274dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // weren't able to create a release_fence, waiting for the 275dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // dequeue_fence is about the best we can do. 276dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall release_fence = image.dequeue_fence; 277dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 278dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.dequeue_fence = -1; 279dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 280dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (window) { 281dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall window->cancelBuffer(window, image.buffer.get(), release_fence); 282dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } else { 283dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (release_fence >= 0) { 284dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall sync_wait(release_fence, -1 /* forever */); 285dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall close(release_fence); 286dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 287dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 288dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 289dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.dequeued = false; 290dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 291dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 292dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (image.image) { 293dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall GetData(device).driver.DestroyImage(device, image.image, nullptr); 294dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.image = VK_NULL_HANDLE; 295dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 296dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 297dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall image.buffer.clear(); 298dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall} 299dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 300dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hallvoid OrphanSwapchain(VkDevice device, Swapchain* swapchain) { 301dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain->surface.swapchain_handle != HandleFromSwapchain(swapchain)) 302dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return; 303dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall for (uint32_t i = 0; i < swapchain->num_images; i++) { 304dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (!swapchain->images[i].dequeued) 305dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i]); 306dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 307dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain->surface.swapchain_handle = VK_NULL_HANDLE; 3088a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott swapchain->timing.clear(); 3098a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott} 3108a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 3118a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottuint32_t get_num_ready_timings(Swapchain& swapchain) { 3121049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (swapchain.timing.size() < MIN_NUM_FRAMES_AGO) { 3131049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson return 0; 3141049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3151049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3168a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott uint32_t num_ready = 0; 3171049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson const size_t num_timings = swapchain.timing.size() - MIN_NUM_FRAMES_AGO + 1; 3188a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott for (uint32_t i = 0; i < num_timings; i++) { 3191049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson TimingInfo& ti = swapchain.timing.editItemAt(i); 3201049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ti.ready()) { 3211049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // This TimingInfo is ready to be reported to the user. Add it 3221049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // to the num_ready. 3231049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson num_ready++; 3241049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson continue; 3251049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3261049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // This TimingInfo is not yet ready to be reported to the user, 3271049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // and so we should look for any available timestamps that 3281049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // might make it ready. 3291049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t desired_present_time = 0; 3301049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t render_complete_time = 0; 3311049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t composition_latch_time = 0; 3321049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int64_t actual_present_time = 0; 3331049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Obtain timestamps: 3341049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson int ret = native_window_get_frame_timestamps( 3351049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson swapchain.surface.window.get(), ti.native_frame_id_, 3361049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson &desired_present_time, &render_complete_time, 3371049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson &composition_latch_time, 3381049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&first_composition_start_time, 3391049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&last_composition_start_time, 3401049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&composition_finish_time, 3411049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // TODO(ianelliott): Maybe ask if this one is 3421049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // supported, at startup time (since it may not be 3431049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // supported): 3441049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson &actual_present_time, 3451049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL, //&dequeue_ready_time, 3461049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson NULL /*&reads_done_time*/); 3471049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3481049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ret != android::NO_ERROR) { 3491049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson continue; 3501049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3511049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3521049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Record the timestamp(s) we received, and then see if this TimingInfo 3531049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // is ready to be reported to the user: 354dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_desired_present_time_ = desired_present_time; 355dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_actual_present_time_ = actual_present_time; 356dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_render_complete_time_ = render_complete_time; 357dc96fdfa58260867c993fff78611220874753201Brian Anderson ti.timestamp_composition_latch_time_ = composition_latch_time; 3581049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3591049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ti.ready()) { 3601049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // The TimingInfo has received enough timestamps, and should now 3611049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // use those timestamps to calculate the info that should be 3621049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // reported to the user: 3631049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson ti.calculate(swapchain.refresh_duration); 3641049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson num_ready++; 3658a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3668a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3678a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott return num_ready; 3688a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott} 3698a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott 3708a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott// TODO(ianelliott): DEAL WITH RETURN VALUE (e.g. VK_INCOMPLETE)!!! 3718a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliottvoid copy_ready_timings(Swapchain& swapchain, 3728a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott uint32_t* count, 3738a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott VkPastPresentationTimingGOOGLE* timings) { 3741049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (swapchain.timing.empty()) { 3751049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson *count = 0; 3761049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson return; 3778a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3781049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3791049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson size_t last_ready = swapchain.timing.size() - 1; 3801049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson while (!swapchain.timing[last_ready].ready()) { 3811049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (last_ready == 0) { 3821049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson *count = 0; 3831049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson return; 3841049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3851049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson last_ready--; 3861049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 3871049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3881049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson uint32_t num_copied = 0; 3891049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson size_t num_to_remove = 0; 3901049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson for (uint32_t i = 0; i <= last_ready && num_copied < *count; i++) { 3911049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson const TimingInfo& ti = swapchain.timing[i]; 3921049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (ti.ready()) { 3931049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson ti.get_values(&timings[num_copied]); 3948a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott num_copied++; 3958a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3961049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson num_to_remove++; 3978a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 3981049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 3991049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Discard old frames that aren't ready if newer frames are ready. 4001049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // We don't expect to get the timing info for those old frames. 4011049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson swapchain.timing.removeItemsAt(0, num_to_remove); 4021049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 4038a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott *count = num_copied; 404dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall} 405dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 4067d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchterandroid_pixel_format GetNativePixelFormat(VkFormat format) { 4077d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter android_pixel_format native_format = HAL_PIXEL_FORMAT_RGBA_8888; 4087d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter switch (format) { 4097d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R8G8B8A8_UNORM: 4107d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R8G8B8A8_SRGB: 4117d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGBA_8888; 4127d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4137d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R5G6B5_UNORM_PACK16: 4147d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGB_565; 4157d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4167d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_R16G16B16A16_SFLOAT: 4177d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGBA_FP16; 4187d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4197d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_FORMAT_A2R10G10B10_UNORM_PACK32: 4207d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_format = HAL_PIXEL_FORMAT_RGBA_1010102; 4217d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4227d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter default: 4237d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter ALOGV("unsupported swapchain format %d", format); 4247d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter break; 4257d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter } 4267d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return native_format; 4277d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter} 4287d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 4297d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchterandroid_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace) { 4307d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter switch (colorspace) { 4317d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: 4327d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB; 4337d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: 4347d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_DISPLAY_P3; 4357d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: 4367d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SCRGB_LINEAR; 437b52abeec9f9b4497c7c7dcb9248e80251e0cddddCourtney Goeltzenleuchter case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT: 438b52abeec9f9b4497c7c7dcb9248e80251e0cddddCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SCRGB; 4397d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT: 4407d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_DCI_P3_LINEAR; 4417d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: 4427d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_DCI_P3; 4437d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_BT709_LINEAR_EXT: 4447d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB_LINEAR; 4457d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_BT709_NONLINEAR_EXT: 4467d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB; 447c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_BT2020_LINEAR_EXT: 448c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter return HAL_DATASPACE_BT2020_LINEAR; 449c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_HDR10_ST2084_EXT: 4507d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return static_cast<android_dataspace>( 451c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | 452c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_RANGE_FULL); 453c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_DOLBYVISION_EXT: 4547d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return static_cast<android_dataspace>( 4557d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 | 4567d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_RANGE_FULL); 457c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter case VK_COLOR_SPACE_HDR10_HLG_EXT: 458c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter return static_cast<android_dataspace>( 459c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG | 460c45673f8f14ecbcf49683ef7dd62dd4123a57fe5Courtney Goeltzenleuchter HAL_DATASPACE_RANGE_FULL); 4617d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT: 4627d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return static_cast<android_dataspace>( 4637d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_STANDARD_ADOBE_RGB | 4647d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter HAL_DATASPACE_TRANSFER_LINEAR | HAL_DATASPACE_RANGE_FULL); 4657d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: 4667d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_ADOBE_RGB; 4677d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 4687d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // Pass through is intended to allow app to provide data that is passed 4697d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // to the display system without modification. 4707d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter case VK_COLOR_SPACE_PASS_THROUGH_EXT: 4717d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_ARBITRARY; 4727d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 4737d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter default: 4747d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // This indicates that we don't know about the 4757d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // dataspace specified and we should indicate that 4767d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter // it's unsupported 4777d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return HAL_DATASPACE_UNKNOWN; 4787d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter } 4797d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter} 4807d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 481d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} // anonymous namespace 482b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 483e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 484622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult CreateAndroidSurfaceKHR( 485f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall VkInstance instance, 486f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, 487f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall const VkAllocationCallbacks* allocator, 488f9fa9a50d5e87dacce36ef2a56b392fc053cf8ceJesse Hall VkSurfaceKHR* out_surface) { 4891f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 4904a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(instance).allocator; 4911f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), 4921f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall alignof(Surface), 4931f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 4941356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (!mem) 4951356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall return VK_ERROR_OUT_OF_HOST_MEMORY; 4961356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall Surface* surface = new (mem) Surface; 497b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 498e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu surface->window = pCreateInfo->window; 499dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall surface->swapchain_handle = VK_NULL_HANDLE; 5006435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang int err = native_window_get_consumer_usage(surface->window.get(), 5016435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang &surface->consumer_usage); 5026435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang if (err != android::NO_ERROR) { 5036435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang ALOGE("native_window_get_consumer_usage() failed: %s (%d)", 5046435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang strerror(-err), err); 5056435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang surface->~Surface(); 5066435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang allocator->pfnFree(allocator->pUserData, surface); 5076435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang return VK_ERROR_INITIALIZATION_FAILED; 5086435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang } 509b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 5101356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN. 5116435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang err = 5121356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall native_window_api_connect(surface->window.get(), NATIVE_WINDOW_API_EGL); 5131356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (err != 0) { 5141356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 5151356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // errors and translate them to valid Vulkan result codes? 5161356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall ALOGE("native_window_api_connect() failed: %s (%d)", strerror(-err), 5171356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall err); 5181356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall surface->~Surface(); 5191f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, surface); 520762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; 5211356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall } 522b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 5231356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall *out_surface = HandleFromSurface(surface); 524b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 525b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 526b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 527e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 528622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DestroySurfaceKHR(VkInstance instance, 529622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSurfaceKHR surface_handle, 530622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator) { 5311356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall Surface* surface = SurfaceFromHandle(surface_handle); 5321356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (!surface) 5331356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall return; 5341356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL); 53542a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF(surface->swapchain_handle != VK_NULL_HANDLE, 536dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "destroyed VkSurfaceKHR 0x%" PRIx64 537dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall " has active VkSwapchainKHR 0x%" PRIx64, 538dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(surface_handle), 539dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(surface->swapchain_handle)); 5401356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall surface->~Surface(); 5411f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 5424a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(instance).allocator; 5431f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, surface); 5441356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 5451356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 546e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 547622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/, 548622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t /*queue_family*/, 5496435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang VkSurfaceKHR surface_handle, 550622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkBool32* supported) { 5516435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang const Surface* surface = SurfaceFromHandle(surface_handle); 5526435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang if (!surface) { 5536435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang return VK_ERROR_SURFACE_LOST_KHR; 5546435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang } 5556435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang const ANativeWindow* window = surface->window.get(); 5566435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang 5576435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang int query_value; 5586435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang int err = window->query(window, NATIVE_WINDOW_FORMAT, &query_value); 5596435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang if (err != 0 || query_value < 0) { 5606435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang ALOGE("NATIVE_WINDOW_FORMAT query failed: %s (%d) value=%d", 5616435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang strerror(-err), err, query_value); 5626435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang return VK_ERROR_SURFACE_LOST_KHR; 5636435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang } 5646435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang 5656435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang android_pixel_format native_format = 5666435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang static_cast<android_pixel_format>(query_value); 5676435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang 5686435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang bool format_supported = false; 5696435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang switch (native_format) { 5706435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang case HAL_PIXEL_FORMAT_RGBA_8888: 5716435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang case HAL_PIXEL_FORMAT_RGB_565: 5726435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang format_supported = true; 5736435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang break; 5746435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang default: 5756435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang break; 5766435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang } 5776435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang 5786435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // USAGE_CPU_READ_MASK 0xFUL 5796435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // USAGE_CPU_WRITE_MASK (0xFUL << 4) 5806435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // The currently used bits are as below: 5816435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // USAGE_CPU_READ_RARELY = 2UL 5826435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // USAGE_CPU_READ_OFTEN = 3UL 5836435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // USAGE_CPU_WRITE_RARELY = (2UL << 4) 5846435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang // USAGE_CPU_WRITE_OFTEN = (3UL << 4) 5856435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang *supported = static_cast<VkBool32>(format_supported || 5866435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang (surface->consumer_usage & 0xFFUL) == 0); 5876435b32fbf30883b84f35f96a7325c8b3413c7a7Yiwei Zhang 588a64292517b1876c4bbe5d3e62c577812f40bd922Jesse Hall return VK_SUCCESS; 5891356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall} 5901356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall 591e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 592622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult GetPhysicalDeviceSurfaceCapabilitiesKHR( 593b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall VkPhysicalDevice /*pdev*/, 594b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall VkSurfaceKHR surface, 595b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall VkSurfaceCapabilitiesKHR* capabilities) { 596d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 5971356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall ANativeWindow* window = SurfaceFromHandle(surface)->window.get(); 598d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 599d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int width, height; 600d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width); 601d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 602d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)", 603d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(-err), err); 604762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 605d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 606d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height); 607d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 608d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)", 609d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(-err), err); 610762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 611d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 612d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 61355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall int transform_hint; 61455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT, &transform_hint); 61555bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall if (err != 0) { 61655bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)", 61755bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall strerror(-err), err); 618762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 61955bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall } 62055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall 621d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Figure out what the min/max values should be. 622dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang int max_buffer_count; 623dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &max_buffer_count); 624dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang if (err != 0) { 625dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang ALOGE("NATIVE_WINDOW_MAX_BUFFER_COUNT query failed: %s (%d)", 626dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang strerror(-err), err); 627dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang return VK_ERROR_SURFACE_LOST_KHR; 628dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang } 6298e951d52c90edc4765221471dd7e49db981fb96cYiwei Zhang capabilities->minImageCount = max_buffer_count == 1 ? 1 : 2; 630dbd961590b9b49e4fbf9cb9b868c7a4323be3517Yiwei Zhang capabilities->maxImageCount = static_cast<uint32_t>(max_buffer_count); 631d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 632fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall capabilities->currentExtent = 633fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)}; 634fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall 635d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Figure out what the max extent should be. Maximum 636d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // texture dimension maybe? 637b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->minImageExtent = VkExtent2D{1, 1}; 638b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->maxImageExtent = VkExtent2D{4096, 4096}; 639d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 640fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall capabilities->maxImageArrayLayers = 1; 641fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall 64255bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall capabilities->supportedTransforms = kSupportedTransforms; 64355bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall capabilities->currentTransform = 64455bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall TranslateNativeToVulkanTransform(transform_hint); 645d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 646fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall // On Android, window composition is a WindowManager property, not something 647fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall // associated with the bufferqueue. It can't be changed from here. 648fe2662d9e32d994346e7705c54043d8eb90a3734Jesse Hall capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; 649d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 650d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): I think these are right, but haven't thought hard about 651d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // it. Do we need to query the driver for support of any of these? 652d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // Currently not included: 653d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // - VK_IMAGE_USAGE_DEPTH_STENCIL_BIT: definitely not 654d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT: definitely not 655b00daadc165d4c3fad13b7cc4aeaa1e85e6df9a0Jesse Hall capabilities->supportedUsageFlags = 6563fbc856120217247c72fb5ed88500000f3881c45Jesse Hall VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | 6573fbc856120217247c72fb5ed88500000f3881c45Jesse Hall VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | 6583fbc856120217247c72fb5ed88500000f3881c45Jesse Hall VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 659d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 660d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 661b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 662b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 663b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 664e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 665e278daf850a664a1f15c760c64a74d3649b6f812Courtney GoeltzenleuchterVkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, 666e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter VkSurfaceKHR surface_handle, 667622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* count, 668622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSurfaceFormatKHR* formats) { 669e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter const InstanceData& instance_data = GetData(pdev); 670e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter 6711356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // TODO(jessehall): Fill out the set of supported formats. Longer term, add 6721356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // a new gralloc method to query whether a (format, usage) pair is 6731356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // supported, and check that for each gralloc format that corresponds to a 6741356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // Vulkan format. Shorter term, just add a few more formats to the ones 6751356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall // hardcoded below. 676d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 677d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall const VkSurfaceFormatKHR kFormats[] = { 6782676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, 6792676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, 6802676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall {VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, 681d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall }; 682d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall const uint32_t kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); 683e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter uint32_t total_num_formats = kNumFormats; 684e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter 685e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter bool wide_color_support = false; 686e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter Surface& surface = *SurfaceFromHandle(surface_handle); 687e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter int err = native_window_get_wide_color_support(surface.window.get(), 688e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter &wide_color_support); 689e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (err) { 690e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter // Not allowed to return a more sensible error code, so do this 691e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter return VK_ERROR_OUT_OF_HOST_MEMORY; 692e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter } 693e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter ALOGV("wide_color_support is: %d", wide_color_support); 694e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter wide_color_support = 695e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter wide_color_support && 696e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace); 697e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter 698e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter const VkSurfaceFormatKHR kWideColorFormats[] = { 699bd7e03a6fa4b4843e924d6477cb7ef75d989ad5eCourtney Goeltzenleuchter {VK_FORMAT_R8G8B8A8_UNORM, 700bd7e03a6fa4b4843e924d6477cb7ef75d989ad5eCourtney Goeltzenleuchter VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}, 701bd7e03a6fa4b4843e924d6477cb7ef75d989ad5eCourtney Goeltzenleuchter {VK_FORMAT_R8G8B8A8_SRGB, 702e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}, 703e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter }; 704e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter const uint32_t kNumWideColorFormats = 705e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter sizeof(kWideColorFormats) / sizeof(kWideColorFormats[0]); 706e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (wide_color_support) { 707e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter total_num_formats += kNumWideColorFormats; 708e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter } 709d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 710d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 711d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (formats) { 712e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter uint32_t out_count = 0; 713e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter uint32_t transfer_count = 0; 714e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (*count < total_num_formats) 715d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall result = VK_INCOMPLETE; 716e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter transfer_count = std::min(*count, kNumFormats); 717e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter std::copy(kFormats, kFormats + transfer_count, formats); 718e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter out_count += transfer_count; 719e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter if (wide_color_support) { 720e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter transfer_count = std::min(*count - out_count, kNumWideColorFormats); 721e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter std::copy(kWideColorFormats, kWideColorFormats + transfer_count, 722e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter formats + out_count); 723e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter out_count += transfer_count; 724e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter } 725e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter *count = out_count; 7267331e228f5089a619a517630351353e88d04c9b5Jesse Hall } else { 727e278daf850a664a1f15c760c64a74d3649b6f812Courtney Goeltzenleuchter *count = total_num_formats; 728d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 729d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 730b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 731b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 732e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 7332452cf7e653c425191791a4fb546106d6a277654Chris ForbesVkResult GetPhysicalDeviceSurfaceCapabilities2KHR( 7342452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkPhysicalDevice physicalDevice, 7352452cf7e653c425191791a4fb546106d6a277654Chris Forbes const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, 7362452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkSurfaceCapabilities2KHR* pSurfaceCapabilities) { 7372452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkResult result = GetPhysicalDeviceSurfaceCapabilitiesKHR( 7382452cf7e653c425191791a4fb546106d6a277654Chris Forbes physicalDevice, pSurfaceInfo->surface, 7392452cf7e653c425191791a4fb546106d6a277654Chris Forbes &pSurfaceCapabilities->surfaceCapabilities); 7402452cf7e653c425191791a4fb546106d6a277654Chris Forbes 74106bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes VkSurfaceCapabilities2KHR* caps = pSurfaceCapabilities; 74206bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes while (caps->pNext) { 74306bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes caps = reinterpret_cast<VkSurfaceCapabilities2KHR*>(caps->pNext); 74406bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes 74506bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes switch (caps->sType) { 74606bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes case VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR: { 74706bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes VkSharedPresentSurfaceCapabilitiesKHR* shared_caps = 74806bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes reinterpret_cast<VkSharedPresentSurfaceCapabilitiesKHR*>( 74906bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes caps); 75006bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes // Claim same set of usage flags are supported for 75106bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes // shared present modes as for other modes. 75206bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes shared_caps->sharedPresentSupportedUsageFlags = 75306bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes pSurfaceCapabilities->surfaceCapabilities 75406bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes .supportedUsageFlags; 75506bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes } break; 75606bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes 75706bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes default: 75806bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes // Ignore all other extension structs 75906bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes break; 76006bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes } 76106bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes } 76206bc009ca14efd3869f2acf0de6ace9f9beb3c0bChris Forbes 7632452cf7e653c425191791a4fb546106d6a277654Chris Forbes return result; 7642452cf7e653c425191791a4fb546106d6a277654Chris Forbes} 7652452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7662452cf7e653c425191791a4fb546106d6a277654Chris ForbesVKAPI_ATTR 7672452cf7e653c425191791a4fb546106d6a277654Chris ForbesVkResult GetPhysicalDeviceSurfaceFormats2KHR( 7682452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkPhysicalDevice physicalDevice, 7692452cf7e653c425191791a4fb546106d6a277654Chris Forbes const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, 7702452cf7e653c425191791a4fb546106d6a277654Chris Forbes uint32_t* pSurfaceFormatCount, 7712452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkSurfaceFormat2KHR* pSurfaceFormats) { 7722452cf7e653c425191791a4fb546106d6a277654Chris Forbes if (!pSurfaceFormats) { 7732452cf7e653c425191791a4fb546106d6a277654Chris Forbes return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, 7742452cf7e653c425191791a4fb546106d6a277654Chris Forbes pSurfaceInfo->surface, 7752452cf7e653c425191791a4fb546106d6a277654Chris Forbes pSurfaceFormatCount, nullptr); 7762452cf7e653c425191791a4fb546106d6a277654Chris Forbes } else { 7772452cf7e653c425191791a4fb546106d6a277654Chris Forbes // temp vector for forwarding; we'll marshal it into the pSurfaceFormats 7782452cf7e653c425191791a4fb546106d6a277654Chris Forbes // after the call. 7792452cf7e653c425191791a4fb546106d6a277654Chris Forbes android::Vector<VkSurfaceFormatKHR> surface_formats; 7802452cf7e653c425191791a4fb546106d6a277654Chris Forbes surface_formats.resize(*pSurfaceFormatCount); 7812452cf7e653c425191791a4fb546106d6a277654Chris Forbes VkResult result = GetPhysicalDeviceSurfaceFormatsKHR( 7822452cf7e653c425191791a4fb546106d6a277654Chris Forbes physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, 7832452cf7e653c425191791a4fb546106d6a277654Chris Forbes &surface_formats.editItemAt(0)); 7842452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7852452cf7e653c425191791a4fb546106d6a277654Chris Forbes if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 7862452cf7e653c425191791a4fb546106d6a277654Chris Forbes // marshal results individually due to stride difference. 7872452cf7e653c425191791a4fb546106d6a277654Chris Forbes // completely ignore any chained extension structs. 7882452cf7e653c425191791a4fb546106d6a277654Chris Forbes uint32_t formats_to_marshal = *pSurfaceFormatCount; 7892452cf7e653c425191791a4fb546106d6a277654Chris Forbes for (uint32_t i = 0u; i < formats_to_marshal; i++) { 7902452cf7e653c425191791a4fb546106d6a277654Chris Forbes pSurfaceFormats[i].surfaceFormat = surface_formats[i]; 7912452cf7e653c425191791a4fb546106d6a277654Chris Forbes } 7922452cf7e653c425191791a4fb546106d6a277654Chris Forbes } 7932452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7942452cf7e653c425191791a4fb546106d6a277654Chris Forbes return result; 7952452cf7e653c425191791a4fb546106d6a277654Chris Forbes } 7962452cf7e653c425191791a4fb546106d6a277654Chris Forbes} 7972452cf7e653c425191791a4fb546106d6a277654Chris Forbes 7982452cf7e653c425191791a4fb546106d6a277654Chris ForbesVKAPI_ATTR 799e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris ForbesVkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev, 800e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang VkSurfaceKHR surface, 801622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* count, 802622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkPresentModeKHR* modes) { 803e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang int err; 804e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang int query_value; 805e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang ANativeWindow* window = SurfaceFromHandle(surface)->window.get(); 806e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang 807e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value); 808e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang if (err != 0 || query_value < 0) { 809e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d) value=%d", 810e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang strerror(-err), err, query_value); 811e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang return VK_ERROR_SURFACE_LOST_KHR; 812e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang } 813e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value); 814e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang 815e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &query_value); 816e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang if (err != 0 || query_value < 0) { 817e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang ALOGE("NATIVE_WINDOW_MAX_BUFFER_COUNT query failed: %s (%d) value=%d", 818e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang strerror(-err), err, query_value); 819e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang return VK_ERROR_SURFACE_LOST_KHR; 820e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang } 821e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang uint32_t max_buffer_count = static_cast<uint32_t>(query_value); 822e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang 823e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes android::Vector<VkPresentModeKHR> present_modes; 824e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang if (min_undequeued_buffers + 1 < max_buffer_count) 825e4a559c1d65e1120048ffa46fd192567391fe559Yiwei Zhang present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR); 826e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR); 827e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes 828e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes VkPhysicalDevicePresentationPropertiesANDROID present_properties; 829e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes if (QueryPresentationProperties(pdev, &present_properties)) { 830e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes if (present_properties.sharedImage) { 831e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR); 832e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes present_modes.push_back(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR); 833e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes } 834e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes } 835e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes 836e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes uint32_t num_modes = uint32_t(present_modes.size()); 837d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 838d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 839d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (modes) { 840e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes if (*count < num_modes) 841d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall result = VK_INCOMPLETE; 842e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes *count = std::min(*count, num_modes); 843e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes std::copy(present_modes.begin(), present_modes.begin() + int(*count), modes); 8447331e228f5089a619a517630351353e88d04c9b5Jesse Hall } else { 845e8d79a60cf5edc9ce0b025e39e3731fabcd2fdf4Chris Forbes *count = num_modes; 846d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 847d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 848b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 849b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 850e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 851f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVkResult GetDeviceGroupPresentCapabilitiesKHR( 852cd8ad33289b74243e21a776a5a9170c845d990c4Ian Elliott VkDevice, 853f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) { 854f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch ALOGV_IF(pDeviceGroupPresentCapabilities->sType != 855f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR, 856f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch "vkGetDeviceGroupPresentCapabilitiesKHR: invalid " 857f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch "VkDeviceGroupPresentCapabilitiesKHR structure type %d", 858f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pDeviceGroupPresentCapabilities->sType); 859f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 860f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch memset(pDeviceGroupPresentCapabilities->presentMask, 0, 861f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch sizeof(pDeviceGroupPresentCapabilities->presentMask)); 862f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 863f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch // assume device group of size 1 864f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pDeviceGroupPresentCapabilities->presentMask[0] = 1 << 0; 865f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pDeviceGroupPresentCapabilities->modes = 866f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR; 867f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 868f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch return VK_SUCCESS; 869f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch} 870f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 871f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVKAPI_ATTR 872f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVkResult GetDeviceGroupSurfacePresentModesKHR( 873cd8ad33289b74243e21a776a5a9170c845d990c4Ian Elliott VkDevice, 874cd8ad33289b74243e21a776a5a9170c845d990c4Ian Elliott VkSurfaceKHR, 875f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch VkDeviceGroupPresentModeFlagsKHR* pModes) { 876f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR; 877f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch return VK_SUCCESS; 878f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch} 879f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 880f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVKAPI_ATTR 881cd8ad33289b74243e21a776a5a9170c845d990c4Ian ElliottVkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice, 882f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch VkSurfaceKHR surface, 883f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch uint32_t* pRectCount, 884f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch VkRect2D* pRects) { 885f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch if (!pRects) { 886f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch *pRectCount = 1; 887f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch } else { 888f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch uint32_t count = std::min(*pRectCount, 1u); 889f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch bool incomplete = *pRectCount < 1; 890f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 891f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch *pRectCount = count; 892f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 893f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch if (incomplete) { 894f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch return VK_INCOMPLETE; 895f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch } 896f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 897f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch int err; 898f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch ANativeWindow* window = SurfaceFromHandle(surface)->window.get(); 899f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 900f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch int width = 0, height = 0; 901f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width); 902f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch if (err != 0) { 903f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)", 904f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch strerror(-err), err); 905f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch } 906f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height); 907f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch if (err != 0) { 908f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch ALOGE("NATIVE_WINDOW_DEFAULT_WIDTH query failed: %s (%d)", 909f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch strerror(-err), err); 910f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch } 911f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 912f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch // TODO: Return something better than "whole window" 913f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pRects[0].offset.x = 0; 914f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pRects[0].offset.y = 0; 915f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width), 916f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch static_cast<uint32_t>(height)}; 917f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch } 918f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch return VK_SUCCESS; 919f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch} 920f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 921f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVKAPI_ATTR 922622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult CreateSwapchainKHR(VkDevice device, 923622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkSwapchainCreateInfoKHR* create_info, 924622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator, 925622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR* swapchain_handle) { 926d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 927d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 928d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 9293d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGV("vkCreateSwapchainKHR: surface=0x%" PRIx64 9303d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall " minImageCount=%u imageFormat=%u imageColorSpace=%u" 9313d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall " imageExtent=%ux%u imageUsage=%#x preTransform=%u presentMode=%u" 9323d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall " oldSwapchain=0x%" PRIx64, 9333d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall reinterpret_cast<uint64_t>(create_info->surface), 9343d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->minImageCount, create_info->imageFormat, 9353d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->imageColorSpace, create_info->imageExtent.width, 9363d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->imageExtent.height, create_info->imageUsage, 9373d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall create_info->preTransform, create_info->presentMode, 9383d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall reinterpret_cast<uint64_t>(create_info->oldSwapchain)); 9393d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 9401f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 9414a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(device).allocator; 9421f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall 9437d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter android_pixel_format native_pixel_format = 9447d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter GetNativePixelFormat(create_info->imageFormat); 9457d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter android_dataspace native_dataspace = 9467d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter GetNativeDataspace(create_info->imageColorSpace); 9477d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter if (native_dataspace == HAL_DATASPACE_UNKNOWN) { 9487d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter ALOGE( 9497d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter "CreateSwapchainKHR(VkSwapchainCreateInfoKHR.imageColorSpace = %d) " 9507d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter "failed: Unsupported color space", 9517d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter create_info->imageColorSpace); 9527d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter return VK_ERROR_INITIALIZATION_FAILED; 9537d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter } 9547d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter 95542a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF(create_info->imageArrayLayers != 1, 956dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "swapchain imageArrayLayers=%u not supported", 957715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall create_info->imageArrayLayers); 95842a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF((create_info->preTransform & ~kSupportedTransforms) != 0, 959dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "swapchain preTransform=%#x not supported", 96055bc09788673f8f35bfb2450028827d5ea76c1d3Jesse Hall create_info->preTransform); 96142a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV_IF(!(create_info->presentMode == VK_PRESENT_MODE_FIFO_KHR || 962980ad05eb054386f62395bdf16298581d2a5b09eChris Forbes create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR || 9631d5f68c10560a82fd3278e17e934ee3bff328374Chris Forbes create_info->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR || 9641d5f68c10560a82fd3278e17e934ee3bff328374Chris Forbes create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR), 965dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "swapchain presentMode=%u not supported", 9660ae0dceca1fb83e095d8de6b811aa193def238a0Jesse Hall create_info->presentMode); 967d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 9683d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall Surface& surface = *SurfaceFromHandle(create_info->surface); 9693d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 970dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (surface.swapchain_handle != create_info->oldSwapchain) { 97142a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ALOGV("Can't create a swapchain for VkSurfaceKHR 0x%" PRIx64 972dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall " because it already has active swapchain 0x%" PRIx64 973dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall " but VkSwapchainCreateInfo::oldSwapchain=0x%" PRIx64, 974dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(create_info->surface), 975dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(surface.swapchain_handle), 976dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(create_info->oldSwapchain)); 977dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; 978dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 979dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (create_info->oldSwapchain != VK_NULL_HANDLE) 980dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall OrphanSwapchain(device, SwapchainFromHandle(create_info->oldSwapchain)); 981dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 9823d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // -- Reset the native window -- 9833d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // The native window might have been used previously, and had its properties 9843d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // changed from defaults. That will affect the answer we get for queries 9853d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // like MIN_UNDEQUED_BUFFERS. Reset to a known/default state before we 9863d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // attempt such queries. 9873d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 988dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // The native window only allows dequeueing all buffers before any have 989dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // been queued, since after that point at least one is assumed to be in 990dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // non-FREE state at any given time. Disconnecting and re-connecting 991dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // orphans the previous buffers, getting us back to the state where we can 992dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // dequeue all buffers. 993dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall err = native_window_api_disconnect(surface.window.get(), 994dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall NATIVE_WINDOW_API_EGL); 995dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGW_IF(err != 0, "native_window_api_disconnect failed: %s (%d)", 996dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall strerror(-err), err); 997dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall err = 998dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall native_window_api_connect(surface.window.get(), NATIVE_WINDOW_API_EGL); 999dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGW_IF(err != 0, "native_window_api_connect failed: %s (%d)", 1000dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall strerror(-err), err); 1001dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 10023d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall err = native_window_set_buffer_count(surface.window.get(), 0); 10033d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall if (err != 0) { 10043d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGE("native_window_set_buffer_count(0) failed: %s (%d)", 10053d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall strerror(-err), err); 1006762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 10073d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall } 10083d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 10099b7e453d71e9c17477c097f5f28f1b9d3a134998Hrishikesh Manohar int swap_interval = 10109b7e453d71e9c17477c097f5f28f1b9d3a134998Hrishikesh Manohar create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR ? 0 : 1; 10119b7e453d71e9c17477c097f5f28f1b9d3a134998Hrishikesh Manohar err = surface.window->setSwapInterval(surface.window.get(), swap_interval); 10123d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall if (err != 0) { 10133d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 10143d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall // errors and translate them to valid Vulkan result codes? 10153d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGE("native_window->setSwapInterval(1) failed: %s (%d)", 10163d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall strerror(-err), err); 1017762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 10183d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall } 10193d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall 1020b8042d26de26e9212e62518b39147008937c7729Chris Forbes err = native_window_set_shared_buffer_mode(surface.window.get(), false); 1021b8042d26de26e9212e62518b39147008937c7729Chris Forbes if (err != 0) { 1022b8042d26de26e9212e62518b39147008937c7729Chris Forbes ALOGE("native_window_set_shared_buffer_mode(false) failed: %s (%d)", 1023b8042d26de26e9212e62518b39147008937c7729Chris Forbes strerror(-err), err); 1024762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1025b8042d26de26e9212e62518b39147008937c7729Chris Forbes } 1026b8042d26de26e9212e62518b39147008937c7729Chris Forbes 1027b8042d26de26e9212e62518b39147008937c7729Chris Forbes err = native_window_set_auto_refresh(surface.window.get(), false); 1028b8042d26de26e9212e62518b39147008937c7729Chris Forbes if (err != 0) { 1029b8042d26de26e9212e62518b39147008937c7729Chris Forbes ALOGE("native_window_set_auto_refresh(false) failed: %s (%d)", 1030b8042d26de26e9212e62518b39147008937c7729Chris Forbes strerror(-err), err); 1031762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1032b8042d26de26e9212e62518b39147008937c7729Chris Forbes } 1033b8042d26de26e9212e62518b39147008937c7729Chris Forbes 1034d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Configure the native window -- 1035d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 10364a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu const auto& dispatch = GetData(device).driver; 103770f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall 10387d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter err = native_window_set_buffers_format(surface.window.get(), 10397d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_pixel_format); 1040517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall if (err != 0) { 1041517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1042517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // errors and translate them to valid Vulkan result codes? 1043517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall ALOGE("native_window_set_buffers_format(%d) failed: %s (%d)", 10447d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_pixel_format, strerror(-err), err); 1045762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1046517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall } 1047517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall err = native_window_set_buffers_data_space(surface.window.get(), 10487d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_dataspace); 1049517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall if (err != 0) { 1050517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1051517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall // errors and translate them to valid Vulkan result codes? 1052517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall ALOGE("native_window_set_buffers_data_space(%d) failed: %s (%d)", 10537d4a64a6ada75c773e9fc39f27a9220be32d084bCourtney Goeltzenleuchter native_dataspace, strerror(-err), err); 1054762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1055517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall } 1056517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall 10573dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall err = native_window_set_buffers_dimensions( 10583dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall surface.window.get(), static_cast<int>(create_info->imageExtent.width), 10593dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall static_cast<int>(create_info->imageExtent.height)); 1060d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 1061d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1062d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 1063d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)", 1064d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall create_info->imageExtent.width, create_info->imageExtent.height, 1065d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(-err), err); 1066762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1067d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1068d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1069178b69664a5f56470c143b5930162f285adc83faJesse Hall // VkSwapchainCreateInfo::preTransform indicates the transformation the app 1070178b69664a5f56470c143b5930162f285adc83faJesse Hall // applied during rendering. native_window_set_transform() expects the 1071178b69664a5f56470c143b5930162f285adc83faJesse Hall // inverse: the transform the app is requesting that the compositor perform 1072178b69664a5f56470c143b5930162f285adc83faJesse Hall // during composition. With native windows, pre-transform works by rendering 1073178b69664a5f56470c143b5930162f285adc83faJesse Hall // with the same transform the compositor is applying (as in Vulkan), but 1074178b69664a5f56470c143b5930162f285adc83faJesse Hall // then requesting the inverse transform, so that when the compositor does 1075178b69664a5f56470c143b5930162f285adc83faJesse Hall // it's job the two transforms cancel each other out and the compositor ends 1076178b69664a5f56470c143b5930162f285adc83faJesse Hall // up applying an identity transform to the app's buffer. 1077178b69664a5f56470c143b5930162f285adc83faJesse Hall err = native_window_set_buffers_transform( 1078178b69664a5f56470c143b5930162f285adc83faJesse Hall surface.window.get(), 1079178b69664a5f56470c143b5930162f285adc83faJesse Hall InvertTransformToNative(create_info->preTransform)); 1080178b69664a5f56470c143b5930162f285adc83faJesse Hall if (err != 0) { 1081178b69664a5f56470c143b5930162f285adc83faJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1082178b69664a5f56470c143b5930162f285adc83faJesse Hall // errors and translate them to valid Vulkan result codes? 1083178b69664a5f56470c143b5930162f285adc83faJesse Hall ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)", 1084178b69664a5f56470c143b5930162f285adc83faJesse Hall InvertTransformToNative(create_info->preTransform), 1085178b69664a5f56470c143b5930162f285adc83faJesse Hall strerror(-err), err); 1086762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1087178b69664a5f56470c143b5930162f285adc83faJesse Hall } 1088178b69664a5f56470c143b5930162f285adc83faJesse Hall 1089f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall err = native_window_set_scaling_mode( 10901356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall surface.window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 1091f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall if (err != 0) { 1092f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1093f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall // errors and translate them to valid Vulkan result codes? 1094f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall ALOGE("native_window_set_scaling_mode(SCALE_TO_WINDOW) failed: %s (%d)", 1095f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall strerror(-err), err); 1096762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1097f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall } 1098f64ca1209c4b67baf36d6f489d3c73067113d419Jesse Hall 109997ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes VkSwapchainImageUsageFlagsANDROID swapchain_image_usage = 0; 110097ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (create_info->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR || 110197ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) { 110297ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes swapchain_image_usage |= VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID; 110397ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes err = native_window_set_shared_buffer_mode(surface.window.get(), true); 110497ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (err != 0) { 110597ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes ALOGE("native_window_set_shared_buffer_mode failed: %s (%d)", strerror(-err), err); 110697ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes return VK_ERROR_SURFACE_LOST_KHR; 110797ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 110897ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 110997ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes 111097ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (create_info->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) { 111197ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes err = native_window_set_auto_refresh(surface.window.get(), true); 111297ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes if (err != 0) { 111397ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes ALOGE("native_window_set_auto_refresh failed: %s (%d)", strerror(-err), err); 111497ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes return VK_ERROR_SURFACE_LOST_KHR; 111597ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 111697ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes } 111797ef461b1b6277f0f31f00e9c390424eb71392dfChris Forbes 1118e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall int query_value; 1119e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall err = surface.window->query(surface.window.get(), 1120e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 1121e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall &query_value); 1122e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall if (err != 0 || query_value < 0) { 1123d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1124d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 1125e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, 1126e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall query_value); 1127762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1128d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1129e6080bf2e54aa0d548b0eb571ad2eef2c52e5fb6Jesse Hall uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value); 1130d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t num_images = 1131d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall (create_info->minImageCount - 1) + min_undequeued_buffers; 11322c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes 11332c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // Lower layer insists that we have at least two buffers. This is wasteful 11342c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // and we'd like to relax it in the shared case, but not all the pieces are 11352c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // in place for that to work yet. Note we only lie to the lower layer-- we 11362c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // don't want to give the app back a swapchain with extra images (which they 11372c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes // can't actually use!). 11382c8fc75cca5e42b4f07b589cef6e78f3dff49ae0Chris Forbes err = native_window_set_buffer_count(surface.window.get(), std::max(2u, num_images)); 1139d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 1140d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1141d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 11423d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall ALOGE("native_window_set_buffer_count(%d) failed: %s (%d)", num_images, 11433d1c82a750046f055951242bf27909ad7d9cdf52Jesse Hall strerror(-err), err); 1144762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1145d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1146d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1147f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch int32_t legacy_usage = 0; 11488c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes if (dispatch.GetSwapchainGrallocUsage2ANDROID) { 1149d1abd7456e10f46200a90e8a0e5a1a8bef0a388aJesse Hall uint64_t consumer_usage, producer_usage; 1150894780b0ac8f3cdb90e52c45f4fe34494131f70bCourtney Goeltzenleuchter result = dispatch.GetSwapchainGrallocUsage2ANDROID( 1151894780b0ac8f3cdb90e52c45f4fe34494131f70bCourtney Goeltzenleuchter device, create_info->imageFormat, create_info->imageUsage, 1152894780b0ac8f3cdb90e52c45f4fe34494131f70bCourtney Goeltzenleuchter swapchain_image_usage, &consumer_usage, &producer_usage); 11538c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes if (result != VK_SUCCESS) { 11548c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result); 1155762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 11568c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes } 1157f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch legacy_usage = 11587992781a574b1c52a203e9271772da16f0f06812Jesse Hall android_convertGralloc1To0Usage(producer_usage, consumer_usage); 11598c47dc9136aa26ee749bbe952db04f6b2fc79399Chris Forbes } else if (dispatch.GetSwapchainGrallocUsageANDROID) { 11601f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall result = dispatch.GetSwapchainGrallocUsageANDROID( 1161f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall device, create_info->imageFormat, create_info->imageUsage, 1162f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch &legacy_usage); 116370f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall if (result != VK_SUCCESS) { 116470f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result); 1165762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 116670f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall } 116770f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall } 1168f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch uint64_t native_usage = static_cast<uint64_t>(legacy_usage); 1169f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 1170f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch bool createProtectedSwapchain = false; 1171f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch if (create_info->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR) { 1172f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch createProtectedSwapchain = true; 1173f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch native_usage |= BufferUsage::PROTECTED; 1174f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch } 1175f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch err = native_window_set_usage(surface.window.get(), native_usage); 117670f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall if (err != 0) { 117770f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 117870f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall // errors and translate them to valid Vulkan result codes? 117970f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), err); 1180762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 118170f9335d77282e34fa1cdb8d1baed89892ccd2e1Jesse Hall } 1182d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1183d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Allocate our Swapchain object -- 1184d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // After this point, we must deallocate the swapchain on error. 1185d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 11861f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall void* mem = allocator->pfnAllocation(allocator->pUserData, 11871f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall sizeof(Swapchain), alignof(Swapchain), 11881f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 11891356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall if (!mem) 1190d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return VK_ERROR_OUT_OF_HOST_MEMORY; 1191ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott Swapchain* swapchain = 1192ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott new (mem) Swapchain(surface, num_images, create_info->presentMode); 1193d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1194d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Dequeue all buffers and create a VkImage for each -- 1195d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // Any failures during or after this must cancel the dequeued buffers. 1196d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1197b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes VkSwapchainImageCreateInfoANDROID swapchain_image_create = { 1198b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes#pragma clang diagnostic push 1199b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes#pragma clang diagnostic ignored "-Wold-style-cast" 1200b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID, 1201b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes#pragma clang diagnostic pop 1202b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .pNext = nullptr, 1203b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .usage = swapchain_image_usage, 1204b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes }; 1205d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkNativeBufferANDROID image_native_buffer = { 1206d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#pragma clang diagnostic push 1207d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#pragma clang diagnostic ignored "-Wold-style-cast" 1208d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID, 1209d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall#pragma clang diagnostic pop 1210b56287ad73b9ea1c8e9d0a24dc3605e8aae06903Chris Forbes .pNext = &swapchain_image_create, 1211d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall }; 1212d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkImageCreateInfo image_create = { 1213d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 1214d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .pNext = &image_native_buffer, 1215d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .imageType = VK_IMAGE_TYPE_2D, 1216517274a29e50522a11e65107bb2c0d5b123aa7d5Jesse Hall .format = create_info->imageFormat, 1217d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .extent = {0, 0, 1}, 1218d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .mipLevels = 1, 1219a15a4bf4bafd6114ae8f28c2df2fc622cb3baaceJesse Hall .arrayLayers = 1, 1220091ed9e69400edcc549c9b11635d1a305d6b5a83Jesse Hall .samples = VK_SAMPLE_COUNT_1_BIT, 1221d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .tiling = VK_IMAGE_TILING_OPTIMAL, 1222f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall .usage = create_info->imageUsage, 1223f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch .flags = createProtectedSwapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u, 1224f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall .sharingMode = create_info->imageSharingMode, 122503b6fe1b099764c6010c173c1416ea102cdfe5a4Jesse Hall .queueFamilyIndexCount = create_info->queueFamilyIndexCount, 1226d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall .pQueueFamilyIndices = create_info->pQueueFamilyIndices, 1227d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall }; 1228d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1229d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (uint32_t i = 0; i < num_images; i++) { 1230d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain::Image& img = swapchain->images[i]; 1231d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1232d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ANativeWindowBuffer* buffer; 12331356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall err = surface.window->dequeueBuffer(surface.window.get(), &buffer, 12341356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall &img.dequeue_fence); 1235d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 1236d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate 1237d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // possible errors and translate them to valid Vulkan result codes? 1238d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dequeueBuffer[%u] failed: %s (%d)", i, strerror(-err), err); 1239762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan result = VK_ERROR_SURFACE_LOST_KHR; 1240d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall break; 1241d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1242e8e689f1190a936ebd6bf6cbe28ab8625e94c6c7Chia-I Wu img.buffer = buffer; 1243d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall img.dequeued = true; 1244d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1245d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_create.extent = 12463dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall VkExtent3D{static_cast<uint32_t>(img.buffer->width), 12473dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall static_cast<uint32_t>(img.buffer->height), 12483dd678a6a30e2d94bfd570ec43ffd379e9c5d409Jesse Hall 1}; 1249d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.handle = img.buffer->handle; 1250d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.stride = img.buffer->stride; 1251d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall image_native_buffer.format = img.buffer->format; 1252cb496acbe593326e8d5d563847067d02b2df40ecMathias Agopian image_native_buffer.usage = int(img.buffer->usage); 12538e0c3f5f1c4ffc3a055fe016406bd6a549ebdd00Chris Forbes android_convertGralloc0To1Usage(int(img.buffer->usage), 12548e0c3f5f1c4ffc3a055fe016406bd6a549ebdd00Chris Forbes &image_native_buffer.usage2.producer, 12558e0c3f5f1c4ffc3a055fe016406bd6a549ebdd00Chris Forbes &image_native_buffer.usage2.consumer); 1256d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 125703b6fe1b099764c6010c173c1416ea102cdfe5a4Jesse Hall result = 12581f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall dispatch.CreateImage(device, &image_create, nullptr, &img.image); 1259d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1260d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGD("vkCreateImage w/ native buffer failed: %u", result); 1261d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall break; 1262d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1263d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1264d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1265d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // -- Cancel all buffers, returning them to the queue -- 1266d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // If an error occurred before, also destroy the VkImage and release the 1267d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // buffer reference. Otherwise, we retain a strong reference to the buffer. 1268d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // 1269d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): The error path here is the same as DestroySwapchain, 1270d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // but not the non-error path. Should refactor/unify. 127131b85c2326ea082733a848d47b630f44c7888549Chris Forbes for (uint32_t i = 0; i < num_images; i++) { 127231b85c2326ea082733a848d47b630f44c7888549Chris Forbes Swapchain::Image& img = swapchain->images[i]; 127331b85c2326ea082733a848d47b630f44c7888549Chris Forbes if (img.dequeued) { 127431b85c2326ea082733a848d47b630f44c7888549Chris Forbes if (!swapchain->shared) { 1275e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes surface.window->cancelBuffer(surface.window.get(), img.buffer.get(), 1276e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes img.dequeue_fence); 1277e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes img.dequeue_fence = -1; 1278e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes img.dequeued = false; 1279e0ced03e62565f42b3005ec34481ef2be7ae2d4bChris Forbes } 128031b85c2326ea082733a848d47b630f44c7888549Chris Forbes } 128131b85c2326ea082733a848d47b630f44c7888549Chris Forbes if (result != VK_SUCCESS) { 128231b85c2326ea082733a848d47b630f44c7888549Chris Forbes if (img.image) 128331b85c2326ea082733a848d47b630f44c7888549Chris Forbes dispatch.DestroyImage(device, img.image, nullptr); 1284d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1285d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1286d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1287d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1288d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain->~Swapchain(); 12891f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, swapchain); 1290d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 1291d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1292d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1293dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall surface.swapchain_handle = HandleFromSwapchain(swapchain); 1294dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall *swapchain_handle = surface.swapchain_handle; 1295b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 1296b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1297b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1298e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1299622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DestroySwapchainKHR(VkDevice device, 1300622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR swapchain_handle, 1301622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator) { 13024a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu const auto& dispatch = GetData(device).driver; 1303d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain* swapchain = SwapchainFromHandle(swapchain_handle); 1304d78c2e8a0807ff45db4cb643cc2ef38eafd22551Daniel Koch if (!swapchain) 1305d78c2e8a0807ff45db4cb643cc2ef38eafd22551Daniel Koch return; 130642a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall bool active = swapchain->surface.swapchain_handle == swapchain_handle; 130742a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr; 1308dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 13094c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (swapchain->frame_timestamps_enabled) { 13104c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott native_window_enable_frame_timestamps(window, false); 13114c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 1312dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall for (uint32_t i = 0; i < swapchain->num_images; i++) 1313dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, window, -1, swapchain->images[i]); 131442a9eecb23c0b72bbee1eb2ef6b0d6586159d1c3Jesse Hall if (active) 1315dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain->surface.swapchain_handle = VK_NULL_HANDLE; 13161f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall if (!allocator) 13174a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu allocator = &GetData(device).allocator; 1318d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain->~Swapchain(); 13191f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall allocator->pfnFree(allocator->pUserData, swapchain); 1320b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1321b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1322e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1323622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult GetSwapchainImagesKHR(VkDevice, 1324622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR swapchain_handle, 1325622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* count, 1326622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkImage* images) { 1327d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 1328dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGW_IF(swapchain.surface.swapchain_handle != swapchain_handle, 1329dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "getting images for non-active swapchain 0x%" PRIx64 1330dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall "; only dequeued image handles are valid", 1331dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall reinterpret_cast<uint64_t>(swapchain_handle)); 1332d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result = VK_SUCCESS; 1333d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (images) { 1334d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t n = swapchain.num_images; 1335d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (*count < swapchain.num_images) { 1336d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall n = *count; 1337d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall result = VK_INCOMPLETE; 1338d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1339d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (uint32_t i = 0; i < n; i++) 1340d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall images[i] = swapchain.images[i].image; 13417331e228f5089a619a517630351353e88d04c9b5Jesse Hall *count = n; 13427331e228f5089a619a517630351353e88d04c9b5Jesse Hall } else { 13437331e228f5089a619a517630351353e88d04c9b5Jesse Hall *count = swapchain.num_images; 1344d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1345d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 1346b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1347b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1348e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1349622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult AcquireNextImageKHR(VkDevice device, 1350622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSwapchainKHR swapchain_handle, 1351622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint64_t timeout, 1352622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkSemaphore semaphore, 1353622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkFence vk_fence, 1354622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint32_t* image_index) { 1355d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 13561356b0d3179254a7a27e88abb2d2500385469f14Jesse Hall ANativeWindow* window = swapchain.surface.window.get(); 1357d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result; 1358d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 1359d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1360dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain.surface.swapchain_handle != swapchain_handle) 1361dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return VK_ERROR_OUT_OF_DATE_KHR; 1362dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1363d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGW_IF( 1364d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall timeout != UINT64_MAX, 1365d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall "vkAcquireNextImageKHR: non-infinite timeouts not yet implemented"); 1366d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1367c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes if (swapchain.shared) { 1368c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes // In shared mode, we keep the buffer dequeued all the time, so we don't 1369c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes // want to dequeue a buffer here. Instead, just ask the driver to ensure 1370c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes // the semaphore and fence passed to us will be signalled. 1371c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes *image_index = 0; 1372c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes result = GetData(device).driver.AcquireImageANDROID( 1373c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes device, swapchain.images[*image_index].image, -1, semaphore, vk_fence); 1374c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes return result; 1375c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes } 1376c88409c2b8e99be8d5f134e260c4c29b1e632b3cChris Forbes 1377d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ANativeWindowBuffer* buffer; 1378061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall int fence_fd; 1379061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall err = window->dequeueBuffer(window, &buffer, &fence_fd); 1380d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (err != 0) { 1381d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // TODO(jessehall): Improve error reporting. Can we enumerate possible 1382d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall // errors and translate them to valid Vulkan result codes? 1383d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err); 1384762c813cd0fdcf41760a7be9b8c73bfa246289c2Mike Stroyan return VK_ERROR_SURFACE_LOST_KHR; 1385d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1386d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1387d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall uint32_t idx; 1388d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (idx = 0; idx < swapchain.num_images; idx++) { 1389d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (swapchain.images[idx].buffer.get() == buffer) { 1390d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain.images[idx].dequeued = true; 1391061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall swapchain.images[idx].dequeue_fence = fence_fd; 1392d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall break; 1393d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1394d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1395d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (idx == swapchain.num_images) { 1396d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dequeueBuffer returned unrecognized buffer"); 1397061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall window->cancelBuffer(window, buffer, fence_fd); 1398d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return VK_ERROR_OUT_OF_DATE_KHR; 1399d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1400d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1401d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int fence_clone = -1; 1402061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall if (fence_fd != -1) { 1403061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall fence_clone = dup(fence_fd); 1404d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (fence_clone == -1) { 1405d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", 1406d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall strerror(errno), errno); 1407061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall sync_wait(fence_fd, -1 /* forever */); 1408d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1409d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1410d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 14114a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu result = GetData(device).driver.AcquireImageANDROID( 14121f91d390ac013ea2514a67e12ddb083119d636d7Jesse Hall device, swapchain.images[idx].image, fence_clone, semaphore, vk_fence); 1413d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1414ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // NOTE: we're relying on AcquireImageANDROID to close fence_clone, 1415ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // even if the call fails. We could close it ourselves on failure, but 1416ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // that would create a race condition if the driver closes it on a 1417ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // failure path: some other thread might create an fd with the same 1418ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // number between the time the driver closes it and the time we close 1419ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // it. We must assume one of: the driver *always* closes it even on 1420ab9aeef063119445b59166f781c464c64e3909dbJesse Hall // failure, or *never* closes it on failure. 1421061938022b3f5f37f7aaebf7ccc8ac20bf4dbf97Jesse Hall window->cancelBuffer(window, buffer, fence_fd); 1422d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain.images[idx].dequeued = false; 1423d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall swapchain.images[idx].dequeue_fence = -1; 1424d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return result; 1425d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1426d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1427d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall *image_index = idx; 1428b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall return VK_SUCCESS; 1429b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} 1430b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 1431f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVKAPI_ATTR 1432f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel KochVkResult AcquireNextImage2KHR(VkDevice device, 1433f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch const VkAcquireNextImageInfoKHR* pAcquireInfo, 1434f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch uint32_t* pImageIndex) { 1435f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch // TODO: this should actually be the other way around and this function 1436f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch // should handle any additional structures that get passed in 1437f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch return AcquireNextImageKHR(device, pAcquireInfo->swapchain, 1438f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pAcquireInfo->timeout, pAcquireInfo->semaphore, 1439f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch pAcquireInfo->fence, pImageIndex); 1440f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch} 1441f25f5bb3eb1ee3e7a3c33b5e44143ad296245f3fDaniel Koch 1442dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hallstatic VkResult WorstPresentResult(VkResult a, VkResult b) { 1443dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // See the error ranking for vkQueuePresentKHR at the end of section 29.6 1444dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // (in spec version 1.0.14). 1445dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall static const VkResult kWorstToBest[] = { 1446dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_DEVICE_LOST, 1447dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_SURFACE_LOST_KHR, 1448dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_OUT_OF_DATE_KHR, 1449dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_OUT_OF_DEVICE_MEMORY, 1450dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_ERROR_OUT_OF_HOST_MEMORY, 1451dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VK_SUBOPTIMAL_KHR, 1452dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall }; 1453dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall for (auto result : kWorstToBest) { 1454dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (a == result || b == result) 1455dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return result; 1456dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1457dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(a == VK_SUCCESS, "invalid vkQueuePresentKHR result %d", a); 1458dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOG_ASSERT(b == VK_SUCCESS, "invalid vkQueuePresentKHR result %d", b); 1459dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall return a != VK_SUCCESS ? a : b; 1460dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall} 1461dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1462e1b12783fff0b8e2defcc94c54fac8d737e6b996Jesse HallVKAPI_ATTR 1463622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { 1464d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 1465d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d", 1466d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall present_info->sType); 1467d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1468dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VkDevice device = GetData(queue).driver_device; 14694a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu const auto& dispatch = GetData(queue).driver; 1470d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult final_result = VK_SUCCESS; 1471dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1472cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott // Look at the pNext chain for supported extension structs: 14734c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentRegionsKHR* present_regions = nullptr; 14744c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentTimesInfoGOOGLE* present_times = nullptr; 1475cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott const VkPresentRegionsKHR* next = 1476cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext); 1477cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott while (next) { 1478cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott switch (next->sType) { 1479cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: 1480cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott present_regions = next; 1481cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott break; 148214866bbeca1ebcda93f43a3352934889a9f37c2bIan Elliott case VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE: 14834c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott present_times = 14844c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott reinterpret_cast<const VkPresentTimesInfoGOOGLE*>(next); 14854c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott break; 1486cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott default: 1487cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x", 1488cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott next->sType); 1489cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott break; 1490cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1491cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott next = reinterpret_cast<const VkPresentRegionsKHR*>(next->pNext); 1492cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1493cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott ALOGV_IF( 1494cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott present_regions && 1495cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott present_regions->swapchainCount != present_info->swapchainCount, 1496cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount"); 14974c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott ALOGV_IF(present_times && 14984c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott present_times->swapchainCount != present_info->swapchainCount, 14994c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott "VkPresentTimesInfoGOOGLE::swapchainCount != " 15004c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott "VkPresentInfo::swapchainCount"); 1501cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott const VkPresentRegionKHR* regions = 15024c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott (present_regions) ? present_regions->pRegions : nullptr; 15034c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentTimeGOOGLE* times = 15044c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott (present_times) ? present_times->pTimes : nullptr; 1505cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott const VkAllocationCallbacks* allocator = &GetData(device).allocator; 15064c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott android_native_rect_t* rects = nullptr; 1507cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott uint32_t nrects = 0; 1508cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott 1509d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { 1510d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall Swapchain& swapchain = 151103b6fe1b099764c6010c173c1416ea102cdfe5a4Jesse Hall *SwapchainFromHandle(present_info->pSwapchains[sc]); 1512f4ab2b18391ab5045b44af9ea1d5698af7c2a0cdJesse Hall uint32_t image_idx = present_info->pImageIndices[sc]; 15135ae3abb3ca6728de04935b0c81bcdbdfc37b0d47Jesse Hall Swapchain::Image& img = swapchain.images[image_idx]; 1514ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott const VkPresentRegionKHR* region = 1515ffedb65cea7551bc689552c0bc21343f568d000eIan Elliott (regions && !swapchain.mailbox_mode) ? ®ions[sc] : nullptr; 15164c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott const VkPresentTimeGOOGLE* time = (times) ? ×[sc] : nullptr; 1517dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall VkResult swapchain_result = VK_SUCCESS; 1518d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall VkResult result; 1519d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int err; 1520d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1521d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall int fence = -1; 1522275d76c8158c90ec5317b82cb10b094bca2b43cfJesse Hall result = dispatch.QueueSignalReleaseImageANDROID( 1523275d76c8158c90ec5317b82cb10b094bca2b43cfJesse Hall queue, present_info->waitSemaphoreCount, 1524275d76c8158c90ec5317b82cb10b094bca2b43cfJesse Hall present_info->pWaitSemaphores, img.image, &fence); 1525d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall if (result != VK_SUCCESS) { 1526ab9aeef063119445b59166f781c464c64e3909dbJesse Hall ALOGE("QueueSignalReleaseImageANDROID failed: %d", result); 1527dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result = result; 1528d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1529d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1530dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain.surface.swapchain_handle == 1531dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall present_info->pSwapchains[sc]) { 1532dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ANativeWindow* window = swapchain.surface.window.get(); 1533dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain_result == VK_SUCCESS) { 1534cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (region) { 1535cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott // Process the incremental-present hint for this swapchain: 1536cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott uint32_t rcount = region->rectangleCount; 1537cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (rcount > nrects) { 1538cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott android_native_rect_t* new_rects = 1539cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott static_cast<android_native_rect_t*>( 1540cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott allocator->pfnReallocation( 1541cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott allocator->pUserData, rects, 1542cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott sizeof(android_native_rect_t) * rcount, 1543cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott alignof(android_native_rect_t), 1544cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); 1545cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (new_rects) { 1546cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott rects = new_rects; 1547cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott nrects = rcount; 1548cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } else { 1549cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott rcount = 0; // Ignore the hint for this swapchain 1550cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1551cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1552cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott for (uint32_t r = 0; r < rcount; ++r) { 1553cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (region->pRectangles[r].layer > 0) { 1554cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott ALOGV( 1555cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott "vkQueuePresentKHR ignoring invalid layer " 1556cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott "(%u); using layer 0 instead", 1557cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott region->pRectangles[r].layer); 1558cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1559cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int x = region->pRectangles[r].offset.x; 1560cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int y = region->pRectangles[r].offset.y; 1561cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int width = static_cast<int>( 1562cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott region->pRectangles[r].extent.width); 1563cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott int height = static_cast<int>( 1564cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott region->pRectangles[r].extent.height); 1565cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott android_native_rect_t* cur_rect = &rects[r]; 1566cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->left = x; 1567cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->top = y + height; 1568cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->right = x + width; 1569cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott cur_rect->bottom = y; 1570cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1571cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott native_window_set_surface_damage(window, rects, rcount); 1572cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 15734c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (time) { 15744c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (!swapchain.frame_timestamps_enabled) { 15758a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ALOGV( 15768a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "Calling " 15778a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "native_window_enable_frame_timestamps(true)"); 15784c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott native_window_enable_frame_timestamps(window, true); 15794c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott swapchain.frame_timestamps_enabled = true; 15804c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 15811049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 15821049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Record the nativeFrameId so it can be later correlated to 15831049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // this present. 15841049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson uint64_t nativeFrameId = 0; 15851049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson err = native_window_get_next_frame_id( 15861049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson window, &nativeFrameId); 15871049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson if (err != android::NO_ERROR) { 15881049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson ALOGE("Failed to get next native frame ID."); 15891049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson } 15901049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson 15911049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // Add a new timing record with the user's presentID and 15921049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson // the nativeFrameId. 15931049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson swapchain.timing.push_back(TimingInfo(time, nativeFrameId)); 15941049d1d0b21ee318e309f9a90098c092cb879c41Brian Anderson while (swapchain.timing.size() > MAX_TIMING_INFOS) { 15958a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott swapchain.timing.removeAt(0); 15968a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 15978a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott if (time->desiredPresentTime) { 15988a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // Set the desiredPresentTime: 15998a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ALOGV( 16008a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "Calling " 16018a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott "native_window_set_buffers_timestamp(%" PRId64 ")", 16028a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott time->desiredPresentTime); 16038a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott native_window_set_buffers_timestamp( 16048a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott window, 16058a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott static_cast<int64_t>(time->desiredPresentTime)); 16068a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott } 16074c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 1608fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes 1609dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall err = window->queueBuffer(window, img.buffer.get(), fence); 1610dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // queueBuffer always closes fence, even on error 1611dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (err != 0) { 1612dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // TODO(jessehall): What now? We should probably cancel the 1613dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall // buffer, I guess? 1614dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ALOGE("queueBuffer failed: %s (%d)", strerror(-err), err); 1615dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result = WorstPresentResult( 1616dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result, VK_ERROR_OUT_OF_DATE_KHR); 1617dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1618dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (img.dequeue_fence >= 0) { 1619dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall close(img.dequeue_fence); 1620dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall img.dequeue_fence = -1; 1621dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1622dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall img.dequeued = false; 1623fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes 1624fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // If the swapchain is in shared mode, immediately dequeue the 1625fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // buffer so it can be presented again without an intervening 1626fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // call to AcquireNextImageKHR. We expect to get the same buffer 1627fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes // back from every call to dequeueBuffer in this mode. 1628fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes if (swapchain.shared && swapchain_result == VK_SUCCESS) { 1629fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes ANativeWindowBuffer* buffer; 1630fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes int fence_fd; 1631fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes err = window->dequeueBuffer(window, &buffer, &fence_fd); 1632fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes if (err != 0) { 1633fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err); 1634fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes swapchain_result = WorstPresentResult(swapchain_result, 1635fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes VK_ERROR_SURFACE_LOST_KHR); 1636fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1637fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes else if (img.buffer != buffer) { 1638fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes ALOGE("got wrong image back for shared swapchain"); 1639fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes swapchain_result = WorstPresentResult(swapchain_result, 1640fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes VK_ERROR_SURFACE_LOST_KHR); 1641fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1642fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes else { 1643fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes img.dequeue_fence = fence_fd; 1644fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes img.dequeued = true; 1645fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1646fca0f29e100d60163d408439f1a5750c353c9adeChris Forbes } 1647dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1648dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain_result != VK_SUCCESS) { 1649dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, window, fence, img); 1650dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall OrphanSwapchain(device, &swapchain); 1651dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } 1652dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall } else { 1653dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall ReleaseSwapchainImage(device, nullptr, fence, img); 1654dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall swapchain_result = VK_ERROR_OUT_OF_DATE_KHR; 1655d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1656d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1657a9e5703e380d9d7f096d177adb792621a1e8d4baJesse Hall if (present_info->pResults) 1658dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall present_info->pResults[sc] = swapchain_result; 1659dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall 1660dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall if (swapchain_result != final_result) 1661dc22507e6fd6659c886aa1218f7681fd43b74598Jesse Hall final_result = WorstPresentResult(final_result, swapchain_result); 1662d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall } 1663cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott if (rects) { 1664cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott allocator->pfnFree(allocator->pUserData, rects); 1665cb35113761ae7afc26c7bffc529b590575a9f4d7Ian Elliott } 1666d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall 1667d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall return final_result; 1668d7b994a0cfb9054aafc1dadc85085a7d0ef8789aJesse Hall} 1669b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall 16704c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVKAPI_ATTR 16714c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVkResult GetRefreshCycleDurationGOOGLE( 16724c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkDevice, 167362c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott VkSwapchainKHR swapchain_handle, 16744c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { 167562c48c931f88ec44c41621afe988c34cab1fb41dIan Elliott Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 16764c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkResult result = VK_SUCCESS; 16774c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 1678dc96fdfa58260867c993fff78611220874753201Brian Anderson pDisplayTimingProperties->refreshDuration = 1679dc96fdfa58260867c993fff78611220874753201Brian Anderson static_cast<uint64_t>(swapchain.refresh_duration); 16804c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 16814c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott return result; 16824c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott} 16834c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 16844c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVKAPI_ATTR 16854c8bb2a95d7849c79dea889f1be59281f4e374bfIan ElliottVkResult GetPastPresentationTimingGOOGLE( 16864c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkDevice, 16874c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkSwapchainKHR swapchain_handle, 16884c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott uint32_t* count, 16894c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkPastPresentationTimingGOOGLE* timings) { 16904c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 16914c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott ANativeWindow* window = swapchain.surface.window.get(); 16924c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott VkResult result = VK_SUCCESS; 16934c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 16944c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (!swapchain.frame_timestamps_enabled) { 16958a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott ALOGV("Calling native_window_enable_frame_timestamps(true)"); 16964c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott native_window_enable_frame_timestamps(window, true); 16974c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott swapchain.frame_timestamps_enabled = true; 16984c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 16994c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 17004c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott if (timings) { 17018a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott // TODO(ianelliott): plumb return value (e.g. VK_INCOMPLETE) 17028a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott copy_ready_timings(swapchain, count, timings); 17034c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } else { 17048a977261a012b0b02c062ac4a5a133f79ef74b62Ian Elliott *count = get_num_ready_timings(swapchain); 17054c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott } 17064c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 17074c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott return result; 17084c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott} 17094c8bb2a95d7849c79dea889f1be59281f4e374bfIan Elliott 17100f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris ForbesVKAPI_ATTR 17110f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris ForbesVkResult GetSwapchainStatusKHR( 17120f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes VkDevice, 17134e18ba82847bdb31504a1b005370f8df931f959dChris Forbes VkSwapchainKHR swapchain_handle) { 17144e18ba82847bdb31504a1b005370f8df931f959dChris Forbes Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); 17150f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes VkResult result = VK_SUCCESS; 17160f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes 17174e18ba82847bdb31504a1b005370f8df931f959dChris Forbes if (swapchain.surface.swapchain_handle != swapchain_handle) { 17184e18ba82847bdb31504a1b005370f8df931f959dChris Forbes return VK_ERROR_OUT_OF_DATE_KHR; 17194e18ba82847bdb31504a1b005370f8df931f959dChris Forbes } 17204e18ba82847bdb31504a1b005370f8df931f959dChris Forbes 17210f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes // TODO(chrisforbes): Implement this function properly 17220f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes 17230f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes return result; 17240f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes} 17250f2ac2e52d06ed171f7b888870c1c3c42b167d1aChris Forbes 1726d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney GoeltzenleuchterVKAPI_ATTR void SetHdrMetadataEXT( 17277671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter VkDevice, 1728d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter uint32_t swapchainCount, 1729d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter const VkSwapchainKHR* pSwapchains, 1730d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter const VkHdrMetadataEXT* pHdrMetadataEXTs) { 17317671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter 17327671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter for (uint32_t idx = 0; idx < swapchainCount; idx++) { 17337671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter Swapchain* swapchain = SwapchainFromHandle(pSwapchains[idx]); 17347671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter if (!swapchain) 17357671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter continue; 17367671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter 17377671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter if (swapchain->surface.swapchain_handle != pSwapchains[idx]) continue; 17387671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter 17397671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter ANativeWindow* window = swapchain->surface.window.get(); 17407671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter 17417671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter VkHdrMetadataEXT vulkanMetadata = pHdrMetadataEXTs[idx]; 17427671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter const android_smpte2086_metadata smpteMetdata = { 17437671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter {vulkanMetadata.displayPrimaryRed.x, 17447671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.displayPrimaryRed.y}, 17457671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter {vulkanMetadata.displayPrimaryGreen.x, 17467671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.displayPrimaryGreen.y}, 17477671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter {vulkanMetadata.displayPrimaryBlue.x, 17487671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.displayPrimaryBlue.y}, 17497671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter {vulkanMetadata.whitePoint.x, vulkanMetadata.whitePoint.y}, 17507671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.maxLuminance, 17517671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.minLuminance}; 17527671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter native_window_set_buffers_smpte2086_metadata(window, &smpteMetdata); 17537671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter 17547671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter const android_cta861_3_metadata cta8613Metadata = { 17557671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.maxContentLightLevel, 17567671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter vulkanMetadata.maxFrameAverageLightLevel}; 17577671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter native_window_set_buffers_cta861_3_metadata(window, &cta8613Metadata); 17587671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter } 17597671d4616faef3b3781dacf953069a3f24f6fdc2Courtney Goeltzenleuchter 1760d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter return; 1761d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter} 1762d634c483bcbd564acd81dcf5d15fc5fa8ab410f4Courtney Goeltzenleuchter 1763622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu} // namespace driver 1764b1352bce9cd82ceaef287b8b3cd7a5c39703a14cJesse Hall} // namespace vulkan 1765