summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-12-11 15:23:55 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-01-05 15:43:43 +0900
commit5e075c193c51201071b8efc950b49b45b9caa92c (patch)
tree2a740276e443dbea4ee790119d25a904ddf2d281
parent9121e503a3a1394e7b56b0e54b6bba3a0338d1e2 (diff)
ector: on-the-fly convert sw buffers during map()
Also use map to generate spans. This should simplify some filters code, making things work, albeit inefficiently. At least they should work. Fix doc too.
-rw-r--r--src/lib/ector/ector_buffer.h1
-rw-r--r--src/lib/ector/ector_generic_buffer.eo20
-rw-r--r--src/lib/ector/software/ector_software_buffer.c109
3 files changed, 62 insertions, 68 deletions
diff --git a/src/lib/ector/ector_buffer.h b/src/lib/ector/ector_buffer.h
index f4a5f9df8c..0e12c79f68 100644
--- a/src/lib/ector/ector_buffer.h
+++ b/src/lib/ector/ector_buffer.h
@@ -35,7 +35,6 @@ typedef struct _Ector_Software_Buffer_Base_Data
35 } internal; 35 } internal;
36 Eina_Bool writable : 1; // pixels can be written to 36 Eina_Bool writable : 1; // pixels can be written to
37 Eina_Bool nofree : 1; // pixel data should not be free()'ed 37 Eina_Bool nofree : 1; // pixel data should not be free()'ed
38 Eina_Bool span_free : 1; // FIXME
39} Ector_Software_Buffer_Base_Data; 38} Ector_Software_Buffer_Base_Data;
40 39
41#endif 40#endif
diff --git a/src/lib/ector/ector_generic_buffer.eo b/src/lib/ector/ector_generic_buffer.eo
index 8f98108bfa..6e735b3428 100644
--- a/src/lib/ector/ector_generic_buffer.eo
+++ b/src/lib/ector/ector_generic_buffer.eo
@@ -40,17 +40,21 @@ mixin Ector.Generic.Buffer
40 } 40 }
41 map { 41 map {
42 [[Map a region of this buffer for read or write access by the CPU, 42 [[Map a region of this buffer for read or write access by the CPU,
43 fetch data from the GPU if needed. 43 fetch data from the GPU if needed. This operation may be slow if
44 cpu_readable_fast or cpu_writeable_fast are not true, or if the
45 required colorspace is different from the internal one.
44 ]] 46 ]]
45 params { 47 params {
46 @out length: uint; [[Accessible buffer size in bytes]] 48 @out length: uint; [[Accessible buffer size in bytes, should not be $null.]]
47 @in mode: Ector.Buffer.Access_Flag; 49 @in mode: Ector.Buffer.Access_Flag; [[Specifies whether to map for read-only,
48 @in x: uint; 50 write-only or read-write access (OR combinaison of flags).]]
49 @in y: uint; 51 @in x: uint; [[X position of the top-left pixel to map]]
52 @in y: uint; [[Y position of the top-left pixel to map]]
50 @in w: uint; [[If 0, defaults to the buffer width]] 53 @in w: uint; [[If 0, defaults to the buffer width]]
51 @in h: uint; [[If 0, defaults to the buffer height]] 54 @in h: uint; [[If 0, defaults to the buffer height]]
52 @in cspace: Efl.Gfx.Colorspace; [[Requested colorspace. If difference from the internal cspace, map may either fail or convert slowly]] 55 @in cspace: Efl.Gfx.Colorspace; [[Requested colorspace. If differen from the internal cspace,
53 @out stride: uint; [[Optional]] 56 map should try to convert the data into a new buffer]]
57 @out stride: uint @optional; [[Returns the length in bytes of a mapped line]]
54 } 58 }
55 return: void* @warn_unused; [[Pointer to the top-left pixel data. Returns $null in case of failure]] 59 return: void* @warn_unused; [[Pointer to the top-left pixel data. Returns $null in case of failure]]
56 } 60 }
@@ -58,7 +62,7 @@ mixin Ector.Generic.Buffer
58 [[Unmap a region of this buffer, and upload data to the GPU (if needed).]] 62 [[Unmap a region of this buffer, and upload data to the GPU (if needed).]]
59 params { 63 params {
60 @in data: void*; [[Data pointer returned by a previous call to map]] 64 @in data: void*; [[Data pointer returned by a previous call to map]]
61 @in length: uint; 65 @in length: uint; [[Must be the same as returned
62 } 66 }
63 } 67 }
64 pixels_set { 68 pixels_set {
diff --git a/src/lib/ector/software/ector_software_buffer.c b/src/lib/ector/software/ector_software_buffer.c
index 1783258a95..e64234d4de 100644
--- a/src/lib/ector/software/ector_software_buffer.c
+++ b/src/lib/ector/software/ector_software_buffer.c
@@ -16,7 +16,7 @@ typedef struct _Ector_Software_Buffer_Map
16{ 16{
17 EINA_INLIST; 17 EINA_INLIST;
18 void *ptr; 18 void *ptr;
19 unsigned int len; 19 unsigned int size; // in bytes
20 Eina_Bool allocated; 20 Eina_Bool allocated;
21} Ector_Software_Buffer_Map; 21} Ector_Software_Buffer_Map;
22 22
@@ -142,8 +142,11 @@ _ector_software_buffer_base_ector_generic_buffer_map(Eo *obj EINA_UNUSED, Ector_
142 unsigned int x, unsigned int y, unsigned int w, unsigned int h, 142 unsigned int x, unsigned int y, unsigned int w, unsigned int h,
143 Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride) 143 Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride)
144{ 144{
145 Ector_Software_Buffer_Map *map; 145 Ector_Software_Buffer_Map *map = NULL;
146 int off; 146 unsigned int off, k;
147
148 if (!w) w = pd->generic->w;
149 if (!h) h = pd->generic->h;
147 150
148 if (!pd->pixels.u8 || !pd->stride) 151 if (!pd->pixels.u8 || !pd->stride)
149 fail("Buffer has no pixel data yet"); 152 fail("Buffer has no pixel data yet");
@@ -153,20 +156,46 @@ _ector_software_buffer_base_ector_generic_buffer_map(Eo *obj EINA_UNUSED, Ector_
153 fail("Invalid region requested: wanted %u,%u %ux%u but image is %ux%u", 156 fail("Invalid region requested: wanted %u,%u %ux%u but image is %ux%u",
154 x, y, w, h, pd->generic->w, pd->generic->h); 157 x, y, w, h, pd->generic->w, pd->generic->h);
155 if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable) 158 if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable)
156 fail("can not map a read-only buffer for writing"); 159 fail("Can not map a read-only buffer for writing");
160
161 map = calloc(1, sizeof(*map));
162 if (!map) fail("Out of memory");
157 163
158 off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + (pd->stride * (y + pd->generic->t)); 164 off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + (pd->stride * (y + pd->generic->t));
159 165
160 map = calloc(1, sizeof(*map)); 166 if (cspace != pd->generic->cspace)
161 map->len = (pd->stride * h) - off; 167 {
162 map->ptr = pd->pixels.u8 + off; 168 // convert on the fly
163 pd->internal.maps = eina_inlist_append(pd->internal.maps, EINA_INLIST_GET(map)); 169 map->size = _min_stride_calc(w, cspace) * h;
170 map->allocated = EINA_TRUE;
171 map->ptr = malloc(map->size);
172 if (!map->ptr) fail("Out of memory");
173 if (stride) *stride = _min_stride_calc(w, cspace);
174
175 if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
176 {
177 for (k = 0; k < h; k++)
178 _pixels_gry8_to_argb_convert((uint32_t *) map->ptr + (k * w), pd->pixels.u8 + off + (k * pd->stride), w);
179 }
180 else
181 {
182 for (k = 0; k < h; k++)
183 _pixels_argb_to_gry8_convert((uint8_t *) map->ptr + (k * w), (uint32_t *) (pd->pixels.u8 + off + (k * pd->stride)), w);
184 }
185 }
186 else
187 {
188 map->size = (pd->stride * h) - off;
189 map->ptr = pd->pixels.u8 + off;
190 if (stride) *stride = pd->stride;
191 }
164 192
165 if (length) *length = map->len; 193 pd->internal.maps = eina_inlist_prepend(pd->internal.maps, EINA_INLIST_GET(map));
166 if (stride) *stride = pd->stride; 194 if (length) *length = map->size;
167 return map->ptr; 195 return map->ptr;
168 196
169on_fail: 197on_fail:
198 free(map);
170 if (length) *length = 0; 199 if (length) *length = 0;
171 if (stride) *stride = 0; 200 if (stride) *stride = 0;
172 return NULL; 201 return NULL;
@@ -181,9 +210,11 @@ _ector_software_buffer_base_ector_generic_buffer_unmap(Eo *obj EINA_UNUSED, Ecto
181 210
182 EINA_INLIST_FOREACH(pd->internal.maps, map) 211 EINA_INLIST_FOREACH(pd->internal.maps, map)
183 { 212 {
184 if ((map->ptr == data) && (map->len == length)) 213 if ((map->ptr == data) && ((map->size == length) || (length == (unsigned int) -1)))
185 { 214 {
186 pd->internal.maps = eina_inlist_remove(pd->internal.maps, EINA_INLIST_GET(map)); 215 pd->internal.maps = eina_inlist_remove(pd->internal.maps, EINA_INLIST_GET(map));
216 if (map->allocated)
217 free(map->ptr);
187 free(map); 218 free(map);
188 return; 219 return;
189 } 220 }
@@ -193,62 +224,22 @@ _ector_software_buffer_base_ector_generic_buffer_unmap(Eo *obj EINA_UNUSED, Ecto
193} 224}
194 225
195EOLIAN static uint8_t * 226EOLIAN static uint8_t *
196_ector_software_buffer_base_ector_generic_buffer_span_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd, 227_ector_software_buffer_base_ector_generic_buffer_span_get(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
197 int x, int y, unsigned int w, Efl_Gfx_Colorspace cspace, 228 int x, int y, unsigned int w, Efl_Gfx_Colorspace cspace,
198 unsigned int *length) 229 unsigned int *length)
199{ 230{
200 uint8_t *src; 231 // ector_buffer_map
201 int len, px; 232 return _ector_software_buffer_base_ector_generic_buffer_map
202 233 (obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL);
203 if (!pd->pixels.u8)
204 fail("No pixel data");
205 if ((x < -pd->generic->l) || (y < -pd->generic->t) ||
206 ((unsigned) x > pd->generic->w) || ((unsigned) y > pd->generic->h))
207 fail("Out of bounds");
208 if (((unsigned) x + w) > (pd->generic->w + pd->generic->l + pd->generic->r))
209 fail("Requested span too large");
210
211 px = _min_stride_calc(1, pd->generic->cspace);
212 len = _min_stride_calc(w, cspace);
213 if (length) *length = len;
214
215 src = pd->pixels.u8 + ((pd->generic->t + y) * pd->stride) + (px * (pd->generic->l + x));
216
217 if (cspace == pd->generic->cspace)
218 {
219 pd->span_free = EINA_FALSE;
220 return src;
221 }
222 else if ((cspace == EFL_GFX_COLORSPACE_ARGB8888) &&
223 (pd->generic->cspace == EFL_GFX_COLORSPACE_GRY8))
224 {
225 uint32_t *buf = malloc(len);
226 _pixels_gry8_to_argb_convert(buf, src, w);
227 pd->span_free = EINA_TRUE;
228 return (uint8_t *) buf;
229 }
230 else if ((cspace == EFL_GFX_COLORSPACE_GRY8) &&
231 (pd->generic->cspace == EFL_GFX_COLORSPACE_ARGB8888))
232 {
233 uint8_t *buf = malloc(len);
234 _pixels_argb_to_gry8_convert(buf, (uint32_t *) src, w);
235 pd->span_free = EINA_TRUE;
236 return buf;
237 }
238 else
239 fail("Unsupported colorspace %u", cspace);
240
241on_fail:
242 if (length) *length = 0;
243 return NULL;
244} 234}
245 235
246EOLIAN static void 236EOLIAN static void
247_ector_software_buffer_base_ector_generic_buffer_span_free(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd, 237_ector_software_buffer_base_ector_generic_buffer_span_free(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
248 uint8_t *data) 238 uint8_t *data)
249{ 239{
250 if (pd->span_free) free(data); 240 // ector_buffer_unmap
251 pd->span_free = EINA_FALSE; 241 return _ector_software_buffer_base_ector_generic_buffer_unmap
242 (obj, pd, data, (unsigned int) -1);
252} 243}
253 244
254EOLIAN static Ector_Buffer_Flag 245EOLIAN static Ector_Buffer_Flag