mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 04:22:50 +02:00
Implemented viSetLayerScalingMode(). Implemented vsync handling. Minor other change.
This commit is contained in:
parent
d0c9d8294d
commit
b5abd52b8b
@ -1,3 +1,4 @@
|
||||
/// Do not use viInitialize/viExit when using these.
|
||||
void gfxInitDefault(void);
|
||||
void gfxExit(void);
|
||||
void gfxWaitForVsync();
|
||||
|
@ -22,6 +22,11 @@ typedef enum {
|
||||
VILAYERFLAGS_Default = 0x1,
|
||||
} viLayerFlags;
|
||||
|
||||
/// Used with viSetLayerScalingMode.
|
||||
typedef enum {
|
||||
VISCALINGMODE_Default = 0x2,
|
||||
} viScalingMode;
|
||||
|
||||
Result viInitialize(viServiceType servicetype);
|
||||
void viExit(void);
|
||||
Handle viGetSessionService(void);
|
||||
@ -35,3 +40,8 @@ Result viOpenDisplay(const char *DisplayName, viDisplay *display);
|
||||
Result viCloseDisplay(viDisplay *display);
|
||||
Result viOpenLayer(u8 NativeWindow[0x100], u64 *NativeWindow_Size, const viDisplay *display, viLayer *layer, u32 LayerFlags, u64 LayerId);
|
||||
Result viCloseLayer(viLayer *layer);
|
||||
|
||||
/// See viScalingMode.
|
||||
Result viSetLayerScalingMode(viLayer *layer, u32 ScalingMode);
|
||||
|
||||
Result viGetDisplayVsyncEvent(viDisplay *display, Handle *handle_out);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
static bool g_gfxInitialized = 0;
|
||||
static viDisplay g_gfxDisplay;
|
||||
static Handle g_gfxDisplayVsyncEvent = INVALID_HANDLE;
|
||||
static viLayer g_gfxLayer;
|
||||
static u8 g_gfxNativeWindow[0x100];
|
||||
static u64 g_gfxNativeWindow_Size;
|
||||
@ -30,14 +31,19 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
|
||||
if(g_gfxInitialized)return 0;
|
||||
|
||||
g_gfxNativeWindow_ID = 0;
|
||||
g_gfxDisplayVsyncEvent = INVALID_HANDLE;
|
||||
|
||||
rc = viInitialize(servicetype);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
rc = viOpenDisplay(DisplayName, &g_gfxDisplay);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = viGetDisplayVsyncEvent(&g_gfxDisplay, &g_gfxDisplayVsyncEvent);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = viOpenLayer(g_gfxNativeWindow, &g_gfxNativeWindow_Size, &g_gfxDisplay, &g_gfxLayer, LayerFlags, LayerId);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = viSetLayerScalingMode(&g_gfxLayer, VISCALINGMODE_Default);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _gfxGetNativeWindowID(g_gfxNativeWindow, g_gfxNativeWindow_Size, &g_gfxNativeWindow_ID);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
@ -70,6 +76,12 @@ void gfxExit(void) {
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
|
||||
viCloseLayer(&g_gfxLayer);
|
||||
|
||||
if(g_gfxDisplayVsyncEvent != INVALID_HANDLE) {
|
||||
svcCloseHandle(g_gfxDisplayVsyncEvent);
|
||||
g_gfxDisplayVsyncEvent = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
viCloseDisplay(&g_gfxDisplay);
|
||||
|
||||
viExit();
|
||||
@ -78,3 +90,9 @@ void gfxExit(void) {
|
||||
g_gfxNativeWindow_ID = 0;
|
||||
}
|
||||
|
||||
void gfxWaitForVsync() {
|
||||
s32 tmpindex=0;
|
||||
svcClearEvent(g_gfxDisplayVsyncEvent);
|
||||
svcWaitSynchronization(&tmpindex, &g_gfxDisplayVsyncEvent, 1, U64_MAX);
|
||||
}
|
||||
|
||||
|
@ -305,6 +305,7 @@ static Result _viCreateStrayLayer(u8 NativeWindow[0x100], u64 *NativeWindow_Size
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2030;
|
||||
raw->LayerFlags = LayerFlags;
|
||||
raw->pad = 0;
|
||||
raw->DisplayId = display->DisplayId;
|
||||
|
||||
Result rc = ipcDispatch(g_viIApplicationDisplayService);
|
||||
@ -394,3 +395,78 @@ Result viCloseLayer(viLayer *layer) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result viSetLayerScalingMode(viLayer *layer, u32 ScalingMode) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
if (!layer->initialized) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 ScalingMode;
|
||||
u32 pad;
|
||||
u64 LayerId;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2101;
|
||||
raw->ScalingMode = ScalingMode;
|
||||
raw->pad = 0;
|
||||
raw->LayerId = layer->LayerId;
|
||||
|
||||
Result rc = ipcDispatch(g_viIApplicationDisplayService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result viGetDisplayVsyncEvent(viDisplay *display, Handle *handle_out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 DisplayId;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 5202;
|
||||
raw->DisplayId = display->DisplayId;
|
||||
|
||||
Result rc = ipcDispatch(g_viIApplicationDisplayService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*handle_out = r.Handles[0];
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user