Added WM Jobs manager
- WM can manage threaded jobs for you; just provide a couple
  of components to get it work:
  - customdata, free callback for it
  - timer step, notifier code
  - start callback, update callback
- Once started, each job runs an own timer, and will for
  every time step check necessary updates, or close the
  job when ready. 
- No drawing happens in jobs, that's for notifiers!
- Every job stores an owner pointer, and based on this owner
  it will prevent multiple jobs to enter the stack. 
  Instead it will re-use a running job, signal it to stop
  and allow caller to re-initialize it even.
- Check new wm_jobs.c for more explanation. Jobs API is still
  under construction. 
  Fun: BLI_addtail(&wm->jobs, steve); :)

Put Node shader previews back using wmJobs
- Preview calculating is now fully threaded (1 thread still)
- Thanks to new event system + notifiers, you can see 
  previews update even while dragging sliders!
- Currently it only starts when you change a node setting.

Warning: the thread render shares Node data, so don't delete
nodes while it renders! This topic is on the todo to make safe.

Also:
- bug in region initialize (do_versions) showed channel list in
  node editor wrong.
- flagged the channel list 'hidden' now, it was really in the
  way! This is for later to work on anyway. 
- recoded Render API callbacks so it gets handlers passed on, 
  no globals to use anymore, remember?
- previewrender code gets now so much nicer! Will remove a lot
  of stuff from code soon.
This commit is contained in:
Ton Roosendaal 2009-01-22 14:59:49 +00:00
parent a017982074
commit 9cc59fb0c3
38 changed files with 14714 additions and 254 deletions

View File

@ -1761,9 +1761,9 @@ void nodeAddToPreview(bNode *node, float *col, int x, int y)
if(x>=0 && y>=0) {
if(x<preview->xsize && y<preview->ysize) {
float *tar= preview->rect+ 4*((preview->xsize*y) + x);
if(tar[0]==0.0f) {
//if(tar[0]==0.0f) {
QUATCOPY(tar, col);
}
//}
}
//else printf("prv out bound x y %d %d\n", x, y);
}
@ -2420,11 +2420,11 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
if(node) {
if(ntree->timecursor)
ntree->timecursor(totnode);
ntree->timecursor(ntree->tch, totnode);
if(ntree->stats_draw) {
char str[64];
sprintf(str, "Compositing %d %s", totnode, node->name);
ntree->stats_draw(str);
ntree->stats_draw(ntree->sdh, str);
}
totnode--;
@ -2440,7 +2440,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
rendering= 0;
/* test for ESC */
if(ntree->test_break && ntree->test_break()) {
if(ntree->test_break && ntree->test_break(ntree->tbh)) {
for(node= ntree->nodes.first; node; node= node->next)
node->exec |= NODE_READY;
}

View File

@ -224,6 +224,8 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
art->free(ar);
}
if(ar) {
if(ar->regiondata)
printf("regiondata free error\n");
BLI_freelistN(&ar->panels);
}
}

View File

@ -4471,7 +4471,7 @@ static void view3d_split_250(View3D *v3d, ListBase *regions)
if(ar->regiontype==RGN_TYPE_WINDOW && ar->regiondata==NULL) {
RegionView3D *rv3d;
rv3d= ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region v3d");
rv3d= ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region v3d patch");
rv3d->persp= v3d->persp;
rv3d->view= v3d->view;
rv3d->dist= v3d->dist;
@ -5416,6 +5416,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->alignment= RGN_ALIGN_LEFT;
ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
break;
case SPACE_ACTION:
ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
BLI_addtail(lb, ar);
@ -5424,6 +5425,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.scroll= V2D_SCROLL_BOTTOM;
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
break;
case SPACE_NLA:
ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
BLI_addtail(lb, ar);
@ -5432,6 +5434,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.scroll= V2D_SCROLL_BOTTOM;
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
break;
case SPACE_NODE:
ar= MEM_callocN(sizeof(ARegion), "nodetree area for node");
BLI_addtail(lb, ar);
@ -5439,6 +5442,10 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->alignment= RGN_ALIGN_LEFT;
ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
/* temporarily hide it */
ar->flag = RGN_FLAG_HIDDEN;
break;
case SPACE_FILE:
/* channel (bookmarks/directories) region */
ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,8 @@ struct Image;
struct ScrArea;
struct uiBlock;
struct Render;
struct bContext;
struct ID;
#define PREVIEW_RENDERSIZE 140
@ -68,21 +70,10 @@ pr_method:
#define PR_ICON_RENDER 1
#define PR_DO_RENDER 2
#if 0
void BIF_previewrender (struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method);
void BIF_previewrender_buts (struct SpaceButs *sbuts);
void BIF_previewdraw (struct ScrArea *sa, struct uiBlock *block);
void BIF_preview_changed (short id_code);
void ED_preview_init_dbase(void);
void ED_preview_free_dbase(void);
void BIF_preview_init_dbase (void);
void BIF_preview_free_dbase (void);
void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, int sizex, int sizey);
void BIF_view3d_previewrender(struct ScrArea *sa);
void BIF_view3d_previewdraw (struct ScrArea *sa, struct uiBlock *block);
void BIF_view3d_previewrender_free(struct View3D *v3d);
void BIF_view3d_previewrender_clear(struct ScrArea *sa);
void BIF_view3d_previewrender_signal(struct ScrArea *sa, short signal);
#endif
#endif

View File

@ -303,6 +303,7 @@ static void ui_tooltip_region_free(ARegion *ar)
data= ar->regiondata;
MEM_freeN(data->tip);
MEM_freeN(data);
ar->regiondata= NULL;
}
ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)

View File

@ -947,7 +947,7 @@ int *mesh_get_x_mirror_faces(Object *ob, EditMesh *em)
/* ****************** render BAKING ********************** */
/* threaded break test */
static int thread_break(void)
static int thread_break(void *unused)
{
return G.afbreek;
}
@ -1038,7 +1038,7 @@ void objects_bake_render(Scene *scene, short event, char **error_msg)
}
waitcursor(1);
RE_test_break_cb(re, thread_break);
RE_test_break_cb(re, NULL, thread_break);
G.afbreek= 0; /* blender_test_break uses this global */
RE_Database_Baking(re, scene, event, (active)? actob: NULL);

View File

@ -1665,7 +1665,7 @@ static int object_clear_origin_exec(bContext *C, wmOperator *op)
ED_anim_dag_flush_update(C);
ED_undo_push(C,"Clear origin");
WM_event_add_notifier(C, NC_SCENE|ND_TRANSFORM, CTX_data_scene(C));
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
return OPERATOR_FINISHED;
}
@ -2941,19 +2941,19 @@ void ED_object_enter_editmode(bContext *C, int flag)
/* to ensure all goes in restposition and without striding */
DAG_object_flush_update(scene, ob, OB_RECALC);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene);
}
else if(ob->type==OB_FONT) {
scene->obedit= ob; // XXX for context
// ok= 1;
// XXX make_editText();
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene);
}
else if(ob->type==OB_MBALL) {
scene->obedit= ob; // XXX for context
// ok= 1;
// XXX make_editMball();
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, scene);
}
else if(ob->type==OB_LATTICE) {
@ -2961,14 +2961,14 @@ void ED_object_enter_editmode(bContext *C, int flag)
ok= 1;
make_editLatt(ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, scene);
}
else if(ob->type==OB_SURF || ob->type==OB_CURVE) {
ok= 1;
scene->obedit= ob; // XXX for context
make_editNurb(ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, scene);
}
if(ok) {
@ -2976,7 +2976,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
}
else {
scene->obedit= NULL; // XXX for context
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, ob);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
}
if(flag & EM_WAITCURSOR) waitcursor(0);

View File

