Exemplo n.º 1
0
static void gfx_ctx_drm_egl_destroy_resources(gfx_ctx_drm_egl_data_t *drm)
{
   if (!drm)
      return;

   /* Make sure we acknowledge all page-flips. */

   if (waiting_for_flip)
      wait_flip(true);

   if (drm->g_egl_dpy)
   {
      if (drm->g_egl_ctx)
      {
         eglMakeCurrent(drm->g_egl_dpy,
               EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
         eglDestroyContext(drm->g_egl_dpy, drm->g_egl_ctx);
      }

      if (drm->g_egl_hw_ctx)
         eglDestroyContext(drm->g_egl_dpy, drm->g_egl_hw_ctx);

      if (drm->g_egl_surf)
         eglDestroySurface(drm->g_egl_dpy, drm->g_egl_surf);
      eglTerminate(drm->g_egl_dpy);
   }

   /* Be as careful as possible in deinit.
    * If we screw up, the KMS tty will not restore.
    */

   drm->g_egl_ctx     = NULL;
   drm->g_egl_hw_ctx  = NULL;
   drm->g_egl_surf    = NULL;
   drm->g_egl_dpy     = NULL;
   drm->g_config      = 0;

   /* Restore original CRTC. */
   if (drm->g_orig_crtc)
   {
      drmModeSetCrtc(drm->g_drm_fd, drm->g_orig_crtc->crtc_id,
            drm->g_orig_crtc->buffer_id,
            drm->g_orig_crtc->x,
            drm->g_orig_crtc->y,
            &drm->g_connector_id, 1, &drm->g_orig_crtc->mode);
   }

   free_drm_resources(drm);

   drm->g_drm_mode = NULL;
   g_quit         = 0;
   drm->g_crtc_id      = 0;
   drm->g_connector_id = 0;

   drm->g_fb_width  = 0;
   drm->g_fb_height = 0;

   drm->g_bo      = NULL;
   drm->g_next_bo = NULL;
}
Exemplo n.º 2
0
static void gfx_ctx_drm_destroy_resources(gfx_ctx_drm_data_t *drm)
{
   if (!drm)
      return;

   /* Make sure we acknowledge all page-flips. */
   gfx_ctx_drm_wait_flip(true);

   switch (drm_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL
         egl_destroy(&drm->egl);
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   free_drm_resources(drm);

   g_drm_mode          = NULL;
   g_crtc_id           = 0;
   g_connector_id      = 0;

   drm->fb_width       = 0;
   drm->fb_height      = 0;

   g_bo                = NULL;
   g_next_bo           = NULL;
}
Exemplo n.º 3
0
static void gfx_ctx_drm_egl_destroy(void *data)
{
   (void)data;
   // Make sure we acknowledge all page-flips.
   if (waiting_for_flip)
      wait_flip(true);

   if (g_egl_dpy)
   {
      if (g_egl_ctx)
      {
         eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
         eglDestroyContext(g_egl_dpy, g_egl_ctx);
      }

      if (g_egl_hw_ctx)
         eglDestroyContext(g_egl_dpy, g_egl_hw_ctx);

      if (g_egl_surf)
         eglDestroySurface(g_egl_dpy, g_egl_surf);
      eglTerminate(g_egl_dpy);
   }

   // Be as careful as possible in deinit.
   // If we screw up, the KMS tty will not restore.

   g_egl_ctx     = NULL;
   g_egl_hw_ctx  = NULL;
   g_egl_surf    = NULL;
   g_egl_dpy     = NULL;
   g_config      = 0;

   // Restore original CRTC.
   if (g_orig_crtc)
   {
      drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id,
            g_orig_crtc->buffer_id,
            g_orig_crtc->x,
            g_orig_crtc->y,
            &g_connector_id, 1, &g_orig_crtc->mode);
   }

   free_drm_resources();

   g_drm_mode = NULL;

   g_quit         = 0;
   g_crtc_id      = 0;
   g_connector_id = 0;

   g_fb_width  = 0;
   g_fb_height = 0;

   g_bo      = NULL;
   g_next_bo = NULL;

   g_inited = false;
}
Exemplo n.º 4
0
static bool gfx_ctx_drm_egl_init(void *data)
{
   const char *gpu;
   int i;
   unsigned monitor_index;
   unsigned gpu_index = 0;
   unsigned monitor = max(g_settings.video.monitor_index, 1);
   struct string_list *gpu_descriptors  = NULL;

   gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*)calloc(1, sizeof(gfx_ctx_drm_egl_data_t));

   if (!drm)
      return NULL;

   drm->g_drm_fd = -1;
   gpu_descriptors = (struct string_list*)dir_list_new("/dev/dri", NULL, false);

nextgpu:
   free_drm_resources(drm);

   if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find a suitable DRM device.\n");
      goto error;
   }
   gpu = gpu_descriptors->elems[gpu_index++].data;

   drm->g_drm_fd = open(gpu, O_RDWR);
   if (drm->g_drm_fd < 0)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't open DRM device.\n");
      goto nextgpu;
   }

   drm->g_resources = drmModeGetResources(drm->g_drm_fd);
   if (!drm->g_resources)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device resources.\n");
      goto nextgpu;
   }

   /* Enumerate all connectors. */
   monitor_index = 0;
   RARCH_LOG("[KMS/EGL]: Found %d connectors.\n",
         drm->g_resources->count_connectors);

   for (i = 0; i < drm->g_resources->count_connectors; i++)
   {
      drmModeConnectorPtr conn = drmModeGetConnector(
            drm->g_drm_fd, drm->g_resources->connectors[i]);

      if (conn)
      {
         bool connected = conn->connection == DRM_MODE_CONNECTED;
         RARCH_LOG("[KMS/EGL]: Connector %d connected: %s\n", i, connected ? "yes" : "no");
         RARCH_LOG("[KMS/EGL]: Connector %d has %d modes.\n", i, conn->count_modes);
         if (connected && conn->count_modes > 0)
         {
            monitor_index++;
            RARCH_LOG("[KMS/EGL]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index);
         }
         drmModeFreeConnector(conn);
      }
   }

   monitor_index = 0;
   for (i = 0; i < drm->g_resources->count_connectors; i++)
   {
      drm->g_connector = drmModeGetConnector(drm->g_drm_fd,
            drm->g_resources->connectors[i]);

      if (!drm->g_connector)
         continue;
      if (drm->g_connector->connection == DRM_MODE_CONNECTED
            && drm->g_connector->count_modes > 0)
      {
         monitor_index++;
         if (monitor_index == monitor)
            break;
      }

      drmModeFreeConnector(drm->g_connector);
      drm->g_connector = NULL;
   }

   if (!drm->g_connector)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device connector.\n");
      goto nextgpu;
   }

   for (i = 0; i < drm->g_resources->count_encoders; i++)
   {
      drm->g_encoder = drmModeGetEncoder(drm->g_drm_fd,
            drm->g_resources->encoders[i]);

      if (!drm->g_encoder)
         continue;
      if (drm->g_encoder->encoder_id == drm->g_connector->encoder_id)
         break;

      drmModeFreeEncoder(drm->g_encoder);
      drm->g_encoder = NULL;
   }

   if (!drm->g_encoder)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto nextgpu;
   }

   for (i = 0; i < drm->g_connector->count_modes; i++)
   {
      RARCH_LOG("[KMS/EGL]: Mode %d: (%s) %d x %d, %u Hz\n",
            i,
            drm->g_connector->modes[i].name,
            drm->g_connector->modes[i].hdisplay,
            drm->g_connector->modes[i].vdisplay,
            drm->g_connector->modes[i].vrefresh);
   }

   drm->g_crtc_id   = drm->g_encoder->crtc_id;
   drm->g_orig_crtc = drmModeGetCrtc(drm->g_drm_fd, drm->g_crtc_id);
   if (!drm->g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   drm->g_connector_id = drm->g_connector->connector_id;

   /* First mode is assumed to be the "optimal" 
    * one for get_video_size() purposes. */
   drm->g_fb_width  = drm->g_connector->modes[0].hdisplay;
   drm->g_fb_height = drm->g_connector->modes[0].vdisplay;

   drm->g_gbm_dev = gbm_create_device(drm->g_drm_fd);

   if (!drm->g_gbm_dev)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't create GBM device.\n");
      goto nextgpu;
   }

   dir_list_free(gpu_descriptors);

   driver.video_context_data = drm;

   return true;

