Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-03-29 20:02:27 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-03-29 20:02:27 +0400
commit2dff7c01ada2a645d39c2acdc83a10e4a295b35b (patch)
treeb68b29a7488b500b8beca2961685badfaf83952f /source/blender/editors/space_clip
parent44a43afd0e858a8a3d563ff0a1a7b6b8043bd8f3 (diff)
Implement GPU-side display transform for clip editor
Implemented using GLSL API from OpenColorIO library and some general functions were added to it's c-api: - OCIO_setupGLSLDraw prepares OpenGL context for GPU-based transformation for a giver processor. This function compiles and links shader, sets up it's argument. After this transformation would be applied on an image displaying as a 2D texture. So, glaDrawPixelsTex called after OCIO_setupGLSLDraw will do a proper color space transform. - OCIO_finishGLSLDraw restores OpenGL context after all color-managed display is over. - OCIO_freeOGLState frees allocated state structure used for cacheing some GLSL-related stuff. There're some utility functions in IMB_colormanagent which are basically proxies to lower level OCIO functions but which could be used from any place in blender. Chacheing of movie clip frame on GPU is also removed now, and either glaDrawPixelsTex or glaDrawPixelsAuto are used for display now. This is so no code duplication happens now and no large textures are lurking around in GPU memory. Known issues: - Texture buffer and GLSL are no longer checking for video card capabilities, possibly could lead to some artifacts on crappy drivers/cards. - Only float buffers are displaying using GLSL, byte buffers will still use fallback display method. This is to be addressed later. - If RGB curves are used as a part of display transform, GLSL display will also be disabled. This is also thing to be solved later. Additional changes: - glaDrawPixelsTexScaled will now use RGBA16F as an internal format of storing textures when it's used to draw float buffer. This is needed so LUT are applied without precision loss.
Diffstat (limited to 'source/blender/editors/space_clip')
-rw-r--r--source/blender/editors/space_clip/clip_draw.c113
-rw-r--r--source/blender/editors/space_clip/clip_editor.c161
-rw-r--r--source/blender/editors/space_clip/space_clip.c3
3 files changed, 66 insertions, 211 deletions
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 2d3dc9127c3..cbca2f0c46e 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -248,6 +248,53 @@ static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
ED_region_info_draw(ar, str, block, 0.6f);
}
+static void draw_movieclip_buffer_glsl(SpaceClip *sc, ImBuf *ibuf, int x, int y,
+ float zoomx, float zoomy)
+{
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ int filter = GL_LINEAR;
+
+ glPushMatrix();
+ glTranslatef(x, y, 0.0f);
+ glScalef(zoomx, zoomy, 1.0f);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ /* non-scaled proxy shouldn;t use diltering */
+ if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
+ ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
+ {
+ filter = GL_NEAREST;
+ }
+
+ glaDrawPixelsTex(0, 0, ibuf->x, ibuf->y, GL_FLOAT, filter, ibuf->rect_float);
+
+ glPopMatrix();
+}
+
+static void draw_movieclip_buffer_fallback(const bContext *C, ImBuf *ibuf, int x, int y,
+ int width, int height, float zoomx, float zoomy)
+{
+ unsigned char *display_buffer;
+ void *cache_handle;
+
+ display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+
+ if (display_buffer) {
+ /* set zoom */
+ glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
+
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
+
+ /* reset zoom */
+ glPixelZoom(1.0f, 1.0f);
+ }
+
+ IMB_display_buffer_release(cache_handle);
+}
+
static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
int width, int height, float zoomx, float zoomy)
{
@@ -261,62 +308,32 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
glRectf(x, y, x + zoomx * width, y + zoomy * height);
}
else {
- unsigned char *display_buffer;
- void *cache_handle;
-
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
- if (display_buffer) {
- int need_fallback = 1;
-
- /* checkerboard for case alpha */
- if (ibuf->planes == 32) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
- }
+ bool need_fallback = true;
- if (ED_space_clip_texture_buffer_supported(sc)) {
- if (ED_space_clip_load_movieclip_buffer(sc, ibuf, display_buffer)) {
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ /* checkerboard for case alpha */
+ if (ibuf->planes == 32) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPushMatrix();
- glTranslatef(x, y, 0.0f);
- glScalef(zoomx, zoomy, 1.0f);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
- glEnd();
-
- glPopMatrix();
-
- ED_space_clip_unload_movieclip_buffer(sc);
-
- need_fallback = 0;
- }
- }
+ fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
+ }
- /* if texture buffers aren't efficiently supported or texture is too large to
- * be binder fallback to simple draw pixels solution */
- if (need_fallback) {
- /* set zoom */
- glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
+ /* GLSL display transform for byte buffers is not supported yet */
+ if (ibuf->rect_float && IMB_coloemanagement_setup_glsl_draw_from_ctx(C)) {
+ draw_movieclip_buffer_glsl(sc, ibuf, x, y, zoomx, zoomy);
- glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
+ IMB_coloemanagement_finish_glsl_draw();
- /* reset zoom */
- glPixelZoom(1.0f, 1.0f);
- }
+ need_fallback = false;
+ }
- if (ibuf->planes == 32)
- glDisable(GL_BLEND);
+ /* if GLSL display failed, fallback to regular glaDrawPixelsAuto method */
+ if (need_fallback) {
+ draw_movieclip_buffer_fallback(C, ibuf, x, y, width, height, zoomx, zoomy);
}
- IMB_display_buffer_release(cache_handle);
+ if (ibuf->planes == 32)
+ glDisable(GL_BLEND);
}
}
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index b00cc564a99..d297d0485e3 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -62,15 +62,13 @@
#include "GPU_extensions.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "ED_screen.h"
#include "ED_clip.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -580,163 +578,6 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask)
}
}
-/* OpenGL draw context */
-
-typedef struct SpaceClipDrawContext {
- int support_checked, buffers_supported;
-
- GLuint texture; /* OGL texture ID */
- short texture_allocated; /* flag if texture was allocated by glGenTextures */
- struct ImBuf *texture_ibuf; /* image buffer for which texture was created */
- const unsigned char *display_buffer; /* display buffer for which texture was created */
- int image_width, image_height; /* image width and height for which texture was created */
- unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */
-
- /* fields to check if cache is still valid */
- int framenr, start_frame, frame_offset;
- short render_size, render_flag;
-
- char colorspace[64];
-} SpaceClipDrawContext;
-
-int ED_space_clip_texture_buffer_supported(SpaceClip *sc)
-{
- SpaceClipDrawContext *context = sc->draw_context;
-
- if (!context) {
- context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext");
- sc->draw_context = context;
- }
-
- if (!context->support_checked) {
- context->support_checked = TRUE;
- if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- context->buffers_supported = FALSE;
- }
- else {
- context->buffers_supported = GPU_non_power_of_two_support();
- }
- }
-
- return context->buffers_supported;
-}
-
-int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsigned char *display_buffer)
-{
- SpaceClipDrawContext *context = sc->draw_context;
- MovieClip *clip = ED_space_clip_get_clip(sc);
- int need_rebind = 0;
-
- context->last_texture = glaGetOneInteger(GL_TEXTURE_2D);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- /* image texture need to be rebinded if displaying another image buffer
- * assuming displaying happens of footage frames only on which painting doesn't happen.
- * so not changed image buffer pointer means unchanged image content */
- need_rebind |= context->texture_ibuf != ibuf;
- need_rebind |= context->display_buffer != display_buffer;
- need_rebind |= context->framenr != sc->user.framenr;
- need_rebind |= context->render_size != sc->user.render_size;
- need_rebind |= context->render_flag != sc->user.render_flag;
- need_rebind |= context->start_frame != clip->start_frame;
- need_rebind |= context->frame_offset != clip->frame_offset;
-
- if (!need_rebind) {
- /* OCIO_TODO: not entirely nice, but currently it seems to be easiest way
- * to deal with changing input color space settings
- * pointer-based check could fail due to new buffers could be
- * be allocated on on old memory
- */
- need_rebind = strcmp(context->colorspace, clip->colorspace_settings.name) != 0;
- }
-
- if (need_rebind) {
- int width = ibuf->x, height = ibuf->y;
- int need_recreate = 0;
-
- if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE)
- return 0;
-
- /* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */
- need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y;
-
- if (context->texture_ibuf && need_recreate) {
- glDeleteTextures(1, &context->texture);
- context->texture_allocated = 0;
- }
-
- if (need_recreate || !context->texture_allocated) {
- /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */
- int filter = GL_LINEAR;
-
- /* non-scaled proxy shouldn;t use diltering */
- if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
- ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
- {
- filter = GL_NEAREST;
- }
-
- glGenTextures(1, &context->texture);
- glBindTexture(GL_TEXTURE_2D, context->texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- }
- else {
- /* if texture doesn't need to be reallocated itself, just bind it so
- * loading of image will happen to a proper texture */
- glBindTexture(GL_TEXTURE_2D, context->texture);
- }
-
- if (display_buffer)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
-
- /* store settings */
- context->texture_allocated = 1;
- context->display_buffer = display_buffer;
- context->texture_ibuf = ibuf;
- context->image_width = ibuf->x;
- context->image_height = ibuf->y;
- context->framenr = sc->user.framenr;
- context->render_size = sc->user.render_size;
- context->render_flag = sc->user.render_flag;
- context->start_frame = clip->start_frame;
- context->frame_offset = clip->frame_offset;
-
- BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace));
- }
- else {
- /* displaying exactly the same image which was loaded t oa texture,
- * just bint texture in this case */
- glBindTexture(GL_TEXTURE_2D, context->texture);
- }
-
- glEnable(GL_TEXTURE_2D);
-
- return TRUE;
-}
-
-void ED_space_clip_unload_movieclip_buffer(SpaceClip *sc)
-{
- SpaceClipDrawContext *context = sc->draw_context;
-
- glBindTexture(GL_TEXTURE_2D, context->last_texture);
- glDisable(GL_TEXTURE_2D);
-}
-
-void ED_space_clip_free_texture_buffer(SpaceClip *sc)
-{
- SpaceClipDrawContext *context = sc->draw_context;
-
- if (context) {
- glDeleteTextures(1, &context->texture);
-
- MEM_freeN(context);
- }
-}
-
/* ******** pre-fetching functions ******** */
typedef struct PrefetchJob {
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index ced19020034..64b643f8a58 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -327,8 +327,6 @@ static void clip_free(SpaceLink *sl)
if (sc->scopes.track_search)
IMB_freeImBuf(sc->scopes.track_search);
-
- ED_space_clip_free_texture_buffer(sc);
}
/* spacetype; init callback */
@@ -348,7 +346,6 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
scn->scopes.track_search = NULL;
scn->scopes.track_preview = NULL;
scn->scopes.ok = FALSE;
- scn->draw_context = NULL;
return (SpaceLink *)scn;
}