1 #include <glib.h>
2 #include <cogl/cogl2-experimental.h>
3 #include <math.h>
4
5 #include "cogl/cogl-profile.h"
6
7 #define FRAMEBUFFER_WIDTH 800
8 #define FRAMEBUFFER_HEIGHT 600
9
10 CoglBool run_all = FALSE;
11
12 typedef struct _Data
13 {
14 CoglContext *ctx;
15 CoglFramebuffer *fb;
16 CoglPipeline *pipeline;
17 CoglPipeline *alpha_pipeline;
18 GTimer *timer;
19 int frame;
20 } Data;
21
22 static void
test_rectangles(Data * data)23 test_rectangles (Data *data)
24 {
25 #define RECT_WIDTH 5
26 #define RECT_HEIGHT 5
27 int x;
28 int y;
29
30 cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 1, 1, 1, 1);
31
32 cogl_framebuffer_push_rectangle_clip (data->fb,
33 10,
34 10,
35 FRAMEBUFFER_WIDTH - 10,
36 FRAMEBUFFER_HEIGHT - 10);
37
38 /* Should the rectangles be randomly positioned/colored/rotated?
39 *
40 * It could be good to develop equivalent GL and Cairo tests so we can
41 * have a sanity check for our Cogl performance.
42 *
43 * The color should vary to check that we correctly batch color changes
44 * The use of alpha should vary so we have a variation of which rectangles
45 * require blending.
46 * Should this be a random variation?
47 * It could be good to experiment with focibly enabling blending for
48 * rectangles that don't technically need it for the sake of extending
49 * batching. E.g. if you a long run of interleved rectangles with every
50 * other rectangle needing blending then it may be worth enabling blending
51 * for all the rectangles to avoid the state changes.
52 * The modelview should change between rectangles to check the software
53 * transform codepath.
54 * Should we group some rectangles under the same modelview? Potentially
55 * we could avoid software transform for long runs of rectangles with the
56 * same modelview.
57 *
58 */
59 for (y = 0; y < FRAMEBUFFER_HEIGHT; y += RECT_HEIGHT)
60 {
61 for (x = 0; x < FRAMEBUFFER_WIDTH; x += RECT_WIDTH)
62 {
63 cogl_framebuffer_push_matrix (data->fb);
64 cogl_framebuffer_translate (data->fb, x, y, 0);
65 cogl_framebuffer_rotate (data->fb, 45, 0, 0, 1);
66
67 cogl_pipeline_set_color4f (data->pipeline,
68 1,
69 (1.0f/FRAMEBUFFER_WIDTH)*y,
70 (1.0f/FRAMEBUFFER_HEIGHT)*x,
71 1);
72 cogl_framebuffer_draw_rectangle (data->fb,
73 data->pipeline,
74 0, 0, RECT_WIDTH, RECT_HEIGHT);
75
76 cogl_framebuffer_pop_matrix (data->fb);
77 }
78 }
79
80 for (y = 0; y < FRAMEBUFFER_HEIGHT; y += RECT_HEIGHT)
81 {
82 for (x = 0; x < FRAMEBUFFER_WIDTH; x += RECT_WIDTH)
83 {
84 cogl_framebuffer_push_matrix (data->fb);
85 cogl_framebuffer_translate (data->fb, x, y, 0);
86
87 cogl_pipeline_set_color4f (data->alpha_pipeline,
88 1,
89 (1.0f/FRAMEBUFFER_WIDTH)*x,
90 (1.0f/FRAMEBUFFER_HEIGHT)*y,
91 (1.0f/FRAMEBUFFER_WIDTH)*x);
92 cogl_framebuffer_draw_rectangle (data->fb,
93 data->alpha_pipeline,
94 0, 0, RECT_WIDTH, RECT_HEIGHT);
95
96 cogl_framebuffer_pop_matrix (data->fb);
97 }
98 }
99
100 cogl_framebuffer_pop_clip (data->fb);
101 }
102
103 static CoglBool
paint_cb(void * user_data)104 paint_cb (void *user_data)
105 {
106 Data *data = user_data;
107 double elapsed;
108
109 data->frame++;
110
111 test_rectangles (data);
112
113 cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
114
115 elapsed = g_timer_elapsed (data->timer, NULL);
116 if (elapsed > 1.0)
117 {
118 g_print ("fps = %f\n", data->frame / elapsed);
119 g_timer_start (data->timer);
120 data->frame = 0;
121 }
122
123 return FALSE; /* remove the callback */
124 }
125
126 static void
frame_event_cb(CoglOnscreen * onscreen,CoglFrameEvent event,CoglFrameInfo * info,void * user_data)127 frame_event_cb (CoglOnscreen *onscreen,
128 CoglFrameEvent event,
129 CoglFrameInfo *info,
130 void *user_data)
131 {
132 if (event == COGL_FRAME_EVENT_SYNC)
133 paint_cb (user_data);
134 }
135
136 int
main(int argc,char ** argv)137 main (int argc, char **argv)
138 {
139 Data data;
140 CoglOnscreen *onscreen;
141 GSource *cogl_source;
142 GMainLoop *loop;
143 COGL_STATIC_TIMER (mainloop_timer,
144 NULL, //no parent
145 "Mainloop",
146 "The time spent in the glib mainloop",
147 0); // no application private data
148
149 data.ctx = cogl_context_new (NULL, NULL);
150
151 onscreen = cogl_onscreen_new (data.ctx,
152 FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
153 cogl_onscreen_set_swap_throttled (onscreen, FALSE);
154 cogl_onscreen_show (onscreen);
155
156 data.fb = onscreen;
157 cogl_framebuffer_orthographic (data.fb,
158 0, 0,
159 FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
160 -1,
161 100);
162
163 data.pipeline = cogl_pipeline_new (data.ctx);
164 cogl_pipeline_set_color4f (data.pipeline, 1, 1, 1, 1);
165 data.alpha_pipeline = cogl_pipeline_new (data.ctx);
166 cogl_pipeline_set_color4f (data.alpha_pipeline, 1, 1, 1, 0.5);
167
168 cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);
169
170 g_source_attach (cogl_source, NULL);
171
172 cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb),
173 frame_event_cb,
174 &data,
175 NULL); /* destroy notify */
176
177 g_idle_add (paint_cb, &data);
178
179 data.frame = 0;
180 data.timer = g_timer_new ();
181 g_timer_start (data.timer);
182
183 loop = g_main_loop_new (NULL, TRUE);
184 COGL_TIMER_START (uprof_get_mainloop_context (), mainloop_timer);
185 g_main_loop_run (loop);
186 COGL_TIMER_STOP (uprof_get_mainloop_context (), mainloop_timer);
187
188 return 0;
189 }
190
191