egl: Overhaul driver API.
[mesa.git] / src / egl / drivers / demo / demo.c
1 /*
2 * Sample driver: Demo
3 */
4
5 #include <assert.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "eglconfig.h"
9 #include "eglcontext.h"
10 #include "egldisplay.h"
11 #include "egldriver.h"
12 #include "eglglobals.h"
13 #include "eglmode.h"
14 #include "eglscreen.h"
15 #include "eglsurface.h"
16
17
18 /**
19 * Demo driver-specific driver class derived from _EGLDriver
20 */
21 typedef struct demo_driver
22 {
23 _EGLDriver Base; /* base class/object */
24 unsigned DemoStuff;
25 } DemoDriver;
26
27 #define DEMO_DRIVER(D) ((DemoDriver *) (D))
28
29
30 /**
31 * Demo driver-specific surface class derived from _EGLSurface
32 */
33 typedef struct demo_surface
34 {
35 _EGLSurface Base; /* base class/object */
36 unsigned DemoStuff;
37 } DemoSurface;
38
39
40 /**
41 * Demo driver-specific context class derived from _EGLContext
42 */
43 typedef struct demo_context
44 {
45 _EGLContext Base; /* base class/object */
46 unsigned DemoStuff;
47 } DemoContext;
48
49
50
51 static EGLBoolean
52 demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
53 {
54 _EGLScreen *scrn;
55 EGLint i;
56
57 /* Create a screen */
58 scrn = calloc(1, sizeof(*scrn));
59 _eglAddScreen(disp, scrn);
60
61 /* Create the screen's modes - silly example */
62 _eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72");
63 _eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70");
64 _eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70");
65 _eglAddNewMode(scrn, 1024, 768, 72 * 1000, "1024x768-72");
66
67 /* Create the display's visual configs - silly example */
68 for (i = 0; i < 4; i++) {
69 _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
70 _eglInitConfig(config, i + 1);
71 _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
72 _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
73 _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
74 _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
75 _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
76 if (i & 1) {
77 _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 32);
78 }
79 if (i & 2) {
80 _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
81 }
82 _eglSetConfigAttrib(config, EGL_SURFACE_TYPE,
83 (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
84 _eglAddConfig(disp, config);
85 }
86
87 drv->Initialized = EGL_TRUE;
88
89 *major = 1;
90 *minor = 0;
91
92 return EGL_TRUE;
93 }
94
95
96 static EGLBoolean
97 demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
98 {
99 /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
100 free(drv);
101 return EGL_TRUE;
102 }
103
104
105 static DemoContext *
106 LookupDemoContext(_EGLContext *c)
107 {
108 return (DemoContext *) c;
109 }
110
111
112 static DemoSurface *
113 LookupDemoSurface(_EGLSurface *s)
114 {
115 return (DemoSurface *) s;
116 }
117
118
119 static _EGLContext *
120 demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
121 {
122 DemoContext *c;
123 int i;
124
125 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
126 switch (attrib_list[i]) {
127 /* no attribs defined for now */
128 default:
129 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
130 return NULL;
131 }
132 }
133
134 c = (DemoContext *) calloc(1, sizeof(DemoContext));
135 if (!c)
136 return NULL;
137
138 _eglInitContext(drv, &c->Base, conf, attrib_list);
139 c->DemoStuff = 1;
140 printf("demoCreateContext\n");
141
142 return &c->Base;
143 }
144
145
146 static _EGLSurface *
147 demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
148 {
149 int i;
150 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
151 switch (attrib_list[i]) {
152 /* no attribs at this time */
153 default:
154 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
155 return NULL;
156 }
157 }
158 printf("eglCreateWindowSurface()\n");
159 /* XXX unfinished */
160
161 return NULL;
162 }
163
164
165 static _EGLSurface *
166 demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
167 {
168 EGLint i;
169
170 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
171 switch (attrib_list[i]) {
172 /* no attribs at this time */
173 default:
174 _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
175 return NULL;
176 }
177 }
178
179 if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
180 _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
181 return NULL;
182 }
183
184 printf("eglCreatePixmapSurface()\n");
185 return NULL;
186 }
187
188
189 static _EGLSurface *
190 demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
191 const EGLint *attrib_list)
192 {
193 DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
194
195 if (!surf)
196 return NULL;
197
198 if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
199 conf, attrib_list)) {
200 free(surf);
201 return NULL;
202 }
203
204 /* a real driver would allocate the pbuffer memory here */
205
206 return &surf->Base;
207 }
208
209
210 static EGLBoolean
211 demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
212 {
213 DemoSurface *fs = LookupDemoSurface(surface);
214 if (!_eglIsSurfaceBound(&fs->Base))
215 free(fs);
216 return EGL_TRUE;
217 }
218
219
220 static EGLBoolean
221 demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
222 {
223 DemoContext *fc = LookupDemoContext(context);
224 if (!_eglIsContextBound(&fc->Base))
225 free(fc);
226 return EGL_TRUE;
227 }
228
229
230 static EGLBoolean
231 demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx)
232 {
233 /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
234 EGLBoolean b;
235
236 b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx);
237 if (!b)
238 return EGL_FALSE;
239
240 /* XXX this is where we'd do the hardware context switch */
241 (void) drawSurf;
242 (void) readSurf;
243 (void) ctx;
244
245 printf("eglMakeCurrent()\n");
246 return EGL_TRUE;
247 }
248
249
250 /**
251 * The bootstrap function. Return a new DemoDriver object and
252 * plug in API functions.
253 */
254 _EGLDriver *
255 _eglMain(_EGLDisplay *dpy, const char *args)
256 {
257 DemoDriver *demo;
258
259 demo = (DemoDriver *) calloc(1, sizeof(DemoDriver));
260 if (!demo) {
261 return NULL;
262 }
263
264 /* First fill in the dispatch table with defaults */
265 _eglInitDriverFallbacks(&demo->Base);
266 /* then plug in our Demo-specific functions */
267 demo->Base.API.Initialize = demoInitialize;
268 demo->Base.API.Terminate = demoTerminate;
269 demo->Base.API.CreateContext = demoCreateContext;
270 demo->Base.API.MakeCurrent = demoMakeCurrent;
271 demo->Base.API.CreateWindowSurface = demoCreateWindowSurface;
272 demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface;
273 demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface;
274 demo->Base.API.DestroySurface = demoDestroySurface;
275 demo->Base.API.DestroyContext = demoDestroyContext;
276
277 /* enable supported extensions */
278 demo->Base.Extensions.MESA_screen_surface = EGL_TRUE;
279 demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
280
281 return &demo->Base;
282 }