[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46122] trunk/blender/source/blender: Camera tracking: use texture buffers (if supported) to display clip editor frames

Sergey Sharybin sergey.vfx at gmail.com
Mon Apr 30 18:19:12 CEST 2012


Revision: 46122
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46122
Author:   nazgul
Date:     2012-04-30 16:19:12 +0000 (Mon, 30 Apr 2012)
Log Message:
-----------
Camera tracking: use texture buffers (if supported) to display clip editor frames

Use texture buffers to display frames of footage in clip editor. This allows
to apply bilinear filtering of proxied resolution which.

This also resolves incredibly slow performance when drawing 4K footage on
some videocards (was originally noticed on macbook pro). Also this allows
to avoid sending the whole frame to the video memory when working with a
single frame (i.e. before this patch the whole frame would be send to the
videocard when panning frame).

Modified Paths:
--------------
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/editors/include/ED_clip.h
    trunk/blender/source/blender/editors/space_clip/CMakeLists.txt
    trunk/blender/source/blender/editors/space_clip/SConscript
    trunk/blender/source/blender/editors/space_clip/clip_draw.c
    trunk/blender/source/blender/editors/space_clip/clip_editor.c
    trunk/blender/source/blender/makesdna/DNA_space_types.h

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2012-04-30 16:19:08 UTC (rev 46121)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2012-04-30 16:19:12 UTC (rev 46122)
@@ -5390,6 +5390,7 @@
 						sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip);
 
 						sclip->scopes.track_preview = NULL;
+						sclip->draw_context = NULL;
 						sclip->scopes.ok = 0;
 					}
 				}

Modified: trunk/blender/source/blender/editors/include/ED_clip.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_clip.h	2012-04-30 16:19:08 UTC (rev 46121)
+++ trunk/blender/source/blender/editors/include/ED_clip.h	2012-04-30 16:19:12 UTC (rev 46122)
@@ -61,6 +61,11 @@
 void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr);
 void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
 
+int ED_space_clip_texture_buffer_supported(struct SpaceClip *sc);
+int ED_space_clip_load_movieclip_buffer(struct SpaceClip *sc, struct ImBuf *ibuf);
+void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc);
+void ED_space_clip_free_texture_buffer(struct SpaceClip *sc);
+
 int ED_space_clip_show_trackedit(struct SpaceClip *sc);
 
 /* clip_ops.c */

Modified: trunk/blender/source/blender/editors/space_clip/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/editors/space_clip/CMakeLists.txt	2012-04-30 16:19:08 UTC (rev 46121)
+++ trunk/blender/source/blender/editors/space_clip/CMakeLists.txt	2012-04-30 16:19:12 UTC (rev 46122)
@@ -31,6 +31,7 @@
 	../../makesdna
 	../../makesrna
 	../../windowmanager
+	../../gpu
 	../../../../intern/guardedalloc
 	${GLEW_INCLUDE_PATH}
 )

Modified: trunk/blender/source/blender/editors/space_clip/SConscript
===================================================================
--- trunk/blender/source/blender/editors/space_clip/SConscript	2012-04-30 16:19:08 UTC (rev 46121)
+++ trunk/blender/source/blender/editors/space_clip/SConscript	2012-04-30 16:19:12 UTC (rev 46122)
@@ -4,6 +4,6 @@
 sources = env.Glob('*.c')
 defs = []
 incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna'
-incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
+incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include ../../gpu'
 
 env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] )

Modified: trunk/blender/source/blender/editors/space_clip/clip_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_clip/clip_draw.c	2012-04-30 16:19:08 UTC (rev 46121)
+++ trunk/blender/source/blender/editors/space_clip/clip_draw.c	2012-04-30 16:19:12 UTC (rev 46122)
@@ -229,9 +229,6 @@
 	int x, y;
 	MovieClip *clip = ED_space_clip(sc);
 
-	/* set zoom */
-	glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
-
 	/* find window pixel coordinates of origin */
 	UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
 
