Cycles: svn merge -r41232:41266 ^/trunk/blender
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 24 Oct 2011 22:51:44 +0000 (22:51 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 24 Oct 2011 22:51:44 +0000 (22:51 +0000)
34 files changed:
build_files/cmake/project_info.py
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/memutil/MEM_CacheLimiter.h
intern/memutil/MEM_CacheLimiterC-Api.h
intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/seqcache.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/math_vector_inline.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/imbuf/CMakeLists.txt
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/IMB_moviecache.h [new file with mode: 0644]
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/module.c
source/blender/imbuf/intern/moviecache.c [new file with mode: 0644]
source/blender/makesdna/DNA_ID.h
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_fcurve.c
source/blender/render/intern/source/convertblender.c
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Ketsji/BL_Action.cpp

index 76183c01f9420fe69cf3c49106cde95d9e315808..f57778f9858f05d511934aa6371a4ccd25def34f 100755 (executable)
@@ -104,7 +104,7 @@ def is_glsl(filename):
 
 def is_c(filename):
     ext = splitext(filename)[1]
-    return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
+    return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc"))
 
 
 def is_c_any(filename):
index ffc858d2fc52717eb00b32cf9097be8f4469b9e9..d9eab56cfdc9fe9eb9e6d161f931025902d1aec7 100644 (file)
@@ -1685,6 +1685,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
                                }
                        }
 
+                       /* arrow keys should not have utf8 */
+                       if ((keyCode > 266) && (keyCode < 271))
+                               utf8_buf[0] = '\0';
+
                        if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
                                break; //Cmd-Q is directly handled by Cocoa
 
index 7f858c323c07c39edc24ceecea1318c091a395bd..5194c97fd78157b2ed82bfbc15b50cdf83fdbba0 100644 (file)
@@ -125,6 +125,10 @@ class MEM_CacheLimiter {
 public:
        typedef typename std::list<MEM_CacheLimiterHandle<T> *,
          MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator iterator;
+       typedef intptr_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
+       MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func getDataSize_)
+               : getDataSize(getDataSize_) {
+       }
        ~MEM_CacheLimiter() {
                for (iterator it = queue.begin(); it != queue.end(); it++) {
                        delete *it;
@@ -143,17 +147,36 @@ public:
        }
        void enforce_limits() {
                intptr_t max = MEM_CacheLimiter_get_maximum();
-               intptr_t mem_in_use= MEM_get_memory_in_use();
-               intptr_t mmap_in_use= MEM_get_mapped_memory_in_use();
+               intptr_t mem_in_use, cur_size;
 
                if (max == 0) {
                        return;
                }
+
+               if(getDataSize) {
+                       mem_in_use = total_size();
+               } else {
+                       mem_in_use = MEM_get_memory_in_use();
+               }
+
                for (iterator it = queue.begin(); 
-                    it != queue.end() && mem_in_use + mmap_in_use > max;) {
+                    it != queue.end() && mem_in_use > max;) {
                        iterator jt = it;
                        ++it;
+
+                       if(getDataSize) {
+                               cur_size= getDataSize((*jt)->get()->get_data());
+                       } else {
+                               cur_size= mem_in_use;
+                       }
+
                        (*jt)->destroy_if_possible();
+
+                       if(getDataSize) {
+                               mem_in_use-= cur_size;
+                       } else {
+                               mem_in_use-= cur_size - MEM_get_memory_in_use();
+                       }
                }
        }
        void touch(MEM_CacheLimiterHandle<T> * handle) {
@@ -164,8 +187,17 @@ public:
                handle->me = it;
        }
 private:
+       intptr_t total_size() {
+               intptr_t size = 0;
+               for (iterator it = queue.begin(); it != queue.end(); it++) {
+                       size+= getDataSize((*it)->get()->get_data());
+               }
+               return size;
+       }
+
        std::list<MEM_CacheLimiterHandle<T>*,
          MEM_Allocator<MEM_CacheLimiterHandle<T> *> > queue;
+       MEM_CacheLimiter_DataSize_Func getDataSize;
 };
 
 #endif // MEM_CACHELIMITER_H
index 72645b9ce7b57e42525d2b58cc594f0978b47f1c..768842caee6a7875556ec0de67e1bb3eecc827a8 100644 (file)
@@ -41,6 +41,9 @@ typedef struct MEM_CacheLimiterHandle_s MEM_CacheLimiterHandleC;
 /* function used to remove data from memory */
 typedef void(*MEM_CacheLimiter_Destruct_Func)(void*);
 
+/* function used to measure stored data element size */
+typedef intptr_t(*MEM_CacheLimiter_DataSize_Func) (void*);
+
 #ifndef MEM_CACHELIMITER_H
 extern void MEM_CacheLimiter_set_maximum(int m);
 extern int MEM_CacheLimiter_get_maximum(void);
@@ -54,7 +57,8 @@ extern int MEM_CacheLimiter_get_maximum(void);
  */
 
 extern MEM_CacheLimiterC * new_MEM_CacheLimiter(
-       MEM_CacheLimiter_Destruct_Func data_destructor);
+       MEM_CacheLimiter_Destruct_Func data_destructor,
+       MEM_CacheLimiter_DataSize_Func data_size);
 
 /** 
  * Delete MEM_CacheLimiter
index 1bc011a5be0d75d18d8064f82b9114e9a579384a..cc8d2497f37747aa812365ddd3bcf6144664c118 100644 (file)
@@ -54,8 +54,8 @@ typedef std::list<MEM_CacheLimiterHandleCClass*,
 
 class MEM_CacheLimiterCClass {
 public:
-       MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_)
-               : data_destructor(data_destructor_) { 
+       MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_, MEM_CacheLimiter_DataSize_Func data_size)
+               : data_destructor(data_destructor_), cache(data_size) {
        }
         ~MEM_CacheLimiterCClass();
        
@@ -142,10 +142,12 @@ static inline handle_t* cast(MEM_CacheLimiterHandleC * l)
 }
 
 MEM_CacheLimiterC * new_MEM_CacheLimiter(
-       MEM_CacheLimiter_Destruct_Func data_destructor)
+       MEM_CacheLimiter_Destruct_Func data_destructor,
+       MEM_CacheLimiter_DataSize_Func data_size)
 {
        return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass(
-               data_destructor);
+               data_destructor,
+               data_size);
 }
 
 void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This)
index b5e4cde53ca3a254bad8f2f25ec5667e753730b9..27e9140ba77eb77754f73b42cd1ac1807184031f 100644 (file)
@@ -213,10 +213,12 @@ struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop,
 int binarysearch_bezt_index(struct BezTriple array[], float frame, int arraylen, short *replace);
 
 /* get the time extents for F-Curve */
-void calc_fcurve_range(struct FCurve *fcu, float *min, float *max, const short selOnly);
+void calc_fcurve_range(struct FCurve *fcu, float *min, float *max,
+                       const short do_sel_only, const short do_min_length);
 
 /* get the bounding-box extents for F-Curve */
-void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly);
+void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
+                        const short do_sel_only);
 
 /* .............. */
 
