egl: Some per-driver data should be per-display.
[mesa.git] / src / egl / drivers / demo / demo.c
index 041884b40a046434608ba0901ef006f854890be8..aea4894448b7625f6f603b25f95b9e22d8299d61 100644 (file)
@@ -21,7 +21,7 @@
 typedef struct demo_driver
 {
    _EGLDriver Base;  /* base class/object */
-   GLuint DemoStuff;
+   unsigned DemoStuff;
 } DemoDriver;
 
 #define DEMO_DRIVER(D) ((DemoDriver *) (D))
@@ -33,7 +33,7 @@ typedef struct demo_driver
 typedef struct demo_surface
 {
    _EGLSurface Base;  /* base class/object */
-   GLuint DemoStuff;
+   unsigned DemoStuff;
 } DemoSurface;
 
 
@@ -43,66 +43,50 @@ typedef struct demo_surface
 typedef struct demo_context
 {
    _EGLContext Base;  /* base class/object */
-   GLuint DemoStuff;
+   unsigned DemoStuff;
 } DemoContext;
 
 
 
 static EGLBoolean
-demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    _EGLScreen *scrn;
    EGLint i;
 
-   disp->NumScreens = 1;
-   disp->Screens = (_EGLScreen *) calloc(disp->NumScreens, sizeof(_EGLScreen));
-   scrn = disp->Screens + 0;
-   scrn->NumModes = 4;
-   scrn->Modes = (_EGLMode *) calloc(scrn->NumModes, sizeof(_EGLMode));
-   scrn->Modes[0].Width = 1600;
-   scrn->Modes[0].Height = 1200;
-   scrn->Modes[0].Depth = 32;
-   scrn->Modes[0].RefreshRate = 72 * 1000;
-   scrn->Modes[1].Width = 1280;
-   scrn->Modes[1].Height = 1024;
-   scrn->Modes[1].Depth = 32;
-   scrn->Modes[1].RefreshRate = 72 * 1000;
-   scrn->Modes[2].Width = 1280;
-   scrn->Modes[2].Height = 1024;
-   scrn->Modes[2].Depth = 16;
-   scrn->Modes[2].RefreshRate = 72 * 1000;
-   scrn->Modes[3].Width = 1024;
-   scrn->Modes[3].Height = 768;
-   scrn->Modes[3].Depth = 16;
-   scrn->Modes[3].RefreshRate = 72 * 1000;
-   for (i = 0; i < scrn->NumModes; i++)
-      scrn->Modes[i].Handle = i + 1;
-
-   /* Create list of visual configs - this is a silly example */
-   disp->NumConfigs = 4;
-   disp->Configs = (_EGLConfig *) calloc(disp->NumConfigs, sizeof(_EGLConfig));
-   for (i = 0; i < disp->NumConfigs; i++) {
-      _EGLConfig *config = disp->Configs + i;
-      _eglInitConfig(config, i + 1);
-      SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, 8);
-      SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, 8);
-      SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, 8);
-      SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, 8);
-      SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, 32);
+   /* Create a screen */
+   scrn = calloc(1, sizeof(*scrn));
+   _eglAddScreen(disp, scrn);
+
+   /* Create the screen's modes - silly example */
+   _eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72");
+   _eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70");
+   _eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70");
+   _eglAddNewMode(scrn, 1024,  768, 72 * 1000, "1024x768-72");
 
+   /* Create the display's visual configs - silly example */
+   for (i = 0; i < 4; i++) {
+      _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
+      _eglInitConfig(config, i + 1);
+      _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
+      _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
+      _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
+      _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
+      _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
       if (i & 1) {
-         SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, 32);
+         _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 32);
       }
       if (i & 2) {
-         SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, 8);
+         _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
       }
