Skip to content
Snippets Groups Projects
Commit 05c56603 authored by Jason Fielder's avatar Jason Fielder Committed by Jeroen Bakker
Browse files

Fix #114192: Resolve animation player greying out on resize in Metal

Standalone animation player has inconsistent GPU context activation
paradigm compared with standard rendering paths. The Metal backend
utilises the context activation step to refresh target window swapchains
from within the GHOST module.

This PR adds activation and deactivation calls, and also aims to clean up
GPU_render_begin/end setup to ensure all paths are covered.

Also resolves a bug upon shutdown wherein GPU resources which may
be tied to a GPU context are released during IMB_exit(), which is called
after GPU context destruction.

Authored by Apple: Michael Parkin-White

Pull Request: https://projects.blender.org/blender/blender/pulls/114573
parent 93278b55
No related branches found
No related tags found
No related merge requests found
...@@ -624,7 +624,7 @@ static void draw_display_buffer(const PlayDisplayContext *display_ctx, ...@@ -624,7 +624,7 @@ static void draw_display_buffer(const PlayDisplayContext *display_ctx,
* \param draw_flip: X/Y flipping (ignored when null). * \param draw_flip: X/Y flipping (ignored when null).
* \param indicator_factor: Display a vertical indicator (ignored when -1). * \param indicator_factor: Display a vertical indicator (ignored when -1).
*/ */
static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window, static void playanim_toscreen_ex(GhostData *data,
const PlayDisplayContext *display_ctx, const PlayDisplayContext *display_ctx,
const PlayAnimPict *picture, const PlayAnimPict *picture,
ImBuf *ibuf, ImBuf *ibuf,
...@@ -635,9 +635,11 @@ static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window, ...@@ -635,9 +635,11 @@ static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window,
const bool draw_flip[2], const bool draw_flip[2],
const float indicator_factor) const float indicator_factor)
{ {
GHOST_ActivateWindowDrawingContext(ghost_window); GHOST_ActivateWindowDrawingContext(data->window);
GPU_render_begin(); GPU_render_begin();
GPU_render_step();
GPUContext *restore_context = GPU_context_active_get();
GPU_context_active_set(data->gpu_context);
GPU_clear_color(0.1f, 0.1f, 0.1f, 0.0f); GPU_clear_color(0.1f, 0.1f, 0.1f, 0.0f);
...@@ -689,7 +691,7 @@ static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window, ...@@ -689,7 +691,7 @@ static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window,
SNPRINTF(label, "%s | <failed to load buffer>", picture->filepath); SNPRINTF(label, "%s | <failed to load buffer>", picture->filepath);
} }
playanim_window_get_size(ghost_window, &sizex, &sizey); playanim_window_get_size(data->window, &sizex, &sizey);
fsizex_inv = 1.0f / sizex; fsizex_inv = 1.0f / sizex;
fsizey_inv = 1.0f / sizey; fsizey_inv = 1.0f / sizey;
...@@ -737,11 +739,17 @@ static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window, ...@@ -737,11 +739,17 @@ static void playanim_toscreen_ex(GHOST_WindowHandle ghost_window,
GPU_matrix_pop_projection(); GPU_matrix_pop_projection();
} }
GHOST_SwapWindowBuffers(ghost_window); GPU_render_step();
if (GPU_backend_get_type() == GPU_BACKEND_METAL) {
GPU_flush();
}
GHOST_SwapWindowBuffers(data->window);
GPU_context_active_set(restore_context);
GPU_render_end(); GPU_render_end();
} }
static void playanim_toscreen_on_load(GHOST_WindowHandle ghost_window, static void playanim_toscreen_on_load(GhostData *ghost_data,
const PlayDisplayContext *display_ctx, const PlayDisplayContext *display_ctx,
const PlayAnimPict *picture, const PlayAnimPict *picture,
ImBuf *ibuf) ImBuf *ibuf)
...@@ -753,7 +761,7 @@ static void playanim_toscreen_on_load(GHOST_WindowHandle ghost_window, ...@@ -753,7 +761,7 @@ static void playanim_toscreen_on_load(GHOST_WindowHandle ghost_window,
const bool *draw_flip = nullptr; const bool *draw_flip = nullptr;
playanim_toscreen_ex( playanim_toscreen_ex(
ghost_window, display_ctx, picture, ibuf, font_id, fstep, zoom, draw_flip, indicator_factor); ghost_data, display_ctx, picture, ibuf, font_id, fstep, zoom, draw_flip, indicator_factor);
} }
static void playanim_toscreen(PlayState *ps, const PlayAnimPict *picture, ImBuf *ibuf) static void playanim_toscreen(PlayState *ps, const PlayAnimPict *picture, ImBuf *ibuf)
...@@ -779,7 +787,7 @@ static void playanim_toscreen(PlayState *ps, const PlayAnimPict *picture, ImBuf ...@@ -779,7 +787,7 @@ static void playanim_toscreen(PlayState *ps, const PlayAnimPict *picture, ImBuf
} }
BLI_assert(ps->loading == false); BLI_assert(ps->loading == false);
playanim_toscreen_ex(ps->ghost_data.window, playanim_toscreen_ex(&ps->ghost_data,
&ps->display_ctx, &ps->display_ctx,
picture, picture,
ibuf, ibuf,
...@@ -804,7 +812,7 @@ static void build_pict_list_from_anim(GhostData *ghost_data, ...@@ -804,7 +812,7 @@ static void build_pict_list_from_anim(GhostData *ghost_data,
ImBuf *ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); ImBuf *ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
if (ibuf) { if (ibuf) {
playanim_toscreen_on_load(ghost_data->window, display_ctx, nullptr, ibuf); playanim_toscreen_on_load(ghost_data, display_ctx, nullptr, ibuf);
IMB_freeImBuf(ibuf); IMB_freeImBuf(ibuf);
} }
...@@ -888,7 +896,7 @@ static void build_pict_list_from_image_sequence(GhostData *ghost_data, ...@@ -888,7 +896,7 @@ static void build_pict_list_from_image_sequence(GhostData *ghost_data,
if (ibuf) { if (ibuf) {
if (display_imbuf) { if (display_imbuf) {
playanim_toscreen_on_load(ghost_data->window, display_ctx, picture, ibuf); playanim_toscreen_on_load(ghost_data, display_ctx, picture, ibuf);
} }
#ifdef USE_FRAME_CACHE_LIMIT #ifdef USE_FRAME_CACHE_LIMIT
if (fill_cache) { if (fill_cache) {
...@@ -1951,9 +1959,15 @@ static char *wm_main_playanim_intern(int argc, const char **argv) ...@@ -1951,9 +1959,15 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
ps.next_frame = ps.direction; ps.next_frame = ps.direction;
GPU_render_begin();
GPUContext *restore_context = GPU_context_active_get();
GPU_context_active_set(ps.ghost_data.gpu_context);
while ((has_event = GHOST_ProcessEvents(ps.ghost_data.system, false))) { while ((has_event = GHOST_ProcessEvents(ps.ghost_data.system, false))) {
GHOST_DispatchEvents(ps.ghost_data.system); GHOST_DispatchEvents(ps.ghost_data.system);
} }
GPU_render_end();
GPU_context_active_set(restore_context);
if (ps.go == false) { if (ps.go == false) {
break; break;
} }
...@@ -2055,6 +2069,10 @@ static char *wm_main_playanim_intern(int argc, const char **argv) ...@@ -2055,6 +2069,10 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
BLF_exit(); BLF_exit();
/* NOTE: Must happen before GPU Context destruction as GPU resources are released via
* Colour Management module. */
IMB_exit();
if (ps.ghost_data.gpu_context) { if (ps.ghost_data.gpu_context) {
GPU_context_active_set(ps.ghost_data.gpu_context); GPU_context_active_set(ps.ghost_data.gpu_context);
GPU_exit(); GPU_exit();
...@@ -2074,8 +2092,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv) ...@@ -2074,8 +2092,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
GHOST_DisposeSystem(ps.ghost_data.system); GHOST_DisposeSystem(ps.ghost_data.system);
IMB_exit();
totblock = MEM_get_memory_blocks_in_use(); totblock = MEM_get_memory_blocks_in_use();
if (totblock != 0) { if (totblock != 0) {
/* prints many bAKey, bArgument's which are tricky to fix */ /* prints many bAKey, bArgument's which are tricky to fix */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment