libobs: Support device loss registration
Complex external systems using the D3D11 device may need to perform their own device loss handling, the upcoming Windows Graphics Capture support for example.
This commit is contained in:
parent
82797eb367
commit
f27f858ab3
@ -348,6 +348,9 @@ try {
|
|||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
|
for (gs_device_loss &callback : loss_callbacks)
|
||||||
|
callback.device_loss_release(callback.data);
|
||||||
|
|
||||||
gs_obj *obj = first_obj;
|
gs_obj *obj = first_obj;
|
||||||
|
|
||||||
while (obj) {
|
while (obj) {
|
||||||
@ -404,6 +407,7 @@ try {
|
|||||||
state.Release();
|
state.Release();
|
||||||
|
|
||||||
context->ClearState();
|
context->ClearState();
|
||||||
|
context->Flush();
|
||||||
|
|
||||||
context.Release();
|
context.Release();
|
||||||
device.Release();
|
device.Release();
|
||||||
@ -506,6 +510,9 @@ try {
|
|||||||
for (auto &state : blendStates)
|
for (auto &state : blendStates)
|
||||||
state.Rebuild(dev);
|
state.Rebuild(dev);
|
||||||
|
|
||||||
|
for (gs_device_loss &callback : loss_callbacks)
|
||||||
|
callback.device_loss_rebuild(device.Get(), callback.data);
|
||||||
|
|
||||||
} catch (const char *error) {
|
} catch (const char *error) {
|
||||||
bcrash("Failed to recreate D3D11: %s", error);
|
bcrash("Failed to recreate D3D11: %s", error);
|
||||||
|
|
||||||
|
@ -2798,3 +2798,22 @@ device_stagesurface_create_nv12(gs_device_t *device, uint32_t width,
|
|||||||
|
|
||||||
return surf;
|
return surf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" EXPORT void
|
||||||
|
device_register_loss_callbacks(gs_device_t *device,
|
||||||
|
const gs_device_loss *callbacks)
|
||||||
|
{
|
||||||
|
device->loss_callbacks.emplace_back(*callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" EXPORT void device_unregister_loss_callbacks(gs_device_t *device,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
for (auto iter = device->loss_callbacks.begin();
|
||||||
|
iter != device->loss_callbacks.end(); ++iter) {
|
||||||
|
if (iter->data == data) {
|
||||||
|
device->loss_callbacks.erase(iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -946,6 +946,7 @@ struct gs_device {
|
|||||||
matrix4 curViewMatrix;
|
matrix4 curViewMatrix;
|
||||||
matrix4 curViewProjMatrix;
|
matrix4 curViewProjMatrix;
|
||||||
|
|
||||||
|
vector<gs_device_loss> loss_callbacks;
|
||||||
gs_obj *first_obj = nullptr;
|
gs_obj *first_obj = nullptr;
|
||||||
|
|
||||||
void InitCompiler();
|
void InitCompiler();
|
||||||
|
@ -214,6 +214,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
|
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
|
||||||
|
GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
|
||||||
|
GRAPHICS_IMPORT_OPTIONAL(device_unregister_loss_callbacks);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -311,6 +311,10 @@ struct gs_exports {
|
|||||||
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
|
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height);
|
uint32_t height);
|
||||||
|
void (*device_register_loss_callbacks)(
|
||||||
|
gs_device_t *device, const struct gs_device_loss *callbacks);
|
||||||
|
void (*device_unregister_loss_callbacks)(gs_device_t *device,
|
||||||
|
void *data);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2959,4 +2959,28 @@ gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_register_loss_callbacks(const struct gs_device_loss *callbacks)
|
||||||
|
{
|
||||||
|
graphics_t *graphics = thread_graphics;
|
||||||
|
|
||||||
|
if (!gs_valid("gs_register_loss_callbacks"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (graphics->exports.device_register_loss_callbacks)
|
||||||
|
graphics->exports.device_register_loss_callbacks(
|
||||||
|
graphics->device, callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gs_unregister_loss_callbacks(void *data)
|
||||||
|
{
|
||||||
|
graphics_t *graphics = thread_graphics;
|
||||||
|
|
||||||
|
if (!gs_valid("gs_unregister_loss_callbacks"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (graphics->exports.device_unregister_loss_callbacks)
|
||||||
|
graphics->exports.device_unregister_loss_callbacks(
|
||||||
|
graphics->device, data);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -169,6 +169,12 @@ enum gs_texture_type {
|
|||||||
GS_TEXTURE_CUBE,
|
GS_TEXTURE_CUBE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gs_device_loss {
|
||||||
|
void (*device_loss_release)(void *data);
|
||||||
|
void (*device_loss_rebuild)(void *device, void *data);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
struct gs_monitor_info {
|
struct gs_monitor_info {
|
||||||
int rotation_degrees;
|
int rotation_degrees;
|
||||||
long x;
|
long x;
|
||||||
@ -883,6 +889,9 @@ EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
|||||||
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width,
|
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width,
|
||||||
uint32_t height);
|
uint32_t height);
|
||||||
|
|
||||||
|
EXPORT void gs_register_loss_callbacks(const struct gs_device_loss *callbacks);
|
||||||
|
EXPORT void gs_unregister_loss_callbacks(void *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* inline functions used by modules */
|
/* inline functions used by modules */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user