Esempio n. 1
0
static bool gfx_ctx_mali_fbdev_set_video_mode(void *data,
      video_frame_info_t *video_info,
      unsigned width, unsigned height,
      bool fullscreen)
{
   struct fb_var_screeninfo vinfo;
   static const EGLint attribs[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2, /* Use version 2, even for GLES3. */
      EGL_NONE
   };
   mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
   RFILE *fd             = filestream_open("/dev/fb0", RFILE_MODE_READ_WRITE, -1);
   int fb                = filestream_get_fd(fd);

   if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0)
   {
      RARCH_ERR("Error obtaining framebuffer info.\n");
      goto error;
   }

   filestream_close(fd);
   
   width                      = vinfo.xres;
   height                     = vinfo.yres;

   mali->width                = width;
   mali->height               = height;

   mali->native_window.width  = vinfo.xres;
   mali->native_window.height = vinfo.yres;

#ifdef HAVE_EGL
   if (!egl_create_context(&mali->egl, attribs))
   {
      egl_report_error();
      goto error;
   }
#endif

#ifdef HAVE_EGL
   if (!egl_create_surface(&mali->egl, &mali->native_window))
      goto error;
#endif

   return true;

error:
   if (fd)
      filestream_close(fd);
   RARCH_ERR("[Mali fbdev]: EGL error: %d.\n", eglGetError());
   gfx_ctx_mali_fbdev_destroy(data);
   return false;
}
Esempio n. 2
0
static void gfx_ctx_swap_interval(unsigned interval)
{
   g_interval = interval;
   if (g_egl_dpy && eglGetCurrentContext())
   {
      RARCH_LOG("[X/EGL]: eglSwapInterval(%u)\n", g_interval);
      if (!eglSwapInterval(g_egl_dpy, g_interval))
      {
         RARCH_ERR("[X/EGL]: eglSwapInterval() failed.\n");
         egl_report_error();
      }
   }
}
Esempio n. 3
0
static void *gfx_ctx_vivante_init(void *video_driver)
{
#ifdef HAVE_EGL
   EGLint n;
   EGLint major, minor;
   EGLint format;
   static const EGLint attribs[] = {
#if 0
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
#endif
      EGL_BLUE_SIZE, 5,
      EGL_GREEN_SIZE, 6,
      EGL_RED_SIZE, 5,
      EGL_ALPHA_SIZE, 0,
      EGL_SAMPLES,            0,
      EGL_NONE
   };
#endif
   vivante_ctx_data_t *viv = (vivante_ctx_data_t*)calloc(1, sizeof(*viv));

   if (!viv)
       return NULL;

#ifdef HAVE_EGL
   frontend_driver_install_signal_handler();
#endif

   /* Disable cursor blinking so it's not visible in RetroArch. */
   system("setterm -cursor off");

#ifdef HAVE_EGL
   if (!egl_init_context(&viv->egl, EGL_DEFAULT_DISPLAY, &major, &minor,
            &n, attribs))
   {
      egl_report_error();
      goto error;
   }
#endif

   return viv;

error:
   RARCH_ERR("[Vivante fbdev]: EGL error: %d.\n", eglGetError());
   gfx_ctx_vivante_destroy(viv);
   return NULL;
}
Esempio n. 4
0
static void gfx_ctx_xegl_swap_interval(void *data, unsigned interval)
{
   (void)data;
   g_interval = interval;

   if (!g_egl_dpy)
      return;
   if (!(eglGetCurrentContext()))
      return;

   RARCH_LOG("[X/EGL]: eglSwapInterval(%u)\n", g_interval);
   if (!eglSwapInterval(g_egl_dpy, g_interval))
   {
      RARCH_ERR("[X/EGL]: eglSwapInterval() failed.\n");
      egl_report_error();
   }
}
static void *gfx_ctx_opendingux_init(video_frame_info_t *video_info, void *video_driver)
{
#ifdef HAVE_EGL
   EGLint n;
   EGLint major, minor;
   EGLint format;
   static const EGLint attribs[] = {
#if 0
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
#endif
      EGL_BLUE_SIZE,  5,
      EGL_GREEN_SIZE, 6,
      EGL_RED_SIZE,   5,
      EGL_ALPHA_SIZE, 0,
      EGL_SAMPLES,    0,
      EGL_NONE
   };
#endif
   opendingux_ctx_data_t *viv = (opendingux_ctx_data_t*)
      calloc(1, sizeof(*viv));

   if (!viv)
      return NULL;
   
#ifdef HAVE_EGL
   frontend_driver_install_signal_handler();

   if (!egl_init_context(&viv->egl, EGL_DEFAULT_DISPLAY,
            &major, &minor,
            &n, attribs))
   {
      egl_report_error();
      goto error;
   }
#endif

   return viv;

error:
#ifdef HAVE_EGL
   RARCH_ERR("[opendingux fbdev]: EGL error: %d.\n", eglGetError());
#endif
   gfx_ctx_opendingux_destroy(viv);
   return NULL;
}
Esempio n. 6
0
static bool gfx_ctx_wl_set_video_mode(void *data,
      unsigned width, unsigned height,
      bool fullscreen)
{
   EGLint egl_attribs[16];
   EGLint *attr = NULL;
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;

   egl_install_sighandlers();

   attr = egl_fill_attribs(wl, egl_attribs);

   wl->width = width ? width : DEFAULT_WINDOWED_WIDTH;
   wl->height = height ? height : DEFAULT_WINDOWED_HEIGHT;

   wl->surface = wl_compositor_create_surface(wl->compositor);
   wl->win = wl_egl_window_create(wl->surface, wl->width, wl->height);
   wl->shell_surf = wl_shell_get_shell_surface(wl->shell, wl->surface);

   wl_shell_surface_add_listener(wl->shell_surf, &shell_surface_listener, NULL);
   wl_shell_surface_set_toplevel(wl->shell_surf);
   wl_shell_surface_set_class(wl->shell_surf, "RetroArch");
   wl_shell_surface_set_title(wl->shell_surf, "RetroArch");

   if (!egl_create_context(wl, (attr != egl_attribs) ? egl_attribs : NULL))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_surface(wl, (EGLNativeWindowType)wl->win))
      goto error;

   egl_set_swap_interval(wl, wl->egl.interval);

   if (fullscreen)
      wl_shell_surface_set_fullscreen(wl->shell_surf, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);

   flush_wayland_fd(wl);
   return true;

