Skip to content

Commit

Permalink
Refactor renderer to support multiple buffers simultaneously
Browse files Browse the repository at this point in the history
  • Loading branch information
twaik committed Feb 12, 2025
1 parent 9c9e533 commit b61b564
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 54 deletions.
8 changes: 4 additions & 4 deletions app/src/main/cpp/lorie/activity.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ static int xcallback(int fd, int events, __unused void* data) {
close(conn_fd);
conn_fd = -1;
rendererSetSharedState(NULL);
rendererSetBuffer(NULL);
rendererRemoveAllBuffers();
log(DEBUG, "disconnected");
return 1;
}
Expand Down Expand Up @@ -197,8 +197,8 @@ static int xcallback(int fd, int events, __unused void* data) {
LorieBuffer_recvHandleFromUnixSocket(conn_fd, &buffer);
desc = LorieBuffer_description(buffer);
log(INFO, "Received shared buffer width %d height %d format %d", desc->width, desc->height, desc->format);
rendererSetBuffer(buffer);
LorieBuffer_release(buffer);
rendererRemoveAllBuffers();
rendererAddBuffer(buffer);
break;
}
}
Expand All @@ -217,7 +217,7 @@ static void connect_(__unused JNIEnv* env, __unused jobject cls, jint fd) {
ALooper_removeFd(ALooper_forThread(), conn_fd);
close(conn_fd);
rendererSetSharedState(NULL);
rendererSetBuffer(NULL);
rendererRemoveAllBuffers();
log(DEBUG, "disconnected");
}

Expand Down
43 changes: 35 additions & 8 deletions app/src/main/cpp/lorie/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "misc.h"
#include "list.h"
#include "buffer.h"