index a44618dcbe89b7daf172ea8a48644dd1536d0acd..947eafa9dd3796ce710f53042784a003f58f1fc6 100644 (file)
@@ -50,6 +50,7 @@ void *copy_libblock(void *rt);
 void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action);
 
 void id_lib_extern(struct ID *id);
+void BKE_library_filepath_set(struct Library *lib, const char *filepath);
 void id_us_plus(struct ID *id);
 void id_us_min(struct ID *id);
 int id_make_local(struct ID *id, int test);
index 759060d408e8c5d6ad3bfc872a67fb23ef940be8..e64de965db58d4f94b8a59a090053c457c990155 100644 (file)
@@ -215,9 +215,7 @@ typedef enum {
        SEQ_STRIPELEM_IBUF_ENDSTILL
 } seq_stripelem_ibuf_t;
 
-void seq_stripelem_cache_init(void);
 void seq_stripelem_cache_destruct(void);
-
 void seq_stripelem_cache_cleanup(void);
 
 /* returned ImBuf is properly refed and has to be freed */
index 8d18a1c27e707341c03e536661df1ee956309af6..e46e2df83530ecbc4427be62573d8fa4807f79e7 100644 (file)
@@ -881,7 +881,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
                                
                                /* get extents for this curve */
                                // TODO: allow enabling/disabling this?
-                               calc_fcurve_range(fcu, &nmin, &nmax, FALSE);
+                               calc_fcurve_range(fcu, &nmin, &nmax, FALSE, TRUE);
                                
                                /* compare to the running tally */
                                min= MIN2(min, nmin);
index 5e38e06ed0c7763fa66b3eec0cb1cd00658ebcd1..4cbdbeb890d7703fb6322b8aee9fdb4d2c94810c 100644 (file)
@@ -61,6 +61,7 @@
 #include "BLI_callbacks.h"
 
 #include "IMB_imbuf.h"
+#include "IMB_moviecache.h"
 
 #include "BKE_blender.h"
 #include "BKE_context.h"
@@ -111,6 +112,7 @@ void free_blender(void)
        BLI_cb_finalize();
 
        seq_stripelem_cache_destruct();
+       IMB_moviecache_destruct();
        
        free_nodesystem();      
 }
index 737baa1ddc47b9026074583e2d77ffa82e566b0b..3529b7b9e6d45aebe60363de0afec93bb3f6820d 100644 (file)
@@ -433,7 +433,8 @@ int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short
 /* ...................................... */
 
 /* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */
-static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last, const short selOnly)
+static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last,
+                                      const short do_sel_only)
 {
        /* init outputs */
        *first = NULL;
@@ -444,7 +445,7 @@ static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple
                return;
        
        /* only include selected items? */
-       if (selOnly) {
+       if (do_sel_only) {
                BezTriple *bezt;
                unsigned int i;
                
@@ -475,11 +476,12 @@ static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple
 
 
 /* Calculate the extents of F-Curve's data */
-void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly)
+void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
+                         const short do_sel_only)
 {
        float xminv=999999999.0f, xmaxv=-999999999.0f;
        float yminv=999999999.0f, ymaxv=-999999999.0f;
-       short foundvert=0;
+       short foundvert= FALSE;
        unsigned int i;
        
        if (fcu->totvert) {
@@ -488,7 +490,7 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
                        
                        if (xmin || xmax) {
                                /* get endpoint keyframes */
-                               get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
+                               get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
                                
                                if (bezt_first) {
                                        BLI_assert(bezt_last != NULL);
@@ -503,11 +505,12 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
                                BezTriple *bezt;
                                
                                for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
-                                       if ((selOnly == 0) || BEZSELECTED(bezt)) {
+                                       if ((do_sel_only == 0) || BEZSELECTED(bezt)) {
                                                if (bezt->vec[1][1] < yminv)
                                                        yminv= bezt->vec[1][1];
                                                if (bezt->vec[1][1] > ymaxv)
                                                        ymaxv= bezt->vec[1][1];
+                                               foundvert= TRUE;
                                        }
                                }
                        }
@@ -528,11 +531,11 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
                                                yminv= fpt->vec[1];
                                        if (fpt->vec[1] > ymaxv)
                                                ymaxv= fpt->vec[1];
+
+                                       foundvert= TRUE;
                                }
                        }
                }
-               
-               foundvert=1;
        }
        
        if (foundvert) {
@@ -555,43 +558,50 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
 }
 
 /* Calculate the extents of F-Curve's keyframes */
-void calc_fcurve_range (FCurve *fcu, float *start, float *end, const short selOnly)
+void calc_fcurve_range (FCurve *fcu, float *start, float *end,
+                        const short do_sel_only, const short do_min_length)
 {
        float min=999999999.0f, max=-999999999.0f;
-       short foundvert=0;
+       short foundvert= FALSE;
 
        if (fcu->totvert) {
                if (fcu->bezt) {
                        BezTriple *bezt_first= NULL, *bezt_last= NULL;
                        
                        /* get endpoint keyframes */
-                       get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
-                       
+                       get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
+
                        if (bezt_first) {
                                BLI_assert(bezt_last != NULL);
-                               
+
                                min= MIN2(min, bezt_first->vec[1][0]);
                                max= MAX2(max, bezt_last->vec[1][0]);
+
+                               foundvert= TRUE;
                        }
                }
                else if (fcu->fpt) {
                        min= MIN2(min, fcu->fpt[0].vec[0]);
                        max= MAX2(max, fcu->fpt[fcu->totvert-1].vec[0]);
+
+                       foundvert= TRUE;
                }
                
-               foundvert=1;
        }
        
-       /* minimum length is 1 frame */
-       if (foundvert) {
-               if (min == max) max += 1.0f;
-               *start= min;
-               *end= max;
+       if (foundvert == FALSE) {
+               min= max= 0.0f;
        }
-       else {
-               *start= 0.0f;
-               *end= 1.0f;
+
+       if (do_min_length) {
+               /* minimum length is 1 frame */
+               if (min == max) {
+                       max += 1.0f;
+               }
        }
+
+       *start= min;
+       *end= max;
 }
 
 /* ----------------- Status Checks -------------------------- */
index 6cde2511a47d1dafd3d3229f328d99d36b6bc563..c44ccd7aa579fb3710675e51d90c876fb80d0c87 100644 (file)
@@ -1461,3 +1461,21 @@ void name_uiprefix_id(char *name, ID *id)
 
        strcpy(name+3, id->name+2);
 }
+
+void BKE_library_filepath_set(Library *lib, const char *filepath)
+{
+       BLI_strncpy(lib->name, filepath, sizeof(lib->name));
+       BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath));
+
+       /* not essential but set filepath is an absolute copy of value which
+        * is more useful if its kept in sync */
+       if (strncmp(lib->filepath, "//", 2) == 0) {
+               /* note that the file may be unsaved, in this case, setting the
+                * filepath on an indirectly linked path is not allowed from the
+                * outliner, and its not really supported but allow from here for now
+                * since making local could cause this to be directly linked - campbell
+                */
+               const char *basepath= lib->parent ? lib->parent->filepath : G.main->name;
+               BLI_path_abs(lib->filepath, basepath);
+       }
+}
index 31a780aa977ffd70ee46c2c771591217c5ea464f..c5761dcc4560542262a5cc59359e9819a84a417a 100644 (file)
@@ -17,6 +17,8 @@
  *
  * Peter Schlaile <peter [at] schlaile [dot] de> 2010
  *
