Code refactoring: move external engine functions into own file.

This commit is contained in:
Brecht Van Lommel 2011-10-22 16:24:28 +00:00
parent 952560dc02
commit 1bdf652b89
10 changed files with 305 additions and 215 deletions

@ -36,6 +36,7 @@
#include "rna_internal.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
#include "BKE_utildefines.h"

@ -199,7 +199,7 @@ EnumPropertyItem image_color_mode_items[] ={
#include "ED_mesh.h"
#include "ED_keyframing.h"
#include "RE_pipeline.h"
#include "RE_engine.h"
static int rna_Scene_object_bases_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
{

@ -56,6 +56,7 @@ set(SRC
intern/raytrace/rayobject_vbvh.cpp
intern/source/convertblender.c
intern/source/envmap.c
intern/source/external_engine.c
intern/source/gammaCorrectionTables.c
intern/source/imagetexture.c
intern/source/initrender.c
@ -79,6 +80,7 @@ set(SRC
intern/source/voxeldata.c
intern/source/zbuf.c
extern/include/RE_engine.h
extern/include/RE_pipeline.h
extern/include/RE_render_ext.h
extern/include/RE_shader_ext.h

@ -0,0 +1,97 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file RE_engine.h
* \ingroup render
*/
#ifndef RE_ENGINE_H
#define RE_ENGINE_H
#include "DNA_listBase.h"
#include "RNA_types.h"
struct Object;
struct Render;
struct RenderEngine;
struct RenderEngineType;
struct RenderLayer;
struct RenderResult;
struct ReportList;
struct Scene;
/* External Engine */
#define RE_INTERNAL 1
#define RE_GAME 2
#define RE_DO_PREVIEW 4
#define RE_DO_ALL 8
extern ListBase R_engines;
typedef struct RenderEngineType {
struct RenderEngineType *next, *prev;
/* type info */
char idname[64]; // best keep the same size as BKE_ST_MAXNAME
char name[64];
int flag;
void (*render)(struct RenderEngine *engine, struct Scene *scene);
/* RNA integration */
ExtensionRNA ext;
} RenderEngineType;
typedef struct RenderEngine {
RenderEngineType *type;
struct Render *re;
ListBase fullresult;
} RenderEngine;
void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y);
void RE_result_load_from_file(struct RenderResult *result, struct ReportList *reports, const char *filename);
struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h);
void RE_engine_update_result(RenderEngine *engine, struct RenderResult *result);
void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result);
int RE_engine_test_break(RenderEngine *engine);
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info);
void RE_engine_report(RenderEngine *engine, int type, const char *msg);
int RE_engine_render(struct Render *re, int do_all);
/* Engine Types */
void RE_engines_init(void);
void RE_engines_exit(void);
#endif /* RE_ENGINE_H */

@ -36,7 +36,6 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
#include "RNA_types.h"
struct bNodeTree;
struct Image;
@ -44,11 +43,8 @@ struct Main;
struct NodeBlurData;
struct Object;
struct RenderData;
struct RenderEngine;
struct RenderEngineType;
struct RenderResult;
struct ReportList;
struct ReportList;
struct Scene;
struct SceneRenderLayer;
struct EnvMap;
@ -276,49 +272,6 @@ void RE_DataBase_GetView(struct Render *re, float mat[][4]);
void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]);
struct Scene *RE_GetScene(struct Render *re);
/* External Engine */
#define RE_INTERNAL 1
#define RE_GAME 2
#define RE_DO_PREVIEW 4
#define RE_DO_ALL 8
extern ListBase R_engines;
typedef struct RenderEngineType {
struct RenderEngineType *next, *prev;
/* type info */
char idname[64]; // best keep the same size as BKE_ST_MAXNAME
char name[64];
int flag;
void (*render)(struct RenderEngine *engine, struct Scene *scene);
/* RNA integration */
ExtensionRNA ext;
} RenderEngineType;
typedef struct RenderEngine {
RenderEngineType *type;
struct Render *re;
ListBase fullresult;
} RenderEngine;
void RE_layer_load_from_file(RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y);
void RE_result_load_from_file(RenderResult *result, struct ReportList *reports, const char *filename);
struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h);
void RE_engine_update_result(RenderEngine *engine, struct RenderResult *result);
void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result);
int RE_engine_test_break(RenderEngine *engine);
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info);
void RE_engine_report(RenderEngine *engine, int type, const char *msg);
void RE_engines_init(void);
void RE_engines_exit(void);
int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports);
#endif /* RE_PIPELINE_H */

@ -35,14 +35,22 @@
#ifndef PIPELINE_H
#define PIPELINE_H
struct ListBase;
struct Render;
struct RenderResult;
struct RenderLayer;
struct rcti;
struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr);
float panorama_pixel_rot(struct Render *re);
#define PASS_VECTOR_MAX 10000.0f
#define RR_USEMEM 0
struct RenderResult *new_render_result(struct Render *re, struct rcti *partrct, int crop, int savebuffers);
void merge_render_result(struct RenderResult *rr, struct RenderResult *rrpart);
void free_render_result(struct ListBase *lb, struct RenderResult *rr);
#endif /* PIPELINE_H */

