win-capture: Cache data to reduce load time
Caches the D3D graphics offsets to file for the sake of improving module load time. If the D3D/DXGI DLL versions change, the data will be refreshed.
This commit is contained in:
parent
b038ed8d1d
commit
f29ac7770c
@ -1,11 +1,13 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <obs-module.h>
|
||||
#include <util/windows/win-version.h>
|
||||
#include <util/platform.h>
|
||||
#include <util/dstr.h>
|
||||
#include <util/config-file.h>
|
||||
#include <util/pipe.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "graphics-hook-info.h"
|
||||
|
||||
extern struct graphics_offsets offsets32;
|
||||
@ -45,10 +47,115 @@ static inline bool load_offsets_from_string(struct graphics_offsets *offsets,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool load_offsets_from_file(struct graphics_offsets *offsets,
|
||||
const char *file)
|
||||
{
|
||||
char *str = os_quick_read_utf8_file(file);
|
||||
bool success = false;
|
||||
if (str && *str)
|
||||
success = load_offsets_from_string(offsets, str);
|
||||
bfree(str);
|
||||
return success;
|
||||
}
|
||||
|
||||
static inline bool config_ver_mismatch(
|
||||
config_t *ver_config,
|
||||
const char *section,
|
||||
struct win_version_info *ver)
|
||||
{
|
||||
struct win_version_info config_ver;
|
||||
bool mismatch = false;
|
||||
|
||||
#define get_sub_ver(subver) \
|
||||
config_ver.subver = (int)config_get_int(ver_config, section, #subver); \
|
||||
mismatch |= config_ver.subver != ver->subver;
|
||||
|
||||
get_sub_ver(major);
|
||||
get_sub_ver(minor);
|
||||
get_sub_ver(build);
|
||||
get_sub_ver(revis);
|
||||
|
||||
#undef get_sub_ver
|
||||
|
||||
return mismatch;
|
||||
}
|
||||
|
||||
static inline void write_config_ver(config_t *ver_config, const char *section,
|
||||
struct win_version_info *ver)
|
||||
{
|
||||
#define set_sub_ver(subver) \
|
||||
config_set_int(ver_config, section, #subver, ver->subver);
|
||||
|
||||
set_sub_ver(major);
|
||||
set_sub_ver(minor);
|
||||
set_sub_ver(build);
|
||||
set_sub_ver(revis);
|
||||
|
||||
#undef set_sub_ver
|
||||
}
|
||||
|
||||
static bool get_32bit_system_dll_ver(const wchar_t *system_lib,
|
||||
struct win_version_info *ver)
|
||||
{
|
||||
wchar_t path[MAX_PATH];
|
||||
|
||||
HRESULT hr = SHGetFolderPathW(NULL, CSIDL_SYSTEMX86, NULL,
|
||||
SHGFP_TYPE_CURRENT, path);
|
||||
if (hr != S_OK) {
|
||||
blog(LOG_ERROR, "Failed to get windows 32bit system path: "
|
||||
"%08lX", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
wcscat(path, L"\\");
|
||||
wcscat(path, system_lib);
|
||||
return get_dll_ver(path, ver);
|
||||
}
|
||||
|
||||
bool cached_versions_match(void)
|
||||
{
|
||||
struct win_version_info d3d8_ver = {0};
|
||||
struct win_version_info d3d9_ver = {0};
|
||||
struct win_version_info dxgi_ver = {0};
|
||||
bool ver_mismatch = false;
|
||||
config_t *config;
|
||||
char *ver_file;
|
||||
int ret;
|
||||
|
||||
ver_mismatch |= !get_32bit_system_dll_ver(L"d3d8.dll", &d3d8_ver);
|
||||
ver_mismatch |= !get_32bit_system_dll_ver(L"d3d9.dll", &d3d9_ver);
|
||||
ver_mismatch |= !get_32bit_system_dll_ver(L"dxgi.dll", &dxgi_ver);
|
||||
|
||||
ver_file = obs_module_config_path("version.ini");
|
||||
if (!ver_file)
|
||||
return false;
|
||||
|
||||
ret = config_open(&config, ver_file, CONFIG_OPEN_ALWAYS);
|
||||
if (ret != CONFIG_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
ver_mismatch |= config_ver_mismatch(config, "d3d8", &d3d8_ver);
|
||||
ver_mismatch |= config_ver_mismatch(config, "d3d9", &d3d9_ver);
|
||||
ver_mismatch |= config_ver_mismatch(config, "dxgi", &dxgi_ver);
|
||||
|
||||
if (ver_mismatch) {
|
||||
write_config_ver(config, "d3d8", &d3d8_ver);
|
||||
write_config_ver(config, "d3d9", &d3d9_ver);
|
||||
write_config_ver(config, "dxgi", &dxgi_ver);
|
||||
config_save_safe(config, "tmp", NULL);
|
||||
}
|
||||
|
||||
failed:
|
||||
bfree(ver_file);
|
||||
config_close(config);
|
||||
return !ver_mismatch;
|
||||
}
|
||||
|
||||
bool load_graphics_offsets(bool is32bit)
|
||||
{
|
||||
char *offset_exe_path = NULL;
|
||||
struct dstr offset_exe = {0};
|
||||
char *config_ini = NULL;
|
||||
struct dstr str = {0};
|
||||
os_process_pipe_t *pp;
|
||||
bool success = false;
|
||||
@ -73,6 +180,11 @@ bool load_graphics_offsets(bool is32bit)
|
||||
dstr_ncat(&str, data, len);
|
||||
}
|
||||
|
||||
config_ini = obs_module_config_path(is32bit ? "32.ini" : "64.ini");
|
||||
os_quick_write_utf8_file_safe(config_ini, str.array, str.len, false,
|
||||
"tmp", NULL);
|
||||
bfree(config_ini);
|
||||
|
||||
success = load_offsets_from_string(is32bit ? &offsets32 : &offsets64,
|
||||
str.array);
|
||||
if (!success) {
|
||||
@ -87,3 +199,18 @@ error:
|
||||
dstr_free(&str);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool load_cached_graphics_offsets(bool is32bit)
|
||||
{
|
||||
char *config_ini = NULL;
|
||||
bool success;
|
||||
|
||||
config_ini = obs_module_config_path(is32bit ? "32.ini" : "64.ini");
|
||||
success = load_offsets_from_file(is32bit ? &offsets32 : &offsets64,
|
||||
config_ini);
|
||||
if (!success)
|
||||
success = load_graphics_offsets(is32bit);
|
||||
|
||||
bfree(config_ini);
|
||||
return success;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <windows.h>
|
||||
#include <obs-module.h>
|
||||
#include <util/windows/win-version.h>
|
||||
#include <util/platform.h>
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
OBS_MODULE_USE_DEFAULT_LOCALE("win-capture", "en-US")
|
||||
@ -10,6 +11,8 @@ extern struct obs_source_info monitor_capture_info;
|
||||
extern struct obs_source_info window_capture_info;
|
||||
extern struct obs_source_info game_capture_info;
|
||||
|
||||
extern bool cached_versions_match(void);
|
||||
extern bool load_cached_graphics_offsets(bool is32bit);
|
||||
extern bool load_graphics_offsets(bool is32bit);
|
||||
|
||||
/* temporary, will eventually be erased once we figure out how to create both
|
||||
@ -24,6 +27,13 @@ bool obs_module_load(void)
|
||||
{
|
||||
struct win_version_info ver;
|
||||
bool win8_or_above = false;
|
||||
char *config_dir;
|
||||
|
||||
config_dir = obs_module_config_path(NULL);
|
||||
if (config_dir) {
|
||||
os_mkdirs(config_dir);
|
||||
bfree(config_dir);
|
||||
}
|
||||
|
||||
get_win_ver(&ver);
|
||||
|
||||
@ -40,7 +50,11 @@ bool obs_module_load(void)
|
||||
|
||||
obs_register_source(&window_capture_info);
|
||||
|
||||
if (load_graphics_offsets(IS32BIT)) {
|
||||
if (cached_versions_match() && load_cached_graphics_offsets(IS32BIT)) {
|
||||
load_cached_graphics_offsets(!IS32BIT);
|
||||
obs_register_source(&game_capture_info);
|
||||
|
||||
} else if (load_graphics_offsets(IS32BIT)) {
|
||||
load_graphics_offsets(!IS32BIT);
|
||||
obs_register_source(&game_capture_info);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user