error:
   gfx_ctx_wl_destroy(data);
   return false;
}
Esempio n. 7
0
static bool gfx_ctx_vivante_set_video_mode(void *data,
      video_frame_info_t *video_info,
      unsigned width, unsigned height,
      bool fullscreen)
{
#ifdef HAVE_EGL
   static const EGLint attribs[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2, /* Use version 2, even for GLES3. */
      EGL_NONE
   };
#endif
   vivante_ctx_data_t *viv = (vivante_ctx_data_t*)data;

   /* Pick some arbitrary default. */
   if (!width || !fullscreen)
      width = 1280;
   if (!height || !fullscreen)
      height = 1024;

   viv->width    = width;
   viv->height   = height;

#ifdef HAVE_EGL
   if (!egl_create_context(&viv->egl, attribs))
   {
      egl_report_error();
      goto error;
   }
#endif

   viv->native_window = fbCreateWindow(fbGetDisplayByIndex(0), 0, 0, 0, 0);

#ifdef HAVE_EGL
   if (!egl_create_surface(&viv->egl, viv->native_window))
      goto error;
#endif

   return true;

error:
   RARCH_ERR("[Vivante fbdev]: EGL error: %d.\n", eglGetError());
   gfx_ctx_vivante_destroy(data);
   return false;
}
Esempio n. 8
0
static void *gfx_ctx_mali_fbdev_init(video_frame_info_t *video_info, void *video_driver)
{
#ifdef HAVE_EGL
   EGLint n;
   EGLint major, minor;
   EGLint format;
   static const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_NONE
   };
#endif

   mali_ctx_data_t *mali = (mali_ctx_data_t*)calloc(1, sizeof(*mali));

   if (!mali)
       return NULL;

#ifdef HAVE_EGL
   frontend_driver_install_signal_handler();
#endif

#ifdef HAVE_EGL
   if (!egl_init_context(&mali->egl, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribs))
   {
      egl_report_error();
      goto error;
   }
#endif

   return mali;

error:
   RARCH_ERR("[Mali fbdev]: EGL error: %d.\n", eglGetError());
   gfx_ctx_mali_fbdev_destroy(video_driver);
   return NULL;
}
Esempio n. 9
0
static bool orbis_ctx_set_video_mode(void *data,
                                      video_frame_info_t *video_info,
                                      unsigned width, unsigned height,
                                      bool fullscreen)
{
    /* Create an EGL rendering context */
    static const EGLint contextAttributeList[] =
        {
            EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL_NONE};

    orbis_ctx_data_t *ctx_orbis = (orbis_ctx_data_t *)data;

    ctx_orbis->width = ATTR_ORBISGL_WIDTH;
    ctx_orbis->height = ATTR_ORBISGL_HEIGHT;

    ctx_orbis->native_window.width = ctx_orbis->width;
    ctx_orbis->native_window.height = ctx_orbis->height;

    ctx_orbis->refresh_rate = 60;

#ifdef HAVE_EGL
    if (!egl_create_context(&ctx_orbis->egl, contextAttributeList))
    {
        egl_report_error();
        goto error;
    }
#endif

#ifdef HAVE_EGL
    if (!egl_create_surface(&ctx_orbis->egl, &ctx_orbis->native_window))
        goto error;
#endif

    return true;

error:
    printf("[ctx_orbis]: EGL error: %d.\n", eglGetError());
    orbis_ctx_destroy(data);

    return false;
}
Esempio n. 10
0
void egl_set_swap_interval(void *data, unsigned interval)
{
   /* Can be called before initialization.
    * Some contexts require that swap interval 
    * is known at startup time.
    */
   g_interval = interval;

   if (g_egl_dpy  == EGL_NO_DISPLAY)
      return;
   if (!(eglGetCurrentContext()))
      return;

   RARCH_LOG("[EGL]: eglSwapInterval(%u)\n", interval);
   if (!eglSwapInterval(g_egl_dpy, interval))
   {
      RARCH_ERR("[EGL]: eglSwapInterval() failed.\n");
      egl_report_error();
   }
}
Esempio n. 11
0
static void *gfx_ctx_mali_fbdev_init(void *video_driver)
{
   EGLint n;
   EGLint major, minor;
   EGLint format;
   static const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_NONE
   };

   mali_ctx_data_t *mali = (mali_ctx_data_t*)calloc(1, sizeof(*mali));

   if (!mali)
       return NULL;

   egl_install_sighandlers();

   /* Disable cursor blinking so it's not visible in RetroArch. */
   system("setterm -cursor off");
   
   if (!egl_init_context(mali, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribs))
   {
      egl_report_error();
      goto error;
   }

   return mali;

