[client/obs] improve frambuffer_read functions to support copy pitch

Fixes #244
This commit is contained in:
Geoffrey McRae
2020-04-14 13:27:07 +10:00
parent ead09ed110
commit f6691a90c0
6 changed files with 68 additions and 36 deletions

View File

@@ -40,12 +40,14 @@ void framebuffer_wait(const FrameBuffer * frame, size_t size);
/**
* Read data from the KVMFRFrame into the dst buffer
*/
bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t size);
bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t dstpitch,
size_t height, size_t width, size_t bpp, size_t pitch);
/**
* Read data from the KVMFRFrame using a callback
*/
bool framebuffer_read_fn(const FrameBuffer * frame, FrameBufferReadFn fn, size_t size, void * opaque);
bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width,
size_t bpp, size_t pitch, FrameBufferReadFn fn, void * opaque);
/**
* Prepare the framebuffer for writing

View File

@@ -38,53 +38,55 @@ void framebuffer_wait(const FrameBuffer * frame, size_t size)
while(atomic_load_explicit(&frame->wp, memory_order_relaxed) != size) {}
}
bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t size)
bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t dstpitch,
size_t height, size_t width, size_t bpp, size_t pitch)
{
uint8_t *d = (uint8_t*)dst;
uint64_t rp = 0;
while(rp < size)
uint8_t *d = (uint8_t*)dst;
uint_least32_t rp = 0;
size_t y = 0;
const size_t linewidth = width * bpp;
while(y < height)
{
uint_least32_t wp;
/* spinlock */
do
wp = atomic_load_explicit(&frame->wp, memory_order_relaxed);
while(rp == wp);
while(wp - rp < pitch);
/* copy what we can */
uint64_t avail = wp - rp;
avail = avail > size ? size : avail;
memcpy(d, frame->data + rp, linewidth);
memcpy(d, frame->data + rp, avail);
rp += avail;
d += avail;
size -= avail;
rp += pitch;
d += dstpitch;
++y;
}
return true;
}
bool framebuffer_read_fn(const FrameBuffer * frame, FrameBufferReadFn fn, size_t size, void * opaque)
bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width,
size_t bpp, size_t pitch, FrameBufferReadFn fn, void * opaque)
{
uint64_t rp = 0;
while(rp < size)
uint_least32_t rp = 0;
size_t y = 0;
const size_t linewidth = width * bpp;
while(y < height)
{
uint_least32_t wp;
/* spinlock */
do
wp = atomic_load_explicit(&frame->wp, memory_order_relaxed);
while(rp == wp);
while(wp - rp < pitch);
/* copy what we can */
uint64_t avail = wp - rp;
avail = avail > size ? size : avail;
if (!fn(opaque, frame->data + rp, avail))
if (!fn(opaque, frame->data + rp, linewidth))
return false;
rp += avail;
size -= avail;
rp += pitch;
++y;
}
return true;