-
-      SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE,
-                        (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
+      _eglSetConfigAttrib(config, EGL_SURFACE_TYPE,
+                          (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
+      _eglAddConfig(disp, config);
    }
 
-   drv->Initialized = EGL_TRUE;
+   /* enable supported extensions */
+   disp->Extensions.MESA_screen_surface = EGL_TRUE;
+   disp->Extensions.MESA_copy_context = EGL_TRUE;
 
    *major = 1;
    *minor = 0;
@@ -112,76 +96,56 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
 
 
 static EGLBoolean
-demoTerminate(_EGLDriver *drv, EGLDisplay dpy)
+demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
-   free(drv);
    return EGL_TRUE;
 }
 
 
 static DemoContext *
-LookupDemoContext(EGLContext ctx)
+LookupDemoContext(_EGLContext *c)
 {
-   _EGLContext *c = _eglLookupContext(ctx);
    return (DemoContext *) c;
 }
 
 
 static DemoSurface *
-LookupDemoSurface(EGLSurface surf)
+LookupDemoSurface(_EGLSurface *s)
 {
-   _EGLSurface *s = _eglLookupSurface(surf);
    return (DemoSurface *) s;
 }
 
 
-
-static EGLContext
-demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
 {
-   _EGLConfig *conf;
    DemoContext *c;
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    int i;
 
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreateContext");
-      return EGL_NO_CONTEXT;
-   }
-
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
       switch (attrib_list[i]) {
          /* no attribs defined for now */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
-         return EGL_NO_CONTEXT;
+         return NULL;
       }
    }
 
    c = (DemoContext *) calloc(1, sizeof(DemoContext));
    if (!c)
-      return EGL_NO_CONTEXT;
+      return NULL;
 
-   _eglInitContext(&c->Base);
-   c->Base.Display = disp;
-   c->Base.Config = conf;
-   c->Base.DrawSurface = EGL_NO_SURFACE;
-   c->Base.ReadSurface = EGL_NO_SURFACE;
+   _eglInitContext(drv, &c->Base, conf, attrib_list);
    c->DemoStuff = 1;
    printf("demoCreateContext\n");
 
-   /* generate handle and insert into hash table */
-   _eglSaveContext(&c->Base);
-   assert(c->Base.Handle);
-
-   return c->Base.Handle;
+   return &c->Base;
 }
 
 
-static EGLSurface
-demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
 {
    int i;
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
@@ -189,155 +153,88 @@ demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nativ
          /* no attribs at this time */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
-         return EGL_NO_SURFACE;
+         return NULL;
       }
    }
    printf("eglCreateWindowSurface()\n");
    /* XXX unfinished */
 
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
-static EGLSurface
-demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
 {
-   _EGLConfig *conf;
    EGLint i;
 
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
-      return EGL_NO_SURFACE;
-   }
-
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
       switch (attrib_list[i]) {
          /* no attribs at this time */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
-         return EGL_NO_SURFACE;
+         return NULL;
       }
    }
 
    if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
       _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
    printf("eglCreatePixmapSurface()\n");
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
-static EGLSurface
-demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+                         const EGLint *attrib_list)
 {
-   _EGLConfig *conf;
-   EGLint i, width = 0, height = 0, largest, texFormat, texTarget, mipmapTex;
-   DemoSurface *surf;
-
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
-      return EGL_NO_SURFACE;
-   }
-
-   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
-      switch (attrib_list[i]) {
-      case EGL_WIDTH:
-         width = attrib_list[++i];
-         break;
-      case EGL_HEIGHT:
-         height = attrib_list[++i];
-         break;
-      case EGL_LARGEST_PBUFFER:
-         largest = attrib_list[++i];
-         break;
-      case EGL_TEXTURE_FORMAT:
-         texFormat = attrib_list[++i];
-         break;
-      case EGL_TEXTURE_TARGET:
-         texTarget = attrib_list[++i];
-         break;
-      case EGL_MIPMAP_TEXTURE:
-         mipmapTex = attrib_list[++i];
-         break;
-      default:
-         _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
-         return EGL_NO_SURFACE;
-      }
-   }
+   DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
 
-   if (width <= 0 || height <= 0) {
-      _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface(width or height)");
-      return EGL_NO_SURFACE;
-   }
-
-   surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
    if (!surf)
-      return EGL_NO_SURFACE;
-
-   surf->Base.Config = conf;
-   surf->Base.Type = EGL_PBUFFER_BIT;
-   surf->Base.Width = width;
-   surf->Base.Height = height;
-   surf->Base.TextureFormat = texFormat;
-   surf->Base.TextureTarget = texTarget;
-   surf->Base.MipmapTexture = mipmapTex;
-   surf->Base.MipmapLevel = 0;
-   surf->Base.SwapInterval = 0;
+      return NULL;
 
