[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55970] trunk/blender/source/blender/ editors: Fix #34817: improve OpenGL preview render speed, it got quite a bit slower since 2.60.

Brecht Van Lommel brechtvanlommel at pandora.be
Thu Apr 11 17:15:06 CEST 2013


Revision: 55970
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55970
Author:   blendix
Date:     2013-04-11 15:15:06 +0000 (Thu, 11 Apr 2013)
Log Message:
-----------
Fix #34817: improve OpenGL preview render speed, it got quite a bit slower since 2.60.

Doing linearization with GLSL was already faster, but even faster is to just read the
bytes instead of floats and convert those to linear, since byte => float is just a quick
256 entry table lookup. Also made it assign the bytes directly to the image buffer so
they do not need to be converted back from float to byte for file saving, and made sky
render write the background color with OpenGL instead of doing it on the CPU.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/include/ED_view3d.h
    trunk/blender/source/blender/editors/render/render_opengl.c
    trunk/blender/source/blender/editors/space_view3d/view3d_draw.c

Modified: trunk/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_view3d.h	2013-04-11 14:46:41 UTC (rev 55969)
+++ trunk/blender/source/blender/editors/include/ED_view3d.h	2013-04-11 15:15:06 UTC (rev 55970)
@@ -281,7 +281,7 @@
 bool ED_view3d_context_activate(struct bContext *C);
 void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
 void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
-                              int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic);
+                              int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky);
 
 struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
                                              bool draw_background, int alpha_mode, char err_out[256]);

Modified: trunk/blender/source/blender/editors/render/render_opengl.c
===================================================================
--- trunk/blender/source/blender/editors/render/render_opengl.c	2013-04-11 14:46:41 UTC (rev 55969)
+++ trunk/blender/source/blender/editors/render/render_opengl.c	2013-04-11 15:15:06 UTC (rev 55970)
@@ -135,6 +135,9 @@
 	int sizex = oglrender->sizex;
 	int sizey = oglrender->sizey;
 	const short view_context = (v3d != NULL);
+	bool draw_bgpic = true;
+	bool draw_sky = (scene->r.alphamode == R_ADDSKY);
+	unsigned char *rect = NULL;
 
 	rr = RE_AcquireResultRead(oglrender->re);
 
@@ -167,7 +170,6 @@
 				BKE_sequencer_imbuf_from_sequencer_space(scene, linear_ibuf);
 			}
 
-
 			memcpy(rr->rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
 
 			IMB_freeImBuf(linear_ibuf);
@@ -194,24 +196,28 @@
 			else perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
 		}
 
+		rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
+
 		if ((scene->r.mode & R_OSA) == 0) {
-			ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
-			GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf);
+			ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky);
+			GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
 		}
 		else {
 			/* simple accumulation, less hassle then FSAA FBO's */
 			static float jit_ofs[32][2];
 			float winmat_jitter[4][4];
-			float *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(float) * 4, "accum1");
-			float *accum_tmp = MEM_mallocN(sizex * sizey * sizeof(float) * 4, "accum2");
-			int j;
+			int *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(int) * 4, "accum1");;
+			int i, j;
 
 			BLI_jitter_init(jit_ofs[0], scene->r.osa);
 
 			/* first sample buffer, also initializes 'rv3d->persmat' */
-			ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
-			GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer);
+			ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky);
+			GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
 
+			for (i = 0; i < sizex * sizey * 4; i++)
+				accum_buffer[i] = rect[i];
+
 			/* skip the first sample */
 			for (j = 1; j < scene->r.osa; j++) {
 				copy_m4_m4(winmat_jitter, winmat);
@@ -219,15 +225,17 @@
 				                    (jit_ofs[j][0] * 2.0f) / sizex,
 				                    (jit_ofs[j][1] * 2.0f) / sizey);
 
-				ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE);
-				GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp);
-				add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float));
+				ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, draw_bgpic, draw_sky);
+				GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
+
+				for (i = 0; i < sizex * sizey * 4; i++)
+					accum_buffer[i] += rect[i];
 			}
 
-			mul_vn_vn_fl(rr->rectf, accum_buffer, sizex * sizey * sizeof(float), 1.0f / scene->r.osa);
+			for (i = 0; i < sizex * sizey * 4; i++)
+				rect[i] = accum_buffer[i] / scene->r.osa;
 
 			MEM_freeN(accum_buffer);
-			MEM_freeN(accum_tmp);
 		}
 
 		GPU_offscreen_unbind(oglrender->ofs); /* unbind */
@@ -236,11 +244,15 @@
 		/* shouldnt suddenly give errors mid-render but possible */
 		char err_out[256] = "unknown";
 		ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
