Skip to content

Commit

Permalink
Make LorieBuffer manage all kinds of pixmaps.
Browse files Browse the repository at this point in the history
  • Loading branch information
twaik committed Feb 10, 2025
1 parent 73f2f99 commit 972b648
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 31 deletions.
38 changes: 16 additions & 22 deletions app/src/main/cpp/lorie/InitOutput.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ static char *xstartup = NULL;

typedef struct {
LorieBuffer *buffer;
AHardwareBuffer* ahb;
uint8_t flipped;
bool flipped, imported;
void *locked;
void *mem;
} LoriePixmapPriv;
Expand Down Expand Up @@ -806,11 +805,10 @@ void *lorieCreatePixmap(__unused ScreenPtr pScreen, int width, int height, __unu
void lorieExaDestroyPixmap(__unused ScreenPtr pScreen, void *driverPriv) {
LoriePixmapPriv *priv = driverPriv;
if (priv->buffer) {
LorieBuffer_unlock(priv->buffer);
if (!priv->imported)
LorieBuffer_unlock(priv->buffer);
LorieBuffer_release(priv->buffer);
}
if (priv->ahb)
AHardwareBuffer_release(priv->ahb);
free(priv);
}

Expand All @@ -826,8 +824,8 @@ Bool loriePrepareAccess(PixmapPtr pPix, int index) {
if (index == EXA_PREPARE_DEST && pScreenPtr->GetScreenPixmap(pScreenPtr) == pPix)
lorie_mutex_lock(&pvfb->state->lock, &pvfb->state->lockingPid);

if (priv->ahb) {
if (AHardwareBuffer_lock(priv->ahb, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, NULL, &pPix->devPrivate.ptr))
if (priv->imported) {
if (LorieBuffer_lock(priv->buffer, &pPix->devPrivate.ptr))
return FALSE;
} else
pPix->devPrivate.ptr = priv->locked ?: priv->mem ?: priv + 1;
Expand All @@ -839,8 +837,8 @@ void lorieFinishAccess(PixmapPtr pPix, int index) {
if (index == EXA_PREPARE_DEST && pScreenPtr->GetScreenPixmap(pScreenPtr) == pPix)
lorie_mutex_unlock(&pvfb->state->lock, &pvfb->state->lockingPid);

if (priv->ahb)
AHardwareBuffer_unlock(priv->ahb, NULL);
if (priv->imported)
LorieBuffer_unlock(priv->buffer);
}

static ExaDriverRec lorieExa = {
Expand All @@ -863,7 +861,6 @@ static PixmapPtr loriePixmapFromFds(ScreenPtr screen, CARD8 num_fds, const int *
AHardwareBuffer_Desc desc = {0};
PixmapPtr pixmap = NullPixmap;
LoriePixmapPriv *priv = NULL;
void *addr = NULL;

check(num_fds > 1, "DRI3: More than 1 fd");
check(modifier != RAW_MMAPPABLE_FD && modifier != AHARDWAREBUFFER_SOCKET_FD && modifier != AHARDWAREBUFFER_FLIPPED_SOCKET_FD &&
Expand All @@ -875,14 +872,16 @@ static PixmapPtr loriePixmapFromFds(ScreenPtr screen, CARD8 num_fds, const int *
priv = exaGetPixmapDriverPrivate(pixmap);
check(!priv, "DRI3: failed to obtain pixmap private");

priv->imported = true;

if (modifier == DRM_FORMAT_MOD_INVALID || modifier == RAW_MMAPPABLE_FD) {
addr = mmap(NULL, strides[0] * height, PROT_READ, MAP_SHARED, fds[0], offsets[0]);
check(!addr || addr == MAP_FAILED, "DRI3: RAW_MMAPPABLE_FD: mmap failed");
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], addr);
check(!(priv->buffer = LorieBuffer_wrapFileDescriptor(width, height, AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM, fds[0], offsets[0])), "DRI3: LorieBuffer_wrapAHardwareBuffer failed.");
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
return pixmap;
}

if (modifier == AHARDWAREBUFFER_SOCKET_FD || modifier == AHARDWAREBUFFER_FLIPPED_SOCKET_FD) {
AHardwareBuffer* buffer;
struct stat info;
uint8_t buf = 1;
int r;
Expand All @@ -892,27 +891,22 @@ static PixmapPtr loriePixmapFromFds(ScreenPtr screen, CARD8 num_fds, const int *
check(!S_ISSOCK(info.st_mode), "DRI3: modifier is AHARDWAREBUFFER_SOCKET_FD but fd is not a socket");
// Sending signal to other end of socket to send buffer.
check(write(fds[0], &buf, 1) != 1, "DRI3: AHARDWAREBUFFER_SOCKET_FD: failed to write to socket: %s", strerror(errno));
check((r = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], &priv->ahb)) != 0,
check((r = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], &buffer)) != 0,
"DRI3: AHARDWAREBUFFER_SOCKET_FD: failed to obtain AHardwareBuffer from socket: %d", r);
check(!priv->ahb, "DRI3: AHARDWAREBUFFER_SOCKET_FD: did not receive AHardwareSocket from buffer");
AHardwareBuffer_describe(priv->ahb, &desc);
check(!buffer, "DRI3: AHARDWAREBUFFER_SOCKET_FD: did not receive AHardwareSocket from buffer");
AHardwareBuffer_describe(buffer, &desc);
check(desc.format != AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM
&& desc.format != AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
&& desc.format != AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM,
"DRI3: AHARDWAREBUFFER_SOCKET_FD: wrong format of AHardwareBuffer. Must be one of: AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM (stands for 5).");
check(!(priv->buffer = LorieBuffer_wrapAHardwareBuffer(buffer)), "DRI3: LorieBuffer_wrapAHardwareBuffer failed.");

screen->ModifyPixmapHeader(pixmap, desc.width, desc.height, 0, 0, desc.stride * 4, NULL);
}

return pixmap;

fail:
if (priv && priv->ahb) {
AHardwareBuffer_release(priv->ahb);
priv->ahb = NULL;
}
if (addr)
munmap(addr, strides[0] * height);
if (pixmap)
screen->DestroyPixmap(pixmap);

Expand Down
17 changes: 9 additions & 8 deletions app/src/main/cpp/lorie/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct LorieBuffer {
// file descriptor of shared memory fragment for shared memory backed buffer
int fd;
size_t size;
off_t offset;

GLuint id;
EGLImage image;
Expand Down Expand Up @@ -93,12 +94,12 @@ int LorieBuffer_createRegion(char const* name, size_t size) {
}
#pragma clang diagnostic pop

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

if (format != LORIEBUFFER_AHARDWAREBUFFER && !acceptable)
if (type != LORIEBUFFER_AHARDWAREBUFFER && !acceptable)
return NULL;

__sync_fetch_and_add(&b.refcount, 1);
Expand All @@ -113,7 +114,7 @@ static LorieBuffer* allocate(int32_t width, int32_t height, int8_t format, int8_
if (b.fd < 0)
return NULL;

b.desc.data = mmap(NULL, b.size, PROT_READ|PROT_WRITE, MAP_SHARED, b.fd, 0);
b.desc.data = mmap(NULL, b.size, PROT_READ|PROT_WRITE, MAP_SHARED, b.fd, b.offset);
if (b.desc.data == NULL || b.desc.data == MAP_FAILED) {
close(b.fd);
return NULL;
Expand Down Expand Up @@ -171,15 +172,15 @@ __LIBC_HIDDEN__ LorieBuffer* LorieBuffer_allocate(int32_t width, int32_t height,
dprintf(2, "FATAL: failed to allocate AHardwareBuffer (width %d height %d format %d): error %d\n", width, height, format, err);
}

return allocate(width, height, format, type, ahardwarebuffer, fd, size);
return allocate(width, height, format, type, ahardwarebuffer, fd, size, 0);
}

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

__LIBC_HIDDEN__ LorieBuffer* LorieBuffer_wrapAHardwareBuffer(AHardwareBuffer* buffer) {
return allocate(0, 0, 0, LORIEBUFFER_AHARDWAREBUFFER, buffer, -1, 0);
return allocate(0, 0, 0, LORIEBUFFER_AHARDWAREBUFFER, buffer, -1, 0, 0);
}

__LIBC_HIDDEN__ void __LorieBuffer_free(LorieBuffer* buffer) {
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/cpp/lorie/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ LorieBuffer* LorieBuffer_allocate(int32_t width, int32_t height, int8_t format,
* @param height height of buffer.
* @param format format of buffer. Accepts AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM or AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM
* @param fd file descriptor of buffer.
* @param size size of memory fragment.
* @param offset offset inside memory fragment.
* @return
*/
LorieBuffer* LorieBuffer_wrapFileDescriptor(int32_t width, int32_t height, int8_t format, int fd);
LorieBuffer* LorieBuffer_wrapFileDescriptor(int32_t width, int32_t height, int8_t format, int fd, off_t offset);

/**
* Wraps given AHardwareBuffer into LorieBuffer.
Expand Down

0 comments on commit 972b648

Please sign in to comment.