mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-05 16:09:24 +02:00
display/binder.h: refactoring and other changes:
- Removed session_handle/native_handle state - Consequence of the above: simplified binderCreate/binderInitSession - Now using viGetSession_IHOSBinderDriverRelay internally - Changed binderGetNativeHandle to return an Event - Added readable aliases for binderAdjustRefcount - gfx: now using async bqDequeueBuffer when the binder event is available
This commit is contained in:
parent
60cbb68f46
commit
819a6f0d89
@ -1,23 +1,22 @@
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "../kernel/event.h"
|
||||
|
||||
#define BINDER_FIRST_CALL_TRANSACTION 0x1
|
||||
|
||||
typedef struct {
|
||||
bool created;
|
||||
bool initialized;
|
||||
Handle session_handle;
|
||||
bool created : 1;
|
||||
bool initialized : 1;
|
||||
bool has_transact_auto : 1;
|
||||
s32 id;
|
||||
Handle native_handle;
|
||||
size_t ipc_buffer_size;
|
||||
bool has_transact_auto;
|
||||
} Binder;
|
||||
|
||||
// Note: binderClose will not close the session_handle provided to binderCreate.
|
||||
void binderCreate(Binder* b, Handle session_handle, s32 id);
|
||||
void binderCreate(Binder* b, s32 id);
|
||||
void binderClose(Binder* b);
|
||||
|
||||
Result binderInitSession(Binder* b, u32 unk0);
|
||||
Result binderInitSession(Binder* b);
|
||||
|
||||
Result binderTransactParcel(
|
||||
Binder* b, u32 code,
|
||||
@ -26,5 +25,24 @@ Result binderTransactParcel(
|
||||
u32 flags);
|
||||
|
||||
Result binderAdjustRefcount(Binder* b, s32 addval, s32 type);
|
||||
Result binderGetNativeHandle(Binder* b, u32 unk0, Handle *handle_out);
|
||||
Result binderGetNativeHandle(Binder* b, u32 unk0, Event *event_out);
|
||||
|
||||
static inline Result binderIncreaseWeakRef(Binder* b)
|
||||
{
|
||||
return binderAdjustRefcount(b, 1, 0);
|
||||
}
|
||||
|
||||
static inline Result binderDecreaseWeakRef(Binder* b)
|
||||
{
|
||||
return binderAdjustRefcount(b, -1, 0);
|
||||
}
|
||||
|
||||
static inline Result binderIncreaseStrongRef(Binder* b)
|
||||
{
|
||||
return binderAdjustRefcount(b, 1, 1);
|
||||
}
|
||||
|
||||
static inline Result binderDecreaseStrongRef(Binder* b)
|
||||
{
|
||||
return binderAdjustRefcount(b, -1, 1);
|
||||
}
|
||||
|
@ -3,19 +3,22 @@
|
||||
#include "result.h"
|
||||
#include "kernel/ipc.h"
|
||||
#include "kernel/detect.h"
|
||||
#include "services/vi.h"
|
||||
#include "display/binder.h"
|
||||
|
||||
void binderCreate(Binder* b, Handle session_handle, s32 id)
|
||||
static Result _binderIpcDispatch(void)
|
||||
{
|
||||
return serviceIpcDispatch(viGetSession_IHOSBinderDriverRelay());
|
||||
}
|
||||
|
||||
void binderCreate(Binder* b, s32 id)
|
||||
{
|
||||
memset(b, 0, sizeof(Binder));
|
||||
b->created = true;
|
||||
b->session_handle = session_handle;
|
||||
b->id = id;
|
||||
b->native_handle = INVALID_HANDLE;
|
||||
b->has_transact_auto = false;
|
||||
}
|
||||
|
||||
Result binderInitSession(Binder* b, u32 unk0)
|
||||
Result binderInitSession(Binder* b)
|
||||
{
|
||||
Result rc = 0;
|
||||
|
||||
@ -25,37 +28,19 @@ Result binderInitSession(Binder* b, u32 unk0)
|
||||
if (b->initialized)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
|
||||
|
||||
rc = binderAdjustRefcount(b, 1, 0);
|
||||
|
||||
rc = binderIncreaseWeakRef(b);
|
||||
if (R_FAILED(rc))
|
||||
return rc;
|
||||
|
||||
rc = binderAdjustRefcount(b, 1, 1);
|
||||
|
||||
rc = binderIncreaseStrongRef(b);
|
||||
if (R_FAILED(rc)) {
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
binderDecreaseStrongRef(b);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = binderGetNativeHandle(b, unk0, &b->native_handle);
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
binderAdjustRefcount(b, -1, 1);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// When the output native_handle is 0 the Binder ID is probably invalid.
|
||||
if (b->native_handle == 0) {
|
||||
binderAdjustRefcount(b, -1, 1);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
}
|
||||
|
||||
b->initialized = true;
|
||||
|
||||
rc = ipcQueryPointerBufferSize(b->session_handle, &b->ipc_buffer_size);
|
||||
|
||||
rc = ipcQueryPointerBufferSize(viGetSession_IHOSBinderDriverRelay()->handle, &b->ipc_buffer_size);
|
||||
if (R_FAILED(rc)) {
|
||||
binderClose(b);
|
||||
return rc;
|
||||
@ -74,16 +59,10 @@ void binderClose(Binder* b)
|
||||
return;
|
||||
|
||||
if (b->initialized) {
|
||||
binderAdjustRefcount(b, -1, 1);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
|
||||
if (b->native_handle != INVALID_HANDLE) {
|
||||
svcCloseHandle(b->native_handle);
|
||||
b->native_handle = INVALID_HANDLE;
|
||||
}
|
||||
binderDecreaseStrongRef(b);
|
||||
binderDecreaseWeakRef(b);
|
||||
}
|
||||
|
||||
b->session_handle = INVALID_HANDLE;
|
||||
b->id = 0;
|
||||
|
||||
b->created = false;
|
||||
@ -120,7 +99,7 @@ static Result _binderTransactParcel(
|
||||
raw->code = code;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
Result rc = _binderIpcDispatch();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -167,7 +146,7 @@ static Result _binderTransactParcelAuto(
|
||||
raw->code = code;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
Result rc = _binderIpcDispatch();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -223,7 +202,7 @@ Result binderAdjustRefcount(Binder* b, s32 addval, s32 type)
|
||||
raw->addval = addval;
|
||||
raw->type = type;
|
||||
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
Result rc = _binderIpcDispatch();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -240,7 +219,7 @@ Result binderAdjustRefcount(Binder* b, s32 addval, s32 type)
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result binderGetNativeHandle(Binder* b, u32 inval, Handle *handle_out)
|
||||
Result binderGetNativeHandle(Binder* b, u32 inval, Event *event_out)
|
||||
{
|
||||
if (!b->created)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
@ -262,7 +241,7 @@ Result binderGetNativeHandle(Binder* b, u32 inval, Handle *handle_out)
|
||||
raw->session_id = b->id;
|
||||
raw->inval = inval;
|
||||
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
Result rc = _binderIpcDispatch();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -276,7 +255,7 @@ Result binderGetNativeHandle(Binder* b, u32 inval, Handle *handle_out)
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*handle_out = r.Handles[0];
|
||||
eventLoadRemote(event_out, r.Handles[0], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ 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;
|
||||
@ -102,8 +103,19 @@ static Result _gfxDequeueBuffer(void) {
|
||||
|
||||
NvMultiFence fence;
|
||||
s32 slot;
|
||||
Result rc = bqDequeueBuffer(&g_gfxBinderSession, false, g_gfx_framebuf_width, g_gfx_framebuf_height, 0, 0x300, &slot, &fence);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
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_Libnx, LibnxError_BufferProducerError)); // todo: check for error -11
|
||||
}
|
||||
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);
|
||||
@ -199,10 +211,12 @@ Result gfxInitDefault(void) {
|
||||
if (R_SUCCEEDED(rc)) rc = viCreateLayer(&g_gfxDisplay, &g_gfxLayer);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
binderCreate(&g_gfxBinderSession, viGetSession_IHOSBinderDriverRelay()->handle, g_gfxLayer.igbp_binder_obj_id);
|
||||
rc = binderInitSession(&g_gfxBinderSession, 0x0f);
|
||||
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);
|
||||
@ -233,6 +247,7 @@ Result gfxInitDefault(void) {
|
||||
nvExit();
|
||||
}
|
||||
|
||||
eventClose(&g_gfxBinderEvent);
|
||||
binderClose(&g_gfxBinderSession);
|
||||
viCloseLayer(&g_gfxLayer);
|
||||
eventClose(&g_gfxDisplayVsyncEvent);
|
||||
@ -276,6 +291,7 @@ void gfxExit(void)
|
||||
nvExit();
|
||||
}
|
||||
|
||||
eventClose(&g_gfxBinderEvent);
|
||||
binderClose(&g_gfxBinderSession);
|
||||
viCloseLayer(&g_gfxLayer);
|
||||
eventClose(&g_gfxDisplayVsyncEvent);
|
||||
|
Loading…
Reference in New Issue
Block a user