error:
   RARCH_ERR("[Mali fbdev]: EGL error: %d.\n", eglGetError());
   gfx_ctx_mali_fbdev_destroy(video_driver);
   return NULL;
}
Esempio n. 12
0
static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
{
#ifdef HAVE_OPENGL
   static const EGLint egl_attribs_gl[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };
#endif

#ifdef HAVE_OPENGLES
#ifdef HAVE_OPENGLES2
   static const EGLint egl_attribs_gles[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };
#endif

#ifdef HAVE_OPENGLES3
#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif
#endif

#endif

#ifdef HAVE_EGL
   static const EGLint egl_attribs_vg[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   EGLint major = 0, minor = 0;
   EGLint n;
   const EGLint *attrib_ptr = NULL;
#endif
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)
      calloc(1, sizeof(gfx_ctx_wayland_data_t));

   if (!wl)
      return NULL;

   (void)video_driver;

#ifdef HAVE_EGL
   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
#ifdef HAVE_OPENGL
         attrib_ptr = egl_attribs_gl;
#endif
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef HAVE_OPENGLES
#ifdef HAVE_OPENGLES3
#ifdef EGL_KHR_create_context
         if (g_egl_major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
#endif
#ifdef HAVE_OPENGLES2
            attrib_ptr = egl_attribs_gles;
#endif
#endif
         break;
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_VG
         attrib_ptr = egl_attribs_vg;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }
#endif

   frontend_driver_destroy_signal_handler_state();

   wl->input.dpy = wl_display_connect(NULL);
   wl->buffer_scale = 1;

   if (!wl->input.dpy)
   {
      RARCH_ERR("[Wayland]: Failed to connect to Wayland server.\n");
      goto error;
   }

   frontend_driver_install_signal_handler();

   wl->registry = wl_display_get_registry(wl->input.dpy);
   wl_registry_add_listener(wl->registry, &registry_listener, wl);
   wl_display_roundtrip(wl->input.dpy);

   if (!wl->compositor)
   {
      RARCH_ERR("[Wayland]: Failed to create compositor.\n");
      goto error;
   }

   if (!wl->shm)
   {
      RARCH_ERR("[Wayland]: Failed to create shm.\n");
      goto error;
   }

   if (!wl->shell)
   {
      RARCH_ERR("[Wayland]: Failed to create shell.\n");
      goto error;
   }

   wl->input.fd = wl_display_get_fd(wl->input.dpy);

   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL
         if (!egl_init_context(&wl->egl,
                  EGL_PLATFORM_WAYLAND_KHR,
                  (EGLNativeDisplayType)wl->input.dpy,
                  &major, &minor, &n, attrib_ptr))
         {
            egl_report_error();
            goto error;
         }

         if (n == 0 || !egl_has_config(&wl->egl))
            goto error;
#endif
         break;
      case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
         if (!vulkan_context_init(&wl->vk, VULKAN_WSI_WAYLAND))
            goto error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   wl->input.keyboard_focus = true;
   wl->input.mouse.focus = true;

   wl->cursor.surface = wl_compositor_create_surface(wl->compositor);
   wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm);
   wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr");
   flush_wayland_fd(&wl->input);

   return wl;

