mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-12-14 12:08:14 +00:00
Compare commits
3 Commits
Release/B6
...
frame-timi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ee30b2308 | ||
|
|
714b1bce70 | ||
|
|
3ec632dd3c |
@@ -65,30 +65,15 @@ static const struct xdg_surface_listener xdgSurfaceListener = {
|
|||||||
static void xdgToplevelConfigure(void * data, struct xdg_toplevel * xdgToplevel,
|
static void xdgToplevelConfigure(void * data, struct xdg_toplevel * xdgToplevel,
|
||||||
int32_t width, int32_t height, struct wl_array * states)
|
int32_t width, int32_t height, struct wl_array * states)
|
||||||
{
|
{
|
||||||
wlWm.width = width;
|
wlWm.width = width;
|
||||||
wlWm.height = height;
|
wlWm.height = height;
|
||||||
wlWm.fullscreen = false;
|
wlWm.fullscreen = false;
|
||||||
wlWm.floating = true;
|
|
||||||
|
|
||||||
enum xdg_toplevel_state * state;
|
enum xdg_toplevel_state * state;
|
||||||
wl_array_for_each(state, states)
|
wl_array_for_each(state, states)
|
||||||
{
|
{
|
||||||
switch (*state)
|
if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN)
|
||||||
{
|
|
||||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
|
||||||
wlWm.fullscreen = true;
|
wlWm.fullscreen = true;
|
||||||
// fallthrough
|
|
||||||
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
|
||||||
case XDG_TOPLEVEL_STATE_TILED_LEFT:
|
|
||||||
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
|
|
||||||
case XDG_TOPLEVEL_STATE_TILED_TOP:
|
|
||||||
case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
|
|
||||||
wlWm.floating = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,14 +156,5 @@ void waylandMinimize(void)
|
|||||||
|
|
||||||
void waylandShellResize(int w, int h)
|
void waylandShellResize(int w, int h)
|
||||||
{
|
{
|
||||||
if (!wlWm.floating)
|
//TODO: Implement resize for XDG.
|
||||||
return;
|
|
||||||
|
|
||||||
wlWm.width = w;
|
|
||||||
wlWm.height = h;
|
|
||||||
xdg_surface_set_window_geometry(wlWm.xdgSurface, 0, 0, w, h);
|
|
||||||
|
|
||||||
wlWm.needsResize = true;
|
|
||||||
app_invalidateWindow(true);
|
|
||||||
waylandStopWaitFrame();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,6 @@ struct WaylandDSState
|
|||||||
bool fractionalScale;
|
bool fractionalScale;
|
||||||
bool needsResize;
|
bool needsResize;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool floating;
|
|
||||||
uint32_t resizeSerial;
|
uint32_t resizeSerial;
|
||||||
bool configured;
|
bool configured;
|
||||||
bool warpSupport;
|
bool warpSupport;
|
||||||
|
|||||||
@@ -478,10 +478,11 @@ void core_handleMouseNormal(double ex, double ey)
|
|||||||
if (!g_state.stopVideo &&
|
if (!g_state.stopVideo &&
|
||||||
g_state.kvmfrFeatures & KVMFR_FEATURE_SETCURSORPOS)
|
g_state.kvmfrFeatures & KVMFR_FEATURE_SETCURSORPOS)
|
||||||
{
|
{
|
||||||
const KVMFRSetCursorPos msg = {
|
const KVMFRMessage_SetCursorPos msg = {
|
||||||
.msg.type = KVMFR_MESSAGE_SETCURSORPOS,
|
.msg.type = KVMFR_MESSAGE_SETCURSORPOS,
|
||||||
.x = round(guest.x),
|
.msg.clientID = g_state.clientID,
|
||||||
.y = round(guest.y)
|
.x = round(guest.x),
|
||||||
|
.y = round(guest.y)
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t setPosSerial;
|
uint32_t setPosSerial;
|
||||||
|
|||||||
@@ -1434,7 +1434,7 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = lgmpClientSessionInit(g_state.lgmp, &udataSize, (uint8_t **)&udata,
|
status = lgmpClientSessionInit(g_state.lgmp, &udataSize, (uint8_t **)&udata,
|
||||||
NULL);
|
&g_state.clientID);
|
||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
case LGMP_OK:
|
case LGMP_OK:
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ struct AppState
|
|||||||
|
|
||||||
struct IVSHMEM shm;
|
struct IVSHMEM shm;
|
||||||
PLGMPClient lgmp;
|
PLGMPClient lgmp;
|
||||||
|
uint32_t clientID;
|
||||||
PLGMPClientQueue pointerQueue;
|
PLGMPClientQueue pointerQueue;
|
||||||
LG_Lock pointerQueueLock;
|
LG_Lock pointerQueueLock;
|
||||||
KVMFRFeatureFlags kvmfrFeatures;
|
KVMFRFeatureFlags kvmfrFeatures;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define KVMFR_MAGIC "KVMFR---"
|
#define KVMFR_MAGIC "KVMFR---"
|
||||||
#define KVMFR_VERSION 19
|
#define KVMFR_VERSION 20
|
||||||
|
|
||||||
#define KVMFR_MAX_DAMAGE_RECTS 64
|
#define KVMFR_MAX_DAMAGE_RECTS 64
|
||||||
|
|
||||||
@@ -56,7 +56,8 @@ typedef uint32_t KVMFRFeatureFlags;
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
KVMFR_MESSAGE_SETCURSORPOS
|
KVMFR_MESSAGE_SETCURSORPOS,
|
||||||
|
KVMFR_MESSAGE_FRAME_TIME
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t KVMFRMessageType;
|
typedef uint32_t KVMFRMessageType;
|
||||||
@@ -137,6 +138,8 @@ typedef struct KVMFRFrame
|
|||||||
{
|
{
|
||||||
uint32_t formatVer; // the frame format version number
|
uint32_t formatVer; // the frame format version number
|
||||||
uint32_t frameSerial; // the unique frame number
|
uint32_t frameSerial; // the unique frame number
|
||||||
|
uint64_t frameTimeUs; // when the capture was started
|
||||||
|
uint64_t frameElapsedUs; // total time elapsed to capture the frame
|
||||||
FrameType type; // the frame data type
|
FrameType type; // the frame data type
|
||||||
uint32_t screenWidth; // the client's screen width
|
uint32_t screenWidth; // the client's screen width
|
||||||
uint32_t screenHeight; // the client's screen height
|
uint32_t screenHeight; // the client's screen height
|
||||||
@@ -155,14 +158,28 @@ KVMFRFrame;
|
|||||||
typedef struct KVMFRMessage
|
typedef struct KVMFRMessage
|
||||||
{
|
{
|
||||||
KVMFRMessageType type;
|
KVMFRMessageType type;
|
||||||
|
uint32_t clientID;
|
||||||
}
|
}
|
||||||
KVMFRMessage;
|
KVMFRMessage;
|
||||||
|
|
||||||
typedef struct KVMFRSetCursorPos
|
typedef struct KVMFRMessage_SetCursorPos
|
||||||
{
|
{
|
||||||
KVMFRMessage msg;
|
KVMFRMessage msg;
|
||||||
int32_t x, y;
|
int32_t x, y;
|
||||||
}
|
}
|
||||||
KVMFRSetCursorPos;
|
KVMFRMessage_SetCursorPos;
|
||||||
|
|
||||||
|
typedef struct KVMFRMessage_FrameTime
|
||||||
|
{
|
||||||
|
KVMFRMessage msg;
|
||||||
|
/* this is the desired time to start the next capture operation where zero is
|
||||||
|
* immediate. This is only a hint to the host application and may not be
|
||||||
|
* honored. The value provided should be offset from the latest frame's
|
||||||
|
* frameTimeUs. When multiple clients are sending this message, the one with
|
||||||
|
* the lowest value will be used.
|
||||||
|
*/
|
||||||
|
uint64_t frameTimeUs;
|
||||||
|
}
|
||||||
|
KVMFRMessage_FrameTime;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -316,55 +316,43 @@ static bool nvfbc_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int adapterIndex = option_get_int("nvfbc", "adapterIndex");
|
int adapterIndex = option_get_int("nvfbc", "adapterIndex");
|
||||||
|
// NOTE: Calling this on hardware that doesn't support NvFBC such as GeForce
|
||||||
bool created = false;
|
// causes a substantial performance pentalty even if it fails! As such we only
|
||||||
for(int retry = 0; retry < 2; ++retry)
|
// attempt NvFBC as a last resort, or if configured via the app:capture
|
||||||
|
// option.
|
||||||
|
if (adapterIndex < 0)
|
||||||
{
|
{
|
||||||
// NOTE: Calling this on hardware that doesn't support NvFBC such as GeForce
|
IDirect3D9 * d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||||
// causes a substantial performance pentalty even if it fails! As such we only
|
int adapterCount = IDirect3D9_GetAdapterCount(d3d);
|
||||||
// attempt NvFBC as a last resort, or if configured via the app:capture
|
for(int i = 0; i < adapterCount; ++i)
|
||||||
// option.
|
{
|
||||||
|
D3DADAPTER_IDENTIFIER9 ident;
|
||||||
|
IDirect3D9_GetAdapterIdentifier(d3d, i, 0, &ident);
|
||||||
|
if (ident.VendorId != 0x10DE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (NvFBCToSysCreate(i, privData, privDataLen, &this->nvfbc,
|
||||||
|
&this->maxWidth, &this->maxHeight))
|
||||||
|
{
|
||||||
|
adapterIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
|
||||||
if (adapterIndex < 0)
|
if (adapterIndex < 0)
|
||||||
{
|
{
|
||||||
IDirect3D9 * d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
free(privData);
|
||||||
int adapterCount = IDirect3D9_GetAdapterCount(d3d);
|
return false;
|
||||||
for(int i = 0; i < adapterCount; ++i)
|
|
||||||
{
|
|
||||||
D3DADAPTER_IDENTIFIER9 ident;
|
|
||||||
IDirect3D9_GetAdapterIdentifier(d3d, i, 0, &ident);
|
|
||||||
if (ident.VendorId != 0x10DE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (NvFBCToSysCreate(i, privData, privDataLen, &this->nvfbc,
|
|
||||||
&this->maxWidth, &this->maxHeight))
|
|
||||||
{
|
|
||||||
adapterIndex = i;
|
|
||||||
created = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IDirect3D9_Release(d3d);
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
if (!NvFBCToSysCreate(adapterIndex, privData, privDataLen, &this->nvfbc, &this->maxWidth, &this->maxHeight))
|
||||||
{
|
{
|
||||||
if (!NvFBCToSysCreate(adapterIndex, privData, privDataLen, &this->nvfbc, &this->maxWidth, &this->maxHeight))
|
free(privData);
|
||||||
continue;
|
return false;
|
||||||
created = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (created)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//1000ms delay before retry
|
|
||||||
nsleep(1000000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!created)
|
|
||||||
{
|
|
||||||
free(privData);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int diffRes = option_get_int("nvfbc", "diffRes");
|
int diffRes = option_get_int("nvfbc", "diffRes");
|
||||||
enum DiffMapBlockSize blockSize;
|
enum DiffMapBlockSize blockSize;
|
||||||
NvFBCGetDiffMapBlockSize(diffRes, &blockSize, &this->diffShift, privData, privDataLen);
|
NvFBCGetDiffMapBlockSize(diffRes, &blockSize, &this->diffShift, privData, privDataLen);
|
||||||
|
|||||||
@@ -526,13 +526,7 @@ bool app_init(void)
|
|||||||
|
|
||||||
// redirect stderr to a file
|
// redirect stderr to a file
|
||||||
if (logFile && strcmp(logFile, "stderr") != 0)
|
if (logFile && strcmp(logFile, "stderr") != 0)
|
||||||
{
|
freopen(logFile, "a", stderr);
|
||||||
DEBUG_INFO("Logs will be written to: %s", logFile);
|
|
||||||
DEBUG_INFO("Please see there for any further information");
|
|
||||||
|
|
||||||
if (!freopen(logFile, "a", stderr))
|
|
||||||
DEBUG_WARN("Failed to open log file, will log to stderr");
|
|
||||||
}
|
|
||||||
|
|
||||||
// always flush stderr
|
// always flush stderr
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, NULL);
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ struct app
|
|||||||
unsigned int frameIndex;
|
unsigned int frameIndex;
|
||||||
bool frameValid;
|
bool frameValid;
|
||||||
uint32_t frameSerial;
|
uint32_t frameSerial;
|
||||||
|
uint64_t frameTimeUs;
|
||||||
|
|
||||||
CaptureInterface * iface;
|
CaptureInterface * iface;
|
||||||
|
|
||||||
@@ -268,6 +269,7 @@ static bool sendFrame(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fi->formatVer = frame.formatVer;
|
fi->formatVer = frame.formatVer;
|
||||||
|
fi->frameTimeUs = app.frameTimeUs;
|
||||||
fi->frameSerial = app.frameSerial++;
|
fi->frameSerial = app.frameSerial++;
|
||||||
fi->screenWidth = frame.screenWidth;
|
fi->screenWidth = frame.screenWidth;
|
||||||
fi->screenHeight = frame.screenHeight;
|
fi->screenHeight = frame.screenHeight;
|
||||||
@@ -295,6 +297,11 @@ static bool sendFrame(void)
|
|||||||
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)fi) + fi->offset);
|
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)fi) + fi->offset);
|
||||||
framebuffer_prepare(fb);
|
framebuffer_prepare(fb);
|
||||||
|
|
||||||
|
// calculate the elapsed time as late as possible, note that this does not
|
||||||
|
// take into account the memory copy time and the client's that care about
|
||||||
|
// this value will need to take this into account
|
||||||
|
fi->frameElapsedUs = microtime() - app.frameTimeUs;
|
||||||
|
|
||||||
/* we post and then get the frame, this is intentional! */
|
/* we post and then get the frame, this is intentional! */
|
||||||
if ((status = lgmpHostQueuePost(app.frameQueue, 0,
|
if ((status = lgmpHostQueuePost(app.frameQueue, 0,
|
||||||
app.frameMemory[app.frameIndex])) != LGMP_OK)
|
app.frameMemory[app.frameIndex])) != LGMP_OK)
|
||||||
@@ -748,7 +755,7 @@ int app_main(int argc, char * argv[])
|
|||||||
if (option_load(configFile))
|
if (option_load(configFile))
|
||||||
DEBUG_INFO("Configuration file loaded");
|
DEBUG_INFO("Configuration file loaded");
|
||||||
else
|
else
|
||||||
DEBUG_INFO("Configuration file not found or invalid, continuing anyway...");
|
DEBUG_INFO("Configuration file not found or invalid");
|
||||||
|
|
||||||
// parse the command line arguments
|
// parse the command line arguments
|
||||||
if (!option_parse(argc, argv))
|
if (!option_parse(argc, argv))
|
||||||
@@ -901,20 +908,20 @@ int app_main(int argc, char * argv[])
|
|||||||
LG_UNLOCK(app.pointerLock);
|
LG_UNLOCK(app.pointerLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t delta = microtime() - previousFrameTime;
|
const uint64_t now = microtime();
|
||||||
|
const uint64_t delta = now - previousFrameTime;
|
||||||
if (delta < throttleUs)
|
if (delta < throttleUs)
|
||||||
{
|
{
|
||||||
const uint64_t us = throttleUs - delta;
|
nsleep((throttleUs - delta) * 1000);
|
||||||
// only delay if the time is reasonable
|
previousFrameTime = microtime();
|
||||||
if (us > 1000)
|
|
||||||
nsleep(us * 1000);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
previousFrameTime = now;
|
||||||
|
|
||||||
const uint64_t captureStart = microtime();
|
app.frameTimeUs = microtime();
|
||||||
switch(iface->capture())
|
switch(iface->capture())
|
||||||
{
|
{
|
||||||
case CAPTURE_RESULT_OK:
|
case CAPTURE_RESULT_OK:
|
||||||
previousFrameTime = captureStart;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAPTURE_RESULT_TIMEOUT:
|
case CAPTURE_RESULT_TIMEOUT:
|
||||||
|
|||||||
2
obs/lg.c
2
obs/lg.c
@@ -421,7 +421,7 @@ static void lgUpdate(void * data, obs_data_t * settings)
|
|||||||
|
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
|
|
||||||
if (lgmpClientSessionInit(this->lgmp, &udataSize, (uint8_t **)&udata, NULL)
|
if (lgmpClientSessionInit(this->lgmp, &udataSize, (uint8_t **)&udata)
|
||||||
!= LGMP_OK)
|
!= LGMP_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user