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
#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);
}

View File

@ -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);
}
}

View File

@ -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);