summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler <raster@rasterman.com>2012-09-26 03:49:33 +0000
committerCarsten Haitzler <raster@rasterman.com>2012-09-26 03:49:33 +0000
commit53f2bc0638b4734c0ea6d6705288e3e641b51532 (patch)
treed8263a78e44525b24e44390ae0c1bf2bc87eccc7
parentfd794e2a543b8f24a1deda08129a6e08594040f8 (diff)
partial swaps++ to evas gl engine.
SVN revision: 77069
-rw-r--r--legacy/evas/ChangeLog13
-rw-r--r--legacy/evas/NEWS1
-rw-r--r--legacy/evas/src/modules/engines/gl_common/evas_gl_context.c23
-rw-r--r--legacy/evas/src/modules/engines/gl_x11/evas_engine.c349
4 files changed, 249 insertions, 137 deletions
diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog
index ec41bbbd7a..316f1f0a26 100644
--- a/legacy/evas/ChangeLog
+++ b/legacy/evas/ChangeLog
@@ -1052,8 +1052,15 @@
1052 1052
10532012-09-24 Sung W. Park (sung_) 10532012-09-24 Sung W. Park (sung_)
1054 1054
1055 * Refactored Evas GL engine code so wayland_egl and gl_x11 and other 1055 * Refactored Evas GL engine code so wayland_egl and gl_x11 and other
1056 engines can share the same code. The common codes are in gl_common/ 1056 engines can share the same code. The common codes are in gl_common/
1057 directory and evas_engine just has to implement a few engine functions. 1057 directory and evas_engine just has to implement a few engine functions.
1058
10592012-09-26 Carsten Haitzler (The Rasterman)
1060
1061 * Add the ability via env vars to do partial swaps in the gl
1062 engine. This requires that we also can get from gl info as to
1063 if a swap was a copy, swap, discard and if a swap with 2 or 3
1064 buffers. don't have that but env var will do for now for testing.
1058 1065
1059 1066
diff --git a/legacy/evas/NEWS b/legacy/evas/NEWS
index 33ccabee89..e8d819a39a 100644
--- a/legacy/evas/NEWS
+++ b/legacy/evas/NEWS
@@ -13,6 +13,7 @@ Improvements:
13 13
14 * Function to rotate an evas map with a quaternion: evas_map_util_quat_rotate(). 14 * Function to rotate an evas map with a quaternion: evas_map_util_quat_rotate().
15 * EVAS_GL_NO_BLACKLIST env var to turn off blacklisted drivers in gl 15 * EVAS_GL_NO_BLACKLIST env var to turn off blacklisted drivers in gl
16 * Evas gl enigne can do partial swaps now.
16 17
17Fixes: 18Fixes:
18 19
diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c
index 0f19cbdffc..f3f3def8b0 100644
--- a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c
+++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c
@@ -2212,16 +2212,27 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
2212 w = w - x; 2212 w = w - x;
2213 h = h - y; 2213 h = h - y;
2214 2214
2215 if (!flat)
2216 {
2217 // FUZZZZ!
2218 x -= 3;
2219 y -= 3;
2220 w += 6;
2221 h += 6;
2222 }
2215 if (clip) 2223 if (clip)
2216 { 2224 {
2217 int nx = x, ny = y, nw = w, nh = h; 2225 if (flat)
2218
2219 RECTS_CLIP_TO_RECT(nx, ny, nw, nh, cx, cy, cw, ch);
2220 if ((nx == x) && (ny == y) && (nw == w) && (nh == h))
2221 { 2226 {
2222 clip = 0; cx = 0; cy = 0; cw = 0; ch = 0; 2227 int nx = x, ny = y, nw = w, nh = h;
2228
2229 RECTS_CLIP_TO_RECT(nx, ny, nw, nh, cx, cy, cw, ch);
2230 if ((nx == x) && (ny == y) && (nw == w) && (nh == h))
2231 {
2232 clip = 0; cx = 0; cy = 0; cw = 0; ch = 0;
2233 }
2234 x = nx; y = ny; w = nw; h = nh;
2223 } 2235 }
2224 x = nx; y = ny; w = nw; h = nh;
2225 } 2236 }
2226 2237
2227 if (!flat) 2238 if (!flat)
diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c
index 304d522aa3..191baac327 100644
--- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c
+++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c
@@ -11,19 +11,31 @@
11#define EVAS_GL_NO_GL_H_CHECK 1 11#define EVAS_GL_NO_GL_H_CHECK 1
12#include "Evas_GL.h" 12#include "Evas_GL.h"
13 13
14enum {
15 MODE_FULL,
16 MODE_COPY,
17 MODE_DOUBLE,
18 MODE_TRIPLE
19};
20
14typedef struct _Render_Engine Render_Engine; 21typedef struct _Render_Engine Render_Engine;
15 22
16struct _Render_Engine 23struct _Render_Engine
17{ 24{
25 Tilebuf_Rect *rects;
26 Tilebuf_Rect *rects_prev[3];
27 Eina_Inlist *cur_rect;
28
18 Evas_GL_X11_Window *win; 29 Evas_GL_X11_Window *win;
19 Evas_Engine_Info_GL_X11 *info; 30 Evas_Engine_Info_GL_X11 *info;
20 Evas *evas; 31 Evas *evas;
21 Tilebuf *tb; 32 Tilebuf *tb;
22 int end; 33 int end;
23 int w, h; 34 int mode;
24 int vsync; 35 int w, h;
36 int vsync;
25 37
26 EVGL_Engine *evgl_engine; 38 EVGL_Engine *evgl_engine;
27}; 39};
28 40
29static int initted = 0; 41static int initted = 0;
@@ -627,6 +639,7 @@ eng_setup(Evas *e, void *in)
627{ 639{
628 Render_Engine *re; 640 Render_Engine *re;
629 Evas_Engine_Info_GL_X11 *info; 641 Evas_Engine_Info_GL_X11 *info;
642 const char *s;
630 643
631 info = (Evas_Engine_Info_GL_X11 *)in; 644 info = (Evas_Engine_Info_GL_X11 *)in;
632 if (!e->engine.data.output) 645 if (!e->engine.data.output)
@@ -740,6 +753,36 @@ eng_setup(Evas *e, void *in)
740 } 753 }
741 } 754 }
742 } 755 }
756 if ((s = getenv("EVAS_GL_SWAP_MODE")))
757 {
758 if ((!strcasecmp(s, "full")) ||
759 (!strcasecmp(s, "f")))
760 re->mode = MODE_FULL;
761 else if ((!strcasecmp(s, "copy")) ||
762 (!strcasecmp(s, "c")))
763 re->mode = MODE_COPY;
764 else if ((!strcasecmp(s, "double")) ||
765 (!strcasecmp(s, "d")) ||
766 (!strcasecmp(s, "2")))
767 re->mode = MODE_DOUBLE;
768 else if ((!strcasecmp(s, "triple")) ||
769 (!strcasecmp(s, "t")) ||
770 (!strcasecmp(s, "3")))
771 re->mode = MODE_TRIPLE;
772 }
773 else
774 {
775// in most gl implementations - egl and glx here that we care about the TEND
776// to either swap or copy backbuffer and front buffer, but strictly that is
777// not true. technically backbuffer content is totally undefined after a swap
778// and thus you MUST re-render all of it, thus MODE_FULL
779// re->mode = MODE_FULL;
780// BUT... reality is that lmost every implementation copies or swaps so
781// triple buffer mode can be used as it is a superset of double buffer and
782// copy (though using those explicitly is more efficient). so let's play with
783// triple buffer mdoe as a default and see.
784 re->mode = MODE_TRIPLE;
785 }
743 if (!re->win) 786 if (!re->win)
744 { 787 {
745 free(re); 788 free(re);
@@ -815,6 +858,10 @@ eng_output_free(void *data)
815 evgl_engine_destroy(re->evgl_engine); 858 evgl_engine_destroy(re->evgl_engine);
816 } 859 }
817 evas_common_tilebuf_free(re->tb); 860 evas_common_tilebuf_free(re->tb);
861 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
862 if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
863 if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
864 if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
818 free(re); 865 free(re);
819 } 866 }
820 if ((initted == 1) && (gl_wins == 0)) 867 if ((initted == 1) && (gl_wins == 0))
@@ -860,6 +907,7 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
860 evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot); 907 evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
861 evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); 908 evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
862 909
910 /* bounding box track */
863 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->w, re->win->h); 911 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->w, re->win->h);
864 if ((w <= 0) || (h <= 0)) return; 912 if ((w <= 0) || (h <= 0)) return;
865 if (!re->win->draw.redraw) 913 if (!re->win->draw.redraw)
@@ -906,6 +954,64 @@ eng_output_redraws_clear(void *data)
906// INF("GL: finish update cycle!"); 954// INF("GL: finish update cycle!");
907} 955}
908 956
957static Tilebuf_Rect *
958_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3)
959{
960 Tilebuf_Rect *r, *rects;
961 int x1, y1, x2, y2;
962
963 if (r1)
964 {
965 EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
966 {
967 evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
968 }
969 }
970 if (r2)
971 {
972 EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
973 {
974 evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
975 }
976 }
977 if (r2)
978 {
979 EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
980 {
981 evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
982 }
983 }
984 rects = evas_common_tilebuf_get_render_rects(tb);
985
986// bounding box -> make a bounding box single region update of all regions.
987// yes we could try and be smart and figure out size of regions, how far
988// apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
989// between multiple update regions to render and total pixels to render.
990 if (rects)
991 {
992 x1 = rects->x; y1 = rects->y;
993 x2 = rects->x + rects->w; y2 = rects->y + rects->h;
994 EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
995 {
996 if (r->x < x1) x1 = r->x;
997 if (r->y < y1) y1 = r->y;
998 if ((r->x + r->w) > x2) x2 = r->x + r->w;
999 if ((r->y + r->h) > y2) y2 = r->y + r->h;
1000 }
1001 evas_common_tilebuf_free_render_rects(rects);
1002 rects = calloc(1, sizeof(Tilebuf_Rect));
1003 if (rects)
1004 {
1005 rects->x = x1;
1006 rects->y = y1;
1007 rects->w = x2 - x1;
1008 rects->h = y2 - y1;
1009 }
1010 }
1011 evas_common_tilebuf_clear(tb);
1012 return rects;
1013}
1014
909/* vsync games - not for now though */ 1015/* vsync games - not for now though */
910#define VSYNC_TO_SCREEN 1 1016#define VSYNC_TO_SCREEN 1
911 1017
@@ -913,90 +1019,126 @@ static void *
913eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) 1019eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
914{ 1020{
915 Render_Engine *re; 1021 Render_Engine *re;
916 Tilebuf_Rect *rects; 1022 Tilebuf_Rect *rect;
1023 int i;
1024 Eina_Bool first_rect = EINA_FALSE;
1025
1026#define CLEAR_PREV_RECTS(x) \
1027 do { \
1028 if (re->rects_prev[i]) \
1029 evas_common_tilebuf_free_render_rects(re->rects_prev[i]); \
1030 re->rects_prev[i] = NULL; \
1031 } while (0)
917 1032
918 re = (Render_Engine *)data; 1033 re = (Render_Engine *)data;
919 /* get the upate rect surface - return engine data as dummy */ 1034 /* get the upate rect surface - return engine data as dummy */
920 rects = evas_common_tilebuf_get_render_rects(re->tb); 1035 if (re->end)
921 if (rects)
922 { 1036 {
923/* 1037 re->end = 0;
924 Tilebuf_Rect *r; 1038 return NULL;
925 1039 }
926 printf("REAAAAACCTS\n"); 1040 if (!re->rects)
927 EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) 1041 {
1042 re->rects = evas_common_tilebuf_get_render_rects(re->tb);
1043 evas_common_tilebuf_clear(re->tb);
1044 if (re->rects)
928 { 1045 {
929 printf(" %i %i %ix%i\n", r->x, r->y, r->w, r->h); 1046 /* ensure we get rid of previous rect lists we dont need if mode
1047 * changed/is appropriate */
1048 switch (re->mode)
1049 {
1050 case MODE_FULL:
1051 case MODE_COPY: // no prev rects needed
1052 for (i = 0; i < 3; i++) CLEAR_PREV_RECTS(i);
1053 break;
1054 case MODE_DOUBLE: // double mode - only 1 level of prev rect
1055 for (i = 1; i < 3; i++) CLEAR_PREV_RECTS(i);
1056 re->rects_prev[1] = re->rects_prev[0];
1057 re->rects_prev[0] = re->rects;
1058 // merge prev[1] + prev[0] -> rects
1059 re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL);
1060 break;
1061 case MODE_TRIPLE: // keep all
1062 for (i = 2; i < 3; i++) CLEAR_PREV_RECTS(i);
1063 re->rects_prev[2] = re->rects_prev[1];
1064 re->rects_prev[1] = re->rects_prev[0];
1065 re->rects_prev[0] = re->rects;
1066 re->rects = NULL;
1067 // merge prev[2] + prev[1] + prev[0] -> rects
1068 re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]);
1069 break;
1070 default:
1071 break;
1072 }
1073 re->cur_rect = EINA_INLIST_GET(re->rects);
1074 first_rect = EINA_TRUE;
930 } 1075 }
931 */ 1076 }
932 evas_common_tilebuf_free_render_rects(rects); 1077 if (!re->cur_rect) return NULL;
933 evas_common_tilebuf_clear(re->tb); 1078 rect = (Tilebuf_Rect *)re->cur_rect;
1079 if (re->rects)
1080 {
1081 switch (re->mode)
1082 {
1083 case MODE_COPY:
1084 case MODE_DOUBLE:
1085 case MODE_TRIPLE:
1086 rect = (Tilebuf_Rect *)re->cur_rect;
1087 *x = rect->x;
1088 *y = rect->y;
1089 *w = rect->w;
1090 *h = rect->h;
1091 *cx = rect->x;
1092 *cy = rect->y;
1093 *cw = rect->w;
1094 *ch = rect->h;
1095 re->cur_rect = re->cur_rect->next;
1096 break;
1097 case MODE_FULL:
1098 re->cur_rect = NULL;
1099 if (x) *x = 0;
1100 if (y) *y = 0;
1101 if (w) *w = re->win->w;
1102 if (h) *h = re->win->h;
1103 if (cx) *cx = 0;
1104 if (cy) *cy = 0;
1105 if (cw) *cw = re->win->w;
1106 if (ch) *ch = re->win->h;
1107 break;
1108 default:
1109 break;
1110 }
1111 if (first_rect)
1112 {
934#ifdef GL_GLES 1113#ifdef GL_GLES
935 // dont need to for egl - eng_window_use() can check for other ctxt's 1114 // dont need to for egl - eng_window_use() can check for other ctxt's
936#else 1115#else
937 eng_window_use(NULL); 1116 eng_window_use(NULL);
938#endif 1117#endif
939 eng_window_use(re->win); 1118 eng_window_use(re->win);
940 if (!_re_wincheck(re)) return NULL; 1119 if (!_re_wincheck(re)) return NULL;
941 evas_gl_common_context_flush(re->win->gl_context); 1120
942 evas_gl_common_context_newframe(re->win->gl_context); 1121 evas_gl_common_context_flush(re->win->gl_context);
943 if (x) *x = 0; 1122 evas_gl_common_context_newframe(re->win->gl_context);
944 if (y) *y = 0; 1123//// debug partial updates :)
945 if (w) *w = re->win->w; 1124// glClearColor(1.0, 0.5, 0.2, 1.0);
946 if (h) *h = re->win->h; 1125// glClear(GL_COLOR_BUFFER_BIT);
947 if (cx) *cx = 0; 1126 }
948 if (cy) *cy = 0; 1127 if (!re->cur_rect)
949 if (cw) *cw = re->win->w; 1128 {
950 if (ch) *ch = re->win->h; 1129 re->end = 1;
1130 }
951 return re->win->gl_context->def_surface; 1131 return re->win->gl_context->def_surface;
952 } 1132 }
953 return NULL; 1133 return NULL;
954/*
955 if (!re->win->draw.redraw) return NULL;
956#ifdef GL_GLES
957 // dont need to for egl - eng_window_use() can check for other ctxt's
958#else
959 eng_window_use(NULL);
960#endif
961 eng_window_use(re->win);
962 if (!_re_wincheck(re)) return NULL;
963 evas_gl_common_context_flush(re->win->gl_context);
964 evas_gl_common_context_newframe(re->win->gl_context);
965 if (x) *x = re->win->draw.x1;
966 if (y) *y = re->win->draw.y1;
967 if (w) *w = re->win->draw.x2 - re->win->draw.x1 + 1;
968 if (h) *h = re->win->draw.y2 - re->win->draw.y1 + 1;
969 if (cx) *cx = re->win->draw.x1;
970 if (cy) *cy = re->win->draw.y1;
971 if (cw) *cw = re->win->draw.x2 - re->win->draw.x1 + 1;
972 if (ch) *ch = re->win->draw.y2 - re->win->draw.y1 + 1;
973 return re->win->gl_context->def_surface;
974 */
975} 1134}
976 1135
977//#define FRAMECOUNT 1
978
979#ifdef FRAMECOUNT
980static double
981get_time(void)
982{
983 struct timeval timev;
984
985 gettimeofday(&timev, NULL);
986 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
987}
988#endif
989
990static int safe_native = -1; 1136static int safe_native = -1;
991 1137
992static void 1138static void
993eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__) 1139eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
994{ 1140{
995 Render_Engine *re; 1141 Render_Engine *re;
996#ifdef FRAMECOUNT
997 static double pt = 0.0;
998 double ta, tb;
999#endif
1000 1142
1001 re = (Render_Engine *)data; 1143 re = (Render_Engine *)data;
1002 /* put back update surface.. in this case just unflag redraw */ 1144 /* put back update surface.. in this case just unflag redraw */
@@ -1023,18 +1165,8 @@ eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x
1023#ifdef GL_GLES 1165#ifdef GL_GLES
1024 // this is needed to make sure all previous rendering is flushed to 1166 // this is needed to make sure all previous rendering is flushed to
1025 // buffers/surfaces 1167 // buffers/surfaces
1026#ifdef FRAMECOUNT
1027 double t0 = get_time();
1028 ta = t0 - pt;
1029 pt = t0;
1030#endif
1031 // previous rendering should be done and swapped 1168 // previous rendering should be done and swapped
1032 if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE); 1169 if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE);
1033#ifdef FRAMECOUNT
1034 double t1 = get_time();
1035 tb = t1 - t0;
1036 printf("... %1.5f -> %1.5f | ", ta, tb);
1037#endif
1038// if (eglGetError() != EGL_SUCCESS) 1170// if (eglGetError() != EGL_SUCCESS)
1039// { 1171// {
1040// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n"); 1172// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n");
@@ -1043,7 +1175,6 @@ eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x
1043 // previous rendering should be done and swapped 1175 // previous rendering should be done and swapped
1044 if (!safe_native) glXWaitX(); 1176 if (!safe_native) glXWaitX();
1045#endif 1177#endif
1046//x// printf("frame -> push\n");
1047} 1178}
1048 1179
1049static void 1180static void
@@ -1054,14 +1185,11 @@ eng_output_flush(void *data)
1054 re = (Render_Engine *)data; 1185 re = (Render_Engine *)data;
1055 if (!_re_wincheck(re)) return; 1186 if (!_re_wincheck(re)) return;
1056 if (!re->win->draw.drew) return; 1187 if (!re->win->draw.drew) return;
1057//x// printf("frame -> flush\n"); 1188
1058 re->win->draw.drew = 0; 1189 re->win->draw.drew = 0;
1059 eng_window_use(re->win); 1190 eng_window_use(re->win);
1060 1191
1061#ifdef GL_GLES 1192#ifdef GL_GLES
1062#ifdef FRAMECOUNT
1063 double t0 = get_time();
1064#endif
1065 if (!re->vsync) 1193 if (!re->vsync)
1066 { 1194 {
1067 if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1); 1195 if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1);
@@ -1072,23 +1200,20 @@ eng_output_flush(void *data)
1072 { 1200 {
1073 re->info->callback.pre_swap(re->info->callback.data, re->evas); 1201 re->info->callback.pre_swap(re->info->callback.data, re->evas);
1074 } 1202 }
1203 // XXX: if partial swaps can be done use re->rects
1075 eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]); 1204 eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
1076 if (!safe_native) eglWaitGL(); 1205 if (!safe_native) eglWaitGL();
1077 if (re->info->callback.post_swap) 1206 if (re->info->callback.post_swap)
1078 { 1207 {
1079 re->info->callback.post_swap(re->info->callback.data, re->evas); 1208 re->info->callback.post_swap(re->info->callback.data, re->evas);
1080 } 1209 }
1081#ifdef FRAMECOUNT
1082 double t1 = get_time();
1083 printf("%1.5f\n", t1 - t0);
1084#endif
1085// if (eglGetError() != EGL_SUCCESS) 1210// if (eglGetError() != EGL_SUCCESS)
1086// { 1211// {
1087// printf("Error: eglSwapBuffers() fail.\n"); 1212// printf("Error: eglSwapBuffers() fail.\n");
1088// } 1213// }
1089#else 1214#else
1090#ifdef VSYNC_TO_SCREEN 1215#ifdef VSYNC_TO_SCREEN
1091 if ((re->info->vsync)/* || (1)*/) 1216 if (re->info->vsync)
1092 { 1217 {
1093 if (glsym_glXSwapIntervalEXT) 1218 if (glsym_glXSwapIntervalEXT)
1094 { 1219 {
@@ -1119,56 +1244,24 @@ eng_output_flush(void *data)
1119 } 1244 }
1120 } 1245 }
1121 } 1246 }
1122# endif 1247#endif
1123 if (re->info->callback.pre_swap) 1248 if (re->info->callback.pre_swap)
1124 { 1249 {
1125 re->info->callback.pre_swap(re->info->callback.data, re->evas); 1250 re->info->callback.pre_swap(re->info->callback.data, re->evas);
1126 } 1251 }
1127#if 1 1252 // XXX: if partial swaps can be done use re->rects
1128 if (1) 1253 glXSwapBuffers(re->win->disp, re->win->win);
1129#else
1130 if ((re->win->draw.x1 == 0) && (re->win->draw.y1 == 0) && (re->win->draw.x2 == (re->win->w - 1)) && (re->win->draw.y2 == (re->win->h - 1)))
1131#endif
1132 {
1133// double t, t2 = 0.0;
1134// t = get_time();
1135 glXSwapBuffers(re->win->disp, re->win->win);
1136// t = get_time() - t;
1137// if (!safe_native)
1138// {
1139// t2 = get_time();
1140// glXWaitGL();
1141// t2 = get_time() - t2;
1142// }
1143// printf("swap: %3.5f (%3.5fms), x wait gl: %3.5f (%3.5fms)\n",
1144// t, t * 1000.0, t2, t2 * 1000.0);
1145 }
1146 else
1147 {
1148// FIXME: this doesn't work.. why oh why?
1149 int sx, sy, sw, sh;
1150
1151 sx = re->win->draw.x1;
1152 sy = re->win->draw.y1;
1153 sw = (re->win->draw.x2 - re->win->draw.x1) + 1;
1154 sh = (re->win->draw.y2 - re->win->draw.y1) + 1;
1155 sy = re->win->h - sy - sh;
1156
1157 glBitmap(0, 0, 0, 0, sx, re->win->h - sy, NULL);
1158 glEnable(GL_SCISSOR_TEST);
1159 glScissor(sx, sy, sw, sh);
1160 glDrawBuffer(GL_FRONT);
1161 glCopyPixels(sx, sy, sw, sh, GL_COLOR);
1162 glDrawBuffer(GL_BACK);
1163 glDisable(GL_SCISSOR_TEST);
1164 glBitmap(0, 0, 0, 0, 0, 0, NULL);
1165 glFlush();
1166 }
1167 if (re->info->callback.post_swap) 1254 if (re->info->callback.post_swap)
1168 { 1255 {
1169 re->info->callback.post_swap(re->info->callback.data, re->evas); 1256 re->info->callback.post_swap(re->info->callback.data, re->evas);
1170 } 1257 }
1171#endif 1258#endif
1259 // clear out rects after swap as we may use them during swap
1260 if (re->rects)
1261 {
1262 evas_common_tilebuf_free_render_rects(re->rects);
1263 re->rects = NULL;
1264 }
1172} 1265}
1173 1266
1174static void 1267static void