[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48540] branches/soc-2011-tomato/source/ blender: Tomato: hack to cache result of rasterization
Sergey Sharybin
sergey.vfx at gmail.com
Tue Jul 3 16:30:57 CEST 2012
Revision: 48540
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48540
Author: nazgul
Date: 2012-07-03 14:30:55 +0000 (Tue, 03 Jul 2012)
Log Message:
-----------
Tomato: hack to cache result of rasterization
It shall be removed as soon as tile-based rasterization is here,
but to remove current stoppers should be fine.
Modified Paths:
--------------
branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
branches/soc-2011-tomato/source/blender/blenloader/intern/readblenentry.c
branches/soc-2011-tomato/source/blender/blenloader/intern/readfile.c
branches/soc-2011-tomato/source/blender/blenloader/intern/readfile.h
branches/soc-2011-tomato/source/blender/makesdna/DNA_mask_types.h
Modified: branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c 2012-07-03 14:25:06 UTC (rev 48539)
+++ branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c 2012-07-03 14:30:55 UTC (rev 48540)
@@ -58,6 +58,18 @@
#include "raskter.h"
+#ifdef USE_MANGO_MASK_CACHE_HACK
+typedef struct MaskRasterCache {
+ float *buffer;
+ int width, height;
+ short do_aspect_correct;
+ short do_mask_aa;
+ short do_feather;
+
+ ListBase layers;
+} MaskRasterCache;
+#endif
+
static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
{
if (point == &points_array[spline->tot_point - 1]) {
@@ -1068,6 +1080,30 @@
MEM_freeN(masklay);
}
+#ifdef USE_MANGO_MASK_CACHE_HACK
+void BKE_mask_raster_cache_free(Mask *mask)
+{
+ MaskRasterCache *cache = mask->raster_cache;
+
+ if (cache) {
+ MaskLayer *layer;
+
+ layer = cache->layers.first;
+ while (layer) {
+ MaskLayer *layer_next = layer->next;
+
+ BKE_mask_layer_free(layer);
+ layer = layer_next;
+ }
+
+ MEM_freeN(cache->buffer);
+ MEM_freeN(cache);
+
+ mask->raster_cache = NULL;
+ }
+}
+#endif
+
void BKE_mask_free(Mask *mask)
{
MaskLayer *masklay = mask->masklayers.first;
@@ -1080,6 +1116,14 @@
masklay = next_masklay;
}
+
+#ifdef USE_MANGO_MASK_CACHE_HACK
+ if (mask->raster_cache) {
+ BKE_mask_raster_cache_free(mask);
+
+ mask->raster_cache = NULL;
+ }
+#endif
}
void BKE_mask_unlink(Main *bmain, Mask *mask)
@@ -2092,18 +2136,195 @@
return MAX2(1, mask->efra - mask->sfra);
}
+#ifdef USE_MANGO_MASK_CACHE_HACK
+static void mask_splines_duplicate(ListBase *base_new, ListBase *base)
+{
+ MaskSpline *spline;
+
+ for (spline = base->first; spline; spline = spline->next) {
+ MaskSpline *spline_new = BKE_mask_spline_copy(spline);
+
+ BLI_addtail(base_new, spline_new);
+ }
+}
+
+static MaskLayer *mask_layer_duplicate(MaskLayer *layer)
+{
+ MaskLayer *layer_new;
+
+ layer_new = MEM_callocN(sizeof(MaskLayer), "new mask layer");
+
+ BLI_strncpy(layer_new->name, layer->name, sizeof(layer_new->name));
+
+ layer_new->alpha = layer->alpha;
+ layer_new->blend = layer->blend;
+ layer_new->blend_flag = layer->blend_flag;
+ layer_new->flag = layer->flag;
+ layer_new->restrictflag = layer->restrictflag;
+
+ mask_splines_duplicate(&layer_new->splines, &layer->splines);
+
+ return layer_new;
+}
+
+static void mask_layers_duplicate(ListBase *base_new, ListBase *base)
+{
+ MaskLayer *layer;
+
+ for (layer = base->first; layer; layer = layer->next) {
+ MaskLayer *layer_new = mask_layer_duplicate(layer);
+
+ BLI_addtail(base_new, layer_new);
+ }
+}
+
+static int mask_point_compare(MaskSplinePoint *point_a, MaskSplinePoint *point_b)
+{
+ if (point_a->tot_uw != point_b->tot_uw) {
+ return FALSE;
+ }
+
+ if (memcmp(&point_a->bezt, &point_b->bezt, sizeof(BezTriple))) {
+ return FALSE;
+ }
+
+ if (memcmp(&point_a->uw, &point_b->uw, 2 * point_a->tot_uw * sizeof(float))) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int mask_points_compare(MaskSplinePoint *points_a, MaskSplinePoint *points_b, int tot_point)
+{
+ MaskSplinePoint *point_a = points_a;
+ MaskSplinePoint *point_b = points_b;
+ int a = tot_point;
+
+ while (a--) {
+ if (!mask_point_compare(point_a, point_b)) {
+ return FALSE;
+ }
+
+ point_a++;
+ point_b++;
+ }
+
+ return TRUE;
+}
+
+static int mask_spline_compare(MaskSpline *spline_a, MaskSpline *spline_b)
+{
+ if (spline_a->flag != spline_b->flag ||
+ spline_a->tot_point != spline_b->tot_point ||
+ spline_a->weight_interp != spline_b->weight_interp)
+ {
+ return FALSE;
+ }
+
+ return mask_points_compare(spline_a->points, spline_b->points, spline_a->tot_point);
+}
+
+static int mask_splines_compare(ListBase *base_a, ListBase *base_b)
+{
+ MaskSpline *spline_a, *spline_b;
+
+ for (spline_a = base_a->first, spline_b = base_b->first;
+ spline_a && spline_b;
+ spline_a = spline_a->next, spline_b = spline_b->next)
+ {
+ if (!mask_spline_compare(spline_a, spline_b)) {
+ return FALSE;
+ }
+ }
+
+ if (spline_a || spline_b)
+ return FALSE;
+
+ return TRUE;
+}
+
+static int mask_layer_compare(MaskLayer *layer_a, MaskLayer *layer_b)
+{
+ if (layer_a->alpha != layer_b->alpha ||
+ layer_a->blend != layer_b->blend ||
+ layer_a->blend_flag != layer_b->blend_flag ||
+ layer_a->flag != layer_b->flag ||
+ layer_a->restrictflag != layer_b->restrictflag)
+ {
+ return FALSE;
+ }
+
+ if (strcmp(layer_a->name, layer_b->name))
+ return FALSE;
+
+ return mask_splines_compare(&layer_a->splines, &layer_b->splines);
+}
+
+static int mask_layers_compare(ListBase *base_a, ListBase *base_b)
+{
+ MaskLayer *layer_a, *layer_b;
+
+ for (layer_a = base_a->first, layer_b = base_b->first;
+ layer_a && layer_b;
+ layer_a = layer_a->next, layer_b = layer_b->next)
+ {
+ if (!mask_layer_compare(layer_a, layer_b)) {
+ return FALSE;
+ }
+ }
+
+ if (layer_a || layer_b)
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
/* rasterization */
void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
const short do_aspect_correct, const short do_mask_aa,
const short do_feather)
{
+ MaskRasterCache *cache = mask->raster_cache;
MaskLayer *masklay;
/* temp blending buffer */
const int buffer_size = width * height;
- float *buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__);
+ float *buffer_tmp;
+#ifdef USE_MANGO_MASK_CACHE_HACK
+ if (cache &&
+ cache->width == width &&
+ cache->height == height &&
+ cache->do_aspect_correct == do_aspect_correct &&
+ cache->do_mask_aa == do_mask_aa &&
+ cache->do_feather == do_feather &&
+ mask_layers_compare(&cache->layers, &mask->masklayers))
+ {
+ memcpy(buffer, cache->buffer, sizeof(float) * buffer_size);
+ return;
+ }
+
+ BKE_mask_raster_cache_free(mask);
+
+ cache = MEM_callocN(sizeof(MaskRasterCache), "mask raster cache");
+
+ /* duplicate first to be sure rasterization happens with the same
+ * configuration as is being cached, otherwise could be threading issues
+ * with transformation code -- in some circumstances deformation could
+ * happen at the same time as deformating spline is rasterizing
+ */
+ mask_layers_duplicate(&cache->layers, &mask->masklayers);
+#endif
+
+ buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__);
+
+#ifdef USE_MANGO_MASK_CACHE_HACK
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+#else
+ for (masklay = cache->layers.first; masklay; masklay = masklay->next) {
+#endif
MaskSpline *spline;
float alpha;
@@ -2225,4 +2446,17 @@
}
MEM_freeN(buffer_tmp);
+
+#ifdef USE_MANGO_MASK_CACHE_HACK
+ cache->buffer = MEM_mallocN(sizeof(float) * buffer_size, "mask raster cache buffer");
+ memcpy(cache->buffer, buffer, sizeof(float) * buffer_size);
+
+ cache->width = width;
+ cache->height = height;
+ cache->do_aspect_correct = do_aspect_correct;
+ cache->do_mask_aa = do_mask_aa;
+ cache->do_feather = do_feather;
+
+ mask->raster_cache = cache;
+#endif
}
Modified: branches/soc-2011-tomato/source/blender/blenloader/intern/readblenentry.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenloader/intern/readblenentry.c 2012-07-03 14:25:06 UTC (rev 48539)
+++ branches/soc-2011-tomato/source/blender/blenloader/intern/readblenentry.c 2012-07-03 14:30:55 UTC (rev 48540)
@@ -310,6 +310,9 @@
/* makes lookup of existing video clips in old main */
blo_make_movieclip_pointer_map(fd, oldmain);
+ /* makes lookup of existing masks in old main */
+ blo_make_mask_pointer_map(fd, oldmain);
+
bfd = blo_read_file_internal(fd, filename);
/* ensures relinked images are not freed */
@@ -318,6 +321,9 @@
/* ensures relinked movie clips are not freed */
blo_end_movieclip_pointer_map(fd, oldmain);
+ /* ensures relinked masks are not freed */
+ blo_end_mask_pointer_map(fd, oldmain);
+
/* move libraries from old main to new main */
if (bfd && mainlist.first != mainlist.last) {
Modified: branches/soc-2011-tomato/source/blender/blenloader/intern/readfile.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenloader/intern/readfile.c 2012-07-03 14:25:06 UTC (rev 48539)
+++ branches/soc-2011-tomato/source/blender/blenloader/intern/readfile.c 2012-07-03 14:30:55 UTC (rev 48540)
@@ -1090,6 +1090,10 @@
oldnewmap_free(fd->imamap);
if (fd->movieclipmap)
oldnewmap_free(fd->movieclipmap);
+#ifdef USE_MANGO_MASK_CACHE_HACK
+ if (fd->maskmap)
+ oldnewmap_free(fd->maskmap);
+#endif
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
oldnewmap_free(fd->libmap);
if (fd->bheadmap)
@@ -1174,7 +1178,16 @@
return NULL;
}
+#ifdef USE_MANGO_MASK_CACHE_HACK
+static void *newmaskadr(FileData *fd, void *adr) /* used to restore mask data after undo */
+{
+ if (fd->maskmap && adr)
+ return oldnewmap_lookup_and_inc(fd->maskmap, adr);
+ return NULL;
+}
+#endif
+
static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
{
return oldnewmap_liblookup(fd->libmap, adr, lib);
@@ -1369,7 +1382,39 @@
}
}
+#ifdef USE_MANGO_MASK_CACHE_HACK
+void blo_make_mask_pointer_map(FileData *fd, Main *oldmain)
+{
+ Mask *mask;
+ fd->maskmap = oldnewmap_new();
+
+ for (mask = oldmain->movieclip.first; mask; mask = mask->id.next) {
+ if (mask->raster_cache)
+ oldnewmap_insert(fd->maskmap, mask->raster_cache, mask->raster_cache, 0);
+ }
+}
+
+/* set old main mask caches to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_mask_pointer_map(FileData *fd, Main *oldmain)
+{
+ OldNew *entry = fd->movieclipmap->entries;
+ Mask *mask;
+ int i;
+
+ /* used entries were restored, so we put them to zero */
+ for (i = 0; i < fd->movieclipmap->nentries; i++, entry++) {
+ if (entry->nr > 0)
+ entry->newp = NULL;
+ }
+
+ for (mask = oldmain->mask.first; mask; mask = mask->id.next) {
+ mask->raster_cache = newmclipadr(fd, mask->raster_cache);
+ }
+}
+#endif
+
/* undo file support: add all library pointers in lookup */
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
{
@@ -6252,6 +6297,11 @@
{
MaskLayer *masklay;
+#ifdef USE_MANGO_MASK_CACHE_HACK
+ if (fd->maskmap) mask->raster_cache = newmaskadr(fd, mask->raster_cache);
+ else mask->raster_cache = NULL;
+#endif
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list