mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 13:02:38 +02:00
Style fixes, use structs for parsing parcels, renamed bufferProducer to bq
This commit is contained in:
parent
772c839c8c
commit
978c3f7f15
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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++) {
|
||||
|
@ -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<len; pos++) {
|
||||
for (pos=0; pos<len; pos++) {
|
||||
ptr[pos] = (u16)str[pos];
|
||||
}
|
||||
}
|
||||
@ -148,16 +166,18 @@ void* parcelReadFlattenedObject(Parcel *ctx, size_t *size) {
|
||||
s32 len = parcelReadInt32(ctx);
|
||||
s32 fd_count = parcelReadInt32(ctx);
|
||||
|
||||
if (size) *size = (u32)len;
|
||||
if (size)
|
||||
*size = (u32)len;
|
||||
|
||||
if(fd_count!=0)return NULL;//Not going to support fds.
|
||||
if (fd_count != 0)
|
||||
return NULL; // Not going to support fds.
|
||||
|
||||
return parcelReadData(ctx, NULL, len);
|
||||
}
|
||||
|
||||
void* parcelWriteFlattenedObject(Parcel *ctx, void* data, size_t size) {
|
||||
parcelWriteInt32(ctx, size);//len
|
||||
parcelWriteInt32(ctx, 0);//fd_count
|
||||
parcelWriteInt32(ctx, size); // len
|
||||
parcelWriteInt32(ctx, 0); // fd_count
|
||||
|
||||
return parcelWriteData(ctx, data, size);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user