[Bf-blender-cvs] [6afde3e] multi_previews_id: Multi-previews: basics (not yet usable from end-user code).

Bastien Montagne noreply at git.blender.org
Sat Oct 22 22:09:13 CEST 2016


Commit: 6afde3ed693e5e0d41b6162558ad7aff237d0885
Author: Bastien Montagne
Date:   Sat Sep 17 10:26:30 2016 +0200
Branches: multi_previews_id
https://developer.blender.org/rB6afde3ed693e5e0d41b6162558ad7aff237d0885

Multi-previews: basics (not yet usable from end-user code).

This commits adds data and basic API needed to handle multi-previews in
a single PreviewImage struct.

Data model is designed to be fully compatible (backward and forward)
with previous one, while keeping a 'flat array' design to store
previews. It also adds an extra integer per frame, that may be used to
store various meta-data.

This commit also updates write/read code, and adds basic BKE API to handle
multiple frames.

TODO: UI code (only very minimal stuff done so far, probably want to add
some template options too...). Access between icon ID and preview frames
is not yet fully designed, but think will rather go with an extra
integer rather that generating an icon ID/icon struct for every frame.

===================================================================

M	source/blender/blenkernel/BKE_icons.h
M	source/blender/blenkernel/intern/icons.c
M	source/blender/blenloader/intern/readblenentry.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/interface/interface_icons.c
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/intern/gpu_texture.c
M	source/blender/makesdna/DNA_ID.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index efef8d4..ff063a5 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -99,6 +99,23 @@ struct PreviewImage *BKE_previewimg_create(void);
 /* create a copy of the preview image */
 struct PreviewImage *BKE_previewimg_copy(struct PreviewImage *prv);
 
+size_t BKE_previewimg_get_rect_size(struct PreviewImage *prv, const int size);
+
+void BKE_previewimg_num_frames_set(struct PreviewImage *prv, const short num_frames);
+void BKE_previewimg_frame_delete(struct PreviewImage *prv, const short frame_idx);
+
+unsigned int *BKE_previewimg_frame_data_get(
+        const struct PreviewImage *prv,
+        const unsigned short frame_idx, const enum eIconSizes size, int *r_meta);
+
+unsigned int *BKE_previewimg_frame_data_search(
+        const struct PreviewImage *prv,
+        const int meta, const enum eIconSizes size, unsigned short *r_frame_idx);
+
+void BKE_previewimg_frame_data_set(
+        const struct PreviewImage *prv,
+        const unsigned short frame_idx, const enum eIconSizes size, const int meta, const unsigned int *data);
+
 void BKE_previewimg_id_copy(struct ID *new_id, struct ID *old_id);
 
 /* retrieve existing or create new preview image */
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 2d5b15c..b35d1eb 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -158,6 +158,14 @@ PreviewImage *BKE_previewimg_create(void)
 	return previewimg_create_ex(0);
 }
 
+static void previewimg_gputexture_free_single(PreviewImage *prv, enum eIconSizes size)
+{
+	if (prv->gputexture[size]) {
+		GPU_texture_free(prv->gputexture[size]);
+		prv->gputexture[size] = NULL;
+	}
+}
+
 void BKE_previewimg_freefunc(void *link)
 {
 	PreviewImage *prv = (PreviewImage *)link;
@@ -168,8 +176,7 @@ void BKE_previewimg_freefunc(void *link)
 			if (prv->rect[i]) {
 				MEM_freeN(prv->rect[i]);
 			}
-			if (prv->gputexture[i])
-				GPU_texture_free(prv->gputexture[i]);
+			previewimg_gputexture_free_single(prv, i);
 		}
 		
 		MEM_freeN(prv);
@@ -184,12 +191,10 @@ void BKE_previewimg_free(PreviewImage **prv)
 	}
 }
 
-void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size)
+void BKE_previewimg_clear_single(PreviewImage *prv, enum eIconSizes size)
 {
 	MEM_SAFE_FREE(prv->rect[size]);
-	if (prv->gputexture[size]) {
-		GPU_texture_free(prv->gputexture[size]);
-	}
+	previewimg_gputexture_free_single(prv, size);
 	prv->h[size] = prv->w[size] = 0;
 	prv->flag[size] |= PRV_CHANGED;
 	prv->flag[size] &= ~PRV_USER_EDITED;
@@ -198,8 +203,8 @@ void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size)
 
 void BKE_previewimg_clear(struct PreviewImage *prv)
 {
-	int i;
-	for (i = 0; i < NUM_ICON_SIZES; ++i) {
+	prv->num_frames = 0;
+	for (int i = 0; i < NUM_ICON_SIZES; ++i) {
 		BKE_previewimg_clear_single(prv, i);
 	}
 }
@@ -221,6 +226,126 @@ PreviewImage *BKE_previewimg_copy(PreviewImage *prv)
 	return prv_img;
 }
 
