Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include "egldriver.h"
  26. #include "eglcurrent.h"
  27. #include "egllog.h"
  28.  
  29. #include "pipe/p_screen.h"
  30. #include "util/u_memory.h"
  31. #include "util/u_format.h"
  32. #include "util/u_string.h"
  33. #include "util/u_atomic.h"
  34.  
  35. #include "egl_g3d.h"
  36. #include "egl_g3d_api.h"
  37. #include "egl_g3d_st.h"
  38. #include "egl_g3d_loader.h"
  39. #include "native.h"
  40.  
  41. static void
  42. egl_g3d_invalid_surface(struct native_display *ndpy,
  43.                         struct native_surface *nsurf,
  44.                         unsigned int seq_num)
  45. {
  46.    /* XXX not thread safe? */
  47.    struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
  48.  
  49.    if (gsurf && gsurf->stfbi)
  50.       p_atomic_inc(&gsurf->stfbi->stamp);
  51. }
  52.  
  53. static struct pipe_screen *
  54. egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
  55. {
  56.    _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
  57.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  58.    return gdpy->loader->create_drm_screen(name, fd);
  59. }
  60.  
  61. static struct pipe_screen *
  62. egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
  63. {
  64.    _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
  65.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  66.    return gdpy->loader->create_sw_screen(ws);
  67. }
  68.  
  69. static struct pipe_resource *
  70. egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image)
  71. {
  72.    _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
  73.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  74.    struct st_egl_image img;
  75.    struct pipe_resource *resource = NULL;
  76.  
  77.    memset(&img, 0, sizeof(img));
  78.    if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img))
  79.       resource = img.texture;
  80.  
  81.    return resource;
  82. }
  83.  
  84. static const struct native_event_handler egl_g3d_native_event_handler = {
  85.    egl_g3d_invalid_surface,
  86.    egl_g3d_new_drm_screen,
  87.    egl_g3d_new_sw_screen,
  88.    egl_g3d_lookup_egl_image
  89. };
  90.  
  91. /**
  92.  * Get the native platform.
  93.  */
  94. static const struct native_platform *
  95. egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
  96. {
  97.    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
  98.  
  99.    if (!gdrv->platforms[plat]) {
  100.       const char *plat_name = NULL;
  101.       const struct native_platform *nplat = NULL;
  102.  
  103.       switch (plat) {
  104.       case _EGL_PLATFORM_WINDOWS:
  105.          plat_name = "Windows";
  106. #ifdef HAVE_GDI_BACKEND
  107.          nplat = native_get_gdi_platform(&egl_g3d_native_event_handler);
  108. #endif
  109.          break;
  110.       case _EGL_PLATFORM_X11:
  111.          plat_name = "X11";
  112. #ifdef HAVE_X11_BACKEND
  113.          nplat = native_get_x11_platform(&egl_g3d_native_event_handler);
  114. #endif
  115.          break;
  116.       case _EGL_PLATFORM_WAYLAND:
  117.          plat_name = "wayland";
  118. #ifdef HAVE_WAYLAND_BACKEND
  119.          nplat = native_get_wayland_platform(&egl_g3d_native_event_handler);
  120. #endif
  121.          break;
  122.       case _EGL_PLATFORM_DRM:
  123.          plat_name = "DRM";
  124. #ifdef HAVE_DRM_BACKEND
  125.          nplat = native_get_drm_platform(&egl_g3d_native_event_handler);
  126. #endif
  127.          break;
  128.       case _EGL_PLATFORM_FBDEV:
  129.          plat_name = "FBDEV";
  130. #ifdef HAVE_FBDEV_BACKEND
  131.          nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler);
  132. #endif
  133.          break;
  134.       case _EGL_PLATFORM_NULL:
  135.          plat_name = "NULL";
  136. #ifdef HAVE_NULL_BACKEND
  137.          nplat = native_get_null_platform(&egl_g3d_native_event_handler);
  138. #endif
  139.          break;
  140.       case _EGL_PLATFORM_ANDROID:
  141.          plat_name = "Android";
  142. #ifdef HAVE_ANDROID_BACKEND
  143.          nplat = native_get_android_platform(&egl_g3d_native_event_handler);
  144. #endif
  145.          break;
  146.       default:
  147.          break;
  148.       }
  149.  
  150.       if (!nplat)
  151.          _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
  152.  
  153.       gdrv->platforms[plat] = nplat;
  154.    }
  155.  
  156.    return gdrv->platforms[plat];
  157. }
  158.  
  159. #ifdef EGL_MESA_screen_surface
  160.  
  161. static void
  162. egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
  163. {
  164.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  165.    const struct native_connector **native_connectors;
  166.    EGLint num_connectors, i;
  167.  
  168.    native_connectors =
  169.       gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
  170.    if (!num_connectors) {
  171.       FREE(native_connectors);
  172.       return;
  173.    }
  174.  
  175.    for (i = 0; i < num_connectors; i++) {
  176.       const struct native_connector *nconn = native_connectors[i];
  177.       struct egl_g3d_screen *gscr;
  178.       const struct native_mode **native_modes;
  179.       EGLint num_modes, j;
  180.  
  181.       /* TODO support for hotplug */
  182.       native_modes =
  183.          gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
  184.       if (!num_modes) {
  185.          FREE(native_modes);
  186.          continue;
  187.       }
  188.  
  189.       gscr = CALLOC_STRUCT(egl_g3d_screen);
  190.       if (!gscr) {
  191.          FREE(native_modes);
  192.          continue;
  193.       }
  194.  
  195.       _eglInitScreen(&gscr->base, dpy, num_modes);
  196.       for (j = 0; j < gscr->base.NumModes; j++) {
  197.          const struct native_mode *nmode = native_modes[j];
  198.          _EGLMode *mode = &gscr->base.Modes[j];
  199.  
  200.          mode->Width = nmode->width;
  201.          mode->Height = nmode->height;
  202.          mode->RefreshRate = nmode->refresh_rate;
  203.          mode->Optimal = EGL_FALSE;
  204.          mode->Interlaced = EGL_FALSE;
  205.          /* no need to strdup() */
  206.          mode->Name = nmode->desc;
  207.       }
  208.  
  209.       gscr->native = nconn;
  210.       gscr->native_modes = native_modes;
  211.  
  212.       _eglLinkScreen(&gscr->base);
  213.    }
  214.  
  215.    FREE(native_connectors);
  216. }
  217.  
  218. #endif /* EGL_MESA_screen_surface */
  219.  
  220. /**
  221.  * Initialize and validate the EGL config attributes.
  222.  */
  223. static EGLBoolean
  224. init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
  225.                        EGLint api_mask, enum pipe_format depth_stencil_format,
  226.                        EGLint preserve_buffer, EGLint max_swap_interval,
  227.                        EGLBoolean pre_alpha)
  228. {
  229.    uint rgba[4], depth_stencil[2], buffer_size;
  230.    EGLint surface_type;
  231.    EGLint i;
  232.  
  233.    /* get the color and depth/stencil component sizes */
  234.    assert(nconf->color_format != PIPE_FORMAT_NONE);
  235.    buffer_size = 0;
  236.    for (i = 0; i < 4; i++) {
  237.       rgba[i] = util_format_get_component_bits(nconf->color_format,
  238.             UTIL_FORMAT_COLORSPACE_RGB, i);
  239.       buffer_size += rgba[i];
  240.    }
  241.    for (i = 0; i < 2; i++) {
  242.       if (depth_stencil_format != PIPE_FORMAT_NONE) {
  243.          depth_stencil[i] =
  244.             util_format_get_component_bits(depth_stencil_format,
  245.                UTIL_FORMAT_COLORSPACE_ZS, i);
  246.       }
  247.       else {
  248.          depth_stencil[i] = 0;
  249.       }
  250.    }
  251.  
  252.    surface_type = 0x0;
  253.    /* pixmap surfaces should be EGL_SINGLE_BUFFER */
  254.    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) {
  255.       if (nconf->pixmap_bit)
  256.          surface_type |= EGL_PIXMAP_BIT;
  257.    }
  258.    /* the others surfaces should be EGL_BACK_BUFFER (or settable) */
  259.    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) {
  260.       if (nconf->window_bit)
  261.          surface_type |= EGL_WINDOW_BIT;
  262. #ifdef EGL_MESA_screen_surface
  263.       if (nconf->scanout_bit)
  264.          surface_type |= EGL_SCREEN_BIT_MESA;
  265. #endif
  266.       surface_type |= EGL_PBUFFER_BIT;
  267.    }
  268.  
  269.    if (preserve_buffer)
  270.       surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
  271.  
  272.    if (pre_alpha && rgba[3]) {
  273.       surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
  274.       /* st/vega does not support premultiplied alpha yet */
  275.       api_mask &= ~EGL_OPENVG_BIT;
  276.    }
  277.  
  278.    conf->Conformant = api_mask;
  279.    conf->RenderableType = api_mask;
  280.  
  281.    conf->RedSize = rgba[0];
  282.    conf->GreenSize = rgba[1];
  283.    conf->BlueSize = rgba[2];
  284.    conf->AlphaSize = rgba[3];
  285.    conf->BufferSize = buffer_size;
  286.  
  287.    conf->DepthSize = depth_stencil[0];
  288.    conf->StencilSize = depth_stencil[1];
  289.  
  290.    /* st/vega will allocate the mask on demand */
  291.    if (api_mask & EGL_OPENVG_BIT)
  292.       conf->AlphaMaskSize = 8;
  293.  
  294.    conf->SurfaceType = surface_type;
  295.  
  296.    conf->NativeRenderable = EGL_TRUE;
  297.    if (surface_type & EGL_WINDOW_BIT) {
  298.       conf->NativeVisualID = nconf->native_visual_id;
  299.       conf->NativeVisualType = nconf->native_visual_type;
  300.    }
  301.  
  302.    if (surface_type & EGL_PBUFFER_BIT) {
  303.       conf->BindToTextureRGB = EGL_TRUE;
  304.       if (rgba[3])
  305.          conf->BindToTextureRGBA = EGL_TRUE;
  306.  
  307.       conf->MaxPbufferWidth = 4096;
  308.       conf->MaxPbufferHeight = 4096;
  309.       conf->MaxPbufferPixels = 4096 * 4096;
  310.    }
  311.  
  312.    conf->Level = nconf->level;
  313.  
  314.    if (nconf->transparent_rgb) {
  315.       conf->TransparentType = EGL_TRANSPARENT_RGB;
  316.       conf->TransparentRedValue = nconf->transparent_rgb_values[0];
  317.       conf->TransparentGreenValue = nconf->transparent_rgb_values[1];
  318.       conf->TransparentBlueValue = nconf->transparent_rgb_values[2];
  319.    }
  320.  
  321.    conf->MinSwapInterval = 0;
  322.    conf->MaxSwapInterval = max_swap_interval;
  323.  
  324.    return _eglValidateConfig(conf, EGL_FALSE);
  325. }
  326.  
  327. /**
  328.  * Initialize an EGL config from the native config.
  329.  */
  330. static EGLBoolean
  331. egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
  332.                     _EGLConfig *conf, const struct native_config *nconf,
  333.                     enum pipe_format depth_stencil_format,
  334.                     int preserve_buffer, int max_swap_interval,
  335.                     int pre_alpha)
  336. {
  337.    struct egl_g3d_config *gconf = egl_g3d_config(conf);
  338.    EGLint buffer_mask;
  339.    EGLBoolean valid;
  340.  
  341.    buffer_mask = 0x0;
  342.    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT))
  343.       buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
  344.    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
  345.       buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
  346.    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_RIGHT))
  347.       buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
  348.    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_RIGHT))
  349.       buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
  350.  
  351.    gconf->stvis.buffer_mask = buffer_mask;
  352.    gconf->stvis.color_format = nconf->color_format;
  353.    gconf->stvis.depth_stencil_format = depth_stencil_format;
  354.    gconf->stvis.accum_format = PIPE_FORMAT_NONE;
  355.    gconf->stvis.samples = 0;
  356.  
  357.    /* will be overridden per surface */
  358.    gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
  359.       ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
  360.  
  361.    valid = init_config_attributes(&gconf->base,
  362.          nconf, dpy->ClientAPIs, depth_stencil_format,
  363.          preserve_buffer, max_swap_interval, pre_alpha);
  364.    if (!valid) {
  365.       _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
  366.       return EGL_FALSE;
  367.    }
  368.  
  369.    gconf->native = nconf;
  370.  
  371.    return EGL_TRUE;
  372. }
  373.  
  374. /**
  375.  * Get all interested depth/stencil formats of a display.
  376.  */
  377. static EGLint
  378. egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
  379.                                    enum pipe_format formats[8])
  380. {
  381.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  382.    struct pipe_screen *screen = gdpy->native->screen;
  383.    const EGLint candidates[] = {
  384.       1, PIPE_FORMAT_Z16_UNORM,
  385.       1, PIPE_FORMAT_Z32_UNORM,
  386.       2, PIPE_FORMAT_Z24_UNORM_S8_UINT, PIPE_FORMAT_S8_UINT_Z24_UNORM,
  387.       2, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM,
  388.       0
  389.    };
  390.    const EGLint *fmt = candidates;
  391.    EGLint count;
  392.  
  393.    count = 0;
  394.    formats[count++] = PIPE_FORMAT_NONE;
  395.  
  396.    while (*fmt) {
  397.       EGLint i, n = *fmt++;
  398.  
  399.       /* pick the first supported format */
  400.       for (i = 0; i < n; i++) {
  401.          if (screen->is_format_supported(screen, fmt[i],
  402.                   PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) {
  403.             formats[count++] = fmt[i];
  404.             break;
  405.          }
  406.       }
  407.  
  408.       fmt += n;
  409.    }
  410.  
  411.    return count;
  412. }
  413.  
  414. /**
  415.  * Add configs to display and return the next config ID.
  416.  */
  417. static EGLint
  418. egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
  419. {
  420.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  421.    const struct native_config **native_configs;
  422.    enum pipe_format depth_stencil_formats[8];
  423.    int num_formats, num_configs, i, j;
  424.    int preserve_buffer, max_swap_interval, premultiplied_alpha;
  425.  
  426.    native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
  427.    if (!num_configs) {
  428.       FREE(native_configs);
  429.       return id;
  430.    }
  431.  
  432.    preserve_buffer =
  433.       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER);
  434.    max_swap_interval =
  435.       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL);
  436.    premultiplied_alpha =
  437.       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA);
  438.  
  439.    num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
  440.          depth_stencil_formats);
  441.  
  442.    for (i = 0; i < num_configs; i++) {
  443.       for (j = 0; j < num_formats; j++) {
  444.          struct egl_g3d_config *gconf;
  445.  
  446.          gconf = CALLOC_STRUCT(egl_g3d_config);
  447.          if (gconf) {
  448.             _eglInitConfig(&gconf->base, dpy, id);
  449.             if (!egl_g3d_init_config(drv, dpy, &gconf->base,
  450.                      native_configs[i], depth_stencil_formats[j],
  451.                      preserve_buffer, max_swap_interval,
  452.                      premultiplied_alpha)) {
  453.                FREE(gconf);
  454.                break;
  455.             }
  456.  
  457.             _eglLinkConfig(&gconf->base);
  458.             id++;
  459.          }
  460.       }
  461.    }
  462.  
  463.    FREE(native_configs);
  464.    return id;
  465. }
  466.  
  467. static void
  468. egl_g3d_free_config(void *conf)
  469. {
  470.    struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf);
  471.    FREE(gconf);
  472. }
  473.  
  474. static void
  475. egl_g3d_free_screen(void *scr)
  476. {
  477. #ifdef EGL_MESA_screen_surface
  478.    struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr);
  479.    FREE(gscr->native_modes);
  480.    FREE(gscr);
  481. #endif
  482. }
  483.  
  484. static EGLBoolean
  485. egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
  486. {
  487.    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
  488.  
  489.    _eglReleaseDisplayResources(drv, dpy);
  490.  
  491.    if (dpy->Configs) {
  492.       _eglDestroyArray(dpy->Configs, egl_g3d_free_config);
  493.       dpy->Configs = NULL;
  494.    }
  495.    if (dpy->Screens) {
  496.       _eglDestroyArray(dpy->Screens, egl_g3d_free_screen);
  497.       dpy->Screens = NULL;
  498.    }
  499.  
  500.    _eglCleanupDisplay(dpy);
  501.  
  502.    if (gdpy->smapi)
  503.       egl_g3d_destroy_st_manager(gdpy->smapi);
  504.  
  505.    if (gdpy->native)
  506.       gdpy->native->destroy(gdpy->native);
  507.  
  508.    FREE(gdpy);
  509.    dpy->DriverData = NULL;
  510.  
  511.    return EGL_TRUE;
  512. }
  513.  
  514. static EGLBoolean
  515. egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
  516. {
  517.    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
  518.    struct egl_g3d_display *gdpy;
  519.    const struct native_platform *nplat;
  520.  
  521.    nplat = egl_g3d_get_platform(drv, dpy->Platform);
  522.    if (!nplat)
  523.       return EGL_FALSE;
  524.  
  525.    if (dpy->Options.TestOnly)
  526.       return EGL_TRUE;
  527.  
  528.    gdpy = CALLOC_STRUCT(egl_g3d_display);
  529.    if (!gdpy) {
  530.       _eglError(EGL_BAD_ALLOC, "eglInitialize");
  531.       goto fail;
  532.    }
  533.    gdpy->loader = gdrv->loader;
  534.    dpy->DriverData = gdpy;
  535.  
  536.    _eglLog(_EGL_INFO, "use %s for display %p",
  537.          nplat->name, dpy->PlatformDisplay);
  538.    gdpy->native =
  539.       nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback);
  540.    if (!gdpy->native) {
  541.       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
  542.       goto fail;
  543.    }
  544.    gdpy->native->user_data = (void *) dpy;
  545.    if (!gdpy->native->init_screen(gdpy->native)) {
  546.       _eglError(EGL_NOT_INITIALIZED,
  547.             "eglInitialize(failed to initialize screen)");
  548.       goto fail;
  549.    }
  550.  
  551.    if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
  552.       dpy->ClientAPIs |= EGL_OPENGL_BIT;
  553.    if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK)
  554.       dpy->ClientAPIs |= EGL_OPENGL_ES_BIT;
  555.    if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK)
  556.       dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT;
  557.    if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK)
  558.       dpy->ClientAPIs |= EGL_OPENVG_BIT;
  559.  
  560.    gdpy->smapi = egl_g3d_create_st_manager(dpy);
  561.    if (!gdpy->smapi) {
  562.       _eglError(EGL_NOT_INITIALIZED,
  563.             "eglInitialize(failed to create st manager)");
  564.       goto fail;
  565.    }
  566.  
  567. #ifdef EGL_MESA_screen_surface
  568.    /* enable MESA_screen_surface before adding (and validating) configs */
  569.    if (gdpy->native->modeset) {
  570.       dpy->Extensions.MESA_screen_surface = EGL_TRUE;
  571.       egl_g3d_add_screens(drv, dpy);
  572.    }
  573. #endif
  574.  
  575.    dpy->Extensions.KHR_image_base = EGL_TRUE;
  576.    if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
  577.       dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
  578.  
  579.    dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
  580.    dpy->Extensions.KHR_fence_sync = EGL_TRUE;
  581.  
  582.    dpy->Extensions.KHR_surfaceless_context = EGL_TRUE;
  583.  
  584.    if (dpy->Platform == _EGL_PLATFORM_DRM) {
  585.       dpy->Extensions.MESA_drm_display = EGL_TRUE;
  586.       if (gdpy->native->buffer)
  587.          dpy->Extensions.MESA_drm_image = EGL_TRUE;
  588.    }
  589.  
  590.    if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer)
  591.       dpy->Extensions.MESA_drm_image = EGL_TRUE;
  592.  
  593. #ifdef EGL_ANDROID_image_native_buffer
  594.    if (dpy->Platform == _EGL_PLATFORM_ANDROID && gdpy->native->buffer)
  595.       dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
  596. #endif
  597.  
  598. #ifdef EGL_WL_bind_wayland_display
  599.    if (gdpy->native->wayland_bufmgr)
  600.       dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
  601. #endif
  602.  
  603.    if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESENT_REGION) &&
  604.        gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER)) {
  605. #ifdef EGL_NOK_swap_region
  606.       dpy->Extensions.NOK_swap_region = EGL_TRUE;
  607. #endif
  608.       dpy->Extensions.NV_post_sub_buffer = EGL_TRUE;
  609.    }
  610.  
  611.    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
  612.       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
  613.       goto fail;
  614.    }
  615.  
  616.    dpy->VersionMajor = 1;
  617.    dpy->VersionMinor = 4;
  618.  
  619.    return EGL_TRUE;
  620.  
  621. fail:
  622.    if (gdpy)
  623.       egl_g3d_terminate(drv, dpy);
  624.    return EGL_FALSE;
  625. }
  626.  
  627. static _EGLProc
  628. egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
  629. {
  630.    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
  631.    struct st_api *stapi = NULL;
  632.  
  633.    if (procname && procname[0] == 'v' && procname[1] == 'g')
  634.       stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
  635.    else if (procname && procname[0] == 'g' && procname[1] == 'l')
  636.       stapi = gdrv->loader->get_st_api(ST_API_OPENGL);
  637.  
  638.    return (_EGLProc) ((stapi) ?
  639.          stapi->get_proc_address(stapi, procname) : NULL);
  640. }
  641.  
  642. _EGLDriver *
  643. egl_g3d_create_driver(const struct egl_g3d_loader *loader)
  644. {
  645.    struct egl_g3d_driver *gdrv;
  646.  
  647.    gdrv = CALLOC_STRUCT(egl_g3d_driver);
  648.    if (!gdrv)
  649.       return NULL;
  650.  
  651.    gdrv->loader = loader;
  652.  
  653.    egl_g3d_init_driver_api(&gdrv->base);
  654.    gdrv->base.API.Initialize = egl_g3d_initialize;
  655.    gdrv->base.API.Terminate = egl_g3d_terminate;
  656.    gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
  657.  
  658.    /* to be filled by the caller */
  659.    gdrv->base.Name = NULL;
  660.    gdrv->base.Unload = NULL;
  661.  
  662.    return &gdrv->base;
  663. }
  664.  
  665. void
  666. egl_g3d_destroy_driver(_EGLDriver *drv)
  667. {
  668.    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
  669.    FREE(gdrv);
  670. }
  671.