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