error:
   gfx_ctx_wl_destroy_resources(wl);

   if (wl)
      free(wl);

   return NULL;
}
Esempio n. 13
0
static bool gfx_ctx_xegl_init(void *data)
{
   static const EGLint egl_attribs_gl[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif

   static const EGLint egl_attribs_vg[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   const EGLint *attrib_ptr;
   EGLint major, minor;
   EGLint n;

   if (g_egl_inited)
      return false;

   XInitThreads();

   switch (g_egl_api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_KHR_create_context
         if (g_major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
            attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
         attrib_ptr = egl_attribs_vg;
         break;
      default:
         attrib_ptr = NULL;
   }

   if (!x11_connect())
      goto error;

   if (!egl_init_context((EGLNativeDisplayType)g_x11_dpy,
            &major, &minor, &n, attrib_ptr))
   {
      egl_report_error();
      goto error;
   }

   if (n == 0 || !g_egl_config)
   {
      RARCH_ERR("[X/EGL]: No EGL configurations available.\n");
      goto error;
   }

   return true;

error:
   gfx_ctx_xegl_destroy(data);
   return false;
}
Esempio n. 14
0
static bool gfx_ctx_wl_set_video_mode(void *data,
      video_frame_info_t *video_info,
      unsigned width, unsigned height,
      bool fullscreen)
{
#ifdef HAVE_EGL
   EGLint egl_attribs[16];
   EGLint *attr              = egl_fill_attribs(
         (gfx_ctx_wayland_data_t*)data, egl_attribs);
#endif
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;

   wl->width                  = width  ? width  : DEFAULT_WINDOWED_WIDTH;
   wl->height                 = height ? height : DEFAULT_WINDOWED_HEIGHT;

   wl->surface                = wl_compositor_create_surface(wl->compositor);

   wl_surface_set_buffer_scale(wl->surface, wl->buffer_scale);

   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL
         wl->win        = wl_egl_window_create(wl->surface, wl->width, wl->height);
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }
   wl->shell_surf = wl_shell_get_shell_surface(wl->shell, wl->surface);

   wl_shell_surface_add_listener(wl->shell_surf, &shell_surface_listener, wl);
   wl_shell_surface_set_toplevel(wl->shell_surf);
   wl_shell_surface_set_class(wl->shell_surf, "RetroArch");
   wl_shell_surface_set_title(wl->shell_surf, "RetroArch");

   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL

         if (!egl_create_context(&wl->egl, (attr != egl_attribs) ? egl_attribs : NULL))
         {
            egl_report_error();
            goto error;
         }

         if (!egl_create_surface(&wl->egl, (EGLNativeWindowType)wl->win))
            goto error;
         egl_set_swap_interval(&wl->egl, wl->egl.interval);
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   if (fullscreen)
      wl_shell_surface_set_fullscreen(wl->shell_surf,
            WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);

   flush_wayland_fd(&wl->input);

   switch (wl_api)
   {
      case GFX_CTX_VULKAN_API:
         wl_display_roundtrip(wl->input.dpy);

#ifdef HAVE_VULKAN
         if (!vulkan_surface_create(&wl->vk, VULKAN_WSI_WAYLAND,
                  wl->input.dpy, wl->surface, 
                  wl->width, wl->height, wl->swap_interval))
            goto error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   if (fullscreen)
   {
      wl->cursor.visible = false;
      gfx_ctx_wl_show_mouse(wl, false);
   }
   else
      wl->cursor.visible = true;

   return true;

error:
   gfx_ctx_wl_destroy(data);
   return false;
}
Esempio n. 15
0
static void *gfx_ctx_vc_init(void *video_driver)
{
   VC_DISPMANX_ALPHA_T alpha;
   EGLint n, major, minor;
   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

#ifdef HAVE_EGL
   static const EGLint attribute_list[] =
   {
      EGL_RED_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_BLUE_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_NONE
   };

   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
#endif
   settings_t *settings = config_get_ptr();
   vc_ctx_data_t *vc    = NULL;

   if (g_egl_inited)
   {
      RARCH_ERR("[VC/EGL]: Attempted to re-initialize driver.\n");
      return NULL;
   }

   vc = (vc_ctx_data_t*)calloc(1, sizeof(*vc));

   if (!vc)
       return NULL;

   bcm_host_init();

#ifdef HAVE_EGL
   if (!egl_init_context(&vc->egl, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribute_list))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_context(&vc->egl, (vc_api == GFX_CTX_OPENGL_ES_API) ? context_attributes : NULL))
   {
      egl_report_error();
      goto error;
   }
#endif

   /* Create an EGL window surface. */
   if (graphics_get_display_size(0 /* LCD */, &vc->fb_width, &vc->fb_height) < 0)
      goto error;

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = vc->fb_width;
   dst_rect.height = vc->fb_height;

   src_rect.x = 0;
   src_rect.y = 0;

   /* Use dispmanx upscaling if fullscreen_x 
    * and fullscreen_y are set. */
   if (settings->video.fullscreen_x != 0 &&
      settings->video.fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->video.fullscreen_x / (float)settings->video.fullscreen_y;
      float dstAspect = (float)vc->fb_width / (float)vc->fb_height;
      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         src_rect.width = (unsigned)(settings->video.fullscreen_y * dstAspect) << 16;
      else
         src_rect.width = settings->video.fullscreen_x << 16;
      src_rect.height = settings->video.fullscreen_y << 16;
   }
   else
   {
      src_rect.width  = vc->fb_width << 16;
      src_rect.height = vc->fb_height << 16;
   }

   dispman_display = vc_dispmanx_display_open(0 /* LCD */);
   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
   dispman_update = vc_dispmanx_update_start(0);

   alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
   alpha.opacity = 255;
   alpha.mask = 0;

   dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display,
      0 /*layer*/, &dst_rect, 0 /*src*/,
      &src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0 /*clamp*/, DISPMANX_NO_ROTATE);

   nativewindow.element = dispman_element;

   /* Use dispmanx upscaling if fullscreen_x and fullscreen_y are set. */

   if (settings->video.fullscreen_x != 0 &&
      settings->video.fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which 
       * can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->video.fullscreen_x / (float)settings->video.fullscreen_y;
      float dstAspect = (float)vc->fb_width / (float)vc->fb_height;

      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         nativewindow.width = (unsigned)(settings->video.fullscreen_y * dstAspect);
      else
         nativewindow.width = settings->video.fullscreen_x;
      nativewindow.height = settings->video.fullscreen_y;
   }
   else
   {
      nativewindow.width = vc->fb_width;
      nativewindow.height = vc->fb_height;
   }
   vc_dispmanx_update_submit_sync(dispman_update);

#ifdef HAVE_EGL
   if (!egl_create_surface(&vc->egl, &nativewindow))
      goto error;
#endif

   return vc;

error:
   gfx_ctx_vc_destroy(video_driver);
   return NULL;
}
Esempio n. 16
0
static bool gfx_ctx_xegl_init(void *data)
{
   static const EGLint egl_attribs_gl[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif

   static const EGLint egl_attribs_vg[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   const EGLint *attrib_ptr;

   EGLint egl_major, egl_minor;
   EGLint num_configs;

   if (g_inited)
      return false;

   XInitThreads();

   switch (g_api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_KHR_create_context
         if (g_major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
            attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
         attrib_ptr = egl_attribs_vg;
         break;
      default:
         attrib_ptr = NULL;
   }

   g_quit = 0;

   /* Keep one g_dpy alive the entire process lifetime.
    * This is necessary for nVidia's EGL implementation for now. */
   if (!g_dpy)
   {
      g_dpy = XOpenDisplay(NULL);
      if (!g_dpy)
         goto error;
   }

   g_egl_dpy = eglGetDisplay((EGLNativeDisplayType)g_dpy);
   if (g_egl_dpy == EGL_NO_DISPLAY)
   {
      RARCH_ERR("[X/EGL]: EGL display not available.\n");
      egl_report_error();
      goto error;
   }

   if (!eglInitialize(g_egl_dpy, &egl_major, &egl_minor))
   {
      RARCH_ERR("[X/EGL]: Unable to initialize EGL.\n");
      egl_report_error();
      goto error;
   }

   RARCH_LOG("[X/EGL]: EGL version: %d.%d\n", egl_major, egl_minor);

   if (!eglChooseConfig(g_egl_dpy, attrib_ptr, &g_egl_config, 1, &num_configs))
   {
      RARCH_ERR("[X/EGL]: eglChooseConfig failed with 0x%x.\n", eglGetError());
      goto error;
   }

   if (num_configs == 0 || !g_egl_config)
   {
      RARCH_ERR("[X/EGL]: No EGL configurations available.\n");
      goto error;
   }

   return true;

error:
   gfx_ctx_xegl_destroy(data);
   return false;
}
Esempio n. 17
0
static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm)
{
   const EGLint *attrib_ptr    = NULL;
   static const EGLint egl_attribs_gl[] = {
      DRM_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      DRM_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      DRM_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif

#ifdef HAVE_VG
   static const EGLint egl_attribs_vg[] = {
      DRM_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };
#endif
   EGLint major;
   EGLint minor;
   EGLint n;
   EGLint egl_attribs[16];
   EGLint *egl_attribs_ptr     = NULL;
   EGLint *attr                = NULL;

   switch (drm_api)
   {
      case GFX_CTX_OPENGL_API:
#ifdef HAVE_OPENGL
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_KHR_create_context
         if (drm->egl.major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
         attrib_ptr = egl_attribs_gles;
#endif
         break;
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_VG
         attrib_ptr = egl_attribs_vg;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   switch (drm_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL
         if (!egl_init_context(&drm->egl, (EGLNativeDisplayType)g_gbm_dev, &major,
                  &minor, &n, attrib_ptr))
            goto error;

         attr            = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs);
         egl_attribs_ptr = &egl_attribs[0];

         if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) 
                  ? egl_attribs_ptr : NULL))
            goto error;

         if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)g_gbm_surface))
            return false;
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
         glClear(GL_COLOR_BUFFER_BIT);
#endif
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   egl_swap_buffers(drm);

   return true;

error:
   egl_report_error();
   return false;
}
Esempio n. 18
0
static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver)
{
   VC_DISPMANX_ALPHA_T alpha;
   EGLint n, major, minor;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

#ifdef HAVE_EGL
   static const EGLint attribute_list[] =
   {
      EGL_RED_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_BLUE_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_DEPTH_SIZE, 16,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_NONE
   };

   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
#endif
   settings_t *settings = config_get_ptr();
   vc_ctx_data_t *vc    = NULL;

   if (g_egl_inited)
   {
      RARCH_ERR("[VC/EGL]: Attempted to re-initialize driver.\n");
      return NULL;
   }

   vc = (vc_ctx_data_t*)calloc(1, sizeof(*vc));

   if (!vc)
       return NULL;

   /* If we set this env variable, Broadcom's EGL implementation will block
    * on vsync with a double buffer when we call eglSwapBuffers. Less input lag!
    * Has to be done before any EGL call.
    * NOTE this is commented out because it should be the right way to do it, but
    * currently it doesn't work, so we are using an vsync callback based solution.*/
   /* if (video_info->max_swapchain_images <= 2)
      setenv("V3D_DOUBLE_BUFFER", "1", 1);
   else
      setenv("V3D_DOUBLE_BUFFER", "0", 1); */

   bcm_host_init();

#ifdef HAVE_EGL
   if (!egl_init_context(&vc->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribute_list))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_context(&vc->egl, (vc_api == GFX_CTX_OPENGL_ES_API)
            ? context_attributes : NULL))
   {
      egl_report_error();
      goto error;
   }
