Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/source/volume_precache.c178
2 files changed, 90 insertions, 89 deletions
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 0b339d285ce..6d27c7707f0 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -485,7 +485,6 @@ typedef struct VolPrecachePart
int res[3];
float bbmin[3];
float voxel[3];
- int working, done;
struct Render *re;
} VolPrecachePart;
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 18132c4a7f3..d6cfcee4ac9 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -477,6 +477,11 @@ static void *vol_precache_part_test(void *data)
}
#endif
+typedef struct VolPrecacheQueue {
+ ThreadQueue *work;
+ ThreadQueue *done;
+} VolPrecacheQueue;
+
/* Iterate over the 3d voxel grid, and fill the voxels with scattering information
*
* It's stored in memory as 3 big float grids next to each other, one for each RGB channel.
@@ -485,58 +490,65 @@ static void *vol_precache_part_test(void *data)
*/
static void *vol_precache_part(void *data)
{
- VolPrecachePart *pa = (VolPrecachePart *)data;
- ObjectInstanceRen *obi = pa->obi;
- RayObject *tree = pa->tree;
- ShadeInput *shi = pa->shi;
- float scatter_col[3] = {0.f, 0.f, 0.f};
- float co[3], cco[3], view[3];
- int x, y, z, i;
- int res[3];
-
- res[0]= pa->res[0];
- res[1]= pa->res[1];
- res[2]= pa->res[2];
-
- for (z= pa->minz; z < pa->maxz; z++) {
- co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
-
- for (y= pa->miny; y < pa->maxy; y++) {
- co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
+ VolPrecacheQueue *queue = (VolPrecacheQueue*)data;
+ VolPrecachePart *pa;
+
+ while ((pa = BLI_thread_queue_pop(queue->work))) {
+ ObjectInstanceRen *obi = pa->obi;
+ RayObject *tree = pa->tree;
+ ShadeInput *shi = pa->shi;
+ float scatter_col[3] = {0.f, 0.f, 0.f};
+ float co[3], cco[3], view[3];
+ int x, y, z, i;
+ int res[3];
+
+ if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
+ break;
+
+ res[0]= pa->res[0];
+ res[1]= pa->res[1];
+ res[2]= pa->res[2];
+
+ for (z= pa->minz; z < pa->maxz; z++) {
+ co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
- for (x=pa->minx; x < pa->maxx; x++) {
- co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
-
- if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
- break;
+ for (y= pa->miny; y < pa->maxy; y++) {
+ co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
- /* convert from world->camera space for shading */
- mul_v3_m4v3(cco, pa->viewmat, co);
-
- i= V_I(x, y, z, res);
+ for (x=pa->minx; x < pa->maxx; x++) {
+ co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
+
+ if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
+ break;
+
+ /* convert from world->camera space for shading */
+ mul_v3_m4v3(cco, pa->viewmat, co);
+
+ i= V_I(x, y, z, res);
+
+ // don't bother if the point is not inside the volume mesh
+ if (!point_inside_obi(tree, obi, cco)) {
+ obi->volume_precache->data_r[i] = -1.0f;
+ obi->volume_precache->data_g[i] = -1.0f;
+ obi->volume_precache->data_b[i] = -1.0f;
+ continue;
+ }
+
+ copy_v3_v3(view, cco);
+ normalize_v3(view);
+ vol_get_scattering(shi, scatter_col, cco, view);
- // don't bother if the point is not inside the volume mesh
- if (!point_inside_obi(tree, obi, cco)) {
- obi->volume_precache->data_r[i] = -1.0f;
- obi->volume_precache->data_g[i] = -1.0f;
- obi->volume_precache->data_b[i] = -1.0f;
- continue;
+ obi->volume_precache->data_r[i] = scatter_col[0];
+ obi->volume_precache->data_g[i] = scatter_col[1];
+ obi->volume_precache->data_b[i] = scatter_col[2];
+
}
-
- copy_v3_v3(view, cco);
- normalize_v3(view);
- vol_get_scattering(shi, scatter_col, cco, view);
-
- obi->volume_precache->data_r[i] = scatter_col[0];
- obi->volume_precache->data_g[i] = scatter_col[1];
- obi->volume_precache->data_b[i] = scatter_col[2];
-
}
}
+
+ BLI_thread_queue_push(queue->done, pa);
}
- pa->done = 1;
-
return NULL;
}
@@ -602,9 +614,6 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob
minz = z * sizez;
maxz = minz + sizez;
maxz = (maxz>res[2])?res[2]:maxz;
-
- pa->done = 0;
- pa->working = 0;
pa->re = re;
pa->num = i;
@@ -630,21 +639,6 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob
}
}
-static VolPrecachePart *precache_get_new_part(Render *re)
-{
- VolPrecachePart *pa, *nextpa=NULL;
-
- for (pa = re->volume_precache_parts.first; pa; pa=pa->next)
- {
- if (pa->done==0 && pa->working==0) {
- nextpa = pa;
- break;
- }
- }
-
- return nextpa;
-}
-
/* calculate resolution from bounding box in world space */
static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen *obi, int res)
{
@@ -678,14 +672,15 @@ static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen
static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma)
{
VolumePrecache *vp;
- VolPrecachePart *nextpa, *pa;
+ VolPrecachePart *pa;
RayObject *tree;
ShadeInput shi;
ListBase threads;
+ VolPrecacheQueue queue;
int parts[3] = {1, 1, 1}, totparts;
- int caching=1, counter=0;
- int totthread = re->r.threads;
+ int counter=0;
+ int totthread = re->r.threads, thread;
double time, lasttime= PIL_check_seconds_timer();
@@ -718,34 +713,29 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
precache_init_parts(re, tree, &shi, obi, totthread, parts);
totparts = parts[0] * parts[1] * parts[2];
+
+ /* setup work and done queues */
+ queue.work = BLI_thread_queue_init();
+ queue.done = BLI_thread_queue_init();
+ BLI_thread_queue_nowait(queue.work);
+
+ for(pa= re->volume_precache_parts.first; pa; pa= pa->next)
+ BLI_thread_queue_push(queue.work, pa);
+ /* launch threads */
BLI_init_threads(&threads, vol_precache_part, totthread);
+
+ for(thread= 0; thread<totthread; thread++)
+ BLI_insert_thread(&threads, &queue);
- while(caching) {
+ /* loop waiting for work to be done */
+ while(counter < totparts) {
+ if(re->test_break && re->test_break(re->tbh))
+ break;
- if(BLI_available_threads(&threads) && !(re->test_break(re->tbh))) {
- nextpa = precache_get_new_part(re);
- if (nextpa) {
- nextpa->working = 1;
- BLI_insert_thread(&threads, nextpa);
- }
- }
- else PIL_sleep_ms(50);
+ if(BLI_thread_queue_pop_timeout(queue.done, 50))
+ counter++;
- caching=0;
- counter=0;
- for(pa= re->volume_precache_parts.first; pa; pa= pa->next) {
-
- if(pa->done) {
- counter++;
- BLI_remove_thread(&threads, pa);
- } else
- caching = 1;
- }
-
- if (re->test_break(re->tbh) && BLI_available_threads(&threads)==totthread)
- caching=0;
-
time= PIL_check_seconds_timer();
if(time-lasttime>1.0) {
char str[64];
@@ -757,7 +747,10 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
}
}
+ /* free */
BLI_end_threads(&threads);
+ BLI_thread_queue_free(queue.work);
+ BLI_thread_queue_free(queue.done);
BLI_freelistN(&re->volume_precache_parts);
if(tree) {
@@ -788,13 +781,22 @@ void volume_precache(Render *re)
ObjectInstanceRen *obi;
VolumeOb *vo;
+ re->i.infostr= "Volume preprocessing";
+ re->stats_draw(re->sdh, &re->i);
+
for(vo= re->volumes.first; vo; vo= vo->next) {
if (using_lightcache(vo->ma)) {
for(obi= re->instancetable.first; obi; obi= obi->next) {
if (obi->obr == vo->obr) {
vol_precache_objectinstance_threads(re, obi, vo->ma);
+
+ if(re->test_break && re->test_break(re->tbh))
+ break;
}
}
+
+ if(re->test_break && re->test_break(re->tbh))
+ break;
}
}