summaryrefslogtreecommitdiff
path: root/src/lib/ector/software/ector_software_buffer.c
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 /src/lib/ector/software/ector_software_buffer.c
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.
Diffstat (limited to 'src/lib/ector/software/ector_software_buffer.c')
-rw-r--r--src/lib/ector/software/ector_software_buffer.c109
1 files changed, 50 insertions, 59 deletions
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