+#define PREVIEWIMG_OFFSET(_prv, _size, _idx) \
+	((_idx) * (_prv)->w[(_size)] * (_prv)->h[(_size)] + (_idx))
+
+size_t BKE_previewimg_get_rect_size(struct PreviewImage *prv, const int size)
+{
+	if (prv->num_frames != 0) {
+		return PREVIEWIMG_OFFSET(prv, size, prv->num_frames) * sizeof(*prv->rect[size]);
+	}
+	else {
+		return prv->w[size] * prv->h[size] * sizeof(*prv->rect[size]);
+	}
+}
+
+void BKE_previewimg_num_frames_set(struct PreviewImage *prv, const short num_frames)
+{
+	BLI_assert(prv != NULL);
+
+	if (num_frames == prv->num_frames) {
+		return;
+	}
+
+	prv->num_frames = num_frames;
+	for (int i = 0; i < NUM_ICON_SIZES; i++) {
+		if (prv->rect[i]) {
+			prv->rect[i] = MEM_recallocN_id(prv->rect[i], BKE_previewimg_get_rect_size(prv, i), __func__);
+		}
+		previewimg_gputexture_free_single(prv, i);
+	}
+}
+
+void BKE_previewimg_frame_delete(struct PreviewImage *prv, const short frame_idx)
+{
+	BLI_assert(prv != NULL && frame_idx < prv->num_frames && frame_idx >= 0);
+
+	if (prv->num_frames <= 1) {
+		BKE_previewimg_clear(prv);
+		return;
+	}
+
+	prv->num_frames--;
+	for (int i = 0; i < NUM_ICON_SIZES; i++) {
+		if (prv->rect[i]) {
+			if (frame_idx != prv->num_frames) {
+				unsigned int *p_del_idx = &prv->rect[i][PREVIEWIMG_OFFSET(prv, i, frame_idx)];
+				unsigned int *p_nxt_idx = &prv->rect[i][PREVIEWIMG_OFFSET(prv, i, frame_idx + 1)];
+				size_t nxt_size = (size_t)(&prv->rect[i][PREVIEWIMG_OFFSET(prv, i, prv->num_frames + 1)] - p_nxt_idx) * sizeof(*prv->rect[i]);
+				memmove(p_del_idx, p_nxt_idx, nxt_size);
+			}
+			prv->rect[i] = MEM_reallocN_id(prv->rect[i], BKE_previewimg_get_rect_size(prv, i), __func__);
+		}
+		previewimg_gputexture_free_single(prv, i);
+	}
+}
+
+unsigned int *BKE_previewimg_frame_data_get(
+        const PreviewImage *prv, const unsigned short frame_idx, const enum eIconSizes size, int *r_meta)
+{
+	BLI_assert(prv != NULL && frame_idx < prv->num_frames);
+
+	unsigned int *frame = NULL;
+	if (r_meta) {
+		*r_meta = 0;
+	}
+
+	if (prv->rect[size]) {
+		frame = &prv->rect[size][PREVIEWIMG_OFFSET(prv, size, frame_idx)];
+		if (r_meta && prv->num_frames > 0) {
+			*r_meta = frame[prv->w[size] * prv->h[size]];
+		}
+	}
+	return frame;
+}
+
+/* Would we want to rather use a search callback? */
+unsigned int *BKE_previewimg_frame_data_search(
+        const PreviewImage *prv, const int meta, const enum eIconSizes size, unsigned short *r_frame_idx)
+{
+	BLI_assert(prv != NULL);
+
+	unsigned int *frame = NULL;
+	if (r_frame_idx) {
+		*r_frame_idx = 0;
+	}
+
+	if (prv->rect[size]) {
+		if (prv->num_frames == 0) {
+			if (meta == 0) {  /* Convention... */
+				frame = prv->rect[size];
+			}
+		}
+		else {
+			ptrdiff_t stride = &prv->rect[size][PREVIEWIMG_OFFSET(prv, size, 1)] - &prv->rect[size][0];
+			unsigned int *frame_it = prv->rect[size];
+			for (unsigned short i = 0; i < prv->num_frames; i++, frame_it += stride) {
+				if (frame_it[prv->w[size] * prv->h[size]] == meta) {
+					if (r_frame_idx) {
+						*r_frame_idx = i;
+					}
+					frame = frame_it;
+					break;
+				}
+			}
+		}
+	}
+	return frame;
+}
+
+void BKE_previewimg_frame_data_set(
+        const PreviewImage *prv,
+        const unsigned short frame_idx, const enum eIconSizes size, const int meta, const unsigned int *data)
+{
+	BLI_assert(prv != NULL && frame_idx < prv->num_frames);
+
+	unsigned int *frame = &prv->rect[size][PREVIEWIMG_OFFSET(prv, size, frame_idx)];
+	memcpy(frame, data, prv->w[size] * prv->h[size] * sizeof(*prv->rect[size]));
+	if (prv->num_frames > 0) {
+		frame[prv->w[size] * prv->h[size]] = meta;
+	}
+}
+
 /** Duplicate preview image from \a id and clear icon_id, to be used by datablock copy functions. */
 void BKE_previewimg_id_copy(ID *new_id, ID *old_id)
 {
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index be89317..1441004 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -53,6 +53,7 @@
 
 #include "BKE_main.h"
 #include "BKE_library.h" // for BKE_main_free
+#include "BKE_icons.h"
 #include "BKE_idcode.h"
 
 #include "BLO_readfile.h"
@@ -211,7 +212,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
 						memcpy(new_prv, prv, sizeof(PreviewImage));
 						if (prv->rect[0] && prv->w[0] && prv->h[0]) {
 							unsigned int *rect = NULL;
-							size_t len = new_prv->w[0] * new_prv->h[0] * sizeof(unsigned int);
+							size_t len = BKE_previewimg_get_rect_size(new_prv, 0);
 							new_prv->rect[0] = MEM_callocN(len, __func__);
 							bhead = blo_nextbhead(fd, bhead);
 							rect = (unsigned int *)(bhead + 1);
@@ -228,7 +229,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
 						
 						if (prv->rect[1] && prv->w[1] && prv->h[1]) {
 							unsigned int *rect = NULL;
-							size_t len = new_prv->w[1] * new_prv->h[1] * sizeof(unsigned int);
+							size_t len = BKE_previewimg_get_rect_size(new_prv, 1);
 							new_prv->rect[1] = MEM_callocN(len, __func__);
 							bhead = blo_nextbhead(fd, bhead);
 							rect = (unsigned int *)(bhead + 1);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 6678189..dab6d70 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -161,6 +161,7 @@
 #include "BKE_curve.h"
 #include "BKE_constraint.h"
 #include "BKE_global.h" // for G
+#include "BKE_icons.h"
 #include "BKE_idcode.h"
 #include "BKE_library.h" // for  set_listbasepointers
 #include "BKE_main.h"
@@ -691,10 +692,10 @@ static void write_previews(WriteData *wd, const PreviewImage *prv_orig)
 		}
 		writestruct_at_address(wd, DATA, PreviewImage, 1, prv_orig, &prv);
 		if (prv.rect[0]) {
-			writedata(wd, DATA, prv.w[0] * prv.h[0] * sizeof(unsigned int), prv.rect[0]);
+			writedata(wd, DATA, BKE_previewimg_get_rect_size(&prv, 0), prv.rect[0]);
 		}
 		if (prv.rect[1]) {
-			writedata(wd, DATA, prv.w[1] * prv.h[1] * sizeof(unsigned int), prv.rect[1]);
+			writedata(wd, DATA, BKE_previewimg_get_rect_size(&prv, 1), prv.rect[1]);
 		}
 	}
 }
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 22a450d..eaf9e79 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1058,6 +1058,7 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size)
 		prv_img->flag[size] |= PRV_CHANGED;
 		prv_img->changed_timestamp[size] = 0;
 		prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(unsigned int), "prv_rect");
+		prv_img->num_frames = 0;
 	}
 }
 
@@ -1300,14 +1301,15 @@ static int get_draw_size(enum eIconSizes size)
 
 
 static void icon_draw_size(
-        float x, float y, int icon_id, float aspect, float alpha, const float rgb[3],
-        enum eIconSizes size, int draw_size, const bool UNUSED(nocreate), const bool is_preview)
+        const float x, const float y, const int icon_id, const sh

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list