Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_playanim.c
| Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| #include "BLI_fileops.h" | #include "BLI_fileops.h" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_path_util.h" | #include "BLI_path_util.h" | ||||
| #include "BLI_rect.h" | |||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "IMB_colormanagement.h" | |||||
| #include "IMB_imbuf.h" | #include "IMB_imbuf.h" | ||||
| #include "IMB_imbuf_types.h" | #include "IMB_imbuf_types.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BIF_glutil.h" | #include "BIF_glutil.h" | ||||
| #include "GPU_context.h" | #include "GPU_context.h" | ||||
| ▲ Show 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | static int pupdate_time(void) | ||||
| double time = PIL_check_seconds_timer(); | double time = PIL_check_seconds_timer(); | ||||
| ptottime += (time - ltime); | ptottime += (time - ltime); | ||||
| ltime = time; | ltime = time; | ||||
| return (ptottime < 0); | return (ptottime < 0); | ||||
| } | } | ||||
| static void *ocio_transform_ibuf(ImBuf *ibuf, | |||||
| bool *r_glsl_used, | |||||
| eGPUTextureFormat *r_format, | |||||
| eGPUDataFormat *r_data) | |||||
| { | |||||
| void *display_buffer; | |||||
| void *cache_handle = NULL; | |||||
| bool force_fallback = false; | |||||
| *r_glsl_used = false; | |||||
| force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL); | |||||
| force_fallback |= (ibuf->dither != 0.0f); | |||||
| /* Default */ | |||||
| *r_format = GPU_RGBA8; | |||||
| *r_data = GPU_DATA_UBYTE; | |||||
| ColorManagedViewSettings view_settings; | |||||
| ColorManagedDisplaySettings display_settings; | |||||
| STRNCPY(display_settings.display_device, | |||||
| IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE)); | |||||
| IMB_colormanagement_init_default_view_settings(&view_settings, &display_settings); | |||||
sergey: Can those be initialized only once? | |||||
| /* Fallback to CPU based color space conversion. */ | |||||
| if (force_fallback) { | |||||
| *r_glsl_used = false; | |||||
| display_buffer = NULL; | |||||
| } | |||||
| else if (ibuf->rect_float) { | |||||
| display_buffer = ibuf->rect_float; | |||||
| *r_data = GPU_DATA_FLOAT; | |||||
| if (ibuf->channels == 4) { | |||||
| *r_format = GPU_RGBA16F; | |||||
| } | |||||
| else if (ibuf->channels == 3) { | |||||
| /* Alpha is implicitly 1. */ | |||||
| *r_format = GPU_RGB16F; | |||||
| } | |||||
| else { | |||||
| BLI_assert(!"Incompatible number of channels for float buffer in sequencer"); | |||||
| *r_format = GPU_RGBA16F; | |||||
| display_buffer = NULL; | |||||
| } | |||||
| if (IMB_colormanagement_support_glsl_draw(&view_settings)) { | |||||
| } | |||||
| if (ibuf->float_colorspace) { | |||||
| *r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space( | |||||
| &view_settings, &display_settings, ibuf->float_colorspace, ibuf->dither, false, false); | |||||
| } | |||||
| else { | |||||
| *r_glsl_used = IMB_colormanagement_setup_glsl_draw( | |||||
| &view_settings, &display_settings, ibuf->dither, false); | |||||
| } | |||||
| } | |||||
| else if (ibuf->rect) { | |||||
| display_buffer = ibuf->rect; | |||||
| *r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space( | |||||
| &view_settings, &display_settings, ibuf->float_colorspace, ibuf->dither, false, false); | |||||
| } | |||||
| else { | |||||
| display_buffer = NULL; | |||||
| } | |||||
| /* There is data to be displayed, but GLSL is not initialized | |||||
| * properly, in this case we fallback to CPU-based display transform. */ | |||||
| if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) { | |||||
| display_buffer = IMB_display_buffer_acquire( | |||||
Done Inline ActionsYou can not release the handle until you're done using display_buffer returned by IMB_display_buffer_acquire. If same release happens in sequencer code, it should be fixed as well. sergey: You can not release the handle until you're done using `display_buffer` returned by… | |||||
| ibuf, &view_settings, &display_settings, &cache_handle); | |||||
| *r_format = GPU_RGBA8; | |||||
| *r_data = GPU_DATA_UBYTE; | |||||
| } | |||||
| if (cache_handle) { | |||||
| IMB_display_buffer_release(cache_handle); | |||||
| } | |||||
| return display_buffer; | |||||
| } | |||||
| static void draw_display_buffer(ImBuf *ibuf) | |||||
| { | |||||
| void *display_buffer; | |||||
| /* Format needs to be created prior to any #immBindShader call. | |||||
| * Do it here because OCIO binds its own shader. */ | |||||
| eGPUTextureFormat format; | |||||
| eGPUDataFormat data; | |||||
| bool glsl_used = false; | |||||
| GPUVertFormat *imm_format = immVertexFormat(); | |||||
| uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | |||||
| uint texCoord = GPU_vertformat_attr_add( | |||||
| imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | |||||
| display_buffer = ocio_transform_ibuf(ibuf, &glsl_used, &format, &data); | |||||
| GPUTexture *texture = GPU_texture_create_2d( | |||||
| "seq_display_buf", ibuf->x, ibuf->y, 1, format, NULL); | |||||
| GPU_texture_update(texture, data, display_buffer); | |||||
| GPU_texture_filter_mode(texture, false); | |||||
| GPU_texture_bind(texture, 0); | |||||
| if (!glsl_used) { | |||||
| immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); | |||||
| immUniformColor3f(1.0f, 1.0f, 1.0f); | |||||
| immUniform1i("image", 0); | |||||
| } | |||||
| immBegin(GPU_PRIM_TRI_FAN, 4); | |||||
| rctf preview; | |||||
| rctf canvas; | |||||
| BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f); | |||||
| BLI_rctf_init(&preview, 0.0f, 1.0f, 0.0f, 1.0f); | |||||
| immAttr2f(texCoord, canvas.xmin, canvas.ymin); | |||||
| immVertex2f(pos, preview.xmin, preview.ymin); | |||||
| immAttr2f(texCoord, canvas.xmin, canvas.ymax); | |||||
| immVertex2f(pos, preview.xmin, preview.ymax); | |||||
| immAttr2f(texCoord, canvas.xmax, canvas.ymax); | |||||
| immVertex2f(pos, preview.xmax, preview.ymax); | |||||
| immAttr2f(texCoord, canvas.xmax, canvas.ymin); | |||||
| immVertex2f(pos, preview.xmax, preview.ymin); | |||||
| immEnd(); | |||||
| GPU_texture_unbind(texture); | |||||
| GPU_texture_free(texture); | |||||
| if (!glsl_used) { | |||||
| immUnbindProgram(); | |||||
| } | |||||
| else { | |||||
| IMB_colormanagement_finish_glsl_draw(); | |||||
| } | |||||
| } | |||||
| static void playanim_toscreen( | static void playanim_toscreen( | ||||
| PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) | PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) | ||||
| { | { | ||||
| if (ibuf == NULL) { | if (ibuf == NULL) { | ||||
| printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>"); | printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>"); | ||||
| return; | return; | ||||
| } | } | ||||
| if (ibuf->rect == NULL && ibuf->rect_float) { | |||||
| IMB_rect_from_float(ibuf); | |||||
| imb_freerectfloatImBuf(ibuf); | |||||
| } | |||||
| if (ibuf->rect == NULL) { | |||||
| return; | |||||
| } | |||||
| GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); | GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); | ||||
| /* size within window */ | /* size within window */ | ||||
| float span_x = (ps->zoom * ibuf->x) / (float)ps->win_x; | float span_x = (ps->zoom * ibuf->x) / (float)ps->win_x; | ||||
| float span_y = (ps->zoom * ibuf->y) / (float)ps->win_y; | float span_y = (ps->zoom * ibuf->y) / (float)ps->win_y; | ||||
| /* offset within window */ | /* offset within window */ | ||||
| Show All 13 Lines | imm_draw_box_checker_2d_ex(offs_x, | ||||
| offs_y, | offs_y, | ||||
| offs_x + span_x, | offs_x + span_x, | ||||
| offs_y + span_y, | offs_y + span_y, | ||||
| (const float[4]){0.15, 0.15, 0.15, 1.0}, | (const float[4]){0.15, 0.15, 0.15, 1.0}, | ||||
| (const float[4]){0.20, 0.20, 0.20, 1.0}, | (const float[4]){0.20, 0.20, 0.20, 1.0}, | ||||
| 8); | 8); | ||||
| } | } | ||||
| IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); | draw_display_buffer(ibuf); | ||||
| immDrawPixelsTex(&state, | |||||
| offs_x + (ps->draw_flip[0] ? span_x : 0.0f), | |||||
| offs_y + (ps->draw_flip[1] ? span_y : 0.0f), | |||||
| ibuf->x, | |||||
| ibuf->y, | |||||
| GPU_RGBA8, | |||||
| false, | |||||
| ibuf->rect, | |||||
| ((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x), | |||||
| ((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y), | |||||
| NULL); | |||||
| GPU_blend(GPU_BLEND_NONE); | GPU_blend(GPU_BLEND_NONE); | ||||
| pupdate_time(); | pupdate_time(); | ||||
| if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) { | if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) { | ||||
| int sizex, sizey; | int sizex, sizey; | ||||
| float fsizex_inv, fsizey_inv; | float fsizex_inv, fsizey_inv; | ||||
| ▲ Show 20 Lines • Show All 1,304 Lines • Show Last 20 Lines | |||||
Can those be initialized only once?