@ -84,6 +84,9 @@
#include "GPU_material.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_anim_api.h"
#include "ED_view3d.h"
@ -100,6 +103,19 @@
static int qtest() {return 0;}
/* XXX */
typedef struct ShaderPreview {
/* from wmJob */
void *owner;
short *stop, *do_update;
Scene *scene;
ID *id;
int sizex, sizey;
int pr_method;
} ShaderPreview;
static void set_previewrect(ScrArea *sa, RenderInfo *ri)
{
ARegion *ar= NULL; // XXX
@ -249,7 +265,7 @@ void BIF_preview_changed(short id_code)
static Main *pr_main= NULL;
void BIF_preview_init_dbase(void)
void ED_preview_init_dbase(void)
{
BlendFileData *bfd;
extern int datatoc_preview_blend_size;
@ -265,7 +281,7 @@ void BIF_preview_init_dbase(void)
G.fileflags &= ~G_FILE_NO_UI;
}
void BIF_preview_free_dbase(void)
void ED_preview_free_dbase(void)
{
if(pr_main)
free_main(pr_main);
@ -280,12 +296,13 @@ static Object *find_object(ListBase *lb, const char *name)
return ob;
}
/* call this with an ID pointer to initialize preview scene */
/* call this with ID NULL to restore assigned ID pointers in preview scene */
static Scene *preview_prepare_scene(Scene *scene, RenderInfo *ri, int id_type, ID *id, int pr_method)
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp)
{
Scene *sce;
Base *base;
ID *id= sp?sp->id:NULL;
if(pr_main==NULL) return NULL;
@ -331,7 +348,7 @@ static Scene *preview_prepare_scene(Scene *scene, RenderInfo *ri, int id_type, I
}
if(pr_method==PR_ICON_RENDER) {
if(sp->pr_method==PR_ICON_RENDER) {
if (mat->mode & MA_HALO) {
sce->lay= 1<<MA_FLAT;
}
@ -342,7 +359,7 @@ static Scene *preview_prepare_scene(Scene *scene, RenderInfo *ri, int id_type, I
else {
sce->lay= 1<<mat->pr_type;
if(mat->nodetree)
ntreeInitPreview(mat->nodetree, ri->pr_rectx, ri->pr_recty);
ntreeInitPreview(mat->nodetree, sp->sizex, sp->sizey);
}
}
else {
@ -412,7 +429,7 @@ static Scene *preview_prepare_scene(Scene *scene, RenderInfo *ri, int id_type, I
return NULL;
}
static void previewrender_progress(RenderResult *rr, volatile rcti *renrect)
void previewrender_progress(void *handle, RenderResult *rr, volatile rcti *renrect)
{
SpaceButs *sbuts= NULL; // XXX
RenderLayer *rl;
@ -436,10 +453,10 @@ static void previewrender_progress(RenderResult *rr, volatile rcti *renrect)
/* called by interface_icons.c, or by BIF_previewrender_buts or by nodes... */
void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method)
{
SpaceButs *sbuts= NULL; // XXX
Render *re;
RenderStats *rstats;
Scene *sce;
SpaceButs *sbuts= NULL;
int oldx= ri->pr_rectx, oldy= ri->pr_recty;
char name [32];
@ -453,7 +470,7 @@ void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struc
}
/* get the stuff from the builtin preview dbase */
sce= preview_prepare_scene(scene, ri, GS(id->name), id, pr_method);
// sce= preview_prepare_scene(scene, ri, GS(id->name), id, pr_method);
if(sce==NULL) return;
/* set drawing conditions OK */
@ -480,15 +497,15 @@ void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struc
/* handle cases */
if(pr_method==PR_DRAW_RENDER) {
RE_display_draw_cb(re, previewrender_progress);
RE_test_break_cb(re, qtest);
// RE_display_draw_cb(re, previewrender_progress);
// RE_test_break_cb(re, qtest);
sce->r.scemode |= R_NODE_PREVIEW;
if(sbuts->flag & SB_PRV_OSA)
sce->r.mode |= R_OSA;
sce->r.scemode &= ~R_NO_IMAGE_LOAD;
}
else if(pr_method==PR_DO_RENDER) {
RE_test_break_cb(re, qtest);
// RE_test_break_cb(re, qtest);
sce->r.scemode |= R_NODE_PREVIEW;
sce->r.scemode &= ~R_NO_IMAGE_LOAD;
}
@ -540,7 +557,7 @@ void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struc
}
/* unassign the pointers, reset vars */
preview_prepare_scene(scene, ri, GS(id->name), NULL, 0);
// preview_prepare_scene(scene, ri, GS(id->name), NULL, 0);
}
@ -646,13 +663,8 @@ void BIF_previewdraw(ScrArea *sa, uiBlock *block)
}
/* *************************** Preview for 3d window *********************** */
static void view3d_previewrender_stats(RenderStats *rs)
{
// if(rs->convertdone)
// printf("rendered %d %.3f\n", rs->partsdone, rs->lastframetime);
}
static void view3d_previewrender_progress(RenderResult *rr, volatile rcti *renrect)
void view3d_previewrender_progress(RenderResult *rr, volatile rcti *renrect)
{
// ScrArea *sa= NULL; // XXX
// View3D *v3d= NULL; // XXX
@ -814,9 +826,9 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
sprintf(name, "View3dPreview %p", sa);
re= ri->re= RE_NewRender(name);
RE_display_draw_cb(re, view3d_previewrender_progress);
RE_stats_draw_cb(re, view3d_previewrender_stats);
RE_test_break_cb(re, qtest);
//RE_display_draw_cb(re, view3d_previewrender_progress);
//RE_stats_draw_cb(re, view3d_previewrender_stats);
//RE_test_break_cb(re, qtest);
/* no osa, blur, seq, layers, etc for preview render */
rdata= scene->r;
@ -960,3 +972,138 @@ void BIF_view3d_previewdraw(struct ScrArea *sa, struct uiBlock *block)
// }
}
/* **************************** New preview system ****************** */
/* called by renderer, sets job update value */
static void shader_preview_draw(void *spv, RenderResult *rr, volatile struct rcti *rect)
{
ShaderPreview *sp= spv;
*(sp->do_update)= 1;
}
/* called by renderer, checks job value */
static int shader_preview_break(void *spv)
{
ShaderPreview *sp= spv;
return *(sp->stop);
}
static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
{
ShaderPreview *sp= customdata;
Render *re;
RenderStats *rstats;
Scene *sce;
char name [32];
sp->stop= stop;
sp->do_update= do_update;
/* get the stuff from the builtin preview dbase */
sce= preview_prepare_scene(sp->scene, GS(sp->id->name), sp);
if(sce==NULL) return;
sprintf(name, "Preview %p", sp->owner);
re= RE_GetRender(name);
/* full refreshed render from first tile */
if(re==NULL) {
re= RE_NewRender(name);
/* sce->r gets copied in RE_InitState! */
if(sp->pr_method==PR_DO_RENDER) {
sce->r.scemode |= R_NODE_PREVIEW;
sce->r.scemode &= ~R_NO_IMAGE_LOAD;
}
else { /* PR_ICON_RENDER */
sce->r.scemode &= ~R_NODE_PREVIEW;
sce->r.scemode |= R_NO_IMAGE_LOAD;
}
/* allocates render result */
RE_InitState(re, NULL, &sce->r, sp->sizex, sp->sizey, NULL);
}
/* callbacs are cleared on GetRender() */
if(sp->pr_method==PR_DO_RENDER) {
RE_display_draw_cb(re, sp, shader_preview_draw);
RE_test_break_cb(re, sp, shader_preview_break);
}
/* enforce preview image clear */
// if(GS(sp->id->name)==ID_MA) {
// Material *ma= (Material *)sp->id;
// ntreeClearPreview(ma->nodetree);
// }
/* entire cycle for render engine */
RE_SetCamera(re, sce->camera);
RE_Database_FromScene(re, sce, 1);
RE_TileProcessor(re, 0, 0); // actual render engine
RE_Database_Free(re);
*do_update= 1;
/* handle results */
if(sp->pr_method==PR_ICON_RENDER) {
//if(ri->rect==NULL)
// ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
//RE_ResultGet32(re, ri->rect);
}
else {
rstats= RE_GetStats(re);
if(rstats->totpart==rstats->partsdone && rstats->partsdone) {
// allqueues
}
else {
// if(pr_method==PR_DRAW_RENDER && qtest())
// addafterqueue(area->win, RENDERPREVIEW, 1);
}
}
/* unassign the pointers, reset vars */
preview_prepare_scene(sp->scene, GS(sp->id->name), NULL);
}
static void shader_preview_free(void *customdata)
{
ShaderPreview *sp= customdata;
MEM_freeN(sp);
}
static void shader_preview_update(void *customdata)
{
// ShaderPreview *sp= customdata;
}
void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, int sizey)
{
wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner);
ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
/* customdata for preview thread */
sp->scene= CTX_data_scene(C);
sp->owner= owner;
sp->sizex= sizex;
sp->sizey= sizey;
sp->pr_method= PR_DO_RENDER;
sp->id = id;
/* setup job */
WM_jobs_customdata(steve, sp, shader_preview_free);
WM_jobs_timer(steve, 0.1, NC_MATERIAL);
WM_jobs_callbacks(steve, shader_preview_startjob, NULL, shader_preview_update);
WM_jobs_start(steve);
}