+ * Contributor(s): Sergey Sharybin
+ *
  * ***** END GPL LICENSE BLOCK *****
  */
 
 
 
 #include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
+
+#include "BLO_sys_types.h"     /* for intptr_t */
 
 #include "MEM_guardedalloc.h"
-#include "MEM_CacheLimiterC-Api.h"
 
 #include "DNA_sequence_types.h"
 #include "BKE_sequencer.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_mempool.h"
-#include <pthread.h>
 
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
+#include "IMB_moviecache.h"
 
 typedef struct seqCacheKey 
 {
@@ -51,20 +46,9 @@ typedef struct seqCacheKey
        seq_stripelem_ibuf_t type;
 } seqCacheKey;
 
-typedef struct seqCacheEntry
-{
-       ImBuf * ibuf;
-       MEM_CacheLimiterHandleC * c_handle;
-} seqCacheEntry;
-
-static GHash * hash = NULL;
-static MEM_CacheLimiterC * limitor = NULL;
-static struct BLI_mempool * entrypool = NULL;
-static struct BLI_mempool * keypool = NULL;
-static int ibufs_in  = 0;
-static int ibufs_rem = 0;
-
-static unsigned int HashHash(const void *key_)
+static struct MovieCache *moviecache = NULL;
+
+static unsigned int seqcache_hashhash(const void *key_)
 {
        const seqCacheKey *key = (seqCacheKey*) key_;
        unsigned int rval = seq_hash_render_data(&key->context);
@@ -76,7 +60,7 @@ static unsigned int HashHash(const void *key_)
        return rval;
 }
 
-static int HashCmp(const void *a_, const void *b_)
+static int seqcache_hashcmp(const void *a_, const void *b_)
 {
        const seqCacheKey * a = (seqCacheKey*) a_;
        const seqCacheKey * b = (seqCacheKey*) b_;
@@ -105,109 +89,37 @@ static int HashCmp(const void *a_, const void *b_)
        return seq_cmp_render_data(&a->context, &b->context);
 }
 
-static void HashKeyFree(void *key)
-{
-       BLI_mempool_free(keypool, key);
-}
-
-static void HashValFree(void *val)
-{
-       seqCacheEntry* e = (seqCacheEntry*) val;
-
-       if (e->ibuf) {
-               /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, 
-                  e->ibuf->refcounter); */
-               IMB_freeImBuf(e->ibuf);
-               MEM_CacheLimiter_unmanage(e->c_handle);
-               ibufs_rem++;
-       }
-
-       e->ibuf = NULL;
-       e->c_handle = NULL;
-
-       BLI_mempool_free(entrypool, e);
-}
-
-static void IMB_seq_cache_destructor(void * p)
-{
-       seqCacheEntry* e = (seqCacheEntry*) p;
-       
-       if (e && e->ibuf) {
-               /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
-                  e->ibuf->refcounter); */
-               IMB_freeImBuf(e->ibuf);
-               ibufs_rem++;
-
-               e->ibuf = NULL;
-               e->c_handle = NULL;
-       }
-}
-
-void seq_stripelem_cache_init(void)
-{
-       hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
-       limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor );
-
-       entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0);
-       keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0);
-}
-
 void seq_stripelem_cache_destruct(void)
 {
-       if (!entrypool) {
-               return;
-       }
-       BLI_ghash_free(hash, HashKeyFree, HashValFree);
-       delete_MEM_CacheLimiter(limitor);
-       BLI_mempool_destroy(entrypool);
-       BLI_mempool_destroy(keypool);
+       if(moviecache)
+               IMB_moviecache_free(moviecache);
 }
 
 void seq_stripelem_cache_cleanup(void)
 {
-       if (!entrypool) {
-               seq_stripelem_cache_init();
+       if(moviecache) {
+               IMB_moviecache_free(moviecache);
+               moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash,
+                               seqcache_hashcmp, NULL);
        }
-
-       /* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n",
-          ibufs_in, ibufs_rem); */
-
-       BLI_ghash_free(hash, HashKeyFree, HashValFree);
-       hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
-
-       /* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n",
-          ibufs_in, ibufs_rem); */
-
 }
 
 struct ImBuf * seq_stripelem_cache_get(
        SeqRenderData context, struct Sequence * seq, 
        float cfra, seq_stripelem_ibuf_t type)
 {
-       seqCacheKey key;
-       seqCacheEntry * e;
-
-       if (!seq) {
-               return NULL;
-       }
-
-       if (!entrypool) {
-               seq_stripelem_cache_init();
-       }
 
-       key.seq = seq;
-       key.context = context;
-       key.cfra = cfra - seq->start;
-       key.type = type;
-       
-       e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key);
+       if(moviecache && seq) {
+               seqCacheKey key;
 
-       if (e && e->ibuf) {
-               IMB_refImBuf(e->ibuf);
+               key.seq = seq;
+               key.context = context;
+               key.cfra = cfra - seq->start;
+               key.type = type;
 
-               MEM_CacheLimiter_touch(e->c_handle);
-               return e->ibuf;
+               return IMB_moviecache_get(moviecache, &key);
        }
+
        return NULL;
 }
 
@@ -215,39 +127,21 @@ void seq_stripelem_cache_put(
        SeqRenderData context, struct Sequence * seq, 
        float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i)
 {
-       seqCacheKey * key;
-       seqCacheEntry * e;
+       seqCacheKey key;
 
        if (!i) {
                return;
        }
 
-       ibufs_in++;
-
-       if (!entrypool) {
-               seq_stripelem_cache_init();
+       if(!moviecache) {
+               moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash,
+                               seqcache_hashcmp, NULL);
        }
 
-       key = (seqCacheKey*) BLI_mempool_alloc(keypool);
-
-       key->seq = seq;
-       key->context = context;
-       key->cfra = cfra - seq->start;
-       key->type = type;
-
-       IMB_refImBuf(i);
-
-       e = (seqCacheEntry*) BLI_mempool_alloc(entrypool);
-
-       e->ibuf = i;
-       e->c_handle = NULL;
-
-       BLI_ghash_remove(hash, key, HashKeyFree, HashValFree);
-       BLI_ghash_insert(hash, key, e);
-
-       e->c_handle = MEM_CacheLimiter_insert(limitor, e);
+       key.seq = seq;
+       key.context = context;
+       key.cfra = cfra - seq->start;
+       key.type = type;
 
-       MEM_CacheLimiter_ref(e->c_handle);
-       MEM_CacheLimiter_enforce_limits(limitor);
-       MEM_CacheLimiter_unref(e->c_handle);
+       IMB_moviecache_put(moviecache, &key, i);
 }
