Support Swap Interval + Cropping + Transforms and more for QueueBuffer

Support for the following parameters was added to `QueueBuffer`:
* Earliest Present Timestamp
* Swap Interval
* Crop
* Scaling Mode
* Transform
* Frame ID (Not returned to guest yet)
We utilize ANativeWindow APIs directly to achieve all of this in an efficient manner since HWC will be used directly for it, we do plan to introduce Vulkan equivalents for all of these operations later down the line for a port to non-Android platforms.
This commit is contained in:
PixelyIon
2021-06-25 07:03:02 +05:30
committed by ◱ Mark
parent 2e8ce2cbaf
commit ce804254ab
7 changed files with 444 additions and 28 deletions

View File

@ -23,6 +23,11 @@ namespace skyline::gpu {
std::mutex mutex; //!< Synchronizes access to the surface objects
std::condition_variable surfaceCondition; //!< Allows us to efficiently wait for Vulkan surface to be initialized
jobject jSurface{}; //!< The Java Surface object backing the ANativeWindow
ANativeWindow* window{}; //!< A pointer to an Android Native Window which is the surface we draw to
service::hosbinder::AndroidRect windowCrop{}; //!< A rectangle with the bounds of the current crop performed on the image prior to presentation
service::hosbinder::NativeWindowScalingMode windowScalingMode{service::hosbinder::NativeWindowScalingMode::ScaleToWindow}; //!< The mode in which the cropped image is scaled up to the surface
service::hosbinder::NativeWindowTransform windowTransform{}; //!< The transformation performed on the image prior to presentation
u64 windowLastTimestamp{}; //!< The last timestamp submitted to the window, 0 or CLOCK_MONOTONIC value
std::optional<vk::raii::SurfaceKHR> vkSurface; //!< The Vulkan Surface object that is backed by ANativeWindow
vk::SurfaceCapabilitiesKHR vkSurfaceCapabilities; //!< The capabilities of the current Vulkan Surface
@ -40,6 +45,13 @@ namespace skyline::gpu {
std::thread choreographerThread; //!< A thread for signalling the V-Sync event using AChoreographer
ALooper *choreographerLooper{}; //!< The looper object associated with the Choreographer thread
u64 lastChoreographerTime{}; //!< The timestamp of the last invocation of Choreographer::doFrame
u64 refreshCycleDuration{}; //!< The duration of a single refresh cycle for the display in nanoseconds
/**
* @url https://developer.android.com/ndk/reference/group/choreographer#achoreographer_framecallback
*/
static void ChoreographerCallback(long frameTimeNanos, PresentationEngine *engine);
/**
* @brief The entry point for the the Choreographer thread, the function runs ALooper on the thread
@ -65,10 +77,15 @@ namespace skyline::gpu {
/**
* @brief Queue the supplied texture to be presented to the screen
* @param presentId A UUID used to tag this frame for presentation timing readouts
* @param timestamp The earliest timestamp (relative to skyline::util::GetTickNs) at which the frame must be presented, it should be 0 when it doesn't matter
* @param swapInterval The amount of display refreshes that must take place prior to presenting this image
* @param crop A rectangle with bounds that the image will be cropped to
* @param scalingMode The mode by which the image must be scaled up to the surface
* @param transform A transformation that should be performed on the image
* @param frameId The ID of this frame for correlating it with presentation timing readouts
* @note The texture **must** be locked prior to calling this
*/
void Present(const std::shared_ptr<Texture> &texture, u64 presentId);
void Present(const std::shared_ptr<Texture> &texture, u64 timestamp, u64 swapInterval, service::hosbinder::AndroidRect crop, service::hosbinder::NativeWindowScalingMode scalingMode, service::hosbinder::NativeWindowTransform transform, u64& frameId);
/**
* @return A transform that the application should render with to elide costly transforms later