View File

@ -121,7 +121,7 @@ static void imagewindow_progress(ScrArea *sa, RenderResult *rr, volatile rcti *r
/* in render window; display a couple of scanlines of rendered image */
/* NOTE: called while render, so no malloc allowed! */
static void imagewindow_progress_display_cb(RenderResult *rr, volatile rcti *rect)
static void imagewindow_progress_display_cb(void *handle, RenderResult *rr, volatile rcti *rect)
{
if (image_area) {
imagewindow_progress(image_area, rr, rect);
@ -132,7 +132,7 @@ static void imagewindow_progress_display_cb(RenderResult *rr, volatile rcti *rec
}
/* unused, init_display_cb is called on each render */
static void imagewindow_clear_display_cb(RenderResult *rr)
static void imagewindow_clear_display_cb(void *handle, RenderResult *rr)
{
if (image_area) {
}
@ -257,7 +257,7 @@ static ScrArea *imagewindow_set_render_display(bContext *C)
return sa;
}
static void imagewindow_init_display_cb(RenderResult *rr)
static void imagewindow_init_display_cb(void *handle, RenderResult *rr)
{
bContext *C= NULL; // XXX
@ -313,7 +313,7 @@ void imagewindow_toggle_render(bContext *C)
}
/* NOTE: called while render, so no malloc allowed! */
static void imagewindow_renderinfo_cb(RenderStats *rs)
static void imagewindow_renderinfo_cb(void *handle, RenderStats *rs)
{
if(image_area) {
// XXX BIF_make_render_text(rs);
@ -327,9 +327,10 @@ static void imagewindow_renderinfo_cb(RenderStats *rs)
void imagewindow_render_callbacks(Render *re)
{
RE_display_init_cb(re, imagewindow_init_display_cb);
RE_display_draw_cb(re, imagewindow_progress_display_cb);
RE_display_clear_cb(re, imagewindow_clear_display_cb);
RE_stats_draw_cb(re, imagewindow_renderinfo_cb);
/* XXX fill in correct handler */
RE_display_init_cb(re, NULL, imagewindow_init_display_cb);
RE_display_draw_cb(re, NULL, imagewindow_progress_display_cb);
RE_display_clear_cb(re, NULL, imagewindow_clear_display_cb);
RE_stats_draw_cb(re, NULL, imagewindow_renderinfo_cb);
}

View File

@ -71,6 +71,7 @@
#include "BMF_Api.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
#include "ED_util.h"
@ -497,7 +498,7 @@ static void socket_vector_menu_cb(bContext *C, void *node_v, void *ntree_v)
{
if(node_v && ntree_v) {
NodeTagChanged(ntree_v, node_v);
// addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC+((bNode *)node_v)->nr); XXX
// addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC); XXX
}
}
@ -606,6 +607,22 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
}
static void do_node_internal_buttons(bContext *C, void *node_v, int event)
{
SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
if(event==B_NODE_EXEC) {
if(snode->treetype==NTREE_SHADER)
WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, snode->id);
// else if(snode->treetype==NTREE_COMPOSIT)
// composit_node_event(snode, val);
// else if(snode->treetype==NTREE_TEXTURE)
// texture_node_event(snode, val);
}
}
static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNode *node)
{
bNodeSocket *sock;
@ -742,7 +759,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
//block= uiNewBlock(&sa->uiblocks, str, UI_EMBOSS, UI_HELV, sa->win);
block= uiBeginBlock(C, ar, str, UI_EMBOSS, UI_HELV);
uiBlockSetFlag(block, UI_BLOCK_NO_HILITE);
uiBlockSetHandleFunc(block, do_node_internal_buttons, node);
// XXX if(snode->id)
// XXX uiSetButLock(snode->id->lib!=NULL, ERROR_LIBDATA_MESSAGE);
}
@ -761,7 +778,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
float *butpoin= sock->ns.vec;
if(sock->type==SOCK_VALUE) {
bt= uiDefButF(block, NUM, B_NODE_EXEC+node->nr, sock->name,
bt= uiDefButF(block, NUM, B_NODE_EXEC, sock->name,
(short)sock->locx+NODE_DYS, (short)(sock->locy)-9, (short)node->width-NODE_DY, 17,
butpoin, sock->ns.min, sock->ns.max, 10, 2, "");
uiButSetFunc(bt, node_sync_cb, snode, node);
@ -776,7 +793,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
if(labelw>0) width= 40; else width= (short)node->width-NODE_DY;
bt= uiDefButF(block, COL, B_NODE_EXEC+node->nr, "",
bt= uiDefButF(block, COL, B_NODE_EXEC, "",
(short)(sock->locx+NODE_DYS), (short)sock->locy-8, width, 15,
butpoin, 0, 0, 0, 0, "");
uiButSetFunc(bt, node_sync_cb, snode, node);
@ -826,12 +843,13 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
if(node->typeinfo->butfunc) {
node->typeinfo->butfunc(block, snode->nodetree, node, &node->butr);
}
uiDrawBlock(C, block);
}
}
if(block)
if(block) {
uiEndBlock(C, block);
uiDrawBlock(C, block);
}
}
static void node_draw_hidden(View2D *v2d, SpaceNode *snode, bNode *node)

View File

@ -175,6 +175,7 @@ static void shader_node_previewrender(ScrArea *sa, SpaceNode *snode)
static void set_timecursor() {}
static int blender_test_break() { return 0; }
// XXX snode_handle_recalc can go away */
static void snode_handle_recalc(SpaceNode *snode)
{
if(snode->treetype==NTREE_SHADER) {

View File

@ -47,6 +47,7 @@
#include "BKE_context.h"
#include "BKE_screen.h"
#include "ED_previewrender.h"
#include "ED_space_api.h"
#include "ED_screen.h"
@ -85,7 +86,7 @@ static SpaceLink *node_new(const bContext *C)
ar->regiontype= RGN_TYPE_CHANNELS;
ar->alignment= RGN_ALIGN_LEFT;
ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
//ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
/* main area */
ar= MEM_callocN(sizeof(ARegion), "main area for node");
@ -134,6 +135,34 @@ static void node_init(struct wmWindowManager *wm, ScrArea *sa)
}
static void node_area_listener(ScrArea *sa, wmNotifier *wmn)
{
/* preview renders */
switch(wmn->category) {
case NC_SCENE:
break;
case NC_MATERIAL:
/* future: add ID check? */
if(wmn->data==ND_SHADING)
ED_area_tag_refresh(sa);
break;
}
}
static void node_area_refresh(const struct bContext *C, struct ScrArea *sa)
{
/* default now: refresh node is starting preview */
SpaceNode *snode= sa->spacedata.first;
if(snode->treetype==NTREE_SHADER) {
if(snode->nodetree) {
ED_preview_shader_job(C, sa, snode->id, 100, 100);
}
}
}
static SpaceLink *node_duplicate(SpaceLink *sl)
{
SpaceNode *snoden= MEM_dupallocN(sl);
@ -231,9 +260,6 @@ static void node_main_area_listener(ARegion *ar, wmNotifier *wmn)
case NC_MATERIAL:
ED_region_tag_redraw(ar);
break;
case ND_NODES:
ED_region_tag_redraw(ar);
break;
}
}
@ -269,6 +295,8 @@ void ED_spacetype_node(void)
st->duplicate= node_duplicate;
st->operatortypes= node_operatortypes;
st->keymap= node_keymap;
st->listener= node_area_listener;
st->refresh= node_area_refresh;
st->context= node_context;
/* regions: main window */
@ -295,7 +323,7 @@ void ED_spacetype_node(void)
/* regions: channels */
art= MEM_callocN(sizeof(ARegionType), "spacetype node region");
art->regionid = RGN_TYPE_CHANNELS;
art->minsizex= 200;
art->minsizex= 100;
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
art->init= node_channel_area_init;

View File

@ -182,9 +182,11 @@ typedef struct bNodeTree {
bNodeSocket *selout;
/* callbacks */
void (*timecursor)(int nr);
void (*stats_draw)(char *str);
int (*test_break)(void);
void (*timecursor)(void *, int nr);
void (*stats_draw)(void *, char *str);
int (*test_break)(void *);
void *tbh, *tch, *sdh;
} bNodeTree;
/* ntree->type, index */

View File

@ -65,9 +65,11 @@ typedef struct wmWindowManager {
ListBase operators; /* operator registry */
ListBase queue; /* refresh/redraw wmNotifier structs */
ListBase reports; /* information and error reports */
ListBase jobs; /* threaded jobs manager */
ListBase paintcursors; /* extra overlay cursors to draw, like circles */
/* used keymaps, optionally/partially saved */

View File

@ -46,5 +46,5 @@ CPPFLAGS += -I../../gpu
CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
DIRS = SHD_nodes CMP_nodes
DIRS = SHD_nodes CMP_nodes TEX_nodes
include nan_subdirs.mk

View File

@ -307,18 +307,18 @@ static void progressiverad_rr(Render *re)
applyformfactors_rr(re, shoot, shootrf);
it++;
re->timecursor(it);
re->timecursor(re->tch, it);
clear_backface_test_rr(re);
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
if(RG.maxiter && RG.maxiter<=it) break;
findshoot_rr(re, &shoot, &shootrf);
}
printf(" Unshot energy:%f\n", 1000.0*maxenergy);
re->timecursor((re->scene->r.cfra));
re->timecursor(re->tch, re->scene->r.cfra);
}
static RadFace *radfaces=NULL;

View File

@ -200,14 +200,13 @@ void RE_make_stars(struct Render *re, struct Scene *scenev3d, void (*initfunc)(v
void (*vertexfunc)(float*), void (*termfunc)(void));
/* display and event callbacks */
void RE_display_init_cb (struct Render *re, void (*f)(RenderResult *rr));
void RE_display_clear_cb(struct Render *re, void (*f)(RenderResult *rr));
void RE_display_draw_cb (struct Render *re, void (*f)(RenderResult *rr, volatile struct rcti *rect));
void RE_stats_draw_cb (struct Render *re, void (*f)(RenderStats *rs));
void RE_timecursor_cb (struct Render *re, void (*f)(int));
void RE_test_break_cb (struct Render *re, int (*f)(void));
void RE_test_return_cb (struct Render *re, int (*f)(void));
void RE_error_cb (struct Render *re, void (*f)(char *str));
void RE_display_init_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr));
void RE_display_clear_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr));
void RE_display_draw_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile struct rcti *rect));
void RE_stats_draw_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderStats *rs));
void RE_timecursor_cb (struct Render *re, void *handle, void (*f)(void *handle, int));
void RE_test_break_cb (struct Render *re, void *handle, int (*f)(void *handle));
void RE_error_cb (struct Render *re, void *handle, void (*f)(void *handle, char *str));
/* should move to kernel once... still unsure on how/where */
float RE_filter_value(int type, float x);