index 5d52874b3b39dce47888c9c846be2ad05de9ad72..6b319e6b5e1444eec79945deafcc80a048cf3c2c 100644 (file)
@@ -1324,6 +1324,10 @@ static void seq_proxy_build_frame(SeqRenderData context,
        quality = seq->strip->proxy->quality;
        ibuf->ftype= JPG | quality;
 
+       /* unsupported feature only confuses other s/w */
+       if(ibuf->depth==32)
+               ibuf->depth= 24;
+
        BLI_make_existing_file(name);
        
        ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
@@ -2501,9 +2505,6 @@ static void *seq_prefetch_thread(void * This_)
 
                for (e = prefetch_done.first; e; e = e->next) {
                        if (s_last > e->monoton_cfra) {
-                               if (e->ibuf) {
-                                       IMB_cache_limiter_unref(e->ibuf);
-                               }
                                BLI_remlink(&prefetch_done, e);
                                MEM_freeN(e);
                        }
@@ -2581,9 +2582,6 @@ static void seq_stop_threads()
        }
 
        for (e = prefetch_done.first; e; e = e->next) {
-               if (e->ibuf) {
-                       IMB_cache_limiter_unref(e->ibuf);
-               }
                BLI_remlink(&prefetch_done, e);
                MEM_freeN(e);
        }
index ed0a351716c417c5fd72ff775733016af57cd030..bdca3c8e6186b497f6892125965679199bfe31b6 100644 (file)
@@ -396,6 +396,20 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
        }
 }
 
+static int ffmpeg_proprty_valid(AVCodecContext *c, const char *prop_name, IDProperty *curr)
+{
+       int valid= 1;
+
+       if(strcmp(prop_name, "video")==0) {
+               if(strcmp(curr->name, "bf")==0) {
+                       /* flash codec doesn't support b frames */
+                       valid&= c->codec_id!=CODEC_ID_FLV1;
+               }
+       }
+
+       return valid;
+}
+
 static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char * prop_name)
 {
        IDProperty * prop;
@@ -414,7 +428,8 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
        iter = IDP_GetGroupIterator(prop);
 
        while ((curr = IDP_GroupIterNext(iter)) != NULL) {
-               set_ffmpeg_property_option(c, curr);
+               if(ffmpeg_proprty_valid(c, prop_name, curr))
+                       set_ffmpeg_property_option(c, curr);
        }
 }
 
@@ -1187,6 +1202,9 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
 {
        int isntsc = (rd->frs_sec != 25);
 
+       if(rd->ffcodecdata.properties)
+               IDP_FreeProperty(rd->ffcodecdata.properties);
+
        switch (preset) {
        case FFMPEG_PRESET_VCD:
                rd->ffcodecdata.type = FFMPEG_MPEG1;
@@ -1217,8 +1235,11 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
        case FFMPEG_PRESET_DVD:
                rd->ffcodecdata.type = FFMPEG_MPEG2;
                rd->ffcodecdata.video_bitrate = 6000;
-               rd->xsch = 720;
-               rd->ysch = isntsc ? 480 : 576;
+
+               /* Don't set resolution, see [#21351]
+                * rd->xsch = 720;
+                * rd->ysch = isntsc ? 480 : 576; */
+
                rd->ffcodecdata.gop_size = isntsc ? 18 : 15;
                rd->ffcodecdata.rc_max_rate = 9000;
                rd->ffcodecdata.rc_min_rate = 0;
@@ -1321,8 +1342,8 @@ void ffmpeg_verify_image_type(RenderData *rd)
                   rd->ffcodecdata.video_bitrate <= 1) {
 
                        rd->ffcodecdata.codec = CODEC_ID_MPEG2VIDEO;
-                       /* Don't set preset, disturbs render resolution.
-                        * ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD); */
+
+                       ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD);
                }
                if(rd->ffcodecdata.type == FFMPEG_OGG) {
                        rd->ffcodecdata.type = FFMPEG_MPEG2;
index 2bb51870fd613d917f0132398748079428222a90..e259071a27ac4943b0ebbf5b92cacc7f19786be0 100644 (file)
@@ -92,6 +92,8 @@ MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], floa
 MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
 MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f);
 
+MINLINE void negate_v2(float r[2]);
+MINLINE void negate_v2_v2(float r[2], const float a[2]);
 MINLINE void negate_v3(float r[3]);
 MINLINE void negate_v3_v3(float r[3], const float a[3]);
 MINLINE void negate_v4(float r[4]);
index 5f5a0acc4276319fbabbf74a26bf6f08c8ae6269..c460b69679b4a0c43a1d22d1f15f0bbf0210ee43 100644 (file)
@@ -308,6 +308,18 @@ MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
        r[2] = v1[2] * v2[2];
 }
 
+MINLINE void negate_v2(float r[3])
+{
+       r[0]= -r[0];
+       r[1]= -r[1];
+}
+
+MINLINE void negate_v2_v2(float r[2], const float a[2])
+{
+       r[0]= -a[0];
+       r[1]= -a[1];
+}
+
 MINLINE void negate_v3(float r[3])
 {
        r[0]= -r[0];
index 9f77317292c5167c46284b27a4b595a25b483505..9d8e2f33f5c8e3470ee91d7878eff0e6f2d051b1 100644 (file)
@@ -1437,8 +1437,11 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
        ui_check_but(but);
 }
 
