[Bf-blender-cvs] [ca0c0e7] master: Implement resolution divider in the Blender Internal

Sergey Sharybin noreply at git.blender.org
Fri Jun 20 13:34:49 CEST 2014


Commit: ca0c0e754931df011ff5421a57e02f8bdfa4559a
Author: Sergey Sharybin
Date:   Thu Jun 19 16:21:17 2014 +0600
https://developer.blender.org/rBca0c0e754931df011ff5421a57e02f8bdfa4559a

Implement resolution divider in the Blender Internal

Currently resolution divider is not exposed to the
interface yet, and i'm not even sure it needs to be
exposed because it's somewhat weird configuration.
Need to check how often artists are changing start
resolution in Cycles.

Pretty much straightforward implementation with the
only weak part: render result is getting re-allocated
and upscaled when current resolution is finished.
Not sure how to make it faster actually. Maybe it's
just a matter of making upscale fast enough.

Needed to fix some possible memory leak happening
in Freestyle when canceling rendering on a special
stage -- it was missing temp bmain free,

Reviewers: campbellbarton, dingto

CC: sebastian_k, fsiddi, venomgfx

Differential Revision: https://developer.blender.org/D609

===================================================================

M	source/blender/editors/render/render_internal.c
M	source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
M	source/blender/render/extern/include/RE_pipeline.h
M	source/blender/render/intern/source/pipeline.c

===================================================================

diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 9fa3128..1bf4806 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1011,6 +1011,8 @@ void RENDER_OT_render(wmOperatorType *ot)
 #define PR_UPDATE_MATERIAL			4
 #define PR_UPDATE_DATABASE			8
 
+#define START_RESOLUTION_DIVIDER	8
+
 typedef struct RenderPreview {
 	/* from wmJob */
 	void *owner;
@@ -1026,6 +1028,8 @@ typedef struct RenderPreview {
 	RenderEngine *engine;
 	
 	float viewmat[4][4];
+
+	int resolution_divider;
 } RenderPreview;
 
 static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect)
@@ -1127,7 +1131,6 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
 	RenderPreview *rp = customdata;
 	Render *re;
 	RenderStats *rstats;
-	RenderData rdata;
 	rctf viewplane;
 	rcti cliprct;
 	float clipsta, clipend, pixsize;
@@ -1161,23 +1164,36 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
 	
 	rstats = RE_GetStats(re);
 
+	if (update_flag & PR_UPDATE_VIEW) {
+		rp->resolution_divider = START_RESOLUTION_DIVIDER;
+	}
+
 	if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
+		RenderData rdata;
+		int winx = rp->ar->winx / rp->resolution_divider,
+		    winy = rp->ar->winy / rp->resolution_divider;
+
 		/* no osa, blur, seq, layers, etc for preview render */
 		rdata = rp->scene->r;
 		rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
 		rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE);
 		rdata.scemode |= R_VIEWPORT_PREVIEW;
-		
+
 		/* we do use layers, but only active */
 		rdata.scemode |= R_SINGLE_LAYER;
 
 		/* initalize always */
 		if (render_view3d_disprect(rp->scene, rp->ar, rp->v3d, rp->rv3d, &cliprct)) {
 			rdata.mode |= R_BORDER;
-			RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, &cliprct);
+			RE_InitState(re, NULL, &rdata, NULL, winx, winy, &cliprct);
 		}
 		else
-			RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, NULL);
+			RE_InitState(re, NULL, &rdata, NULL, winx, winy, NULL);
+	}
+	else if (update_flag & PR_UPDATE_VIEW) {
+		int winx = rp->ar->winx / rp->resolution_divider,
+		    winy = rp->ar->winy / rp->resolution_divider;
+		RE_ChangeResolution(re, winx, winy, NULL);
 	}
 
 	if (orth)
@@ -1225,8 +1241,30 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
 
 	/* OK, can we enter render code? */
 	if (rstats->convertdone) {
-		RE_TileProcessor(re);
-		
+		for (;;) {
+			RE_TileProcessor(re);
+
+			if (!*stop && rp->resolution_divider > 1) {
+				int winx, winy;
+				rp->resolution_divider /= 2;
+				winx = rp->ar->winx / rp->resolution_divider;
+				winy = rp->ar->winy / rp->resolution_divider;
+				*do_update = 1;
+				RE_ChangeResolution(re, winx, winy, NULL);
+
+				/* Otherwise shadows are incorrect. */
+				if (orth) {
+					RE_SetOrtho(re, &viewplane, clipsta, clipend);
+				}
+				else {
+					RE_SetWindow(re, &viewplane, clipsta, clipend);
+				}
+			}
+			else {
+				break;
+			}
+		}
+
 		/* always rotate back */
 		if (restore)
 			RE_DataBase_IncrementalView(re, rp->viewmat, 1);
@@ -1341,6 +1379,7 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C)
 	rp->v3d = rp->sa->spacedata.first;
 	rp->rv3d = CTX_wm_region_view3d(C);
 	rp->bmain = CTX_data_main(C);
+	rp->resolution_divider = START_RESOLUTION_DIVIDER;
 	copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
 	
 	/* clear info text */