View File

@ -208,16 +208,23 @@ struct Render
struct MemArena *memArena;
/* callbacks */
void (*display_init)(RenderResult *rr);
void (*display_clear)(RenderResult *rr);
void (*display_draw)(RenderResult *rr, volatile rcti *rect);
void (*display_init)(void *handle, RenderResult *rr);
void *dih;
void (*display_clear)(void *handle, RenderResult *rr);
void *dch;
void (*display_draw)(void *handle, RenderResult *rr, volatile rcti *rect);
void *ddh;
void (*stats_draw)(RenderStats *ri);
void (*timecursor)(int i);
void (*stats_draw)(void *handle, RenderStats *ri);
void *sdh;
void (*timecursor)(void *handle, int i);
void *tch;
int (*test_break)(void);
int (*test_return)(void);
void (*error)(char *str);
int (*test_break)(void *handle);
void *tbh;
void (*error)(void *handle, char *str);
void *erh;
RenderStats i;
};

View File

@ -2021,7 +2021,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if(orco1==0)
orco+=3;
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
@ -4357,7 +4357,7 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject
re->i.totstrand= re->totstrand;
re->i.tothalo= re->tothalo;
re->i.totlamp= re->totlamp;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
}
ob->flag |= OB_DONE;
@ -4727,7 +4727,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
else
init_render_object(re, obd, ob, dob, timeoffset, vectorlay);
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
}
free_object_duplilist(lb);
@ -4738,7 +4738,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
}
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
}
/* objects in groups with OB_RENDER_DUPLI set still need to be created,
@ -4755,7 +4755,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
}
}
if(!re->test_break())
if(!re->test_break(re->tbh))
RE_makeRenderInstances(re);
}
@ -4817,7 +4817,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
/* MAKE RENDER DATA */
database_init_objects(re, lay, 0, 0, 0, 0);
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
int tothalo;
set_material_lightgroups(re);
@ -4832,17 +4832,17 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
re->i.totstrand= re->totstrand;
re->i.tothalo= re->tothalo;
re->i.totlamp= re->totlamp;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
/* don't sort stars */
tothalo= re->tothalo;
if(!re->test_break())
if(!re->test_break(re->tbh))
if(re->wrld.mode & WO_STARS)
RE_make_stars(re, NULL, NULL, NULL, NULL);
sort_halos(re, tothalo);
re->i.infostr= "Creating Shadowbuffers";
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
/* SHADOW BUFFER */
threaded_makeshadowbufs(re);
@ -4851,43 +4851,43 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
/* although radio mode could be useful at some point, later */
if (re->r.renderer==R_INTERN) {
/* RADIO (uses no R anymore) */
if(!re->test_break())
if(!re->test_break(re->tbh))
if(re->r.mode & R_RADIO) do_radio_render(re);
/* raytree */
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
if(re->r.mode & R_RAYTRACE) {
makeraytree(re);
}
}
/* ENVIRONMENT MAPS */
if(!re->test_break())
if(!re->test_break(re->tbh))
make_envmaps(re);
}
if(!re->test_break())
if(!re->test_break(re->tbh))
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
/* Occlusion */
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break())
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break(re->tbh))
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
if(re->r.renderer==R_INTERN)
if(re->r.mode & R_SHADOW)
make_occ_tree(re);
/* SSS */
if((re->r.mode & R_SSS) && !re->test_break())
if((re->r.mode & R_SSS) && !re->test_break(re->tbh))
if(re->r.renderer==R_INTERN)
make_sss_tree(re);
}
if(re->test_break())
if(re->test_break(re->tbh))
RE_Database_Free(re);
else
re->i.convertdone= 1;
re->i.infostr= NULL;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
}
/* exported call to recalculate hoco for vertices, when winmat changed */
@ -4940,7 +4940,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, int timeoffset)
/* MAKE RENDER DATA */
database_init_objects(re, lay, 0, 0, 0, timeoffset);
if(!re->test_break())
if(!re->test_break(re->tbh))
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
/* do this in end, particles for example need cfra */
@ -5313,7 +5313,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
RE_Database_Free(re);
re->strandsurface= strandsurface;
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
/* creates entire dbase */
re->i.infostr= "Calculating next frame vectors";
@ -5328,10 +5328,10 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
RE_Database_Free(re);
re->strandsurface= strandsurface;
if(!re->test_break())
if(!re->test_break(re->tbh))
RE_Database_FromScene(re, sce, 1);
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
for(step= 0; step<2; step++) {
if(step)
@ -5400,7 +5400,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
}
re->i.infostr= NULL;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
}
@ -5499,12 +5499,12 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
threaded_makeshadowbufs(re);
/* raytree */
if(!re->test_break())
if(!re->test_break(re->tbh))
if(re->r.mode & R_RAYTRACE)
makeraytree(re);
/* occlusion */
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break())
if((re->wrld.mode & WO_AMB_OCC) && !re->test_break(re->tbh))
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
if(re->r.mode & R_SHADOW)
make_occ_tree(re);

View File