#endif

   /* Create an EGL window surface. */
   if (graphics_get_display_size(0 /* LCD */, &vc->fb_width, &vc->fb_height) < 0)
      goto error;

   dst_rect.x      = 0;
   dst_rect.y      = 0;
   dst_rect.width  = vc->fb_width;
   dst_rect.height = vc->fb_height;

   src_rect.x      = 0;
   src_rect.y      = 0;

   /* Use dispmanx upscaling if fullscreen_x
    * and fullscreen_y are set. */
   if ((settings->uints.video_fullscreen_x != 0) &&
       (settings->uints.video_fullscreen_y != 0))
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect        = (float)settings->uints.video_fullscreen_x / (float)settings->uints.video_fullscreen_y;
      float dstAspect        = (float)vc->fb_width / (float)vc->fb_height;
      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         src_rect.width      = (unsigned)(settings->uints.video_fullscreen_y * dstAspect) << 16;
      else
         src_rect.width      = settings->uints.video_fullscreen_x << 16;
      src_rect.height        = settings->uints.video_fullscreen_y << 16;
   }
   else
   {
      src_rect.width         = vc->fb_width << 16;
      src_rect.height        = vc->fb_height << 16;
   }

   dispman_display           = vc_dispmanx_display_open(0 /* LCD */);
   vc->dispman_display       = dispman_display;

   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);

   dispman_update            = vc_dispmanx_update_start(0);

   alpha.flags               = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
   alpha.opacity             = 255;
   alpha.mask                = 0;

   dispman_element           = vc_dispmanx_element_add(dispman_update, dispman_display,
         0 /*layer*/, &dst_rect, 0 /*src*/,
         &src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0 /*clamp*/, DISPMANX_NO_ROTATE);

   vc->native_window.element = dispman_element;

   /* Use dispmanx upscaling if fullscreen_x and fullscreen_y are set. */

   if (settings->uints.video_fullscreen_x != 0 &&
       settings->uints.video_fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which
       * can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->uints.video_fullscreen_x
         / (float)settings->uints.video_fullscreen_y;
      float dstAspect = (float)vc->fb_width / (float)vc->fb_height;

      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         vc->native_window.width = (unsigned)(settings->uints.video_fullscreen_y * dstAspect);
      else
         vc->native_window.width = settings->uints.video_fullscreen_x;
      vc->native_window.height   = settings->uints.video_fullscreen_y;
   }
   else
   {
      vc->native_window.width = vc->fb_width;
      vc->native_window.height = vc->fb_height;
   }
   vc_dispmanx_update_submit_sync(dispman_update);

#ifdef HAVE_EGL
   if (!egl_create_surface(&vc->egl, &vc->native_window))
      goto error;
#endif

   /* For vsync after eglSwapBuffers when max_swapchain < 3 */
   vc->vsync_condition       = scond_new();
   vc->vsync_condition_mutex = slock_new();
   vc->vsync_callback_set    = false;

   if (video_info->max_swapchain_images <= 2)
   {
      /* Start sending vsync callbacks so we can wait for vsync after eglSwapBuffers */
      vc_dispmanx_vsync_callback(vc->dispman_display,
            dispmanx_vsync_callback, (void*)vc);
      vc->vsync_callback_set = true;
   }

   return vc;

