/* Draw given image buffer on a screen using GLSL for display transform */ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings) { bool force_fallback = false; bool need_fallback = true; /* Early out */ if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; /* Dithering is not supported on GLSL yet */ force_fallback |= ibuf->dither != 0.0f; /* Single channel images could not be transformed using GLSL yet */ force_fallback |= ibuf->channels == 1; /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */ force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); /* This is actually lots of crap, but currently not sure about * more clear way to bypass partial buffer update crappyness * while rendering. * * The thing is -- render engines are only updating byte and * display buffers for active render result opened in image * editor. This works fine to show render progress without * switching render layers in image editor user, but this is * completely useless for GLSL display, where we need to have * original buffer which we could color manage. * * For the time of rendering, we'll stick back to slower CPU * display buffer update. GLSL could be used as soon as some * fixes (?) are done in render itself, so we'll always have * image buffer with relevant float buffer opened while * rendering. * * On the other hand, when using Cycles, stressing GPU with * GLSL could backfire on a performance. * - sergey - */ if (G.is_rendering) { /* Try to detect whether we're drawing render result, * other images could have both rect and rect_float * but they'll be synchronized */ if (ibuf->rect_float && ibuf->rect && ((ibuf->mall & IB_rectfloat) == 0)) { force_fallback = true; } } /* Try to draw buffer using GLSL display transform */ if (force_fallback == false) { int ok; if (ibuf->rect_float) { if (ibuf->float_colorspace) { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, ibuf->float_colorspace, TRUE); } else { ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, TRUE); } } else { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, ibuf->rect_colorspace, FALSE); } if (ok) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f(1.0, 1.0, 1.0, 1.0); if (ibuf->rect_float) { int format = 0; if (ibuf->channels == 3) format = GL_RGB; else if (ibuf->channels == 4) format = GL_RGBA; else BLI_assert(!"Incompatible number of channels for GLSL display"); if (format != 0) { glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT, zoomfilter, ibuf->rect_float); } } else if (ibuf->rect) { /* ibuf->rect is always RGBA */ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect); } IMB_colormanagement_finish_glsl_draw(); need_fallback = false; } } /* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */ if (need_fallback) { unsigned char *display_buffer; void *cache_handle; display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle); if (display_buffer) glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, display_buffer); IMB_display_buffer_release(cache_handle); } }
/* Draw given image buffer on a screen using GLSL for display transform */ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings) { bool force_fallback = false; bool need_fallback = true; /* Early out */ if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; /* Single channel images could not be transformed using GLSL yet */ force_fallback |= ibuf->channels == 1; /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */ force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); /* Try to draw buffer using GLSL display transform */ if (force_fallback == false) { int ok; if (ibuf->rect_float) { if (ibuf->float_colorspace) { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true); } else { ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, ibuf->dither, true); } } else { ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false); } if (ok) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f(1.0, 1.0, 1.0, 1.0); if (ibuf->rect_float) { int format = 0; if (ibuf->channels == 3) format = GL_RGB; else if (ibuf->channels == 4) format = GL_RGBA; else BLI_assert(!"Incompatible number of channels for GLSL display"); if (format != 0) { glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT, zoomfilter, ibuf->rect_float); } } else if (ibuf->rect) { /* ibuf->rect is always RGBA */ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect); } IMB_colormanagement_finish_glsl_draw(); need_fallback = false; } } /* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */ if (need_fallback) { unsigned char *display_buffer; void *cache_handle; display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle); if (display_buffer) glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, display_buffer); IMB_display_buffer_release(cache_handle); } }