summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-01-17 15:05:23 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-02-07 17:33:17 +0900
commit8062df320c579ad053ef73c0930afe9c2b003ce4 (patch)
tree1ea1972735632efb59f1e4f529836f578bbbab8f /src
parentf007cd5665e1020fa9ee0a2966bfbc279fa49c73 (diff)
Evas filters: OpenGL support part 2.
This patch implements the final draw from RGBA_Image to the OpenGL surface. We can even steal the output buffer and redraw it quickly, without having to re-render everything (same as in SW).
Diffstat (limited to 'src')
-rw-r--r--src/lib/evas/canvas/evas_object_text.c28
-rw-r--r--src/lib/evas/filters/evas_filter.c95
-rw-r--r--src/lib/evas/filters/evas_filter_private.h9
-rw-r--r--src/lib/evas/include/evas_filter.h1
4 files changed, 103 insertions, 30 deletions
diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c
index af3c48844f..fab1f3b5d4 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -2128,12 +2128,9 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
2128 { 2128 {
2129 int X, Y, W, H; 2129 int X, Y, W, H;
2130 Evas_Filter_Context *filter; 2130 Evas_Filter_Context *filter;
2131 int inbuf = 1; 2131 const int inbuf = 1;
2132 int outbuf = 2; 2132 const int outbuf = 2;
2133 int targetbuf;
2134 RGBA_Image *input, *outputimg = NULL; // FIXME: This is engine dependent
2135 void *filter_ctx; 2133 void *filter_ctx;
2136 static int gl_engine = -1;
2137 Eina_Bool ok; 2134 Eina_Bool ok;
2138 int ox = 0, oy = 0; 2135 int ox = 0, oy = 0;
2139 2136
@@ -2144,10 +2141,6 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
2144 * image to GL. 2141 * image to GL.
2145 */ 2142 */
2146 2143
2147 // FIXME. Disabled redraw for OpenGL.
2148 if (gl_engine == -1)
2149 gl_engine = !!strstr(obj->layer->evas->engine.module->definition->name, "gl");
2150
2151 W = obj->cur->geometry.w; 2144 W = obj->cur->geometry.w;
2152 H = obj->cur->geometry.h; 2145 H = obj->cur->geometry.h;
2153 X = obj->cur->geometry.x; 2146 X = obj->cur->geometry.x;
@@ -2185,7 +2178,6 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
2185 else 2178 else
2186 { 2179 {
2187 // Render this image only 2180 // Render this image only
2188 outputimg = o->cur.filter.output;
2189 ENFN->image_draw(ENDT, context, 2181 ENFN->image_draw(ENDT, context,
2190 surface, o->cur.filter.output, 2182 surface, o->cur.filter.output,
2191 0, 0, W, H, // src 2183 0, 0, W, H, // src
@@ -2208,21 +2200,15 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
2208 // Proxies 2200 // Proxies
2209 evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE); 2201 evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
2210 2202
2211 // Output
2212 targetbuf = evas_filter_buffer_image_new(filter, surface);
2213
2214 // Context: FIXME it should be a sw context only 2203 // Context: FIXME it should be a sw context only
2215 filter_ctx = ENFN->context_new(ENDT); 2204 filter_ctx = ENFN->context_new(ENDT);
2216 ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255); 2205 ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
2217 2206
2218 // Alloc input now so we can draw text asap 2207 // Allocate main buffers now
2219 evas_filter_buffer_data_set(filter, inbuf, NULL, W, H, EINA_TRUE); 2208 evas_filter_buffer_data_set(filter, inbuf, NULL, W, H, EINA_TRUE);
2220
2221 // Allocate and steal output so we can keep it around
2222 evas_filter_buffer_data_set(filter, outbuf, NULL, W, H, EINA_FALSE); 2209 evas_filter_buffer_data_set(filter, outbuf, NULL, W, H, EINA_FALSE);
2223 if (!gl_engine) 2210 evas_filter_target_set(filter, context, surface, X + x, Y + y);
2224 outputimg = evas_filter_buffer_backing_steal(filter, outbuf); 2211 o->cur.filter.output = evas_filter_buffer_backing_steal(filter, outbuf);
2225 o->cur.filter.output = outputimg;
2226 2212
2227 // Render text to input buffer 2213 // Render text to input buffer
2228 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it) 2214 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
@@ -2235,10 +2221,6 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
2235 do_async); 2221 do_async);
2236 } 2222 }
2237 2223
2238 // FIXME: This final blend is not necessary. Needs to be removed.
2239 evas_filter_command_blend_add(filter, context, outbuf, targetbuf,
2240 X + x, Y + y, EVAS_FILTER_FILL_MODE_NONE);
2241
2242 ENFN->context_free(ENDT, filter_ctx); 2224 ENFN->context_free(ENDT, filter_ctx);
2243 2225
2244 // Add post-run callback and run filter 2226 // Add post-run callback and run filter
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 61563c0e8e..96dd50f891 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -330,7 +330,6 @@ _rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
330 } 330 }
331 else 331 else
332 { 332 {
333 WRN("EXPERIMENTAL OpenGL support. VERY HACKISH!");
334 // FIXME: Directly calling the alloc functions since we want to use sw surfaces. 333 // FIXME: Directly calling the alloc functions since we want to use sw surfaces.
335 334
336 if (!data) 335 if (!data)
@@ -371,6 +370,9 @@ evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h)
371 { 370 {
372 int W, H; 371 int W, H;
373 372
373 if (fb->ctx->gl_engine)
374 return EINA_TRUE;
375
374 fb->ENFN->image_size_get(fb->ENDT, fb->backing, &W, &H); 376 fb->ENFN->image_size_get(fb->ENDT, fb->backing, &W, &H);
375 if ((W == w) && (H == h)) 377 if ((W == w) && (H == h))
376 return EINA_TRUE; 378 return EINA_TRUE;
@@ -526,8 +528,13 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
526 buffer = _filter_buffer_get(ctx, bufid); 528 buffer = _filter_buffer_get(ctx, bufid);
527 if (!buffer) return NULL; 529 if (!buffer) return NULL;
528 530
529 buffer->allocated = EINA_FALSE; 531 if (!buffer->glimage)
530 return buffer->backing; 532 {
533 buffer->allocated = EINA_FALSE;
534 return buffer->backing;
535 }
536 else
537 return buffer->glimage;
531} 538}
532 539
533static Evas_Filter_Command * 540static Evas_Filter_Command *
@@ -1211,6 +1218,78 @@ evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd)
1211} 1218}
1212 1219
1213 1220
1221/* Final target */
1222Eina_Bool
1223evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
1224 void *surface, int x, int y)
1225{
1226 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
1227
1228 ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
1229 if (!ctx->gl_engine)
1230 {
1231 /* FIXME: This extraneous blend could be avoided if all filters
1232 * drawing to output (buffer #2) support proper colors and offsets.
1233 */
1234 evas_filter_command_blend_add(ctx, draw_context, 2, ctx->target.bufid,
1235 x, y, EVAS_FILTER_FILL_MODE_NONE);
1236 }
1237 else
1238 {
1239 // Since GL has sync rendering, draw_context is safe to keep around
1240 Evas_Filter_Buffer *target, *image;
1241 RGBA_Image *im;
1242
1243 ctx->target.context = draw_context;
1244 ctx->target.x = x;
1245 ctx->target.y = y;
1246
1247 target = _filter_buffer_get(ctx, ctx->target.bufid);
1248 target->glimage = target->backing;
1249 target->backing = NULL;
1250
1251 image = _filter_buffer_get(ctx, 2);
1252 im = image->backing;
1253 image->glimage = ENFN->image_new_from_data
1254 (ENDT, image->w, image->h, im->image.data, EINA_TRUE, im->cache_entry.space);
1255 }
1256
1257 return EINA_TRUE;
1258}
1259
1260static Eina_Bool
1261_filter_target_render(Evas_Filter_Context *ctx)
1262{
1263 Evas_Filter_Buffer *src, *dst;
1264 Eina_Bool ok;
1265
1266 /* FIXME: This is some hackish hook to send the final buffer on the screen
1267 * Only used for OpenGL now, since evas_filter_target_set() adds a blend
1268 * command in case of pure software rendering.
1269 */
1270
1271 if (!ctx->gl_engine) return EINA_FALSE;
1272 EINA_SAFETY_ON_FALSE_RETURN_VAL(ctx->target.bufid, EINA_FALSE);
1273
1274 src = _filter_buffer_get(ctx, 2);
1275 if (!src) return EINA_FALSE;
1276
1277 dst = _filter_buffer_get(ctx, ctx->target.bufid);
1278 if (!dst) return EINA_FALSE;
1279
1280 EINA_SAFETY_ON_NULL_RETURN_VAL(src->glimage, EINA_FALSE);
1281 EINA_SAFETY_ON_NULL_RETURN_VAL(dst->glimage, EINA_FALSE);
1282
1283 ok = ENFN->image_draw(ENDT, ctx->target.context,
1284 dst->glimage, src->glimage,
1285 0, 0, src->w, src->h,
1286 ctx->target.x, ctx->target.y, src->w, src->h,
1287 EINA_TRUE, EINA_FALSE);
1288
1289 return ok;
1290}
1291
1292
1214/* Font drawing stuff */ 1293/* Font drawing stuff */
1215Eina_Bool 1294Eina_Bool
1216evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, 1295evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
@@ -1367,9 +1446,6 @@ _filter_command_run(Evas_Filter_Command *cmd)
1367 //func = cmd->ENFN->filter_command_func_get(cmd); 1446 //func = cmd->ENFN->filter_command_func_get(cmd);
1368 // FIXME: Must call engine function, not CPU directly. 1447 // FIXME: Must call engine function, not CPU directly.
1369 1448
1370 if (strncmp(cmd->ctx->evas->engine.module->definition->name, "software", 8))
1371 WRN("EXPERIMENTAL OpenGL support! ALL HELL WILL BREAK LOOSE!");
1372
1373 switch (cmd->mode) 1449 switch (cmd->mode)
1374 { 1450 {
1375 case EVAS_FILTER_MODE_BLEND: 1451 case EVAS_FILTER_MODE_BLEND:
@@ -1436,7 +1512,9 @@ _filter_chain_run(Evas_Filter_Context *ctx)
1436 } 1512 }
1437 } 1513 }
1438 1514
1439 return ok; 1515 if (!ok) return EINA_FALSE;
1516
1517 return _filter_target_render(ctx);
1440} 1518}
1441 1519
1442static void 1520static void
@@ -1458,6 +1536,9 @@ evas_filter_run(Evas_Filter_Context *ctx, Eina_Bool do_async)
1458 if (!ctx->commands) 1536 if (!ctx->commands)
1459 return EINA_TRUE; 1537 return EINA_TRUE;
1460 1538
1539 if (ctx->gl_engine)
1540 WRN("EXPERIMENTAL OpenGL support! Might very well crash or not render anything.");
1541
1461 if (do_async) 1542 if (do_async)
1462 { 1543 {
1463 evas_thread_cmd_enqueue(_filter_thread_run_cb, ctx); 1544 evas_thread_cmd_enqueue(_filter_thread_run_cb, ctx);
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index 8f9be8088e..ab73a921d3 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -57,6 +57,14 @@ struct _Evas_Filter_Context
57 void *data; 57 void *data;
58 } post_run; 58 } post_run;
59 59
60 struct
61 {
62 // Only used with the GL engine.
63 int bufid;
64 void *context;
65 int x, y;
66 } target;
67
60 Eina_Bool gl_engine : 1; 68 Eina_Bool gl_engine : 1;
61}; 69};
62 70
@@ -139,6 +147,7 @@ struct _Evas_Filter_Buffer
139 147
140 Evas_Object *source; 148 Evas_Object *source;
141 void *backing; 149 void *backing;
150 void *glimage;
142 int w, h; 151 int w, h;
143 152
144 Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA) 153 Eina_Bool alpha_only : 1; // 1 channel (A) instead of 4 (RGBA)
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index 1b68d8a557..88e24fa60a 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -113,6 +113,7 @@ Eina_Bool evas_filter_buffer_data_set(Evas_Filter_Context *ctx, i
113Eina_Bool evas_filter_run(Evas_Filter_Context *ctx, Eina_Bool do_async); 113Eina_Bool evas_filter_run(Evas_Filter_Context *ctx, Eina_Bool do_async);
114 114
115Eina_Bool evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async); 115Eina_Bool evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async);
116Eina_Bool evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y);
116 117
117/** 118/**
118 * @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color 119 * @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color