2 * Cairo Performance Test Framework
3 * (c) 2012 Samsung Electronics, Inc.
6 * Measures rendering performance for image, gl backends
8 * This software is a confidential and proprietary information of Samsung
9 * Electronics, Inc. ("Confidential Information"). You shall not disclose such
10 * Confidential Information and shall use it only in accordance with the terms
11 * of the license agreement you entered into with Samsung Electronics.
13 * Author: Dongyeon Kim <dy5.kim@samsung.com>
17 #include <Elementary.h>
19 #include <EGL/eglext.h>
23 #define SURFACE_TYPE_IMAGE 0
24 #define SURFACE_TYPE_GL 1
25 #define TOTAL_TIME 100
29 //Ecore Evas variables
30 Ecore_X_Window window;
34 EGLDisplay egl_display;
35 EGLSurface egl_surface;
36 EGLContext egl_context;
39 cairo_device_t *cairo_device;
40 cairo_surface_t *cairo_surface;
43 Eina_Bool renderMain(void *data)
45 static int counter = 0;
46 static float totalTime = 0;
47 static float totalPaint = 0;
48 static float totalUpdate = 0;
49 struct timeval paintStart, paintStop, updateStop;
52 gettimeofday(&paintStart, NULL);
53 /* ########## PAINT : START ########## */
55 /* ########## PAINT : END ########## */
56 gettimeofday(&paintStop, NULL);
57 /* ########## UPDATE : START ########## */
58 if(cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_GL) {
59 cairo_gl_surface_swapbuffers(cairo_get_target(cr));
61 unsigned char *imageData = cairo_image_surface_get_data(cairo_get_target(cr));
62 evas_object_image_data_set(img, imageData);
63 evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT);
66 /* ########## UPDATE : END ########## */
67 gettimeofday(&updateStop, NULL);
70 totalTime += updateStop.tv_usec - paintStart.tv_usec;
71 totalTime += (updateStop.tv_sec - paintStart.tv_sec)*1000000;
72 totalPaint += (paintStop.tv_usec - paintStart.tv_usec);
73 totalPaint += (paintStop.tv_sec - paintStart.tv_sec)*1000000;
74 totalUpdate += (updateStop.tv_usec - paintStop.tv_usec);
75 totalUpdate += (updateStop.tv_sec - paintStop.tv_sec)*1000000;
78 if(counter == TOTAL_TIME)
80 float fps = TOTAL_TIME / totalTime * 1000000.0f;
81 printf("fps = %0.2f\n", fps);
82 printf("average paint time = %0.1f usec, update time = %0.1f usec\n", totalPaint/TOTAL_TIME, totalUpdate/TOTAL_TIME);
89 void initELMWindow(int surface_type)
91 Evas_Object *win = elm_win_add(NULL, "cairotest", ELM_WIN_BASIC);
92 elm_win_autodel_set(win, EINA_TRUE);
93 ecore_x_screen_size_get(ecore_x_default_screen_get(), &WIDTH, &HEIGHT);
94 evas_object_resize(win, WIDTH, HEIGHT);
95 evas_object_show(win);
97 if (surface_type == SURFACE_TYPE_IMAGE) {
98 Evas_Object *img_win = elm_image_add(win);
99 img = evas_object_image_filled_add(evas_object_evas_get(img_win));
100 elm_win_resize_object_add(win, img);
101 evas_object_image_content_hint_set(img, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
102 evas_object_image_size_set(img, WIDTH, HEIGHT);
103 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
104 evas_object_image_alpha_set(img, 0);
105 evas_object_show(img_win);
106 evas_object_show(img);
107 } else if(surface_type == SURFACE_TYPE_GL) {
108 window = ecore_x_window_new(0, 0, 0, WIDTH, HEIGHT);
109 ecore_x_icccm_title_set(window, "window");
110 ecore_x_netwm_name_set(window, "window");
111 ecore_x_input_multi_select(window);
112 ecore_x_icccm_transient_for_set(window, elm_win_xwindow_get(win));
113 ecore_x_window_show(window);
117 void initEGL(int surface_type)
119 if(surface_type != SURFACE_TYPE_GL)
122 setenv("ELM_ENGINE", "gl", 1);
124 egl_display = eglGetDisplay((EGLNativeDisplayType) ecore_x_display_get());
125 if(egl_display == EGL_NO_DISPLAY)
127 printf("cannot get egl display\n");
132 if(!eglInitialize(egl_display, &major, &minor))
134 printf("cannot initialize egl\n");
138 if(!eglBindAPI(EGL_OPENGL_ES_API))
140 printf("cannot bind egl to gles2 API\n");
144 EGLConfig egl_config;
149 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
150 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
161 if(!eglChooseConfig(egl_display, attr, &egl_config, 1, &num))
163 printf("cannot choose config\n");
169 printf("did not get exactly one config = %d\n", num);
173 egl_surface = eglCreateWindowSurface(egl_display,
174 egl_config, (NativeWindowType) window, NULL);
175 if(egl_surface == EGL_NO_SURFACE)
177 printf("cannot create surface\n");
181 EGLint e = eglGetError();
182 //printf("egl error = %x\n", e);
186 EGL_CONTEXT_CLIENT_VERSION, 2,
190 egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, ctxattr);
191 if(egl_context == EGL_NO_CONTEXT)
193 EGLint e = eglGetError();
194 printf("cannot create context, error = %x\n", e);
199 EGLBoolean result = eglQueryContext(egl_display, egl_context, EGL_CONTEXT_CLIENT_VERSION, &value);
200 //printf("Context version = %x, result = %d\n", value, result);
202 eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
205 void destroyEGL(int surface_type)
207 if(surface_type != SURFACE_TYPE_GL)
210 eglDestroyContext(egl_display, egl_context);
211 eglDestroySurface(egl_display, egl_surface);
212 eglTerminate(egl_display);
215 void initCairo(int surface_type)
217 if(surface_type == SURFACE_TYPE_IMAGE) {
218 printf("== CREATE IMAGE SURFACE ==\n");
219 cairo_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
220 } else if(surface_type == SURFACE_TYPE_GL) {
221 printf("== CREATE GL SURFACE ==\n");
222 setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
223 cairo_device = cairo_egl_device_create(egl_display, egl_context);
224 cairo_gl_device_set_thread_aware(cairo_device, 0);
225 cairo_surface = cairo_gl_surface_create_for_egl(cairo_device, egl_surface, WIDTH, HEIGHT);
227 cr = cairo_create(cairo_surface);
230 void destroyCairo(int surface_type)
232 cairo_surface_destroy(cairo_surface);
235 if(surface_type == SURFACE_TYPE_GL) {
236 cairo_device_destroy(cairo_device);
240 int main(int argc, char **argv)
242 int surface_type = SURFACE_TYPE_GL;
245 surface_type = atoi(argv[1]);
247 elm_init(argc, argv);
249 initELMWindow(surface_type);
250 initEGL(surface_type);
251 initCairo(surface_type);
254 Ecore_Animator *animator = ecore_animator_add(renderMain, (void *)cr);
258 destroyCairo(surface_type);
259 destroyEGL(surface_type);