@ -408,7 +408,7 @@ static void render_envmap(Render *re, EnvMap *env)
if(env->type==ENV_PLANE && part!=1)
continue;
re->display_clear(envre->result);
re->display_clear(re->dch, envre->result);
MTC_Mat4CpyMat4(tmat, orthmat);
envmap_transmatrix(tmat, part);
@ -429,7 +429,7 @@ static void render_envmap(Render *re, EnvMap *env)
env_hideobject(envre, env->object);
env_set_imats(envre);
if(re->test_break()==0) {
if(re->test_break(re->tbh)==0) {
RE_TileProcessor(envre, 0, 0);
}
@ -437,7 +437,7 @@ static void render_envmap(Render *re, EnvMap *env)
env_showobjects(envre);
env_rotate_scene(envre, tmat, 0);
if(re->test_break()==0) {
if(re->test_break(re->tbh)==0) {
RenderLayer *rl= envre->result->layers.first;
int y;
char *alpha;
@ -455,11 +455,11 @@ static void render_envmap(Render *re, EnvMap *env)
env->cube[part]= ibuf;
}
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
}
if(re->test_break()) BKE_free_envmapdata(env);
if(re->test_break(re->tbh)) BKE_free_envmapdata(env);
else {
if(envre->r.mode & R_OSA) env->ok= ENV_OSA;
else env->ok= ENV_NORMAL;
@ -486,7 +486,7 @@ void make_envmaps(Render *re)
re->r.mode &= ~R_RAYTRACE;
re->i.infostr= "Creating Environment maps";
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
/* 5 = hardcoded max recursion level */
while(depth<5) {
@ -547,8 +547,8 @@ void make_envmaps(Render *re)
}
if(do_init) {
re->display_init(re->result);
re->display_clear(re->result);
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
// re->flag |= R_REDRAW_PRV;
}
// restore

View File

@ -1292,11 +1292,11 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
VECADDFAC(co, co, n, 1e-8f);
occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL);
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
if(re->test_break())
if(re->test_break(re->tbh))
break;
for(i=0; i<tree->totface; i++) {
@ -1546,7 +1546,7 @@ void make_occ_tree(Render *re)
R= *re;
re->i.infostr= "Occlusion preprocessing";
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
re->occlusiontree= occ_tree_build(re);
@ -1738,7 +1738,7 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
sample->filled= 1;
}
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
}

View File