error:
   dir_list_free(gpu_descriptors);

   gfx_ctx_drm_egl_destroy_resources(drm);

   if (drm)
      free(drm);

   return false;
}
Exemplo n.º 5
0
static void *gfx_ctx_drm_init(void *video_driver)
{
   int fd, i;
   unsigned monitor_index;
   unsigned gpu_index                   = 0;
   const char *gpu                      = NULL;
   struct string_list *gpu_descriptors  = NULL;
   gfx_ctx_drm_data_t *drm          = (gfx_ctx_drm_data_t*)
      calloc(1, sizeof(gfx_ctx_drm_data_t));

   if (!drm)
      return NULL;

   gpu_descriptors = dir_list_new("/dev/dri", NULL, false, true, false, false);

nextgpu:
   free_drm_resources(drm);

   if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
   {
      RARCH_ERR("[KMS]: Couldn't find a suitable DRM device.\n");
      goto error;
   }
   gpu = gpu_descriptors->elems[gpu_index++].data;

   drm->drm    = filestream_open(gpu, RFILE_MODE_READ_WRITE, -1);
   if (!drm->drm)
   {
      RARCH_WARN("[KMS]: Couldn't open DRM device.\n");
      goto nextgpu;
   }

   fd = filestream_get_fd(drm->drm);

   if (!drm_get_resources(fd))
      goto nextgpu;

   if (!drm_get_connector(fd))
      goto nextgpu;

   if (!drm_get_encoder(fd))
      goto nextgpu;

   drm_setup(fd);

   /* First mode is assumed to be the "optimal" 
    * one for get_video_size() purposes. */
   drm->fb_width    = g_drm_connector->modes[0].hdisplay;
   drm->fb_height   = g_drm_connector->modes[0].vdisplay;

   g_gbm_dev        = gbm_create_device(fd);

   if (!g_gbm_dev)
   {
      RARCH_WARN("[KMS]: Couldn't create GBM device.\n");
      goto nextgpu;
   }

   dir_list_free(gpu_descriptors);

   /* Setup the flip handler. */
   g_drm_fds.fd                   = fd;
   g_drm_fds.events               = POLLIN;
   g_drm_evctx.version            = DRM_EVENT_CONTEXT_VERSION;
   g_drm_evctx.page_flip_handler  = drm_flip_handler;

   g_drm_fd                       = fd;

   return drm;

error:
   dir_list_free(gpu_descriptors);

   gfx_ctx_drm_destroy_resources(drm);

   if (drm)
      free(drm);

   return NULL;
}