@ -0,0 +1,186 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/render/intern/pipeline/engine.c
* \ingroup render
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
#include "render_types.h"
#include "renderpipeline.h"
/************************** External Engines ***************************/
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h)
{
Render *re= engine->re;
RenderResult *result;
rcti disprect;
/* ensure the coordinates are within the right limits */
CLAMP(x, 0, re->result->rectx);
CLAMP(y, 0, re->result->recty);
CLAMP(w, 0, re->result->rectx);
CLAMP(h, 0, re->result->recty);
if(x + w > re->result->rectx)
w= re->result->rectx - x;
if(y + h > re->result->recty)
h= re->result->recty - y;
/* allocate a render result */
disprect.xmin= x;
disprect.xmax= x+w;
disprect.ymin= y;
disprect.ymax= y+h;
result= new_render_result(re, &disprect, 0, RR_USEMEM);
BLI_addtail(&engine->fullresult, result);
return result;
}
void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
{
Render *re= engine->re;
if(result) {
result->renlay= result->layers.first; // weak, draws first layer always
re->display_draw(re->ddh, result, NULL);
}
}
void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
{
Render *re= engine->re;
if(!result)
return;
/* merge. on break, don't merge in result for preview renders, looks nicer */
if(!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
merge_render_result(re->result, result);
/* draw */
if(!re->test_break(re->tbh)) {
result->renlay= result->layers.first; // weak, draws first layer always
re->display_draw(re->ddh, result, NULL);
}
/* free */
free_render_result(&engine->fullresult, result);
}
/* Cancel */
int RE_engine_test_break(RenderEngine *engine)
{
Render *re= engine->re;
if(re)
return re->test_break(re->tbh);
return 0;
}
/* Statistics */
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)
{
Render *re= engine->re;
re->i.statstr= stats;
re->i.infostr= info;
re->stats_draw(re->sdh, &re->i);
re->i.infostr= NULL;
re->i.statstr= NULL;
}
void RE_engine_report(RenderEngine *engine, int type, const char *msg)
{
BKE_report(engine->re->reports, type, msg);
}
/* Render */
int RE_engine_render(Render *re, int do_all)
{
RenderEngineType *type= BLI_findstring(&R_engines, re->r.engine, offsetof(RenderEngineType, idname));
RenderEngine engine;
if(!(type && type->render))
return 0;
if((re->r.scemode & R_PREVIEWBUTS) && !(type->flag & RE_DO_PREVIEW))
return 0;
if(do_all && !(type->flag & RE_DO_ALL))
return 0;
if(!do_all && (type->flag & RE_DO_ALL))
return 0;
/* create render result */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, 0);
}
BLI_rw_mutex_unlock(&re->resultmutex);
if(re->result==NULL)
return 1;
/* external */
memset(&engine, 0, sizeof(engine));
engine.type= type;
engine.re= re;
type->render(&engine, re->scene);
free_render_result(&engine.fullresult, engine.fullresult.first);
return 1;
}

