mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 13:37:22 +00:00
[host] kvmfr: allow the frame size to exceed the available memory
This change allows the host to still transmit a frame that is truncated if the IVSHMEM size is too small to allow for a full frame.
This commit is contained in:
parent
4b99bba200
commit
d36c4f0e83
@ -28,7 +28,7 @@
|
||||
#include "types.h"
|
||||
|
||||
#define KVMFR_MAGIC "KVMFR---"
|
||||
#define KVMFR_VERSION 9
|
||||
#define KVMFR_VERSION 10
|
||||
|
||||
#define LGMP_Q_POINTER 1
|
||||
#define LGMP_Q_FRAME 2
|
||||
@ -68,8 +68,9 @@ typedef struct KVMFRFrame
|
||||
{
|
||||
uint32_t formatVer; // the frame format version number
|
||||
FrameType type; // the frame data type
|
||||
uint32_t width; // the width
|
||||
uint32_t height; // the height
|
||||
uint32_t width; // the frame width
|
||||
uint32_t height; // the frame height
|
||||
uint32_t realHeight; // the real height if the frame was truncated due to low mem
|
||||
FrameRotation rotation; // the frame rotation
|
||||
uint32_t stride; // the row stride (zero if compressed data)
|
||||
uint32_t pitch; // the row pitch (stride in bytes or the compressed frame size)
|
||||
|
@ -64,6 +64,7 @@ typedef struct CaptureFrame
|
||||
unsigned int formatVer;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int realHeight;
|
||||
unsigned int pitch;
|
||||
unsigned int stride;
|
||||
CaptureFormat format;
|
||||
@ -99,15 +100,14 @@ typedef struct CaptureInterface
|
||||
CapturePostPointerBuffer postPointerBufferFn
|
||||
);
|
||||
|
||||
bool (*init )();
|
||||
void (*stop )();
|
||||
bool (*deinit )();
|
||||
void (*free )();
|
||||
unsigned int (*getMaxFrameSize)();
|
||||
unsigned int (*getMouseScale )();
|
||||
bool (*init )();
|
||||
void (*stop )();
|
||||
bool (*deinit )();
|
||||
void (*free )();
|
||||
unsigned int (*getMouseScale)();
|
||||
|
||||
CaptureResult (*capture )();
|
||||
CaptureResult (*waitFrame )(CaptureFrame * frame);
|
||||
CaptureResult (*getFrame )(FrameBuffer * frame);
|
||||
CaptureResult (*waitFrame )(CaptureFrame * frame, const size_t maxFrameSize);
|
||||
CaptureResult (*getFrame )(FrameBuffer * frame, const unsigned int height);
|
||||
}
|
||||
CaptureInterface;
|
||||
|
@ -714,14 +714,6 @@ static void dxgi_free(void)
|
||||
this = NULL;
|
||||
}
|
||||
|
||||
static unsigned int dxgi_getMaxFrameSize(void)
|
||||
{
|
||||
assert(this);
|
||||
assert(this->initialized);
|
||||
|
||||
return this->height * this->pitch;
|
||||
}
|
||||
|
||||
static unsigned int dxgi_getMouseScale(void)
|
||||
{
|
||||
assert(this);
|
||||
@ -928,7 +920,7 @@ static CaptureResult dxgi_capture(void)
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
||||
static CaptureResult dxgi_waitFrame(CaptureFrame * frame, const size_t maxFrameSize)
|
||||
{
|
||||
assert(this);
|
||||
assert(this->initialized);
|
||||
@ -980,26 +972,30 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
||||
|
||||
tex->state = TEXTURE_STATE_MAPPED;
|
||||
|
||||
frame->formatVer = tex->formatVer;
|
||||
frame->width = this->width;
|
||||
frame->height = this->height;
|
||||
frame->pitch = this->pitch;
|
||||
frame->stride = this->stride;
|
||||
frame->format = this->format;
|
||||
frame->rotation = this->rotation;
|
||||
const unsigned int maxHeight = maxFrameSize / this->pitch;
|
||||
|
||||
frame->formatVer = tex->formatVer;
|
||||
frame->width = this->width;
|
||||
frame->height = maxHeight > this->height ? this->height : maxHeight;
|
||||
frame->realHeight = this->height;
|
||||
frame->pitch = this->pitch;
|
||||
frame->stride = this->stride;
|
||||
frame->format = this->format;
|
||||
frame->rotation = this->rotation;
|
||||
|
||||
atomic_fetch_sub_explicit(&this->texReady, 1, memory_order_release);
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
static CaptureResult dxgi_getFrame(FrameBuffer * frame)
|
||||
static CaptureResult dxgi_getFrame(FrameBuffer * frame,
|
||||
const unsigned int height)
|
||||
{
|
||||
assert(this);
|
||||
assert(this->initialized);
|
||||
|
||||
Texture * tex = &this->texture[this->texRIndex];
|
||||
|
||||
framebuffer_write(frame, tex->map.pData, this->pitch * this->height);
|
||||
framebuffer_write(frame, tex->map.pData, this->pitch * height);
|
||||
LOCKED({ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)tex->tex, 0);});
|
||||
tex->state = TEXTURE_STATE_UNUSED;
|
||||
|
||||
@ -1052,7 +1048,6 @@ struct CaptureInterface Capture_DXGI =
|
||||
.stop = dxgi_stop,
|
||||
.deinit = dxgi_deinit,
|
||||
.free = dxgi_free,
|
||||
.getMaxFrameSize = dxgi_getMaxFrameSize,
|
||||
.getMouseScale = dxgi_getMouseScale,
|
||||
.capture = dxgi_capture,
|
||||
.waitFrame = dxgi_waitFrame,
|
||||
|
@ -275,11 +275,6 @@ static void nvfbc_free(void)
|
||||
NvFBCFree();
|
||||
}
|
||||
|
||||
static unsigned int nvfbc_getMaxFrameSize(void)
|
||||
{
|
||||
return this->maxWidth * this->maxHeight * 4;
|
||||
}
|
||||
|
||||
static unsigned int nvfbc_getMouseScale(void)
|
||||
{
|
||||
return this->dpi * 100 / DPI_100_PERCENT;
|
||||
@ -320,7 +315,8 @@ static CaptureResult nvfbc_capture(void)
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
static CaptureResult nvfbc_waitFrame(CaptureFrame * frame)
|
||||
static CaptureResult nvfbc_waitFrame(CaptureFrame * frame,
|
||||
const size_t maxFrameSize)
|
||||
{
|
||||
if (!lgWaitEvent(this->frameEvent, 1000))
|
||||
return CAPTURE_RESULT_TIMEOUT;
|
||||
@ -339,12 +335,15 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame)
|
||||
++this->formatVer;
|
||||
}
|
||||
|
||||
frame->formatVer = this->formatVer;
|
||||
frame->width = this->grabWidth;
|
||||
frame->height = this->grabHeight;
|
||||
frame->pitch = this->grabStride * 4;
|
||||
frame->stride = this->grabStride;
|
||||
frame->rotation = CAPTURE_ROT_0;
|
||||
const unsigned int maxHeight = maxFrameSize / (this->grabStride * 4);
|
||||
|
||||
frame->formatVer = this->formatVer;
|
||||
frame->width = this->grabWidth;
|
||||
frame->height = maxHeight > this->grabHeight ? this->grabHeight : maxHeight;
|
||||
frame->realHeight = this->grabHeight;
|
||||
frame->pitch = this->grabStride * 4;
|
||||
frame->stride = this->grabStride;
|
||||
frame->rotation = CAPTURE_ROT_0;
|
||||
|
||||
#if 0
|
||||
//NvFBC never sets bIsHDR so instead we check for any data in the alpha channel
|
||||
@ -366,12 +365,13 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame)
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
static CaptureResult nvfbc_getFrame(FrameBuffer * frame)
|
||||
static CaptureResult nvfbc_getFrame(FrameBuffer * frame,
|
||||
const unsigned int height)
|
||||
{
|
||||
framebuffer_write(
|
||||
frame,
|
||||
this->frameBuffer,
|
||||
this->grabInfo.dwHeight * this->grabInfo.dwBufferWidth * 4
|
||||
height * this->grabInfo.dwBufferWidth * 4
|
||||
);
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
@ -442,7 +442,6 @@ struct CaptureInterface Capture_NVFBC =
|
||||
.stop = nvfbc_stop,
|
||||
.deinit = nvfbc_deinit,
|
||||
.free = nvfbc_free,
|
||||
.getMaxFrameSize = nvfbc_getMaxFrameSize,
|
||||
.getMouseScale = nvfbc_getMouseScale,
|
||||
.capture = nvfbc_capture,
|
||||
.waitFrame = nvfbc_waitFrame,
|
||||
|
@ -156,7 +156,7 @@ static int frameThread(void * opaque)
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(app.iface->waitFrame(&frame))
|
||||
switch(app.iface->waitFrame(&frame, app.maxFrameSize))
|
||||
{
|
||||
case CAPTURE_RESULT_OK:
|
||||
repeatFrame = false;
|
||||
@ -230,6 +230,7 @@ static int frameThread(void * opaque)
|
||||
fi->formatVer = frame.formatVer;
|
||||
fi->width = frame.width;
|
||||
fi->height = frame.height;
|
||||
fi->realHeight = frame.realHeight;
|
||||
fi->stride = frame.stride;
|
||||
fi->pitch = frame.pitch;
|
||||
fi->offset = pageSize - FrameBufferStructSize;
|
||||
@ -248,7 +249,7 @@ static int frameThread(void * opaque)
|
||||
DEBUG_ERROR("%s", lgmpStatusString(status));
|
||||
continue;
|
||||
}
|
||||
app.iface->getFrame(fb);
|
||||
app.iface->getFrame(fb, frame.height);
|
||||
}
|
||||
DEBUG_INFO("Frame thread stopped");
|
||||
return 0;
|
||||
@ -295,24 +296,7 @@ static bool captureStart(void)
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned int maxFrameSize = app.iface->getMaxFrameSize();
|
||||
if (maxFrameSize > app.maxFrameSize)
|
||||
{
|
||||
DEBUG_ERROR("Maximum frame size of %d bytes exceeds maximum space available", maxFrameSize);
|
||||
|
||||
const float needed = ((maxFrameSize * 2) / 1048576.0f) + 10.0f;
|
||||
const int size = (int)powf(2.0f, ceilf(logf(needed) / logf(2.0f)));
|
||||
|
||||
char * msg;
|
||||
alloc_sprintf(&msg, "IVSHMEM size too small, increase to %d MiB", size);
|
||||
os_showMessage("Looking Glass Error", msg);
|
||||
free(msg);
|
||||
|
||||
return false;
|
||||
}
|
||||
DEBUG_INFO("Capture Size : %u MiB (%u)", maxFrameSize / 1048576, maxFrameSize);
|
||||
|
||||
DEBUG_INFO("==== [ Capture Start ] ====");
|
||||
DEBUG_INFO("==== [ Capture Start ] ====");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user