Whenever an exception happens in VR session code, we cancel the entire
session. Alongside that, we removed the "surface" item used to draw into
an offscreen context. This would mess up the iterator of the surface
draw loop.
Similar to 7afd84df40.
141 lines
3.2 KiB
C
141 lines
3.2 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/** \file
|
|
* \ingroup wm
|
|
*/
|
|
|
|
#include "BKE_context.h"
|
|
|
|
#include "BLF_api.h"
|
|
|
|
#include "BLI_listbase.h"
|
|
#include "BLI_threads.h"
|
|
|
|
#include "GHOST_C-api.h"
|
|
|
|
#include "GPU_batch_presets.h"
|
|
#include "GPU_context.h"
|
|
#include "GPU_framebuffer.h"
|
|
#include "GPU_immediate.h"
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "WM_api.h"
|
|
#include "WM_types.h"
|
|
#include "wm.h"
|
|
|
|
#include "wm_surface.h"
|
|
|
|
static ListBase global_surface_list = {NULL, NULL};
|
|
static wmSurface *g_drawable = NULL;
|
|
|
|
void wm_surfaces_iter(bContext *C, void (*cb)(bContext *C, wmSurface *))
|
|
{
|
|
/* Mutable iterator in case a surface is freed. */
|
|
LISTBASE_FOREACH_MUTABLE (wmSurface *, surf, &global_surface_list) {
|
|
cb(C, surf);
|
|
}
|
|
}
|
|
|
|
static void wm_surface_do_depsgraph_fn(bContext *C, wmSurface *surface)
|
|
{
|
|
if (surface->do_depsgraph) {
|
|
surface->do_depsgraph(C);
|
|
}
|
|
}
|
|
|
|
void wm_surfaces_do_depsgraph(bContext *C)
|
|
{
|
|
wm_surfaces_iter(C, wm_surface_do_depsgraph_fn);
|
|
}
|
|
|
|
void wm_surface_clear_drawable(void)
|
|
{
|
|
if (g_drawable) {
|
|
WM_opengl_context_release(g_drawable->ghost_ctx);
|
|
GPU_context_active_set(NULL);
|
|
|
|
if (g_drawable->deactivate) {
|
|
g_drawable->deactivate();
|
|
}
|
|
|
|
g_drawable = NULL;
|
|
}
|
|
}
|
|
|
|
void wm_surface_set_drawable(wmSurface *surface, bool activate)
|
|
{
|
|
BLI_assert(ELEM(g_drawable, NULL, surface));
|
|
|
|
g_drawable = surface;
|
|
if (activate) {
|
|
if (surface->activate) {
|
|
surface->activate();
|
|
}
|
|
WM_opengl_context_activate(surface->ghost_ctx);
|
|
}
|
|
|
|
GPU_context_active_set(surface->gpu_ctx);
|
|
}
|
|
|
|
void wm_surface_make_drawable(wmSurface *surface)
|
|
{
|
|
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
|
|
|
|
if (surface != g_drawable) {
|
|
wm_surface_clear_drawable();
|
|
wm_surface_set_drawable(surface, true);
|
|
}
|
|
}
|
|
|
|
void wm_surface_reset_drawable(void)
|
|
{
|
|
BLI_assert(BLI_thread_is_main());
|
|
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
|
|
|
|
if (g_drawable) {
|
|
wm_surface_clear_drawable();
|
|
wm_surface_set_drawable(g_drawable, true);
|
|
}
|
|
}
|
|
|
|
void wm_surface_add(wmSurface *surface)
|
|
{
|
|
BLI_addtail(&global_surface_list, surface);
|
|
}
|
|
|
|
void wm_surface_remove(wmSurface *surface)
|
|
{
|
|
if (surface == g_drawable) {
|
|
wm_surface_clear_drawable();
|
|
}
|
|
BLI_remlink(&global_surface_list, surface);
|
|
surface->free_data(surface);
|
|
MEM_freeN(surface);
|
|
}
|
|
|
|
void wm_surfaces_free(void)
|
|
{
|
|
wm_surface_clear_drawable();
|
|
|
|
LISTBASE_FOREACH_MUTABLE (wmSurface *, surf, &global_surface_list) {
|
|
wm_surface_remove(surf);
|
|
}
|
|
|
|
BLI_assert(BLI_listbase_is_empty(&global_surface_list));
|
|
}
|