@ -73,6 +73,7 @@
#include "intern/openexr/openexr_multi.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
/* internal */
@ -215,7 +216,7 @@ void RE_FreeRenderResult(RenderResult *res)
}
/* version that's compatible with fullsample buffers */
static void free_render_result(ListBase *lb, RenderResult *rr)
void free_render_result(ListBase *lb, RenderResult *rr)
{
RenderResult *rrnext;
@ -545,12 +546,11 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)
return NULL;
}
#define RR_USEMEM 0
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
/* re->winx,winy is coordinate space of entire image, partrct the part within */
static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)
RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)
{
RenderResult *rr;
RenderLayer *rl;
@ -729,7 +729,7 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target,
/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
/* no test happens here if it fits... we also assume layers are in sync */
/* is used within threads */
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
void merge_render_result(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl, *rlp;
RenderPass *rpass, *rpassp;
@ -998,7 +998,7 @@ static int read_render_result_from_file(const char *filename, RenderResult *rr)
IMB_exr_read_channels(exrhandle);
renderresult_add_names(rr);
}
IMB_exr_close(exrhandle);
return 1;
@ -1811,12 +1811,10 @@ void RE_TileProcessor(Render *re)
/* ************ This part uses API, for rendering Blender scenes ********** */
static int external_render_3d(Render *re, int do_all);
static void do_render_3d(Render *re)
{
/* try external */
if(external_render_3d(re, 0))
if(RE_engine_render(re, 0))
return;
/* internal */
@ -2648,7 +2646,7 @@ static void do_render_all_options(Render *re)
/* ensure no images are in memory from previous animated sequences */
BKE_image_all_free_anim_ibufs(re->r.cfra);
if(external_render_3d(re, 1)) {
if(RE_engine_render(re, 1)) {
/* in this case external render overrides all */
}
else if(seq_render_active(re)) {
@ -3279,106 +3277,6 @@ void RE_init_threadcount(Render *re)
}
}
/************************** External Engines ***************************/
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h)
{
Render *re= engine->re;
RenderResult *result;
rcti disprect;
/* ensure the coordinates are within the right limits */
CLAMP(x, 0, re->result->rectx);
CLAMP(y, 0, re->result->recty);
CLAMP(w, 0, re->result->rectx);
CLAMP(h, 0, re->result->recty);
if(x + w > re->result->rectx)
w= re->result->rectx - x;
if(y + h > re->result->recty)
h= re->result->recty - y;
/* allocate a render result */
disprect.xmin= x;
disprect.xmax= x+w;
disprect.ymin= y;
disprect.ymax= y+h;
if(0) { // XXX (re->r.scemode & R_FULL_SAMPLE)) {
result= new_full_sample_buffers(re, &engine->fullresult, &disprect, 0);
}
else {
result= new_render_result(re, &disprect, 0, RR_USEMEM);
BLI_addtail(&engine->fullresult, result);
}
return result;
}
void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
{
Render *re= engine->re;
if(result && render_display_draw_enabled(re)) {
result->renlay= result->layers.first; // weak
re->display_draw(re->ddh, result, NULL);
}
}
void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
{
Render *re= engine->re;
if(!result)
return;
/* merge */
if(re->result->exrhandle) {
RenderResult *rr, *rrpart;
// XXX crashes, exr expects very particular part sizes
for(rr= re->result, rrpart= result; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
save_render_result_tile(rr, rrpart);
}
else if(render_display_draw_enabled(re)) {
/* on break, don't merge in result for preview renders, looks nicer */
if(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS));
else merge_render_result(re->result, result);
}
/* draw */
if(!re->test_break(re->tbh) && render_display_draw_enabled(re)) {
result->renlay= result->layers.first; // weak
re->display_draw(re->ddh, result, NULL);
}
/* free */
free_render_result(&engine->fullresult, result);
}
int RE_engine_test_break(RenderEngine *engine)
{
Render *re= engine->re;
return re->test_break(re->tbh);
}
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)
{
Render *re= engine->re;
re->i.statstr= stats;
re->i.infostr= info;
re->stats_draw(re->sdh, &re->i);
re->i.infostr= NULL;
re->i.statstr= NULL;
}
void RE_engine_report(RenderEngine *engine, int type, const char *msg)
{
BKE_report(engine->re->reports, type, msg);
}
/* loads in image into a result, size must match
* x/y offsets are only used on a partial copy when dimensions dont match */
void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)
@ -3429,64 +3327,6 @@ void RE_result_load_from_file(RenderResult *result, ReportList *reports, const c
}
}
static int external_render_3d(Render *re, int do_all)
{
RenderEngineType *type= BLI_findstring(&R_engines, re->r.engine, offsetof(RenderEngineType, idname));
RenderEngine engine;
if(!(type && type->render))
return 0;
if((re->r.scemode & R_PREVIEWBUTS) && !(type->flag & RE_DO_PREVIEW))
return 0;
if(do_all && !(type->flag & RE_DO_ALL))
return 0;
if(!do_all && (type->flag & RE_DO_ALL))
return 0;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
RE_FreeRenderResult(re->result);
if(0) // XXX re->r.scemode & R_FULL_SAMPLE)
re->result= new_full_sample_buffers_exr(re);
else
re->result= new_render_result(re, &re->disprect, 0, 0); // XXX re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE));
}
BLI_rw_mutex_unlock(&re->resultmutex);
if(re->result==NULL)
return 1;
/* external */
memset(&engine, 0, sizeof(engine));
engine.type= type;
engine.re= re;
type->render(&engine, re->scene);
free_render_result(&engine.fullresult, engine.fullresult.first);
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result->exrhandle) {
RenderResult *rr;
save_empty_result_tiles(re);
for(rr= re->result; rr; rr= rr->next) {
IMB_exr_close(rr->exrhandle);
rr->exrhandle= NULL;
}
free_render_result(&re->fullresult, re->result);
re->result= NULL;
read_render_result(re, 0);
}
BLI_rw_mutex_unlock(&re->resultmutex);
return 1;
}
const float default_envmap_layout[] = { 0,0, 1,0, 2,0, 0,1, 1,1, 2,1 };
int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, int imtype, float layout[12])
@ -3544,3 +3384,4 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
return FALSE;
}
}

@ -66,6 +66,7 @@
#include "BLI_blenlib.h"
#include "BLI_winstuff.h"
#include "RE_engine.h"
#include "RE_pipeline.h" /* RE_ free stuff */
#ifdef WITH_PYTHON

@ -86,6 +86,7 @@
#include "BPY_extern.h"
#endif
#include "RE_engine.h"
#include "RE_pipeline.h"
//XXX #include "playanim_ext.h"