-/* note: utf8 & ascii funcs should be merged */
-static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const char utf8_buf[6])
+/* this is used for both utf8 and ascii, its meant to be used for single keys,
+ * notie the buffer is either copied or not, so its not suitable for pasting in
+ * - campbell */
+static int ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data,
+                                const char *utf8_buf, int utf8_buf_len)
 {
        char *str;
        int len, changed= 0;
@@ -1447,7 +1450,7 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
        len= strlen(str);
 
        if(len-(but->selend - but->selsta)+1 <= data->maxlen) {
-               int step= BLI_str_utf8_size(utf8_buf);
+               int step= utf8_buf_len;
 
                /* type over the current selection */
                if ((but->selend - but->selsta) > 0) {
@@ -1468,8 +1471,17 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
 
 static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char ascii)
 {
-       char utf8_buf[6]= {ascii, '\0'};
-       return ui_textedit_type_utf8(but, data, utf8_buf);
+       char buf[2]= {ascii, '\0'};
+
+       if (ui_is_but_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
+               printf("%s: entering invalid ascii char into an ascii key (%d)\n",
+                      __func__, (int)(unsigned char)ascii);
+
+               return 0;
+       }
+
+       /* in some cases we want to allow invalid utf8 chars */
+       return ui_textedit_type_buf(but, data, buf, 1);
 }
 
 static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, uiButtonJumpType jump)
@@ -1941,9 +1953,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
 
                        if(event->utf8_buf[0]) {
                                /* keep this printf until utf8 is well tested */
-                               printf("%s: utf8 char '%s'\n", __func__, event->utf8_buf);
+                               printf("%s: utf8 char '%.*s'\n", __func__, BLI_str_utf8_size(event->utf8_buf), event->utf8_buf);
                                // strcpy(event->utf8_buf, "12345");
-                               changed= ui_textedit_type_utf8(but, data, event->utf8_buf);
+                               changed= ui_textedit_type_buf(but, data, event->utf8_buf, BLI_str_utf8_size(event->utf8_buf));
                        }
                        else {
                                changed= ui_textedit_type_ascii(but, data, ascii);
index 7bf0f98b471906592461643ff54b6beb0574ee6a..eb29dfb2ce1784f2de1e1554904875c8e416674c 100644 (file)
@@ -261,7 +261,7 @@ static void get_keyframe_extents (bAnimContext *ac, float *min, float *max, cons
                                float tmin, tmax;
 
                                /* get range and apply necessary scaling before processing */
-                               calc_fcurve_range(fcu, &tmin, &tmax, onlySel);
+                               calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE);
 
                                if (adt) {
                                        tmin= BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
index 10ca482ae0ed7da2dc353e0f5c4ff390bed6cf53..608a3c4c0b28886f4e6eb6f26acb9f34adc9cded 100644 (file)
@@ -310,11 +310,19 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
                        }                                       
                        /* Check the library target exists */
                        if (te->idcode == ID_LI) {
-                               char expanded[FILE_MAXDIR + FILE_MAXFILE];
-                               BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE);
+                               Library *lib= (Library *)tselem->id;
+                               char expanded[FILE_MAX];
+
+                               BLI_strncpy(expanded, lib->name, sizeof(expanded));
+
+                               /* even though we already set the name this syncs the absolute
+                                * path, this is intentionally not already expanded yet to
+                                * avoid copying lib->name to its self. */
+                               BKE_library_filepath_set(lib, expanded);
+
                                BLI_path_abs(expanded, G.main->name);
                                if (!BLI_exists(expanded)) {
-                                       BKE_report(CTX_wm_reports(C), RPT_ERROR, "This path does not exist, correct this before saving");
+                                       BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Library path '%s' does not exist, correct this before saving", expanded);
                                }
                        }
                }
index 5df61619ece76a2283c914ecf26635a91d892446..6e26fb15873145128a4a867dabbbe9a24609ae91 100644 (file)
@@ -161,17 +161,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
        RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */
        RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1);
 
-       /* 3D mouse */
-       WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
-       WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
-       WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
-       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
-
        /* numpad view hotkeys*/
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
        RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
@@ -220,6 +209,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
        kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
        RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
        RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+       
+       /* 3D mouse */
+       WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
+       WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
+       RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
 
        /* 3D mouse align */
        kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
index 76c69292b0ff5d0b93f1a2c583c9fc271fb44190..6aef9a4254e64c2f0f088d79fbeeb02d2d131b44 100644 (file)
@@ -61,6 +61,7 @@ set(SRC
        intern/md5.c
        intern/metadata.c
        intern/module.c
+       intern/moviecache.c
        intern/openimageio.cpp
        intern/png.c
        intern/readimage.c
@@ -75,6 +76,7 @@ set(SRC
 
        IMB_imbuf.h
        IMB_imbuf_types.h
+       IMB_moviecache.h
        IMB_thumbs.h
        intern/IMB_allocimbuf.h
        intern/IMB_anim.h
index e57130c7c3586408a43f39c37f9764308d9c52dc..5f03ca9ba28cb5617f040c21b20ed184fa1b908e 100644 (file)
@@ -133,19 +133,6 @@ struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y,
 void IMB_refImBuf(struct ImBuf *ibuf);
 struct ImBuf * IMB_makeSingleUser(struct ImBuf *ibuf);
 
-/**
- *
- * @attention Defined in allocimbuf.c
- */
-void IMB_cache_limiter_insert(struct ImBuf *i);
-void IMB_cache_limiter_unmanage(struct ImBuf *i);
-void IMB_cache_limiter_touch(struct ImBuf *i);
-void IMB_cache_limiter_ref(struct ImBuf *i);
-void IMB_cache_limiter_unref(struct ImBuf *i);
-int IMB_cache_limiter_get_refcount(struct ImBuf *i);
-
-void IMB_free_cache_limiter(void);
-
 /**
  *
  * @attention Defined in allocimbuf.c
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
new file mode 100644 (file)
index 0000000..309c6ee
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef IMB_MOVIECACHE_H
+#define IMB_MOVIECACHE_H
+
+/** \file IMB_moviecache.h
+ *  \ingroup imbuf
+ *  \author Sergey Sharybin
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+/* Cache system for movie data - now supports stoting ImBufs only
+   Supposed to provide unified cache system for movie clips, sequencer and
+   other movie-related areas */
+
+struct ImBuf;
+struct MovieCache;
+
+typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr, int *proxy, int *render_flags);
+
+void IMB_moviecache_init(void);
+void IMB_moviecache_destruct(void);
+
+struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp, MovieCacheGetKeyDataFP getdatafp);
+void IMB_moviecache_put(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
+struct ImBuf* IMB_moviecache_get(struct MovieCache *cache, void *userkey);
+void IMB_moviecache_free(struct MovieCache *cache);
+void IMB_moviecache_get_cache_segments(struct MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r);
+
+#endif
index 077d907dda023068045e12348b2a558747c8d4da..98828c58511c5d5e414ea76faeb50edc668efd1f 100644 (file)
@@ -164,7 +164,6 @@ void IMB_freeImBuf(ImBuf *ibuf)
                        IMB_freezbufImBuf(ibuf);
                        IMB_freezbuffloatImBuf(ibuf);
                        freeencodedbufferImBuf(ibuf);
-                       IMB_cache_limiter_unmanage(ibuf);
                        IMB_metadata_free(ibuf);
                        MEM_freeN(ibuf);
                }
@@ -467,60 +466,7 @@ static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
        static MEM_CacheLimiterC *c = NULL;
 
        if(!c)
-               c = new_MEM_CacheLimiter(imbuf_cache_destructor);
+               c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
 
        return &c;
 }
