2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2010-07-23 16:57:11 +00:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* Peter Schlaile <peter [at] schlaile [dot] de> 2010
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup bke
|
2011-02-27 20:40:57 +00:00
|
|
|
*/
|
|
|
|
|
2010-07-23 16:57:11 +00:00
|
|
|
#include <stddef.h>
|
2011-10-23 17:52:20 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
#include "BLI_sys_types.h" /* for intptr_t */
|
2010-07-23 16:57:11 +00:00
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "DNA_sequence_types.h"
|
2015-04-06 10:40:12 -03:00
|
|
|
#include "DNA_scene_types.h"
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2011-10-23 17:52:20 +00:00
|
|
|
#include "IMB_moviecache.h"
|
2012-08-19 15:41:56 +00:00
|
|
|
#include "IMB_imbuf.h"
|
2012-08-08 11:52:14 +00:00
|
|
|
#include "IMB_imbuf_types.h"
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
#include "BLI_listbase.h"
|
|
|
|
|
2013-03-08 04:00:06 +00:00
|
|
|
#include "BKE_sequencer.h"
|
2015-04-06 10:40:12 -03:00
|
|
|
#include "BKE_scene.h"
|
2013-03-08 04:00:06 +00:00
|
|
|
|
2012-06-10 15:20:10 +00:00
|
|
|
typedef struct SeqCacheKey {
|
2019-04-17 06:17:24 +02:00
|
|
|
struct Sequence *seq;
|
|
|
|
SeqRenderData context;
|
|
|
|
float cfra;
|
|
|
|
eSeqStripElemIBuf type;
|
2012-06-10 15:20:10 +00:00
|
|
|
} SeqCacheKey;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
typedef struct SeqPreprocessCacheElem {
|
2019-04-17 06:17:24 +02:00
|
|
|
struct SeqPreprocessCacheElem *next, *prev;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
struct Sequence *seq;
|
|
|
|
SeqRenderData context;
|
|
|
|
eSeqStripElemIBuf type;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ImBuf *ibuf;
|
2012-08-19 15:41:56 +00:00
|
|
|
} SeqPreprocessCacheElem;
|
|
|
|
|
|
|
|
typedef struct SeqPreprocessCache {
|
2019-04-17 06:17:24 +02:00
|
|
|
int cfra;
|
|
|
|
ListBase elems;
|
2012-08-19 15:41:56 +00:00
|
|
|
} SeqPreprocessCache;
|
|
|
|
|
2011-10-23 17:52:20 +00:00
|
|
|
static struct MovieCache *moviecache = NULL;
|
2012-08-19 15:41:56 +00:00
|
|
|
static struct SeqPreprocessCache *preprocess_cache = NULL;
|
|
|
|
|
|
|
|
static void preprocessed_cache_destruct(void);
|
2011-10-23 17:52:20 +00:00
|
|
|
|
2014-09-25 06:15:52 +10:00
|
|
|
static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
|
2012-08-08 11:15:32 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return ((a->preview_render_size != b->preview_render_size) || (a->rectx != b->rectx) ||
|
|
|
|
(a->recty != b->recty) || (a->bmain != b->bmain) || (a->scene != b->scene) ||
|
|
|
|
(a->motion_blur_shutter != b->motion_blur_shutter) ||
|
|
|
|
(a->motion_blur_samples != b->motion_blur_samples) ||
|
|
|
|
(a->scene->r.views_format != b->scene->r.views_format) || (a->view_id != b->view_id));
|
2012-08-08 11:15:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int seq_hash_render_data(const SeqRenderData *a)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
unsigned int rval = a->rectx + a->recty;
|
2012-08-08 11:15:32 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
rval ^= a->preview_render_size;
|
|
|
|
rval ^= ((intptr_t)a->bmain) << 6;
|
|
|
|
rval ^= ((intptr_t)a->scene) << 6;
|
|
|
|
rval ^= (int)(a->motion_blur_shutter * 100.0f) << 10;
|
|
|
|
rval ^= a->motion_blur_samples << 16;
|
|
|
|
rval ^= ((a->scene->r.views_format * 2) + a->view_id) << 24;
|
2012-08-08 11:15:32 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return rval;
|
2012-08-08 11:15:32 +00:00
|
|
|
}
|
|
|
|
|
2011-10-23 17:52:20 +00:00
|
|
|
static unsigned int seqcache_hashhash(const void *key_)
|
2010-07-23 16:57:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const SeqCacheKey *key = key_;
|
|
|
|
unsigned int rval = seq_hash_render_data(&key->context);
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
rval ^= *(const unsigned int *)&key->cfra;
|
|
|
|
rval += key->type;
|
|
|
|
rval ^= ((intptr_t)key->seq) << 6;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return rval;
|
2010-07-23 16:57:11 +00:00
|
|
|
}
|
|
|
|
|
2014-09-25 06:15:52 +10:00
|
|
|
static bool seqcache_hashcmp(const void *a_, const void *b_)
|
2010-07-23 16:57:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const SeqCacheKey *a = a_;
|
|
|
|
const SeqCacheKey *b = b_;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return ((a->seq != b->seq) || (a->cfra != b->cfra) || (a->type != b->type) ||
|
|
|
|
seq_cmp_render_data(&a->context, &b->context));
|
2010-07-23 16:57:11 +00:00
|
|
|
}
|
|
|
|
|
2012-08-08 11:56:58 +00:00
|
|
|
void BKE_sequencer_cache_destruct(void)
|
2010-07-23 16:57:11 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (moviecache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IMB_moviecache_free(moviecache);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
preprocessed_cache_destruct();
|
2010-07-23 16:57:11 +00:00
|
|
|
}
|
|
|
|
|
2012-08-08 11:56:58 +00:00
|
|
|
void BKE_sequencer_cache_cleanup(void)
|
2010-07-23 16:57:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (moviecache) {
|
|
|
|
IMB_moviecache_free(moviecache);
|
|
|
|
moviecache = IMB_moviecache_create(
|
|
|
|
"seqcache", sizeof(SeqCacheKey), seqcache_hashhash, seqcache_hashcmp);
|
|
|
|
}
|
2012-08-20 15:14:23 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_sequencer_preprocessed_cache_cleanup();
|
2010-07-23 16:57:11 +00:00
|
|
|
}
|
|
|
|
|
2013-12-13 16:22:08 +06:00
|
|
|
static bool seqcache_key_check_seq(ImBuf *UNUSED(ibuf), void *userkey, void *userdata)
|
2012-08-08 16:46:40 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SeqCacheKey *key = (SeqCacheKey *)userkey;
|
|
|
|
Sequence *seq = (Sequence *)userdata;
|
2012-08-08 16:46:40 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return key->seq == seq;
|
2012-08-08 16:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BKE_sequencer_cache_cleanup_sequence(Sequence *seq)
|
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (moviecache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
IMB_moviecache_cleanup(moviecache, seqcache_key_check_seq, seq);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-08 16:46:40 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context,
|
|
|
|
Sequence *seq,
|
|
|
|
float cfra,
|
|
|
|
eSeqStripElemIBuf type)
|
2010-07-23 16:57:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
if (moviecache && seq) {
|
|
|
|
SeqCacheKey key;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key.seq = seq;
|
|
|
|
key.context = *context;
|
|
|
|
key.cfra = cfra - seq->start;
|
|
|
|
key.type = type;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return IMB_moviecache_get(moviecache, &key);
|
|
|
|
}
|
2011-10-23 17:52:20 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2010-07-23 16:57:11 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
void BKE_sequencer_cache_put(
|
|
|
|
const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type, ImBuf *i)
|
2010-07-23 16:57:11 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SeqCacheKey key;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (i == NULL || context->skip_cache) {
|
|
|
|
return;
|
|
|
|
}
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!moviecache) {
|
|
|
|
moviecache = IMB_moviecache_create(
|
|
|
|
"seqcache", sizeof(SeqCacheKey), seqcache_hashhash, seqcache_hashcmp);
|
|
|
|
}
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
key.seq = seq;
|
|
|
|
key.context = *context;
|
|
|
|
key.cfra = cfra - seq->start;
|
|
|
|
key.type = type;
|
2010-07-23 16:57:11 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
IMB_moviecache_put(moviecache, &key, i);
|
2010-07-23 16:57:11 +00:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2012-08-21 10:42:21 +00:00
|
|
|
void BKE_sequencer_preprocessed_cache_cleanup(void)
|
2012-08-19 15:41:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SeqPreprocessCacheElem *elem;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!preprocess_cache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
|
|
|
|
IMB_freeImBuf(elem->ibuf);
|
|
|
|
}
|
|
|
|
BLI_freelistN(&preprocess_cache->elems);
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_listbase_clear(&preprocess_cache->elems);
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void preprocessed_cache_destruct(void)
|
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!preprocess_cache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_sequencer_preprocessed_cache_cleanup();
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(preprocess_cache);
|
|
|
|
preprocess_cache = NULL;
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context,
|
|
|
|
Sequence *seq,
|
|
|
|
float cfra,
|
|
|
|
eSeqStripElemIBuf type)
|
2012-08-19 15:41:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SeqPreprocessCacheElem *elem;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!preprocess_cache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (preprocess_cache->cfra != cfra) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (elem->seq != seq) {
|
2019-04-17 06:17:24 +02:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (elem->type != type) {
|
2019-04-17 06:17:24 +02:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (seq_cmp_render_data(&elem->context, context) != 0) {
|
2019-04-17 06:17:24 +02:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
IMB_refImBuf(elem->ibuf);
|
|
|
|
return elem->ibuf;
|
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return NULL;
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
void BKE_sequencer_preprocessed_cache_put(
|
|
|
|
const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type, ImBuf *ibuf)
|
2012-08-19 15:41:56 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SeqPreprocessCacheElem *elem;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!preprocess_cache) {
|
|
|
|
preprocess_cache = MEM_callocN(sizeof(SeqPreprocessCache), "sequencer preprocessed cache");
|
|
|
|
}
|
|
|
|
else {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (preprocess_cache->cfra != cfra) {
|
2019-04-17 06:17:24 +02:00
|
|
|
BKE_sequencer_preprocessed_cache_cleanup();
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
elem = MEM_callocN(sizeof(SeqPreprocessCacheElem), "sequencer preprocessed cache element");
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
elem->seq = seq;
|
|
|
|
elem->type = type;
|
|
|
|
elem->context = *context;
|
|
|
|
elem->ibuf = ibuf;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
preprocess_cache->cfra = cfra;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
IMB_refImBuf(ibuf);
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_addtail(&preprocess_cache->elems, elem);
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BKE_sequencer_preprocessed_cache_cleanup_sequence(Sequence *seq)
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
SeqPreprocessCacheElem *elem, *elem_next;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!preprocess_cache) {
|
2019-04-17 06:17:24 +02:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
for (elem = preprocess_cache->elems.first; elem; elem = elem_next) {
|
|
|
|
elem_next = elem->next;
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
if (elem->seq == seq) {
|
|
|
|
IMB_freeImBuf(elem->ibuf);
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
BLI_freelinkN(&preprocess_cache->elems, elem);
|
|
|
|
}
|
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
}
|