Finally remove deprecated old gfx API

This commit is contained in:
fincs 2019-01-03 21:13:20 +01:00
parent e04f311dd4
commit e708372dca
3 changed files with 0 additions and 675 deletions

View File

@ -82,7 +82,6 @@ extern "C" {
#include "switch/services/ncm.h"
#include "switch/services/psc.h"
#include "switch/display/gfx.h"
#include "switch/display/binder.h"
#include "switch/display/parcel.h"
#include "switch/display/buffer_producer.h"

View File

@ -1,152 +0,0 @@
/**
* @file gfx.h
* @brief Deprecated graphics API, use \ref NWindow and \ref Framebuffer instead.
* @deprecated Use \ref NWindow and \ref Framebuffer instead.
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../nvidia/fence.h"
/// GfxMode set by \ref gfxSetMode. The default is GfxMode_LinearDouble. Note that the text-console (see console.h) sets this to GfxMode_TiledDouble.
/// \deprecated Use \ref framebufferMakeLinear instead.
typedef enum
{
GfxMode_TiledDouble, ///< Double-buffering with raw tiled (block-linear) framebuffer.
GfxMode_LinearDouble ///< Double-buffering with linear framebuffer, which is transferred to the actual framebuffer by \ref gfxFlushBuffers().
} GfxMode;
/**
* @brief Initializes the deprecated graphics subsystem.
* @warning Do not use \ref viInitialize when using this function.
* @deprecated Use \ref nwindowGetDefault and \ref framebufferCreate instead.
*/
__attribute__((deprecated))
Result gfxInitDefault(void);
/**
* @brief Uninitializes the deprecated graphics subsystem.
* @warning Do not use \ref viExit when using this function.
* @deprecated Use \ref framebufferClose instead.
*/
__attribute__((deprecated))
void gfxExit(void);
/**
* @brief Sets the resolution to be used when initializing the deprecated graphics subsystem.
* @param[in] width Horizontal resolution, in pixels.
* @param[in] height Vertical resolution, in pixels.
* @note The default resolution is 720p.
* @note This can only be used before calling \ref gfxInitDefault, this will use \ref fatalSimple otherwise. If the input is 0, the default resolution will be used during \ref gfxInitDefault. This sets the maximum resolution for the framebuffer, used during \ref gfxInitDefault. This is also used as the current resolution when crop isn't set. The width/height are reset to the default when \ref gfxExit is used.
* @note Normally you should only use this when you need a maximum resolution larger than the default, see above.
* @note The width and height are aligned to 4.
* @deprecated Use \ref nwindowSetDimensions instead.
*/
__attribute__((deprecated))
void gfxInitResolution(u32 width, u32 height);
/// Wrapper for \ref gfxInitResolution with resolution=1080p. Use this if you want to support 1080p or >720p in docked-mode.
/// \deprecated Use \ref nwindowSetDimensions instead.
__attribute__((deprecated))
void gfxInitResolutionDefault(void);
/// Configure framebuffer crop, by default crop is all-zero. Use all-zero input to reset to default. \ref gfxExit resets this to the default.
/// When the input is invalid this returns without changing the crop data, this includes the input values being larger than the framebuf width/height.
/// This will update the display width/height returned by \ref gfxGetFramebuffer, with that width/height being reset to the default when required.
/// \ref gfxGetFramebufferDisplayOffset uses absolute x/y, it will not adjust for non-zero crop left/top.
/// When used during frame-drawing, this should be called before \ref gfxGetFramebuffer.
/// The right and bottom params are aligned to 4.
/// \deprecated Use \ref nwindowSetCrop instead.
__attribute__((deprecated))
void gfxConfigureCrop(s32 left, s32 top, s32 right, s32 bottom);
/// Wrapper for \ref gfxConfigureCrop. Use this to set the resolution, within the bounds of the maximum resolution. Use all-zero input to reset to default.
/// \deprecated Use \ref nwindowSetCrop instead.
__attribute__((deprecated))
void gfxConfigureResolution(s32 width, s32 height);
/// If enabled, \ref gfxConfigureResolution will be used with the input resolution for the current OperationMode. Then \ref gfxConfigureResolution will automatically be used with the specified resolution each time OperationMode changes.
/// \deprecated No replacement. Manually query the current OperationMode and use \ref nwindowSetCrop instead.
__attribute__((deprecated))
void gfxConfigureAutoResolution(bool enable, s32 handheld_width, s32 handheld_height, s32 docked_width, s32 docked_height);
/// Wrapper for \ref gfxConfigureAutoResolution. handheld_resolution=720p, docked_resolution={all-zero for using current maximum resolution}.
/// \deprecated No replacement. Manually query the current OperationMode and use \ref nwindowSetCrop instead.
__attribute__((deprecated))
void gfxConfigureAutoResolutionDefault(bool enable);
/// Waits for vertical sync.
/// \deprecated No replacement. Waiting for vertical sync is neither necessary nor desirable with the system's compositor.
__attribute__((deprecated))
void gfxWaitForVsync(void);
/// Appends one or more fences that the display service will wait on before rendering the current framebuffer. Note that only up to 4 fences can be submitted.
/// \deprecated Use \ref nwindowQueueBuffer parameter \p fence instead.
__attribute__((deprecated))
void gfxAppendFence(NvMultiFence* mf);
/// Swaps the framebuffers.
/// \deprecated Use \ref framebufferBegin and \ref framebufferEnd, or \ref nwindowDequeueBuffer and \ref nwindowQueueBuffer instead.
__attribute__((deprecated))
void gfxSwapBuffers(void);
/// Get the specified framebuffer nvmap handle where index specifies the buffer number beginning with the back buffer, with optional output ptr for the offset in the buffer.
/// \deprecated No replacement.
__attribute__((deprecated))
u32 gfxGetFramebufferHandle(u32 index, u32* offset);
/// Get the current framebuffer address, with optional output ptrs for the display framebuffer width/height. The display width/height is adjusted by \ref gfxConfigureCrop and \ref gfxConfigureResolution.
/// \deprecated Check return value of \ref framebufferBegin instead.
__attribute__((deprecated))
u8* gfxGetFramebuffer(u32* width, u32* height);
/// Get the framebuffer width/height without crop.
/// \deprecated Use \ref nwindowGetDimensions instead.
__attribute__((deprecated))
void gfxGetFramebufferResolution(u32* width, u32* height);
/// Use this to get the actual byte-size of the framebuffer for use with memset/etc.
/// \deprecated No replacement.
__attribute__((deprecated))
size_t gfxGetFramebufferSize(void);
/// Use this to get the actual byte-pitch of the framebuffer for use with memset/etc.
/// \deprecated Use \ref framebufferBegin parameter \p out_stride instead.
__attribute__((deprecated))
u32 gfxGetFramebufferPitch(void);
/// Sets the \ref GfxMode.
/// \deprecated Use \ref framebufferMakeLinear instead.
__attribute__((deprecated))
void gfxSetMode(GfxMode mode);
/// Configures transform. See the NATIVE_WINDOW_TRANSFORM_* enums in buffer_producer.h. The default is 0.
/// \deprecated Use \ref nwindowSetTransform instead.
__attribute__((deprecated))
void gfxConfigureTransform(u32 transform);
/// Flushes the framebuffer in the data cache. When \ref GfxMode is GfxMode_LinearDouble, this also transfers the linear-framebuffer to the actual framebuffer.
/// \deprecated No replacement and no need to flush data cache manually when using \ref Framebuffer.
__attribute__((deprecated))
void gfxFlushBuffers(void);
/// Use this to get the pixel-offset in the framebuffer. Returned value is in pixels, not bytes.
/// This implements tegra blocklinear, with hard-coded constants etc.
/// Do not use this when \ref GfxMode is GfxMode_LinearDouble.
/// \deprecated No replacement. Use linear mode (\ref framebufferMakeLinear), or manually implement Tegra block linear layout with 16Bx2 sector ordering.
__attribute__((deprecated))
static inline u32 gfxGetFramebufferDisplayOffset(u32 x, u32 y) {
u32 tmp_pos;
extern size_t g_gfx_framebuf_aligned_width;
//if (x >= g_gfx_framebuf_width || y >= g_gfx_framebuf_display_height) return (gfxGetFramebufferSize()-4)/4;//Return the last pixel-offset in the buffer, the data located here is not displayed due to alignment. (Disabled for perf)
tmp_pos = ((y & 127) / 16) + (x/16*8) + ((y/16/8)*(g_gfx_framebuf_aligned_width/16*8));
tmp_pos *= 16*16 * 4;
tmp_pos += ((y%16)/8)*512 + ((x%16)/8)*256 + ((y%8)/2)*64 + ((x%8)/4)*32 + (y%2)*16 + (x%4)*4;//This line is a modified version of code from the Tegra X1 datasheet.
return tmp_pos / 4;
}

View File

@ -1,522 +0,0 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <string.h>
#include <malloc.h>
#include "types.h"
#include "result.h"
#include "arm/cache.h"
#include "services/fatal.h"
#include "services/vi.h"
#include "services/applet.h"
#include "services/nv.h"
#include "display/binder.h"
#include "display/buffer_producer.h"
#include "display/gfx.h"
#include "nvidia/map.h"
#include "nvidia/graphic_buffer.h"
__attribute__((weak)) ViServiceType __nx_gfx_vi_service_type = ViServiceType_Default;
static bool g_gfxInitialized = 0;
static ViDisplay g_gfxDisplay;
static Event g_gfxDisplayVsyncEvent;
static ViLayer g_gfxLayer;
static Binder g_gfxBinderSession;
static Event g_gfxBinderEvent;
static s32 g_gfxCurrentBuffer = 0;
static s32 g_gfxCurrentProducerBuffer = 0;
static bool g_gfx_ProducerConnected = 0;
static u32 g_gfx_ProducerSlotsRequested = 0;
static u8 *g_gfxFramebuf;
static size_t g_gfxFramebufSize;
static BqBufferOutput g_gfx_Connect_QueueBufferOutput;
static BqBufferOutput g_gfx_QueueBuffer_QueueBufferOutput;
static GfxMode g_gfxMode = GfxMode_LinearDouble;
static u8 *g_gfxFramebufLinear;
size_t g_gfx_framebuf_width=0, g_gfx_framebuf_aligned_width=0;
size_t g_gfx_framebuf_height=0, g_gfx_framebuf_aligned_height=0;
size_t g_gfx_framebuf_display_width=0, g_gfx_framebuf_display_height=0;
size_t g_gfx_singleframebuf_size=0;
size_t g_gfx_singleframebuf_linear_size=0;
static AppletHookCookie g_gfx_autoresolution_applethookcookie;
static bool g_gfx_autoresolution_enabled;
static s32 g_gfx_autoresolution_handheld_width;
static s32 g_gfx_autoresolution_handheld_height;
static s32 g_gfx_autoresolution_docked_width;
static s32 g_gfx_autoresolution_docked_height;
extern u32 __nx_applet_type;
static const u32 g_nvgfx_totalframebufs = 2;
static NvMap g_nvmap_obj;
//static Result _gfxGetDisplayResolution(u64 *width, u64 *height);
// TODO: Let the user configure some of this?
static BqBufferInput g_gfxQueueBufferData = {
.timestamp = 0x0,
.isAutoTimestamp = 0x1,
.crop = {0x0, 0x0, 0x0, 0x0}, //Official apps which use multiple resolutions configure this for the currently used resolution, depending on the current appletOperationMode.
.scalingMode = 0x0,
.transform = 0,
.stickyTransform = 0x0,
.unk = 0x0,
.swapInterval = 0x1,
.fence = {0},
};
static NvGraphicBuffer g_gfx_GraphicBuffer = {
.header = {
.num_ints = (sizeof(NvGraphicBuffer) - sizeof(NativeHandle)) / 4,
},
.unk0 = -1,
.magic = 0xDAFFCAFF,
.pid = 42,
.usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
.format = PIXEL_FORMAT_RGBA_8888,
.ext_format = PIXEL_FORMAT_RGBA_8888,
.num_planes = 1,
.planes = {
{
.color_format = NvColorFormat_A8B8G8R8,
.layout = NvLayout_BlockLinear,
.kind = NvKind_Generic_16BX2,
.block_height_log2 = 4, // i.e. block height is 16 which is the preferred value according to TRM
}
}
};
static BqGraphicBuffer g_gfx_BufferInitData = {
.format = PIXEL_FORMAT_RGBA_8888,
.usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
.native_handle = &g_gfx_GraphicBuffer.header,
};
static Result _gfxDequeueBuffer(void) {
if (g_gfxCurrentProducerBuffer >= 0)
return 0;
NvMultiFence fence;
s32 slot;
Result rc;
if (g_gfxBinderEvent.revent != INVALID_HANDLE) {
do {
eventWait(&g_gfxBinderEvent, U64_MAX);
rc = bqDequeueBuffer(&g_gfxBinderSession, true, g_gfx_framebuf_width, g_gfx_framebuf_height, 0, 0x300, &slot, &fence);
} while (rc == MAKERESULT(Module_LibnxBinder, LibnxBinderError_WouldBlock));
}
else
rc = bqDequeueBuffer(&g_gfxBinderSession, false, g_gfx_framebuf_width, g_gfx_framebuf_height, 0, 0x300, &slot, &fence);
if (R_FAILED(rc))
return rc;
if (!(g_gfx_ProducerSlotsRequested & BIT(slot))) {
rc = bqRequestBuffer(&g_gfxBinderSession, slot, NULL);
if (R_FAILED(rc)) {
bqCancelBuffer(&g_gfxBinderSession, slot, &fence);
return rc;
}
g_gfx_ProducerSlotsRequested |= BIT(slot);
}
rc = nvMultiFenceWait(&fence, -1);
if (R_FAILED(rc))
return rc;
if (R_SUCCEEDED(rc)) {
g_gfxCurrentProducerBuffer = slot;
g_gfxCurrentBuffer = g_gfxCurrentProducerBuffer;
}
return rc;
}
void gfxAppendFence(NvMultiFence* mf) {
u32 max_fences = 4 - g_gfxQueueBufferData.fence.num_fences;
u32 num_fences = max_fences < mf->num_fences ? max_fences : mf->num_fences;
for (u32 i = 0; i < num_fences; i ++)
g_gfxQueueBufferData.fence.fences[g_gfxQueueBufferData.fence.num_fences++] = mf->fences[i];
}
static Result _gfxQueueBuffer(void) {
Result rc=0;
if (g_gfxCurrentProducerBuffer >= 0) {
rc = bqQueueBuffer(&g_gfxBinderSession, g_gfxCurrentProducerBuffer, &g_gfxQueueBufferData, &g_gfx_QueueBuffer_QueueBufferOutput);
g_gfxQueueBufferData.fence.num_fences = 0;
g_gfxCurrentProducerBuffer = -1;
}
return rc;
}
static Result _gfxCancelBuffer(void) {
Result rc=0;
if (g_gfxCurrentProducerBuffer >= 0) {
rc = bqCancelBuffer(&g_gfxBinderSession, g_gfxCurrentProducerBuffer, &g_gfxQueueBufferData.fence);
g_gfxQueueBufferData.fence.num_fences = 0;
g_gfxCurrentProducerBuffer = -1;
}
return rc;
}
Result gfxInitDefault(void) {
Result rc=0;
if(g_gfxInitialized)return 0;
g_gfxCurrentBuffer = -1;
g_gfxCurrentProducerBuffer = -1;
g_gfx_ProducerConnected = 0;
g_gfxFramebuf = NULL;
g_gfxFramebufSize = 0;
g_gfxMode = GfxMode_LinearDouble;
g_gfxQueueBufferData.transform = 0;
//memset(g_gfx_ProducerSlotsRequested, 0, sizeof(g_gfx_ProducerSlotsRequested));
g_gfx_ProducerSlotsRequested = 0;
if (g_gfx_framebuf_width==0 || g_gfx_framebuf_height==0) {
g_gfx_framebuf_width = 1280;
g_gfx_framebuf_height = 720;
}
g_gfx_framebuf_display_width = g_gfx_framebuf_width;
g_gfx_framebuf_display_height = g_gfx_framebuf_height;
g_gfx_framebuf_aligned_width = (g_gfx_framebuf_width+15) & ~15;//Align to 16.
g_gfx_framebuf_aligned_height = (g_gfx_framebuf_height+127) & ~127;//Align to 128.
g_gfx_singleframebuf_size = g_gfx_framebuf_aligned_width*g_gfx_framebuf_aligned_height*4;
g_gfx_singleframebuf_linear_size = g_gfx_framebuf_width*g_gfx_framebuf_height*4;
g_gfx_BufferInitData.width = g_gfx_framebuf_width;
g_gfx_BufferInitData.height = g_gfx_framebuf_height;
g_gfx_BufferInitData.stride = g_gfx_framebuf_aligned_width;
g_gfx_GraphicBuffer.stride = g_gfx_framebuf_aligned_width;
g_gfx_GraphicBuffer.total_size = g_gfx_singleframebuf_size;
g_gfx_GraphicBuffer.planes[0].width = g_gfx_framebuf_width;
g_gfx_GraphicBuffer.planes[0].height = g_gfx_framebuf_height;
g_gfx_GraphicBuffer.planes[0].pitch = g_gfx_framebuf_aligned_width*4;
g_gfx_GraphicBuffer.planes[0].size = g_gfx_singleframebuf_size;
g_gfxFramebufLinear = memalign(0x1000, g_gfx_singleframebuf_linear_size);
if (g_gfxFramebufLinear) {
memset(g_gfxFramebufLinear, 0, g_gfx_singleframebuf_linear_size);
}
else {
rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
return rc;
}
g_gfxFramebufSize = g_nvgfx_totalframebufs*g_gfx_singleframebuf_size;
g_gfxFramebufSize = (g_gfxFramebufSize + 0xFFF) &~ 0xFFF; // page align
g_gfxFramebuf = memalign(0x1000, g_gfxFramebufSize);
if (!g_gfxFramebuf) {
free(g_gfxFramebufLinear);
g_gfxFramebufLinear = NULL;
rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
return rc;
}
rc = viInitialize(__nx_gfx_vi_service_type);
if (R_SUCCEEDED(rc)) rc = viOpenDefaultDisplay(&g_gfxDisplay);
if (R_SUCCEEDED(rc)) rc = viGetDisplayVsyncEvent(&g_gfxDisplay, &g_gfxDisplayVsyncEvent);
if (R_SUCCEEDED(rc)) rc = viCreateLayer(&g_gfxDisplay, &g_gfxLayer);
if (R_SUCCEEDED(rc)) {
binderCreate(&g_gfxBinderSession, g_gfxLayer.igbp_binder_obj_id);
rc = binderInitSession(&g_gfxBinderSession);
}
if (R_SUCCEEDED(rc)) binderGetNativeHandle(&g_gfxBinderSession, 0x0f, &g_gfxBinderEvent); // a failure here is not fatal
if (R_SUCCEEDED(rc)) rc = viSetLayerScalingMode(&g_gfxLayer, ViScalingMode_Default);
if (R_SUCCEEDED(rc)) rc = bqConnect(&g_gfxBinderSession, NATIVE_WINDOW_API_CPU, 0, &g_gfx_Connect_QueueBufferOutput);
if (R_SUCCEEDED(rc)) g_gfx_ProducerConnected = true;
if (R_SUCCEEDED(rc)) rc = nvInitialize();
if (R_SUCCEEDED(rc)) rc = nvFenceInit();
if (R_SUCCEEDED(rc)) rc = nvMapInit();
if (R_SUCCEEDED(rc)) rc = nvMapCreate(&g_nvmap_obj, g_gfxFramebuf, g_gfxFramebufSize, 0x20000, NvKind_Pitch, true);
if (R_SUCCEEDED(rc)) {
g_gfx_GraphicBuffer.nvmap_id = nvMapGetId(&g_nvmap_obj);
for (s32 i = 0; i < g_nvgfx_totalframebufs; i ++) {
g_gfx_GraphicBuffer.planes[0].offset = g_gfx_singleframebuf_size*i;
rc = bqSetPreallocatedBuffer(&g_gfxBinderSession, i, &g_gfx_BufferInitData);
if (R_FAILED(rc))
break;
}
}
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer();
// todo: figure out if it's possible to wait for the 'Nintendo' logo screen to finish displaying (NSO, applet type: Application)
if (R_FAILED(rc)) {
if (g_gfx_ProducerConnected) {
_gfxCancelBuffer();
for(u32 i=0; i<32; i++) {
if (g_gfx_ProducerSlotsRequested & BIT(i)) bqDetachBuffer(&g_gfxBinderSession, i);
}
bqDisconnect(&g_gfxBinderSession, NATIVE_WINDOW_API_CPU);
nvMapClose(&g_nvmap_obj);
nvMapExit();
nvFenceExit();
nvExit();
}
eventClose(&g_gfxBinderEvent);
binderClose(&g_gfxBinderSession);
viCloseLayer(&g_gfxLayer);
eventClose(&g_gfxDisplayVsyncEvent);
viCloseDisplay(&g_gfxDisplay);
viExit();
free(g_gfxFramebuf);
free(g_gfxFramebufLinear);
g_gfxFramebufLinear = NULL;
g_gfxCurrentBuffer = 0;
g_gfxCurrentProducerBuffer = -1;
g_gfx_ProducerConnected = 0;
g_gfxFramebuf = NULL;
g_gfxFramebufSize = 0;
g_gfx_framebuf_width = 0;
g_gfx_framebuf_height = 0;
g_gfx_ProducerSlotsRequested = 0;
}
if (R_SUCCEEDED(rc)) g_gfxInitialized = 1;
return rc;
}
void gfxExit(void)
{
if (!g_gfxInitialized)
return;
if (g_gfx_ProducerConnected) {
_gfxCancelBuffer();
for(u32 i=0; i<32; i++) {
if (g_gfx_ProducerSlotsRequested & BIT(i)) bqDetachBuffer(&g_gfxBinderSession, i);
}
bqDisconnect(&g_gfxBinderSession, NATIVE_WINDOW_API_CPU);
nvMapClose(&g_nvmap_obj);
nvMapExit();
nvFenceExit();
nvExit();
}
eventClose(&g_gfxBinderEvent);
binderClose(&g_gfxBinderSession);
viCloseLayer(&g_gfxLayer);
eventClose(&g_gfxDisplayVsyncEvent);
viCloseDisplay(&g_gfxDisplay);
viExit();
free(g_gfxFramebuf);
free(g_gfxFramebufLinear);
g_gfxFramebufLinear = NULL;
g_gfxInitialized = 0;
g_gfxCurrentBuffer = 0;
g_gfxCurrentProducerBuffer = -1;
g_gfx_ProducerConnected = 0;
g_gfxFramebuf = NULL;
g_gfxFramebufSize = 0;
g_gfx_framebuf_width = 0;
g_gfx_framebuf_height = 0;
gfxConfigureAutoResolution(0, 0, 0, 0, 0);
g_gfx_ProducerSlotsRequested = 0;
memset(&g_gfxQueueBufferData.crop, 0, sizeof(g_gfxQueueBufferData.crop));
}
void gfxInitResolution(u32 width, u32 height) {
if (g_gfxInitialized) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized));
g_gfx_framebuf_width = (width+3) & ~3;
g_gfx_framebuf_height = (height+3) & ~3;
}
void gfxInitResolutionDefault(void) {
gfxInitResolution(1920, 1080);
}
void gfxConfigureCrop(s32 left, s32 top, s32 right, s32 bottom) {
if (right==0 || bottom==0) {
g_gfx_framebuf_display_width = g_gfx_framebuf_width;
g_gfx_framebuf_display_height = g_gfx_framebuf_height;
}
if (left < 0 || top < 0 || right < 0 || bottom < 0) return;
right = (right+3) & ~3;
bottom = (bottom+3) & ~3;
if (right < left || bottom < top) return;
if (left > g_gfx_framebuf_width || top > g_gfx_framebuf_height) return;
if (right > g_gfx_framebuf_width || bottom > g_gfx_framebuf_height) return;
g_gfxQueueBufferData.crop.left = left;
g_gfxQueueBufferData.crop.top = top;
g_gfxQueueBufferData.crop.right = right;
g_gfxQueueBufferData.crop.bottom = bottom;
if (right!=0 && bottom!=0) {
g_gfx_framebuf_display_width = right;
g_gfx_framebuf_display_height = bottom;
}
}
void gfxConfigureResolution(s32 width, s32 height) {
gfxConfigureCrop(0, 0, width, height);
}
static void _gfxAutoResolutionAppletHook(AppletHookType hook, void* param) {
u8 mode=0;
if (hook != AppletHookType_OnOperationMode)
return;
mode = appletGetOperationMode();
if (mode == AppletOperationMode_Handheld) {
gfxConfigureResolution(g_gfx_autoresolution_handheld_width, g_gfx_autoresolution_handheld_height);
}
else if (mode == AppletOperationMode_Docked) {
gfxConfigureResolution(g_gfx_autoresolution_docked_width, g_gfx_autoresolution_docked_height);
}
}
void gfxConfigureAutoResolution(bool enable, s32 handheld_width, s32 handheld_height, s32 docked_width, s32 docked_height) {
if (g_gfx_autoresolution_enabled != enable) {
if(enable) appletHook(&g_gfx_autoresolution_applethookcookie, _gfxAutoResolutionAppletHook, 0);
if (!enable) appletUnhook(&g_gfx_autoresolution_applethookcookie);
}
g_gfx_autoresolution_enabled = enable;
g_gfx_autoresolution_handheld_width = handheld_width;
g_gfx_autoresolution_handheld_height = handheld_height;
g_gfx_autoresolution_docked_width = docked_width;
g_gfx_autoresolution_docked_height = docked_height;
if (enable) _gfxAutoResolutionAppletHook(AppletHookType_OnOperationMode, 0);
if (!enable) gfxConfigureResolution(0, 0);
}
void gfxConfigureAutoResolutionDefault(bool enable) {
gfxConfigureAutoResolution(enable, 1280, 720, 0, 0);
}
void gfxWaitForVsync(void) {
Result rc = eventWait(&g_gfxDisplayVsyncEvent, U64_MAX);
if (R_FAILED(rc))
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGfxEventWait));
}
void gfxSwapBuffers(void) {
Result rc=0;
rc = _gfxQueueBuffer();
if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGfxQueueBuffer));
rc = _gfxDequeueBuffer();
if (R_FAILED(rc)) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGfxDequeueBuffer));
}
u32 gfxGetFramebufferHandle(u32 index, u32* offset) {
if (offset) {
index = (g_gfxCurrentBuffer + index) & (g_nvgfx_totalframebufs-1);
*offset = index*g_gfx_singleframebuf_size;
}
return nvMapGetId(&g_nvmap_obj);
}
u8* gfxGetFramebuffer(u32* width, u32* height) {
if(width) *width = g_gfx_framebuf_display_width;
if(height) *height = g_gfx_framebuf_display_height;
if (g_gfxMode == GfxMode_LinearDouble)
return g_gfxFramebufLinear;
return &g_gfxFramebuf[g_gfxCurrentBuffer*g_gfx_singleframebuf_size];
}
void gfxGetFramebufferResolution(u32* width, u32* height) {
if(width) *width = g_gfx_framebuf_width;
if(height) *height = g_gfx_framebuf_height;
}
size_t gfxGetFramebufferSize(void) {
if (g_gfxMode == GfxMode_LinearDouble)
return g_gfx_singleframebuf_linear_size;
return g_gfx_singleframebuf_size;
}
u32 gfxGetFramebufferPitch(void) {
return g_gfx_framebuf_aligned_width*4;
}
void gfxSetMode(GfxMode mode) {
g_gfxMode = mode;
}
void gfxConfigureTransform(u32 transform) {
g_gfxQueueBufferData.transform = transform;
}
void gfxFlushBuffers(void) {
u32 *actual_framebuf = (u32*)&g_gfxFramebuf[g_gfxCurrentBuffer*g_gfx_singleframebuf_size];
if (g_gfxMode == GfxMode_LinearDouble) {
size_t x, y;
size_t width = g_gfx_framebuf_display_width;
size_t height = g_gfx_framebuf_display_height;
u32 *in_framebuf = (u32*)g_gfxFramebufLinear;
for (y=0; y<height; y++) {
for (x=0; x<width; x+=4) {
*((u128*)&actual_framebuf[gfxGetFramebufferDisplayOffset(x, y)]) = *((u128*)&in_framebuf[y * width + x]);
}
}
}
armDCacheFlush(actual_framebuf, g_gfx_singleframebuf_size);
}
/*static Result _gfxGetDisplayResolution(u64 *width, u64 *height) {
return viGetDisplayResolution(&g_gfxDisplay, width, height);
}*/