More detailed vdisplay driver state
This commit is contained in:
@@ -547,7 +547,7 @@ namespace confighttp {
|
||||
outputTree.put("platform", SUNSHINE_PLATFORM);
|
||||
outputTree.put("version", PROJECT_VER);
|
||||
#ifdef _WIN32
|
||||
outputTree.put("vdisplayStatus", proc::vdisplayDriverInitialized ? "true" : "false");
|
||||
outputTree.put("vdisplayStatus", (int)proc::vDisplayDriverStatus);
|
||||
#endif
|
||||
|
||||
auto vars = config::parse_config(file_handler::read_file(config::sunshine.config_file.c_str()));
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
#include "uuid.h"
|
||||
#include "video.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "platform/windows/virtual_display.h"
|
||||
#endif
|
||||
|
||||
using namespace std::literals;
|
||||
namespace nvhttp {
|
||||
|
||||
@@ -708,7 +712,7 @@ namespace nvhttp {
|
||||
|
||||
#ifdef _WIN32
|
||||
tree.put("root.VirtualDisplayCapable", true);
|
||||
tree.put("root.VirtualDisplayDriverReady", proc::vdisplayDriverInitialized);
|
||||
tree.put("root.VirtualDisplayDriverReady", proc::vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK);
|
||||
#endif
|
||||
|
||||
// Only include the MAC address for requests sent from paired clients over HTTPS.
|
||||
|
||||
@@ -102,7 +102,32 @@ bool setPrimaryDisplay(const wchar_t* primaryDeviceName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool startPingThread() {
|
||||
void closeVDisplayDevice() {
|
||||
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(SUDOVDA_DRIVER_HANDLE);
|
||||
|
||||
SUDOVDA_DRIVER_HANDLE = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
DRIVER_STATUS openVDisplayDevice() {
|
||||
SUDOVDA_DRIVER_HANDLE = OpenDevice(&SUVDA_INTERFACE_GUID);
|
||||
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
|
||||
return DRIVER_STATUS::FAILED;
|
||||
}
|
||||
|
||||
if (!CheckProtocolCompatible(SUDOVDA_DRIVER_HANDLE)) {
|
||||
printf("[SUDOVDA] SUDOVDA protocol not compatible with driver!\n");
|
||||
closeVDisplayDevice();
|
||||
return DRIVER_STATUS::VERSION_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
return DRIVER_STATUS::OK;
|
||||
}
|
||||
|
||||
bool startPingThread(std::function<void()> failCb) {
|
||||
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
@@ -117,10 +142,17 @@ bool startPingThread() {
|
||||
|
||||
if (watchdogOut.Timeout) {
|
||||
auto sleepInterval = watchdogOut.Timeout * 1000 / 2;
|
||||
std::thread ping_thread([sleepInterval]{
|
||||
std::thread ping_thread([sleepInterval, failCb = std::move(failCb)]{
|
||||
uint8_t fail_count = 0;
|
||||
for (;;) {
|
||||
if (!sleepInterval) return;
|
||||
if (!PingDriver(SUDOVDA_DRIVER_HANDLE)) return;
|
||||
if (!PingDriver(SUDOVDA_DRIVER_HANDLE)) {
|
||||
fail_count += 1;
|
||||
if (fail_count > 3) {
|
||||
failCb();
|
||||
return;
|
||||
}
|
||||
};
|
||||
Sleep(sleepInterval);
|
||||
}
|
||||
});
|
||||
@@ -131,22 +163,6 @@ bool startPingThread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool openVDisplayDevice() {
|
||||
SUDOVDA_DRIVER_HANDLE = OpenDevice(&SUVDA_INTERFACE_GUID);
|
||||
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CheckProtocolCompatible(SUDOVDA_DRIVER_HANDLE)) {
|
||||
printf("[SUDOVDA] SUDOVDA protocol not compatible with driver!\n");
|
||||
CloseHandle(SUDOVDA_DRIVER_HANDLE);
|
||||
SUDOVDA_DRIVER_HANDLE = INVALID_HANDLE_VALUE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return startPingThread();
|
||||
}
|
||||
|
||||
std::wstring createVirtualDisplay(
|
||||
const char* s_client_uid,
|
||||
const char* s_client_name,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#ifndef FILE_DEVICE_UNKNOWN
|
||||
#define FILE_DEVICE_UNKNOWN 0x00000022
|
||||
#endif
|
||||
@@ -9,6 +11,14 @@
|
||||
#include <sudovda/sudovda.h>
|
||||
|
||||
namespace VDISPLAY {
|
||||
enum class DRIVER_STATUS {
|
||||
UNKNOWN = 1,
|
||||
OK = 0,
|
||||
FAILED = -1,
|
||||
VERSION_INCOMPATIBLE = -2,
|
||||
WATCHDOG_FAILED = -3
|
||||
};
|
||||
|
||||
extern HANDLE SUDOVDA_DRIVER_HANDLE;
|
||||
|
||||
LONG getDeviceSettings(const wchar_t* deviceName, DEVMODEW& devMode);
|
||||
@@ -16,8 +26,9 @@ namespace VDISPLAY {
|
||||
std::wstring getPrimaryDisplay();
|
||||
bool setPrimaryDisplay(const wchar_t* primaryDeviceName);
|
||||
|
||||
bool startPingThread();
|
||||
bool openVDisplayDevice();
|
||||
void closeVDisplayDevice();
|
||||
DRIVER_STATUS openVDisplayDevice();
|
||||
bool startPingThread(std::function<void()> failCb);
|
||||
std::wstring createVirtualDisplay(
|
||||
const char* s_client_uid,
|
||||
const char* s_client_name,
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#ifdef _WIN32
|
||||
// from_utf8() string conversion function
|
||||
#include "platform/windows/misc.h"
|
||||
#include "platform/windows/virtual_display.h"
|
||||
|
||||
// _SH constants for _wfsopen()
|
||||
#include <share.h>
|
||||
@@ -47,7 +46,21 @@ namespace proc {
|
||||
proc_t proc;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool vdisplayDriverInitialized = false;
|
||||
VDISPLAY::DRIVER_STATUS vDisplayDriverStatus = VDISPLAY::DRIVER_STATUS::UNKNOWN;
|
||||
|
||||
void onVDisplayWatchdogFailed() {
|
||||
vDisplayDriverStatus = VDISPLAY::DRIVER_STATUS::WATCHDOG_FAILED;
|
||||
VDISPLAY::closeVDisplayDevice();
|
||||
}
|
||||
|
||||
void initVDisplayDriver() {
|
||||
vDisplayDriverStatus = VDISPLAY::openVDisplayDevice();
|
||||
if (vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK) {
|
||||
if (!VDISPLAY::startPingThread(onVDisplayWatchdogFailed)) {
|
||||
onVDisplayWatchdogFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
class deinit_t: public platf::deinit_t {
|
||||
@@ -225,15 +238,15 @@ namespace proc {
|
||||
|
||||
#ifdef _WIN32
|
||||
if (launch_session->virtual_display || _app.virtual_display) {
|
||||
if (!vdisplayDriverInitialized) {
|
||||
if (vDisplayDriverStatus != VDISPLAY::DRIVER_STATUS::OK) {
|
||||
// Try init driver again
|
||||
vdisplayDriverInitialized = VDISPLAY::openVDisplayDevice();
|
||||
initVDisplayDriver();
|
||||
}
|
||||
|
||||
if (vdisplayDriverInitialized) {
|
||||
if (vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK) {
|
||||
std::wstring prevPrimaryDisplayName = VDISPLAY::getPrimaryDisplay();
|
||||
|
||||
launch_session->display_guid = *(GUID*)(void*)&http::uuid;
|
||||
memcpy(&launch_session->display_guid, &http::uuid, sizeof(GUID));
|
||||
|
||||
std::wstring vdisplayName = VDISPLAY::createVirtualDisplay(
|
||||
launch_session->unique_id.c_str(),
|
||||
@@ -410,7 +423,7 @@ namespace proc {
|
||||
_pipe.reset();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (vdisplayDriverInitialized && _launch_session && this->virtual_display) {
|
||||
if (vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK && _launch_session && this->virtual_display) {
|
||||
VDISPLAY::removeVirtualDisplay(_launch_session->display_guid);
|
||||
}
|
||||
#endif
|
||||
@@ -677,7 +690,7 @@ namespace proc {
|
||||
std::vector<proc::ctx_t> apps;
|
||||
int i = 0;
|
||||
|
||||
if (vdisplayDriverInitialized) {
|
||||
if (vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK) {
|
||||
proc::ctx_t ctx;
|
||||
ctx.name = "Virtual Display";
|
||||
ctx.image_path = parse_env_val(this_env, "virtual_desktop.png");
|
||||
@@ -822,8 +835,8 @@ namespace proc {
|
||||
void
|
||||
refresh(const std::string &file_name) {
|
||||
#ifdef _WIN32
|
||||
if (!vdisplayDriverInitialized) {
|
||||
vdisplayDriverInitialized = VDISPLAY::openVDisplayDevice();
|
||||
if (vDisplayDriverStatus != VDISPLAY::DRIVER_STATUS::OK) {
|
||||
initVDisplayDriver();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -18,11 +18,15 @@
|
||||
#include "rtsp.h"
|
||||
#include "utility.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "platform/windows/virtual_display.h"
|
||||
#endif
|
||||
|
||||
namespace proc {
|
||||
using file_t = util::safe_ptr_v2<FILE, int, fclose>;
|
||||
|
||||
#ifdef _WIN32
|
||||
extern bool vdisplayDriverInitialized;
|
||||
extern VDISPLAY::DRIVER_STATUS vDisplayDriverStatus;
|
||||
#endif
|
||||
|
||||
typedef config::prep_cmd_t cmd_t;
|
||||
|
||||
Reference in New Issue
Block a user