@@ -242,8 +239,42 @@
 	else {
 		verify_buffer_float(ibuf);
 
-		if (ibuf->rect)
-			glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+		if (ibuf->rect) {
+			int need_fallback = 1;
+
+			if (ED_space_clip_texture_buffer_supported(sc)) {
+				if (ED_space_clip_load_movieclip_buffer(sc, ibuf)) {
+					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;
+				}
+			}
+
+			/* if texture buffers aren't efifciently 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);
+
+				glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+
+				/* reset zoom */
+				glPixelZoom(1.0f, 1.0f);
+			}
+		}
 	}
 
 	/* draw boundary border for frame if stabilization is enabled */
@@ -255,9 +286,9 @@
 		glLogicOp(GL_NOR);
 
 		glPushMatrix();
-		glTranslatef(x, y, 0);
+		glTranslatef(x, y, 0.0f);
 
-		glScalef(zoomx, zoomy, 0);
+		glScalef(zoomx, zoomy, 1.0f);
 		glMultMatrixf(sc->stabmat);
 
 		glBegin(GL_LINE_LOOP);
@@ -272,10 +303,6 @@
 		glDisable(GL_COLOR_LOGIC_OP);
 		glDisable(GL_LINE_STIPPLE);
 	}
-
-
-	/* reset zoom */
-	glPixelZoom(1.0f, 1.0f);
 }
 
 static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)

Modified: trunk/blender/source/blender/editors/space_clip/clip_editor.c
===================================================================
--- trunk/blender/source/blender/editors/space_clip/clip_editor.c	2012-04-30 16:19:08 UTC (rev 46121)
+++ trunk/blender/source/blender/editors/space_clip/clip_editor.c	2012-04-30 16:19:12 UTC (rev 46122)
@@ -31,6 +31,8 @@
 
 #include <stddef.h>
 
+#include "MEM_guardedalloc.h"
+
 #include "BKE_main.h"
 #include "BKE_movieclip.h"
 #include "BKE_context.h"
@@ -41,6 +43,8 @@
 #include "BLI_utildefines.h"
 #include "BLI_math.h"
 
+#include "GPU_extensions.h"
+
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
@@ -48,6 +52,7 @@
 #include "ED_clip.h"
 
 #include "BIF_gl.h"
+#include "BIF_glutil.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -363,6 +368,146 @@
 	ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]);
 }
 
+/* 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 */
+	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 */
+	int framenr;
+} 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)
+{
+	SpaceClipDrawContext *context = sc->draw_context;
+	MovieClip *clip = ED_space_clip(sc);
+	int need_rebind = 0;
+
+	context->last_texture = glaGetOneInteger(GL_TEXTURE_2D);
+
+	/* image texture need to be rebinded if displaying another image buffer
+	 * assuming displaying happens of footage frames only on which painting doesn't heppen.
+	 * so not changed image buffer pointer means unchanged image content */
+	need_rebind |= context->texture_ibuf != ibuf;
+	need_rebind |= context->framenr != sc->user.framenr;
+
+	if (need_rebind) {
+		int width = ibuf->x, height = ibuf->y;
+		float *frect = NULL, *fscalerect = NULL;
+		unsigned int *rect = NULL, *scalerect = NULL;
+		int need_recreate = 0;
+
+		if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE)
+			return 0;
+
+		rect = ibuf->rect;
+		frect = ibuf->rect_float;
+
+		/* 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 (frect)
+			glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA16,  width, height, 0, GL_RGBA, GL_FLOAT, frect);
+		else
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+
+		/* store settings */
+		context->texture_allocated = 1;
+		context->texture_ibuf = ibuf;
+		context->image_width = ibuf->x;
+		context->image_height = ibuf->y;
+		context->framenr = sc->user.framenr;
+
+		if (fscalerect)
+			MEM_freeN(fscalerect);
+		if (scalerect)
+			MEM_freeN(scalerect);
+	}
+	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);
+	}
+}
+
 int ED_space_clip_show_trackedit(SpaceClip *sc)
 {
 	if (sc) {


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list