Skip to content

Commit 0634a1d

Browse files
committed
convert LorieBuffer to shareable type if app requests window flip
1 parent 883a66b commit 0634a1d

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

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

+37
Original file line numberDiff line numberDiff line change
@@ -743,11 +743,48 @@ static void loriePerformVblanks(void) {
743743
}
744744
}
745745

746+
Bool loriePresentCheckFlip(__unused RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, __unused Bool sync_flip) {
747+
LoriePixmapPriv* priv = (LoriePixmapPriv*) exaGetPixmapDriverPrivate(pixmap);
748+
if (!priv || !priv->buffer || priv->mem)
749+
return FALSE;
750+
751+
const LorieBuffer_Desc *desc = LorieBuffer_description(priv->buffer);
752+
if (desc->type == LORIEBUFFER_REGULAR) {
753+
// Regular buffers can not be shared to activity, we must explicitly convert LorieBuffer to FD or AHardwareBuffer
754+
int8_t type = pvfb->root.legacyDrawing ? LORIEBUFFER_FD : LORIEBUFFER_AHARDWAREBUFFER;
755+
int8_t format = pvfb->root.flip ? AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM : AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;
756+
LorieBuffer_convert(priv->buffer, type, format);
757+
if (desc->type != LORIEBUFFER_REGULAR) {
758+
// LorieBuffer_convert does not report status but it does not let the type change in the case of error.
759+
pScreenPtr->ModifyPixmapHeader(pixmap, 0, 0, 0, 0, desc->stride * 4, NULL);
760+
LorieBuffer_lock(priv->buffer, &priv->locked);
761+
}
762+
}
763+
764+
if (desc->type != LORIEBUFFER_FD && desc->type != LORIEBUFFER_AHARDWAREBUFFER)
765+
return FALSE;
766+
767+
/* currently not implemented */
768+
return FALSE;
769+
}
770+
771+
Bool loriePresentFlip(__unused RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, PixmapPtr pixmap, __unused Bool sync_flip) {
772+
/* currently not implemented */
773+
return FALSE;
774+
}
775+
776+
void loriePresentUnflip(__unused ScreenPtr screen, uint64_t event_id) {
777+
/* currently not implemented */
778+
}
779+
746780
static struct present_screen_info loriePresentInfo = {
747781
.get_crtc = loriePresentGetCrtc,
748782
.get_ust_msc = loriePresentGetUstMsc,
749783
.queue_vblank = loriePresentQueueVblank,
750784
.abort_vblank = loriePresentAbortVblank,
785+
.check_flip = loriePresentCheckFlip,
786+
.flip = loriePresentFlip,
787+
.unflip = loriePresentUnflip,
751788
};
752789

753790
void exaDDXDriverInit(__unused ScreenPtr pScreen) {}

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

+50
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,56 @@ __LIBC_HIDDEN__ LorieBuffer* LorieBuffer_wrapAHardwareBuffer(AHardwareBuffer* bu
189189
return allocate(0, 0, 0, 0, LORIEBUFFER_AHARDWAREBUFFER, buffer, -1, 0, 0);
190190
}
191191

192+
__LIBC_HIDDEN__ void LorieBuffer_convert(LorieBuffer* buffer, int8_t type, int8_t format) {
193+
if (!buffer || buffer->desc.type != LORIEBUFFER_REGULAR
194+
|| (type != LORIEBUFFER_FD && type != LORIEBUFFER_AHARDWAREBUFFER)
195+
|| (format != AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM && format != AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM))
196+
return;
197+
198+
if (type == LORIEBUFFER_FD) {
199+
size_t size = alignToPage(buffer->desc.stride * buffer->desc.height * sizeof(uint32_t));
200+
int fd = LorieBuffer_createRegion("LorieBuffer", size);
201+
void *data;
202+
if (fd < 0)
203+
return;
204+
205+
data = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
206+
if (!data || data == MAP_FAILED) {
207+
close(fd);
208+
return;
209+
}
210+
211+
buffer->desc.type = type;
212+
buffer->desc.format = format;
213+
buffer->fd = fd;
214+
buffer->size = size;
215+
buffer->offset = 0;
216+
free(buffer->desc.data);
217+
buffer->desc.data = data;
218+
219+
buffer->lockedData = NULL;
220+
buffer->locked = 0;
221+
} else {
222+
AHardwareBuffer *b = NULL;
223+
AHardwareBuffer_Desc desc = { .width = buffer->desc.width, .height = buffer->desc.height, .format = format, .layers = 1,
224+
.usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE };
225+
int err = AHardwareBuffer_allocate(&desc, &b);
226+
if (err != 0)
227+
return;
228+
229+
AHardwareBuffer_describe(b, &desc);
230+
231+
buffer->desc.type = type;
232+
buffer->desc.format = format;
233+
buffer->desc.stride = desc.stride;
234+
buffer->desc.buffer = b;
235+
free(buffer->desc.data);
236+
buffer->desc.data = NULL;
237+
buffer->lockedData = NULL;
238+
buffer->locked = 0;
239+
}
240+
}
241+
192242
__LIBC_HIDDEN__ void __LorieBuffer_free(LorieBuffer* buffer) {
193243
if (!buffer)
194244
return;

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

+9
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ LorieBuffer* _Nullable LorieBuffer_wrapFileDescriptor(int32_t width, int32_t str
6868
*/
6969
LorieBuffer* _Nullable LorieBuffer_wrapAHardwareBuffer(AHardwareBuffer* _Nullable buffer);
7070

71+
/**
72+
* Convert regular buffer to given type.
73+
*
74+
* @param buffer
75+
* @param type
76+
* @param format
77+
*/
78+
void LorieBuffer_convert(LorieBuffer* _Nullable buffer, int8_t type, int8_t format);
79+
7180
/**
7281
* Acquire a reference on the given LorieBuffer object.
7382
*

0 commit comments

Comments
 (0)