error:
   gfx_ctx_vc_destroy(video_driver);
   return NULL;
}
Esempio n. 19
0
static bool gfx_ctx_qnx_init(void *data)
{
   EGLint n;
   EGLint major, minor;
   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
   const EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_NONE
   };
   int angle, size[2];
   int usage, format = SCREEN_FORMAT_RGBX8888;

   /* Create a screen context that will be used to 
    * create an EGL surface to receive libscreen events */

   RARCH_LOG("Initializing screen context...\n");
   if (!screen_ctx)
   {
      screen_create_context(&screen_ctx, 0);

      if (screen_request_events(screen_ctx) != BPS_SUCCESS)
      {
         RARCH_ERR("screen_request_events failed.\n");
         goto screen_error;
      }

      if (navigator_request_events(0) != BPS_SUCCESS)
      {
         RARCH_ERR("navigator_request_events failed.\n");
         goto screen_error;
      }

      if (navigator_rotation_lock(false) != BPS_SUCCESS)
      {
         RARCH_ERR("navigator_location_lock failed.\n");
         goto screen_error;
      }
   }

   usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;

   if (!eglBindAPI(EGL_OPENGL_ES_API))
   {
      RARCH_ERR("eglBindAPI failed.\n");
      goto error;
   }

   if (!egl_init_context(EGL_DEFAULT_DISPLAY, &major, &minor,
            &n, attribs))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_context(context_attributes))
   {
      egl_report_error();
      goto error;
   }

   if(!screen_win)
   {
      if (screen_create_window(&screen_win, screen_ctx))
      {
	     RARCH_ERR("screen_create_window failed:.\n");
	     goto error;
      }
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_FORMAT] failed.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_USAGE] failed.\n");
      goto error;
   }

   if (screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp))
   {
      RARCH_ERR("screen_get_window_property_pv [SCREEN_PROPERTY_DISPLAY] failed.\n");
      goto error;
   }

   int screen_resolution[2];

   if (screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution))
   {
      RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_SIZE] failed.\n");
      goto error;
   }

#ifndef HAVE_BB10
   angle = atoi(getenv("ORIENTATION"));

   screen_display_mode_t screen_mode;
   if (screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode))
   {
      RARCH_ERR("screen_get_display_property_pv [SCREEN_PROPERTY_MODE] failed.\n");
      goto error;
   }

   if (screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size))
   {
      RARCH_ERR("screen_get_window_property_iv [SCREEN_PROPERTY_BUFFER_SIZE] failed.\n");
      goto error;
   }

   int buffer_size[2] = {size[0], size[1]};

   if ((angle == 0) || (angle == 180))
   {
      if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
            ((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
      {
         buffer_size[1] = size[0];
         buffer_size[0] = size[1];
      }
   }
   else if ((angle == 90) || (angle == 270))
   {
      if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
            ((screen_mode.width < screen_mode.height && size[0] < size[1])))
      {
         buffer_size[1] = size[0];
         buffer_size[0] = size[1];
      }
   }
   else
   {
      RARCH_ERR("Navigator returned an unexpected orientation angle.\n");
      goto error;
   }


   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_BUFFER_SIZE] failed.\n");
      goto error;
   }

   if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle))
   {
      RARCH_ERR("screen_set_window_property_iv [SCREEN_PROPERTY_ROTATION] failed.\n");
      goto error;
   }
#endif

   if (screen_create_window_buffers(screen_win, WINDOW_BUFFERS))
   {
      RARCH_ERR("screen_create_window_buffers failed.\n");
      goto error;
   }

   if (!egl_create_surface(screen_win))
      goto error;

   return true;

error:
   RARCH_ERR("EGL error: %d.\n", eglGetError());
   gfx_ctx_qnx_destroy(data);
