GPU: Rename GPU_shader_get_uniform to GPU_shader_get_uniform_ensure
[blender.git] / source / blender / editors / space_image / image_draw.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2009
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_image/image_draw.c
27  *  \ingroup spimage
28  */
29
30
31 #include <math.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_camera_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_space_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_screen_types.h"
42 #include "DNA_brush_types.h"
43 #include "DNA_mask_types.h"
44
45 #include "PIL_time.h"
46
47 #include "BLI_math.h"
48 #include "BLI_rect.h"
49 #include "BLI_threads.h"
50 #include "BLI_string.h"
51 #include "BLI_utildefines.h"
52
53 #include "IMB_imbuf.h"
54 #include "IMB_imbuf_types.h"
55 #include "IMB_colormanagement.h"
56 #include "IMB_moviecache.h"
57
58 #include "BKE_context.h"
59 #include "BKE_global.h"
60 #include "BKE_image.h"
61 #include "BKE_paint.h"
62
63 #include "BIF_glutil.h"
64
65 #include "GPU_immediate.h"
66 #include "GPU_immediate_util.h"
67 #include "GPU_matrix.h"
68 #include "GPU_state.h"
69
70 #include "BLF_api.h"
71
72 #include "ED_gpencil.h"
73 #include "ED_image.h"
74 #include "ED_mask.h"
75 #include "ED_render.h"
76 #include "ED_screen.h"
77
78 #include "UI_interface.h"
79 #include "UI_resources.h"
80 #include "UI_view2d.h"
81
82 #include "RE_pipeline.h"
83 #include "RE_engine.h"
84
85 #include "image_intern.h"
86
87 static void draw_render_info(const bContext *C,
88                              Scene *scene,
89                              Image *ima,
90                              ARegion *ar,
91                              float zoomx,
92                              float zoomy)
93 {
94         Render *re = RE_GetSceneRender(scene);
95         RenderData *rd = RE_engine_get_render_data(re);
96         Scene *stats_scene = ED_render_job_get_scene(C);
97         if (stats_scene == NULL) {
98                 stats_scene = CTX_data_scene(C);
99         }
100
101         RenderResult *rr = BKE_image_acquire_renderresult(stats_scene, ima);
102
103         if (rr && rr->text) {
104                 float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
105                 ED_region_info_draw(ar, rr->text, fill_color, true);
106         }
107
108         BKE_image_release_renderresult(stats_scene, ima);
109
110         if (re) {
111                 int total_tiles;
112                 bool need_free_tiles;
113                 rcti *tiles = RE_engine_get_current_tiles(re, &total_tiles, &need_free_tiles);
114
115                 if (total_tiles) {
116                         /* find window pixel coordinates of origin */
117                         int x, y;
118                         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
119
120                         GPU_matrix_push();
121                         GPU_matrix_translate_2f(x, y);
122                         GPU_matrix_scale_2f(zoomx, zoomy);
123
124                         if (rd->mode & R_BORDER) {
125                                 /* TODO: round or floor instead of casting to int */
126                                 GPU_matrix_translate_2f((int)(-rd->border.xmin * rd->xsch * rd->size * 0.01f),
127                                                (int)(-rd->border.ymin * rd->ysch * rd->size * 0.01f));
128                         }
129
130                         uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
131                         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
132                         immUniformThemeColor(TH_FACE_SELECT);
133
134                         GPU_line_width(1.0f);
135
136                         rcti *tile = tiles;
137                         for (int i = 0; i < total_tiles; i++, tile++) {
138                                 immDrawBorderCorners(pos, tile, zoomx, zoomy);
139                         }
140
141                         immUnbindProgram();
142
143                         if (need_free_tiles) {
144                                 MEM_freeN(tiles);
145                         }
146
147                         GPU_matrix_pop();
148                 }
149         }
150 }
151
152 /* used by node view too */
153 void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y,
154                         const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf)
155 {
156         rcti color_rect;
157         char str[256];
158         int dx = 6;
159         const int dy = 0.3f * UI_UNIT_Y;
160         /* text colors */
161         /* XXX colored text not allowed in Blender UI */
162 #if 0
163         unsigned char red[3] = {255, 50, 50};
164         unsigned char green[3] = {0, 255, 0};
165         unsigned char blue[3] = {100, 100, 255};
166 #else
167         unsigned char red[3] = {255, 255, 255};
168         unsigned char green[3] = {255, 255, 255};
169         unsigned char blue[3] = {255, 255, 255};
170 #endif
171         float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
172         float col[4], finalcol[4];
173
174         GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
175         GPU_blend(true);
176
177         uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
178         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
179
180         /* noisy, high contrast make impossible to read if lower alpha is used. */
181         immUniformColor4ub(0, 0, 0, 190);
182         immRecti(pos, 0, 0, BLI_rcti_size_x(&ar->winrct) + 1, UI_UNIT_Y);
183
184         immUnbindProgram();
185
186         GPU_blend(false);
187
188         BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi);
189
190         BLF_color3ub(blf_mono_font, 255, 255, 255);
191         BLI_snprintf(str, sizeof(str), "X:%-4d  Y:%-4d |", x, y);
192         BLF_position(blf_mono_font, dx, dy, 0);
193         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
194         dx += BLF_width(blf_mono_font, str, sizeof(str));
195
196         if (zp) {
197                 BLF_color3ub(blf_mono_font, 255, 255, 255);
198                 BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff));
199                 BLF_position(blf_mono_font, dx, dy, 0);
200                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
201                 dx += BLF_width(blf_mono_font, str, sizeof(str));
202         }
203         if (zpf) {
204                 BLF_color3ub(blf_mono_font, 255, 255, 255);
205                 BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
206                 BLF_position(blf_mono_font, dx, dy, 0);
207                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
208                 dx += BLF_width(blf_mono_font, str, sizeof(str));
209         }
210
211         if (channels == 1 && (cp != NULL || fp != NULL)) {
212                 if (fp != NULL) {
213                         BLI_snprintf(str, sizeof(str), " Val:%-.3f |", fp[0]);
214                 }
215                 else if (cp != NULL) {
216                         BLI_snprintf(str, sizeof(str), " Val:%-.3f |", cp[0] / 255.0f);
217                 }
218                 BLF_color3ub(blf_mono_font, 255, 255, 255);
219                 BLF_position(blf_mono_font, dx, dy, 0);
220                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
221                 dx += BLF_width(blf_mono_font, str, sizeof(str));
222         }
223
224         if (channels >= 3) {
225                 BLF_color3ubv(blf_mono_font, red);
226                 if (fp)
227                         BLI_snprintf(str, sizeof(str), "  R:%-.5f", fp[0]);
228                 else if (cp)
229                         BLI_snprintf(str, sizeof(str), "  R:%-3d", cp[0]);
230                 else
231                         BLI_snprintf(str, sizeof(str), "  R:-");
232                 BLF_position(blf_mono_font, dx, dy, 0);
233                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
234                 dx += BLF_width(blf_mono_font, str, sizeof(str));
235
236                 BLF_color3ubv(blf_mono_font, green);
237                 if (fp)
238                         BLI_snprintf(str, sizeof(str), "  G:%-.5f", fp[1]);
239                 else if (cp)
240                         BLI_snprintf(str, sizeof(str), "  G:%-3d", cp[1]);
241                 else
242                         BLI_snprintf(str, sizeof(str), "  G:-");
243                 BLF_position(blf_mono_font, dx, dy, 0);
244                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
245                 dx += BLF_width(blf_mono_font, str, sizeof(str));
246
247                 BLF_color3ubv(blf_mono_font, blue);
248                 if (fp)
249                         BLI_snprintf(str, sizeof(str), "  B:%-.5f", fp[2]);
250                 else if (cp)
251                         BLI_snprintf(str, sizeof(str), "  B:%-3d", cp[2]);
252                 else
253                         BLI_snprintf(str, sizeof(str), "  B:-");
254                 BLF_position(blf_mono_font, dx, dy, 0);
255                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
256                 dx += BLF_width(blf_mono_font, str, sizeof(str));
257
258                 if (channels == 4) {
259                         BLF_color3ub(blf_mono_font, 255, 255, 255);
260                         if (fp)
261                                 BLI_snprintf(str, sizeof(str), "  A:%-.4f", fp[3]);
262                         else if (cp)
263                                 BLI_snprintf(str, sizeof(str), "  A:%-3d", cp[3]);
264                         else
265                                 BLI_snprintf(str, sizeof(str), "- ");
266                         BLF_position(blf_mono_font, dx, dy, 0);
267                         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
268                         dx += BLF_width(blf_mono_font, str, sizeof(str));
269                 }
270
271                 if (color_manage) {
272                         float rgba[4];
273
274                         copy_v3_v3(rgba, linearcol);
275                         if (channels == 3)
276                                 rgba[3] = 1.0f;
277                         else
278                                 rgba[3] = linearcol[3];
279
280                         if (use_default_view)
281                                 IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, NULL, &scene->display_settings);
282                         else
283                                 IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, &scene->view_settings, &scene->display_settings);
284
285                         BLI_snprintf(str, sizeof(str), "  |  CM  R:%-.4f  G:%-.4f  B:%-.4f", rgba[0], rgba[1], rgba[2]);
286                         BLF_position(blf_mono_font, dx, dy, 0);
287                         BLF_draw_ascii(blf_mono_font, str, sizeof(str));
288                         dx += BLF_width(blf_mono_font, str, sizeof(str));
289                 }
290         }
291
292         /* color rectangle */
293         if (channels == 1) {
294                 if (fp) {
295                         col[0] = col[1] = col[2] = fp[0];
296                 }
297                 else if (cp) {
298                         col[0] = col[1] = col[2] = (float)cp[0] / 255.0f;
299                 }
300                 else {
301                         col[0] = col[1] = col[2] = 0.0f;
302                 }
303                 col[3] = 1.0f;
304         }
305         else if (channels == 3) {
306                 copy_v3_v3(col, linearcol);
307                 col[3] = 1.0f;
308         }
309         else if (channels == 4) {
310                 copy_v4_v4(col, linearcol);
311         }
312         else {
313                 BLI_assert(0);
314                 zero_v4(col);
315         }
316
317         if (color_manage) {
318                 if (use_default_view)
319                         IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, NULL, &scene->display_settings);
320                 else
321                         IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, &scene->view_settings, &scene->display_settings);
322         }
323         else {
324                 copy_v4_v4(finalcol, col);
325         }
326
327         GPU_blend(false);
328         dx += 0.25f * UI_UNIT_X;
329
330         BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y);
331
332         /* BLF uses immediate mode too, so we must reset our vertex format */
333         pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
334         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
335
336         if (channels == 4) {
337                 rcti color_rect_half;
338                 int color_quater_x, color_quater_y;
339
340                 color_rect_half = color_rect;
341                 color_rect_half.xmax = BLI_rcti_cent_x(&color_rect);
342                 /* what color ??? */
343                 immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
344
345                 color_rect_half = color_rect;
346                 color_rect_half.xmin = BLI_rcti_cent_x(&color_rect);
347
348                 color_quater_x = BLI_rcti_cent_x(&color_rect_half);
349                 color_quater_y = BLI_rcti_cent_y(&color_rect_half);
350
351                 immUniformColor3ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK);
352                 immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_rect_half.xmax, color_rect_half.ymax);
353
354                 immUniformColor3ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT);
355                 immRecti(pos, color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax);
356                 immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y);
357
358                 GPU_blend(true);
359                 immUniformColor3fvAlpha(finalcol, fp ? fp[3] : (cp[3] / 255.0f));
360                 immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
361                 GPU_blend(false);
362         }
363         else {
364                 immUniformColor3fv(finalcol);
365                 immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
366         }
367         immUnbindProgram();
368
369         /* draw outline */
370         pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
371         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
372         immUniformColor3ub(128, 128, 128);
373         imm_draw_box_wire_2d(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
374         immUnbindProgram();
375
376         dx += 1.75f * UI_UNIT_X;
377
378         BLF_color3ub(blf_mono_font, 255, 255, 255);
379         if (channels == 1) {
380                 if (fp) {
381                         rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
382                         rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v, BLI_YUV_ITU_BT709);
383                 }
384                 else if (cp) {
385                         rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val);
386                         rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v, BLI_YUV_ITU_BT709);
387                 }
388
389                 BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
390                 BLF_position(blf_mono_font, dx, dy, 0);
391                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
392                 dx += BLF_width(blf_mono_font, str, sizeof(str));
393
394                 BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
395                 BLF_position(blf_mono_font, dx, dy, 0);
396                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
397         }
398         else if (channels >= 3) {
399                 rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val);
400                 rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v, BLI_YUV_ITU_BT709);
401
402                 BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
403                 BLF_position(blf_mono_font, dx, dy, 0);
404                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
405                 dx += BLF_width(blf_mono_font, str, sizeof(str));
406
407                 BLI_snprintf(str, sizeof(str), "  S:%-.4f", sat);
408                 BLF_position(blf_mono_font, dx, dy, 0);
409                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
410                 dx += BLF_width(blf_mono_font, str, sizeof(str));
411
412                 BLI_snprintf(str, sizeof(str), "  V:%-.4f", val);
413                 BLF_position(blf_mono_font, dx, dy, 0);
414                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
415                 dx += BLF_width(blf_mono_font, str, sizeof(str));
416
417                 BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
418                 BLF_position(blf_mono_font, dx, dy, 0);
419                 BLF_draw_ascii(blf_mono_font, str, sizeof(str));
420         }
421 }
422
423 /* image drawing */
424 static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *rect,
425                                   float zoomx, float zoomy)
426 {
427         float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
428
429         /* Slowwww */
430         int *recti = MEM_mallocN(rectx * recty * sizeof(int), "temp");
431         for (int a = rectx * recty - 1; a >= 0; a--) {
432                 /* zbuffer values are signed, so we need to shift color range */
433                 recti[a] = rect[a] * 0.5f + 0.5f;
434         }
435
436         IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
437         GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform_ensure(state.shader, "shuffle"), 4, 1, red);
438
439         immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_RED, GL_INT, GL_NEAREST, recti, zoomx, zoomy, NULL);
440
441         MEM_freeN(recti);
442 }
443
444 static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rectx, int recty,
445                                        float *rect_float, float zoomx, float zoomy)
446 {
447         float bias, scale, *rectf, clipend;
448         int a;
449         float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
450
451         if (scene->camera && scene->camera->type == OB_CAMERA) {
452                 bias = ((Camera *)scene->camera->data)->clipsta;
453                 clipend = ((Camera *)scene->camera->data)->clipend;
454                 scale = 1.0f / (clipend - bias);
455         }
456         else {
457                 bias = 0.1f;
458                 scale = 0.01f;
459                 clipend = 100.0f;
460         }
461
462         rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp");
463         for (a = rectx * recty - 1; a >= 0; a--) {
464                 if (rect_float[a] > clipend)
465                         rectf[a] = 0.0f;
466                 else if (rect_float[a] < bias)
467                         rectf[a] = 1.0f;
468                 else {
469                         rectf[a] = 1.0f - (rect_float[a] - bias) * scale;
470                         rectf[a] *= rectf[a];
471                 }
472         }
473
474         IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
475         GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform_ensure(state.shader, "shuffle"), 4, 1, red);
476
477         immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_RED, GL_FLOAT, GL_NEAREST, rectf, zoomx, zoomy, NULL);
478
479         MEM_freeN(rectf);
480 }
481
482 static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
483 {
484         int x, y;
485
486         /* find window pixel coordinates of origin */
487         UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y);
488
489         /* this part is generic image display */
490         if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
491                 if (ibuf->zbuf)
492                         sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf, zoomx, zoomy);
493                 else if (ibuf->zbuf_float)
494                         sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float, zoomx, zoomy);
495                 else if (ibuf->channels == 1)
496                         sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float, zoomx, zoomy);
497         }
498         else {
499                 int clip_max_x, clip_max_y;
500                 UI_view2d_view_to_region(&ar->v2d,
501                                          ar->v2d.cur.xmax, ar->v2d.cur.ymax,
502                                          &clip_max_x, &clip_max_y);
503
504                 if (sima->flag & SI_USE_ALPHA) {
505                         imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
506
507                         GPU_blend(true);
508                         GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
509                 }
510
511                 /* If RGBA display with color management */
512                 if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
513
514                         glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, GL_NEAREST,
515                                                        0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
516                 }
517                 else {
518                         float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
519                         unsigned char *display_buffer;
520                         void *cache_handle;
521                         ColorManagedViewSettings *view_settings;
522                         ColorManagedDisplaySettings *display_settings;
523
524                         if (sima->flag & SI_SHOW_R)
525                                 shuffle[0] = 1.0f;
526                         else if (sima->flag & SI_SHOW_G)
527                                 shuffle[1] = 1.0f;
528                         else if (sima->flag & SI_SHOW_B)
529                                 shuffle[2] = 1.0f;
530                         else if (sima->flag & SI_SHOW_ALPHA)
531                                 shuffle[3] = 1.0f;
532
533                         IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
534                         GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform_ensure(state.shader, "shuffle"), 4, 1, shuffle);
535
536                         IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
537                         display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);
538
539                         if (display_buffer) {
540                                 immDrawPixelsTex_clipping(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer,
541                                                           0, 0, clip_max_x, clip_max_y, zoomx, zoomy, NULL);
542                         }
543
544                         IMB_display_buffer_release(cache_handle);
545                 }
546
547                 if (sima->flag & SI_USE_ALPHA)
548                         GPU_blend(false);
549         }
550 }
551
552 static void draw_image_buffer_repeated(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float zoomx, float zoomy)
553 {
554         const double time_current = PIL_check_seconds_timer();
555
556         const int xmax = ceil(ar->v2d.cur.xmax);
557         const int ymax = ceil(ar->v2d.cur.ymax);
558         const int xmin = floor(ar->v2d.cur.xmin);
559         const int ymin = floor(ar->v2d.cur.ymin);
560
561         for (int x = xmin; x < xmax; x++) {
562                 for (int y = ymin; y < ymax; y++) {
563                         draw_image_buffer(C, sima, ar, scene, ibuf, x, y, zoomx, zoomy);
564
565                         /* only draw until running out of time */
566                         if ((PIL_check_seconds_timer() - time_current) > 0.25)
567                                 return;
568                 }
569         }
570 }
571
572 /* draw uv edit */
573
574 /* draw grease pencil */
575 void draw_image_grease_pencil(bContext *C, bool onlyv2d)
576 {
577         /* draw in View2D space? */
578         if (onlyv2d) {
579                 /* draw grease-pencil ('image' strokes) */
580                 ED_gpencil_draw_2dimage(C);
581         }
582         else {
583                 /* assume that UI_view2d_restore(C) has been called... */
584                 //SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
585
586                 /* draw grease-pencil ('screen' strokes) */
587                 ED_gpencil_draw_view2d(C, 0);
588         }
589 }
590
591 void draw_image_sample_line(SpaceImage *sima)
592 {
593         if (sima->sample_line_hist.flag & HISTO_FLAG_SAMPLELINE) {
594                 Histogram *hist = &sima->sample_line_hist;
595
596                 GPUVertFormat *format = immVertexFormat();
597                 uint shdr_dashed_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
598
599                 immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
600
601                 float viewport_size[4];
602                 GPU_viewport_size_get_f(viewport_size);
603                 immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
604
605                 immUniform1i("colors_len", 2);  /* Advanced dashes. */
606                 immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
607                 immUniform1f("dash_width", 2.0f);
608
609                 immBegin(GPU_PRIM_LINES, 2);
610                 immVertex2fv(shdr_dashed_pos, hist->co[0]);
611                 immVertex2fv(shdr_dashed_pos, hist->co[1]);
612                 immEnd();
613
614                 immUnbindProgram();
615         }
616 }
617
618 static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scene, float zoomx, float zoomy)
619 {
620         Brush *brush;
621         int x, y;
622         ImBuf *ibuf;
623
624         brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint);
625
626         if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE) && brush->clone.image) {
627                 ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL);
628
629                 if (ibuf) {
630                         void *cache_handle = NULL;
631                         float col[4] = {1.0f, 1.0f, 1.0f, brush->clone.alpha};
632                         UI_view2d_view_to_region(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
633
634                         unsigned char *display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
635
636                         if (!display_buffer) {
637                                 BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
638                                 IMB_display_buffer_release(cache_handle);
639                                 return;
640                         }
641
642                         GPU_blend(true);
643                         GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
644
645                         IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
646                         immDrawPixelsTex(&state, x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer, zoomx, zoomy, col);
647
648                         GPU_blend(false);
649
650                         BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
651                         IMB_display_buffer_release(cache_handle);
652                 }
653         }
654 }
655
656 /* draw main image region */
657
658 void draw_image_main(const bContext *C, ARegion *ar)
659 {
660         SpaceImage *sima = CTX_wm_space_image(C);
661         Scene *scene = CTX_data_scene(C);
662         Image *ima;
663         ImBuf *ibuf;
664         float zoomx, zoomy;
665         bool show_viewer, show_render, show_paint, show_stereo3d, show_multilayer;
666         void *lock;
667
668         /* XXX can we do this in refresh? */
669 #if 0
670         what_image(sima);
671
672         if (sima->image) {
673                 ED_image_get_aspect(sima->image, &xuser_asp, &yuser_asp);
674
675                 /* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */
676                 if (sima->image->type == IMA_TYPE_COMPOSITE) {
677                         ImageUser *iuser = ntree_get_active_iuser(scene->nodetree);
678                         if (iuser) {
679                                 BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0);
680                                 sima->iuser = *iuser;
681                         }
682                 }
683                 /* and we check for spare */
684                 ibuf = ED_space_image_buffer(sima);
685         }
686 #endif
687
688         /* retrieve the image and information about it */
689         ima = ED_space_image(sima);
690         ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
691
692         show_viewer = (ima && ima->source == IMA_SRC_VIEWER) != 0;
693         show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT) != 0;
694         show_paint = (ima && (sima->mode == SI_MODE_PAINT) && (show_viewer == false) && (show_render == false));
695         show_stereo3d = (ima && BKE_image_is_stereo(ima) && (sima->iuser.flag & IMA_SHOW_STEREO));
696         show_multilayer = ima && BKE_image_is_multilayer(ima);
697
698         if (show_viewer) {
699                 /* use locked draw for drawing viewer image buffer since the compositor
700                  * is running in separated thread and compositor could free this buffers.
701                  * other images are not modifying in such a way so they does not require
702                  * lock (sergey)
703                  */
704                 BLI_thread_lock(LOCK_DRAW_IMAGE);
705         }
706
707         if (show_stereo3d) {
708                 if (show_multilayer)
709                         /* update multiindex and pass for the current eye */
710                         BKE_image_multilayer_index(ima->rr, &sima->iuser);
711                 else
712                         BKE_image_multiview_index(ima, &sima->iuser);
713         }
714
715         ibuf = ED_space_image_acquire_buffer(sima, &lock);
716
717         /* draw the image or grid */
718         if (ibuf == NULL) {
719                 ED_region_grid_draw(ar, zoomx, zoomy);
720         }
721         else {
722                 if (sima->flag & SI_DRAW_TILE)
723                         draw_image_buffer_repeated(C, sima, ar, scene, ibuf, zoomx, zoomy);
724                 else
725                         draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy);
726
727                 if (sima->flag & SI_DRAW_METADATA) {
728                         int x, y;
729                         rctf frame;
730
731                         BLI_rctf_init(&frame, 0.0f, ibuf->x, 0.0f, ibuf->y);
732                         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
733
734                         ED_region_image_metadata_draw(x, y, ibuf, &frame, zoomx, zoomy);
735                 }
736         }
737
738         ED_space_image_release_buffer(sima, ibuf, lock);
739
740         /* paint helpers */
741         if (show_paint)
742                 draw_image_paint_helpers(C, ar, scene, zoomx, zoomy);
743
744         if (show_viewer) {
745                 BLI_thread_unlock(LOCK_DRAW_IMAGE);
746         }
747
748         /* render info */
749         if (ima && show_render)
750                 draw_render_info(C, sima->iuser.scene, ima, ar, zoomx, zoomy);
751 }
752
753 bool ED_space_image_show_cache(SpaceImage *sima)
754 {
755         Image *image = ED_space_image(sima);
756         Mask *mask = NULL;
757         if (sima->mode == SI_MODE_MASK) {
758                 mask = ED_space_image_get_mask(sima);
759         }
760         if (image == NULL && mask == NULL) {
761                 return false;
762         }
763         if (mask == NULL) {
764                 return ELEM(image->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE);
765         }
766         return true;
767 }
768
769 void draw_image_cache(const bContext *C, ARegion *ar)
770 {
771         SpaceImage *sima = CTX_wm_space_image(C);
772         Scene *scene = CTX_data_scene(C);
773         Image *image = ED_space_image(sima);
774         float x, cfra = CFRA, sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
775         Mask *mask = NULL;
776
777         if (!ED_space_image_show_cache(sima)) {
778                 return;
779         }
780
781         if (sima->mode == SI_MODE_MASK) {
782                 mask = ED_space_image_get_mask(sima);
783         }
784
785         GPU_blend(true);
786         GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
787
788         /* Draw cache background. */
789         ED_region_cache_draw_background(ar);
790
791         /* Draw cached segments. */
792         if (image != NULL && image->cache != NULL && ELEM(image->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
793                 int num_segments = 0;
794                 int *points = NULL;
795
796                 IMB_moviecache_get_cache_segments(image->cache, IMB_PROXY_NONE, 0, &num_segments, &points);
797                 ED_region_cache_draw_cached_segments(ar, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset);
798         }
799
800         GPU_blend(false);
801
802         /* Draw current frame. */
803         x = (cfra - sfra) / (efra - sfra + 1) * ar->winx;
804
805         uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
806         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
807         immUniformThemeColor(TH_CFRAME);
808         immRecti(pos, x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
809         immUnbindProgram();
810
811         ED_region_cache_draw_curfra_label(cfra, x, 8.0f * UI_DPI_FAC);
812
813         if (mask != NULL) {
814                 ED_mask_draw_frames(mask, ar, cfra, sfra, efra);
815         }
816 }