Added display+layer support. Started 'gfx'.

This commit is contained in:
yellows8 2017-11-03 12:31:30 -04:00
parent d62b909757
commit ec1faa34ef
8 changed files with 344 additions and 3 deletions

View File

@ -24,7 +24,7 @@ VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
#---------------------------------------------------------------------------------
TARGET := nx
#BUILD := build
SOURCES := source/system source/kernel source/services source/devices
SOURCES := source/system source/kernel source/services source/devices source/gfx
DATA := data
INCLUDES := include

View File

@ -31,6 +31,8 @@ extern "C" {
#include <switch/devices/usb_dev.h>
#include <switch/gfx/gfx.h>
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,3 @@
/// Do not use viInitialize/viExit when using these.
void gfxInitDefault(void);
void gfxExit(void);

View File

@ -12,3 +12,5 @@ typedef enum
Result appletInitialize(void);
void appletExit(void);
Result appletGetAppletResourceUserId(u64 *out);
Result appletCreateManagedDisplayLayer(u64 *out);

View File

@ -1,11 +1,27 @@
typedef enum
{
typedef struct {
u64 DisplayId;
char DisplayName[0x40];
bool initialized;
} viDisplay;
typedef struct {
u64 LayerId;
bool StrayLayer;
bool initialized;
} viLayer;
typedef enum {
VISERVTYPE_Default = -1,
VISERVTYPE_Application = 0,
VISERVTYPE_System = 1,
VISERVTYPE_Manager = 2,
} viServiceType;
/// Used by viOpenLayer when CreateStrayLayer is used internally.
typedef enum {
VILAYERFLAGS_Default = 0x1,
} viLayerFlags;
Result viInitialize(viServiceType servicetype);
void viExit(void);
Handle viGetSessionService(void);
@ -14,3 +30,8 @@ Handle viGetSession_IHOSBinderDriverRelay(void);
Handle viGetSession_ISystemDisplayService(void);
Handle viGetSession_IManagerDisplayService(void);
Handle viGetSession_IHOSBinderDriverIndirect(void);
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);

47
nx/source/gfx/gfx.c Normal file
View File

@ -0,0 +1,47 @@
#include <string.h>
#include <switch.h>
static bool g_gfxInitialized = 0;
static viDisplay g_gfxDisplay;
static viLayer g_gfxLayer;
static u8 g_gfxNativeWindow[0x100];
static u64 g_gfxNativeWindow_Size;
static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 LayerFlags, u64 LayerId) {
Result rc=0;
if(g_gfxInitialized)return 0;
rc = viInitialize(servicetype);
if (R_FAILED(rc)) return rc;
rc = viOpenDisplay(DisplayName, &g_gfxDisplay);
if (R_SUCCEEDED(rc)) rc = viOpenLayer(g_gfxNativeWindow, &g_gfxNativeWindow_Size, &g_gfxDisplay, &g_gfxLayer, LayerFlags, LayerId);
if (R_FAILED(rc)) {
viCloseDisplay(&g_gfxDisplay);
viExit();
}
if (R_SUCCEEDED(rc)) g_gfxInitialized = 1;
return 0;
}
void gfxInitDefault(void) {
Result rc = _gfxInit(VILAYERFLAGS_Default, "Default", VILAYERFLAGS_Default, 0);
if (R_FAILED(rc)) fatalSimple(rc);
}
void gfxExit(void) {
if(!g_gfxInitialized)return;
viCloseLayer(&g_gfxLayer);
viCloseDisplay(&g_gfxDisplay);
viExit();
g_gfxInitialized = 0;
}

View File

@ -309,3 +309,39 @@ static Result _appletNotifyRunning(u8 *out) {
return rc;
}
Result appletCreateManagedDisplayLayer(u64 *out) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 40;
Result rc = ipcDispatch(g_appletISelfController);
if (R_SUCCEEDED(rc)) {
IpcCommandResponse r;
ipcParseResponse(&r);
struct {
u64 magic;
u64 result;
u64 out;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*out = resp->out;
}
}
return rc;
}

View File