@@ -1386,9 +1425,12 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
 	
 	if (rres.rectf) {
 		Scene *scene = CTX_data_scene(C);
+		ARegion *ar = CTX_wm_region(C);
 		bool force_fallback = false;
 		bool need_fallback = true;
 		float dither = scene->r.dither_intensity;
+		float scale_x = (float) ar->winx / rres.rectx;
+		float scale_y = (float) ar->winy / rres.recty;
 
 		/* Dithering is not supported on GLSL yet */
 		force_fallback |= dither != 0.0f;
@@ -1420,8 +1462,10 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
 
 			glEnable(GL_BLEND);
 			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+			glPixelZoom(scale_x, scale_y);
 			glaDrawPixelsAuto(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE,
 			                  GL_NEAREST, display_buffer);
+			glPixelZoom(1.0f, 1.0f);
 			glDisable(GL_BLEND);
 
 			MEM_freeN(display_buffer);
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 49c3fdc..4d60b54 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -611,25 +611,25 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
 		if (G.debug & G_DEBUG_FREESTYLE) {
 			cout << "Break" << endl;
 		}
-		return NULL;
 	}
-
-	// render and composite Freestyle result
-	if (controller->_ViewMap) {
-		// render strokes
-		re->i.infostr = "Freestyle: Stroke rendering";
-		re->stats_draw(re->sdh, &re->i);
-		re->i.infostr = NULL;
-		freestyle_scene = re->scene;
-		controller->DrawStrokes();
-		freestyle_render = controller->RenderStrokes(re, true);
-		controller->CloseFile();
-		freestyle_scene = NULL;
-
-		// composite result
-		FRS_composite_result(re, srl, freestyle_render);
-		RE_FreeRenderResult(freestyle_render->result);
-		freestyle_render->result = NULL;
+	else {
+		// render and composite Freestyle result
+		if (controller->_ViewMap) {
+			// render strokes
+			re->i.infostr = "Freestyle: Stroke rendering";
+			re->stats_draw(re->sdh, &re->i);
+			re->i.infostr = NULL;
+			freestyle_scene = re->scene;
+			controller->DrawStrokes();
+			freestyle_render = controller->RenderStrokes(re, true);
+			controller->CloseFile();
+			freestyle_scene = NULL;
+
+			// composite result
+			FRS_composite_result(re, srl, freestyle_render);
+			RE_FreeRenderResult(freestyle_render->result);
+			freestyle_render->result = NULL;
+		}
 	}
 
 	// Free temp main (currently only text blocks are stored there)
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 031d6b5..68ac0cd 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -190,7 +190,10 @@ struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name)
 float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype);
 
 /* obligatory initialize call, disprect is optional */
-void RE_InitState(struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect);
+void RE_InitState(struct Render *re, struct Render *source, struct RenderData *rd,
+                  struct SceneRenderLayer *srl,
+                  int winx, int winy, rcti *disprect);
+void RE_ChangeResolution(struct Render *re, int winx, int winy, rcti *disprect);
 
 /* set up the viewplane/perspective matrix, three choices */
 struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 537714a..d4f089d 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -511,32 +511,9 @@ static int check_mode_full_sample(RenderData *rd)
 	return scemode;
 }
 
-/* what doesn't change during entire render sequence */
-/* disprect is optional, if NULL it assumes full window render */
-void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *srl, int winx, int winy, rcti *disprect)
+static void re_init_resolution(Render *re, Render *source,
+                               int winx, int winy, rcti *disprect)
 {
-	bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0;
-
-	re->ok = true;   /* maybe flag */
-	
-	re->i.starttime = PIL_check_seconds_timer();
-
-	/* copy render data and render layers for thread safety */
-	BLI_freelistN(&re->r.layers);
-	re->r = *rd;
-	BLI_duplicatelist(&re->r.layers, &rd->layers);
-
-	if (source) {
-		/* reuse border flags from source renderer */
-		re->r.mode &= ~(R_BORDER | R_CROP);
-		re->r.mode |= source->r.mode & (R_BORDER | R_CROP);
-
-		/* dimensions shall be shared between all renderers */
-		re->r.xsch = source->r.xsch;
-		re->r.ysch = source->r.ysch;
-		re->r.size = source->r.size;
-	}
-
 	re->winx = winx;
 	re->winy = winy;
 	if (source && (source->r.mode & R_BORDER)) {
@@ -570,7 +547,41 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
 		re->rectx = winx;
 		re->recty = winy;
 	}
+
+	/* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */
+	re->clipcrop = 1.0f + 2.0f / (float)(re->winx > re->winy ? re->winy : re->winx);
+}
+
+/* what doesn't change during entire render sequence */
+/* disprect is optional, if NULL it assumes full window render */
+void RE_InitState(Render *re, Render *source, RenderData *rd,
+                  SceneRenderLayer *srl,
+                  int winx, int winy, rcti *disprect)
+{
+	bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0;
+
+	re->ok = true;   /* maybe flag */
 	
+	re->i.starttime = PIL_check_seconds_timer();
+
+	/* copy render data and render layers for thread safety */
+	BLI_freelistN(&re->r.layers);
+	re->r = *rd;
+	BLI_duplicatelist(&re->r.layers, &rd->layers);
+
+	if (source) {
+		/* reuse border flags from source renderer */
+		re->r.mode &= ~(R_BORDER | R_CROP);
+		re->r.mode |= source->r.mode & (R_BORDER | R_CROP);
+
+		/* dimensions shall be shared between all renderers */
+		re->r.xsch = source->r.xsch;
+		re->r.ysch = source->r.ysch;
+		re->r.size = source->r.size;
+	}
+
+	re_init_resolution(re, source, winx, winy, disprect);
+
 	if (re->rectx < 1 || re->recty < 1 || (BKE_imtype_is_movie(rd->im_format.imtype) &&
 	                                       (re->rectx < 16 || re->recty < 16) ))
 	{
@@ -654,14 +665,69 @@ void RE_InitState(Render *re,

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list