summaryrefslogtreecommitdiff
path: root/progs/egl/eglut/eglut_screen.c
blob: 50549e4bcf8ac0cbbdb81d4d388c7d58d64bf3fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

#define EGL_EGLEXT_PROTOTYPES
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "eglutint.h"

#define MAX_MODES 100

static EGLScreenMESA kms_screen;
static EGLModeMESA kms_mode;
static EGLint kms_width, kms_height;

void
_eglutNativeInitDisplay(void)
{
   _eglut->native_dpy = EGL_DEFAULT_DISPLAY;
   _eglut->surface_type = EGL_SCREEN_BIT_MESA;
}

void
_eglutNativeFiniDisplay(void)
{
   kms_screen = 0;
   kms_mode = 0;
   kms_width = 0;
   kms_height = 0;
}

static void
init_kms(void)
{
   EGLModeMESA modes[MAX_MODES];
   EGLint num_screens, num_modes;
   EGLint width, height, best_mode;
   EGLint i;

   if (!eglGetScreensMESA(_eglut->dpy, &kms_screen, 1, &num_screens) ||
         !num_screens)
      _eglutFatal("eglGetScreensMESA failed\n");

   if (!eglGetModesMESA(_eglut->dpy, kms_screen,
            modes, MAX_MODES, &num_modes) || !num_modes)
      _eglutFatal("eglGetModesMESA failed!\n");

   printf("Found %d modes:\n", num_modes);

   best_mode = 0;
   width = 0;
   height = 0;
   for (i = 0; i < num_modes; i++) {
      EGLint w, h;
      eglGetModeAttribMESA(_eglut->dpy, modes[i], EGL_WIDTH, &w);
      eglGetModeAttribMESA(_eglut->dpy, modes[i], EGL_HEIGHT, &h);
      printf("%3d: %d x %d\n", i, w, h);
      if (w > width && h > height) {
         width = w;
         height = h;
         best_mode = i;
      }
   }

   printf("Will use screen size: %d x %d\n", width, height);

   kms_mode = modes[best_mode];
   kms_width = width;
   kms_height = height;
}

void
_eglutNativeInitWindow(struct eglut_window *win, const char *title,
                       int x, int y, int w, int h)
{
   EGLint surf_attribs[16];
   EGLint i;
   const char *exts;

   exts = eglQueryString(_eglut->dpy, EGL_EXTENSIONS);
   if (!exts || !strstr(exts, "EGL_MESA_screen_surface"))
      _eglutFatal("EGL_MESA_screen_surface is not supported\n");

   init_kms();

   i = 0;
   surf_attribs[i++] = EGL_WIDTH;
   surf_attribs[i++] = kms_width;
   surf_attribs[i++] = EGL_HEIGHT;
   surf_attribs[i++] = kms_height;
   surf_attribs[i++] = EGL_NONE;

   /* create surface */
   win->native.u.surface = eglCreateScreenSurfaceMESA(_eglut->dpy,
         win->config, surf_attribs);
   if (win->native.u.surface == EGL_NO_SURFACE)
      _eglutFatal("eglCreateScreenSurfaceMESA failed\n");

   if (!eglShowScreenSurfaceMESA(_eglut->dpy, kms_screen,
            win->native.u.surface, kms_mode))
      _eglutFatal("eglShowScreenSurfaceMESA failed\n");

   win->native.width = kms_width;
   win->native.height = kms_height;
}

void
_eglutNativeFiniWindow(struct eglut_window *win)
{
   eglShowScreenSurfaceMESA(_eglut->dpy,
         kms_screen, EGL_NO_SURFACE, 0);
   eglDestroySurface(_eglut->dpy, win->native.u.surface);
}

void
_eglutNativeEventLoop(void)
{
   int start = _eglutNow();
   int frames = 0;

   _eglut->redisplay = 1;

   while (1) {
      struct eglut_window *win = _eglut->current;
      int now = _eglutNow();

      if (now - start > 5000) {
         double elapsed = (double) (now - start) / 1000.0;

         printf("%d frames in %3.1f seconds = %6.3f FPS\n",
               frames, elapsed, frames / elapsed);

         start = now;
         frames = 0;

         /* send escape */
         if (win->keyboard_cb)
            win->keyboard_cb(27);
      }

      if (_eglut->idle_cb)
         _eglut->idle_cb();

      if (_eglut->redisplay) {
         _eglut->redisplay = 0;

         if (win->display_cb)
            win->display_cb();
         eglSwapBuffers(_eglut->dpy, win->surface);
         frames++;
      }
   }
}