screen_error:
   screen_stop_events(screen_ctx);
   return false;
}
Esempio n. 20
0
static void *android_gfx_ctx_init(video_frame_info_t *video_info, void *video_driver)
{
#ifdef HAVE_OPENGLES
   EGLint n, major, minor;
   EGLint format;
#if 0
   struct retro_hw_render_callback *hwr = video_driver_get_hw_context();
   bool debug = hwr->debug_context;
#endif
   EGLint context_attributes[] = {
      EGL_CONTEXT_CLIENT_VERSION, g_es3 ? 3 : 2,
#if 0
      EGL_CONTEXT_FLAGS_KHR, debug ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0,
#endif
      EGL_NONE
   };
   EGLint attribs[] = {
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_BLUE_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_RED_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_DEPTH_SIZE, 16,
      EGL_NONE
   };
#endif
   struct android_app *android_app = (struct android_app*)g_android;
   android_ctx_data_t *and  = (android_ctx_data_t*)calloc(1, sizeof(*and));

   if (!android_app || !and)
      return false;

#ifdef HAVE_OPENGLES
   if (g_es3)
      attribs[1] = EGL_OPENGL_ES3_BIT_KHR;
#endif

   switch (android_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
#ifdef HAVE_EGL
         RARCH_LOG("Android EGL: GLES version = %d.\n", g_es3 ? 3 : 2);

         if (!egl_init_context(&and->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
                  &major, &minor, &n, attribs))
         {
            egl_report_error();
            goto error;
         }

         if (!egl_get_native_visual_id(&and->egl, &format))
            goto error;
#endif
         break;
      case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
         if (!vulkan_context_init(&and->vk, VULKAN_WSI_ANDROID))
            goto error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   slock_lock(android_app->mutex);
   if (!android_app->window)
      goto unlock_error;

   switch (android_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
         ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format);

#ifdef HAVE_EGL
         if (!egl_create_context(&and->egl, context_attributes))
         {
            egl_report_error();
            goto unlock_error;
         }

         if (!egl_create_surface(&and->egl, android_app->window))
            goto unlock_error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   slock_unlock(android_app->mutex);
   return and;

unlock_error:
   slock_unlock(android_app->mutex);
error:
   android_gfx_ctx_destroy(and);

   return NULL;
}
Esempio n. 21
0
static void *gfx_ctx_xegl_init(void *video_driver)
{
#ifdef HAVE_EGL
   static const EGLint egl_attribs_gl[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif
#ifdef HAVE_VG
   static const EGLint egl_attribs_vg[] = {
      XEGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };
#endif
   const EGLint *attrib_ptr = NULL;
   EGLint major, minor;
   EGLint n;
#endif
   xegl_ctx_data_t *xegl;

   if (g_egl_inited)
      return NULL;

   XInitThreads();

   xegl = (xegl_ctx_data_t*)calloc(1, sizeof(xegl_ctx_data_t));
   if (!xegl)
      return NULL;

   switch (x_api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_KHR_create_context
         if (xegl->egl.major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
            attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_VG
         attrib_ptr = egl_attribs_vg;
#endif
         break;
      default:
         break;
   }

   if (!x11_connect())
      goto error;

#ifdef HAVE_EGL
   if (!egl_init_context(&xegl->egl, (EGLNativeDisplayType)g_x11_dpy,
            &major, &minor, &n, attrib_ptr))
   {
      egl_report_error();
      goto error;
   }

   if (n == 0 || !egl_has_config(&xegl->egl))
      goto error;
#endif

   return xegl;

error:
   gfx_ctx_xegl_destroy(xegl);
   return NULL;
}
Esempio n. 22
0
static void *orbis_ctx_init(video_frame_info_t *video_info, void *video_driver)
{
#ifdef HAVE_EGL
    int ret;
    EGLint n;
    EGLint major, minor;
    static const EGLint attribs[] = {
        EGL_RED_SIZE, 8,
         EGL_GREEN_SIZE, 8,
         EGL_BLUE_SIZE, 8,
         EGL_ALPHA_SIZE, 8,
         EGL_DEPTH_SIZE, 16,
         EGL_STENCIL_SIZE, 0,
         EGL_SAMPLE_BUFFERS, 0,
         EGL_SAMPLES, 0,
         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
         EGL_NONE};
#endif

    orbis_ctx_data_t *ctx_orbis = (orbis_ctx_data_t *)calloc(1, sizeof(*ctx_orbis));

    if (!ctx_orbis)
        return NULL;

    nx_ctx_ptr = ctx_orbis;

#ifdef HAVE_EGL

   memset(&ctx_orbis->pgl_config, 0, sizeof(ctx_orbis->pgl_config));
   {
      ctx_orbis->pgl_config.size=sizeof(ctx_orbis->pgl_config);
      ctx_orbis->pgl_config.flags=SCE_PGL_FLAGS_USE_COMPOSITE_EXT | SCE_PGL_FLAGS_USE_FLEXIBLE_MEMORY | 0x60;
      ctx_orbis->pgl_config.processOrder=1;
      ctx_orbis->pgl_config.systemSharedMemorySize=0x200000;
      ctx_orbis->pgl_config.videoSharedMemorySize=0x2400000;
      ctx_orbis->pgl_config.maxMappedFlexibleMemory=0xAA00000;
      ctx_orbis->pgl_config.drawCommandBufferSize=0xC0000;
      ctx_orbis->pgl_config.lcueResourceBufferSize=0x10000;
      ctx_orbis->pgl_config.dbgPosCmd_0x40=ATTR_ORBISGL_WIDTH;
      ctx_orbis->pgl_config.dbgPosCmd_0x44=ATTR_ORBISGL_HEIGHT;
      ctx_orbis->pgl_config.dbgPosCmd_0x48=0;
      ctx_orbis->pgl_config.dbgPosCmd_0x4C=0;
      ctx_orbis->pgl_config.unk_0x5C=2;
   }
    ret = scePigletSetConfigurationVSH(&ctx_orbis->pgl_config);
    if (!ret)
    {
		  printf("[ORBISGL] scePigletSetConfigurationVSH failed 0x%08X.\n",ret);
        goto error;
    }

    if (!egl_init_context(&ctx_orbis->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
                          &major, &minor, &n, attribs, NULL))
    {
        egl_report_error();
        printf("[ORBIS]: EGL error: %d.\n", eglGetError());
        goto error;
    }
#endif

    return ctx_orbis;

error:
    orbis_ctx_destroy(video_driver);
    return NULL;
}
Esempio n. 23
0
static bool gfx_ctx_xegl_set_video_mode(void *data,
   unsigned width, unsigned height,
   bool fullscreen)
{
   XEvent event;
   EGLint egl_attribs[16];
   EGLint vid, num_visuals;
   EGLint *attr             = NULL;
   bool windowed_full       = false;
   bool true_full           = false;
   int x_off                = 0;
   int y_off                = 0;
   XVisualInfo temp         = {0};
   XSetWindowAttributes swa = {0};
   XVisualInfo *vi          = NULL;
   settings_t *settings     = config_get_ptr();
   xegl_ctx_data_t *xegl    = (xegl_ctx_data_t*)data;

   int (*old_handler)(Display*, XErrorEvent*) = NULL;

   frontend_driver_install_signal_handler();

   windowed_full = settings->video.windowed_fullscreen;

   attr = egl_attribs;
   attr = xegl_fill_attribs(xegl, attr);

#ifdef HAVE_EGL
   if (!egl_get_native_visual_id(&xegl->egl, &vid))
      goto error;
#endif

   temp.visualid = vid;

   vi = XGetVisualInfo(g_x11_dpy, VisualIDMask, &temp, &num_visuals);
   if (!vi)
      goto error;

   swa.colormap = g_x11_cmap = XCreateColormap(
         g_x11_dpy, RootWindow(g_x11_dpy, vi->screen),
         vi->visual, AllocNone);
   swa.event_mask = StructureNotifyMask | KeyPressMask | 
      ButtonPressMask | ButtonReleaseMask | KeyReleaseMask;
   swa.override_redirect = fullscreen ? True : False;

   if (fullscreen && !windowed_full)
   {
      if (x11_enter_fullscreen(g_x11_dpy, width, height, &xegl->desktop_mode))
      {
         xegl->should_reset_mode = true;
         true_full = true;
      }
      else
         RARCH_ERR("[X/EGL]: Entering true fullscreen failed. Will attempt windowed mode.\n");
   }

   if (settings->video.monitor_index)
      g_x11_screen = settings->video.monitor_index - 1;

#ifdef HAVE_XINERAMA
   if (fullscreen || g_x11_screen != 0)
   {
      unsigned new_width  = width;
      unsigned new_height = height;

      if (x11_get_xinerama_coord(g_x11_dpy, g_x11_screen,
               &x_off, &y_off, &new_width, &new_height))
         RARCH_LOG("[X/EGL]: Using Xinerama on screen #%u.\n", g_x11_screen);
      else
         RARCH_LOG("[X/EGL]: Xinerama is not active on screen.\n");

      if (fullscreen)
      {
         width  = new_width;
         height = new_height;
      }
   }
#endif

   RARCH_LOG("[X/EGL]: X = %d, Y = %d, W = %u, H = %u.\n",
         x_off, y_off, width, height);

   g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen),
         x_off, y_off, width, height, 0,
         vi->depth, InputOutput, vi->visual, 
         CWBorderPixel | CWColormap | CWEventMask | 
         (true_full ? CWOverrideRedirect : 0), &swa);
   XSetWindowBackground(g_x11_dpy, g_x11_win, 0);

   if (!egl_create_context(&xegl->egl, (attr != egl_attribs) ? egl_attribs : NULL))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_surface(&xegl->egl, (void*)g_x11_win))
      goto error;

   x11_set_window_attr(g_x11_dpy, g_x11_win);
   x11_update_window_title(NULL);

   if (fullscreen)
      x11_show_mouse(g_x11_dpy, g_x11_win, false);

   if (true_full)
   {
      RARCH_LOG("[X/EGL]: Using true fullscreen.\n");
      XMapRaised(g_x11_dpy, g_x11_win);
   }
   else if (fullscreen) 
   {
      /* We attempted true fullscreen, but failed.
       * Attempt using windowed fullscreen. */
      XMapRaised(g_x11_dpy, g_x11_win);
      RARCH_LOG("[X/EGL]: Using windowed fullscreen.\n");

      /* We have to move the window to the screen we 
       * want to go fullscreen on first.
       * x_off and y_off usually get ignored in XCreateWindow().
       */
      x11_move_window(g_x11_dpy, g_x11_win, x_off, y_off, width, height);
      x11_windowed_fullscreen(g_x11_dpy, g_x11_win);
   }
   else
   {
      XMapWindow(g_x11_dpy, g_x11_win);

      /* If we want to map the window on a different screen, 
       * we'll have to do it by force.
       *
       * Otherwise, we should try to let the window manager sort it out.
       * x_off and y_off usually get ignored in XCreateWindow().
       */
      if (g_x11_screen)
         x11_move_window(g_x11_dpy, g_x11_win, x_off, y_off, width, height);
   }

   x11_event_queue_check(&event);
   x11_install_quit_atom();

#ifdef HAVE_EGL
   gfx_ctx_xegl_set_swap_interval(&xegl->egl, xegl->egl.interval);
#endif

   /* This can blow up on some drivers. It's not fatal, 
    * so override errors for this call.
    */
   old_handler = XSetErrorHandler(x_nul_handler);
   XSetInputFocus(g_x11_dpy, g_x11_win, RevertToNone, CurrentTime);
   XSync(g_x11_dpy, False);
   XSetErrorHandler(old_handler);

   XFree(vi);
   g_egl_inited = true;

   if (!x11_input_ctx_new(true_full))
      goto error;

   return true;

error:
   if (vi)
      XFree(vi);

   gfx_ctx_xegl_destroy(data);
   return false;
}
Esempio n. 24
0
static void *gfx_ctx_emscripten_init(void *video_driver)
{
#ifdef HAVE_EGL
   unsigned width, height;
   EGLint major, minor;
   EGLint n;
   static const EGLint attribute_list[] =
   {
      EGL_RED_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_BLUE_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_NONE
   };
   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
#endif
   emscripten_ctx_data_t *emscripten = (emscripten_ctx_data_t*)
      calloc(1, sizeof(*emscripten));

   if (!emscripten)
      return NULL;

   (void)video_driver;

#ifdef HAVE_EGL
   if (g_egl_inited)
   {
      RARCH_LOG("[EMSCRIPTEN/EGL]: Attempted to re-initialize driver.\n");
      return (void*)"emscripten";
   }

   if (!egl_init_context(&emscripten->egl, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribute_list))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_context(&emscripten->egl, context_attributes))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_surface(&emscripten->egl, 0))
      goto error;

   egl_get_video_size(&emscripten->egl, &width, &height);

   emscripten->fb_width  = width;
   emscripten->fb_height = height;
   RARCH_LOG("[EMSCRIPTEN/EGL]: Dimensions: %ux%u\n", width, height);