@ -122,20 +122,20 @@ static int commandline_threads= -1;
static volatile int g_break= 0;
static int thread_break(void)
static int thread_break(void *unused)
{
return g_break;
}
/* default callbacks, set in each new render */
static void result_nothing(RenderResult *rr) {}
static void result_rcti_nothing(RenderResult *rr, volatile struct rcti *rect) {}
static void stats_nothing(RenderStats *rs) {}
static void int_nothing(int val) {}
static int void_nothing(void) {return 0;}
static void print_error(char *str) {printf("ERROR: %s\n", str);}
static void result_nothing(void *unused, RenderResult *rr) {}
static void result_rcti_nothing(void *unused, RenderResult *rr, volatile struct rcti *rect) {}
static void stats_nothing(void *unused, RenderStats *rs) {}
static void int_nothing(void *unused, int val) {}
static int void_nothing(void *unused) {return 0;}
static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);}
static void stats_background(RenderStats *rs)
static void stats_background(void *unused, RenderStats *rs)
{
uintptr_t mem_in_use= MEM_get_memory_in_use();
float megs_used_memory= mem_in_use/(1024.0*1024.0);
@ -1019,12 +1019,13 @@ Render *RE_NewRender(const char *name)
re->display_draw= result_rcti_nothing;
re->timecursor= int_nothing;
re->test_break= void_nothing;
re->test_return= void_nothing;
re->error= print_error;
if(G.background)
re->stats_draw= stats_background;
else
re->stats_draw= stats_nothing;
/* clear callback handles */
re->dih= re->dch= re->ddh= re->sdh= re->tch= re->tbh= re->erh= NULL;
/* init some variables */
re->ycor= 1.0f;
@ -1083,7 +1084,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy
if(re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->imtype) &&
(re->rectx < 16 || re->recty < 16) )) {
re->error("Image too small");
re->error(re->erh, "Image too small");
re->ok= 0;
}
else {
@ -1173,39 +1174,41 @@ void RE_SetView(Render *re, float mat[][4])
}
/* image and movie output has to move to either imbuf or kernel */
void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr))
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
re->display_init= f;
re->dih= handle;
}
void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr))
void RE_display_clear_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
re->display_clear= f;
re->dch= handle;
}
void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, volatile rcti *rect))
void RE_display_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile rcti *rect))
{
re->display_draw= f;
re->ddh= handle;
}
void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs))
void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs))
{
re->stats_draw= f;
re->sdh= handle;
}
void RE_timecursor_cb(Render *re, void (*f)(int))
void RE_timecursor_cb(Render *re, void *handle, void (*f)(void *handle, int))
{
re->timecursor= f;
re->tch= handle;
}
void RE_test_break_cb(Render *re, int (*f)(void))
void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))
{
re->test_break= f;
re->tbh= handle;
}
void RE_test_return_cb(Render *re, int (*f)(void))
{
re->test_return= f;
}
void RE_error_cb(Render *re, void (*f)(char *str))
void RE_error_cb(Render *re, void *handle, void (*f)(void *handle, char *str))
{
re->error= f;
re->erh= handle;
}
@ -1253,7 +1256,7 @@ static void *do_part_thread(void *pa_v)
RenderPart *pa= pa_v;
/* need to return nicely all parts on esc */
if(R.test_break()==0) {
if(R.test_break(R.tbh)==0) {
if(!R.sss_points && (R.r.scemode & R_FULL_SAMPLE))
pa->result= new_full_sample_buffers(&R, &pa->fullresult, &pa->disprect, pa->crop);
@ -1289,7 +1292,7 @@ static void render_tile_processor(Render *re, int firsttile)
{
RenderPart *pa;
if(re->test_break())
if(re->test_break(re->tbh))
return;
/* hrmf... exception, this is used for preview render, re-entrant, so render result has to be re-used */
@ -1298,7 +1301,7 @@ static void render_tile_processor(Render *re, int firsttile)
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
}
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
if(re->result==NULL)
return;
@ -1317,17 +1320,17 @@ static void render_tile_processor(Render *re, int firsttile)
do_part_thread(pa);
if(pa->result) {
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
if(render_display_draw_enabled(re))
re->display_draw(pa->result, NULL);
re->display_draw(re->ddh, pa->result, NULL);
re->i.partsdone++;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
}
RE_FreeRenderResult(pa->result);
pa->result= NULL;
}
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
}
@ -1444,7 +1447,7 @@ static void print_part_stats(Render *re, RenderPart *pa)
sprintf(str, "Part %d-%d", pa->nr, re->i.totpart);
re->i.infostr= str;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
re->i.infostr= NULL;
}
@ -1514,7 +1517,7 @@ static void threaded_tile_processor(Render *re)
while(rendering) {
if(re->test_break())
if(re->test_break(re->tbh))
PIL_sleep_ms(50);
else if(nextpa && BLI_available_threads(&threads)) {
drawtimer= 0;
@ -1547,7 +1550,7 @@ static void threaded_tile_processor(Render *re)
if(pa->result) {
if(render_display_draw_enabled(re))
re->display_draw(pa->result, NULL);
re->display_draw(re->ddh, pa->result, NULL);
print_part_stats(re, pa);
free_render_result(&pa->fullresult, pa->result);
@ -1560,7 +1563,7 @@ static void threaded_tile_processor(Render *re)
rendering= 1;
if(pa->nr && pa->result && drawtimer>20) {
if(render_display_draw_enabled(re))
re->display_draw(pa->result, &pa->result->renrect);
re->display_draw(re->ddh, pa->result, &pa->result->renrect);
hasdrawn= 1;
}
}
@ -1569,7 +1572,7 @@ static void threaded_tile_processor(Render *re)
drawtimer= 0;
/* on break, wait for all slots to get freed */
if( (g_break=re->test_break()) && BLI_available_threads(&threads)==re->r.threads)
if( (g_break=re->test_break(re->tbh)) && BLI_available_threads(&threads)==re->r.threads)
rendering= 0;
}
@ -1615,7 +1618,7 @@ void RE_TileProcessor(Render *re, int firsttile, int threaded)
if(!re->sss_points)
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
}
@ -1636,7 +1639,7 @@ static void do_render_3d(Render *re)
/* do left-over 3d post effects (flares) */
if(re->flag & R_HALO)
if(!re->test_break())
if(!re->test_break(re->tbh))
add_halo_flare(re);
@ -1709,7 +1712,7 @@ static void do_render_blur_3d(Render *re)
blurfac= 1.0f/(float)(re->r.osa-blur);
merge_renderresult_blur(rres, re->result, blurfac);
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
}
/* swap results */
@ -1721,7 +1724,7 @@ static void do_render_blur_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
}
@ -1788,7 +1791,7 @@ static void do_render_fields_3d(Render *re)
re->result= NULL;
/* second field */
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
re->i.curfield= 2; /* stats */
@ -1827,7 +1830,7 @@ static void do_render_fields_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
}
static void load_backbuffer(Render *re)
@ -1910,8 +1913,8 @@ static void do_render_fields_blur_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
re->display_init(re->result);
re->display_draw(re->result, NULL);
re->display_init(re->dih, re->result);
re->display_draw(re->ddh, re->result, NULL);
}
}
}
@ -2017,10 +2020,10 @@ static int composite_needs_render(Scene *sce)
}
/* bad call... need to think over proper method still */
static void render_composit_stats(char *str)
static void render_composit_stats(void *unused, char *str)
{
R.i.infostr= str;
R.stats_draw(&R.i);
R.stats_draw(R.sdh, &R.i);
R.i.infostr= NULL;
}
@ -2086,10 +2089,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
if(sample!=re->osa-1) {
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
}
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
@ -2127,8 +2130,8 @@ void RE_MergeFullSample(Render *re, Scene *sce, bNodeTree *ntree)
RE_ReadRenderResult(re->scene, re->scene);
/* and now we can draw (result is there) */
re->display_init(re->result);
re->display_clear(re->result);
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
do_merge_fullsample(re, ntree);
}
@ -2152,7 +2155,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
if(re->r.scemode & R_SINGLE_LAYER)
pop_render_result(re);
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
if(ntree) {
ntreeCompositTagRender(re->scene);
@ -2165,9 +2168,11 @@ static void do_render_composite_fields_blur_3d(Render *re)
if((re->r.scemode & R_SINGLE_LAYER)==0)
ntree_render_scenes(re);
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
ntree->stats_draw= render_composit_stats;
ntree->test_break= re->test_break;
ntree->sdh= re->sdh;
ntree->tbh= re->tbh;
/* in case it was never initialized */
R.stats_draw= re->stats_draw;
@ -2178,6 +2183,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
ntree->stats_draw= NULL;
ntree->test_break= NULL;
ntree->tbh= ntree->sdh= NULL;
}
}
else if(re->r.scemode & R_FULL_SAMPLE)
@ -2187,7 +2193,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
}
#ifndef DISABLE_YAFRAY
@ -2237,14 +2243,14 @@ static void yafrayRender(Render *re)
RE_FreeRenderResult(re->result);
re->result= rres;
re->display_init(re->result);
re->display_draw(re->result, NULL);
re->display_init(re->dih, re->result);
re->display_draw(re->ddh, re->result, NULL);
}
}
}
re->i.lastframetime = PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
RE_Database_Free(re);
}
@ -2273,11 +2279,11 @@ static void do_render_all_options(Render *re)
if(re->r.scemode & R_DOSEQ) {
/* note: do_render_seq() frees rect32 when sequencer returns float images */
if(!re->test_break())
if(!re->test_break(re->tbh))
; //XXX do_render_seq(re->result, re->r.cfra);
re->stats_draw(&re->i);
re->display_draw(re->result, NULL);
re->stats_draw(re->sdh, &re->i);
re->display_draw(re->ddh, re->result, NULL);
}
else {
@ -2296,12 +2302,12 @@ static void do_render_all_options(Render *re)
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
/* stamp image info here */
if((re->r.scemode & R_STAMP_INFO) && (re->r.stamp & R_STAMP_DRAW)) {
renderresult_stampinfo(re->scene);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
}
}
@ -2312,11 +2318,11 @@ static int is_rendering_allowed(Render *re)
/* forbidden combinations */
if(re->r.mode & R_PANORAMA) {
if(re->r.mode & R_BORDER) {
re->error("No border supported for Panorama");
re->error(re->erh, "No border supported for Panorama");
return 0;
}
if(re->r.mode & R_ORTHO) {
re->error("No Ortho render possible for Panorama");
re->error(re->erh, "No Ortho render possible for Panorama");
return 0;
}
}
@ -2324,11 +2330,11 @@ static int is_rendering_allowed(Render *re)
if(re->r.mode & R_BORDER) {
if(re->r.border.xmax <= re->r.border.xmin ||
re->r.border.ymax <= re->r.border.ymin) {
re->error("No border area selected.");
re->error(re->erh, "No border area selected.");
return 0;
}
if(re->r.scemode & R_EXR_TILE_FILE) {
re->error("Border render and Buffer-save not supported yet");
re->error(re->erh, "Border render and Buffer-save not supported yet");
return 0;
}
}
@ -2339,7 +2345,7 @@ static int is_rendering_allowed(Render *re)
render_unique_exr_name(re, str, 0);
if (BLI_is_writable(str)==0) {
re->error("Can not save render buffers, check the temp default path");
re->error(re->erh, "Can not save render buffers, check the temp default path");
return 0;
}
@ -2349,7 +2355,7 @@ static int is_rendering_allowed(Render *re)
/* no fullsample and edge */
if((re->r.scemode & R_FULL_SAMPLE) && (re->r.mode & R_EDGE)) {
re->error("Full Sample doesn't support Edge Enhance");
re->error(re->erh, "Full Sample doesn't support Edge Enhance");
return 0;
}
@ -2363,7 +2369,7 @@ static int is_rendering_allowed(Render *re)
bNode *node;
if(ntree==NULL) {
re->error("No Nodetree in Scene");
re->error(re->erh, "No Nodetree in Scene");
return 0;
}
@ -2373,7 +2379,7 @@ static int is_rendering_allowed(Render *re)
if(node==NULL) {
re->error("No Render Output Node in Scene");
re->error(re->erh, "No Render Output Node in Scene");
return 0;
}
}
@ -2385,7 +2391,7 @@ static int is_rendering_allowed(Render *re)
if(!(re->r.scemode & (R_DOSEQ|R_DOCOMP))) {
if(re->scene->camera==NULL) {
re->error("No camera");
re->error(re->erh, "No camera");
return 0;
}
}
@ -2401,13 +2407,13 @@ static int is_rendering_allowed(Render *re)
if(!(srl->layflag & SCE_LAY_DISABLE))
break;
if(srl==NULL) {
re->error("All RenderLayers are disabled");
re->error(re->erh, "All RenderLayers are disabled");
return 0;
}
/* renderer */
if(!ELEM(re->r.renderer, R_INTERN, R_YAFRAY)) {
re->error("Unknown render engine set");
re->error(re->erh, "Unknown render engine set");
return 0;
}
return 1;
@ -2464,8 +2470,8 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim)
if(!is_rendering_allowed(re))
return 0;
re->display_init(re->result);
re->display_clear(re->result);
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
return 1;
}
@ -2585,11 +2591,11 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
do_render_all_options(re);
if(re->test_break() == 0) {
if(re->test_break(re->tbh) == 0) {
do_write_image_or_movie(re, scene, mh);
}
} else {
re->test_break();
re->test_break(re->tbh);
}
}
} else {
@ -2633,7 +2639,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
do_render_all_options(re);
if(re->test_break() == 0) {
if(re->test_break(re->tbh) == 0) {
do_write_image_or_movie(re, scene, mh);
}

View File

@ -180,13 +180,13 @@ void makeraytree(Render *re)
double time= PIL_check_seconds_timer();
vlr= obr->vlaknodes[v>>8].vlak;
if(re->test_break())
if(re->test_break(re->tbh))
break;
if(time-lasttime>1.0f) {
char str[32];
sprintf(str, "Filling Octree: %d", totv);
re->i.infostr= str;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
re->i.infostr= NULL;
lasttime= time;
}
@ -202,7 +202,7 @@ void makeraytree(Render *re)
RE_ray_tree_done(re->raytree);
re->i.infostr= NULL;
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
}
static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)

View File

