Changeset View
Standalone View
source/blender/render/intern/engine.cc
| Show All 28 Lines | |||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_debug.h" | #include "DEG_depsgraph_debug.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "GPU_context.h" | |||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| # include "BPY_extern.h" | # include "BPY_extern.h" | ||||
| #endif | #endif | ||||
| #include "RE_bake.h" | #include "RE_bake.h" | ||||
| #include "RE_engine.h" | #include "RE_engine.h" | ||||
| ▲ Show 20 Lines • Show All 1,235 Lines • ▼ Show 20 Lines | if (engine->use_drw_render_context) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* Viewport render case where no render context is available. We are expected to be on | /* Viewport render case where no render context is available. We are expected to be on | ||||
| * the main thread here to safely create a context. */ | * the main thread here to safely create a context. */ | ||||
| BLI_assert(BLI_thread_is_main()); | BLI_assert(BLI_thread_is_main()); | ||||
| const bool drw_state = DRW_opengl_context_release(); | const bool drw_state = DRW_opengl_context_release(); | ||||
| engine->gpu_context = WM_opengl_context_create(); | engine->wm_gpu_context = WM_opengl_context_create(); | ||||
| /* On Windows an old context is restored after creation, and subsequent release of context | if (engine->wm_gpu_context) { | ||||
| * generates a Win32 error. Harmless for users, but annoying to have possible misleading | /* Activate new OpenGL Context for GPUContext creation. */ | ||||
| * error prints in the console. */ | WM_opengl_context_activate(engine->wm_gpu_context); | ||||
| #ifndef _WIN32 | /* Requires GPUContext for usage of GPU Module for displaying results. */ | ||||
| if (engine->gpu_context) { | engine->gpu_context = GPU_context_create(nullptr, engine->wm_gpu_context); | ||||
| WM_opengl_context_release(engine->gpu_context); | GPU_context_active_set(nullptr); | ||||
brecht: `DRW_opengl_context_create` seems to call `WM_opengl_context_activate` before… | |||||
Not Done Inline ActionsAh yes, this is probably a safe bet. However the pattern does seem to vary a little. comp->gl_context = WM_opengl_context_create(); comp->gpu_context = GPU_context_create(NULL); GPU_context_active_set(NULL); WM_opengl_context_activate(DST.gl_context); GPU_context_active_set(DST.gpu_context); Though ensuring this context is active prior to GPU Context creation appears to make more sense, to ensure the backing OpenGL context is active before resources are created. Should be reasonable to modify the code accordingly. MichaelPW: Ah yes, this is probably a safe bet. However the pattern does seem to vary a little.
In… | |||||
Not Done Inline ActionsFrom testing, adding a WM_opengl_context_activate(comp->gl_context) before GPU_context_creation fails on the assertion: BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());``` due to having no valid GPU context active at the time.
```void WM_opengl_context_activate(void *context)
{
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
GHOST_ActivateOpenGLContext((GHOST_ContextHandle)context);
}As DRW_opengl_context_release() called above disables the active GPU_context, which is later restored in the call to: DRW_opengl_context_activate Given the code does not immediately require usage of the newly created GPU_context, then perhaps this is not a problem as-is. However, if we did want to ensure the backing GL context was active during context creation, then we could:
Or, please let me know if there is an alternative preferred approach for this. Thanks! MichaelPW: From testing, adding a `WM_opengl_context_activate(comp->gl_context)` before… | |||||
Not Done Inline ActionsI think we can leave the code as is then for this patch. Not sure what exactly the plan is for Metal contexts, but in general this code should be refactored at some point. Removing "opengl" from the names, consistent order of creation/activation, platform consistency so we don't need #ifndef _WIN32 and better comments explaining the different types of contexts and how to use them. But that's beyond the scope of this patch. brecht: I think we can leave the code as is then for this patch.
Not sure what exactly the plan is for… | |||||
| /* Deactivate newly created OpenGL Context, as it is not needed until | |||||
| * `RE_engine_gpu_context_enable` is called. */ | |||||
| WM_opengl_context_release(engine->wm_gpu_context); | |||||
| } | |||||
| else { | |||||
| engine->gpu_context = nullptr; | |||||
| } | } | ||||
| #endif | |||||
| DRW_opengl_context_activate(drw_state); | DRW_opengl_context_activate(drw_state); | ||||
| return engine->gpu_context != nullptr; | return engine->wm_gpu_context != nullptr; | ||||
| } | } | ||||
| void RE_engine_gpu_context_destroy(RenderEngine *engine) | void RE_engine_gpu_context_destroy(RenderEngine *engine) | ||||
| { | { | ||||
| if (!engine->gpu_context) { | if (!engine->wm_gpu_context) { | ||||
| return; | return; | ||||
| } | } | ||||
| const bool drw_state = DRW_opengl_context_release(); | const bool drw_state = DRW_opengl_context_release(); | ||||
| WM_opengl_context_activate(engine->gpu_context); | WM_opengl_context_activate(engine->wm_gpu_context); | ||||
| WM_opengl_context_dispose(engine->gpu_context); | if (engine->gpu_context) { | ||||
| GPUContext *restore_context = GPU_context_active_get(); | |||||
| GPU_context_active_set(engine->gpu_context); | |||||
| GPU_context_discard(engine->gpu_context); | |||||
| if (restore_context != engine->gpu_context) { | |||||
| GPU_context_active_set(restore_context); | |||||
| } | |||||
| engine->gpu_context = nullptr; | |||||
| } | |||||
| WM_opengl_context_dispose(engine->wm_gpu_context); | |||||
| DRW_opengl_context_activate(drw_state); | DRW_opengl_context_activate(drw_state); | ||||
| } | } | ||||
| bool RE_engine_gpu_context_enable(RenderEngine *engine) | bool RE_engine_gpu_context_enable(RenderEngine *engine) | ||||
| { | { | ||||
| engine->gpu_restore_context = false; | |||||
| if (engine->use_drw_render_context) { | if (engine->use_drw_render_context) { | ||||
| DRW_render_context_enable(engine->re); | DRW_render_context_enable(engine->re); | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (engine->gpu_context) { | if (engine->wm_gpu_context) { | ||||
| BLI_mutex_lock(&engine->gpu_context_mutex); | BLI_mutex_lock(&engine->gpu_context_mutex); | ||||
| WM_opengl_context_activate(engine->gpu_context); | /* If a previous OpenGL/GPUContext was active (DST.gpu_context), we should later restore this | ||||
| * when disabling the RenderEngine context. */ | |||||
| engine->gpu_restore_context = DRW_opengl_context_release(); | |||||
| /* Activate RenderEngine OpenGL and GPU Context. */ | |||||
| WM_opengl_context_activate(engine->wm_gpu_context); | |||||
| if (engine->gpu_context) { | |||||
| GPU_context_active_set(engine->gpu_context); | |||||
| GPU_render_begin(); | |||||
| } | |||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void RE_engine_gpu_context_disable(RenderEngine *engine) | void RE_engine_gpu_context_disable(RenderEngine *engine) | ||||
| { | { | ||||
| if (engine->use_drw_render_context) { | if (engine->use_drw_render_context) { | ||||
| DRW_render_context_disable(engine->re); | DRW_render_context_disable(engine->re); | ||||
| } | } | ||||
| else { | else { | ||||
| if (engine->wm_gpu_context) { | |||||
| if (engine->gpu_context) { | if (engine->gpu_context) { | ||||
| WM_opengl_context_release(engine->gpu_context); | GPU_render_end(); | ||||
| GPU_context_active_set(nullptr); | |||||
| } | |||||
| WM_opengl_context_release(engine->wm_gpu_context); | |||||
| /* Restore DRW state context if previously active. */ | |||||
| DRW_opengl_context_activate(engine->gpu_restore_context); | |||||
| BLI_mutex_unlock(&engine->gpu_context_mutex); | BLI_mutex_unlock(&engine->gpu_context_mutex); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void RE_engine_gpu_context_lock(RenderEngine *engine) | void RE_engine_gpu_context_lock(RenderEngine *engine) | ||||
| { | { | ||||
| if (engine->use_drw_render_context) { | if (engine->use_drw_render_context) { | ||||
| /* Locking already handled by the draw manager. */ | /* Locking already handled by the draw manager. */ | ||||
| } | } | ||||
| else { | else { | ||||
| if (engine->gpu_context) { | if (engine->wm_gpu_context) { | ||||
| BLI_mutex_lock(&engine->gpu_context_mutex); | BLI_mutex_lock(&engine->gpu_context_mutex); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void RE_engine_gpu_context_unlock(RenderEngine *engine) | void RE_engine_gpu_context_unlock(RenderEngine *engine) | ||||
| { | { | ||||
| if (engine->use_drw_render_context) { | if (engine->use_drw_render_context) { | ||||
| /* Locking already handled by the draw manager. */ | /* Locking already handled by the draw manager. */ | ||||
| } | } | ||||
| else { | else { | ||||
| if (engine->gpu_context) { | if (engine->wm_gpu_context) { | ||||
| BLI_mutex_unlock(&engine->gpu_context_mutex); | BLI_mutex_unlock(&engine->gpu_context_mutex); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
DRW_opengl_context_create seems to call WM_opengl_context_activate before GPU_context_create. Is it needed here also?