-		                                                         IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out);
+		                                                         IB_rect, OB_SOLID, FALSE, TRUE,
+																 (draw_sky)? R_ADDSKY: R_ALPHAPREMUL, err_out);
 		camera = scene->camera;
 
 		if (ibuf_view) {
-			memcpy(rr->rectf, ibuf_view->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
+			/* steal rect reference from ibuf */
+			rect = (unsigned char*)ibuf_view->rect;
+			ibuf_view->mall &= ~IB_rect;
+
 			IMB_freeImBuf(ibuf_view);
 		}
 		else {
@@ -248,12 +260,6 @@
 		}
 	}
 
-	if (scene->r.alphamode == R_ADDSKY) {
-		float sky_color[3];
-		ED_view3d_offscreen_sky_color_get(scene, sky_color);
-		IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color);
-	}
-
 	/* note on color management:
 	 *
 	 * OpenGL renders into sRGB colors, but render buffers are expected to be
@@ -262,21 +268,18 @@
 	 * correct linear float buffer.
 	 */
 
-	if (!oglrender->is_sequencer) {
+	if (rect) {
 		/* sequencer has got trickier conversion happened above
-		 * also assume opengl's space matches byte buffer color space
-		 */
-		if (!glaBufferTransformFromRole_glsl(rr->rectf, oglrender->sizex, oglrender->sizey, COLOR_ROLE_DEFAULT_BYTE)) {
-			IMB_buffer_float_from_float(rr->rectf, rr->rectf,
-			                            4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, TRUE,
-			                            oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
-		}
+		 * also assume opengl's space matches byte buffer color space */
+		IMB_buffer_float_from_byte(rr->rectf, rect,
+									IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, TRUE,
+									oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
 	}
 
 	/* rr->rectf is now filled with image data */
 
 	if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW))
-		BKE_stamp_buf(scene, camera, NULL, rr->rectf, rr->rectx, rr->recty, 4);
+		BKE_stamp_buf(scene, camera, rect, rr->rectf, rr->rectx, rr->recty, 4);
 
 	RE_ReleaseResult(oglrender->re);
 
@@ -284,8 +287,15 @@
 	ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
 
 	if (ibuf) {
-		image_buffer_rect_update(scene, rr, ibuf, NULL);
+		/* update display buffer */
+		if (ibuf->rect == NULL)
+			imb_addrectImBuf(ibuf);
 
+		IMB_partial_display_buffer_update(ibuf, rr->rectf, rect, rr->rectx, 0, 0,
+										  &scene->view_settings, &scene->display_settings,
+										  0, 0, rr->rectx, rr->recty, TRUE);
+
+		/* write file for animation */
 		if (oglrender->write_still) {
 			char name[FILE_MAX];
 			int ok;
@@ -302,6 +312,9 @@
 	}
 	
 	BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
+
+	if (rect)
+		MEM_freeN(rect);
 }
 
 static int screen_opengl_render_init(bContext *C, wmOperator *op)

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_draw.c	2013-04-11 14:46:41 UTC (rev 55969)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_draw.c	2013-04-11 15:15:06 UTC (rev 55970)
@@ -2463,7 +2463,7 @@
 		invert_m4_m4(rv3d.persinv, rv3d.viewinv);
 
 		/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
-		ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, false);
+		ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, false, false);
 		GPU_lamp_shadow_buffer_unbind(shadow->lamp);
 		
 		v3d->drawtype = drawtype;
@@ -2611,7 +2611,7 @@
  * stuff like shadow buffers
  */
 void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
-                              float viewmat[4][4], float winmat[4][4], bool do_bgpic)
+                              float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky)
 {
 	RegionView3D *rv3d = ar->regiondata;
 	Base *base;
@@ -2642,8 +2642,17 @@
 	 * warning! can be slow so only free animated images - campbell */
 	GPU_free_images_anim();
 
-	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	/* clear opengl buffers */
+	if (do_sky) {
+		float sky_color[3];
 
+		ED_view3d_offscreen_sky_color_get(scene, sky_color);
+		glClearColor(sky_color[0], sky_color[1], sky_color[2], 1.0f);
+	}
+	else {
+		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	}
+
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 	/* setup view matrices */
@@ -2753,18 +2762,6 @@
 		UI_GetThemeColor3fv(TH_BACK, sky_color);
 }
 
-static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene)
-{
-	float sky_color[3];
-
-	ED_view3d_offscreen_sky_color_get(scene, sky_color);
-
-	if (ibuf->rect_float)
-		IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color);
-	else
-		IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color);
-}
-
 /* utility func for ED_view3d_draw_offscreen */
 ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
                                       bool draw_background, int alpha_mode, char err_out[256])
@@ -2772,6 +2769,7 @@
 	RegionView3D *rv3d = ar->regiondata;
 	ImBuf *ibuf;
 	GPUOffScreen *ofs;
+	bool draw_sky = (alpha_mode == R_ADDSKY);
 	
 	/* state changes make normal drawing go weird otherwise */
 	glPushAttrib(GL_LIGHTING_BIT);
@@ -2794,10 +2792,10 @@
 		BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
 		BKE_camera_params_compute_matrix(&params);
 
-		ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list