mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-06 02:34:00 +00:00
[client/obs] improve frambuffer_read functions to support copy pitch
Fixes #244
This commit is contained in:
@@ -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
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user