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:
fincs 2018-08-31 12:59:10 +02:00
parent 60cbb68f46
commit 819a6f0d89
3 changed files with 66 additions and 53 deletions

View File

@ -1,23 +1,22 @@
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../kernel/event.h"
#define BINDER_FIRST_CALL_TRANSACTION 0x1 #define BINDER_FIRST_CALL_TRANSACTION 0x1
typedef struct { typedef struct {
bool created; bool created : 1;
bool initialized; bool initialized : 1;
Handle session_handle; bool has_transact_auto : 1;
s32 id; s32 id;
Handle native_handle;
size_t ipc_buffer_size; size_t ipc_buffer_size;
bool has_transact_auto;
} Binder; } Binder;
// Note: binderClose will not close the session_handle provided to binderCreate. // 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); void binderClose(Binder* b);
Result binderInitSession(Binder* b, u32 unk0); Result binderInitSession(Binder* b);
Result binderTransactParcel( Result binderTransactParcel(
Binder* b, u32 code, Binder* b, u32 code,
@ -26,5 +25,24 @@ Result binderTransactParcel(
u32 flags); u32 flags);
Result binderAdjustRefcount(Binder* b, s32 addval, s32 type); 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);
}

View File

@ -3,19 +3,22 @@
#include "result.h" #include "result.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/detect.h" #include "kernel/detect.h"
#include "services/vi.h"
#include "display/binder.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)); memset(b, 0, sizeof(Binder));
b->created = true; b->created = true;
b->session_handle = session_handle;
b->id = id; 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; Result rc = 0;
@ -25,37 +28,19 @@ Result binderInitSession(Binder* b, u32 unk0)
if (b->initialized) if (b->initialized)
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
rc = binderAdjustRefcount(b, 1, 0); rc = binderIncreaseWeakRef(b);
if (R_FAILED(rc)) if (R_FAILED(rc))
return rc; return rc;
rc = binderAdjustRefcount(b, 1, 1); rc = binderIncreaseStrongRef(b);
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
binderAdjustRefcount(b, -1, 0); binderDecreaseStrongRef(b);
return rc; 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; 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)) { if (R_FAILED(rc)) {
binderClose(b); binderClose(b);
return rc; return rc;
@ -74,16 +59,10 @@ void binderClose(Binder* b)
return; return;
if (b->initialized) { if (b->initialized) {
binderAdjustRefcount(b, -1, 1); binderDecreaseStrongRef(b);
binderAdjustRefcount(b, -1, 0); binderDecreaseWeakRef(b);
if (b->native_handle != INVALID_HANDLE) {
svcCloseHandle(b->native_handle);
b->native_handle = INVALID_HANDLE;
}
} }
b->session_handle = INVALID_HANDLE;
b->id = 0; b->id = 0;
b->created = false; b->created = false;
@ -120,7 +99,7 @@ static Result _binderTransactParcel(
raw->code = code; raw->code = code;
raw->flags = flags; raw->flags = flags;
Result rc = ipcDispatch(b->session_handle); Result rc = _binderIpcDispatch();
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -167,7 +146,7 @@ static Result _binderTransactParcelAuto(
raw->code = code; raw->code = code;
raw->flags = flags; raw->flags = flags;
Result rc = ipcDispatch(b->session_handle); Result rc = _binderIpcDispatch();
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -223,7 +202,7 @@ Result binderAdjustRefcount(Binder* b, s32 addval, s32 type)
raw->addval = addval; raw->addval = addval;
raw->type = type; raw->type = type;
Result rc = ipcDispatch(b->session_handle); Result rc = _binderIpcDispatch();
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -240,7 +219,7 @@ Result binderAdjustRefcount(Binder* b, s32 addval, s32 type)
return rc; return rc;
} }
Result binderGetNativeHandle(Binder* b, u32 inval, Handle *handle_out) Result binderGetNativeHandle(Binder* b, u32 inval, Event *event_out)
{ {
if (!b->created) if (!b->created)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); 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->session_id = b->id;
raw->inval = inval; raw->inval = inval;
Result rc = ipcDispatch(b->session_handle); Result rc = _binderIpcDispatch();
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -276,7 +255,7 @@ Result binderGetNativeHandle(Binder* b, u32 inval, Handle *handle_out)
rc = resp->result; rc = resp->result;
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
*handle_out = r.Handles[0]; eventLoadRemote(event_out, r.Handles[0], false);
} }
} }

View File

@ -17,6 +17,7 @@ static ViDisplay g_gfxDisplay;
static Event g_gfxDisplayVsyncEvent; static Event g_gfxDisplayVsyncEvent;
static ViLayer g_gfxLayer; static ViLayer g_gfxLayer;
static Binder g_gfxBinderSession; static Binder g_gfxBinderSession;
static Event g_gfxBinderEvent;
static s32 g_gfxCurrentBuffer = 0; static s32 g_gfxCurrentBuffer = 0;
static s32 g_gfxCurrentProducerBuffer = 0; static s32 g_gfxCurrentProducerBuffer = 0;
static bool g_gfx_ProducerConnected = 0; static bool g_gfx_ProducerConnected = 0;
@ -102,8 +103,19 @@ static Result _gfxDequeueBuffer(void) {
NvMultiFence fence; NvMultiFence fence;
s32 slot; s32 slot;
Result rc = bqDequeueBuffer(&g_gfxBinderSession, false, g_gfx_framebuf_width, g_gfx_framebuf_height, 0, 0x300, &slot, &fence); Result rc;
if (R_FAILED(rc)) return 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))) { if (!(g_gfx_ProducerSlotsRequested & BIT(slot))) {
rc = bqRequestBuffer(&g_gfxBinderSession, slot, NULL); 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)) rc = viCreateLayer(&g_gfxDisplay, &g_gfxLayer);
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
binderCreate(&g_gfxBinderSession, viGetSession_IHOSBinderDriverRelay()->handle, g_gfxLayer.igbp_binder_obj_id); binderCreate(&g_gfxBinderSession, g_gfxLayer.igbp_binder_obj_id);
rc = binderInitSession(&g_gfxBinderSession, 0x0f); 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 = 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)) rc = bqConnect(&g_gfxBinderSession, NATIVE_WINDOW_API_CPU, 0, &g_gfx_Connect_QueueBufferOutput);
@ -233,6 +247,7 @@ Result gfxInitDefault(void) {
nvExit(); nvExit();
} }
eventClose(&g_gfxBinderEvent);
binderClose(&g_gfxBinderSession); binderClose(&g_gfxBinderSession);
viCloseLayer(&g_gfxLayer); viCloseLayer(&g_gfxLayer);
eventClose(&g_gfxDisplayVsyncEvent); eventClose(&g_gfxDisplayVsyncEvent);
@ -276,6 +291,7 @@ void gfxExit(void)
nvExit(); nvExit();
} }
eventClose(&g_gfxBinderEvent);
binderClose(&g_gfxBinderSession); binderClose(&g_gfxBinderSession);
viCloseLayer(&g_gfxLayer); viCloseLayer(&g_gfxLayer);
eventClose(&g_gfxDisplayVsyncEvent); eventClose(&g_gfxDisplayVsyncEvent);