Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_viewport.c
| Show All 34 Lines | |||||
| #include "IMB_colormanagement.h" | #include "IMB_colormanagement.h" | ||||
| #include "DNA_vec_types.h" | #include "DNA_vec_types.h" | ||||
| #include "DNA_userdef_types.h" | #include "DNA_userdef_types.h" | ||||
| #include "GPU_framebuffer.h" | #include "GPU_framebuffer.h" | ||||
| #include "GPU_glew.h" | #include "GPU_glew.h" | ||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "GPU_matrix.h" | |||||
| #include "GPU_texture.h" | #include "GPU_texture.h" | ||||
| #include "GPU_viewport.h" | #include "GPU_viewport.h" | ||||
| #include "GPU_uniformbuffer.h" | #include "GPU_uniformbuffer.h" | ||||
| #include "DRW_engine.h" | #include "DRW_engine.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| Show All 12 Lines | typedef struct ViewportTempTexture { | ||||
| void *user[MAX_ENGINE_BUFFER_SHARING]; | void *user[MAX_ENGINE_BUFFER_SHARING]; | ||||
| GPUTexture *texture; | GPUTexture *texture; | ||||
| } ViewportTempTexture; | } ViewportTempTexture; | ||||
| struct GPUViewport { | struct GPUViewport { | ||||
| int size[2]; | int size[2]; | ||||
| int flag; | int flag; | ||||
| /* If engine_handles mismatch we free all ViewportEngineData in this viewport */ | /* Set the active view (for stereoscoptic viewport rendering). */ | ||||
fclem: Uppercase first letter and end with fullstop!
Also the comment should be
`/* Active view used… | |||||
| int active_view; | |||||
| /* If engine_handles mismatch we free all ViewportEngineData in this viewport. */ | |||||
| struct { | struct { | ||||
| void *handle; | void *handle; | ||||
| ViewportEngineData *data; | ViewportEngineData *data; | ||||
| } engine_data[MAX_ENABLE_ENGINE]; | } engine_data[MAX_ENABLE_ENGINE]; | ||||
| DefaultFramebufferList *fbl; | DefaultFramebufferList *fbl; | ||||
| DefaultTextureList *txl; | DefaultTextureList *txl; | ||||
| ViewportMemoryPool vmempool; /* Used for rendering data structure. */ | ViewportMemoryPool vmempool; /* Used for rendering data structure. */ | ||||
| struct DRWInstanceDataList *idatalist; /* Used for rendering data structure. */ | struct DRWInstanceDataList *idatalist; /* Used for rendering data structure. */ | ||||
| ListBase tex_pool; /* ViewportTempTexture list : Temporary textures shared across draw engines */ | ListBase | ||||
| tex_pool; /* ViewportTempTexture list : Temporary textures shared across draw engines. */ | |||||
| /* Profiling data */ | /* Profiling data. */ | ||||
| double cache_time; | double cache_time; | ||||
| /* Color management. */ | /* Color management. */ | ||||
| ColorManagedViewSettings view_settings; | ColorManagedViewSettings view_settings; | ||||
| ColorManagedDisplaySettings display_settings; | ColorManagedDisplaySettings display_settings; | ||||
| float dither; | float dither; | ||||
| /* TODO(fclem) the uvimage display use the viewport but do not set any view transform for the | /* TODO(fclem) the uvimage display use the viewport but do not set any view transform for the | ||||
| * moment. The end goal would be to let the GPUViewport do the color management. */ | * moment. The end goal would be to let the GPUViewport do the color management. */ | ||||
| bool do_color_management; | bool do_color_management; | ||||
| }; | }; | ||||
| enum { | enum { | ||||
| DO_UPDATE = (1 << 0), | DO_UPDATE = (1 << 0), | ||||
| GPU_VIEWPORT_STEREO = (1 << 1), | |||||
| }; | }; | ||||
| static void gpu_viewport_buffers_free(FramebufferList *fbl, | static void gpu_viewport_buffers_free( | ||||
| int fbl_len, | FramebufferList *fbl, int fbl_len, TextureList *txl, TextureList *txl_stereo, int txl_len); | ||||
| TextureList *txl, | |||||
| int txl_len); | |||||
| static void gpu_viewport_storage_free(StorageList *stl, int stl_len); | static void gpu_viewport_storage_free(StorageList *stl, int stl_len); | ||||
| static void gpu_viewport_passes_free(PassList *psl, int psl_len); | static void gpu_viewport_passes_free(PassList *psl, int psl_len); | ||||
| static void gpu_viewport_texture_pool_free(GPUViewport *viewport); | static void gpu_viewport_texture_pool_free(GPUViewport *viewport); | ||||
| void GPU_viewport_tag_update(GPUViewport *viewport) | void GPU_viewport_tag_update(GPUViewport *viewport) | ||||
| { | { | ||||
| viewport->flag |= DO_UPDATE; | viewport->flag |= DO_UPDATE; | ||||
| } | } | ||||
| bool GPU_viewport_do_update(GPUViewport *viewport) | bool GPU_viewport_do_update(GPUViewport *viewport) | ||||
| { | { | ||||
| bool ret = (viewport->flag & DO_UPDATE); | bool ret = (viewport->flag & DO_UPDATE); | ||||
| viewport->flag &= ~DO_UPDATE; | viewport->flag &= ~DO_UPDATE; | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| GPUViewport *GPU_viewport_create(void) | GPUViewport *GPU_viewport_create(bool stereo) | ||||
| { | { | ||||
| GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport"); | GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport"); | ||||
| viewport->fbl = MEM_callocN(sizeof(DefaultFramebufferList), "FramebufferList"); | viewport->fbl = MEM_callocN(sizeof(DefaultFramebufferList), "FramebufferList"); | ||||
| viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList"); | viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList"); | ||||
| viewport->idatalist = DRW_instance_data_list_create(); | viewport->idatalist = DRW_instance_data_list_create(); | ||||
| viewport->do_color_management = false; | viewport->do_color_management = false; | ||||
| viewport->size[0] = viewport->size[1] = -1; | viewport->size[0] = viewport->size[1] = -1; | ||||
| SET_FLAG_FROM_TEST(viewport->flag, stereo, GPU_VIEWPORT_STEREO); | |||||
| viewport->active_view = -1; | |||||
| return viewport; | return viewport; | ||||
| } | } | ||||
| static void gpu_viewport_framebuffer_view_set(GPUViewport *viewport, int view) | |||||
| { | |||||
| /* Early check if the view is the latest requested. */ | |||||
| if (viewport->active_view == view) { | |||||
| return; | |||||
| } | |||||
| DefaultFramebufferList *dfbl = viewport->fbl; | |||||
| DefaultTextureList *dtxl = viewport->txl; | |||||
| /* Only swap the texture when this is a Stereo Viewport. */ | |||||
| if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { | |||||
| SWAP(GPUTexture *, dtxl->color, dtxl->color_stereo); | |||||
| SWAP(GPUTexture *, dtxl->color_overlay, dtxl->color_overlay_stereo); | |||||
| for (int i = 0; i < MAX_ENABLE_ENGINE; i++) { | |||||
| if (viewport->engine_data[i].handle != NULL) { | |||||
| ViewportEngineData *data = viewport->engine_data[i].data; | |||||
| SWAP(StorageList *, data->stl, data->stl_stereo); | |||||
| SWAP(TextureList *, data->txl, data->txl_stereo); | |||||
| } | |||||
| else { | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| GPU_framebuffer_ensure_config(&dfbl->default_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth), | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color), | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->overlay_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth), | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth), | |||||
| GPU_ATTACHMENT_NONE, | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->color_only_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_NONE, | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color), | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_NONE, | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), | |||||
| }); | |||||
| if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { | |||||
| GPU_framebuffer_ensure_config(&dfbl->stereo_comp_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_NONE, | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color), | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), | |||||
| }); | |||||
| } | |||||
| else { | |||||
| dfbl->stereo_comp_fb = NULL; | |||||
| } | |||||
| viewport->active_view = view; | |||||
| } | |||||
| void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) | void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) | ||||
| { | { | ||||
| ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData"); | ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData"); | ||||
| int fbl_len, txl_len, psl_len, stl_len; | int fbl_len, txl_len, psl_len, stl_len; | ||||
| DRW_engine_viewport_data_size_get(engine_type, &fbl_len, &txl_len, &psl_len, &stl_len); | DRW_engine_viewport_data_size_get(engine_type, &fbl_len, &txl_len, &psl_len, &stl_len); | ||||
| data->engine_type = engine_type; | data->engine_type = engine_type; | ||||
| data->fbl = MEM_callocN((sizeof(void *) * fbl_len) + sizeof(FramebufferList), "FramebufferList"); | data->fbl = MEM_callocN((sizeof(void *) * fbl_len) + sizeof(FramebufferList), "FramebufferList"); | ||||
| data->txl = MEM_callocN((sizeof(void *) * txl_len) + sizeof(TextureList), "TextureList"); | data->txl = MEM_callocN((sizeof(void *) * txl_len) + sizeof(TextureList), "TextureList"); | ||||
| data->psl = MEM_callocN((sizeof(void *) * psl_len) + sizeof(PassList), "PassList"); | data->psl = MEM_callocN((sizeof(void *) * psl_len) + sizeof(PassList), "PassList"); | ||||
| data->stl = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), "StorageList"); | data->stl = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), "StorageList"); | ||||
| if ((viewport->flag & GPU_VIEWPORT_STEREO) != 0) { | |||||
| data->txl_stereo = MEM_callocN((sizeof(void *) * txl_len) + sizeof(TextureList), | |||||
| "TextureList"); | |||||
| data->stl_stereo = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), | |||||
| "StorageList"); | |||||
| } | |||||
| for (int i = 0; i < MAX_ENABLE_ENGINE; i++) { | for (int i = 0; i < MAX_ENABLE_ENGINE; i++) { | ||||
| if (viewport->engine_data[i].handle == NULL) { | if (viewport->engine_data[i].handle == NULL) { | ||||
| viewport->engine_data[i].handle = engine_type; | viewport->engine_data[i].handle = engine_type; | ||||
| viewport->engine_data[i].data = data; | viewport->engine_data[i].data = data; | ||||
| return data; | return data; | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(!"Too many draw engines enabled at the same time"); | BLI_assert(!"Too many draw engines enabled at the same time"); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| static void gpu_viewport_engines_data_free(GPUViewport *viewport) | static void gpu_viewport_engines_data_free(GPUViewport *viewport) | ||||
| { | { | ||||
| int fbl_len, txl_len, psl_len, stl_len; | int fbl_len, txl_len, psl_len, stl_len; | ||||
| for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { | for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { | ||||
| ViewportEngineData *data = viewport->engine_data[i].data; | ViewportEngineData *data = viewport->engine_data[i].data; | ||||
| DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, &psl_len, &stl_len); | DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, &psl_len, &stl_len); | ||||
| gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len); | gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, data->txl_stereo, txl_len); | ||||
| gpu_viewport_passes_free(data->psl, psl_len); | gpu_viewport_passes_free(data->psl, psl_len); | ||||
| gpu_viewport_storage_free(data->stl, stl_len); | gpu_viewport_storage_free(data->stl, stl_len); | ||||
| MEM_freeN(data->fbl); | MEM_freeN(data->fbl); | ||||
| MEM_freeN(data->txl); | MEM_freeN(data->txl); | ||||
| MEM_freeN(data->psl); | MEM_freeN(data->psl); | ||||
| MEM_freeN(data->stl); | MEM_freeN(data->stl); | ||||
| if ((viewport->flag & GPU_VIEWPORT_STEREO) != 0) { | |||||
| gpu_viewport_storage_free(data->stl_stereo, stl_len); | |||||
| MEM_freeN(data->txl_stereo); | |||||
| MEM_freeN(data->stl_stereo); | |||||
| } | |||||
| /* We could handle this in the DRW module */ | /* We could handle this in the DRW module */ | ||||
| if (data->text_draw_cache) { | if (data->text_draw_cache) { | ||||
| extern void DRW_text_cache_destroy(struct DRWTextStore * dt); | extern void DRW_text_cache_destroy(struct DRWTextStore * dt); | ||||
| DRW_text_cache_destroy(data->text_draw_cache); | DRW_text_cache_destroy(data->text_draw_cache); | ||||
| data->text_draw_cache = NULL; | data->text_draw_cache = NULL; | ||||
| } | } | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| Show All 22 Lines | ViewportMemoryPool *GPU_viewport_mempool_get(GPUViewport *viewport) | ||||
| return &viewport->vmempool; | return &viewport->vmempool; | ||||
| } | } | ||||
| struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *viewport) | struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *viewport) | ||||
| { | { | ||||
| return viewport->idatalist; | return viewport->idatalist; | ||||
| } | } | ||||
| /* Note this function is only allowed to be called from `DRW_notify_view_update`. The rest | |||||
| * should bind the correct viewport. | |||||
| * | |||||
| * The reason is that DRW_notify_view_update can be called from a different thread, but needs | |||||
| * access to the engine data. */ | |||||
| void GPU_viewport_active_view_set(GPUViewport *viewport, int view) | |||||
| { | |||||
| gpu_viewport_framebuffer_view_set(viewport, view); | |||||
| } | |||||
| void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport) | void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport) | ||||
| { | { | ||||
| return viewport->fbl; | return viewport->fbl; | ||||
| } | } | ||||
| void *GPU_viewport_texture_list_get(GPUViewport *viewport) | void *GPU_viewport_texture_list_get(GPUViewport *viewport) | ||||
| { | { | ||||
| return viewport->txl; | return viewport->txl; | ||||
| ▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | void GPU_viewport_cache_release(GPUViewport *viewport) | ||||
| for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { | for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { | ||||
| ViewportEngineData *data = viewport->engine_data[i].data; | ViewportEngineData *data = viewport->engine_data[i].data; | ||||
| int psl_len; | int psl_len; | ||||
| DRW_engine_viewport_data_size_get(data->engine_type, NULL, NULL, &psl_len, NULL); | DRW_engine_viewport_data_size_get(data->engine_type, NULL, NULL, &psl_len, NULL); | ||||
| gpu_viewport_passes_free(data->psl, psl_len); | gpu_viewport_passes_free(data->psl, psl_len); | ||||
| } | } | ||||
| } | } | ||||
| static void gpu_viewport_default_fb_create(GPUViewport *viewport) | static void gpu_viewport_default_fb_create(GPUViewport *viewport) | ||||
Done Inline ActionsI'm not a huge fan of having a state dependent view here. I would prefer if all viewport functions that are used for a specific view would take the view as argument. fclem: I'm not a huge fan of having a state dependent view here.
I would prefer if all viewport… | |||||
| { | { | ||||
| DefaultFramebufferList *dfbl = viewport->fbl; | DefaultFramebufferList *dfbl = viewport->fbl; | ||||
| DefaultTextureList *dtxl = viewport->txl; | DefaultTextureList *dtxl = viewport->txl; | ||||
| int *size = viewport->size; | int *size = viewport->size; | ||||
| bool ok = true; | bool ok = true; | ||||
| dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); | dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); | ||||
| dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL); | dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL); | ||||
| if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { | |||||
| dtxl->color_stereo = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); | |||||
| dtxl->color_overlay_stereo = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL); | |||||
| } | |||||
| /* Can be shared with GPUOffscreen. */ | /* Can be shared with GPUOffscreen. */ | ||||
| if (dtxl->depth == NULL) { | if (dtxl->depth == NULL) { | ||||
| dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); | dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); | ||||
| } | } | ||||
| if (!dtxl->depth || !dtxl->color) { | if (!dtxl->depth || !dtxl->color) { | ||||
| ok = false; | ok = false; | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| GPU_framebuffer_ensure_config(&dfbl->default_fb, | gpu_viewport_framebuffer_view_set(viewport, 0); | ||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth), | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color), | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->overlay_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth), | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->depth), | |||||
| GPU_ATTACHMENT_NONE, | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->color_only_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_NONE, | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color), | |||||
| }); | |||||
| GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb, | |||||
| { | |||||
| GPU_ATTACHMENT_NONE, | |||||
| GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), | |||||
| }); | |||||
| ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); | ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); | ||||
| ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_fb, NULL); | ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_fb, NULL); | ||||
| ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); | ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); | ||||
| ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); | ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); | ||||
| ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_only_fb, NULL); | ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_only_fb, NULL); | ||||
| if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { | |||||
| ok = ok && GPU_framebuffer_check_valid(dfbl->stereo_comp_fb, NULL); | |||||
| } | |||||
| cleanup: | cleanup: | ||||
| if (!ok) { | if (!ok) { | ||||
| GPU_viewport_free(viewport); | GPU_viewport_free(viewport); | ||||
| DRW_opengl_context_disable(); | DRW_opengl_context_disable(); | ||||
| return; | return; | ||||
| } | } | ||||
| GPU_framebuffer_restore(); | GPU_framebuffer_restore(); | ||||
| } | } | ||||
| void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) | void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect) | ||||
| { | { | ||||
| DefaultFramebufferList *dfbl = viewport->fbl; | DefaultFramebufferList *dfbl = viewport->fbl; | ||||
| int fbl_len, txl_len; | int fbl_len, txl_len; | ||||
| int rect_size[2]; | int rect_size[2]; | ||||
| /* add one pixel because of scissor test */ | /* add one pixel because of scissor test */ | ||||
| rect_size[0] = BLI_rcti_size_x(rect) + 1; | rect_size[0] = BLI_rcti_size_x(rect) + 1; | ||||
| rect_size[1] = BLI_rcti_size_y(rect) + 1; | rect_size[1] = BLI_rcti_size_y(rect) + 1; | ||||
| DRW_opengl_context_enable(); | DRW_opengl_context_enable(); | ||||
| if (dfbl->default_fb) { | if (dfbl->default_fb) { | ||||
| if (!equals_v2v2_int(viewport->size, rect_size)) { | if (!equals_v2v2_int(viewport->size, rect_size)) { | ||||
| gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, | gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, | ||||
| default_fbl_len, | default_fbl_len, | ||||
| (TextureList *)viewport->txl, | (TextureList *)viewport->txl, | ||||
| NULL, | |||||
| default_txl_len); | default_txl_len); | ||||
| for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { | for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { | ||||
| ViewportEngineData *data = viewport->engine_data[i].data; | ViewportEngineData *data = viewport->engine_data[i].data; | ||||
| DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, NULL, NULL); | DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, NULL, NULL); | ||||
| gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len); | gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, data->txl_stereo, txl_len); | ||||
| } | } | ||||
| gpu_viewport_texture_pool_free(viewport); | gpu_viewport_texture_pool_free(viewport); | ||||
| viewport->active_view = -1; | |||||
| } | } | ||||
| } | } | ||||
| copy_v2_v2_int(viewport->size, rect_size); | copy_v2_v2_int(viewport->size, rect_size); | ||||
| gpu_viewport_texture_pool_clear_users(viewport); | gpu_viewport_texture_pool_clear_users(viewport); | ||||
| if (!dfbl->default_fb) { | if (!dfbl->default_fb) { | ||||
| gpu_viewport_default_fb_create(viewport); | gpu_viewport_default_fb_create(viewport); | ||||
| } | } | ||||
| gpu_viewport_framebuffer_view_set(viewport, view); | |||||
| } | } | ||||
| void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs) | void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs) | ||||
| { | { | ||||
| DefaultFramebufferList *dfbl = viewport->fbl; | DefaultFramebufferList *dfbl = viewport->fbl; | ||||
| DefaultTextureList *dtxl = viewport->txl; | DefaultTextureList *dtxl = viewport->txl; | ||||
| GPUTexture *color, *depth; | GPUTexture *color, *depth; | ||||
| GPUFrameBuffer *fb; | GPUFrameBuffer *fb; | ||||
| Show All 18 Lines | void GPU_viewport_colorspace_set(GPUViewport *viewport, | ||||
| float dither) | float dither) | ||||
| { | { | ||||
| memcpy(&viewport->view_settings, view_settings, sizeof(*view_settings)); | memcpy(&viewport->view_settings, view_settings, sizeof(*view_settings)); | ||||
| memcpy(&viewport->display_settings, display_settings, sizeof(*display_settings)); | memcpy(&viewport->display_settings, display_settings, sizeof(*display_settings)); | ||||
| viewport->dither = dither; | viewport->dither = dither; | ||||
| viewport->do_color_management = true; | viewport->do_color_management = true; | ||||
| } | } | ||||
| /* Merge the stereo textures. `color` and `overlay` texture will be modified. */ | |||||
| void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format) | |||||
| { | |||||
| if (!ELEM(stereo_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) { | |||||
| /* Early Exit: the other display modes need access to the full screen and cannot be | |||||
| * done from a single viewport. See `wm_stereo.c` */ | |||||
| return; | |||||
| } | |||||
| gpu_viewport_framebuffer_view_set(viewport, 0); | |||||
| DefaultTextureList *dtxl = viewport->txl; | |||||
| DefaultFramebufferList *dfbl = viewport->fbl; | |||||
| GPUVertFormat *vert_format = immVertexFormat(); | |||||
| uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | |||||
| GPU_framebuffer_bind(dfbl->stereo_comp_fb); | |||||
| GPU_matrix_push(); | |||||
| GPU_matrix_push_projection(); | |||||
| GPU_matrix_identity_set(); | |||||
| GPU_matrix_identity_projection_set(); | |||||
| immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE); | |||||
| immUniform1i("imageTexture", 0); | |||||
| immUniform1i("overlayTexture", 1); | |||||
| int settings = stereo_format->display_mode; | |||||
Done Inline ActionsRemove mask. It is incorrect jbakker: Remove mask. It is incorrect | |||||
| if (settings == S3D_DISPLAY_ANAGLYPH) { | |||||
| switch (stereo_format->anaglyph_type) { | |||||
| case S3D_ANAGLYPH_REDCYAN: | |||||
| glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); | |||||
| break; | |||||
| case S3D_ANAGLYPH_GREENMAGENTA: | |||||
| glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE); | |||||
| break; | |||||
| case S3D_ANAGLYPH_YELLOWBLUE: | |||||
| glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); | |||||
| break; | |||||
| } | |||||
| } | |||||
| else if (settings == S3D_DISPLAY_INTERLACE) { | |||||
| settings |= stereo_format->interlace_type << 3; | |||||
| SET_FLAG_FROM_TEST(settings, stereo_format->flag & S3D_INTERLACE_SWAP, 1 << 6); | |||||
| } | |||||
| immUniform1i("stereoDisplaySettings", settings); | |||||
| GPU_texture_bind(dtxl->color_stereo, 0); | |||||
| GPU_texture_bind(dtxl->color_overlay_stereo, 1); | |||||
| immBegin(GPU_PRIM_TRI_STRIP, 4); | |||||
| immVertex2f(pos, -1.0f, -1.0f); | |||||
| immVertex2f(pos, 1.0f, -1.0f); | |||||
| immVertex2f(pos, -1.0f, 1.0f); | |||||
| immVertex2f(pos, 1.0f, 1.0f); | |||||
| immEnd(); | |||||
| GPU_texture_unbind(dtxl->color_stereo); | |||||
| GPU_texture_unbind(dtxl->color_overlay_stereo); | |||||
| immUnbindProgram(); | |||||
| GPU_matrix_pop_projection(); | |||||
| GPU_matrix_pop(); | |||||
| if (settings == S3D_DISPLAY_ANAGLYPH) { | |||||
| glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |||||
| } | |||||
| GPU_framebuffer_restore(); | |||||
| } | |||||
| static void gpu_viewport_draw_colormanaged(GPUViewport *viewport, | static void gpu_viewport_draw_colormanaged(GPUViewport *viewport, | ||||
| const rctf *rect_pos, | const rctf *rect_pos, | ||||
| const rctf *rect_uv, | const rctf *rect_uv, | ||||
| bool display_colorspace) | bool display_colorspace) | ||||
| { | { | ||||
| DefaultTextureList *dtxl = viewport->txl; | DefaultTextureList *dtxl = viewport->txl; | ||||
| GPUTexture *color = dtxl->color; | GPUTexture *color = dtxl->color; | ||||
| GPUTexture *color_overlay = dtxl->color_overlay; | GPUTexture *color_overlay = dtxl->color_overlay; | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | static void gpu_viewport_draw_colormanaged(GPUViewport *viewport, | ||||
| if (use_ocio) { | if (use_ocio) { | ||||
| IMB_colormanagement_finish_glsl_draw(); | IMB_colormanagement_finish_glsl_draw(); | ||||
| } | } | ||||
| else { | else { | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| } | } | ||||
| } | } | ||||
| void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) | void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect) | ||||
| { | { | ||||
| gpu_viewport_framebuffer_view_set(viewport, view); | |||||
| DefaultFramebufferList *dfbl = viewport->fbl; | DefaultFramebufferList *dfbl = viewport->fbl; | ||||
| DefaultTextureList *dtxl = viewport->txl; | DefaultTextureList *dtxl = viewport->txl; | ||||
| GPUTexture *color = dtxl->color; | GPUTexture *color = dtxl->color; | ||||
| if (dfbl->default_fb == NULL) { | if (dfbl->default_fb == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void GPU_viewport_unbind(GPUViewport *UNUSED(viewport)) | void GPU_viewport_unbind(GPUViewport *UNUSED(viewport)) | ||||
| { | { | ||||
| GPU_framebuffer_restore(); | GPU_framebuffer_restore(); | ||||
| DRW_opengl_context_disable(); | DRW_opengl_context_disable(); | ||||
| } | } | ||||
| GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport) | GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport, int view) | ||||
| { | { | ||||
| DefaultFramebufferList *dfbl = viewport->fbl; | DefaultFramebufferList *dfbl = viewport->fbl; | ||||
| if (dfbl->default_fb) { | if (dfbl->default_fb) { | ||||
| DefaultTextureList *dtxl = viewport->txl; | DefaultTextureList *dtxl = viewport->txl; | ||||
| if (viewport->active_view == view) { | |||||
| return dtxl->color; | return dtxl->color; | ||||
| } | } | ||||
| else { | |||||
| return dtxl->color_stereo; | |||||
| } | |||||
| } | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| static void gpu_viewport_buffers_free(FramebufferList *fbl, | static void gpu_viewport_buffers_free( | ||||
| int fbl_len, | FramebufferList *fbl, int fbl_len, TextureList *txl, TextureList *txl_stereo, int txl_len) | ||||
| TextureList *txl, | |||||
| int txl_len) | |||||
| { | { | ||||
| for (int i = 0; i < fbl_len; i++) { | for (int i = 0; i < fbl_len; i++) { | ||||
| GPUFrameBuffer *fb = fbl->framebuffers[i]; | GPUFrameBuffer *fb = fbl->framebuffers[i]; | ||||
| if (fb) { | if (fb) { | ||||
| GPU_framebuffer_free(fb); | GPU_framebuffer_free(fb); | ||||
| fbl->framebuffers[i] = NULL; | fbl->framebuffers[i] = NULL; | ||||
| } | } | ||||
| } | } | ||||
| for (int i = 0; i < txl_len; i++) { | for (int i = 0; i < txl_len; i++) { | ||||
| GPUTexture *tex = txl->textures[i]; | GPUTexture *tex = txl->textures[i]; | ||||
| if (tex) { | if (tex) { | ||||
| GPU_texture_free(tex); | GPU_texture_free(tex); | ||||
| txl->textures[i] = NULL; | txl->textures[i] = NULL; | ||||
| } | } | ||||
| } | } | ||||
| if (txl_stereo != NULL) { | |||||
| for (int i = 0; i < txl_len; i++) { | |||||
| GPUTexture *tex = txl_stereo->textures[i]; | |||||
| if (tex) { | |||||
| GPU_texture_free(tex); | |||||
| txl_stereo->textures[i] = NULL; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| static void gpu_viewport_storage_free(StorageList *stl, int stl_len) | static void gpu_viewport_storage_free(StorageList *stl, int stl_len) | ||||
| { | { | ||||
| for (int i = 0; i < stl_len; i++) { | for (int i = 0; i < stl_len; i++) { | ||||
Done Inline Actionsremove new line fclem: remove new line | |||||
| void *storage = stl->storage[i]; | void *storage = stl->storage[i]; | ||||
| if (storage) { | if (storage) { | ||||
| MEM_freeN(storage); | MEM_freeN(storage); | ||||
| stl->storage[i] = NULL; | stl->storage[i] = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void gpu_viewport_passes_free(PassList *psl, int psl_len) | static void gpu_viewport_passes_free(PassList *psl, int psl_len) | ||||
| { | { | ||||
| memset(psl->passes, 0, sizeof(*psl->passes) * psl_len); | memset(psl->passes, 0, sizeof(*psl->passes) * psl_len); | ||||
| } | } | ||||
| /* Must be executed inside Drawmanager Opengl Context. */ | /* Must be executed inside Drawmanager Opengl Context. */ | ||||
| void GPU_viewport_free(GPUViewport *viewport) | void GPU_viewport_free(GPUViewport *viewport) | ||||
| { | { | ||||
| gpu_viewport_engines_data_free(viewport); | gpu_viewport_engines_data_free(viewport); | ||||
| gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, | gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, | ||||
| default_fbl_len, | default_fbl_len, | ||||
| (TextureList *)viewport->txl, | (TextureList *)viewport->txl, | ||||
| NULL, | |||||
| default_txl_len); | default_txl_len); | ||||
| gpu_viewport_texture_pool_free(viewport); | gpu_viewport_texture_pool_free(viewport); | ||||
| MEM_freeN(viewport->fbl); | MEM_freeN(viewport->fbl); | ||||
| MEM_freeN(viewport->txl); | MEM_freeN(viewport->txl); | ||||
| if (viewport->vmempool.commands != NULL) { | if (viewport->vmempool.commands != NULL) { | ||||
| ▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines | |||||
Uppercase first letter and end with fullstop!
Also the comment should be
/* Active view used for stereo viewport rendering. */