forked from bartvdbraak/blender
Cycles: svn merge -r41232:41266 ^/trunk/blender
This commit is contained in:
commit
47463742e2
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
/* .............. */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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=1;
|
||||
foundvert= TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundvert) {
|
||||
@ -555,44 +558,51 @@ 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;
|
||||
}
|
||||
|
||||
if (foundvert == FALSE) {
|
||||
min= max= 0.0f;
|
||||
}
|
||||
|
||||
if (do_min_length) {
|
||||
/* minimum length is 1 frame */
|
||||
if (foundvert) {
|
||||
if (min == max) max += 1.0f;
|
||||
if (min == max) {
|
||||
max += 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
*start= min;
|
||||
*end= max;
|
||||
}
|
||||
else {
|
||||
*start= 0.0f;
|
||||
*end= 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------- Status Checks -------------------------- */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
*
|
||||
* Peter Schlaile <peter [at] schlaile [dot] de> 2010
|
||||
*
|
||||
* Contributor(s): Sergey Sharybin
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
@ -26,22 +28,15 @@
|
||||
|
||||
|
||||
#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 struct MovieCache *moviecache = NULL;
|
||||
|
||||
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 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)
|
||||
{
|
||||
|
||||
if(moviecache && seq) {
|
||||
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 (e && e->ibuf) {
|
||||
IMB_refImBuf(e->ibuf);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
MEM_CacheLimiter_ref(e->c_handle);
|
||||
MEM_CacheLimiter_enforce_limits(limitor);
|
||||
MEM_CacheLimiter_unref(e->c_handle);
|
||||
IMB_moviecache_put(moviecache, &key, i);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,6 +428,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
|
||||
iter = IDP_GetGroupIterator(prop);
|
||||
|
||||
while ((curr = IDP_GroupIterNext(iter)) != NULL) {
|
||||
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;
|
||||
|
@ -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]);
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
@ -221,6 +210,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
|
||||
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);
|
||||
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
56
source/blender/imbuf/IMB_moviecache.h
Normal file
56
source/blender/imbuf/IMB_moviecache.h
Normal file
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -37,7 +37,6 @@ void IMB_init(void)
|
||||
|
||||
void IMB_exit(void)
|
||||
{
|
||||
IMB_free_cache_limiter();
|
||||
imb_tile_cache_exit();
|
||||
imb_filetypes_exit();
|
||||
}
|
||||
|
382
source/blender/imbuf/intern/moviecache.c
Normal file
382
source/blender/imbuf/intern/moviecache.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -3345,8 +3345,6 @@ 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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
@ -328,12 +335,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
}
|
||||
}
|
||||
|
||||
if (bUseContinue && (m_flag & ACT_FLAG_ACTIVE))
|
||||
{
|
||||
m_localtime = obj->GetActionFrame(m_layer);
|
||||
ResetStartTime(curtime);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user