diff --git a/nx/include/switch/display/framebuffer.h b/nx/include/switch/display/framebuffer.h index eb7d9445..8d766314 100644 --- a/nx/include/switch/display/framebuffer.h +++ b/nx/include/switch/display/framebuffer.h @@ -1,7 +1,14 @@ +/** + * @file framebuffer.h + * @brief Framebuffer wrapper object, providing support for software rendered graphics. + * @author fincs + * @copyright libnx Authors + */ #pragma once #include "../nvidia/map.h" #include "native_window.h" +/// Framebuffer structure. typedef struct Framebuffer { NWindow *win; NvMap map; @@ -14,8 +21,41 @@ typedef struct Framebuffer { bool has_init; } Framebuffer; +/** + * @brief Creates a \ref Framebuffer object. + * @param[out] fb Output \ref Framebuffer structure. + * @param[in] win Pointer to the \ref NWindow to which the \ref Framebuffer will be registered. + * @param[in] width Desired width of the framebuffer (usually 1280). + * @param[in] height Desired height of the framebuffer (usually 720). + * @param[in] format Desired pixel format (see PIXEL_FORMAT_* enum). + * @param[in] num_fbs Number of buffers to create. Pass 1 for single-buffering, 2 for double-buffering or 3 for triple-buffering. + * @note Presently, only the following pixel formats are supported: + * \ref PIXEL_FORMAT_RGBA_8888 + * \ref PIXEL_FORMAT_RGBX_8888 + * \ref PIXEL_FORMAT_RGB_565 + * \ref PIXEL_FORMAT_BGRA_8888 + * \ref PIXEL_FORMAT_RGBA_4444 + */ Result framebufferCreate(Framebuffer* fb, NWindow *win, u32 width, u32 height, u32 format, u32 num_fbs); + +/// Closes a \ref Framebuffer object, freeing all resources associated with it. void framebufferClose(Framebuffer* fb); +/** + * @brief Begins rendering a frame in a Framebuffer. + * @param[in] fb Pointer to \ref Framebuffer structure. + * @param[out] out_stride Output variable containing the distance in bytes between rows of pixels in memory. + * @return Pointer to buffer to which new graphics data should be written to. + * @note When this function is called, a buffer will be dequeued from the corresponding \ref NWindow. + * @note This function will return pointers to different buffers, depending on the number of buffers it was initialized with. + * @note Each call to \ref framebufferBegin must be paired with a \ref framebufferEnd call. + */ void* framebufferBegin(Framebuffer* fb, u32* out_stride); + +/** + * @brief Finishes rendering a frame in a Framebuffer. + * @param[in] fb Pointer to \ref Framebuffer structure. + * @note When this function is called, the written image data will be flushed and queued (presented) in the corresponding \ref NWindow. + * @note Each call to \ref framebufferBegin must be paired with a \ref framebufferEnd call. + */ void framebufferEnd(Framebuffer* fb); diff --git a/nx/include/switch/display/native_window.h b/nx/include/switch/display/native_window.h index 9483b8e8..35f633d0 100644 --- a/nx/include/switch/display/native_window.h +++ b/nx/include/switch/display/native_window.h @@ -1,3 +1,9 @@ +/** + * @file native_window.h + * @brief Native window (NWindow) wrapper object, used for presenting images to the display (or other sinks). + * @author fincs + * @copyright libnx Authors + */ #pragma once #include "../kernel/mutex.h" #include "../kernel/event.h" @@ -7,6 +13,7 @@ #include "binder.h" #include "buffer_producer.h" +/// Native window structure. typedef struct NWindow { u32 magic; Binder bq; @@ -30,24 +37,141 @@ typedef struct NWindow { bool consumer_running_behind; } NWindow; +///@name Basic functions +///@{ + +/// Checks whether a pointer refers to a valid \ref NWindow object. bool nwindowIsValid(NWindow* nw); + +/** + * @brief Creates a \ref NWindow. + * @param[out] nw Output \ref NWindow structure. + * @param[in] binder_id Android IGraphicBufferProducer binder session ID. + * @param[in] producer_controlled_by_app Specifies whether the producer is controlled by the application. + */ Result nwindowCreate(NWindow* nw, s32 binder_id, bool producer_controlled_by_app); + +/** + * @brief Creates a \ref NWindow operating on a \ref ViLayer. + * @param[out] nw Output \ref NWindow structure. + * @param[in] layer Pointer to \ref ViLayer structure (such as the one returned by \ref viCreateLayer). + */ Result nwindowCreateFromLayer(NWindow* nw, const ViLayer* layer); + +/// Closes a \ref NWindow, freeing all resources associated with it. void nwindowClose(NWindow* nw); +///@} + +///@name Window configuration +///@{ + +/** + * @brief Retrieves the dimensions of a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[out] out_width Output variable containing the width of the \ref NWindow. + * @param[out] out_height Output variable containing the height of the \ref NWindow. + * @note After creation, a \ref NWindow reports a default size (usually 1280x720). + * This size can be overriden by calling \ref nwindowSetDimensions. + */ Result nwindowGetDimensions(NWindow* nw, u32* out_width, u32* out_height); + +/** + * @brief Sets the dimensions of a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] width Desired width of the \ref NWindow. + * @param[in] height Desired width of the \ref NWindow. + * @note This function cannot be called when there are buffers registered with the \ref NWindow. + */ Result nwindowSetDimensions(NWindow* nw, u32 width, u32 height); + +/** + * @brief Configures the crop applied to images presented through a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] left X coordinate of the left margin of the crop bounding box. + * @param[in] top Y coordinate of the top margin of the crop bounding box. + * @param[in] right X coordinate of the right margin of the crop bounding box. + * @param[in] bottom Y coordinate of the bottom margin of the crop bounding box. + * @note Passing zero to all parameters disables the crop functionality. This is also the default. + * @note The bounding box defined by the parameters will be adjusted to fit within the dimensions of the \ref NWindow. + * @note \p left must be less or equal than \p right. + * @note \p top must be less or equal than \p bottom. + */ Result nwindowSetCrop(NWindow* nw, s32 left, s32 top, s32 right, s32 bottom); + +/** + * @brief Configures the transformation applied to images presented through a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] transform Android transformation mode (see NATIVE_WINDOW_TRANSFORM_* enum) + * @note The default transformation is 0 (i.e. no transformation applied) + */ Result nwindowSetTransform(NWindow* nw, u32 transform); + +/** + * @brief Configures the swap interval of a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] swap_interval Value specifying the number of display refreshes (VBlanks) that must occur between presenting images. + * @note The default swap interval is 1. + * @note If the \ref NWindow has three or more buffers configured (with \ref nwindowConfigureBuffer), it is possible to pass 0 + * to disable the swap interval feature and present images as fast as allowed by the compositor. Otherwise, the system + * enforces a minimum of 1 as the swap interval. + */ Result nwindowSetSwapInterval(NWindow* nw, u32 swap_interval); -Result nwindowConfigureBuffer(NWindow* nw, s32 slot, NvGraphicBuffer* buf); -Result nwindowDequeueBuffer(NWindow* nw, s32* out_slot, NvMultiFence* out_fence); -Result nwindowCancelBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence); -Result nwindowQueueBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence); -void nwindowReleaseBuffers(NWindow* nw); - +/// Checks whether the consumer of a \ref NWindow is running behind. static inline bool nwindowIsConsumerRunningBehind(NWindow* nw) { return nw->consumer_running_behind; } + +///@} + +///@name Buffer configuration and presentation +///@{ + +/** + * @brief Registers a \ref NvGraphicBuffer with a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] slot ID of the slot to configure (starting from 0). + * @param[in] buf Pointer to \ref NvGraphicBuffer structure. + * @note When a buffer is registered, it is added to the internal queue of buffers used for presenting. + * @note All buffers registered with a \ref NWindow must have the same dimensions, format and usage. + * If \ref nwindowSetDimensions has not been previously called, the \ref NWindow will automatically + * adopt the dimensions of the first buffer registered with it. Otherwise, said buffer will need + * to match the dimensions that were previously configured. + */ +Result nwindowConfigureBuffer(NWindow* nw, s32 slot, NvGraphicBuffer* buf); + +/** + * @brief Dequeues a buffer from a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[out] out_slot Output variable containing the ID of the slot that has been dequeued. + * @param[out] out_fence Output variable containing a \ref NvMultiFence that will be signalled by + * the compositor when the buffer is ready to be written to. Pass NULL to wait instead + * on this fence before this function returns. + * @note For \p out_fence=NULL to work, \ref nvFenceInit must have been previously called. + */ +Result nwindowDequeueBuffer(NWindow* nw, s32* out_slot, NvMultiFence* out_fence); + +/** + * @brief Cancels a buffer previously dequeued with \ref nwindowDequeueBuffer. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] slot ID of the slot to cancel. This must match the output of the previous \ref nwindowDequeueBuffer call. + * @param[in] fence Pointer to the \ref NvMultiFence that will be waited on by the compositor before cancelling the buffer. + * Pass NULL if there is no such fence. + */ +Result nwindowCancelBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence); + +/** + * @brief Queues a buffer previously dequeued with \ref nwindowDequeueBuffer, making it ready for presentation. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] slot ID of the slot to queue. This must match the output of the previous \ref nwindowDequeueBuffer call. + * @param[in] fence Pointer to the \ref NvMultiFence that will be waited on by the compositor before queuing/presenting the buffer. + * Pass NULL if there is no such fence. + */ +Result nwindowQueueBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence); + +/// Releases all buffers registered with a \ref NWindow. +void nwindowReleaseBuffers(NWindow* nw); + +///@} diff --git a/nx/include/switch/display/types.h b/nx/include/switch/display/types.h index 5c19c21d..12f35975 100644 --- a/nx/include/switch/display/types.h +++ b/nx/include/switch/display/types.h @@ -1,3 +1,8 @@ +/** + * @file types.h + * @brief Definitions for Android-related types and enumerations. + * @copyright libnx Authors + */ #pragma once #include "../types.h"