Esempio n. 1
0
void IMB_freeImBuf(ImBuf *ibuf)
{
    if (ibuf) {
        bool needs_free = false;

        BLI_spin_lock(&refcounter_spin);
        if (ibuf->refcounter > 0) {
            ibuf->refcounter--;
        }
        else {
            needs_free = true;
        }
        BLI_spin_unlock(&refcounter_spin);

        if (needs_free) {
            imb_freerectImBuf(ibuf);
            imb_freerectfloatImBuf(ibuf);
            imb_freetilesImBuf(ibuf);
            IMB_freezbufImBuf(ibuf);
            IMB_freezbuffloatImBuf(ibuf);
            freeencodedbufferImBuf(ibuf);
            IMB_metadata_free(ibuf);
            colormanage_cache_free(ibuf);

            if (ibuf->dds_data.data != NULL) {
                free(ibuf->dds_data.data); /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
            }
            MEM_freeN(ibuf);
        }
    }
}
Esempio n. 2
0
ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
{
	ImBuf *rval;

	if (ibuf) {
		bool is_single;
		BLI_spin_lock(&refcounter_spin);
		is_single = (ibuf->refcounter == 0);
		BLI_spin_unlock(&refcounter_spin);
		if (is_single) {
			return ibuf;
		}
	}
	else {
		return NULL;
	}

	rval = IMB_dupImBuf(ibuf);

	IMB_metadata_copy(rval, ibuf);

	IMB_freeImBuf(ibuf);

	return rval;
}
Esempio n. 3
0
static void *do_multires_bake_thread(void *data_v)
{
	MultiresBakeThread *handle = (MultiresBakeThread *) data_v;
	MResolvePixelData *data = &handle->data;
	MBakeRast *bake_rast = &handle->bake_rast;
	MultiresBakeRender *bkr = handle->bkr;
	int f;

	while ((f = multires_bake_queue_next_face(handle->queue)) >= 0) {
		MTFace *mtfate = &data->mtface[f];
		int verts[3][2], nr_tris, t;

		if (multiresbake_test_break(bkr))
			break;

		if (mtfate->tpage != handle->image)
			continue;

		data->face_index = f;

		/* might support other forms of diagonal splits later on such as
		 * split by shortest diagonal.*/
		verts[0][0] = 0;
		verts[1][0] = 1;
		verts[2][0] = 2;

		verts[0][1] = 0;
		verts[1][1] = 2;
		verts[2][1] = 3;

		nr_tris = data->mface[f].v4 != 0 ? 2 : 1;
		for (t = 0; t < nr_tris; t++) {
			data->i0 = verts[0][t];
			data->i1 = verts[1][t];
			data->i2 = verts[2][t];

			bake_rasterize(bake_rast, mtfate->uv[data->i0], mtfate->uv[data->i1], mtfate->uv[data->i2]);

			/* tag image buffer for refresh */
			if (data->ibuf->rect_float)
				data->ibuf->userflags |= IB_RECT_INVALID;

			data->ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
		}

		/* update progress */
		BLI_spin_lock(&handle->queue->spin);
		bkr->baked_faces++;

		if (bkr->do_update)
			*bkr->do_update = TRUE;

		if (bkr->progress)
			*bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / handle->queue->tot_face) / bkr->tot_obj;
		BLI_spin_unlock(&handle->queue->spin);
	}

	return NULL;
}
Esempio n. 4
0
/* get memory buffer for first uncached frame within prefetch frame range */
static unsigned char *prefetch_thread_next_frame(
        PrefetchQueue *queue, MovieClip *clip,
        size_t *r_size, int *r_current_frame)
{
	unsigned char *mem = NULL;

	BLI_spin_lock(&queue->spin);
	if (!*queue->stop && !check_prefetch_break() &&
	    IN_RANGE_INCL(queue->current_frame, queue->start_frame, queue->end_frame))
	{
		int current_frame;

		if (queue->forward) {
			current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame,
			                                             queue->render_size, queue->render_flag, 1);
			/* switch direction if read frames from current up to scene end frames */
			if (current_frame > queue->end_frame) {
				queue->current_frame = queue->initial_frame;
				queue->forward = false;
			}
		}

		if (!queue->forward) {
			current_frame = prefetch_find_uncached_frame(clip, queue->current_frame - 1, queue->start_frame,
			                                             queue->render_size, queue->render_flag, -1);
		}

		if (IN_RANGE_INCL(current_frame, queue->start_frame, queue->end_frame)) {
			int frames_processed;

			mem = prefetch_read_file_to_memory(clip, current_frame, queue->render_size,
			                                   queue->render_flag, r_size);

			*r_current_frame = current_frame;

			queue->current_frame = current_frame;

			if (queue->forward) {
				frames_processed = queue->current_frame - queue->initial_frame;
			}
			else {
				frames_processed = (queue->end_frame - queue->initial_frame) +
				                   (queue->initial_frame - queue->current_frame);
			}

			*queue->do_update = 1;
			*queue->progress = (float)frames_processed / (queue->end_frame - queue->start_frame);
		}
	}
	BLI_spin_unlock(&queue->spin);

	return mem;
}
Esempio n. 5
0
/* only this runs inside thread */
static void preview_startjob(void *data, short *stop, short *do_update, float *progress)
{
	PreviewJob *pj = data;
	PreviewJobAudio *previewjb;

	BLI_mutex_lock(pj->mutex);
	previewjb = pj->previews.first;
	BLI_mutex_unlock(pj->mutex);

	while (previewjb) {
		PreviewJobAudio *preview_next;
		bSound *sound = previewjb->sound;

		BKE_sound_read_waveform(sound, stop);

		if (*stop || G.is_break) {
			BLI_mutex_lock(pj->mutex);
			previewjb = previewjb->next;
			BLI_mutex_unlock(pj->mutex);
			while (previewjb) {
				sound = previewjb->sound;

				/* make sure we cleanup the loading flag! */
				BLI_spin_lock(sound->spinlock);
				sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
				BLI_spin_unlock(sound->spinlock);

				BLI_mutex_lock(pj->mutex);
				previewjb = previewjb->next;
				BLI_mutex_unlock(pj->mutex);
			}

			BLI_mutex_lock(pj->mutex);
			BLI_freelistN(&pj->previews);
			pj->total = 0;
			pj->processed = 0;
			BLI_mutex_unlock(pj->mutex);
			break;
		}

		BLI_mutex_lock(pj->mutex);
		preview_next = previewjb->next;
		BLI_freelinkN(&pj->previews, previewjb);
		previewjb = preview_next;
		pj->processed++;
		*progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0f;
		*do_update = true;
		BLI_mutex_unlock(pj->mutex);
	}
}
Esempio n. 6
0
static unsigned char *proxy_thread_next_frame(ProxyQueue *queue, MovieClip *clip, size_t *size_r, int *cfra_r)
{
	unsigned char *mem = NULL;

	BLI_spin_lock(&queue->spin);
	if (!*queue->stop && queue->cfra <= queue->efra) {
		MovieClipUser user = {0};
		char name[FILE_MAX];
		size_t size;
		int file;

		user.framenr = queue->cfra;

		BKE_movieclip_filename_for_frame(clip, &user, name);

		file = open(name, O_BINARY | O_RDONLY, 0);
		if (file < 0) {
			BLI_spin_unlock(&queue->spin);
			return NULL;
		}

		size = BLI_file_descriptor_size(file);
		if (size < 1) {
			close(file);
			BLI_spin_unlock(&queue->spin);
			return NULL;
		}

		mem = MEM_mallocN(size, "movieclip proxy memory file");

		if (read(file, mem, size) != size) {
			close(file);
			BLI_spin_unlock(&queue->spin);
			MEM_freeN(mem);
			return NULL;
		}

		*size_r = size;
		*cfra_r = queue->cfra;

		queue->cfra++;
		close(file);

		*queue->do_update = 1;
		*queue->progress = (float)(queue->cfra - queue->sfra) / (queue->efra - queue->sfra);
	}
	BLI_spin_unlock(&queue->spin);

	return mem;
}
Esempio n. 7
0
void BKE_cachefile_ensure_handle(const Main *bmain, CacheFile *cache_file)
{
	BLI_spin_lock(&spin);
	if (cache_file->handle_mutex == NULL) {
		cache_file->handle_mutex = BLI_mutex_alloc();
	}
	BLI_spin_unlock(&spin);

	BLI_mutex_lock(cache_file->handle_mutex);

	if (cache_file->handle == NULL) {
		BKE_cachefile_reload(bmain, cache_file);
	}

	BLI_mutex_unlock(cache_file->handle_mutex);
}
Esempio n. 8
0
static int multires_bake_queue_next_face(MultiresBakeQueue *queue)
{
	int face = -1;

	/* TODO: it could worth making it so thread will handle neighbor faces
	 *       for better memory cache utilization
	 */

	BLI_spin_lock(&queue->spin);
	if (queue->cur_face < queue->tot_face) {
		face = queue->cur_face;
		queue->cur_face++;
	}
	BLI_spin_unlock(&queue->spin);

	return face;
}
Esempio n. 9
0
void IMB_refImBuf(ImBuf *ibuf)
{
    BLI_spin_lock(&refcounter_spin);
    ibuf->refcounter++;
    BLI_spin_unlock(&refcounter_spin);
}
Esempio n. 10
0
GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
{
	FT_GlyphSlot slot;
	GlyphBLF *g;
	FT_Error err;
	FT_Bitmap bitmap, tempbitmap;
	const bool is_sharp = (U.text_render & USER_TEXT_DISABLE_AA) != 0;
	int flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
	FT_BBox bbox;
	unsigned int key;

	g = blf_glyph_search(font->glyph_cache, c);
	if (g)
		return g;

	/* glyphs are dynamically created as needed by font rendering. this means that
	 * to make font rendering thread safe we have to do locking here. note that this
	 * must be a lock for the whole library and not just per font, because the font
	 * renderer uses a shared buffer internally */
	BLI_spin_lock(font->ft_lib_mutex);

	/* search again after locking */
	g = blf_glyph_search(font->glyph_cache, c);
	if (g) {
		BLI_spin_unlock(font->ft_lib_mutex);
		return g;
	}

	if (font->flags & BLF_HINTING)
		flags &= ~FT_LOAD_NO_HINTING;
	
	if (is_sharp)
		err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
	else
		err = FT_Load_Glyph(font->face, (FT_UInt)index, flags);  

	if (err) {
		BLI_spin_unlock(font->ft_lib_mutex);
		return NULL;
	}

	/* get the glyph. */
	slot = font->face->glyph;

	if (is_sharp) {
		err = FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);

		/* Convert result from 1 bit per pixel to 8 bit per pixel */
		/* Accum errors for later, fine if not interested beyond "ok vs any error" */
		FT_Bitmap_New(&tempbitmap);
		err += FT_Bitmap_Convert(font->ft_lib, &slot->bitmap, &tempbitmap, 1); /* Does Blender use Pitch 1 always? It works so far */
		err += FT_Bitmap_Copy(font->ft_lib, &tempbitmap, &slot->bitmap);
		err += FT_Bitmap_Done(font->ft_lib, &tempbitmap);
	}
	else {
		err = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
	}

	if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) {
		BLI_spin_unlock(font->ft_lib_mutex);
		return NULL;
	}

	g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add");
	g->c = c;
	g->idx = (FT_UInt)index;
	g->xoff = -1;
	g->yoff = -1;
	bitmap = slot->bitmap;
	g->width = (int)bitmap.width;
	g->height = (int)bitmap.rows;

	if (g->width && g->height) {
		if (is_sharp) {
			/* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
			int i;
			for (i = 0; i < (g->width * g->height); i++) {
				bitmap.buffer[i] = bitmap.buffer[i] ? 255 : 0;
			}
		}

		g->bitmap = (unsigned char *)MEM_mallocN((size_t)(g->width * g->height), "glyph bitmap");
		memcpy((void *)g->bitmap, (void *)bitmap.buffer, (size_t)(g->width * g->height));
	}

	g->advance = ((float)slot->advance.x) / 64.0f;
	g->advance_i = (int)g->advance;
	g->pos_x = (float)slot->bitmap_left;
	g->pos_y = (float)slot->bitmap_top;
	g->pitch = slot->bitmap.pitch;

	FT_Outline_Get_CBox(&(slot->outline), &bbox);
	g->box.xmin = ((float)bbox.xMin) / 64.0f;
	g->box.xmax = ((float)bbox.xMax) / 64.0f;
	g->box.ymin = ((float)bbox.yMin) / 64.0f;
	g->box.ymax = ((float)bbox.yMax) / 64.0f;

	key = blf_hash(g->c);
	BLI_addhead(&(font->glyph_cache->bucket[key]), g);

	BLI_spin_unlock(font->ft_lib_mutex);

	return g;
}
Esempio n. 11
0
void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
{
	MovieTrackingTrack *track;
	ListBase tracks = {NULL, NULL}, new_tracks = {NULL, NULL};
	ListBase *old_tracks;
	int a;

	if (map->is_camera) {
		old_tracks = &tracking->tracks;
	}
	else {
		MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, map->object_name);

		if (!object) {
			/* object was deleted by user, create new one */
			object = BKE_tracking_object_add(tracking, map->object_name);
		}

		old_tracks = &object->tracks;
	}

	/* duplicate currently operating tracks to temporary list.
	 * this is needed to keep names in unique state and it's faster to change names
	 * of currently operating tracks (if needed)
	 */
	for (a = 0; a < map->num_tracks; a++) {
		MovieTrackingTrack *old_track;
		bool mapped_to_old = false;

		track = &map->tracks[a];

		/* find original of operating track in list of previously displayed tracks */
		old_track = BLI_ghash_lookup(map->hash, track);
		if (old_track) {
			if (BLI_findindex(old_tracks, old_track) != -1) {
				BLI_remlink(old_tracks, old_track);

				BLI_spin_lock(&map->spin_lock);

				/* Copy flags like selection back to the track map. */
				track->flag = old_track->flag;
				track->pat_flag = old_track->pat_flag;
				track->search_flag = old_track->search_flag;

				/* Copy all the rest settings back from the map to the actual tracks. */
				MEM_freeN(old_track->markers);
				*old_track = *track;
				old_track->markers = MEM_dupallocN(old_track->markers);

				BLI_spin_unlock(&map->spin_lock);

				BLI_addtail(&tracks, old_track);

				mapped_to_old = true;
			}
		}

		if (mapped_to_old == false) {
			MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);

			/* Update old-new track mapping */
			BLI_ghash_reinsert(map->hash, track, new_track, NULL, NULL);

			BLI_addtail(&tracks, new_track);
		}
	}

	/* move all tracks, which aren't operating */
	track = old_tracks->first;
	while (track) {
		MovieTrackingTrack *next = track->next;
		BLI_addtail(&new_tracks, track);
		track = next;
	}

	/* now move all tracks which are currently operating and keep their names unique */
	track = tracks.first;
	while (track) {
		MovieTrackingTrack *next = track->next;

		BLI_remlink(&tracks, track);

		track->next = track->prev = NULL;
		BLI_addtail(&new_tracks, track);

		BLI_uniquename(&new_tracks, track, CTX_DATA_(BLF_I18NCONTEXT_ID_MOVIECLIP, "Track"), '.',
		               offsetof(MovieTrackingTrack, name), sizeof(track->name));

		track = next;
	}

	*old_tracks = new_tracks;
}
Esempio n. 12
0
void imb_mmap_lock(void)
{
	BLI_spin_lock(&mmap_spin);
}
Esempio n. 13
0
static void BLI_lock_malloc_thread(void)
{
	BLI_spin_lock(&_malloc_lock);
}
Esempio n. 14
0
static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
{
	/*
	 * x1 is the starting x value to draw the wave,
	 * x2 the end x value, same for y1 and y2
	 * stepsize is width of a pixel.
	 */
	if ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)) {
		int i, j, pos;
		int length = floor((x2 - x1) / stepsize) + 1;
		float ymid = (y1 + y2) / 2;
		float yscale = (y2 - y1) / 2;
		float samplestep;
		float startsample, endsample;
		float value1, value2;
		bSound *sound = seq->sound;
		
		SoundWaveform *waveform;
		
		if (!sound->spinlock) {
			sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
			BLI_spin_init(sound->spinlock);
		}
		
		BLI_spin_lock(sound->spinlock);
		if (!seq->sound->waveform) {
			if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) {
				/* prevent sounds from reloading */
				seq->sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING;
				BLI_spin_unlock(sound->spinlock);
				sequencer_preview_add_sound(C, seq);
			}
			else {
				BLI_spin_unlock(sound->spinlock);
			}
			return;  /* nothing to draw */
		}
		BLI_spin_unlock(sound->spinlock);
		
		waveform = seq->sound->waveform;

		if (waveform->length == 0) {
			/* BKE_sound_read_waveform() set an empty SoundWaveform data in case it cannot generate a valid one...
			 * See T45726. */
			return;
		}

		startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
		endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
		samplestep = (endsample - startsample) * stepsize / (x2 - x1);

		if (length > floor((waveform->length - startsample) / samplestep))
			length = floor((waveform->length - startsample) / samplestep);

		glColor4f(1.0f, 1.0f, 1.0f, 0.5);
		glEnable(GL_BLEND);
		glBegin(GL_TRIANGLE_STRIP);
		for (i = 0; i < length; i++) {
			float sampleoffset = startsample + i * samplestep;
			pos = sampleoffset;

			value1 = waveform->data[pos * 3];
			value2 = waveform->data[pos * 3 + 1];

			if (samplestep > 1.0f) {
				for (j = pos + 1; (j < waveform->length) && (j < pos + samplestep); j++) {
					if (value1 > waveform->data[j * 3])
						value1 = waveform->data[j * 3];

					if (value2 < waveform->data[j * 3 + 1])
						value2 = waveform->data[j * 3 + 1];
				}
			}
			else {
				/* use simple linear interpolation */
				float f = sampleoffset - pos;
				value1 = (1.0f - f) * value1 + f * waveform->data[pos * 3 + 3];
				value2 = (1.0f - f) * value2 + f * waveform->data[pos * 3 + 4];
			}

			glVertex2f(x1 + i * stepsize, ymid + value1 * yscale);
			glVertex2f(x1 + i * stepsize, ymid + value2 * yscale);
		}
		glEnd();
		glDisable(GL_BLEND);
	}
}
Esempio n. 15
0
void BKE_main_lock(struct Main *bmain)
{
	BLI_spin_lock((SpinLock *) bmain->lock);
}