@ -314,7 +314,7 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl)
}
}
}
if(R.test_break() ) break;
if(R.test_break(R.tbh) ) break;
}
}
@ -430,7 +430,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
if(rd) rd++;
}
if(y&1)
if(R.test_break()) break;
if(R.test_break(R.tbh)) break;
}
}
@ -662,7 +662,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
}
if(y&1)
if(R.test_break()) break;
if(R.test_break(R.tbh)) break;
}
}
@ -760,7 +760,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
int samp;
int x, y, seed, crop=0, offs=0, od;
if(R.test_break()) return;
if(R.test_break(R.tbh)) return;
/* irregular shadowb buffer creation */
if(R.r.mode & R_SHADOW)
@ -821,7 +821,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
rectdaps+= pa->rectx;
offs+= pa->rectx;
if(y&1) if(R.test_break()) break;
if(y&1) if(R.test_break(R.tbh)) break;
}
/* disable scanline updating */
@ -1142,7 +1142,7 @@ void zbufshadeDA_tile(RenderPart *pa)
sdata.psmlist= &psmlist;
sdata.edgerect= edgerect;
zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
if(R.test_break()) break;
if(R.test_break(R.tbh)) break;
}
/* shades solid */
@ -1280,7 +1280,7 @@ void zbufshade_tile(RenderPart *pa)
zbuffer_solid(pa, rl, NULL, NULL);
if(!R.test_break()) { /* NOTE: this if() is not consistant */
if(!R.test_break(R.tbh)) { /* NOTE: this if() is not consistant */
/* edges only for solid part, ztransp doesn't support it yet anti-aliased */
if(rl->layflag & SCE_LAY_EDGE) {
@ -1325,7 +1325,7 @@ void zbufshade_tile(RenderPart *pa)
}
}
if(y&1)
if(R.test_break()) break;
if(R.test_break(R.tbh)) break;
}
if(R.occlusiontree)
@ -1377,7 +1377,7 @@ void zbufshade_tile(RenderPart *pa)
if(rl->layflag & SCE_LAY_SKY)
sky_tile(pa, rl);
if(!R.test_break()) {
if(!R.test_break(R.tbh)) {
if(rl->layflag & SCE_LAY_EDGE)
if(R.r.mode & R_EDGE)
edge_enhance_add(pa, rl->rectf, edgerect);
@ -1717,7 +1717,7 @@ void zbufshade_sss_tile(RenderPart *pa)
}
if(y&1)
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
}
/* note: after adding we do not free these arrays, sss keeps them */
@ -1797,7 +1797,7 @@ static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* pos
rectft+= 4*rr->rectx;
if(R.test_break()) break;
if(R.test_break(R.tbh)) break;
}
}
}
@ -1915,7 +1915,7 @@ void add_halo_flare(Render *re)
if(do_draw) {
/* weak... the display callback wants an active renderlayer pointer... */
rr->renlay= rl;
re->display_draw(rr, NULL);
re->display_draw(re->ddh, rr, NULL);
}
R.r.mode= mode;
@ -2334,7 +2334,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
ShadeInput *shi= ssamp->shi;
/* fast threadsafe break test */
if(R.test_break())
if(R.test_break(R.tbh))
return;
/* setup render coordinates */
@ -2567,7 +2567,7 @@ static void *do_bake_thread(void *bs_v)
shade_tface(bs);
/* fast threadsafe break test */
if(R.test_break())
if(R.test_break(R.tbh))
break;
}
bs->ready= 1;

View File

@ -425,7 +425,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
/* create Z tiles (for compression): this system is 24 bits!!! */
compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE);
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
@ -457,13 +457,13 @@ static void *do_shadow_thread(void *re_v)
lar->thread_ready= 1;
BLI_unlock_thread(LOCK_CUSTOM1);
}
} while(lar && !re->test_break());
} while(lar && !re->test_break(re->tbh));
return NULL;
}
static volatile int g_break= 0;
static int thread_break(void)
static int thread_break(void *unused)
{
return g_break;
}
@ -473,7 +473,7 @@ void threaded_makeshadowbufs(Render *re)
ListBase threads;
LampRen *lar;
int a, totthread= 0;
int (*test_break)(void);
int (*test_break)(void *);
/* count number of threads to use */
if(G.rendering) {
@ -488,7 +488,7 @@ void threaded_makeshadowbufs(Render *re)
if(totthread <= 1) {
for(lar=re->lampren.first; lar; lar= lar->next) {
if(re->test_break()) break;
if(re->test_break(re->tbh)) break;
if(lar->shb) {
/* if type is irregular, this only sets the perspective matrix and autoclips */
makeshadowbuf(re, lar);
@ -512,7 +512,7 @@ void threaded_makeshadowbufs(Render *re)
/* keep rendering as long as there are shadow buffers not ready */
do {
if((g_break=test_break()))
if((g_break=test_break(re->tbh)))
break;
PIL_sleep_ms(50);

View File

@ -852,7 +852,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
float (*co)[3] = NULL, (*color)[3] = NULL, *area = NULL;
int totpoint = 0, osa, osaflag, partsdone;
if(re->test_break())
if(re->test_break(re->tbh))
return;
points.first= points.last= NULL;
@ -888,7 +888,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
return;
/* merge points together into a single buffer */
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
for(totpoint=0, p=points.first; p; p=p->next)
totpoint += p->totpoint;
@ -913,7 +913,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
BLI_freelistN(&points);
/* build tree */
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData");
float ior= mat->sss_ior, cfac= mat->sss_colfac;
float *col= mat->sss_col, *radius= mat->sss_radius;
@ -981,7 +981,7 @@ void make_sss_tree(Render *re)
re->sss_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
re->i.infostr= "SSS preprocessing";
re->stats_draw(&re->i);
re->stats_draw(re->sdh, &re->i);
for(mat= G.main->mat.first; mat; mat= mat->id.next)
if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS))

View File

@ -773,7 +773,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
float z[4], bounds[4], winmat[4][4];
int a, b, c, i, totsegment, clip[4];
if(re->test_break())
if(re->test_break(re->tbh))
return 0;
if(re->totstrand == 0)
return 0;
@ -881,7 +881,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
}
}
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
/* convert list to array and sort */
sortsegments= MEM_mallocN(sizeof(StrandSortSegment)*totsegment, "StrandSortSegment");
for(a=0, sortseg=firstseg; a<totsegment; a++, sortseg=sortseg->next)
@ -893,11 +893,11 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand
spart.totapixbuf= MEM_callocN(sizeof(int)*pa->rectx*pa->recty, "totapixbuf");
if(!re->test_break()) {
if(!re->test_break(re->tbh)) {
/* render segments in sorted order */
sortseg= sortsegments;
for(a=0; a<totsegment; a++, sortseg++) {
if(re->test_break())
if(re->test_break(re->tbh))
break;
obi= &re->objectinstance[sortseg->obi];

View File

@ -2495,7 +2495,7 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
}
}
if((a & 255)==255 && re->test_break())
if((a & 255)==255 && re->test_break(re->tbh))
break;
}
@ -2544,13 +2544,13 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
}
}
if((a & 255)==255 && re->test_break())
if((a & 255)==255 && re->test_break(re->tbh))
break;
}
}
}
if(re->test_break())
if(re->test_break(re->tbh))
break;
}
@ -3512,13 +3512,13 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
}
}
if((v & 255)==255)
if(R.test_break())
if(R.test_break(R.tbh))
break;
}
}
}
if(R.test_break()) break;
if(R.test_break(R.tbh)) break;
}
for(zsample=0; zsample<samples; zsample++) {
@ -4013,7 +4013,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
unsigned short *ztramask= NULL, filled;
/* looks nicer for calling code */
if(R.test_break())
if(R.test_break(R.tbh))
return NULL;
if(R.osa>16) { /* MAX_OSA */
@ -4096,7 +4096,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
apstrand= aprectstrand;
od= offs;
if(R.test_break())
if(R.test_break(R.tbh))
break;
for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, apstrand++, pass+=4, od++) {

View File

@ -36,9 +36,13 @@ struct IDProperty;
struct wmEvent;
struct wmEventHandler;
struct wmGesture;
struct wmJob;
struct wmNotifier;
struct rcti;
struct PointerRNA;
typedef struct wmJob wmJob;
/* general API */
void WM_setprefsize (int stax, int stay, int sizx, int sizy);
@ -168,5 +172,18 @@ void wmOrtho2 (float x1, float x2, float y1, float y2);
void WM_set_framebuffer_index_color(int index);
int WM_framebuffer_to_index(unsigned int col);
/* threaded Jobs Manager */
struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner);
void WM_jobs_customdata(struct wmJob *, void *customdata, void (*free)(void *));
void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note);
void WM_jobs_callbacks(struct wmJob *,
void (*startjob)(void *, short *, short *),
void (*listener)(struct wmJob *, struct wmNotifier *),
void (*update)(void *));
void WM_jobs_start(struct wmJob *);
#endif /* WM_API_H */

View File

@ -517,7 +517,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
static int wm_event_always_pass(wmEvent *event)
{
/* some events we always pass on, to ensure proper communication */
return ELEM4(event->type, TIMER, TIMER0, TIMER1, TIMER2);
return ELEM5(event->type, TIMER, TIMER0, TIMER1, TIMER2, TIMERJOBS);
}
/* Warning: this function removes a modal handler, when finished */

