Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_manager.c
| Show All 24 Lines | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_mempool.h" | #include "BLI_mempool.h" | ||||
| #include "BLI_rect.h" | #include "BLI_rect.h" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_string_utils.h" | #include "BLI_string_utils.h" | ||||
| #include "BLI_threads.h" | |||||
| #include "BIF_glutil.h" | #include "BIF_glutil.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_pbvh.h" | #include "BKE_pbvh.h" | ||||
| Show All 36 Lines | |||||
| #include "RE_engine.h" | #include "RE_engine.h" | ||||
| #include "RE_pipeline.h" | #include "RE_pipeline.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "wm_window.h" | |||||
| #include "draw_manager_text.h" | #include "draw_manager_text.h" | ||||
| #include "draw_manager_profiling.h" | #include "draw_manager_profiling.h" | ||||
| /* only for callbacks */ | /* only for callbacks */ | ||||
| #include "draw_cache_impl.h" | #include "draw_cache_impl.h" | ||||
| #include "draw_instance_data.h" | #include "draw_instance_data.h" | ||||
| #include "draw_mode_engines.h" | #include "draw_mode_engines.h" | ||||
| #include "engines/clay/clay_engine.h" | #include "engines/clay/clay_engine.h" | ||||
| #include "engines/eevee/eevee_engine.h" | #include "engines/eevee/eevee_engine.h" | ||||
| #include "engines/basic/basic_engine.h" | #include "engines/basic/basic_engine.h" | ||||
| #include "engines/external/external_engine.h" | #include "engines/external/external_engine.h" | ||||
| #include "../../../intern/gawain/gawain/gwn_context.h" | |||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Local Features | /** \name Local Features | ||||
| * \{ */ | * \{ */ | ||||
| #define USE_PROFILE | #define USE_PROFILE | ||||
| ▲ Show 20 Lines • Show All 256 Lines • ▼ Show 20 Lines | |||||
| static struct DRWMatrixOveride { | static struct DRWMatrixOveride { | ||||
| float mat[6][4][4]; | float mat[6][4][4]; | ||||
| bool override[6]; | bool override[6]; | ||||
| } viewport_matrix_override = {{{{0}}}}; | } viewport_matrix_override = {{{{0}}}}; | ||||
| ListBase DRW_engines = {NULL, NULL}; | ListBase DRW_engines = {NULL, NULL}; | ||||
| /* Unique ghost context used by the draw manager. */ | |||||
| static void *g_ogl_context = NULL; | |||||
| static Gwn_Context *g_gwn_context = NULL; | |||||
| /* Mutex to lock the drw manager and avoid concurent context usage. */ | |||||
brecht: Only write locks are used for this read-write mutex, so unless you are planning to use read… | |||||
| static ThreadMutex cache_rwlock = BLI_MUTEX_INITIALIZER; | |||||
Not Done Inline ActionsRename to g_ogl_context_lock or something like that? brecht: Rename to `g_ogl_context_lock` or something like that? | |||||
| #ifdef USE_GPU_SELECT | #ifdef USE_GPU_SELECT | ||||
| static unsigned int g_DRW_select_id = (unsigned int)-1; | static unsigned int g_DRW_select_id = (unsigned int)-1; | ||||
| void DRW_select_load_id(unsigned int id) | void DRW_select_load_id(unsigned int id) | ||||
| { | { | ||||
| BLI_assert(G.f & G_PICKSEL); | BLI_assert(G.f & G_PICKSEL); | ||||
| g_DRW_select_id = id; | g_DRW_select_id = id; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 3,049 Lines • ▼ Show 20 Lines | |||||
| * Need to reset DST before calling this function | * Need to reset DST before calling this function | ||||
| */ | */ | ||||
| void DRW_draw_render_loop_ex( | void DRW_draw_render_loop_ex( | ||||
| struct Depsgraph *depsgraph, | struct Depsgraph *depsgraph, | ||||
| RenderEngineType *engine_type, | RenderEngineType *engine_type, | ||||
| ARegion *ar, View3D *v3d, const eObjectMode object_mode, | ARegion *ar, View3D *v3d, const eObjectMode object_mode, | ||||
| const bContext *evil_C) | const bContext *evil_C) | ||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| DST.draw_ctx.evil_C = evil_C; | DST.draw_ctx.evil_C = evil_C; | ||||
| DST.viewport = rv3d->viewport; | DST.viewport = rv3d->viewport; | ||||
| v3d->zbuf = true; | v3d->zbuf = true; | ||||
| ▲ Show 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | |||||
| void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) | void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) | ||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| RenderEngineType *engine_type = engine->type; | RenderEngineType *engine_type = engine->type; | ||||
| DrawEngineType *draw_engine_type = engine_type->draw_engine; | DrawEngineType *draw_engine_type = engine_type->draw_engine; | ||||
| RenderData *r = &scene->r; | RenderData *r = &scene->r; | ||||
| Render *render = engine->re; | Render *render = engine->re; | ||||
| const EvaluationContext *eval_ctx = RE_GetEvalCtx(render); | const EvaluationContext *eval_ctx = RE_GetEvalCtx(render); | ||||
| /* Changing Context */ | |||||
| DRW_opengl_context_enable(); | |||||
| /* IMPORTANT: We dont support immediate mode in render mode! | |||||
| * This shall remain in effect until immediate mode supports | |||||
Not Done Inline ActionsMaybe add a DRW_ogl_select_ctx_enable() and use it here? Just to keep that locking logic together a bit. brecht: Maybe add a `DRW_ogl_select_ctx_enable()` and use it here? Just to keep that locking logic… | |||||
| * multiple threads. */ | |||||
| /* Reset before using it. */ | /* Reset before using it. */ | ||||
| memset(&DST, 0x0, sizeof(DST)); | memset(&DST, 0x0, sizeof(DST)); | ||||
| DST.options.is_image_render = true; | DST.options.is_image_render = true; | ||||
| DST.options.is_scene_render = true; | DST.options.is_scene_render = true; | ||||
| DST.options.draw_background = scene->r.alphamode == R_ADDSKY; | DST.options.draw_background = scene->r.alphamode == R_ADDSKY; | ||||
| DST.draw_ctx = (DRWContextState){ | DST.draw_ctx = (DRWContextState){ | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) | ||||
| * on at this point. */ | * on at this point. */ | ||||
| glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
| /* Restore Drawing area. */ | /* Restore Drawing area. */ | ||||
| gpuPopAttrib(); | gpuPopAttrib(); | ||||
| glEnable(GL_SCISSOR_TEST); | glEnable(GL_SCISSOR_TEST); | ||||
| GPU_framebuffer_restore(); | GPU_framebuffer_restore(); | ||||
| /* Changing Context */ | |||||
| DRW_opengl_context_disable(); | |||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| /* Avoid accidental reuse. */ | /* Avoid accidental reuse. */ | ||||
| memset(&DST, 0xFF, sizeof(DST)); | memset(&DST, 0xFF, sizeof(DST)); | ||||
| #endif | #endif | ||||
| } | } | ||||
| void DRW_render_object_iter( | void DRW_render_object_iter( | ||||
| void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph, | void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph, | ||||
| void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph)) | void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph)) | ||||
| { | { | ||||
| DEG_OBJECT_ITER_FOR_RENDER_ENGINE(depsgraph, ob, DRW_iterator_mode_get()) | DEG_OBJECT_ITER_FOR_RENDER_ENGINE(depsgraph, ob, DRW_iterator_mode_get()) | ||||
| { | { | ||||
| callback(vedata, ob, engine, depsgraph); | callback(vedata, ob, engine, depsgraph); | ||||
| } | } | ||||
| DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END | DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END | ||||
| } | } | ||||
| static struct DRWSelectBuffer { | |||||
| struct GPUFrameBuffer *framebuffer; | |||||
| struct GPUTexture *texture_depth; | |||||
| } g_select_buffer = {NULL}; | |||||
| static void draw_select_framebuffer_setup(const rcti *rect) | |||||
| { | |||||
| if (g_select_buffer.framebuffer == NULL) { | |||||
| g_select_buffer.framebuffer = GPU_framebuffer_create(); | |||||
| } | |||||
| /* If size mismatch recreate the texture. */ | |||||
| if ((g_select_buffer.texture_depth != NULL) && | |||||
| ((GPU_texture_width(g_select_buffer.texture_depth) != BLI_rcti_size_x(rect)) || | |||||
| (GPU_texture_height(g_select_buffer.texture_depth) != BLI_rcti_size_y(rect)))) | |||||
| { | |||||
| GPU_texture_free(g_select_buffer.texture_depth); | |||||
| g_select_buffer.texture_depth = NULL; | |||||
| } | |||||
| if (g_select_buffer.texture_depth == NULL) { | |||||
| g_select_buffer.texture_depth = GPU_texture_create_depth(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), NULL); | |||||
| GPU_framebuffer_texture_attach(g_select_buffer.framebuffer, g_select_buffer.texture_depth, 0, 0); | |||||
| if (!GPU_framebuffer_check_valid(g_select_buffer.framebuffer, NULL)) { | |||||
| printf("Error invalid selection framebuffer\n"); | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Must run after all instance datas have been added. */ | /* Must run after all instance datas have been added. */ | ||||
| void DRW_render_instance_buffer_finish(void) | void DRW_render_instance_buffer_finish(void) | ||||
| { | { | ||||
| BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!"); | BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!"); | ||||
| DST.buffer_finish_called = true; | DST.buffer_finish_called = true; | ||||
| DRW_instance_buffer_finish(DST.idatalist); | DRW_instance_buffer_finish(DST.idatalist); | ||||
| } | } | ||||
| Show All 29 Lines | if (obact->type == OB_MBALL) { | ||||
| obedit_mode = CTX_MODE_EDIT_METABALL; | obedit_mode = CTX_MODE_EDIT_METABALL; | ||||
| } | } | ||||
| else if (obact->type == OB_ARMATURE) { | else if (obact->type == OB_ARMATURE) { | ||||
| use_obedit = true; | use_obedit = true; | ||||
| obedit_mode = CTX_MODE_EDIT_ARMATURE; | obedit_mode = CTX_MODE_EDIT_ARMATURE; | ||||
| } | } | ||||
| } | } | ||||
| gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); | |||||
| glDisable(GL_SCISSOR_TEST); | |||||
| struct GPUViewport *viewport = GPU_viewport_create(); | struct GPUViewport *viewport = GPU_viewport_create(); | ||||
| GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}); | GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}); | ||||
| bool cache_is_dirty; | |||||
| DST.viewport = viewport; | DST.viewport = viewport; | ||||
| v3d->zbuf = true; | v3d->zbuf = true; | ||||
| /* Setup framebuffer */ | |||||
| draw_select_framebuffer_setup(rect); | |||||
| GPU_framebuffer_bind(g_select_buffer.framebuffer); | |||||
| DRW_framebuffer_clear(false, true, false, NULL, 1.0f); | |||||
| DST.options.is_select = true; | DST.options.is_select = true; | ||||
| /* Get list of enabled engines */ | /* Get list of enabled engines */ | ||||
| if (use_obedit) { | if (use_obedit) { | ||||
| drw_engines_enable_from_mode(obedit_mode); | drw_engines_enable_from_mode(obedit_mode); | ||||
| } | } | ||||
| else { | else { | ||||
| drw_engines_enable_basic(); | drw_engines_enable_basic(); | ||||
| drw_engines_enable_from_object_mode(); | drw_engines_enable_from_object_mode(); | ||||
| } | } | ||||
| /* Setup viewport */ | /* Setup viewport */ | ||||
| cache_is_dirty = true; | |||||
| /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ | /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ | ||||
| DST.draw_ctx = (DRWContextState){ | DST.draw_ctx = (DRWContextState){ | ||||
| ar, rv3d, v3d, scene, view_layer, obact, engine_type, depsgraph, object_mode, | ar, rv3d, v3d, scene, view_layer, obact, engine_type, depsgraph, object_mode, | ||||
| (bContext *)NULL, | (bContext *)NULL, | ||||
| }; | }; | ||||
| drw_context_state_init(); | drw_context_state_init(); | ||||
| drw_viewport_var_init(); | drw_viewport_var_init(); | ||||
| /* Update ubos */ | /* Update ubos */ | ||||
| DRW_globals_update(); | DRW_globals_update(); | ||||
| /* Init engines */ | /* Init engines */ | ||||
| drw_engines_init(); | drw_engines_init(); | ||||
| /* TODO : tag to refresh by the dependency graph */ | { | ||||
| /* ideally only refresh when objects are added/removed */ | |||||
| /* or render properties / materials change */ | |||||
| if (cache_is_dirty) { | |||||
| drw_engines_cache_init(); | drw_engines_cache_init(); | ||||
| if (use_obedit) { | if (use_obedit) { | ||||
| drw_engines_cache_populate(obact); | drw_engines_cache_populate(obact); | ||||
| } | } | ||||
| else { | else { | ||||
| DEG_OBJECT_ITER(depsgraph, ob, DRW_iterator_mode_get(), | DEG_OBJECT_ITER(depsgraph, ob, DRW_iterator_mode_get(), | ||||
| DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | | DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | | ||||
| Show All 21 Lines | #else | ||||
| DRW_state_reset(); | DRW_state_reset(); | ||||
| drw_engines_disable(); | drw_engines_disable(); | ||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| /* Avoid accidental reuse. */ | /* Avoid accidental reuse. */ | ||||
| memset(&DST, 0xFF, sizeof(DST)); | memset(&DST, 0xFF, sizeof(DST)); | ||||
| #endif | #endif | ||||
| GPU_framebuffer_restore(); | |||||
| /* Cleanup for selection state */ | /* Cleanup for selection state */ | ||||
| GPU_viewport_free(viewport); | GPU_viewport_free(viewport); | ||||
| MEM_freeN(viewport); | MEM_freeN(viewport); | ||||
| /* Restore Drawing area. */ | |||||
| gpuPopAttrib(); | |||||
| glEnable(GL_SCISSOR_TEST); | |||||
| /* restore */ | /* restore */ | ||||
| rv3d->viewport = backup_viewport; | rv3d->viewport = backup_viewport; | ||||
| #endif /* USE_GPU_SELECT */ | #endif /* USE_GPU_SELECT */ | ||||
| } | } | ||||
| static void draw_depth_texture_to_screen(GPUTexture *texture) | |||||
| { | |||||
| const float w = (float)GPU_texture_width(texture); | |||||
| const float h = (float)GPU_texture_height(texture); | |||||
| Gwn_VertFormat *format = immVertexFormat(); | |||||
| unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); | |||||
| unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); | |||||
| immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH_COPY); | |||||
| GPU_texture_bind(texture, 0); | |||||
| immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ | |||||
| immBegin(GWN_PRIM_TRI_STRIP, 4); | |||||
| immAttrib2f(texcoord, 0.0f, 0.0f); | |||||
| immVertex2f(pos, 0.0f, 0.0f); | |||||
| immAttrib2f(texcoord, 1.0f, 0.0f); | |||||
| immVertex2f(pos, w, 0.0f); | |||||
| immAttrib2f(texcoord, 0.0f, 1.0f); | |||||
| immVertex2f(pos, 0.0f, h); | |||||
| immAttrib2f(texcoord, 1.0f, 1.0f); | |||||
| immVertex2f(pos, w, h); | |||||
| immEnd(); | |||||
| GPU_texture_unbind(texture); | |||||
| immUnbindProgram(); | |||||
| } | |||||
| /** | /** | ||||
| * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing). | * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing). | ||||
| */ | */ | ||||
| void DRW_draw_depth_loop( | void DRW_draw_depth_loop( | ||||
| Depsgraph *depsgraph, | Depsgraph *depsgraph, | ||||
| ARegion *ar, View3D *v3d, const eObjectMode object_mode) | ARegion *ar, View3D *v3d, const eObjectMode object_mode) | ||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); | RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id); | ||||
| ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| DRW_opengl_context_enable(); | |||||
| /* backup (_never_ use rv3d->viewport) */ | /* backup (_never_ use rv3d->viewport) */ | ||||
| void *backup_viewport = rv3d->viewport; | void *backup_viewport = rv3d->viewport; | ||||
| rv3d->viewport = NULL; | rv3d->viewport = NULL; | ||||
| /* Reset before using it. */ | /* Reset before using it. */ | ||||
| memset(&DST, 0x0, sizeof(DST)); | memset(&DST, 0x0, sizeof(DST)); | ||||
| gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); | |||||
| glDisable(GL_SCISSOR_TEST); | |||||
| struct GPUViewport *viewport = GPU_viewport_create(); | struct GPUViewport *viewport = GPU_viewport_create(); | ||||
| GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy}); | GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy}); | ||||
| /* Setup framebuffer */ | |||||
| draw_select_framebuffer_setup(&ar->winrct); | |||||
| GPU_framebuffer_bind(g_select_buffer.framebuffer); | |||||
| DRW_framebuffer_clear(false, true, false, NULL, 1.0f); | |||||
| bool cache_is_dirty; | bool cache_is_dirty; | ||||
| DST.viewport = viewport; | DST.viewport = viewport; | ||||
| v3d->zbuf = true; | v3d->zbuf = true; | ||||
| DST.options.is_depth = true; | DST.options.is_depth = true; | ||||
| /* Get list of enabled engines */ | /* Get list of enabled engines */ | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | void DRW_draw_depth_loop( | ||||
| DRW_state_reset(); | DRW_state_reset(); | ||||
| drw_engines_disable(); | drw_engines_disable(); | ||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| /* Avoid accidental reuse. */ | /* Avoid accidental reuse. */ | ||||
| memset(&DST, 0xFF, sizeof(DST)); | memset(&DST, 0xFF, sizeof(DST)); | ||||
| #endif | #endif | ||||
| /* TODO: Reading depth for operators should be done here. */ | |||||
| GPU_framebuffer_restore(); | |||||
| /* Cleanup for selection state */ | /* Cleanup for selection state */ | ||||
| GPU_viewport_free(viewport); | GPU_viewport_free(viewport); | ||||
| MEM_freeN(viewport); | MEM_freeN(viewport); | ||||
| /* Restore Drawing area. */ | |||||
| gpuPopAttrib(); | |||||
| glEnable(GL_SCISSOR_TEST); | |||||
| /* Changin context */ | |||||
| DRW_opengl_context_disable(); | |||||
| /* XXX Drawing the resulting buffer to the BACK_BUFFER */ | |||||
| gpuPushMatrix(); | |||||
| gpuPushProjectionMatrix(); | |||||
| wmOrtho2_region_pixelspace(ar); | |||||
| gpuLoadIdentity(); | |||||
| glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */ | |||||
| glDepthFunc(GL_ALWAYS); | |||||
| draw_depth_texture_to_screen(g_select_buffer.texture_depth); | |||||
| glDepthFunc(GL_LEQUAL); | |||||
| gpuPopMatrix(); | |||||
| gpuPopProjectionMatrix(); | |||||
| /* restore */ | /* restore */ | ||||
| rv3d->viewport = backup_viewport; | rv3d->viewport = backup_viewport; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | /* setup callbacks */ | ||||
| BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free; | BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free; | ||||
| } | } | ||||
| } | } | ||||
| extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ | extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ | ||||
| extern struct GPUTexture *globals_ramp; /* draw_common.c */ | extern struct GPUTexture *globals_ramp; /* draw_common.c */ | ||||
| void DRW_engines_free(void) | void DRW_engines_free(void) | ||||
| { | { | ||||
| DRW_opengl_context_enable(); | |||||
| DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth); | |||||
| DRW_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer); | |||||
| DRW_shape_cache_free(); | DRW_shape_cache_free(); | ||||
| DRW_stats_free(); | DRW_stats_free(); | ||||
| DRW_globals_free(); | DRW_globals_free(); | ||||
| DrawEngineType *next; | DrawEngineType *next; | ||||
| for (DrawEngineType *type = DRW_engines.first; type; type = next) { | for (DrawEngineType *type = DRW_engines.first; type; type = next) { | ||||
| next = type->next; | next = type->next; | ||||
| BLI_remlink(&R_engines, type); | BLI_remlink(&R_engines, type); | ||||
| Show All 9 Lines | void DRW_engines_free(void) | ||||
| if (globals_ramp) | if (globals_ramp) | ||||
| GPU_texture_free(globals_ramp); | GPU_texture_free(globals_ramp); | ||||
| MEM_SAFE_FREE(g_pos_format); | MEM_SAFE_FREE(g_pos_format); | ||||
| MEM_SAFE_FREE(RST.bound_texs); | MEM_SAFE_FREE(RST.bound_texs); | ||||
| MEM_SAFE_FREE(RST.bound_tex_slots); | MEM_SAFE_FREE(RST.bound_tex_slots); | ||||
| DRW_opengl_context_disable(); | |||||
| #ifdef WITH_CLAY_ENGINE | #ifdef WITH_CLAY_ENGINE | ||||
| BLI_remlink(&R_engines, &DRW_engine_viewport_clay_type); | BLI_remlink(&R_engines, &DRW_engine_viewport_clay_type); | ||||
| #endif | #endif | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /** \name Init/Exit (DRW_opengl_ctx) | |||||
| * \{ */ | |||||
| void DRW_opengl_context_create(void) | |||||
Not Done Inline ActionsI would prefer to have the full name DRW_opengl_context_create() here for clarity, it's not so long and abbreviations are not always obvious. brecht: I would prefer to have the full name `DRW_opengl_context_create()` here for clarity, it's not… | |||||
| { | |||||
| BLI_assert(g_ogl_context == NULL); /* Ensure it's called once */ | |||||
| BLI_assert(BLI_thread_is_main()); | |||||
| immDeactivate(); | |||||
| /* This changes the active context. */ | |||||
| g_ogl_context = WM_opengl_context_create(); | |||||
| /* Be sure to create gawain.context too. */ | |||||
| g_gwn_context = GWN_context_create(); | |||||
| immActivate(); | |||||
| /* So we activate the window's one afterwards. */ | |||||
| wm_window_reset_drawable(); | |||||
| } | |||||
| void DRW_opengl_context_destroy(void) | |||||
| { | |||||
| BLI_assert(BLI_thread_is_main()); | |||||
| if (g_ogl_context != NULL) { | |||||
| WM_opengl_context_activate(g_ogl_context); | |||||
| GWN_context_active_set(g_gwn_context); | |||||
| GWN_context_discard(g_gwn_context); | |||||
| WM_opengl_context_dispose(g_ogl_context); | |||||
| } | |||||
| } | |||||
| void DRW_opengl_context_enable(void) | |||||
| { | |||||
| if (g_ogl_context != NULL) { | |||||
| /* IMPORTANT: We dont support immediate mode in render mode! | |||||
| * This shall remain in effect until immediate mode supports | |||||
| * multiple threads. */ | |||||
| BLI_mutex_lock(&cache_rwlock); | |||||
| if (BLI_thread_is_main()) { | |||||
| immDeactivate(); | |||||
| } | |||||
| WM_opengl_context_activate(g_ogl_context); | |||||
| GWN_context_active_set(g_gwn_context); | |||||
| if (BLI_thread_is_main()) { | |||||
| immActivate(); | |||||
| } | |||||
| } | |||||
| } | |||||
| void DRW_opengl_context_disable(void) | |||||
| { | |||||
| if (g_ogl_context != NULL) { | |||||
| wm_window_reset_drawable(); | |||||
| BLI_mutex_unlock(&cache_rwlock); | |||||
| } | |||||
| } | |||||
| /** \} */ | |||||
Only write locks are used for this read-write mutex, so unless you are planning to use read locks you could use a regular mutex instead.