Skip to content

Commit 883a66b

Browse files
committed
make X server share more than 1 LorieBuffer simultaneously.
1 parent 7ee2cc3 commit 883a66b

File tree

6 files changed

+55
-12
lines changed

6 files changed

+55
-12
lines changed

app/src/main/cpp/lorie/InitOutput.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct {
9999
void *mem;
100100
} LoriePixmapPriv;
101101

102+
#define LORIE_PIXMAP_PRIV_FROM_PIXMAP(pixmap) (pixmap ? ((LoriePixmapPriv*) exaGetPixmapDriverPrivate(pixmap)) : NULL)
102103
#define LORIE_BUFFER_FROM_PIXMAP(pixmap) (pixmap ? ((LoriePixmapPriv*) exaGetPixmapDriverPrivate(pixmap))->buffer : NULL)
103104

104105
void OsVendorInit(void) {
@@ -132,7 +133,7 @@ void OsVendorInit(void) {
132133
void lorieActivityConnected(void) {
133134
pvfb->state->drawRequested = pvfb->state->cursor.updated = true;
134135
lorieSendSharedServerState(pvfb->stateFd);
135-
lorieSendRootWindowBuffer(LORIE_BUFFER_FROM_PIXMAP(pScreenPtr->devPrivate));
136+
lorieRegisterBuffer(LORIE_BUFFER_FROM_PIXMAP(pScreenPtr->devPrivate));
136137
}
137138

138139
static LoriePixmapPriv* lorieRootWindowPixmapPriv(void) {
@@ -396,6 +397,7 @@ static void loriePerformVblanks(void);
396397
static Bool lorieRedraw(__unused ClientPtr pClient, __unused void *closure) {
397398
int status, nonEmpty;
398399
LoriePixmapPriv* priv;
400+
PixmapPtr root = pScreenPtr && pScreenPtr->root ? pScreenPtr->GetWindowPixmap(pScreenPtr->root) : NULL;
399401

400402
loriePerformVblanks();
401403

@@ -405,7 +407,7 @@ static Bool lorieRedraw(__unused ClientPtr pClient, __unused void *closure) {
405407
return TRUE;
406408

407409
nonEmpty = RegionNotEmpty(DamageRegion(pvfb->damage));
408-
priv = lorieRootWindowPixmapPriv();
410+
priv = root ? exaGetPixmapDriverPrivate(root) : NULL;
409411

410412
if (!priv)
411413
// Impossible situation, but let's skip this step
@@ -457,7 +459,7 @@ static Bool lorieCreateScreenResources(ScreenPtr pScreen) {
457459
DamageRegister(&(*pScreen->GetScreenPixmap)(pScreen)->drawable, pvfb->damage);
458460
pvfb->fpsTimer = TimerSet(NULL, 0, 5000, lorieFramecounter, pScreen);
459461

460-
lorieSendRootWindowBuffer(LORIE_BUFFER_FROM_PIXMAP(pScreen->devPrivate));
462+
lorieRegisterBuffer(LORIE_BUFFER_FROM_PIXMAP(pScreenPtr->devPrivate));
461463

462464
return TRUE;
463465
}
@@ -517,7 +519,7 @@ static Bool lorieRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
517519
pScreen->DestroyPixmap(oldPixmap);
518520
}
519521

520-
lorieSendRootWindowBuffer(LORIE_BUFFER_FROM_PIXMAP(pScreen->devPrivate));
522+
lorieRegisterBuffer(LORIE_BUFFER_FROM_PIXMAP(pScreenPtr->devPrivate));
521523

522524
pScreen->ResizeWindow(pScreen->root, 0, 0, width, height, NULL);
523525
RegionReset(&pScreen->root->winSize, &box);
@@ -782,6 +784,7 @@ void lorieExaDestroyPixmap(__unused ScreenPtr pScreen, void *driverPriv) {
782784
if (!priv->imported)
783785
LorieBuffer_unlock(priv->buffer);
784786
LorieBuffer_release(priv->buffer);
787+
lorieUnregisterBuffer(priv->buffer);
785788
}
786789
free(priv);
787790
}

app/src/main/cpp/lorie/activity.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,19 @@ static int xcallback(int fd, int events, __unused void* data) {
191191
close(stateFd); // Closing file descriptor does not unmmap shared memory fragment.
192192
break;
193193
}
194-
case EVENT_SHARED_ROOT_WINDOW_BUFFER: {
194+
case EVENT_ADD_BUFFER: {
195195
static LorieBuffer* buffer = NULL;
196196
const LorieBuffer_Desc* desc;
197197
LorieBuffer_recvHandleFromUnixSocket(conn_fd, &buffer);
198198
desc = LorieBuffer_description(buffer);
199-
log(INFO, "Received shared buffer width %d height %d format %d", desc->width, desc->height, desc->format);
200-
rendererRemoveAllBuffers();
199+
log(INFO, "Received shared buffer width %d height %d format %d type %d id %llu", desc->width, desc->height, desc->format, desc->type, desc->id);
201200
rendererAddBuffer(buffer);
202201
break;
203202
}
203+
case EVENT_REMOVE_BUFFER: {
204+
rendererRemoveBuffer(e.removeBuffer.id);
205+
break;
206+
}
204207
}
205208
}
206209

app/src/main/cpp/lorie/buffer.c

+3
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,10 @@ static LorieBuffer* allocate(int32_t width, int32_t stride, int32_t height, int8
127127
return NULL;
128128

129129
AHardwareBuffer_describe(b.desc.buffer, &desc);
130+
b.desc.width = desc.width;
131+
b.desc.height = desc.height;
130132
b.desc.stride = desc.stride;
133+
b.desc.format = desc.format;
131134
break;
132135
}
133136
default: return NULL;

app/src/main/cpp/lorie/cmdentrypoint.c

+27-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ void lorieKeysymKeyboardEvent(KeySym keysym, int down);
3737
char *xtrans_unix_path_x11 = NULL;
3838
char *xtrans_unix_dir_x11 = NULL;
3939

40+
struct xorg_list registeredBuffers;
41+
4042
static void* startServer(__unused void* cookie) {
4143
char* envp[] = { NULL };
4244
exit(dix_main(argc, (char**) argv, envp));
@@ -196,6 +198,7 @@ Java_com_termux_x11_CmdEntryPoint_start(JNIEnv *env, __unused jclass cls, jobjec
196198
// Trigger it first time
197199
AChoreographer_postFrameCallback(choreographer, (AChoreographer_frameCallback) lorieChoreographerFrameCallback, choreographer);
198200

201+
xorg_list_init(&registeredBuffers);
199202
pthread_create(&t, NULL, startServer, vm);
200203
return JNI_TRUE;
201204
}
@@ -261,10 +264,13 @@ void handleLorieEvents(int fd, __unused int ready, __unused void *ignored) {
261264
valuator_mask_zero(&mask);
262265

263266
if (ready & X_NOTIFY_ERROR) {
267+
LorieBuffer* buf;
264268
InputThreadUnregisterDev(fd);
265269
close(fd);
266270
conn_fd = -1;
267271
lorieEnableClipboardSync(FALSE);
272+
while ((buf = LorieBufferList_first(&registeredBuffers)))
273+
LorieBuffer_removeFromList(buf);
268274
return;
269275
}
270276

@@ -433,11 +439,30 @@ void lorieSendSharedServerState(int memfd) {
433439
}
434440
}
435441

436-
void lorieSendRootWindowBuffer(LorieBuffer* buffer) {
442+
void lorieRegisterBuffer(LorieBuffer* buffer) {
443+
unsigned long id = LorieBuffer_description(buffer)->id;
444+
if (LorieBufferList_findById(&registeredBuffers, id))
445+
return; // Already registered
446+
437447
if (conn_fd != -1 && buffer) {
438-
lorieEvent e = { .type = EVENT_SHARED_ROOT_WINDOW_BUFFER };
448+
lorieEvent e = { .type = EVENT_ADD_BUFFER };
439449
write(conn_fd, &e, sizeof(e));
440450
LorieBuffer_sendHandleToUnixSocket(buffer, conn_fd);
451+
LorieBuffer_addToList(buffer, &registeredBuffers);
452+
const LorieBuffer_Desc* desc = LorieBuffer_description(buffer);
453+
log(INFO, "Received shared buffer width %d height %d format %d type %d id %llu", desc->width, desc->height, desc->format, desc->type, desc->id);
454+
}
455+
}
456+
457+
void lorieUnregisterBuffer(LorieBuffer* buffer) {
458+
unsigned long id;
459+
if (!buffer || (!LorieBufferList_findById(&registeredBuffers, (id = LorieBuffer_description(buffer)->id))))
460+
return; // Not exist or not registered so no need to unregister
461+
462+
if (conn_fd != -1 && buffer) {
463+
lorieEvent e = { .removeBuffer = { .t = EVENT_REMOVE_BUFFER, .id = id } };
464+
write(conn_fd, &e, sizeof(e));
465+
LorieBuffer_removeFromList(buffer);
441466
}
442467
}
443468

app/src/main/cpp/lorie/lorie.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ void lorieTriggerWorkingQueue(void);
3232
void lorieChoreographerFrameCallback(__unused long t, AChoreographer* d);
3333
void lorieActivityConnected(void);
3434
void lorieSendSharedServerState(int memfd);
35-
void lorieSendRootWindowBuffer(LorieBuffer* buffer);
35+
void lorieRegisterBuffer(LorieBuffer* buffer);
36+
void lorieUnregisterBuffer(LorieBuffer* buffer);
3637
bool lorieConnectionAlive(void);
3738

3839
__unused void rendererInit(JNIEnv* env);
@@ -88,7 +89,8 @@ static inline __always_inline void lorie_mutex_unlock(pthread_mutex_t* mutex, pi
8889
typedef enum {
8990
EVENT_UNKNOWN __unused = 0,
9091
EVENT_SHARED_SERVER_STATE,
91-
EVENT_SHARED_ROOT_WINDOW_BUFFER,
92+
EVENT_ADD_BUFFER,
93+
EVENT_REMOVE_BUFFER,
9294
EVENT_SCREEN_SIZE,
9395
EVENT_TOUCH,
9496
EVENT_MOUSE,
@@ -110,6 +112,10 @@ typedef union {
110112
size_t name_size;
111113
char *name;
112114
} screenSize;
115+
struct {
116+
uint8_t t;
117+
unsigned long id;
118+
} removeBuffer;
113119
struct {
114120
uint8_t t;
115121
uint16_t type, id, x, y;

app/src/main/cpp/lorie/renderer.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -521,10 +521,13 @@ void rendererRedrawLocked(JNIEnv* env) {
521521
// The buffer will not be released until this function ends, but main thread can modify buffer list
522522
pthread_mutex_lock(&stateLock);
523523
LorieBuffer *buffer = LorieBufferList_findById(&buffers, state->rootWindowTextureID);
524+
// Probably X server requested us to draw removed buffer and immediately requested to remove it. Let's display it one last time.
525+
if (!buffer)
526+
buffer = LorieBufferList_findById(&removedBuffers, state->rootWindowTextureID);
524527
pthread_mutex_unlock(&stateLock);
525528
if (!buffer) {
526529
log("Buffer %llu not found", state->rootWindowTextureID);
527-
usleep(2); // probably other thread did not push the buffer yet.
530+
usleep(4000); // probably other thread did not push the buffer yet, 4 ms should be enough time to finish this.
528531
return;
529532
}
530533

0 commit comments

Comments
 (0)