Files
2025-05-18 13:04:45 +08:00

121 lines
4.0 KiB
C++

/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SwappyVkFallback.h"
#define LOG_TAG "SwappyVkFallback"
#include "SwappyLog.h"
namespace swappy {
SwappyVkFallback::SwappyVkFallback(JNIEnv* env, jobject jactivity,
VkPhysicalDevice physicalDevice,
VkDevice device,
const SwappyVkFunctionProvider* provider)
: SwappyVkBase(env, jactivity, physicalDevice, device, provider) {}
bool SwappyVkFallback::doGetRefreshCycleDuration(VkSwapchainKHR swapchain,
uint64_t* pRefreshDuration) {
if (!isEnabled()) {
SWAPPY_LOGE("Swappy is disabled.");
return false;
}
// Since we don't have presentation timing, we cannot achieve pipelining.
mCommonBase.setAutoPipelineMode(false);
*pRefreshDuration = mCommonBase.getRefreshPeriod().count();
// refreshRate is only used for logging, which maybe disabled.
[[maybe_unused]] double refreshRate = 1000000000.0 / *pRefreshDuration;
SWAPPY_LOGI("Returning refresh duration of %" PRIu64 " nsec (approx %f Hz)",
*pRefreshDuration, refreshRate);
return true;
}
VkResult SwappyVkFallback::doQueuePresent(
VkQueue queue, uint32_t queueFamilyIndex,
const VkPresentInfoKHR* pPresentInfo) {
if (!isEnabled()) {
SWAPPY_LOGE("Swappy is disabled.");
return VK_ERROR_INITIALIZATION_FAILED;
}
VkResult result = initializeVkSyncObjects(queue, queueFamilyIndex);
if (result) {
return result;
}
const SwappyCommon::SwapHandlers handlers = {
.lastFrameIsComplete =
std::bind(&SwappyVkFallback::lastFrameIsCompleted, this, queue),
.getPrevFrameGpuTime =
std::bind(&SwappyVkFallback::getLastFenceTime, this, queue),
};
// Inject the fence first and wait for it in onPreSwap() as we don't want to
// submit a frame before rendering is completed.
VkSemaphore semaphore;
result = injectFence(queue, pPresentInfo, &semaphore);
if (result) {
SWAPPY_LOGE("Failed to vkQueueSubmit %d", result);
return result;
}
uint32_t waitSemaphoreCount;
const VkSemaphore* pWaitSemaphores;
if (semaphore != VK_NULL_HANDLE) {
waitSemaphoreCount = 1;
pWaitSemaphores = &semaphore;
} else {
waitSemaphoreCount = pPresentInfo->waitSemaphoreCount;
pWaitSemaphores = pPresentInfo->pWaitSemaphores;
}
mCommonBase.onPreSwap(handlers);
VkPresentInfoKHR replacementPresentInfo = {
pPresentInfo->sType, nullptr,
waitSemaphoreCount, pWaitSemaphores,
pPresentInfo->swapchainCount, pPresentInfo->pSwapchains,
pPresentInfo->pImageIndices, pPresentInfo->pResults};
result = mpfnQueuePresentKHR(queue, &replacementPresentInfo);
mCommonBase.onPostSwap(handlers);
return result;
}
void SwappyVkFallback::enableStats(bool enabled) {
SWAPPY_LOGE("Frame Statistics Unsupported - API ignored");
}
void SwappyVkFallback::getStats(SwappyStats* swappyStats) {
SWAPPY_LOGE("Frame Statistics Unsupported - API ignored");
}
void SwappyVkFallback::recordFrameStart(VkQueue queue, uint32_t image) {
SWAPPY_LOGE("Frame Statistics Unsupported - API ignored");
}
void SwappyVkFallback::clearStats() {
SWAPPY_LOGE("Frame Statistics Unsupported - API ignored");
}
} // namespace swappy