-
-void IMB_free_cache_limiter(void)
-{
-       delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
-       *get_imbuf_cache_limiter() = NULL;
-}
-
-void IMB_cache_limiter_insert(ImBuf *i)
-{
-       if(!i->c_handle) {
-               i->c_handle = MEM_CacheLimiter_insert(
-                       *get_imbuf_cache_limiter(), i);
-               MEM_CacheLimiter_ref(i->c_handle);
-               MEM_CacheLimiter_enforce_limits(
-                       *get_imbuf_cache_limiter());
-               MEM_CacheLimiter_unref(i->c_handle);
-       }
-}
-
-void IMB_cache_limiter_unmanage(ImBuf *i)
-{
-       if(i->c_handle) {
-               MEM_CacheLimiter_unmanage(i->c_handle);
-               i->c_handle = NULL;
-       }
-}
-
-void IMB_cache_limiter_touch(ImBuf *i)
-{
-       if(i->c_handle)
-               MEM_CacheLimiter_touch(i->c_handle);
-}
-
-void IMB_cache_limiter_ref(ImBuf *i)
-{
-       if(i->c_handle)
-               MEM_CacheLimiter_ref(i->c_handle);
-}
-
-void IMB_cache_limiter_unref(ImBuf *i)
-{
-       if(i->c_handle)
-               MEM_CacheLimiter_unref(i->c_handle);
-}
-
-int IMB_cache_limiter_get_refcount(ImBuf *i)
-{
-       if(i->c_handle)
-               return MEM_CacheLimiter_get_refcount(i->c_handle);
-
-       return 0;
-}
-
index 242d7dcb7001930c2e02f1010245fe735af29e49..3a94c79f48d5fda889fd4da2debbec23c5a83a09 100644 (file)
@@ -452,7 +452,7 @@ static int round_up(int x, int mod)
 static struct proxy_output_ctx * alloc_proxy_output_ffmpeg(
        struct anim * anim,
        AVStream * st, int proxy_size, int width, int height,
-       int quality)
+       int UNUSED(quality))
 {
        struct proxy_output_ctx * rv = MEM_callocN(
                sizeof(struct proxy_output_ctx), "alloc_proxy_output");
index f787a6c777e579cc90ea9b386f266e8789a54a5b..55a293336206f2520c728c6f346fc524faa9f945 100644 (file)
@@ -37,7 +37,6 @@ void IMB_init(void)
 
 void IMB_exit(void)
 {
-       IMB_free_cache_limiter();
        imb_tile_cache_exit();
        imb_filetypes_exit();
 }
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
new file mode 100644 (file)
index 0000000..7492b6a
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin,
+ *                 Peter Schlaile
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/moviecache.c
+ *  \ingroup bke
+ */
+
+#include <stdlib.h> /* for qsort */
+#include <memory.h>
+
+#include "MEM_guardedalloc.h"
+#include "MEM_CacheLimiterC-Api.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_mempool.h"
+
+#include "IMB_moviecache.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+static MEM_CacheLimiterC *limitor= NULL;
+
+typedef struct MovieCache {
+       GHash *hash;
+       GHashHashFP hashfp;
+       GHashCmpFP cmpfp;
+       MovieCacheGetKeyDataFP getdatafp;
+
+       struct BLI_mempool *keys_pool;
+       struct BLI_mempool *items_pool;
+       struct BLI_mempool *userkeys_pool;
+
+       int keysize;
+       unsigned long curtime;
+
+       int totseg, *points, proxy, render_flags;       /* for visual statistics optimization */
+       int pad;
+} MovieCache;
+
+typedef struct MovieCacheKey {
+       MovieCache *cache_owner;
+       void *userkey;
+} MovieCacheKey;
+
+typedef struct MovieCacheItem {
+       MovieCache *cache_owner;
+       ImBuf *ibuf;
+       MEM_CacheLimiterHandleC * c_handle;
+       unsigned long last_access;
+} MovieCacheItem;
+
+static unsigned int moviecache_hashhash(const void *keyv)
+{
+       MovieCacheKey *key= (MovieCacheKey*)keyv;
+
+       return key->cache_owner->hashfp(key->userkey);
+}
+
+static int moviecache_hashcmp(const void *av, const void *bv)
+{
+       const MovieCacheKey *a= (MovieCacheKey*)av;
+       const MovieCacheKey *b= (MovieCacheKey*)bv;
+
+       return a->cache_owner->cmpfp(a->userkey, b->userkey);
+}
+
+static void moviecache_keyfree(void *val)
+{
+       MovieCacheKey *key= (MovieCacheKey*)val;
+
+       BLI_mempool_free(key->cache_owner->keys_pool, key);
+}
+
+static void moviecache_valfree(void *val)
+{
+       MovieCacheItem *item= (MovieCacheItem*)val;
+
+       if (item->ibuf) {
+               MEM_CacheLimiter_unmanage(item->c_handle);
+               IMB_freeImBuf(item->ibuf);
+       }
+
+       BLI_mempool_free(item->cache_owner->items_pool, item);
+}
+
+static void check_unused_keys(MovieCache *cache)
+{
+       GHashIterator *iter;
+
+       iter= BLI_ghashIterator_new(cache->hash);
+       while(!BLI_ghashIterator_isDone(iter)) {
+               MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
+               MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
+
+               BLI_ghashIterator_step(iter);
+
+               if(!item->ibuf)
+                       BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
+       }
+
+       BLI_ghashIterator_free(iter);
+}
+
+static int compare_int(const void *av, const void *bv)
+{
+       const int *a= (int *)av;
+       const int *b= (int *)bv;
+       return *a-*b;
+}
+
+static void IMB_moviecache_destructor(void *p)
+{
+       MovieCacheItem *item= (MovieCacheItem *) p;
+
+       if (item && item->ibuf) {
+               IMB_freeImBuf(item->ibuf);
+
+               item->ibuf= NULL;
+               item->c_handle= NULL;
+       }
+}
+
+/* approximate size of ImBuf in memory */
+static intptr_t IMB_get_size_in_memory(ImBuf *ibuf)
+{
+       int a;
+       intptr_t size= 0, channel_size= 0;
+
+       size+= sizeof(ImBuf);
+
+       if(ibuf->rect)
+               channel_size+= sizeof(char);
+
+       if(ibuf->rect_float)
+               channel_size+= sizeof(float);
+
+       size+= channel_size*ibuf->x*ibuf->y*ibuf->channels;
+
+       if(ibuf->miptot) {
+               for(a= 0; a<ibuf->miptot; a++) {
+                       if(ibuf->mipmap[a])
+                               size+= IMB_get_size_in_memory(ibuf->mipmap[a]);
+               }
+       }
+
+       if(ibuf->tiles) {
+               size+= sizeof(unsigned int)*ibuf->ytiles*ibuf->xtiles;
+       }
+
+       return size;
+}
+
+static intptr_t get_item_size (void *p)
+{
+       intptr_t size= sizeof(MovieCacheItem);
+       MovieCacheItem *item= (MovieCacheItem *) p;
+
+       if(item->ibuf)
+               size+= IMB_get_size_in_memory(item->ibuf);
+
+       return size;
+}
+
+void IMB_moviecache_init(void)
+{
+       limitor= new_MEM_CacheLimiter(IMB_moviecache_destructor, get_item_size);
+}
+
+void IMB_moviecache_destruct(void)
+{
+       if(limitor)
+               delete_MEM_CacheLimiter(limitor);
+}
+
+struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp,
+               MovieCacheGetKeyDataFP getdatafp)
+{
+       MovieCache *cache;
+
+       cache= MEM_callocN(sizeof(MovieCache), "MovieCache");
+       cache->keys_pool= BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, 0);
+       cache->items_pool= BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, 0);
+       cache->userkeys_pool= BLI_mempool_create(keysize, 64, 64, 0);
+       cache->hash= BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
+
+       cache->keysize= keysize;
+       cache->hashfp= hashfp;
+       cache->cmpfp= cmpfp;
+       cache->getdatafp= getdatafp;
+       cache->proxy= -1;
+
+       return cache;
+}
+
+void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf)
+{
+       MovieCacheKey *key;
+       MovieCacheItem *item;
+
+       if(!limitor)
+               IMB_moviecache_init();
+
+       IMB_refImBuf(ibuf);
+
+       key= BLI_mempool_alloc(cache->keys_pool);
+       key->cache_owner= cache;
+       key->userkey= BLI_mempool_alloc(cache->userkeys_pool);;
+       memcpy(key->userkey, userkey, cache->keysize);
+
+       item= BLI_mempool_alloc(cache->items_pool);
+       item->ibuf= ibuf;
+       item->cache_owner= cache;
+       item->last_access= cache->curtime++;
+       item->c_handle= NULL;
+
+       BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
+       BLI_ghash_insert(cache->hash, key, item);
+
+       item->c_handle= MEM_CacheLimiter_insert(limitor, item);
+
+       MEM_CacheLimiter_ref(item->c_handle);
+       MEM_CacheLimiter_enforce_limits(limitor);
+       MEM_CacheLimiter_unref(item->c_handle);
+
+       /* cache limiter can't remove unused keys which points to destoryed values */
+       check_unused_keys(cache);
+
+       if(cache->points) {
+               MEM_freeN(cache->points);
+               cache->points= NULL;
+       }
+}
+
+ImBuf* IMB_moviecache_get(MovieCache *cache, void *userkey)
+{
+       MovieCacheKey key;
+       MovieCacheItem *item;
+
+       key.cache_owner= cache;
+       key.userkey= userkey;
+       item= (MovieCacheItem*)BLI_ghash_lookup(cache->hash, &key);
+
+       if(item) {
+               item->last_access= cache->curtime++;
+
+               if(item->ibuf) {
+                       MEM_CacheLimiter_touch(item->c_handle);
+                       IMB_refImBuf(item->ibuf);
+
+                       return item->ibuf;
+               }
+       }
+
+       return NULL;
+}
+
+void IMB_moviecache_free(MovieCache *cache)
+{
+       BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree);
+
+       BLI_mempool_destroy(cache->keys_pool);
+       BLI_mempool_destroy(cache->items_pool);
+       BLI_mempool_destroy(cache->userkeys_pool);
+
+       if(cache->points)
+               MEM_freeN(cache->points);
+
+       MEM_freeN(cache);
+}
+
+/* get segments of cached frames. useful for debugging cache policies */
+void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
+{
+       *totseg_r= 0;
+       *points_r= NULL;
+
+       if(!cache->getdatafp)
+               return;
+
+       if(cache->proxy!=proxy || cache->render_flags!=render_flags) {
+               if(cache->points)
+                       MEM_freeN(cache->points);
+
+               cache->points= NULL;
+       }
+
+       if(cache->points) {
+               *totseg_r= cache->totseg;
+               *points_r= cache->points;
+       } else {
+               int totframe= BLI_ghash_size(cache->hash);
+               int *frames= MEM_callocN(totframe*sizeof(int), "movieclip cache frames");
+               int a, totseg= 0;
+               GHashIterator *iter;
+
+               iter= BLI_ghashIterator_new(cache->hash);
+               a= 0;
+               while(!BLI_ghashIterator_isDone(iter)) {
+                       MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
+                       MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
+                       int framenr, curproxy, curflags;
+
+                       if(item->ibuf) {
+                               cache->getdatafp(key->userkey, &framenr, &curproxy, &curflags);
+
+                               if(curproxy==proxy && curflags==render_flags)
+                                       frames[a++]= framenr;
+                       }
+
+                       BLI_ghashIterator_step(iter);
+               }
+
+               BLI_ghashIterator_free(iter);
+
+               qsort(frames, totframe, sizeof(int), compare_int);
+
+               /* count */
+               for(a= 0; a<totframe; a++) {
+                       if(a && frames[a]-frames[a-1]!=1)
+                               totseg++;
+
+                       if(a==totframe-1)
+                               totseg++;
+               }
+
+               if(totseg) {
+                       int b, *points;
+
+                       points= MEM_callocN(2*sizeof(int)*totseg, "movieclip cache segments");
+
+                       /* fill */
+                       for(a= 0, b= 0; a<totframe; a++) {
+                               if(a==0)
+                                       points[b++]= frames[a];
+
+                               if(a && frames[a]-frames[a-1]!=1) {
+                                       points[b++]= frames[a-1];
+                                       points[b++]= frames[a];
+                               }
+
+                               if(a==totframe-1)
+                                       points[b++]= frames[a];
+                       }
+
+                       *totseg_r= totseg;
+                       *points_r= points;
+
+                       cache->totseg= totseg;
+                       cache->points= points;
+                       cache->proxy= proxy;
+                       cache->render_flags= render_flags;
+               }
+
+               MEM_freeN(frames);
+       }
+}
index 48ad8a0c017e1a3eb4e65a61c1f8b814c347add2..6f2933d154b1d8c8e8136b79f7dfd33600381417 100644 (file)
@@ -116,7 +116,13 @@ typedef struct Library {
        ID *idblock;
        struct FileData *filedata;
        char name[240];                 /* path name used for reading, can be relative and edited in the outliner */
-       char filepath[240];             /* temp. absolute filepath, only used while reading */
+       char filepath[240];             /* absolute filepath, this is only for convenience,
+                                                        * 'name' is the real path used on file read but in
+                                                        * some cases its useful to access the absolute one,
+                                                        * This is set on file read.
+                                                        * Use BKE_library_filepath_set() rather than
+                                                        * setting 'name' directly and it will be kepk in
+                                                        * sync - campbell */
        int tot, pad;                   /* tot, idblock and filedata are only fo read and write */
        struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
 } Library;
