Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2010 LunarG Inc.
  5.  * Copyright (C) 2011 VMware Inc. All rights reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23.  * DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Chia-I Wu <olv@lunarg.com>
  27.  *    Thomas Hellstrom <thellstrom@vmware.com>
  28.  */
  29.  
  30. #include "util/u_memory.h"
  31. #include "util/u_inlines.h"
  32. #include "egllog.h"
  33.  
  34. #include "native_drm.h"
  35.  
  36. static boolean
  37. drm_surface_validate(struct native_surface *nsurf, uint attachment_mask,
  38.                      unsigned int *seq_num, struct pipe_resource **textures,
  39.                      int *width, int *height)
  40. {
  41.    struct drm_surface *drmsurf = drm_surface(nsurf);
  42.  
  43.    if (!resource_surface_add_resources(drmsurf->rsurf, attachment_mask))
  44.       return FALSE;
  45.    if (textures)
  46.       resource_surface_get_resources(drmsurf->rsurf, textures, attachment_mask);
  47.  
  48.    if (seq_num)
  49.       *seq_num = drmsurf->sequence_number;
  50.    if (width)
  51.       *width = drmsurf->width;
  52.    if (height)
  53.       *height = drmsurf->height;
  54.  
  55.    return TRUE;
  56. }
  57.  
  58. /**
  59.  * Add textures as DRM framebuffers.
  60.  */
  61. static boolean
  62. drm_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
  63. {
  64. #if 0
  65.    struct drm_surface *drmsurf = drm_surface(nsurf);
  66.    struct drm_display *drmdpy = drmsurf->drmdpy;
  67.    int num_framebuffers = (need_back) ? 2 : 1;
  68.    int i, err;
  69.  
  70.    for (i = 0; i < num_framebuffers; i++) {
  71.       struct drm_framebuffer *fb;
  72.       enum native_attachment natt;
  73.       struct winsys_handle whandle;
  74.       uint block_bits;
  75.  
  76.       if (i == 0) {
  77.          fb = &drmsurf->front_fb;
  78.          natt = NATIVE_ATTACHMENT_FRONT_LEFT;
  79.       }
  80.       else {
  81.          fb = &drmsurf->back_fb;
  82.          natt = NATIVE_ATTACHMENT_BACK_LEFT;
  83.       }
  84.  
  85.       if (!fb->texture) {
  86.          /* make sure the texture has been allocated */
  87.          resource_surface_add_resources(drmsurf->rsurf, 1 << natt);
  88.          fb->texture =
  89.             resource_surface_get_single_resource(drmsurf->rsurf, natt);
  90.          if (!fb->texture)
  91.             return FALSE;
  92.       }
  93.  
  94.       /* already initialized */
  95.       if (fb->buffer_id)
  96.          continue;
  97.  
  98.       /* TODO detect the real value */
  99.       fb->is_passive = TRUE;
  100.  
  101.       memset(&whandle, 0, sizeof(whandle));
  102.       whandle.type = DRM_API_HANDLE_TYPE_KMS;
  103.  
  104.       if (!drmdpy->base.screen->resource_get_handle(drmdpy->base.screen,
  105.                fb->texture, &whandle))
  106.          return FALSE;
  107.  
  108.       block_bits = util_format_get_blocksizebits(drmsurf->color_format);
  109.       err = drmModeAddFB(drmdpy->fd, drmsurf->width, drmsurf->height,
  110.             block_bits, block_bits, whandle.stride, whandle.handle,
  111.             &fb->buffer_id);
  112.       if (err) {
  113.          fb->buffer_id = 0;
  114.          return FALSE;
  115.       }
  116.    }
  117.  
  118.    return TRUE;
  119. #endif
  120.     return FALSE;
  121. }
  122.  
  123. static boolean
  124. drm_surface_flush_frontbuffer(struct native_surface *nsurf)
  125. {
  126. #ifdef DRM_MODE_FEATURE_DIRTYFB
  127. #endif
  128.  
  129.    return TRUE;
  130. }
  131.  
  132. static boolean
  133. drm_surface_copy_swap(struct native_surface *nsurf)
  134. {
  135.    struct drm_surface *drmsurf = drm_surface(nsurf);
  136.    struct drm_display *drmdpy = drmsurf->drmdpy;
  137.  
  138.    (void) resource_surface_throttle(drmsurf->rsurf);
  139.    if (!resource_surface_copy_swap(drmsurf->rsurf, &drmdpy->base))
  140.       return FALSE;
  141.  
  142.    (void) resource_surface_flush(drmsurf->rsurf, &drmdpy->base);
  143.    if (!drm_surface_flush_frontbuffer(nsurf))
  144.       return FALSE;
  145.  
  146.    drmsurf->sequence_number++;
  147.  
  148.    return TRUE;
  149. }
  150.  
  151. static boolean
  152. drm_surface_swap_buffers(struct native_surface *nsurf)
  153. {
  154. #if 0
  155.    struct drm_surface *drmsurf = drm_surface(nsurf);
  156.    struct drm_crtc *drmcrtc = &drmsurf->current_crtc;
  157.    struct drm_display *drmdpy = drmsurf->drmdpy;
  158.    struct drm_framebuffer tmp_fb;
  159.    int err;
  160.  
  161.    if (!drmsurf->have_pageflip)
  162.       return drm_surface_copy_swap(nsurf);
  163.  
  164.    if (!drmsurf->back_fb.buffer_id) {
  165.       if (!drm_surface_init_framebuffers(&drmsurf->base, TRUE))
  166.          return FALSE;
  167.    }
  168.  
  169.    if (drmsurf->is_shown && drmcrtc->crtc) {
  170.       err = drmModePageFlip(drmdpy->fd, drmcrtc->crtc->crtc_id,
  171.                             drmsurf->back_fb.buffer_id, 0, NULL);
  172.       if (err) {
  173.          drmsurf->have_pageflip = FALSE;
  174.          return drm_surface_copy_swap(nsurf);
  175.       }
  176.    }
  177.  
  178.    /* swap the buffers */
  179.    tmp_fb = drmsurf->front_fb;
  180.    drmsurf->front_fb = drmsurf->back_fb;
  181.    drmsurf->back_fb = tmp_fb;
  182.  
  183.    resource_surface_swap_buffers(drmsurf->rsurf,
  184.          NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
  185.    /* the front/back textures are swapped */
  186.    drmsurf->sequence_number++;
  187.    drmdpy->event_handler->invalid_surface(&drmdpy->base,
  188.          &drmsurf->base, drmsurf->sequence_number);
  189. #endif
  190.  
  191.    return TRUE;
  192. }
  193.  
  194. static boolean
  195. drm_surface_present(struct native_surface *nsurf,
  196.                     const struct native_present_control *ctrl)
  197. {
  198.    boolean ret;
  199.  
  200.    if (ctrl->swap_interval)
  201.       return FALSE;
  202.  
  203.    switch (ctrl->natt) {
  204.    case NATIVE_ATTACHMENT_FRONT_LEFT:
  205.       ret = drm_surface_flush_frontbuffer(nsurf);
  206.       break;
  207.    case NATIVE_ATTACHMENT_BACK_LEFT:
  208.       if (ctrl->preserve)
  209.          ret = drm_surface_copy_swap(nsurf);
  210.       else
  211.          ret = drm_surface_swap_buffers(nsurf);
  212.       break;
  213.    default:
  214.       ret = FALSE;
  215.       break;
  216.    }
  217.  
  218.    return ret;
  219. }
  220.  
  221. static void
  222. drm_surface_wait(struct native_surface *nsurf)
  223. {
  224.    struct drm_surface *drmsurf = drm_surface(nsurf);
  225.  
  226.    resource_surface_wait(drmsurf->rsurf);
  227. }
  228.  
  229. static void
  230. drm_surface_destroy(struct native_surface *nsurf)
  231. {
  232. #if 0
  233.    struct drm_surface *drmsurf = drm_surface(nsurf);
  234.  
  235.    resource_surface_wait(drmsurf->rsurf);
  236.    if (drmsurf->current_crtc.crtc)
  237.          drmModeFreeCrtc(drmsurf->current_crtc.crtc);
  238.  
  239.    if (drmsurf->front_fb.buffer_id)
  240.       drmModeRmFB(drmsurf->drmdpy->fd, drmsurf->front_fb.buffer_id);
  241.    pipe_resource_reference(&drmsurf->front_fb.texture, NULL);
  242.  
  243.    if (drmsurf->back_fb.buffer_id)
  244.       drmModeRmFB(drmsurf->drmdpy->fd, drmsurf->back_fb.buffer_id);
  245.    pipe_resource_reference(&drmsurf->back_fb.texture, NULL);
  246.  
  247.    resource_surface_destroy(drmsurf->rsurf);
  248.    FREE(drmsurf);
  249. #endif
  250. }
  251.  
  252. static struct drm_surface *
  253. drm_display_create_surface(struct native_display *ndpy,
  254.                            const struct native_config *nconf,
  255.                            uint width, uint height)
  256. {
  257.    struct drm_display *drmdpy = drm_display(ndpy);
  258.    struct drm_config *drmconf = drm_config(nconf);
  259.    struct drm_surface *drmsurf;
  260.  
  261.    drmsurf = CALLOC_STRUCT(drm_surface);
  262.    if (!drmsurf)
  263.       return NULL;
  264.  
  265.    drmsurf->drmdpy = drmdpy;
  266.    drmsurf->color_format = drmconf->base.color_format;
  267.    drmsurf->width = width;
  268.    drmsurf->height = height;
  269.    drmsurf->have_pageflip = TRUE;
  270.  
  271.    drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
  272.          drmsurf->color_format,
  273.          PIPE_BIND_RENDER_TARGET |
  274.          PIPE_BIND_SAMPLER_VIEW |
  275.          PIPE_BIND_DISPLAY_TARGET |
  276.          PIPE_BIND_SCANOUT);
  277.    if (!drmsurf->rsurf) {
  278.       FREE(drmsurf);
  279.       return NULL;
  280.    }
  281.  
  282.    resource_surface_set_size(drmsurf->rsurf, drmsurf->width, drmsurf->height);
  283.  
  284.    drmsurf->base.destroy = drm_surface_destroy;
  285.    drmsurf->base.present = drm_surface_present;
  286.    drmsurf->base.validate = drm_surface_validate;
  287.    drmsurf->base.wait = drm_surface_wait;
  288.  
  289.    return drmsurf;
  290. }
  291.  
  292. struct native_surface *
  293. drm_display_create_surface_from_resource(struct native_display *ndpy,
  294.                                          struct pipe_resource *resource)
  295. {
  296.    struct drm_display *drmdpy = drm_display(ndpy);
  297.    struct drm_surface *drmsurf;
  298.    enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
  299.  
  300.    drmsurf = CALLOC_STRUCT(drm_surface);
  301.    if (!drmsurf)
  302.       return NULL;
  303.  
  304.    drmsurf->drmdpy = drmdpy;
  305.    drmsurf->color_format = resource->format;
  306.    drmsurf->width = resource->width0;
  307.    drmsurf->height = resource->height0;
  308.    drmsurf->have_pageflip = FALSE;
  309.  
  310.    drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
  311.          drmsurf->color_format,
  312.          PIPE_BIND_RENDER_TARGET |
  313.          PIPE_BIND_SAMPLER_VIEW |
  314.          PIPE_BIND_DISPLAY_TARGET |
  315.          PIPE_BIND_SCANOUT);
  316.  
  317.    resource_surface_import_resource(drmsurf->rsurf, natt, resource);
  318.  
  319.    drmsurf->base.destroy = drm_surface_destroy;
  320.    drmsurf->base.present = drm_surface_present;
  321.    drmsurf->base.validate = drm_surface_validate;
  322.    drmsurf->base.wait = drm_surface_wait;
  323.  
  324.    return &drmsurf->base;
  325. }
  326.  
  327.  
  328. /**
  329.  * Choose a CRTC that supports all given connectors.
  330.  */
  331. static uint32_t
  332. drm_display_choose_crtc(struct native_display *ndpy,
  333.                         uint32_t *connectors, int num_connectors)
  334. {
  335.    struct drm_display *drmdpy = drm_display(ndpy);
  336.    int idx;
  337. #if 0
  338.    for (idx = 0; idx < drmdpy->resources->count_crtcs; idx++) {
  339.       boolean found_crtc = TRUE;
  340.       int i, j;
  341.  
  342.       for (i = 0; i < num_connectors; i++) {
  343.          drmModeConnectorPtr connector;
  344.          int encoder_idx = -1;
  345.  
  346.          connector = drmModeGetConnector(drmdpy->fd, connectors[i]);
  347.          if (!connector) {
  348.             found_crtc = FALSE;
  349.             break;
  350.          }
  351.  
  352.          /* find an encoder the CRTC supports */
  353.          for (j = 0; j < connector->count_encoders; j++) {
  354.             drmModeEncoderPtr encoder =
  355.                drmModeGetEncoder(drmdpy->fd, connector->encoders[j]);
  356.             if (encoder->possible_crtcs & (1 << idx)) {
  357.                encoder_idx = j;
  358.                break;
  359.             }
  360.             drmModeFreeEncoder(encoder);
  361.          }
  362.  
  363.          drmModeFreeConnector(connector);
  364.          if (encoder_idx < 0) {
  365.             found_crtc = FALSE;
  366.             break;
  367.          }
  368.       }
  369.  
  370.       if (found_crtc)
  371.          break;
  372.    }
  373.  
  374.    if (idx >= drmdpy->resources->count_crtcs) {
  375.       _eglLog(_EGL_WARNING,
  376.             "failed to find a CRTC that supports the given %d connectors",
  377.             num_connectors);
  378.       return 0;
  379.    }
  380.  
  381.    return drmdpy->resources->crtcs[idx];
  382. #endif
  383.     return 0;
  384. }
  385.  
  386. /**
  387.  * Remember the original CRTC status and set the CRTC
  388.  */
  389. static boolean
  390. drm_display_set_crtc(struct native_display *ndpy, int crtc_idx,
  391.                      uint32_t buffer_id, uint32_t x, uint32_t y,
  392.                      uint32_t *connectors, int num_connectors,
  393.                      drmModeModeInfoPtr mode)
  394. {
  395.    struct drm_display *drmdpy = drm_display(ndpy);
  396.    struct drm_crtc *drmcrtc = &drmdpy->saved_crtcs[crtc_idx];
  397.    uint32_t crtc_id;
  398.    int err;
  399. #if 0
  400.    if (drmcrtc->crtc) {
  401.       crtc_id = drmcrtc->crtc->crtc_id;
  402.    }
  403.    else {
  404.       int count = 0, i;
  405.  
  406.       /*
  407.        * Choose the CRTC once.  It could be more dynamic, but let's keep it
  408.        * simple for now.
  409.        */
  410.       crtc_id = drm_display_choose_crtc(&drmdpy->base,
  411.             connectors, num_connectors);
  412.  
  413.       /* save the original CRTC status */
  414.       drmcrtc->crtc = drmModeGetCrtc(drmdpy->fd, crtc_id);
  415.       if (!drmcrtc->crtc)
  416.          return FALSE;
  417.  
  418.       for (i = 0; i < drmdpy->num_connectors; i++) {
  419.          struct drm_connector *drmconn = &drmdpy->connectors[i];
  420.          drmModeConnectorPtr connector = drmconn->connector;
  421.          drmModeEncoderPtr encoder;
  422.  
  423.          encoder = drmModeGetEncoder(drmdpy->fd, connector->encoder_id);
  424.          if (encoder) {
  425.             if (encoder->crtc_id == crtc_id) {
  426.                drmcrtc->connectors[count++] = connector->connector_id;
  427.                if (count >= Elements(drmcrtc->connectors))
  428.                   break;
  429.             }
  430.             drmModeFreeEncoder(encoder);
  431.          }
  432.       }
  433.  
  434.       drmcrtc->num_connectors = count;
  435.    }
  436.  
  437.    err = drmModeSetCrtc(drmdpy->fd, crtc_id, buffer_id, x, y,
  438.          connectors, num_connectors, mode);
  439.    if (err) {
  440.       drmModeFreeCrtc(drmcrtc->crtc);
  441.       drmcrtc->crtc = NULL;
  442.       drmcrtc->num_connectors = 0;
  443.  
  444.       return FALSE;
  445.    }
  446.  
  447.    return TRUE;
  448. #endif
  449.    return FALSE;
  450.  
  451. }
  452.  
  453. static boolean
  454. drm_display_program(struct native_display *ndpy, int crtc_idx,
  455.                     struct native_surface *nsurf, uint x, uint y,
  456.                     const struct native_connector **nconns, int num_nconns,
  457.                     const struct native_mode *nmode)
  458. {
  459. #if 0
  460.    struct drm_display *drmdpy = drm_display(ndpy);
  461.    struct drm_surface *drmsurf = drm_surface(nsurf);
  462.    const struct drm_mode *drmmode = drm_mode(nmode);
  463.    uint32_t connector_ids[32];
  464.    uint32_t buffer_id;
  465.    drmModeModeInfo mode_tmp, *mode;
  466.    int i;
  467.  
  468.    if (num_nconns > Elements(connector_ids)) {
  469.       _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns);
  470.       num_nconns = Elements(connector_ids);
  471.    }
  472.  
  473.    if (drmsurf) {
  474.       if (!drm_surface_init_framebuffers(&drmsurf->base, FALSE))
  475.          return FALSE;
  476.  
  477.       buffer_id = drmsurf->front_fb.buffer_id;
  478.       /* the mode argument of drmModeSetCrtc is not constified */
  479.       mode_tmp = drmmode->mode;
  480.       mode = &mode_tmp;
  481.    }
  482.    else {
  483.       /* disable the CRTC */
  484.       buffer_id = 0;
  485.       mode = NULL;
  486.       num_nconns = 0;
  487.    }
  488.  
  489.    for (i = 0; i < num_nconns; i++) {
  490.       struct drm_connector *drmconn = drm_connector(nconns[i]);
  491.       connector_ids[i] = drmconn->connector->connector_id;
  492.    }
  493.  
  494.    if (!drm_display_set_crtc(&drmdpy->base, crtc_idx, buffer_id, x, y,
  495.             connector_ids, num_nconns, mode)) {
  496.       _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx);
  497.  
  498.       return FALSE;
  499.    }
  500.  
  501.    if (drmdpy->shown_surfaces[crtc_idx])
  502.       drmdpy->shown_surfaces[crtc_idx]->is_shown = FALSE;
  503.    drmdpy->shown_surfaces[crtc_idx] = drmsurf;
  504.  
  505.    /* remember the settings for buffer swapping */
  506.    if (drmsurf) {
  507.       uint32_t crtc_id = drmdpy->saved_crtcs[crtc_idx].crtc->crtc_id;
  508.       struct drm_crtc *drmcrtc = &drmsurf->current_crtc;
  509.  
  510.       if (drmcrtc->crtc)
  511.          drmModeFreeCrtc(drmcrtc->crtc);
  512.       drmcrtc->crtc = drmModeGetCrtc(drmdpy->fd, crtc_id);
  513.  
  514.       assert(num_nconns < Elements(drmcrtc->connectors));
  515.       memcpy(drmcrtc->connectors, connector_ids,
  516.             sizeof(*connector_ids) * num_nconns);
  517.       drmcrtc->num_connectors = num_nconns;
  518.  
  519.       drmsurf->is_shown = TRUE;
  520.    }
  521.  
  522.    return TRUE;
  523. #endif
  524.    return FALSE;
  525.  
  526. }
  527.  
  528. static const struct native_mode **
  529. drm_display_get_modes(struct native_display *ndpy,
  530.                       const struct native_connector *nconn,
  531.                       int *num_modes)
  532. {
  533. #if 0
  534.    struct drm_display *drmdpy = drm_display(ndpy);
  535.    struct drm_connector *drmconn = drm_connector(nconn);
  536.    const struct native_mode **nmodes_return;
  537.    int count, i;
  538.  
  539.    /* delete old data */
  540.    if (drmconn->connector) {
  541.       drmModeFreeConnector(drmconn->connector);
  542.       FREE(drmconn->drm_modes);
  543.  
  544.       drmconn->connector = NULL;
  545.       drmconn->drm_modes = NULL;
  546.       drmconn->num_modes = 0;
  547.    }
  548.  
  549.    /* detect again */
  550.    drmconn->connector = drmModeGetConnector(drmdpy->fd, drmconn->connector_id);
  551.    if (!drmconn->connector)
  552.       return NULL;
  553.  
  554.    count = drmconn->connector->count_modes;
  555.    drmconn->drm_modes = CALLOC(count, sizeof(*drmconn->drm_modes));
  556.    if (!drmconn->drm_modes) {
  557.       drmModeFreeConnector(drmconn->connector);
  558.       drmconn->connector = NULL;
  559.  
  560.       return NULL;
  561.    }
  562.  
  563.    for (i = 0; i < count; i++) {
  564.       struct drm_mode *drmmode = &drmconn->drm_modes[i];
  565.       drmModeModeInfoPtr mode = &drmconn->connector->modes[i];
  566.  
  567.       drmmode->mode = *mode;
  568.  
  569.       drmmode->base.desc = drmmode->mode.name;
  570.       drmmode->base.width = drmmode->mode.hdisplay;
  571.       drmmode->base.height = drmmode->mode.vdisplay;
  572.       drmmode->base.refresh_rate = drmmode->mode.vrefresh;
  573.       /* not all kernels have vrefresh = refresh_rate * 1000 */
  574.       if (drmmode->base.refresh_rate < 1000)
  575.          drmmode->base.refresh_rate *= 1000;
  576.    }
  577.  
  578.    nmodes_return = MALLOC(count * sizeof(*nmodes_return));
  579.    if (nmodes_return) {
  580.       for (i = 0; i < count; i++)
  581.          nmodes_return[i] = &drmconn->drm_modes[i].base;
  582.       if (num_modes)
  583.          *num_modes = count;
  584.    }
  585.  
  586.    return nmodes_return;
  587. #endif
  588.    return NULL;
  589. }
  590.  
  591. static const struct native_connector **
  592. drm_display_get_connectors(struct native_display *ndpy, int *num_connectors,
  593.                            int *num_crtc)
  594. {
  595. #if 0
  596.    struct drm_display *drmdpy = drm_display(ndpy);
  597.    const struct native_connector **connectors;
  598.    int i;
  599.  
  600.    if (!drmdpy->connectors) {
  601.       drmdpy->connectors =
  602.          CALLOC(drmdpy->resources->count_connectors, sizeof(*drmdpy->connectors));
  603.       if (!drmdpy->connectors)
  604.          return NULL;
  605.  
  606.       for (i = 0; i < drmdpy->resources->count_connectors; i++) {
  607.          struct drm_connector *drmconn = &drmdpy->connectors[i];
  608.  
  609.          drmconn->connector_id = drmdpy->resources->connectors[i];
  610.          /* drmconn->connector is allocated when the modes are asked */
  611.       }
  612.  
  613.       drmdpy->num_connectors = drmdpy->resources->count_connectors;
  614.    }
  615.  
  616.    connectors = MALLOC(drmdpy->num_connectors * sizeof(*connectors));
  617.    if (connectors) {
  618.       for (i = 0; i < drmdpy->num_connectors; i++)
  619.          connectors[i] = &drmdpy->connectors[i].base;
  620.       if (num_connectors)
  621.          *num_connectors = drmdpy->num_connectors;
  622.    }
  623.  
  624.    if (num_crtc)
  625.       *num_crtc = drmdpy->resources->count_crtcs;
  626.  
  627.    return connectors;
  628. #endif
  629.     return NULL;
  630. }
  631.  
  632. static struct native_surface *
  633. drm_display_create_scanout_surface(struct native_display *ndpy,
  634.                                    const struct native_config *nconf,
  635.                                    uint width, uint height)
  636. {
  637.    struct drm_surface *drmsurf;
  638.  
  639.    drmsurf = drm_display_create_surface(ndpy, nconf, width, height);
  640.    return &drmsurf->base;
  641. }
  642.  
  643. static struct native_display_modeset drm_display_modeset = {
  644.    .get_connectors = drm_display_get_connectors,
  645.    .get_modes = drm_display_get_modes,
  646.    .create_scanout_surface = drm_display_create_scanout_surface,
  647.    .program = drm_display_program
  648. };
  649.  
  650. void
  651. drm_display_fini_modeset(struct native_display *ndpy)
  652. {
  653. #if 0
  654.    struct drm_display *drmdpy = drm_display(ndpy);
  655.    int i;
  656.  
  657.    if (drmdpy->connectors) {
  658.       for (i = 0; i < drmdpy->num_connectors; i++) {
  659.          struct drm_connector *drmconn = &drmdpy->connectors[i];
  660.          if (drmconn->connector) {
  661.             drmModeFreeConnector(drmconn->connector);
  662.             FREE(drmconn->drm_modes);
  663.          }
  664.       }
  665.       FREE(drmdpy->connectors);
  666.    }
  667.  
  668.    FREE(drmdpy->shown_surfaces);
  669.    drmdpy->shown_surfaces = NULL;
  670.  
  671.    if (drmdpy->saved_crtcs) {
  672.       for (i = 0; i < drmdpy->resources->count_crtcs; i++) {
  673.          struct drm_crtc *drmcrtc = &drmdpy->saved_crtcs[i];
  674.  
  675.          if (drmcrtc->crtc) {
  676.             /* restore crtc */
  677.             drmModeSetCrtc(drmdpy->fd, drmcrtc->crtc->crtc_id,
  678.                   drmcrtc->crtc->buffer_id, drmcrtc->crtc->x, drmcrtc->crtc->y,
  679.                   drmcrtc->connectors, drmcrtc->num_connectors,
  680.                   &drmcrtc->crtc->mode);
  681.  
  682.             drmModeFreeCrtc(drmcrtc->crtc);
  683.          }
  684.       }
  685.       FREE(drmdpy->saved_crtcs);
  686.    }
  687.  
  688.    if (drmdpy->resources) {
  689.       drmModeFreeResources(drmdpy->resources);
  690.       drmdpy->resources = NULL;
  691.    }
  692.  
  693.    drmdpy->base.modeset = NULL;
  694. #endif
  695. }
  696.  
  697. boolean
  698. drm_display_init_modeset(struct native_display *ndpy)
  699. {
  700. #if 0
  701.    struct drm_display *drmdpy = drm_display(ndpy);
  702.  
  703.    /* resources are fixed, unlike crtc, connector, or encoder */
  704.    drmdpy->resources = drmModeGetResources(drmdpy->fd);
  705.    if (!drmdpy->resources) {
  706.       _eglLog(_EGL_DEBUG, "Failed to get KMS resources.  Disable modeset.");
  707.       return FALSE;
  708.    }
  709.  
  710.    drmdpy->saved_crtcs =
  711.       CALLOC(drmdpy->resources->count_crtcs, sizeof(*drmdpy->saved_crtcs));
  712.    if (!drmdpy->saved_crtcs) {
  713.       drm_display_fini_modeset(&drmdpy->base);
  714.       return FALSE;
  715.    }
  716.  
  717.    drmdpy->shown_surfaces =
  718.       CALLOC(drmdpy->resources->count_crtcs, sizeof(*drmdpy->shown_surfaces));
  719.    if (!drmdpy->shown_surfaces) {
  720.       drm_display_fini_modeset(&drmdpy->base);
  721.       return FALSE;
  722.    }
  723.  
  724.    drmdpy->base.modeset = &drm_display_modeset;
  725. #endif
  726.    return TRUE;
  727. }
  728.