Page Menu
Home
Search
Configure Global Search
Log In
Files
F4196
blender_prefetch_patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Peter Schlaile (schlaile)
Nov 13 2013, 1:14 PM
Size
18 KB
Subscribers
None
blender_prefetch_patch
View Options
Index: include/BIF_drawseq.h
===================================================================
--- include/BIF_drawseq.h (revision 11922)
+++ include/BIF_drawseq.h (working copy)
@@ -36,6 +36,7 @@
struct ScrArea;
struct Sequence;
+void drawprefetchseqspace(struct ScrArea *sa, void *spacedata);
void drawseqspace(struct ScrArea *sa, void *spacedata);
void set_special_seq_update(int val);
Index: include/BSE_sequence.h
===================================================================
--- include/BSE_sequence.h (revision 11922)
+++ include/BSE_sequence.h (working copy)
@@ -60,6 +60,15 @@
struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel);
/* chansel: render this channel. Default=0 (renders end result)*/
+/* sequence prefetch API */
+void seq_start_threads();
+void seq_stop_threads();
+void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown);
+void seq_wait_for_prefetch_ready();
+struct ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra,
+ int chanshown);
+
+
void free_imbuf_seq_except(int cfra);
void free_imbuf_seq_with_ipo(struct Ipo * ipo);
void free_imbuf_seq(void);
Index: include/BIF_spacetypes.h
===================================================================
--- include/BIF_spacetypes.h (revision 11922)
+++ include/BIF_spacetypes.h (working copy)
@@ -35,6 +35,7 @@
typedef struct _SpaceType SpaceType;
+typedef void (*SpacePrefetchDrawFP) (struct ScrArea *sa, void *spacedata);
typedef void (*SpaceDrawFP) (struct ScrArea *sa, void *spacedata);
typedef void (*SpaceChangeFP) (struct ScrArea *sa, void *spacedata);
typedef void (*SpaceHandleFP) (struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
@@ -43,7 +44,7 @@
SpaceType* spacetype_new (char *name);
-void spacetype_set_winfuncs (SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle);
+void spacetype_set_winfuncs (SpaceType *st, SpacePrefetchDrawFP prefetch, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle);
/***/
Index: include/BIF_space.h
===================================================================
--- include/BIF_space.h (revision 11922)
+++ include/BIF_space.h (working copy)
@@ -92,6 +92,7 @@
#define B_RECALCLIGHT 3310
+void scrarea_do_winprefetchdraw (struct ScrArea *sa);
void scrarea_do_windraw (struct ScrArea *sa);
void scrarea_do_winchange (struct ScrArea *sa);
void scrarea_do_winhandle (struct ScrArea *sa, struct BWinEvent *evt);
Index: makesdna/DNA_userdef_types.h
===================================================================
--- makesdna/DNA_userdef_types.h (revision 11922)
+++ makesdna/DNA_userdef_types.h (working copy)
@@ -171,6 +171,7 @@
short tw_hotspot, tw_flag, tw_handlesize, tw_size;
int textimeout, texcollectrate;
int memcachelimit;
+ int prefetchframes;
short frameserverport;
short pad_rot_angle; /*control the rotation step of the view when PAD2,PAD4,PAD6&PAD8 is use*/
short obcenter_dia;
@@ -181,7 +182,6 @@
short recent_files; /* maximum number of recently used files to remember */
short smooth_viewtx; /* miliseconds to spend spinning the view */
short glreslimit;
- char pad[4];
} UserDef;
extern UserDef U; /* from usiblender.c !!!! */
Index: src/sequence.c
===================================================================
--- src/sequence.c (revision 11922)
+++ src/sequence.c (working copy)
@@ -70,6 +70,7 @@
#include "RE_pipeline.h" // talks to entire render API
#include "blendef.h"
+#include <pthread.h>
int seqrectx, seqrecty;
@@ -1179,6 +1180,217 @@
}
+/* threading api */
+
+static ListBase running_threads;
+static ListBase prefetch_wait;
+static ListBase prefetch_done;
+
+static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
+
+static volatile int seq_thread_shutdown = FALSE;
+static volatile int seq_last_given_cfra = 0;
+
+typedef struct PrefetchThread {
+ struct PrefetchThread *next, *prev;
+ pthread_t pthread;
+ int running;
+} PrefetchThread;
+
+typedef struct PrefetchQueueElem {
+ struct PrefetchQueueElem *next, *prev;
+
+ int rectx;
+ int recty;
+ int cfra;
+ int chanshown;
+
+ struct ImBuf * ibuf;
+} PrefetchQueueElem;
+
+
+static void * seq_prefetch_thread(void * This_)
+{
+ PrefetchThread * This = This_;
+
+ while (!seq_thread_shutdown) {
+ PrefetchQueueElem * e;
+ int s_last;
+
+ pthread_mutex_lock(&queue_lock);
+ e = prefetch_wait.first;
+ if (e) {
+ BLI_remlink(&prefetch_wait, e);
+ }
+ s_last = seq_last_given_cfra;
+
+ pthread_mutex_unlock(&queue_lock);
+
+ if (!e) {
+ pthread_mutex_lock(&prefetch_ready_lock);
+
+ This->running = FALSE;
+
+ pthread_cond_signal(&prefetch_ready_cond);
+ pthread_mutex_unlock(&prefetch_ready_lock);
+
+ pthread_mutex_lock(&wakeup_lock);
+ pthread_cond_wait(&wakeup_cond, &wakeup_lock);
+ pthread_mutex_unlock(&wakeup_lock);
+ continue;
+ }
+
+ This->running = TRUE;
+
+ if (e->cfra >= s_last) {
+ e->ibuf = give_ibuf_seq(e->rectx, e->recty, e->cfra,
+ e->chanshown);
+ }
+
+ if (e->ibuf) {
+ IMB_cache_limiter_ref(e->ibuf);
+ }
+
+ pthread_mutex_lock(&queue_lock);
+
+ BLI_addtail(&prefetch_done, e);
+
+ for (e = prefetch_wait.first; e; e = e->next) {
+ if (s_last > e->cfra) {
+ BLI_remlink(&prefetch_done, e);
+ MEM_freeN(e);
+ }
+ }
+
+ for (e = prefetch_done.first; e; e = e->next) {
+ if (s_last > e->cfra) {
+ if (e->ibuf) {
+ IMB_cache_limiter_unref(e->ibuf);
+ }
+ BLI_remlink(&prefetch_done, e);
+ MEM_freeN(e);
+ }
+ }
+
+ pthread_mutex_unlock(&queue_lock);
+
+ }
+ return 0;
+}
+
+void seq_start_threads()
+{
+ int i;
+
+ running_threads.first = running_threads.last = NULL;
+ prefetch_wait.first = prefetch_wait.last = NULL;
+ prefetch_done.first = prefetch_done.last = NULL;
+
+ seq_thread_shutdown = FALSE;
+ seq_last_given_cfra = MAXFRAME;
+
+ /* since global structures are modified during the processing
+ of one frame, only one render thread is currently possible...
+
+ (but we code, in the hope, that we can remove this restriction
+ soon...)
+ */
+
+ for (i = 0; i < 1; i++) {
+ PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread),
+ "prefetch_thread");
+ BLI_addtail(&running_threads, t);
+
+ pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
+ }
+}
+
+void seq_stop_threads()
+{
+ PrefetchThread *tslot;
+
+ seq_thread_shutdown = TRUE;
+
+ pthread_mutex_lock(&wakeup_lock);
+ pthread_cond_broadcast(&wakeup_cond);
+ pthread_mutex_unlock(&wakeup_lock);
+
+ for(tslot = running_threads.first; tslot; tslot= tslot->next) {
+ pthread_join(tslot->pthread, NULL);
+ }
+
+ BLI_freelistN(&running_threads);
+}
+
+void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown)
+{
+ PrefetchQueueElem * e = MEM_callocN(sizeof(PrefetchQueueElem),
+ "prefetch_queue_elem");
+ e->rectx = rectx;
+ e->recty = recty;
+ e->cfra = cfra;
+ e->chanshown = chanshown;
+
+ pthread_mutex_lock(&queue_lock);
+ BLI_addtail(&prefetch_wait, e);
+ pthread_mutex_unlock(&queue_lock);
+
+ pthread_mutex_lock(&wakeup_lock);
+ pthread_cond_signal(&wakeup_cond);
+ pthread_mutex_unlock(&wakeup_lock);
+}
+
+void seq_wait_for_prefetch_ready()
+{
+ PrefetchThread *tslot;
+
+ pthread_mutex_lock(&prefetch_ready_lock);
+
+ for(;;) {
+ for(tslot = running_threads.first; tslot; tslot= tslot->next) {
+ if (tslot->running) {
+ break;
+ }
+ }
+ if (!tslot) {
+ break;
+ }
+ pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
+ }
+
+ pthread_mutex_unlock(&prefetch_ready_lock);
+}
+
+ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, int chanshown)
+{
+ PrefetchQueueElem * e = 0;
+
+ pthread_mutex_lock(&queue_lock);
+
+ for (e = prefetch_done.first; e; e = e->next) {
+ if (cfra == e->cfra &&
+ chanshown == e->chanshown &&
+ rectx == e->rectx &&
+ recty == e->recty) {
+ break;
+ }
+ }
+
+ /* e->ibuf is unrefed by render thread on next round. */
+ seq_last_given_cfra = cfra;
+
+ pthread_mutex_unlock(&queue_lock);
+
+ return e ? e->ibuf : 0;
+}
+
+
+
/* Functions to free imbuf and anim data on changes */
static void free_imbuf_strip_elem(StripElem *se)
@@ -1371,11 +1583,12 @@
*/
{
extern int mem_in_use;
+ extern int mmap_in_use;
int max = MEM_CacheLimiter_get_maximum();
- if (max != 0 && mem_in_use > max) {
+ if (max != 0 && mem_in_use + mmap_in_use > max) {
fprintf(stderr, "mem_in_use = %d, max = %d\n",
- mem_in_use, max);
+ mem_in_use + mmap_in_use, max);
fprintf(stderr, "Cleaning up, please wait...\n"
"If this happens very often,\n"
"consider "
Index: src/drawview.c
===================================================================
--- src/drawview.c (revision 11922)
+++ src/drawview.c (working copy)
@@ -3168,6 +3168,9 @@
double tottime = 0.0;
+static ScrArea *oldsa;
+static double swaptime;
+static int curmode;
int update_time(void)
{
@@ -3183,12 +3186,67 @@
return (tottime < 0.0);
}
+static void inner_play_prefetch_frame(int mode, int cfra)
+{
+ ScrArea *sa;
+ int oldcfra = CFRA;
+
+ if (!U.prefetchframes) {
+ return;
+ }
+
+ CFRA = cfra;
+
+ sa= G.curscreen->areabase.first;
+ while(sa) {
+ if(sa==oldsa) {
+ scrarea_do_winprefetchdraw(sa);
+ }
+ else if(curmode & 1) { /* all view3d and seq spaces */
+ if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
+ scrarea_do_winprefetchdraw(sa);
+ }
+ }
+ else if(curmode & 4) { /* all seq spaces */
+ if (sa->spacetype == SPACE_SEQ) {
+ scrarea_do_winprefetchdraw(sa);
+ }
+ }
+
+ sa= sa->next;
+ }
+
+ CFRA = oldcfra;
+}
+
+static void inner_play_prefetch_startup(int mode)
+{
+ int i;
+
+ if (!U.prefetchframes) {
+ return;
+ }
+
+ seq_start_threads();
+
+ for (i = 0; i <= U.prefetchframes; i++) {
+ inner_play_prefetch_frame(mode, CFRA + i);
+ }
+
+ seq_wait_for_prefetch_ready();
+}
+
+static void inner_play_prefetch_shutdown(int mode)
+{
+ if (!U.prefetchframes) {
+ return;
+ }
+ seq_stop_threads();
+}
+
void inner_play_anim_loop(int init, int mode)
{
ScrArea *sa;
- static ScrArea *oldsa;
- static double swaptime;
- static int curmode;
/* init */
if(init) {
@@ -3223,6 +3281,8 @@
sa= sa->next;
}
+ inner_play_prefetch_frame(mode, CFRA + U.prefetchframes);
+
/* make sure that swaptime passed by */
tottime -= swaptime;
while (update_time()) PIL_sleep_ms(1);
@@ -3265,6 +3325,8 @@
cfraont= CFRA;
oldsa= curarea;
+ inner_play_prefetch_startup(mode);
+
audiostream_start( CFRA );
if (curarea && curarea->spacetype == SPACE_SEQ) {
@@ -3313,6 +3375,7 @@
if(event==SPACEKEY);
else CFRA= cfraont;
+ inner_play_prefetch_shutdown(mode);
audiostream_stop();
if(oldsa!=curarea) areawinset(oldsa->win);
Index: src/spacetypes.c
===================================================================
--- src/spacetypes.c (revision 11922)
+++ src/spacetypes.c (working copy)
@@ -52,6 +52,7 @@
struct _SpaceType {
char name[32];
+ SpacePrefetchDrawFP winprefetchdraw;
SpaceDrawFP windraw;
SpaceChangeFP winchange;
SpaceHandleFP winhandle;
@@ -70,8 +71,9 @@
return st;
}
-void spacetype_set_winfuncs(SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle)
+void spacetype_set_winfuncs(SpaceType *st, SpacePrefetchDrawFP prefetchdraw, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle)
{
+ st->winprefetchdraw = prefetchdraw;
st->windraw= draw;
st->winchange= change;
st->winhandle= handle;
@@ -105,6 +107,17 @@
}
}
+void scrarea_do_winprefetchdraw(ScrArea *area)
+{
+ SpaceType *st= spacetype_from_area(area);
+
+ areawinset(area->win);
+
+ if(area->win && st->winprefetchdraw) {
+ st->winprefetchdraw(area, area->spacedata.first);
+ }
+}
+
void scrarea_do_windraw(ScrArea *area)
{
SpaceType *st= spacetype_from_area(area);
Index: src/space.c
===================================================================
--- src/space.c (revision 11922)
+++ src/space.c (working copy)
@@ -3126,8 +3126,8 @@
uiBlock *block;
static short cur_light=0;
float fac, col[3];
- short xpos, ypos, ypostab, buth, rspace, dx, y1, y2, y3, y4, y5, y6;
- short y2label, y3label, y4label, y5label, y6label;
+ short xpos, ypos, ypostab, buth, rspace, dx, y1, y2, y3, y4, y5, y6, y7;
+ short y2label, y3label, y4label, y5label, y6label, y7label;
short spref, mpref, lpref, smfileselbut;
short edgsp, midsp;
char naam[32];
@@ -3178,6 +3178,7 @@
y4 = ypos+3*(buth+rspace);
y5 = ypos+4*(buth+rspace);
y6 = ypos+5*(buth+rspace);
+ y7 = ypos+6*(buth+rspace);
y2label = y2-2; /* adjustments to offset the labels down to align better */
@@ -3185,6 +3186,7 @@
y4label = y4-2;
y5label = y5-2;
y6label = y6-2;
+ y7label = y7-2;
/* set the color to blue and draw the main 'tab' controls */
@@ -3768,8 +3770,13 @@
uiDefBut(block, LABEL,0,"System:",
- (xpos+edgsp+(4*midsp)+(4*mpref)),y6label,mpref,buth,
+ (xpos+edgsp+(4*midsp)+(4*mpref)),y7label,mpref,buth,
0, 0, 0, 0, 0, "");
+ uiDefButI(block, NUM, B_REDR, "Prefetch frames ",
+ (xpos+edgsp+(4*mpref)+(4*midsp)), y6, mpref, buth,
+ &U.prefetchframes, 0.0, 50.0, 20, 2,
+ "Number of frames to render ahead during playback.");
+
uiDefButI(block, NUM, B_MEMCACHELIMIT, "MEM Cache Limit ",
(xpos+edgsp+(4*mpref)+(4*midsp)), y5, mpref, buth,
&U.memcachelimit, 0.0, 1024.0, 30, 2,
@@ -6171,7 +6178,7 @@
if (!st) {
st= spacetype_new("Action");
- spacetype_set_winfuncs(st, drawactionspace, changeactionspace, winqreadactionspace);
+ spacetype_set_winfuncs(st, NULL, drawactionspace, changeactionspace, winqreadactionspace);
}
return st;
@@ -6182,7 +6189,7 @@
if (!st) {
st= spacetype_new("Buts");
- spacetype_set_winfuncs(st, drawbutspace, changebutspace, winqreadbutspace);
+ spacetype_set_winfuncs(st, NULL, drawbutspace, changebutspace, winqreadbutspace);
}
return st;
@@ -6193,7 +6200,7 @@
if (!st) {
st= spacetype_new("File");
- spacetype_set_winfuncs(st, drawfilespace, NULL, winqreadfilespace);
+ spacetype_set_winfuncs(st, NULL, drawfilespace, NULL, winqreadfilespace);
}
return st;
@@ -6204,7 +6211,7 @@
if (!st) {
st= spacetype_new("Image");
- spacetype_set_winfuncs(st, drawimagespace, changeimagepace, winqreadimagespace);
+ spacetype_set_winfuncs(st, NULL, drawimagespace, changeimagepace, winqreadimagespace);
}
return st;
@@ -6215,7 +6222,7 @@
if (!st) {
st= spacetype_new("Imasel");
- spacetype_set_winfuncs(st, drawimaselspace, changeimaselspace, winqreadimaselspace);
+ spacetype_set_winfuncs(st, NULL, drawimaselspace, changeimaselspace, winqreadimaselspace);
}
return st;
@@ -6226,7 +6233,7 @@
if (!st) {
st= spacetype_new("Info");
- spacetype_set_winfuncs(st, drawinfospace, NULL, winqreadinfospace);
+ spacetype_set_winfuncs(st, NULL, drawinfospace, NULL, winqreadinfospace);
}
return st;
@@ -6237,7 +6244,7 @@
if (!st) {
st= spacetype_new("Ipo");
- spacetype_set_winfuncs(st, drawipospace, changeview2dspace, winqreadipospace);
+ spacetype_set_winfuncs(st, NULL, drawipospace, changeview2dspace, winqreadipospace);
}
return st;
@@ -6248,7 +6255,7 @@
if (!st) {
st= spacetype_new("Nla");
- spacetype_set_winfuncs(st, drawnlaspace, changeview2dspace, winqreadnlaspace);
+ spacetype_set_winfuncs(st, NULL, drawnlaspace, changeview2dspace, winqreadnlaspace);
}
return st;
@@ -6259,7 +6266,7 @@
if (!st) {
st= spacetype_new("Oops");
- spacetype_set_winfuncs(st, drawoopsspace, changeview2dspace, winqreadoopsspace);
+ spacetype_set_winfuncs(st, NULL, drawoopsspace, changeview2dspace, winqreadoopsspace);
}
return st;
@@ -6270,7 +6277,7 @@
if (!st) {
st= spacetype_new("Sequence");
- spacetype_set_winfuncs(st, drawseqspace, changeview2dspace, winqreadseqspace);
+ spacetype_set_winfuncs(st, drawprefetchseqspace, drawseqspace, changeview2dspace, winqreadseqspace);
}
return st;
@@ -6281,7 +6288,7 @@
if (!st) {
st= spacetype_new("Sound");
- spacetype_set_winfuncs(st, drawsoundspace, changeview2dspace, winqreadsoundspace);
+ spacetype_set_winfuncs(st, NULL, drawsoundspace, changeview2dspace, winqreadsoundspace);
}
return st;
@@ -6292,7 +6299,7 @@
if (!st) {
st= spacetype_new("Text");
- spacetype_set_winfuncs(st, drawtextspace, NULL, winqreadtextspace);
+ spacetype_set_winfuncs(st, NULL, drawtextspace, NULL, winqreadtextspace);
}
return st;
@@ -6316,7 +6323,7 @@
if (!st) {
st = spacetype_new("Script");
- spacetype_set_winfuncs(st, drawscriptspace, spacescript_change, winqreadscriptspace);
+ spacetype_set_winfuncs(st, NULL, drawscriptspace, spacescript_change, winqreadscriptspace);
}
return st;
@@ -6327,7 +6334,7 @@
if (!st) {
st= spacetype_new("View3D");
- spacetype_set_winfuncs(st, drawview3dspace, changeview3dspace, winqreadview3dspace);
+ spacetype_set_winfuncs(st, NULL, drawview3dspace, changeview3dspace, winqreadview3dspace);
}
return st;
@@ -6338,7 +6345,7 @@
if (!st) {
st= spacetype_new("Time");
- spacetype_set_winfuncs(st, drawtimespace, NULL, winqreadtimespace);
+ spacetype_set_winfuncs(st, NULL, drawtimespace, NULL, winqreadtimespace);
}
return st;
@@ -6350,7 +6357,7 @@
if (!st) {
st= spacetype_new("Node");
- spacetype_set_winfuncs(st, drawnodespace, changeview2dspace, winqreadnodespace);
+ spacetype_set_winfuncs(st, NULL, drawnodespace, changeview2dspace, winqreadnodespace);
}
return st;
Index: src/drawseq.c
===================================================================
--- src/drawseq.c (revision 11922)
+++ src/drawseq.c (working copy)
@@ -51,6 +51,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view2d_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "BKE_plugin_types.h"
@@ -788,7 +789,11 @@
return;
else {
recursive= 1;
- ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+ if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) {
+ ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+ } else {
+ ibuf= (ImBuf *)give_ibuf_threaded(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+ }
recursive= 0;
/* HURMF! the give_ibuf_seq can call image display in this window */
@@ -1276,6 +1281,20 @@
}
+void drawprefetchseqspace(ScrArea *sa, void *spacedata)
+{
+ SpaceSeq *sseq= sa->spacedata.first;
+ int rectx, recty;
+
+ rectx= (G.scene->r.size*G.scene->r.xsch)/100;
+ recty= (G.scene->r.size*G.scene->r.ysch)/100;
+
+ if(sseq->mainb) {
+ give_ibuf_prefetch_request(
+ rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+ }
+}
+
void drawseqspace(ScrArea *sa, void *spacedata)
{
SpaceSeq *sseq= sa->spacedata.first;
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
3e/0a/3c02ea56496f4c7388934052e805
Event Timeline
Log In to Comment