-   printf("eglCreatePbufferSurface()\n");
+   if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
+                        conf, attrib_list)) {
+      free(surf);
+      return NULL;
+   }
 
-   /* insert into hash table */
-   _eglSaveSurface(&surf->Base);
-   assert(surf->Base.Handle);
+   /* a real driver would allocate the pbuffer memory here */
 
-   return surf->Base.Handle;
+   return &surf->Base;
 }
 
 
 static EGLBoolean
-demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
 {
    DemoSurface *fs = LookupDemoSurface(surface);
-   _eglRemoveSurface(&fs->Base);
-   if (fs->Base.IsBound) {
-      fs->Base.DeletePending = EGL_TRUE;
-   }
-   else {
+   if (!_eglIsSurfaceBound(&fs->Base))
       free(fs);
-   }
    return EGL_TRUE;
 }
 
 
 static EGLBoolean
-demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
 {
    DemoContext *fc = LookupDemoContext(context);
-   _eglRemoveContext(&fc->Base);
-   if (fc->Base.IsBound) {
-      fc->Base.DeletePending = EGL_TRUE;
-   }
-   else {
+   if (!_eglIsContextBound(&fc->Base))
       free(fc);
-   }
    return EGL_TRUE;
 }
 
 
 static EGLBoolean
-demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx)
 {
    /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
-   DemoSurface *readSurf = LookupDemoSurface(read);
-   DemoSurface *drawSurf = LookupDemoSurface(draw);
-   DemoContext *ctx = LookupDemoContext(context);
    EGLBoolean b;
 
-   b = _eglMakeCurrent(drv, dpy, draw, read, context);
+   b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx);
    if (!b)
       return EGL_FALSE;
 
@@ -351,33 +248,19 @@ demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea
 }
 
 
-static const char *
-demoQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
+static void
+demoUnload(_EGLDriver *drv)
 {
-   if (name == EGL_EXTENSIONS) {
-      return "EGL_MESA_screen_surface";
-   }
-   else {
-      return _eglQueryString(drv, dpy, name);
-   }
+   free(drv);
 }
 
 
-
-
-/*
- * Just to silence warning
- */
-extern _EGLDriver *
-_eglMain(NativeDisplayType dpy);
-
-
 /**
  * The bootstrap function.  Return a new DemoDriver object and
  * plug in API functions.
  */
 _EGLDriver *
-_eglMain(NativeDisplayType dpy)
+_eglMain(const char *args)
 {
    DemoDriver *demo;
 
@@ -389,15 +272,18 @@ _eglMain(NativeDisplayType dpy)
    /* First fill in the dispatch table with defaults */
    _eglInitDriverFallbacks(&demo->Base);
    /* then plug in our Demo-specific functions */
-   demo->Base.Initialize = demoInitialize;
-   demo->Base.Terminate = demoTerminate;
-   demo->Base.CreateContext = demoCreateContext;
-   demo->Base.MakeCurrent = demoMakeCurrent;
-   demo->Base.CreateWindowSurface = demoCreateWindowSurface;
-   demo->Base.CreatePixmapSurface = demoCreatePixmapSurface;
-   demo->Base.CreatePbufferSurface = demoCreatePbufferSurface;
-   demo->Base.DestroySurface = demoDestroySurface;
-   demo->Base.DestroyContext = demoDestroyContext;
-   demo->Base.QueryString = demoQueryString;
+   demo->Base.API.Initialize = demoInitialize;
+   demo->Base.API.Terminate = demoTerminate;
+   demo->Base.API.CreateContext = demoCreateContext;
+   demo->Base.API.MakeCurrent = demoMakeCurrent;
+   demo->Base.API.CreateWindowSurface = demoCreateWindowSurface;
+   demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface;
+   demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface;
+   demo->Base.API.DestroySurface = demoDestroySurface;
+   demo->Base.API.DestroyContext = demoDestroyContext;
+
+   demo->Base.Name = "egl/demo";
+   demo->Base.Unload = demoUnload;
+
    return &demo->Base;
 }