@ -163,3 +163,233 @@ static Result _viGetSessionNoParams(Handle sessionhandle, Handle* handle_out, u6
return _viGetSession(sessionhandle, handle_out, &raw, sizeof(raw));
}
Result viOpenDisplay(const char *DisplayName, viDisplay *display) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
char DisplayName[0x40];
} *raw;
memset(display, 0, sizeof(viDisplay));
raw = ipcPrepareHeader(&c, sizeof(raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 1010;
strncpy(display->DisplayName, DisplayName, sizeof(display->DisplayName)-1);
memcpy(raw->DisplayName, display->DisplayName, sizeof(display->DisplayName));
Result rc = ipcDispatch(g_viIApplicationDisplayService);
if (R_SUCCEEDED(rc)) {
IpcCommandResponse r;
ipcParseResponse(&r);
struct {
u64 magic;
u64 result;
u64 DisplayId;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
display->DisplayId = resp->DisplayId;
display->initialized = 1;
}
}
return rc;
}
Result viCloseDisplay(viDisplay *display) {
IpcCommand c;
ipcInitialize(&c);
if(!display->initialized)return 0;
struct {
u64 magic;
u64 cmd_id;
u64 DisplayId;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 1020;
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;
display->initialized = 0;
}
return rc;
}
static Result _viOpenLayer(u8 NativeWindow[0x100], u64 *NativeWindow_Size, const viDisplay *display, u64 LayerId, u64 AppletResourceUserId) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
char DisplayName[0x40];
u64 LayerId;
u64 AppletResourceUserId;
} *raw;
ipcSendPid(&c);
ipcAddRecvBuffer(&c, NativeWindow, 0x100, 0);
raw = ipcPrepareHeader(&c, sizeof(raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 2020;
memcpy(raw->DisplayName, display->DisplayName, sizeof(display->DisplayName));
raw->LayerId = LayerId;
raw->AppletResourceUserId = AppletResourceUserId;
Result rc = ipcDispatch(g_viIApplicationDisplayService);
if (R_SUCCEEDED(rc)) {
IpcCommandResponse r;
ipcParseResponse(&r);
struct {
u64 magic;
u64 result;
u64 NativeWindow_Size;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*NativeWindow_Size = resp->NativeWindow_Size;
}
}
return rc;
}
static Result _viCreateStrayLayer(u8 NativeWindow[0x100], u64 *NativeWindow_Size, const viDisplay *display, u32 LayerFlags, u64 *LayerId) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 LayerFlags;
u32 pad;
u64 DisplayId;
} *raw;
ipcAddRecvBuffer(&c, NativeWindow, 0x100, 0);
raw = ipcPrepareHeader(&c, sizeof(raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 2030;
raw->LayerFlags = LayerFlags;
raw->DisplayId = display->DisplayId;
Result rc = ipcDispatch(g_viIApplicationDisplayService);
if (R_SUCCEEDED(rc)) {
IpcCommandResponse r;
ipcParseResponse(&r);
struct {
u64 magic;
u64 result;
u64 LayerId;
u64 NativeWindow_Size;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*LayerId = resp->LayerId;
*NativeWindow_Size = resp->NativeWindow_Size;
}
}
return rc;
}
Result viOpenLayer(u8 NativeWindow[0x100], u64 *NativeWindow_Size, const viDisplay *display, viLayer *layer, u32 LayerFlags, u64 LayerId) {
Result rc = 0;
u64 AppletResourceUserId = 0;
memset(layer, 0, sizeof(viLayer));
if (LayerId==0) rc = appletGetAppletResourceUserId(&AppletResourceUserId);
if (LayerId==0 && (R_FAILED(rc) || AppletResourceUserId == 0)) {
rc = _viCreateStrayLayer(NativeWindow, NativeWindow_Size, display, LayerFlags, &layer->LayerId);
}
else {
if (LayerId==0) {
rc = appletCreateManagedDisplayLayer(&LayerId);
if (R_FAILED(rc)) return rc;
}
rc = _viOpenLayer(NativeWindow, NativeWindow_Size, display, LayerId, AppletResourceUserId);
if (R_SUCCEEDED(rc)) layer->LayerId = LayerId;
}
if (R_SUCCEEDED(rc)) layer->initialized = 1;
return rc;
}
Result viCloseLayer(viLayer *layer) {
IpcCommand c;
ipcInitialize(&c);
if(!layer->initialized)return 0;
struct {
u64 magic;
u64 cmd_id;
u64 LayerId;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = layer->StrayLayer==0 ? 2021 : 2031;
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;
memset(layer, 0, sizeof(viLayer));
}
return rc;
}