diff --git a/common/include/common/framebuffer.h b/common/include/common/framebuffer.h index 176c75f3..10818910 100644 --- a/common/include/common/framebuffer.h +++ b/common/include/common/framebuffer.h @@ -61,6 +61,12 @@ void framebuffer_prepare(FrameBuffer * frame); */ bool framebuffer_write(FrameBuffer * frame, const void * src, size_t size); +/** + * Gets the underlying data buffer of the framebuffer. + * For custom read routines only. + */ +const uint8_t * framebuffer_get_buffer(const FrameBuffer * frame); + /** * Gets the underlying data buffer of the framebuffer. * For custom write routines only. diff --git a/common/include/common/rects.h b/common/include/common/rects.h index ca79d503..50ad8932 100644 --- a/common/include/common/rects.h +++ b/common/include/common/rects.h @@ -42,4 +42,8 @@ void rectsBufferToFramebuffer(FrameDamageRect * rects, int count, FrameBuffer * frame, int dstStride, int height, const uint8_t * src, int srcStride); +void rectsFramebufferToBuffer(FrameDamageRect * rects, int count, + uint8_t * dst, int dstStride, int height, + const FrameBuffer * frame, int srcStride); + #endif diff --git a/common/src/framebuffer.c b/common/src/framebuffer.c index 484fea54..b677b53e 100644 --- a/common/src/framebuffer.c +++ b/common/src/framebuffer.c @@ -214,6 +214,11 @@ bool framebuffer_write(FrameBuffer * frame, const void * restrict src, size_t si return true; } +const uint8_t * framebuffer_get_buffer(const FrameBuffer * frame) +{ + return frame->data; +} + uint8_t * framebuffer_get_data(FrameBuffer * frame) { return frame->data; diff --git a/common/src/rects.c b/common/src/rects.c index e92b03a7..e510edc8 100644 --- a/common/src/rects.c +++ b/common/src/rects.c @@ -50,6 +50,7 @@ static int cornerCompare(const void * a_, const void * b_) inline static void rectsBufferCopy(FrameDamageRect * rects, int count, uint8_t * dst, int dstStride, int height, const uint8_t * src, int srcStride, void * opaque, + void (*rowCopyStart)(int y, void * opaque), void (*rowCopyFinish)(int y, void * opaque)) { const int cornerCount = 4 * count; @@ -99,6 +100,9 @@ inline static void rectsBufferCopy(FrameDamageRect * rects, int count, change[changes++] = (struct Edge) { .x = x, .delta = delta }; } + if (rowCopyStart) + rowCopyStart(y, opaque); + struct Edge * active = active_[activeRow]; int x1 = 0; int in_rect = 0; @@ -169,6 +173,27 @@ void rectsBufferToFramebuffer(FrameDamageRect * rects, int count, { struct ToFramebufferData data = { .frame = frame, .stride = dstStride }; rectsBufferCopy(rects, count, framebuffer_get_data(frame), dstStride, height, - src, srcStride, &data, fbRowFinish); + src, srcStride, &data, NULL, fbRowFinish); framebuffer_set_write_ptr(frame, height * dstStride); } + +struct FromFramebufferData +{ + const FrameBuffer * frame; + int stride; +}; + +static void fbRowStart(int y, void * opaque) +{ + struct FromFramebufferData * data = opaque; + framebuffer_wait(data->frame, y * data->stride); +} + +void rectsFramebufferToBuffer(FrameDamageRect * rects, int count, + uint8_t * dst, int dstStride, int height, + const FrameBuffer * frame, int srcStride) +{ + struct FromFramebufferData data = { .frame = frame, .stride = srcStride }; + rectsBufferCopy(rects, count, dst, dstStride, height, + framebuffer_get_buffer(frame), srcStride, &data, fbRowStart, NULL); +}