diff options
author | Carsten Haitzler <raster@rasterman.com> | 2012-09-26 03:49:33 +0000 |
---|---|---|
committer | Carsten Haitzler <raster@rasterman.com> | 2012-09-26 03:49:33 +0000 |
commit | 53f2bc0638b4734c0ea6d6705288e3e641b51532 (patch) | |
tree | d8263a78e44525b24e44390ae0c1bf2bc87eccc7 /legacy | |
parent | fd794e2a543b8f24a1deda08129a6e08594040f8 (diff) |
partial swaps++ to evas gl engine.
SVN revision: 77069
Diffstat (limited to '')
-rw-r--r-- | legacy/evas/ChangeLog | 13 | ||||
-rw-r--r-- | legacy/evas/NEWS | 1 | ||||
-rw-r--r-- | legacy/evas/src/modules/engines/gl_common/evas_gl_context.c | 23 | ||||
-rw-r--r-- | legacy/evas/src/modules/engines/gl_x11/evas_engine.c | 349 |
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 | ||
1053 | 2012-09-24 Sung W. Park (sung_) | 1053 | 2012-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 | |||
1059 | 2012-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 | ||
17 | Fixes: | 18 | Fixes: |
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 | ||
14 | enum { | ||
15 | MODE_FULL, | ||
16 | MODE_COPY, | ||
17 | MODE_DOUBLE, | ||
18 | MODE_TRIPLE | ||
19 | }; | ||
20 | |||
14 | typedef struct _Render_Engine Render_Engine; | 21 | typedef struct _Render_Engine Render_Engine; |
15 | 22 | ||
16 | struct _Render_Engine | 23 | struct _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 | ||
29 | static int initted = 0; | 41 | static 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 | ||
957 | static 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 * | |||
913 | eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) | 1019 | eng_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 | ||
980 | static double | ||
981 | get_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 | |||
990 | static int safe_native = -1; | 1136 | static int safe_native = -1; |
991 | 1137 | ||
992 | static void | 1138 | static void |
993 | eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__) | 1139 | eng_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 | ||
1049 | static void | 1180 | static 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 | ||
1174 | static void | 1267 | static void |