From 978c3f7f1536732a710b8ef5c0d76362717e603f Mon Sep 17 00:00:00 2001 From: plutooo Date: Tue, 20 Feb 2018 06:56:10 +0100 Subject: [PATCH] Style fixes, use structs for parsing parcels, renamed bufferProducer to bq --- nx/include/switch/gfx/buffer_producer.h | 48 ++++----- nx/include/switch/gfx/parcel.h | 16 +-- nx/source/gfx/buffer_producer.c | 118 +++++++++++---------- nx/source/gfx/gfx.c | 45 ++++---- nx/source/gfx/nvgfx.c | 2 +- nx/source/gfx/parcel.c | 132 ++++++++++++++---------- 6 files changed, 198 insertions(+), 163 deletions(-) diff --git a/nx/include/switch/gfx/buffer_producer.h b/nx/include/switch/gfx/buffer_producer.h index e6a8a750..97de2f6c 100644 --- a/nx/include/switch/gfx/buffer_producer.h +++ b/nx/include/switch/gfx/buffer_producer.h @@ -4,32 +4,32 @@ typedef struct { u32 is_valid; nvioctl_fence nv_fences[4]; -} PACKED bufferProducerFence; +} PACKED BqFence; typedef struct { s32 left; s32 top; s32 right; s32 bottom; -} PACKED bufferProducerRect; +} PACKED BqRect; typedef struct { s64 timestamp; s32 isAutoTimestamp; - bufferProducerRect crop; + BqRect crop; s32 scalingMode; - u32 transform;//See the NATIVE_WINDOW_TRANSFORM_* enums. + u32 transform; // See the NATIVE_WINDOW_TRANSFORM_* enums. u32 stickyTransform; u32 unk[2]; - bufferProducerFence fence; -} PACKED bufferProducerQueueBufferInput; + BqFence fence; +} PACKED BqQueueBufferInput; typedef struct { u32 width; u32 height; u32 transformHint; u32 numPendingBuffers; -} PACKED bufferProducerQueueBufferOutput; +} PACKED BqQueueBufferOutput; typedef struct { u32 magic; @@ -45,7 +45,7 @@ typedef struct { u32 numFds; u32 numInts; - struct {//Actual size is numFds*4 + numInts*4. + struct { // Actual size is numFds*4 + numInts*4. u32 unk_x0; u32 nvmap_handle0; u32 unk_x8; @@ -74,12 +74,12 @@ typedef struct { u32 unk_x64; u32 unk_x68; u32 buffer_size1; - u32 unk_x70[0x33];//Normally all-zero. + u32 unk_x70[0x33]; // Normally all-zero. u64 timestamp; } PACKED data; -} PACKED bufferProducerGraphicBuffer; +} PACKED BqGraphicBuffer; -//From Android window.h. +// From Android window.h. /* attributes queriable with query() */ enum { NATIVE_WINDOW_WIDTH = 0, @@ -90,7 +90,7 @@ enum { // NATIVE_WINDOW_DEFAULT_HEIGHT = 7, }; -//From Android window.h. +// From Android window.h. /* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */ enum { //... @@ -100,7 +100,7 @@ enum { //... }; -//From Android hardware.h. +// From Android hardware.h. /** * Transformation definitions @@ -123,7 +123,7 @@ enum { HAL_TRANSFORM_ROT_270 = 0x07, }; -//From Android window.h. +// From Android window.h. /* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ enum { /* flip source image horizontally */ @@ -138,14 +138,14 @@ enum { NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, }; -Result bufferProducerInitialize(Binder *session); -void bufferProducerExit(void); +Result bqInitialize(Binder *session); +void bqExit(void); -Result bufferProducerRequestBuffer(s32 bufferIdx, bufferProducerGraphicBuffer *buf); -Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf, bufferProducerFence *fence); -Result bufferProducerDetachBuffer(s32 slot); -Result bufferProducerQueueBuffer(s32 buf, bufferProducerQueueBufferInput *input, bufferProducerQueueBufferOutput *output); -Result bufferProducerQuery(s32 what, s32* value); -Result bufferProducerConnect(s32 api, bool producerControlledByApp, bufferProducerQueueBufferOutput *output); -Result bufferProducerDisconnect(s32 api); -Result bufferProducerGraphicBufferInit(s32 buf, bufferProducerGraphicBuffer *input); +Result bqRequestBuffer(s32 bufferIdx, BqGraphicBuffer *buf); +Result bqDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf, BqFence *fence); +Result bqDetachBuffer(s32 slot); +Result bqQueueBuffer(s32 buf, BqQueueBufferInput *input, BqQueueBufferOutput *output); +Result bqQuery(s32 what, s32* value); +Result bqConnect(s32 api, bool producerControlledByApp, BqQueueBufferOutput *output); +Result bqDisconnect(s32 api); +Result bqGraphicBufferInit(s32 buf, BqGraphicBuffer *input); diff --git a/nx/include/switch/gfx/parcel.h b/nx/include/switch/gfx/parcel.h index e208a81a..4b1b2fd3 100644 --- a/nx/include/switch/gfx/parcel.h +++ b/nx/include/switch/gfx/parcel.h @@ -2,14 +2,16 @@ #include "../result.h" #include "../gfx/binder.h" -typedef struct { - u8 payload[0x400]; - u32 capacity; - u32 size; - u32 pos; +#define PARCEL_MAX_PAYLOAD 0x400 - u8 *ParcelObjects; - u32 ParcelObjectsSize; +typedef struct { + u8 payload[PARCEL_MAX_PAYLOAD]; + u32 payload_size; + u8* objects; + u32 objects_size; + + u32 capacity; + u32 pos; } Parcel; void parcelInitialize(Parcel *ctx); diff --git a/nx/source/gfx/buffer_producer.c b/nx/source/gfx/buffer_producer.c index 94311d8a..147cf788 100644 --- a/nx/source/gfx/buffer_producer.c +++ b/nx/source/gfx/buffer_producer.c @@ -27,47 +27,50 @@ enum { /* 0xE */ GRAPHIC_BUFFER_INIT, // Custom Switch-specific command - unofficial name. }; -static char g_bufferProducer_InterfaceDescriptor[] = "android.gui.IGraphicBufferProducer"; +static char g_bq_InterfaceDescriptor[] = "android.gui.IGraphicBufferProducer"; -static Binder *g_bufferProducerBinderSession; +static Binder *g_bqBinderSession; -Result bufferProducerInitialize(Binder *session) +Result bqInitialize(Binder *session) { - g_bufferProducerBinderSession = session; + g_bqBinderSession = session; return 0; } -void bufferProducerExit(void) +void bqExit(void) { - g_bufferProducerBinderSession = NULL; + g_bqBinderSession = NULL; } -Result bufferProducerRequestBuffer(s32 bufferIdx, bufferProducerGraphicBuffer *buf) +Result bqRequestBuffer(s32 bufferIdx, BqGraphicBuffer *buf) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, bufferIdx); - rc = parcelTransact(g_bufferProducerBinderSession, REQUEST_BUFFER, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, REQUEST_BUFFER, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { int nonNull = parcelReadInt32(&parcel_reply); if (nonNull != 0) { - size_t tmpsize=0; + size_t tmp_size=0; void* tmp_ptr; - tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmpsize); - if (tmp_ptr==NULL || tmpsize!=sizeof(bufferProducerGraphicBuffer)) return MAKERESULT(Module_Libnx, LibnxError_BadInput); - if (buf) memcpy(buf, tmp_ptr, sizeof(bufferProducerGraphicBuffer)); + tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmp_size); + if (tmp_ptr == NULL || tmp_size != sizeof(BqGraphicBuffer)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + if (buf) + memcpy(buf, tmp_ptr, sizeof(BqGraphicBuffer)); } int status = parcelReadInt32(&parcel_reply); @@ -80,18 +83,18 @@ Result bufferProducerRequestBuffer(s32 bufferIdx, bufferProducerGraphicBuffer *b return rc; } -Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf, bufferProducerFence *fence) +Result bqDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf, BqFence *fence) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, async); parcelWriteUInt32(&parcel, width); @@ -99,18 +102,21 @@ Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format parcelWriteInt32(&parcel, format); parcelWriteUInt32(&parcel, usage); - rc = parcelTransact(g_bufferProducerBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { *buf = parcelReadInt32(&parcel_reply); if(parcelReadInt32(&parcel_reply)) { - size_t tmpsize=0; + size_t tmp_size=0; void* tmp_ptr; - tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmpsize); - if (tmp_ptr==NULL || tmpsize!=sizeof(bufferProducerFence)) return MAKERESULT(Module_Libnx, LibnxError_BadInput); - if (fence) memcpy(fence, tmp_ptr, sizeof(bufferProducerFence)); + tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmp_size); + if (tmp_ptr == NULL || tmp_size != sizeof(BqFence)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + if (fence) + memcpy(fence, tmp_ptr, sizeof(BqFence)); } int result = parcelReadInt32(&parcel_reply); @@ -121,21 +127,21 @@ Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format return rc; } -Result bufferProducerDetachBuffer(s32 slot) +Result bqDetachBuffer(s32 slot) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, slot); - rc = parcelTransact(g_bufferProducerBinderSession, DETACH_BUFFER, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, DETACH_BUFFER, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { //TODO: parse reply @@ -144,25 +150,26 @@ Result bufferProducerDetachBuffer(s32 slot) return rc; } -Result bufferProducerQueueBuffer(s32 buf, bufferProducerQueueBufferInput *input, bufferProducerQueueBufferOutput *output) +Result bqQueueBuffer(s32 buf, BqQueueBufferInput *input, BqQueueBufferOutput *output) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, buf); - parcelWriteFlattenedObject(&parcel, input, sizeof(bufferProducerQueueBufferInput)); + parcelWriteFlattenedObject(&parcel, input, sizeof(*input)); - rc = parcelTransact(g_bufferProducerBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { - if (parcelReadData(&parcel_reply, output, sizeof(bufferProducerQueueBufferOutput))==NULL) return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (parcelReadData(&parcel_reply, output, sizeof(*output)) == NULL) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); int result = parcelReadInt32(&parcel_reply); if (result != 0) @@ -172,21 +179,21 @@ Result bufferProducerQueueBuffer(s32 buf, bufferProducerQueueBufferInput *input, return rc; } -Result bufferProducerQuery(s32 what, s32* value) +Result bqQuery(s32 what, s32* value) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, what); - rc = parcelTransact(g_bufferProducerBinderSession, QUERY, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, QUERY, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { *value = parcelReadInt32(&parcel_reply); @@ -199,28 +206,29 @@ Result bufferProducerQuery(s32 what, s32* value) return rc; } -Result bufferProducerConnect(s32 api, bool producerControlledByApp, bufferProducerQueueBufferOutput *output) +Result bqConnect(s32 api, bool producerControlledByApp, BqQueueBufferOutput *output) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_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_bufferProducerBinderSession, CONNECT, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, CONNECT, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { - if (parcelReadData(&parcel_reply, output, sizeof(bufferProducerQueueBufferOutput))==NULL) return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (parcelReadData(&parcel_reply, output, sizeof(*output)) == NULL) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); int result = parcelReadInt32(&parcel_reply); if (result != 0) @@ -230,48 +238,52 @@ Result bufferProducerConnect(s32 api, bool producerControlledByApp, bufferProduc return rc; } -Result bufferProducerDisconnect(s32 api) +Result bqDisconnect(s32 api) { Result rc; Parcel parcel, parcel_reply; - if (g_bufferProducerBinderSession == NULL) + if (g_bqBinderSession == NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, api); - rc = parcelTransact(g_bufferProducerBinderSession, DISCONNECT, &parcel, &parcel_reply); + rc = parcelTransact(g_bqBinderSession, DISCONNECT, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { - //TODO: parse reply + // TODO: parse reply } return rc; } -Result bufferProducerGraphicBufferInit(s32 buf, bufferProducerGraphicBuffer *input) +Result bqGraphicBufferInit(s32 buf, BqGraphicBuffer *input) { Result rc; Parcel parcel, parcel_reply; bool flag = 0; - if (g_bufferProducerBinderSession==NULL) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + if (g_bqBinderSession == NULL) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); parcelInitialize(&parcel); parcelInitialize(&parcel_reply); - parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); + parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor); parcelWriteInt32(&parcel, buf); - if (input!=NULL) flag = 1; - parcelWriteInt32(&parcel, flag); - if (flag) parcelWriteFlattenedObject(&parcel, input, sizeof(bufferProducerGraphicBuffer)); + if (input != NULL) + flag = 1; - rc = parcelTransact(g_bufferProducerBinderSession, GRAPHIC_BUFFER_INIT, &parcel, &parcel_reply); + parcelWriteInt32(&parcel, flag); + if (flag) + parcelWriteFlattenedObject(&parcel, input, sizeof(BqGraphicBuffer)); + + rc = parcelTransact(g_bqBinderSession, GRAPHIC_BUFFER_INIT, &parcel, &parcel_reply); if (R_SUCCEEDED(rc)) { int result = parcelReadInt32(&parcel_reply); diff --git a/nx/source/gfx/gfx.c b/nx/source/gfx/gfx.c index 8bfa2208..bdd37b5c 100644 --- a/nx/source/gfx/gfx.c +++ b/nx/source/gfx/gfx.c @@ -26,9 +26,9 @@ static bool g_gfx_ProducerConnected = 0; static bool g_gfx_ProducerSlotsRequested[2] = {0, 0}; static u8 *g_gfxFramebuf; static size_t g_gfxFramebufSize; -static bufferProducerFence g_gfx_DequeueBuffer_fence; -static bufferProducerQueueBufferOutput g_gfx_Connect_QueueBufferOutput; -static bufferProducerQueueBufferOutput g_gfx_QueueBuffer_QueueBufferOutput; +static BqFence g_gfx_DequeueBuffer_fence; +static BqQueueBufferOutput g_gfx_Connect_QueueBufferOutput; +static BqQueueBufferOutput g_gfx_QueueBuffer_QueueBufferOutput; static GfxMode g_gfxMode = GfxMode_LinearDouble; @@ -57,7 +57,8 @@ extern nvioctl_fence g_nvgfx_nvhostgpu_gpfifo_fence; //static Result _gfxGetDisplayResolution(u64 *width, u64 *height); -static bufferProducerQueueBufferInput g_gfxQueueBufferData = { +// TODO: Let the user configure some of this? +static BqQueueBufferInput g_gfxQueueBufferData = { .timestamp = 0x0, .isAutoTimestamp = 0x1, .crop = {0x0, 0x0, 0x0, 0x0}, //Official apps which use multiple resolutions configure this for the currently used resolution, depending on the current appletOperationMode. @@ -78,8 +79,8 @@ static bufferProducerQueueBufferInput g_gfxQueueBufferData = { } }; -//Some of this struct is based on tegra_dc_ext_flip_windowattr. -static bufferProducerGraphicBuffer g_gfx_BufferInitData = { +// Some of this struct is based on tegra_dc_ext_flip_windowattr. +static BqGraphicBuffer g_gfx_BufferInitData = { .magic = 0x47424652,//"RFBG"/'GBFR' .format = 0x1, .usage = 0xb00, @@ -125,8 +126,8 @@ static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) { static Result _gfxDequeueBuffer(void) { Result rc=0; - bufferProducerFence *fence = &g_gfx_DequeueBuffer_fence; - bufferProducerFence tmp_fence; + BqFence *fence = &g_gfx_DequeueBuffer_fence; + BqFence tmp_fence; bool async=0; if (g_gfxMode == GfxMode_TiledSingle) { @@ -134,9 +135,9 @@ static Result _gfxDequeueBuffer(void) { return 0; } - memcpy(&tmp_fence, fence, sizeof(bufferProducerFence));//Offical sw waits on the fence from the previous DequeueBuffer call. Using the fence from the current DequeueBuffer call results in nvgfxEventWait() failing. + memcpy(&tmp_fence, fence, sizeof(BqFence));//Offical sw waits on the fence from the previous DequeueBuffer call. Using the fence from the current DequeueBuffer call results in nvgfxEventWait() failing. - rc = bufferProducerDequeueBuffer(async, g_gfx_framebuf_width, g_gfx_framebuf_height, 0, 0x300, &g_gfxCurrentProducerBuffer, fence); + rc = bqDequeueBuffer(async, g_gfx_framebuf_width, g_gfx_framebuf_height, 0, 0x300, &g_gfxCurrentProducerBuffer, fence); //Only run nvgfxEventWait when the fence is valid and the id is not NO_FENCE. if (R_SUCCEEDED(rc) && tmp_fence.is_valid && tmp_fence.nv_fences[0].id!=0xffffffff) rc = nvgfxEventWait(tmp_fence.nv_fences[0].id, tmp_fence.nv_fences[0].value, -1); @@ -158,7 +159,7 @@ static Result _gfxQueueBuffer(s32 buf) { //if (g_nvgfx_nvhostgpu_gpfifo_fence.id) rc = nvgfxEventWait(g_nvgfx_nvhostgpu_gpfifo_fence.id, g_nvgfx_nvhostgpu_gpfifo_fence.value, -1); if (R_FAILED(rc)) return rc; - rc = bufferProducerQueueBuffer(buf, &g_gfxQueueBufferData, &g_gfx_QueueBuffer_QueueBufferOutput); + rc = bqQueueBuffer(buf, &g_gfxQueueBufferData, &g_gfx_QueueBuffer_QueueBufferOutput); if (R_FAILED(rc)) return rc; return rc; @@ -240,9 +241,9 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L if (R_SUCCEEDED(rc)) rc = nvInitialize(nv_servicetype, nv_transfermem_size); - if (R_SUCCEEDED(rc)) rc = bufferProducerInitialize(&g_gfxBinderSession); + if (R_SUCCEEDED(rc)) rc = bqInitialize(&g_gfxBinderSession); - if (R_SUCCEEDED(rc)) rc = bufferProducerConnect(NATIVE_WINDOW_API_CPU, 0, &g_gfx_Connect_QueueBufferOutput); + if (R_SUCCEEDED(rc)) rc = bqConnect(NATIVE_WINDOW_API_CPU, 0, &g_gfx_Connect_QueueBufferOutput); if (R_SUCCEEDED(rc)) g_gfx_ProducerConnected = 1; @@ -250,12 +251,12 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L if (R_SUCCEEDED(rc)) rc = nvgfxGetFramebuffer(&g_gfxFramebuf, &g_gfxFramebufSize); - if (R_SUCCEEDED(rc)) { //Official sw would use bufferProducerRequestBuffer() when required during swap-buffers/or similar, but that's not really an option here due to gfxSetDoubleBuffering(). + if (R_SUCCEEDED(rc)) { //Official sw would use bqRequestBuffer() when required during swap-buffers/or similar, but that's not really an option here due to gfxSetDoubleBuffering(). for(i=0; i<2; i++) { rc = _gfxDequeueBuffer(); if (R_FAILED(rc)) break; - rc = bufferProducerRequestBuffer(g_gfxCurrentProducerBuffer, NULL); + rc = bqRequestBuffer(g_gfxCurrentProducerBuffer, NULL); if (R_FAILED(rc)) break; g_gfx_ProducerSlotsRequested[i] = 1; @@ -284,12 +285,12 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L if (R_FAILED(rc)) { _gfxQueueBuffer(g_gfxCurrentProducerBuffer); for(i=0; i<2; i++) { - if (g_gfx_ProducerSlotsRequested[i]) bufferProducerDetachBuffer(i); + if (g_gfx_ProducerSlotsRequested[i]) bqDetachBuffer(i); } - if (g_gfx_ProducerConnected) bufferProducerDisconnect(NATIVE_WINDOW_API_CPU); + if (g_gfx_ProducerConnected) bqDisconnect(NATIVE_WINDOW_API_CPU); nvgfxExit(); - bufferProducerExit(); + bqExit(); binderExitSession(&g_gfxBinderSession); nvExit(); @@ -353,13 +354,13 @@ void gfxExit(void) _gfxQueueBuffer(g_gfxCurrentProducerBuffer); for (i=0; i<2; i++) { - if (g_gfx_ProducerSlotsRequested[i]) bufferProducerDetachBuffer(i); + if (g_gfx_ProducerSlotsRequested[i]) bqDetachBuffer(i); } - if (g_gfx_ProducerConnected) bufferProducerDisconnect(2); + if (g_gfx_ProducerConnected) bqDisconnect(2); nvgfxExit(); - bufferProducerExit(); + bqExit(); binderExitSession(&g_gfxBinderSession); nvExit(); @@ -482,7 +483,7 @@ Result _gfxGraphicBufferInit(s32 buf, u32 nvmap_handle) { g_gfx_BufferInitData.data.buffer_offset = g_gfx_singleframebuf_size*buf; g_gfx_BufferInitData.data.timestamp = svcGetSystemTick(); - return bufferProducerGraphicBufferInit(buf, &g_gfx_BufferInitData); + return bqGraphicBufferInit(buf, &g_gfx_BufferInitData); } static void _waitevent(Handle *handle) { diff --git a/nx/source/gfx/nvgfx.c b/nx/source/gfx/nvgfx.c index e54847ab..9eb4272b 100644 --- a/nx/source/gfx/nvgfx.c +++ b/nx/source/gfx/nvgfx.c @@ -269,7 +269,7 @@ Result nvgfxInitialize(void) { } if (R_SUCCEEDED(rc)) { - rc = bufferProducerQuery(NATIVE_WINDOW_FORMAT, &tmp);//TODO: What does official sw use the output from this for? + rc = bqQuery(NATIVE_WINDOW_FORMAT, &tmp);//TODO: What does official sw use the output from this for? if (R_SUCCEEDED(rc)) { for(i=0; i<2; i++) { diff --git a/nx/source/gfx/parcel.c b/nx/source/gfx/parcel.c index 56e31866..57526373 100644 --- a/nx/source/gfx/parcel.c +++ b/nx/source/gfx/parcel.c @@ -2,14 +2,14 @@ #include "result.h" #include "gfx/parcel.h" -//This implements Android Parcel, hence names etc here are based on Android Parcel.cpp. +// This implements Android Parcel, hence names etc here are based on Android Parcel.cpp. -//#define PARCEL_LOGGING - -#ifdef PARCEL_LOGGING -u8 parcel_reply_log[0x10000] = {0}; -size_t parcel_reply_log_size = 0; -#endif +typedef struct { + u32 payload_size; + u32 payload_off; + u32 objects_size; + u32 objects_off; +} ParcelHeader; void parcelInitialize(Parcel *ctx) { @@ -17,68 +17,86 @@ void parcelInitialize(Parcel *ctx) ctx->capacity = sizeof(ctx->payload); } -Result parcelTransact(Binder *session, u32 code, Parcel *in_parcel, Parcel *parcel_reply) +Result parcelTransact(Binder *session, u32 code, Parcel *in_parcel, Parcel *out_parcel) { - Result rc=0; - u8 inparcel[0x400]; - u8 outparcel[0x400]; - size_t outparcel_size = sizeof(outparcel); - u32 *inparcel32 = (u32*)inparcel; - u32 *outparcel32 = (u32*)outparcel; - u32 payloadSize = in_parcel->size; - u32 ParcelObjectsSize = in_parcel->ParcelObjectsSize; + Result rc; + char in[PARCEL_MAX_PAYLOAD]; + char out[PARCEL_MAX_PAYLOAD]; - memset(inparcel, 0, sizeof(inparcel)); - memset(outparcel, 0, outparcel_size); + memset(in, 0, sizeof(in)); + memset(out, 0, sizeof(out)); - if((size_t)payloadSize >= sizeof(inparcel) || (size_t)ParcelObjectsSize >= sizeof(inparcel) || ((size_t)payloadSize)+((size_t)ParcelObjectsSize)+0x10 >= sizeof(inparcel)) return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (in_parcel->payload_size > sizeof(in)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (in_parcel->objects_size > sizeof(in)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); - inparcel32[0] = payloadSize;//payloadSize - inparcel32[1] = 0x10;//payloadOffset - inparcel32[2] = ParcelObjectsSize;//ParcelObjectsSize - inparcel32[3] = 0x10+payloadSize;//ParcelObjectsOffset + size_t total_size = 0; + total_size += sizeof(ParcelHeader); + total_size += in_parcel->payload_size; + total_size += in_parcel->objects_size; - if(in_parcel->payload && payloadSize)memcpy(&inparcel[inparcel32[1]], in_parcel->payload, payloadSize); - if(in_parcel->ParcelObjects && ParcelObjectsSize)memcpy(&inparcel[inparcel32[3]], in_parcel->ParcelObjects, ParcelObjectsSize); + if (total_size > sizeof(in)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); - rc = binderTransactParcel(session, code, inparcel, payloadSize+ParcelObjectsSize+0x10, outparcel, outparcel_size, 0); - if (R_FAILED(rc)) return rc; + ParcelHeader* in_hdr = (ParcelHeader*) ∈ + in_hdr->payload_size = in_parcel->payload_size; + in_hdr->payload_off = sizeof(ParcelHeader); + in_hdr->objects_size = in_parcel->objects_size; + in_hdr->objects_off = sizeof(ParcelHeader) + in_parcel->payload_size; - if((size_t)outparcel32[1] >= outparcel_size || ((size_t)outparcel32[0])+((size_t)outparcel32[1]) >= outparcel_size) return MAKERESULT(Module_Libnx, LibnxError_BadInput); - if((size_t)outparcel32[2] >= outparcel_size || ((size_t)outparcel32[2])+((size_t)outparcel32[3]) >= outparcel_size) return MAKERESULT(Module_Libnx, LibnxError_BadInput); - if((size_t)outparcel32[0] >= outparcel_size || (size_t)outparcel32[3] >= outparcel_size) return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (in_parcel->payload != NULL) + memcpy(&in[in_hdr->payload_off], in_parcel->payload, in_parcel->payload_size); - memcpy(parcel_reply->payload, &outparcel[outparcel32[1]], outparcel32[0]); - parcel_reply->size = outparcel32[0]; + if (in_parcel->objects != NULL) + memcpy(&in[in_hdr->objects_off], in_parcel->objects, in_parcel->objects_size); - #ifdef PARCEL_LOGGING - if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) { - memcpy(&parcel_reply_log[parcel_reply_log_size], inparcel, sizeof(inparcel)); - parcel_reply_log_size+= sizeof(inparcel); - memcpy(&parcel_reply_log[parcel_reply_log_size], outparcel, outparcel_size); - parcel_reply_log_size+= outparcel_size; + rc = binderTransactParcel(session, code, in, total_size, out, sizeof(out), 0); + + if (R_SUCCEEDED(rc)) + { + ParcelHeader* out_hdr = (ParcelHeader*) &out; + + if (out_hdr->payload_size > sizeof(out)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (out_hdr->objects_size > sizeof(out)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (out_hdr->payload_off > sizeof(out)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (out_hdr->objects_off > sizeof(out)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if ((out_hdr->payload_off+out_hdr->payload_size) > sizeof(out)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + if ((out_hdr->objects_off+out_hdr->objects_size) > sizeof(out)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + memcpy(out_parcel->payload, &out[out_hdr->payload_off], out_hdr->payload_size); + out_parcel->payload_size = out_hdr->payload_size; + + // TODO: Objects are not populated on response. + out_parcel->objects = NULL; + out_parcel->objects_size = 0; } - #endif - return 0; + return rc; } void* parcelWriteData(Parcel *ctx, void* data, size_t data_size) { - void* ptr = &ctx->payload[ctx->size]; + void* ptr = &ctx->payload[ctx->payload_size]; - if(data_size & BIT(31)) + if (data_size & BIT(31)) return NULL; data_size = (data_size+3) & ~3; - if(ctx->size + data_size >= ctx->capacity) + if (ctx->payload_size + data_size >= ctx->capacity) return NULL; - if(data) + if (data) memcpy(ptr, data, data_size); - ctx->size += data_size; + ctx->payload_size += data_size; return ptr; } @@ -87,15 +105,15 @@ void* parcelReadData(Parcel *ctx, void* data, size_t data_size) void* ptr = &ctx->payload[ctx->pos]; size_t aligned_data_size; - if(data_size & BIT(31)) + if (data_size & BIT(31)) return NULL; aligned_data_size = (data_size+3) & ~3; - if(ctx->pos + aligned_data_size >= ctx->size) + if (ctx->pos + aligned_data_size >= ctx->payload_size) return NULL; - if(data) + if (data) memcpy(data, ptr, data_size); ctx->pos += aligned_data_size; @@ -110,8 +128,7 @@ void parcelWriteUInt32(Parcel *ctx, u32 val) { parcelWriteData(ctx, &val, sizeof(val)); } -void parcelWriteString16(Parcel *ctx, const char *str) -{ +void parcelWriteString16(Parcel *ctx, const char *str) { u32 pos, len; u16 *ptr; @@ -120,9 +137,10 @@ void parcelWriteString16(Parcel *ctx, const char *str) len++; ptr = parcelWriteData(ctx, NULL, len*2); - if(ptr==NULL)return; + if (ptr == NULL) + return; - for(pos=0; pos