mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 13:02:38 +02:00
Added PARCEL_LOGGING define in parcel.c. Fixed the 'code' value used in gfxproducerQueueBuffer(). Moved some gfxproducer init into nvgfx. Moved some nvgfx event init into nvgfxEventInit(). Updated the code using gfxproducerBufferInit() for setting the nvmap-handles. Disabled a nvQueryEvent() call which now fails. Other changes. The setup framebuf/windowbuf is now displayed.
176 lines
5.0 KiB
C
176 lines
5.0 KiB
C
#include <string.h>
|
|
#include <switch.h>
|
|
|
|
//This implements the version of Android IGraphicBufferProducer used by Switch, hence names/params etc here are based on Android IGraphicBufferProducer.cpp.
|
|
|
|
//Based on an old version of the enum from the above .cpp.
|
|
//Unknown whether all of these are correct for Switch.
|
|
enum {
|
|
REQUEST_BUFFER = BINDER_FIRST_CALL_TRANSACTION, //0x1
|
|
SET_BUFFER_COUNT, //0x2
|
|
DEQUEUE_BUFFER, //0x3
|
|
DETACH_BUFFER, //0x4
|
|
DETACH_NEXT_BUFFER, //0x5
|
|
ATTACH_BUFFER, //0x6
|
|
QUEUE_BUFFER, //0x7
|
|
CANCEL_BUFFER, //0x8
|
|
QUERY, //0x9
|
|
CONNECT, //0xA
|
|
DISCONNECT, //0xB
|
|
SET_SIDEBAND_STREAM, //0xC
|
|
ALLOCATE_BUFFERS, //0xD
|
|
};
|
|
|
|
static char _gfxproducer_InterfaceDescriptor[] = "android.gui.IGraphicBufferProducer";
|
|
|
|
static binderSession *g_gfxproducerBinderSession;
|
|
|
|
Result gfxproducerInitialize(binderSession *session) {
|
|
g_gfxproducerBinderSession = session;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void gfxproducerExit() {
|
|
g_gfxproducerBinderSession = NULL;
|
|
}
|
|
|
|
Result gfxproducerRequestBuffer(s32 bufferIdx) {
|
|
Result rc;
|
|
parcelContext parcel, parcel_reply;
|
|
|
|
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
|
|
|
parcelInitializeContext(&parcel);
|
|
parcelInitializeContext(&parcel_reply);
|
|
|
|
parcelWriteInterfaceToken(&parcel, _gfxproducer_InterfaceDescriptor);
|
|
parcelWriteInt32(&parcel, bufferIdx);
|
|
|
|
rc = parcelTransact(g_gfxproducerBinderSession, REQUEST_BUFFER, &parcel, &parcel_reply);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
//TODO: parse reply
|
|
|
|
return 0;
|
|
}
|
|
|
|
Result gfxproducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage) {
|
|
Result rc;
|
|
parcelContext parcel, parcel_reply;
|
|
|
|
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
|
|
|
parcelInitializeContext(&parcel);
|
|
parcelInitializeContext(&parcel_reply);
|
|
|
|
parcelWriteInterfaceToken(&parcel, _gfxproducer_InterfaceDescriptor);
|
|
|
|
parcelWriteInt32(&parcel, async);
|
|
parcelWriteUInt32(&parcel, width);
|
|
parcelWriteUInt32(&parcel, height);
|
|
parcelWriteInt32(&parcel, format);
|
|
parcelWriteUInt32(&parcel, usage);
|
|
|
|
rc = parcelTransact(g_gfxproducerBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
//TODO: parse reply
|
|
|
|
return 0;
|
|
}
|
|
|
|
Result gfxproducerQueueBuffer(s32 buf, u8 input[0x5c]) {
|
|
Result rc;
|
|
parcelContext parcel, parcel_reply;
|
|
|
|
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
|
|
|
parcelInitializeContext(&parcel);
|
|
parcelInitializeContext(&parcel_reply);
|
|
|
|
parcelWriteInterfaceToken(&parcel, _gfxproducer_InterfaceDescriptor);
|
|
|
|
parcelWriteInt32(&parcel, buf);
|
|
parcelWriteData(&parcel, input, 0x5c);
|
|
|
|
rc = parcelTransact(g_gfxproducerBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
//TODO: parse reply
|
|
|
|
return 0;
|
|
}
|
|
|
|
Result gfxproducerQuery(s32 what, s32* value) {
|
|
Result rc;
|
|
parcelContext parcel, parcel_reply;
|
|
|
|
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
|
|
|
parcelInitializeContext(&parcel);
|
|
parcelInitializeContext(&parcel_reply);
|
|
|
|
parcelWriteInterfaceToken(&parcel, _gfxproducer_InterfaceDescriptor);
|
|
|
|
parcelWriteInt32(&parcel, what);
|
|
|
|
rc = parcelTransact(g_gfxproducerBinderSession, QUERY, &parcel, &parcel_reply);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
*value = parcelReadInt32(&parcel_reply);
|
|
rc = parcelReadInt32(&parcel_reply);
|
|
if (rc) rc = MAKERESULT(MODULE_LIBNX, LIBNX_PARCEL_ERRBASE);
|
|
|
|
return rc;
|
|
}
|
|
|
|
Result gfxproducerConnect(s32 api, bool producerControlledByApp) {
|
|
Result rc;
|
|
parcelContext parcel, parcel_reply;
|
|
|
|
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
|
|
|
parcelInitializeContext(&parcel);
|
|
parcelInitializeContext(&parcel_reply);
|
|
|
|
parcelWriteInterfaceToken(&parcel, _gfxproducer_InterfaceDescriptor);
|
|
|
|
//Hard-code this as if listener==NULL, since that's not known to be used officially.
|
|
parcelWriteInt32(&parcel, 0);
|
|
|
|
parcelWriteInt32(&parcel, api);
|
|
parcelWriteInt32(&parcel, producerControlledByApp);
|
|
|
|
rc = parcelTransact(g_gfxproducerBinderSession, CONNECT, &parcel, &parcel_reply);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
//TODO: parse reply (contains 32bit width and height)
|
|
|
|
return 0;
|
|
}
|
|
|
|
//Unknown what this is.
|
|
Result gfxproducerBufferInit(s32 buf, u8 input[0x178]) {
|
|
Result rc;
|
|
parcelContext parcel, parcel_reply;
|
|
|
|
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
|
|
|
parcelInitializeContext(&parcel);
|
|
parcelInitializeContext(&parcel_reply);
|
|
|
|
parcelWriteInterfaceToken(&parcel, _gfxproducer_InterfaceDescriptor);
|
|
|
|
parcelWriteInt32(&parcel, buf);
|
|
parcelWriteData(&parcel, input, 0x178);
|
|
|
|
rc = parcelTransact(g_gfxproducerBinderSession, 0xE, &parcel, &parcel_reply);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
//TODO: parse reply
|
|
|
|
return 0;
|
|
}
|
|
|