struct LorieBuffer {
Expand All @@ -35,6 +35,7 @@ struct LorieBuffer {

GLuint id;
EGLImage image;
struct xorg_list link;
};

__attribute__((unused))
Expand Down Expand Up @@ -96,7 +97,7 @@ int LorieBuffer_createRegion(char const* name, size_t size) {

static LorieBuffer* allocate(int32_t width, int32_t stride, int32_t height, int8_t format, int8_t type, AHardwareBuffer *buf, int fd, size_t size, off_t offset) {
AHardwareBuffer_Desc desc = {0};
static unsigned long id = 0;
static uint64_t id = 0;
bool acceptable = (format == AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM || format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) && width > 0 && height > 0;
LorieBuffer b = { .desc = { .width = width, .stride = stride, .height = height, .format = format, .type = type, .buffer = buf, .id = id++ }, .fd = fd, .size = size, .offset = offset };

Expand Down Expand Up @@ -152,6 +153,7 @@ static LorieBuffer* allocate(int32_t width, int32_t stride, int32_t height, int8
}

*buffer = b;
xorg_list_init(&buffer->link);
return buffer;
}

Expand All @@ -177,7 +179,7 @@ __LIBC_HIDDEN__ LorieBuffer* LorieBuffer_allocate(int32_t width, int32_t height,
}

__LIBC_HIDDEN__ LorieBuffer* LorieBuffer_wrapFileDescriptor(int32_t width, int32_t stride, int32_t height, int8_t format, int fd, off_t offset) {
return allocate(width, stride, height, format, LORIEBUFFER_FD, NULL, fd, width * height * sizeof(uint32_t), offset);
return allocate(width, stride, height, format, LORIEBUFFER_FD, NULL, fd, stride * height * sizeof(uint32_t), offset);
}

__LIBC_HIDDEN__ LorieBuffer* LorieBuffer_wrapAHardwareBuffer(AHardwareBuffer* buffer) {
Expand All @@ -188,6 +190,8 @@ __LIBC_HIDDEN__ void __LorieBuffer_free(LorieBuffer* buffer) {
if (!buffer)
return;

xorg_list_del(&buffer->link);

if (eglGetCurrentContext())
glDeleteTextures(1, &buffer->id);

Expand Down Expand Up @@ -321,10 +325,11 @@ __LIBC_HIDDEN__ void LorieBuffer_recvHandleFromUnixSocket(int socketFd, LorieBuf
}

*ret = buffer;
xorg_list_init(&ret->link);
*outBuffer = ret;
}

void LorieBuffer_attachToGL(LorieBuffer* buffer) {
__LIBC_HIDDEN__ void LorieBuffer_attachToGL(LorieBuffer* buffer) {
const EGLint imageAttributes[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
if (!eglGetCurrentDisplay() || !buffer)
return;
Expand All @@ -348,7 +353,7 @@ void LorieBuffer_attachToGL(LorieBuffer* buffer) {
}
}

void LorieBuffer_bindTexture(LorieBuffer *buffer) {
__LIBC_HIDDEN__ void LorieBuffer_bindTexture(LorieBuffer *buffer) {
if (!buffer)
return;

Expand All @@ -357,18 +362,40 @@ void LorieBuffer_bindTexture(LorieBuffer *buffer) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, buffer->desc.width, buffer->desc.height, buffer->desc.format == AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM ? GL_BGRA_EXT : GL_RGBA, GL_UNSIGNED_BYTE, buffer->desc.data);
}

int LorieBuffer_getWidth(LorieBuffer *buffer) {
__LIBC_HIDDEN__ int LorieBuffer_getWidth(LorieBuffer *buffer) {
return LorieBuffer_description(buffer)->width;
}

int LorieBuffer_getHeight(LorieBuffer *buffer) {
__LIBC_HIDDEN__ int LorieBuffer_getHeight(LorieBuffer *buffer) {
return LorieBuffer_description(buffer)->height;
}

bool LorieBuffer_isRgba(LorieBuffer *buffer) {
__LIBC_HIDDEN__ bool LorieBuffer_isRgba(LorieBuffer *buffer) {
return LorieBuffer_description(buffer)->format != AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;
}

__LIBC_HIDDEN__ void LorieBuffer_addToList(LorieBuffer* _Nullable buffer, struct xorg_list* _Nullable list) {
if (buffer && list)
xorg_list_add(&buffer->link, list);
}

__LIBC_HIDDEN__ void LorieBuffer_removeFromList(LorieBuffer* _Nullable buffer) {
if (buffer)
xorg_list_del(&buffer->link);
}

__LIBC_HIDDEN__ LorieBuffer* _Nullable LorieBufferList_first(struct xorg_list* _Nullable list) {
return xorg_list_is_empty(list) ? NULL : xorg_list_first_entry(list, LorieBuffer, link);
}

__LIBC_HIDDEN__ LorieBuffer* _Nullable LorieBufferList_findById(struct xorg_list* _Nullable list, uint64_t id) {
LorieBuffer *buffer;
xorg_list_for_each_entry(buffer, list, link)
if (buffer->desc.id == id)
return buffer;
return NULL;
}

__LIBC_HIDDEN__ int ancil_send_fd(int sock, int fd) {
char nothing = '!';
struct iovec nothing_ptr = { .iov_base = &nothing, .iov_len = 1 };
Expand Down
38 changes: 36 additions & 2 deletions app/src/main/cpp/lorie/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ enum {
typedef struct {
int32_t width, height, stride;
uint8_t format, type;
unsigned long id;
uint64_t id;
AHardwareBuffer* _Nullable buffer;
void* _Nullable data;
} LorieBuffer_Desc;
Expand Down Expand Up @@ -91,7 +91,7 @@ STATIC_INLINE void LorieBuffer_acquire(LorieBuffer* _Nullable buffer) {
*/
STATIC_INLINE void LorieBuffer_release(LorieBuffer* _Nullable buffer) {
void __LorieBuffer_free(LorieBuffer* buffer);
if (buffer && __sync_fetch_and_sub((int*) buffer, 1) == 1) // refcount is the first object in the struct
if (buffer && __sync_fetch_and_sub((int16_t*) buffer, 1) == 1) // refcount is the first object in the struct
__LorieBuffer_free(buffer);
}

Expand Down Expand Up @@ -178,6 +178,40 @@ int LorieBuffer_getHeight(LorieBuffer* _Nullable buffer);
*/
bool LorieBuffer_isRgba(LorieBuffer* _Nullable buffer);

struct xorg_list;

/**
* Add the buffer to xorg_list.
*
* @param buffer
* @param list
*/
void LorieBuffer_addToList(LorieBuffer* _Nullable buffer, struct xorg_list* _Nullable list);

/**
* Remove the buffer from xorg_list.
*
* @param buffer
*/
void LorieBuffer_removeFromList(LorieBuffer* _Nullable buffer);

/**
* Get the first buffer in the list.
*
* @param list
* @return buffer if it is present, NULL otherwise.
*/
LorieBuffer* _Nullable LorieBufferList_first(struct xorg_list* _Nullable list);

/**
* Find the buffer with given ID in the list
*
* @param list
* @param id
* @return buffer if it is present, NULL otherwise.
*/
LorieBuffer* _Nullable LorieBufferList_findById(struct xorg_list* _Nullable list, uint64_t id);

#undef STATIC_INLINE

int ancil_send_fd(int sock, int fd);
Expand Down
1 change: 0 additions & 1 deletion app/src/main/cpp/lorie/cmdentrypoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ static Bool detectTracer(void)
FILE *fp;
char line[256];
int pid = 0;
Bool detected = FALSE;

fp = fopen("/proc/self/status", "r");
if (!fp)
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/cpp/lorie/lorie.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ bool lorieConnectionAlive(void);

__unused void rendererInit(JNIEnv* env);
__unused void rendererTestCapabilities(int* legacy_drawing, uint8_t* flip);
__unused void rendererSetBuffer(LorieBuffer* buf);
__unused void rendererSetWindow(ANativeWindow* newWin);
__unused void rendererSetSharedState(struct lorie_shared_server_state* newState);
__unused void rendererAddBuffer(LorieBuffer* buf);
__unused void rendererRemoveBuffer(uint64_t id);
__unused void rendererRemoveAllBuffers(void);

static inline __always_inline void lorie_mutex_lock(pthread_mutex_t* mutex, pid_t* lockingPid) {
// Unfortunately there is no robust mutexes in bionic.
Expand Down Expand Up @@ -163,7 +165,7 @@ struct lorie_shared_server_state {
pthread_cond_t cond; // initialized at X server side.

/* ID of root window texture to be drawn. */
unsigned long rootWindowTextureID;
uint64_t rootWindowTextureID;

/* A signal to renderer to update root window texture content from shared fragment if needed */
volatile uint8_t drawRequested;
Expand Down
Loading

0 comments on commit b61b564

Please sign in to comment.