View File

@ -82,6 +82,7 @@
#include "wm_files.h"
#include "wm_window.h"
#include "ED_previewrender.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_util.h"
@ -142,7 +143,7 @@ void WM_init(bContext *C)
sound_init_listener();
// init_node_butfuncs();
// XXX BIF_preview_init_dbase();
ED_preview_init_dbase();
GPU_extensions_init();
@ -215,7 +216,8 @@ void WM_exit(bContext *C)
#endif
// fastshade_free_render(); /* shaded view */
free_blender(); /* blender.c, does entire library */
ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */
free_blender(); /* blender.c, does entire library and spacetypes */
// free_matcopybuf();
// free_ipocopybuf();
free_actcopybuf();
@ -260,7 +262,6 @@ void WM_exit(bContext *C)
UI_exit();
BLI_freelistN(&U.themes);
// XXX BIF_preview_free_dbase();
RNA_exit();

View File

@ -0,0 +1,270 @@
/**
* $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
*
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "DNA_windowmanager_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm_window.h"
#include "wm_event_system.h"
#include "wm_event_types.h"
#include "wm.h"
#include "ED_screen.h"
#include "RNA_types.h"
/* ********************** Threaded Jobs Manager ****************************** */
/*
Add new job
- register in WM
- configure callbacks
Start or re-run job
- if job running
- signal job to end
- add timer notifier to verify when it has ended, to start it
- else
- start job
- add timer notifier to handle progress
Stop job
- signal job to end
on end, job will tag itself as sleeping
Remove job
- signal job to end
on end, job will remove itself
When job is done:
- it puts timer to sleep (or removes?)
*/
struct wmJob {
struct wmJob *next, *prev;
/* job originating from, keep track of this when deleting windows */
wmWindow *win;
/* should store entire own context, for start, free or listeners */
void *customdata;
void (*startjob)(void *, short *stop, short *do_update);
void (*free)(void *);
/* running jobs each have own timer */
double timestep;
wmTimer *wt;
/* the notifier event timers should send */
unsigned int note;
/* managing */
void (*listener)(struct wmJob *, struct wmNotifier *);
/* update gets called if thread defines so, and max once per timerstep */
/* no drawing, send notifiers! */
void (*update)(void *);
/* internal */
void *owner;
short running, ready, do_update, stop;
/* once running, we store this separately */
void *run_customdata;
void (*run_free)(void *);
/* we use BLI_threads api, but per job only 1 thread runs */
ListBase threads;
};
/* ******************* public API ***************** */
/* returns current or adds new job, but doesnt run it */
wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner)
{
wmJob *steve;
for(steve= wm->jobs.first; steve; steve= steve->next)
if(steve->owner==owner)
break;
if(steve==NULL) {
steve= MEM_callocN(sizeof(wmJob), "new job");
BLI_addtail(&wm->jobs, steve);
steve->win= win;
steve->owner= owner;
}
return steve;
}
void WM_jobs_customdata(wmJob *steve, void *customdata, void (*free)(void *))
{
/* pending job? just free */
if(steve->customdata)
steve->free(steve->customdata);
steve->customdata= customdata;
steve->free= free;
if(steve->running) {
/* signal job to end */
steve->stop= 1;
}
}
void WM_jobs_timer(wmJob *steve, double timestep, unsigned int note)
{
steve->timestep = timestep;
steve->note = note;
}
void WM_jobs_callbacks(wmJob *steve,
void (*startjob)(void *, short *, short *),
void (*listener)(struct wmJob *, struct wmNotifier *),
void (*update)(void *))
{
steve->startjob= startjob;
steve->listener= listener;
steve->update= update;
}
static void *do_job_thread(void *job_v)
{
wmJob *steve= job_v;
steve->stop= steve->ready= 0;
steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update);
steve->ready= 1;
return NULL;
}
void WM_jobs_start(wmJob *steve)
{
if(steve->running) {
/* signal job to end and restart */
steve->stop= 1;
}
else {
if(steve->customdata && steve->startjob) {
/* copy to ensure proper free in end */
steve->run_customdata= steve->customdata;
steve->run_free= steve->free;
steve->free= NULL;
steve->customdata= NULL;
steve->running= 1;
BLI_init_threads(&steve->threads, do_job_thread, 1);
BLI_insert_thread(&steve->threads, steve);
/* restarted job has timer already */
if(steve->wt==NULL)
steve->wt= WM_event_add_window_timer(steve->win, TIMERJOBS, steve->timestep);
}
else printf("job fails, not initialized\n");
}
}
/* hardcoded to event TIMERJOBS */
static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
{
wmWindowManager *wm= CTX_wm_manager(C);
wmJob *steve= wm->jobs.first;
for(; steve; steve= steve->next) {
if(evt->customdata==steve->wt) {
/* running threads */
if(steve->threads.first) {
if(steve->do_update) {
if(steve->update)
steve->update(steve->customdata);
if(steve->note)
WM_event_add_notifier(C, steve->note, NULL);
steve->do_update= 0;
}
if(steve->ready) {
/* free own data */
steve->run_free(steve->run_customdata);
steve->run_customdata= NULL;
steve->run_free= NULL;
steve->running= 0;
BLI_end_threads(&steve->threads);
/* new job added for steve? */
if(steve->customdata) {
WM_jobs_start(steve);
}
else {
WM_event_remove_window_timer(steve->win, steve->wt);
steve->wt= NULL;
/* remove steve */
BLI_remlink(&wm->jobs, steve);
MEM_freeN(steve);
}
}
}
return OPERATOR_FINISHED;
}
}
return OPERATOR_PASS_THROUGH;
}
void WM_OT_jobs_timer(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Jobs timer";
ot->idname= "WM_OT_jobs_timer";
/* api callbacks */
ot->invoke= wm_jobs_timer;
ot->poll= ED_operator_screenactive;
}

View File

@ -874,6 +874,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_tweak_gesture);
WM_operatortype_append(WM_OT_open_recentfile);
WM_operatortype_append(WM_OT_open_mainfile);
WM_operatortype_append(WM_OT_jobs_timer);
WM_operatortype_append(WM_OT_save_as_mainfile);
}
@ -882,6 +883,9 @@ void wm_window_keymap(wmWindowManager *wm)
{
ListBase *keymap= WM_keymap_listbase(wm, "Window", 0, 0);
/* items to make WM work */
WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0);
/* note, this doesn't replace existing keymap items */
WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_verify_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);

View File

@ -59,5 +59,9 @@ void wm_gesture_draw(struct wmWindow *win);
int wm_gesture_evaluate(bContext *C, wmGesture *gesture);
void wm_gesture_tag_redraw(bContext *C);
/* wm_jobs.h */
void WM_OT_jobs_timer(struct wmOperatorType *ot);
#endif /* WM_H */

View File

@ -75,7 +75,7 @@
#define TIMER0 0x0111 /* timer event, slot for internal use */
#define TIMER1 0x0112 /* timer event, slot for internal use */
#define TIMER2 0x0113 /* timer event, slot for internal use */
#define TIMER3 0x0114 /* timer event, slot for internal use */
#define TIMERJOBS 0x0114 /* timer event, internal use */
/* standard keyboard */

View File

@ -360,7 +360,7 @@ void yafrayFileRender_t::displayImage()
// based on another assumption of ogl errors on my system, forgot to actually draw it...
re->result->renlay = render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
}

View File

@ -1946,11 +1946,11 @@ bool blenderYafrayOutput_t::putPixel(int x, int y, const yafray::color_t &c,
out++;
if ((out==4096) || ((x+y*re->rectx) == ((re->rectx-1)+(re->recty-1)*re->rectx))) {
re->result->renlay = render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
re->display_draw(re->ddh, re->result, NULL);
out = 0;
}
}
if (re->test_break()) return false;
if (re->test_break(re->tbh)) return false;
return true;
}
@ -1982,9 +1982,9 @@ bool blenderYafrayOutput_t::putPixel(int x, int y, const yafray::color_t &c,
re->result->renlay = render_get_active_layer(re, re->result);
// note: ymin/ymax swapped here, img. upside down!
rcti rt = {txs, txe+1, maxy-tye, ((tys==0) ? maxy : (rres.recty-tys))}; // !!! tys can be zero
re->display_draw(re->result, &rt);
re->display_draw(re->ddh, re->result, &rt);
}
if (re->test_break()) return false;
if (re->test_break(re->tbh)) return false;
return true;
}