mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-11-03 22:22:08 +00:00 
			
		
		
		
	@@ -187,7 +187,7 @@ static int frameThread(void * opaque)
 | 
			
		||||
    fi->height  = frame.height;
 | 
			
		||||
    fi->stride  = frame.stride;
 | 
			
		||||
    fi->pitch   = frame.pitch;
 | 
			
		||||
    fi->offset  = pageSize - sizeof(FrameBuffer);
 | 
			
		||||
    fi->offset  = pageSize - FrameBufferStructSize;
 | 
			
		||||
    frameValid  = true;
 | 
			
		||||
 | 
			
		||||
    // put the framebuffer on the border of the next page
 | 
			
		||||
 
 | 
			
		||||
@@ -23,24 +23,19 @@ Place, Suite 330, Boston, MA 02111-1307 USA
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct stFrameBuffer
 | 
			
		||||
{
 | 
			
		||||
  uint64_t  wp;
 | 
			
		||||
  uint8_t   data[0];
 | 
			
		||||
}
 | 
			
		||||
FrameBuffer;
 | 
			
		||||
 | 
			
		||||
typedef struct stFrameBuffer FrameBuffer;
 | 
			
		||||
 | 
			
		||||
typedef bool (*FrameBufferReadFn)(void * opaque, const void * src, size_t size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The size of the FrameBuffer struct
 | 
			
		||||
 */
 | 
			
		||||
extern const size_t FrameBufferStructSize;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wait for the framebuffer to fill to the specified size
 | 
			
		||||
 */
 | 
			
		||||
static inline void framebuffer_wait(const FrameBuffer * frame, size_t size)
 | 
			
		||||
{
 | 
			
		||||
  while(frame->wp != size) {}
 | 
			
		||||
}
 | 
			
		||||
void framebuffer_wait(const FrameBuffer * frame, size_t size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read data from the KVMFRFrame into the dst buffer
 | 
			
		||||
@@ -60,4 +55,4 @@ void framebuffer_prepare(FrameBuffer * frame);
 | 
			
		||||
/**
 | 
			
		||||
 * Write data from the src buffer into the KVMFRFrame
 | 
			
		||||
 */
 | 
			
		||||
bool framebuffer_write(FrameBuffer * frame, const void * src, size_t size);
 | 
			
		||||
bool framebuffer_write(FrameBuffer * frame, const void * src, size_t size);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,19 +21,38 @@ Place, Suite 330, Boston, MA 02111-1307 USA
 | 
			
		||||
#include "common/debug.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdatomic.h>
 | 
			
		||||
 | 
			
		||||
#define FB_CHUNK_SIZE 1024
 | 
			
		||||
 | 
			
		||||
struct stFrameBuffer
 | 
			
		||||
{
 | 
			
		||||
  atomic_uint_least32_t wp;
 | 
			
		||||
  uint8_t               data[0];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const size_t FrameBufferStructSize = sizeof(FrameBuffer);
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
  uint8_t *d  = (uint8_t*)dst;
 | 
			
		||||
  uint64_t rp = 0;
 | 
			
		||||
  while(rp < size)
 | 
			
		||||
  {
 | 
			
		||||
    uint_least32_t wp;
 | 
			
		||||
 | 
			
		||||
    /* spinlock */
 | 
			
		||||
    while(rp == frame->wp) { }
 | 
			
		||||
    do
 | 
			
		||||
      wp = atomic_load_explicit(&frame->wp, memory_order_relaxed);
 | 
			
		||||
    while(rp == wp);
 | 
			
		||||
 | 
			
		||||
    /* copy what we can */
 | 
			
		||||
    uint64_t avail = frame->wp - rp;
 | 
			
		||||
    uint64_t avail = wp - rp;
 | 
			
		||||
    avail = avail > size ? size : avail;
 | 
			
		||||
 | 
			
		||||
    memcpy(d, frame->data + rp, avail);
 | 
			
		||||
@@ -50,11 +69,15 @@ bool framebuffer_read_fn(const FrameBuffer * frame, FrameBufferReadFn fn, size_t
 | 
			
		||||
  uint64_t rp = 0;
 | 
			
		||||
  while(rp < size)
 | 
			
		||||
  {
 | 
			
		||||
    uint_least32_t wp;
 | 
			
		||||
 | 
			
		||||
    /* spinlock */
 | 
			
		||||
    while(rp == frame->wp) { }
 | 
			
		||||
    do
 | 
			
		||||
      wp = atomic_load_explicit(&frame->wp, memory_order_relaxed);
 | 
			
		||||
    while(rp == wp);
 | 
			
		||||
 | 
			
		||||
    /* copy what we can */
 | 
			
		||||
    uint64_t avail = frame->wp - rp;
 | 
			
		||||
    uint64_t avail = wp - rp;
 | 
			
		||||
    avail = avail > size ? size : avail;
 | 
			
		||||
 | 
			
		||||
    if (!fn(opaque, frame->data + rp, avail))
 | 
			
		||||
@@ -82,8 +105,8 @@ bool framebuffer_write(FrameBuffer * frame, const void * src, size_t size)
 | 
			
		||||
  {
 | 
			
		||||
    size_t copy = size < FB_CHUNK_SIZE ? FB_CHUNK_SIZE : size;
 | 
			
		||||
    memcpy(frame->data + frame->wp, src, copy);
 | 
			
		||||
    __sync_fetch_and_add(&frame->wp, copy);
 | 
			
		||||
    atomic_fetch_add(&frame->wp, copy);
 | 
			
		||||
    size -= copy;
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user