index 71b34d31e96c6b6c9711ec7a10e0c5e8695a9143..ba7d2881ad87c80714faa9f35b769201e6152944 100644 (file)
@@ -326,6 +326,12 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig
        }
 }
 
+void rna_Library_filepath_set(PointerRNA *ptr, const char *value)
+{
+       Library *lib= (Library*)ptr->data;
+       BKE_library_filepath_set(lib, value);
+}
+
 #else
 
 static void rna_def_ID_properties(BlenderRNA *brna)
@@ -531,7 +537,7 @@ static void rna_def_library(BlenderRNA *brna)
        prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_string_sdna(prop, NULL, "name");
        RNA_def_property_ui_text(prop, "File Path", "Path to the library .blend file");
-       /* TODO - lib->filename isnt updated, however the outliner also skips this, probably only needed on read. */
+       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Library_filepath_set");
        
        prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "Library");
index 08a71e0cd4fe05fb2c356e350195ff02d165f4c5..c651dca4b318b7e91461c8a5521c8c1833b35b04 100644 (file)
@@ -621,7 +621,7 @@ static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, BezTri
 
 static void rna_fcurve_range(FCurve *fcu, float range[2])
 {
-       calc_fcurve_range(fcu, range, range+1, FALSE);
+       calc_fcurve_range(fcu, range, range+1, FALSE, FALSE);
 }
 
 #else
index 369272e0be6ba0499921e5546b0f86c4f4056667..5968a6e64f82cb9aa679af8de21d1b878ca66ecc 100644 (file)
@@ -3345,9 +3345,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                mul_m4_v3(mat, ver->co);
                                mul_transposed_m3_v3(imat, ver->n);
                                normalize_v3(ver->n);
