Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_image/image_draw.c
| Show First 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | else if (channels >= 3) { | ||||
| BLF_position(blf_mono_font, dx, dy, 0); | BLF_position(blf_mono_font, dx, dy, 0); | ||||
| BLF_draw_ascii(blf_mono_font, str, sizeof(str)); | BLF_draw_ascii(blf_mono_font, str, sizeof(str)); | ||||
| dx += BLF_width(blf_mono_font, str, sizeof(str)); | dx += BLF_width(blf_mono_font, str, sizeof(str)); | ||||
| } | } | ||||
| (void)dx; | (void)dx; | ||||
| } | } | ||||
| /* Image drawing helpers. | |||||
| * | |||||
| * The idea here is following: we acquire all buffers and information which is | |||||
| * needed for actual drawing, cache it in the ImageDrawContext and release all | |||||
| * resources as soon as possible. | |||||
| * | |||||
| * For example, we can release lock of RenderResult once we've acquired display | |||||
| * buffer associated with this. This will allow render threads to keep writing | |||||
| * to render result without waiting drawing code to finish it's business. | |||||
| */ | |||||
| typedef struct ImageDrawContext { | |||||
| /* Context is sued for GLSL drawing. The lifetime of ImageDrawContext is | |||||
| * mush shorter than lifetime of bContext so there is nothing evil here. | |||||
| */ | |||||
| const bContext *C; | |||||
| /* Cached pointers from context for faster access later on.. */ | |||||
| Scene *scene; | |||||
| SpaceImage *sima; | |||||
| ARegion *ar; | |||||
| Image *image; | |||||
| /* Denotes whether lower image drawing routines will use GLSL for color | |||||
| * management. | |||||
| */ | |||||
| bool use_glsl_draw; | |||||
| /* Pointer to actual image buffer, used for following cases: | |||||
| * - GLSL color management. | |||||
| * - Drawing of alpha and Z buffer. | |||||
| * If it's non-NULL then the render result is locked. If the render result | |||||
| * is not needed for drawing,m then this pointer is set to NULL and none of | |||||
| * the image buffer locks is held while drawing. | |||||
| */ | |||||
| ImBuf *ibuf; | |||||
| void *ibuf_lock; | |||||
| /* Dimensions of the image buffer. Those can be accessed no matter whether | |||||
| * image buffer was released early on or not. | |||||
| */ | |||||
| int ibuf_width, ibuf_height; | |||||
| /* Pointer to a color managed display buffer. Used for following: | |||||
| * - Non-GLSL color management. | |||||
| * - Individual color channels drawing. | |||||
| */ | |||||
| unsigned char *display_buffer; | |||||
| void *cache_handle; | |||||
| } ImageDrawContext; | |||||
| /* Check whether drawing will be possible using GLSL, this includes both OpenGL | |||||
| * capabilities to perform GLSL color management and user preferences which | |||||
| * might or might not use GLSL image draw method. | |||||
| * | |||||
| * TODO(sergey): Do we need this type of check to happen in more centralized | |||||
| * place to avoid possible code divergence? | |||||
| */ | |||||
| static bool draw_image_use_glsl_draw(Scene *scene) | |||||
| { | |||||
| return IMB_colormanagement_support_glsl_draw(&scene->view_settings) && | |||||
| U.image_draw_method == IMAGE_DRAW_METHOD_GLSL; | |||||
| } | |||||
| /* Check whether CPU side display buffer is to be acquired and held for | |||||
| * image drawing. | |||||
| */ | |||||
| static bool draw_image_need_display_buffer(const ImageDrawContext *draw_ctx) | |||||
| { | |||||
| /* Tiled drawing performs magic on CPU side display buffer. | |||||
| * | |||||
| * NOTE: Keep in sync with draw_image_buffer_tiled(). | |||||
| */ | |||||
| if (draw_ctx->image != NULL && (draw_ctx->image->tpageflag & IMA_TILES)) { | |||||
| return true; | |||||
| } | |||||
| /* For GLSL color management we don't need to color manage anything on | |||||
| * CPU side. | |||||
| */ | |||||
| if (draw_ctx->use_glsl_draw) { | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /* Check whether ImageBuffer is to be held completely for drawing. */ | |||||
| static bool draw_image_need_imbuf(const ImageDrawContext *draw_ctx) | |||||
| { | |||||
| /* GLSL drawing will need to acquire "raw" buffer from image buffer. */ | |||||
| if (draw_ctx->use_glsl_draw) { | |||||
| return true; | |||||
| } | |||||
| /* Alpha drawing or Z buffer drawing will need access original buffers | |||||
| * as well. | |||||
| */ | |||||
| if (draw_ctx->sima->flag & SI_SHOW_ALPHA) { | |||||
| return true; | |||||
| } | |||||
| if (draw_ctx->sima->flag & SI_SHOW_ZBUF && | |||||
| (draw_ctx->ibuf->zbuf || | |||||
| draw_ctx->ibuf->zbuf_float || | |||||
| (draw_ctx->ibuf->channels == 1))) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| /* Metadata is also coming from original image buffer. | |||||
| * | |||||
| * TODO(sergey): Metadata is small, so we can make a copy from inside lock | |||||
| * and release image buffer after that. | |||||
| */ | |||||
| if (draw_ctx->sima->flag & SI_DRAW_METADATA) { | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| static bool draw_image_begin(const bContext *C, ARegion *ar, | |||||
| ImageDrawContext *draw_ctx) | |||||
| { | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| SpaceImage *sima = CTX_wm_space_image(C); | |||||
| Image *image = ED_space_image(sima); | |||||
| memset(draw_ctx, 0, sizeof(*draw_ctx)); | |||||
| /* Cache context, only used for GLSL drawing and lifetime of image draw | |||||
| * context is much smaller than lifetime of bContext, so it's all fine. | |||||
| */ | |||||
| draw_ctx->C = C; | |||||
| /* Cache commonly used pointers in all drawing functions. */ | |||||
| draw_ctx->scene = scene; | |||||
| draw_ctx->ar = ar; | |||||
| draw_ctx->sima = sima; | |||||
| draw_ctx->image = image; | |||||
| /* Keep this check first, used by other checks later on. */ | |||||
| draw_ctx->use_glsl_draw = draw_image_use_glsl_draw(scene); | |||||
| /* Acquire actual image buffer. | |||||
| * | |||||
| * NOTE: If image buffer is NULL we still need to release it's lock, that's | |||||
| * how API is supposed to be used. | |||||
| */ | |||||
| draw_ctx->ibuf = ED_space_image_acquire_buffer(draw_ctx->sima, | |||||
| &draw_ctx->ibuf_lock); | |||||
| if (draw_ctx->ibuf == NULL) { | |||||
| /* Indicate drawing routines that there is nothing to be displayed. */ | |||||
| return false; | |||||
| } | |||||
| /* Store image dimensions before possibly release the image buffer, so we | |||||
| * can access dimensions no matter what locks we released early on. | |||||
| */ | |||||
| draw_ctx->ibuf_width = draw_ctx->ibuf->x; | |||||
| draw_ctx->ibuf_height = draw_ctx->ibuf->y; | |||||
| /* Acquire display buffer and it's lock (if needed), hoping that it's the | |||||
| * only lock we meed to keep. | |||||
| */ | |||||
| if (draw_image_need_display_buffer(draw_ctx)) { | |||||
| draw_ctx->display_buffer = IMB_display_buffer_acquire_ctx( | |||||
| C, draw_ctx->ibuf, &draw_ctx->cache_handle); | |||||
| } | |||||
| /* Try to release image buffer (which keeps render result locked) as soon | |||||
| * as possible, allowing render threads to keep working. | |||||
| */ | |||||
| if (!draw_image_need_imbuf(draw_ctx)) { | |||||
| ED_space_image_release_buffer(draw_ctx->sima, | |||||
| draw_ctx->ibuf, | |||||
| draw_ctx->ibuf_lock); | |||||
| draw_ctx->ibuf_lock = NULL; | |||||
| draw_ctx->ibuf = NULL; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| static void draw_image_end(ImageDrawContext *draw_ctx) | |||||
| { | |||||
| /* Release all resources which were not releases early on. */ | |||||
| if (draw_ctx->ibuf_lock != NULL) { | |||||
| ED_space_image_release_buffer(draw_ctx->sima, | |||||
| draw_ctx->ibuf, | |||||
| draw_ctx->ibuf_lock); | |||||
| } | |||||
| if (draw_ctx->cache_handle != NULL) { | |||||
| IMB_display_buffer_release(draw_ctx->cache_handle); | |||||
| } | |||||
| } | |||||
| /* image drawing */ | /* image drawing */ | ||||
| static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti) | static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti) | ||||
| { | { | ||||
| /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ | /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ | ||||
| if (ENDIAN_ORDER == B_ENDIAN) | if (ENDIAN_ORDER == B_ENDIAN) | ||||
| glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); | glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | #ifdef __BIG_ENDIAN__ | ||||
| else return 2; | else return 2; | ||||
| #else | #else | ||||
| if (sima->flag & SI_SHOW_R) return 1; | if (sima->flag & SI_SHOW_R) return 1; | ||||
| else if (sima->flag & SI_SHOW_G) return 2; | else if (sima->flag & SI_SHOW_G) return 2; | ||||
| else return 3; | else return 3; | ||||
| #endif | #endif | ||||
| } | } | ||||
| static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy) | static void draw_image_buffer(ImageDrawContext *draw_ctx, | ||||
| float fx, float fy, | |||||
| float zoomx, float zoomy) | |||||
| { | { | ||||
| Scene *scene = draw_ctx->scene; | |||||
| SpaceImage *sima = draw_ctx->sima; | |||||
| ARegion *ar = draw_ctx->ar; | |||||
| ImBuf *ibuf = draw_ctx->ibuf; | |||||
| int x, y; | int x, y; | ||||
| /* set zoom */ | /* set zoom */ | ||||
| glPixelZoom(zoomx, zoomy); | glPixelZoom(zoomx, zoomy); | ||||
| glaDefine2DArea(&ar->winrct); | glaDefine2DArea(&ar->winrct); | ||||
| /* find window pixel coordinates of origin */ | /* find window pixel coordinates of origin */ | ||||
| Show All 13 Lines | else if (ibuf->zbuf_float) | ||||
| sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float); | sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float); | ||||
| else if (ibuf->channels == 1) | else if (ibuf->channels == 1) | ||||
| sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float); | sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float); | ||||
| } | } | ||||
| else { | else { | ||||
| if (sima->flag & SI_USE_ALPHA) { | if (sima->flag & SI_USE_ALPHA) { | ||||
| glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| fdrawcheckerboard(x, y, | |||||
| fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); | x + draw_ctx->ibuf_width * zoomx, | ||||
| y + draw_ctx->ibuf_height * zoomy); | |||||
| } | } | ||||
| if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) == 0) { | if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) == 0) { | ||||
| int clip_max_x, clip_max_y; | int clip_max_x, clip_max_y; | ||||
| UI_view2d_view_to_region(&ar->v2d, | UI_view2d_view_to_region(&ar->v2d, | ||||
| ar->v2d.cur.xmax, ar->v2d.cur.ymax, | ar->v2d.cur.xmax, ar->v2d.cur.ymax, | ||||
| &clip_max_x, &clip_max_y); | &clip_max_x, &clip_max_y); | ||||
| glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, GL_NEAREST, | if (draw_ctx->use_glsl_draw) { | ||||
| glaDrawImBuf_glsl_ctx_clipping(draw_ctx->C, ibuf, x, y, GL_NEAREST, | |||||
| 0, 0, clip_max_x, clip_max_y); | 0, 0, clip_max_x, clip_max_y); | ||||
| } | } | ||||
| else { | else { | ||||
| unsigned char *display_buffer; | glaDrawPixelsAuto_clipping( | ||||
| void *cache_handle; | x, y, | ||||
| draw_ctx->ibuf_width, draw_ctx->ibuf_height, | |||||
| /* TODO(sergey): Ideally GLSL shading should be capable of either | GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, | ||||
| * disabling some channels or displaying buffer with custom offset. | draw_ctx->display_buffer, | ||||
| */ | 0, 0, clip_max_x, clip_max_y); | ||||
| display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); | |||||
| if (display_buffer != NULL) { | |||||
| int channel_offset = draw_image_channel_offset(sima); | |||||
| glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_LUMINANCE, GL_UNSIGNED_INT, | |||||
| display_buffer - (4 - channel_offset)); | |||||
| } | } | ||||
| if (cache_handle != NULL) { | |||||
| IMB_display_buffer_release(cache_handle); | |||||
| } | } | ||||
| else { | |||||
| if (draw_ctx->display_buffer != NULL) { | |||||
| int channel_offset = draw_image_channel_offset(sima); | |||||
| glaDrawPixelsSafe(x, y, | |||||
| draw_ctx->ibuf_width, draw_ctx->ibuf_height, | |||||
| draw_ctx->ibuf_width, | |||||
| GL_LUMINANCE, GL_UNSIGNED_INT, | |||||
| draw_ctx->display_buffer - (4 - channel_offset)); | |||||
| } | } | ||||
| } | |||||
| if (sima->flag & SI_USE_ALPHA) | if (sima->flag & SI_USE_ALPHA) { | ||||
| glDisable(GL_BLEND); | glDisable(GL_BLEND); | ||||
| } | } | ||||
| } | |||||
| /* reset zoom */ | /* reset zoom */ | ||||
| glPixelZoom(1.0f, 1.0f); | glPixelZoom(1.0f, 1.0f); | ||||
| } | } | ||||
| static unsigned int *get_part_from_buffer(unsigned int *buffer, int width, short startx, short starty, short endx, short endy) | static unsigned int *get_part_from_buffer(unsigned int *buffer, int width, short startx, short starty, short endx, short endy) | ||||
| { | { | ||||
| unsigned int *rt, *rp, *rectmain; | unsigned int *rt, *rp, *rectmain; | ||||
| Show All 11 Lines | static unsigned int *get_part_from_buffer(unsigned int *buffer, int width, short startx, short starty, short endx, short endy) | ||||
| for (y = 0; y < heigth; y++) { | for (y = 0; y < heigth; y++) { | ||||
| memcpy(rp, rt, len * 4); | memcpy(rp, rt, len * 4); | ||||
| rt += width; | rt += width; | ||||
| rp += len; | rp += len; | ||||
| } | } | ||||
| return rectmain; | return rectmain; | ||||
| } | } | ||||
| static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy) | static void draw_image_buffer_tiled(ImageDrawContext *draw_ctx, | ||||
| float fx, float fy, | |||||
| float zoomx, float zoomy) | |||||
| { | { | ||||
| unsigned char *display_buffer; | const Image *image = draw_ctx->image; | ||||
| SpaceImage *sima = draw_ctx->sima; | |||||
| ARegion *ar = draw_ctx->ar; | |||||
| const int ibuf_width = draw_ctx->ibuf_width; | |||||
| const int ibuf_height = draw_ctx->ibuf_height; | |||||
| unsigned int *rect; | unsigned int *rect; | ||||
| int dx, dy, sx, sy, x, y; | int dx, dy, sx, sy, x, y; | ||||
| void *cache_handle; | |||||
| int channel_offset = -1; | int channel_offset = -1; | ||||
| /* verify valid values, just leave this a while */ | /* verify valid values, just leave this a while */ | ||||
| if (ima->xrep < 1) return; | if (image->xrep < 1) return; | ||||
| if (ima->yrep < 1) return; | if (image->yrep < 1) return; | ||||
| if (ima->flag & IMA_VIEW_AS_RENDER) | |||||
| display_buffer = IMB_display_buffer_acquire(ibuf, &scene->view_settings, &scene->display_settings, &cache_handle); | |||||
| else | |||||
| display_buffer = IMB_display_buffer_acquire(ibuf, NULL, &scene->display_settings, &cache_handle); | |||||
| if (!display_buffer) | const unsigned char *display_buffer = draw_ctx->display_buffer; | ||||
| if (display_buffer == NULL) { | |||||
| return; | return; | ||||
| } | |||||
| glPixelZoom(zoomx, zoomy); | glPixelZoom(zoomx, zoomy); | ||||
| if (sima->curtile >= ima->xrep * ima->yrep) | if (sima->curtile >= image->xrep * image->yrep) { | ||||
| sima->curtile = ima->xrep * ima->yrep - 1; | sima->curtile = image->xrep * image->yrep - 1; | ||||
| } | |||||
| /* retrieve part of image buffer */ | /* retrieve part of image buffer */ | ||||
| dx = max_ii(ibuf->x / ima->xrep, 1); | dx = max_ii(ibuf_width / image->xrep, 1); | ||||
| dy = max_ii(ibuf->y / ima->yrep, 1); | dy = max_ii(ibuf_height / image->yrep, 1); | ||||
| sx = (sima->curtile % ima->xrep) * dx; | sx = (sima->curtile % image->xrep) * dx; | ||||
| sy = (sima->curtile / ima->xrep) * dy; | sy = (sima->curtile / image->xrep) * dy; | ||||
| rect = get_part_from_buffer((unsigned int *)display_buffer, ibuf->x, sx, sy, sx + dx, sy + dy); | rect = get_part_from_buffer((unsigned int *)display_buffer, | ||||
| ibuf_width, sx, sy, sx + dx, sy + dy); | |||||
| /* draw repeated */ | /* draw repeated */ | ||||
| if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) != 0) { | if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B)) != 0) { | ||||
| channel_offset = draw_image_channel_offset(sima); | channel_offset = draw_image_channel_offset(sima); | ||||
| } | } | ||||
| for (sy = 0; sy + dy <= ibuf->y; sy += dy) { | for (sy = 0; sy + dy <= ibuf_height; sy += dy) { | ||||
| for (sx = 0; sx + dx <= ibuf->x; sx += dx) { | for (sx = 0; sx + dx <= ibuf_width; sx += dx) { | ||||
| UI_view2d_view_to_region(&ar->v2d, fx + (float)sx / (float)ibuf->x, fy + (float)sy / (float)ibuf->y, &x, &y); | UI_view2d_view_to_region(&ar->v2d, | ||||
| fx + (float)sx / (float)ibuf_width, | |||||
| fy + (float)sy / (float)ibuf_height, | |||||
| &x, &y); | |||||
| if (channel_offset == -1) { | if (channel_offset == -1) { | ||||
| glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect); | glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect); | ||||
| } | } | ||||
| else { | else { | ||||
| glaDrawPixelsSafe(x, y, dx, dy, dx, GL_LUMINANCE, GL_UNSIGNED_INT, | glaDrawPixelsSafe(x, y, dx, dy, dx, GL_LUMINANCE, GL_UNSIGNED_INT, | ||||
| (unsigned char *)rect - (4 - channel_offset)); | (unsigned char *)rect - (4 - channel_offset)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| glPixelZoom(1.0f, 1.0f); | glPixelZoom(1.0f, 1.0f); | ||||
| IMB_display_buffer_release(cache_handle); | |||||
| MEM_freeN(rect); | MEM_freeN(rect); | ||||
| } | } | ||||
| static void draw_image_buffer_repeated(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy) | static void draw_image_buffer_repeated(ImageDrawContext *draw_ctx, float zoomx, float zoomy) | ||||
| { | { | ||||
| const double time_current = PIL_check_seconds_timer(); | const double time_current = PIL_check_seconds_timer(); | ||||
| const Image *image = draw_ctx->image; | |||||
| const ARegion *ar = draw_ctx->ar; | |||||
| const int xmax = ceil(ar->v2d.cur.xmax); | const int xmax = ceil(ar->v2d.cur.xmax); | ||||
| const int ymax = ceil(ar->v2d.cur.ymax); | const int ymax = ceil(ar->v2d.cur.ymax); | ||||
| const int xmin = floor(ar->v2d.cur.xmin); | const int xmin = floor(ar->v2d.cur.xmin); | ||||
| const int ymin = floor(ar->v2d.cur.ymin); | const int ymin = floor(ar->v2d.cur.ymin); | ||||
| int x; | int x; | ||||
| for (x = xmin; x < xmax; x++) { | for (x = xmin; x < xmax; x++) { | ||||
| int y; | int y; | ||||
| for (y = ymin; y < ymax; y++) { | for (y = ymin; y < ymax; y++) { | ||||
| if (ima && (ima->tpageflag & IMA_TILES)) | if (image && (image->tpageflag & IMA_TILES)) { | ||||
| draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy); | draw_image_buffer_tiled(draw_ctx, x, y, zoomx, zoomy); | ||||
| else | } | ||||
| draw_image_buffer(C, sima, ar, scene, ibuf, x, y, zoomx, zoomy); | else { | ||||
| draw_image_buffer(draw_ctx, x, y, zoomx, zoomy); | |||||
| } | |||||
| /* only draw until running out of time */ | /* only draw until running out of time */ | ||||
| if ((PIL_check_seconds_timer() - time_current) > 0.25) | if ((PIL_check_seconds_timer() - time_current) > 0.25) | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | static void draw_image_paint_helpers(const bContext *C, ARegion *ar, Scene *scene, float zoomx, float zoomy) | ||||
| } | } | ||||
| } | } | ||||
| /* draw main image region */ | /* draw main image region */ | ||||
| void draw_image_main(const bContext *C, ARegion *ar) | void draw_image_main(const bContext *C, ARegion *ar) | ||||
| { | { | ||||
| SpaceImage *sima = CTX_wm_space_image(C); | SpaceImage *sima = CTX_wm_space_image(C); | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Image *ima; | Image *ima; | ||||
| ImBuf *ibuf; | |||||
| float zoomx, zoomy; | float zoomx, zoomy; | ||||
| bool show_viewer, show_render, show_paint, show_stereo3d, show_multilayer; | bool show_viewer, show_render, show_paint, show_stereo3d, show_multilayer; | ||||
| void *lock; | |||||
| /* XXX can we do this in refresh? */ | /* XXX can we do this in refresh? */ | ||||
| #if 0 | #if 0 | ||||
| what_image(sima); | what_image(sima); | ||||
| if (sima->image) { | if (sima->image) { | ||||
| ED_image_get_aspect(sima->image, &xuser_asp, &yuser_asp); | ED_image_get_aspect(sima->image, &xuser_asp, &yuser_asp); | ||||
| Show All 32 Lines | #endif | ||||
| if (show_stereo3d) { | if (show_stereo3d) { | ||||
| if (show_multilayer) | if (show_multilayer) | ||||
| /* update multiindex and pass for the current eye */ | /* update multiindex and pass for the current eye */ | ||||
| BKE_image_multilayer_index(ima->rr, &sima->iuser); | BKE_image_multilayer_index(ima->rr, &sima->iuser); | ||||
| else | else | ||||
| BKE_image_multiview_index(ima, &sima->iuser); | BKE_image_multiview_index(ima, &sima->iuser); | ||||
| } | } | ||||
| ibuf = ED_space_image_acquire_buffer(sima, &lock); | ImageDrawContext draw_ctx; | ||||
| /* draw the image or grid */ | /* draw the image or grid */ | ||||
| if (ibuf == NULL) { | if (!draw_image_begin(C, ar, &draw_ctx)) { | ||||
| ED_region_grid_draw(ar, zoomx, zoomy); | ED_region_grid_draw(ar, zoomx, zoomy); | ||||
| } | } | ||||
| else { | else { | ||||
| if (sima->flag & SI_DRAW_TILE) { | |||||
| if (sima->flag & SI_DRAW_TILE) | draw_image_buffer_repeated(&draw_ctx, zoomx, zoomy); | ||||
| draw_image_buffer_repeated(C, sima, ar, scene, ima, ibuf, zoomx, zoomy); | } | ||||
| else if (ima && (ima->tpageflag & IMA_TILES)) | else if (ima && (ima->tpageflag & IMA_TILES)) { | ||||
| draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy); | draw_image_buffer_tiled(&draw_ctx, 0.0f, 0.0, zoomx, zoomy); | ||||
| else | } | ||||
| draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy); | else { | ||||
| draw_image_buffer(&draw_ctx, 0.0f, 0.0f, zoomx, zoomy); | |||||
| } | |||||
| if (sima->flag & SI_DRAW_METADATA) { | if (sima->flag & SI_DRAW_METADATA) { | ||||
| int x, y; | int x, y; | ||||
| rctf frame; | rctf frame; | ||||
| BLI_rctf_init(&frame, 0.0f, ibuf->x, 0.0f, ibuf->y); | BLI_rctf_init(&frame, 0.0f, draw_ctx.ibuf_width, 0.0f, | ||||
| draw_ctx.ibuf_height); | |||||
| UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y); | UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y); | ||||
| ED_region_image_metadata_draw(x, y, ibuf, &frame, zoomx, zoomy); | ED_region_image_metadata_draw(x, y, draw_ctx.ibuf, &frame, zoomx, zoomy); | ||||
| } | } | ||||
| } | } | ||||
| ED_space_image_release_buffer(sima, ibuf, lock); | draw_image_end(&draw_ctx); | ||||
| /* paint helpers */ | /* paint helpers */ | ||||
| if (show_paint) | if (show_paint) { | ||||
| draw_image_paint_helpers(C, ar, scene, zoomx, zoomy); | draw_image_paint_helpers(C, ar, CTX_data_scene(C), zoomx, zoomy); | ||||
| } | |||||
| /* XXX integrate this code */ | /* XXX integrate this code */ | ||||
| #if 0 | #if 0 | ||||
| if (ibuf) { | if (ibuf) { | ||||
| float xoffs = 0.0f, yoffs = 0.0f; | float xoffs = 0.0f, yoffs = 0.0f; | ||||
| if (image_preview_active(sa, &xim, &yim)) { | if (image_preview_active(sa, &xim, &yim)) { | ||||
| xoffs = scene->r.disprect.xmin; | xoffs = scene->r.disprect.xmin; | ||||
| ▲ Show 20 Lines • Show All 79 Lines • Show Last 20 Lines | |||||