#endif

   return emscripten;

error:
   gfx_ctx_emscripten_destroy(video_driver);
   return NULL;
}
Esempio n. 25
0
static void *gfx_ctx_wl_init(void *video_driver)
{
   static const EGLint egl_attribs_gl[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };

   static const EGLint egl_attribs_gles[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };

#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif

   static const EGLint egl_attribs_vg[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   EGLint major = 0, minor = 0;
   EGLint n;
   const EGLint *attrib_ptr;
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)
      calloc(1, sizeof(gfx_ctx_wayland_data_t));

   (void)video_driver;

   if (!wl)
      return NULL;

   switch (wl->egl.api)
   {
      case GFX_CTX_OPENGL_API:
         attrib_ptr = egl_attribs_gl;
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_KHR_create_context
         if (g_egl_major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
            attrib_ptr = egl_attribs_gles;
         break;
      case GFX_CTX_OPENVG_API:
         attrib_ptr = egl_attribs_vg;
         break;
      default:
         attrib_ptr = NULL;
   }

   g_egl_quit = 0;

   wl->dpy = wl_display_connect(NULL);
   if (!wl->dpy)
   {
      RARCH_ERR("Failed to connect to Wayland server.\n");
      goto error;
   }

   wl->registry = wl_display_get_registry(wl->dpy);
   wl_registry_add_listener(wl->registry, &registry_listener, wl);
   wl_display_dispatch(wl->dpy);
   wl_display_roundtrip(wl->dpy);

   if (!wl->compositor)
   {
      RARCH_ERR("Failed to create compositor.\n");
      goto error;
   }

   if (!wl->shell)
   {
      RARCH_ERR("Failed to create shell.\n");
      goto error;
   }

   wl->fd = wl_display_get_fd(wl->dpy);

   if (!egl_init_context(wl, (EGLNativeDisplayType)wl->dpy,
            &major, &minor, &n, attrib_ptr))
   {
      egl_report_error();
      goto error;
   }

   if (n == 0 || !egl_has_config(wl))
      goto error;

   return wl;

error:
   gfx_ctx_wl_destroy_resources(wl);

   if (wl)
      free(wl);

   return NULL;
}