-
-                               if(!negative_scale)
-                                       negate_v3(ver->n);
+                               negate_v3(ver->n);
                        }
   
                        if(orco) {
@@ -3405,10 +3403,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                                
                                                if( mface->mat_nr==a1 ) {
                                                        float len;
-                                                               
-                                                       v1= mface->v1;
+                                                       int reverse_verts = negative_scale!=0 && do_autosmooth==0;
+                                                       int rev_tab[] = {reverse_verts==0 ? 0 : 2, 1, reverse_verts==0 ? 2 : 0, 3};
+                                                       v1= reverse_verts==0 ? mface->v1 : mface->v3;
                                                        v2= mface->v2;
-                                                       v3= mface->v3;
+                                                       v3= reverse_verts==0 ? mface->v3 : mface->v1;
                                                        v4= mface->v4;
                                                        flag= mface->flag & ME_SMOOTH;
 
@@ -3445,36 +3444,40 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                                                                CustomDataLayer *layer;
                                                                MTFace *mtface, *mtf;
                                                                MCol *mcol, *mc;
-                                                               int index, mtfn= 0, mcn= 0, mtng=0;
+                                                               int index, mtfn= 0, mcn= 0, mtng=0, vindex;
                                                                char *name;
+                                                               int nr_verts = v4!=0 ? 4 : 3;
 
                                                                for(index=0; index<dm->faceData.totlayer; index++) {
                                                                        layer= &dm->faceData.layers[index];
                                                                        name= layer->name;
                                                                        
                                                                        if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
+                                                                               int t;
                                                                                mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
                                                                                mtface= (MTFace*)layer->data;
-                                                                               *mtf= mtface[a];
+                                                                               *mtf= mtface[a];        // copy face info
+                                                                               for(vindex=0; vindex<nr_verts; vindex++)
+                                                                                       for(t=0; t<2; t++)
+                                                                                               mtf->uv[vindex][t]=mtface[a].uv[rev_tab[vindex]][t];
                                                                        }
                                                                        else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
                                                                                mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
                                                                                mcol= (MCol*)layer->data;
-                                                                               memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
+                                                                               for(vindex=0; vindex<nr_verts; vindex++)
+                                                                                       mc[vindex]=mcol[a*4+rev_tab[vindex]];
                                                                        }
                                                                        else if(layer->type == CD_TANGENT && mtng < 1)
                                                                        {
                                                                                if(need_nmap_tangent!=0)
                                                                                {
                                                                                        const float * tangent = (const float *) layer->data;
-                                                                                       int t;
-                                                                                       int nr_verts = v4!=0 ? 4 : 3;
                                                                                        float * ftang = RE_vlakren_get_nmap_tangent(obr, vlr, 1);
-                                                                                       for(t=0; t<nr_verts; t++)
+                                                                                       for(vindex=0; vindex<nr_verts; vindex++)
                                                                                        {
-                                                                                               QUATCOPY(ftang+t*4, tangent+a*16+t*4);
-                                                                                               mul_mat3_m4_v3(mat, ftang+t*4);
-                                                                                               normalize_v3(ftang+t*4);
+                                                                                               QUATCOPY(ftang+vindex*4, tangent+a*16+rev_tab[vindex]*4);
+                                                                                               mul_mat3_m4_v3(mat, ftang+vindex*4);
+                                                                                               normalize_v3(ftang+vindex*4);
                                                                                        }
                                                                                }
                                                                        }
index 505bbf9dee4734e53789448a8128dd0df37faa8f..6f2ca28c135b1a47062193dcbaf676e7911ccc4c 100644 (file)
@@ -158,6 +158,8 @@ void BL_ActionActuator::SetLocalTime(float curtime)
 
                        m_starttime = curtime;
 
+                       m_flag ^= ACT_FLAG_REVERSE;
+
                        break;
                }
        }
@@ -206,9 +208,8 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
                
                        if (m_flag & ACT_FLAG_REVERSE)
                        {
-                               m_localtime = start;
-                               start = end;
-                               end = m_localtime;
+                               start = m_endframe;
+                               end = m_startframe;
                        }
 
                        break;
@@ -236,6 +237,12 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
                RemoveAllEvents();
        }
 
+       if (bUseContinue && (m_flag & ACT_FLAG_ACTIVE))
+       {
+               m_localtime = obj->GetActionFrame(m_layer);
+               ResetStartTime(curtime);
+       }
+
        if (m_flag & ACT_FLAG_ATTEMPT_PLAY)
                SetLocalTime(curtime);
 
@@ -257,6 +264,9 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
        {
                m_flag &= ~ACT_FLAG_ACTIVE;
                m_flag &= ~ACT_FLAG_ATTEMPT_PLAY;
+
+               if (m_playtype == ACT_ACTION_PINGPONG)
+                       m_flag ^= ACT_FLAG_REVERSE;
                return false;
        }
        
@@ -266,7 +276,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
 
        if (bPositiveEvent || (m_flag & ACT_FLAG_ATTEMPT_PLAY && !(m_flag & ACT_FLAG_ACTIVE)))
        {
-               if (bPositiveEvent)
+               if (bPositiveEvent && m_playtype == ACT_ACTION_PLAY)
                {
                        if (obj->IsActionDone(m_layer))
                                m_localtime = start;
@@ -279,7 +289,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
                        if (bUseContinue)
                                obj->SetActionFrame(m_layer, m_localtime);
 
-                       if (m_playtype == ACT_ACTION_PLAY)
+                       if (m_playtype == ACT_ACTION_PLAY || m_playtype == ACT_ACTION_PINGPONG)
                                m_flag |= ACT_FLAG_PLAY_END;
                        else
                                m_flag &= ~ACT_FLAG_PLAY_END;
@@ -307,9 +317,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
                                // We're done
                                m_flag &= ~ACT_FLAG_ACTIVE;
                                return false;
-                       case ACT_ACTION_PINGPONG:
-                               m_flag ^= ACT_FLAG_REVERSE;
-                               // Now fallthrough to LOOP_END code
                        case ACT_ACTION_LOOP_END:
                                // Convert into a play and let it finish
                                obj->SetPlayMode(m_layer, BL_Action::ACT_MODE_PLAY);
@@ -327,12 +334,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
                                break;
                }
        }
-       
-       if (bUseContinue && (m_flag & ACT_FLAG_ACTIVE))
-       {
-               m_localtime = obj->GetActionFrame(m_layer);
-               ResetStartTime(curtime);
-       }
 
        return true;
 }
index 2da3fdfd225f26e0e430466a51c1d3c0ea7cc5ce..931e5412338dce12c8ecd2f7c84e7b3ce46e8549 100644 (file)
@@ -279,7 +279,7 @@ void BL_Action::SetLocalTime(float curtime)
 
 void BL_Action::ResetStartTime(float curtime)
 {
-       float dt = m_localtime - m_startframe;
+       float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime;
 
        m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
        SetLocalTime(curtime);