Пример #1
0
static void*
d3d12_font_init_font(void* data, const char* font_path,
      float font_size, bool is_threaded)
{
   d3d12_video_t* d3d12 = (d3d12_video_t*)data;
   d3d12_font_t*  font  = (d3d12_font_t*)calloc(1, sizeof(*font));

   if (!font)
      return NULL;

   if (!font_renderer_create_default(
             (const void**)&font->font_driver,
             &font->font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't initialize font renderer.\n");
      free(font);
      return NULL;
   }

   font->atlas               = font->font_driver->get_atlas(font->font_data);
   font->texture.sampler     = d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_BORDER];
   font->texture.desc.Width  = font->atlas->width;
   font->texture.desc.Height = font->atlas->height;
   font->texture.desc.Format = DXGI_FORMAT_A8_UNORM;
   font->texture.srv_heap    = &d3d12->desc.srv_heap;
   d3d12_init_texture(d3d12->device, &font->texture);
   d3d12_update_texture(
         font->atlas->width, font->atlas->height,
         font->atlas->width, DXGI_FORMAT_A8_UNORM,
         font->atlas->buffer, &font->texture);
   font->atlas->dirty = false;

   return font;
}
Пример #2
0
static void *gl_init_font(void *gl_data, const char *font_path, float font_size)
{
   gl_raster_t *font = (gl_raster_t*)calloc(1, sizeof(*font));
   if (!font)
      return NULL;

   font->gl = (gl_t*)gl_data;

   if (!font_renderer_create_default(&font->font_driver, &font->font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't init font renderer.\n");
      free(font);
      return NULL;
   }

   glGenTextures(1, &font->tex);
   glBindTexture(GL_TEXTURE_2D, font->tex);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

   const struct font_atlas *atlas = font->font_driver->get_atlas(font->font_data);

   unsigned width = next_pow2(atlas->width);
   unsigned height = next_pow2(atlas->height);
   // Ideally, we'd use single component textures, but the difference in ways to do that between core GL and GLES/legacy GL
   // is too great to bother going down that route.
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

   uint8_t *tmp_buffer = (uint8_t*)malloc(atlas->width * atlas->height * 4);
   if (tmp_buffer)
   {
      unsigned i;
      uint8_t *dst = tmp_buffer;
      const uint8_t *src = atlas->buffer;
      for (i = 0; i < atlas->width * atlas->height; i++)
      {
         *dst++ = 0xff;
         *dst++ = 0xff;
         *dst++ = 0xff;
         *dst++ = *src++;
      }
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, atlas->width, atlas->height, GL_RGBA, GL_UNSIGNED_BYTE, tmp_buffer);
      free(tmp_buffer);
   }

   font->tex_width  = width;
   font->tex_height = height;

   glBindTexture(GL_TEXTURE_2D, font->gl->texture[font->gl->tex_index]);
   return font;
}
Пример #3
0
static void* wiiu_font_init_font(void* data, const char* font_path,
      float font_size, bool is_threaded)
{
   uint32_t i;
   wiiu_font_t* font = (wiiu_font_t*)calloc(1, sizeof(*font));

   if (!font)
      return NULL;

   if (!font_renderer_create_default(
            &font->font_driver,
            &font->font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't initialize font renderer.\n");
      free(font);
      return NULL;
   }

   font->atlas = font->font_driver->get_atlas(font->font_data);
   font->texture.surface.width       = font->atlas->width;
   font->texture.surface.height      = font->atlas->height;
   font->texture.surface.depth       = 1;
   font->texture.surface.dim         = GX2_SURFACE_DIM_TEXTURE_2D;
   font->texture.surface.tileMode    = GX2_TILE_MODE_LINEAR_ALIGNED;
   font->texture.viewNumSlices       = 1;

   font->texture.surface.format   = GX2_SURFACE_FORMAT_UNORM_R8;
   font->texture.compMap          = GX2_COMP_SEL(_R, _R, _R, _R);

   GX2CalcSurfaceSizeAndAlignment(&font->texture.surface);
   GX2InitTextureRegs(&font->texture);
   font->texture.surface.image = MEM1_alloc(font->texture.surface.imageSize,
                                 font->texture.surface.alignment);

   for (i = 0; (i < font->atlas->height) && (i < font->texture.surface.height); i++)
      memcpy((uint8_t*)font->texture.surface.image + (i * font->texture.surface.pitch),
             font->atlas->buffer + (i * font->atlas->width), font->atlas->width);

   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, font->texture.surface.image,
                 font->texture.surface.imageSize);

   font->atlas->dirty = false;

   font->ubo_tex = MEM1_alloc(sizeof(*font->ubo_tex), GX2_UNIFORM_BLOCK_ALIGNMENT);
   font->ubo_tex->width = font->texture.surface.width;
   font->ubo_tex->height = font->texture.surface.height;
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, font->ubo_tex,
                 sizeof(*font->ubo_tex));

   return font;
}
Пример #4
0
static void *gl_raster_font_init_font(void *data,
      const char *font_path, float font_size,
      bool is_threaded)
{
   gl_raster_t   *font  = (gl_raster_t*)calloc(1, sizeof(*font));

   if (!font)
      return NULL;

   font->gl = (gl_t*)data;

   if (!font_renderer_create_default((const void**)&font->font_driver,
            &font->font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't initialize font renderer.\n");
      free(font);
      return NULL;
   }

   if (is_threaded)
      video_context_driver_make_current(false);

   glGenTextures(1, &font->tex);
   glBindTexture(GL_TEXTURE_2D, font->tex);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

   font->atlas = font->font_driver->get_atlas(font->font_data);
   font->tex_width  = next_pow2(font->atlas->width);
   font->tex_height = next_pow2(font->atlas->height);

   if (!gl_raster_font_upload_atlas(font))
      goto error;

   font->atlas->dirty = false;

   glBindTexture(GL_TEXTURE_2D, font->gl->texture[font->gl->tex_index]);

   return font;

error:
   gl_raster_font_free_font(font, is_threaded);
   font = NULL;

   return NULL;
}
Пример #5
0
static bool gl_init_font(void *data, const char *font_path, float font_size, unsigned win_width, unsigned win_height)
{
   size_t i, j;
   (void)win_width;
   (void)win_height;

   if (!g_settings.video.font_enable)
      return false;

   (void)font_size;
   gl_t *gl = (gl_t*)data;

   if (font_renderer_create_default(&gl->font_driver, &gl->font))
   {
      glGenTextures(1, &gl->font_tex);
      glBindTexture(GL_TEXTURE_2D, gl->font_tex);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
      glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl->max_font_size);
   }
   else
   {
      RARCH_WARN("Couldn't init font renderer.\n");
      return false;
   }

   for (i = 0; i < 4; i++)
   {
      gl->font_color[4 * i + 0] = g_settings.video.msg_color_r;
      gl->font_color[4 * i + 1] = g_settings.video.msg_color_g;
      gl->font_color[4 * i + 2] = g_settings.video.msg_color_b;
      gl->font_color[4 * i + 3] = 1.0;
   }

   for (i = 0; i < 4; i++)
   {
      for (j = 0; j < 3; j++)
         gl->font_color_dark[4 * i + j] = 0.3 * gl->font_color[4 * i + j];
      gl->font_color_dark[4 * i + 3] = 1.0;
   }

   return true;
}
Пример #6
0
static void *vulkan_raster_font_init_font(void *data,
      const char *font_path, float font_size,
      bool is_threaded)
{
   vulkan_raster_t *font          = 
      (vulkan_raster_t*)calloc(1, sizeof(*font));

#if 0
   VkComponentMapping swizzle = {
      VK_COMPONENT_SWIZZLE_ONE,
      VK_COMPONENT_SWIZZLE_ONE,
      VK_COMPONENT_SWIZZLE_ONE,
      VK_COMPONENT_SWIZZLE_R,
   };
#endif

   if (!font)
      return NULL;

   font->vk = (vk_t*)data;

   if (!font_renderer_create_default((const void**)&font->font_driver,
            &font->font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't initialize font renderer.\n");
      free(font);
      return NULL;
   }

   font->atlas = font->font_driver->get_atlas(font->font_data);
   font->texture = vulkan_create_texture(font->vk, NULL,
         font->atlas->width, font->atlas->height, VK_FORMAT_R8_UNORM, font->atlas->buffer,
         NULL /*&swizzle*/, VULKAN_TEXTURE_STAGING);

   vulkan_map_persistent_texture(
         font->vk->context->device, &font->texture);

   font->texture_optimal = vulkan_create_texture(font->vk, NULL,
         font->atlas->width, font->atlas->height, VK_FORMAT_R8_UNORM, NULL,
         NULL /*&swizzle*/, VULKAN_TEXTURE_DYNAMIC);

   font->needs_update = true;

   return font;
}
Пример #7
0
static void *gdi_init_font(void *data,
      const char *font_path, float font_size,
      bool is_threaded)
{
   gdi_raster_t *font  = (gdi_raster_t*)calloc(1, sizeof(*font));

   if (!font)
      return NULL;

   font->gdi = (gdi_t*)data;

   if (!font_renderer_create_default((const void**)&font->gdi_font_driver,
            &font->gdi_font_data, font_path, font_size))
   {
      RARCH_WARN("Couldn't initialize font renderer.\n");
      return NULL;
   }

   return font;
}
Пример #8
0
static void *vita2d_font_init_font(void *gl_data, const char *font_path, float font_size)
{
	 unsigned int stride, pitch, j, k;
   const struct font_atlas *atlas = NULL;
	 vita_font_t *font = (vita_font_t*)calloc(1, sizeof(*font));

	 if (!font)
	 	 return NULL;

	 if (!font_renderer_create_default((const void**)&font->font_driver,
	 				 &font->font_data, font_path, font_size))
	 {
	 	 RARCH_WARN("Couldn't initialize font renderer.\n");
	 	 free(font);
	 	 return NULL;
	 }

	 atlas = font->font_driver->get_atlas(font->font_data);

	 font->texture = vita2d_create_empty_texture_format(atlas->width,atlas->height,SCE_GXM_TEXTURE_FORMAT_U8_R111);

	 if (!font->texture) {
 		free(font);
 		return NULL;
 	 }

	 vita2d_texture_set_filters(font->texture,
 				   SCE_GXM_TEXTURE_FILTER_POINT,
 				   SCE_GXM_TEXTURE_FILTER_LINEAR);

	 stride = vita2d_texture_get_stride(font->texture);
   uint8_t             *tex32 = vita2d_texture_get_datap(font->texture);
   const uint8_t     *frame32 = atlas->buffer;
   pitch = atlas->width;
   for (j = 0; j < atlas->height; j++)
      for (k = 0; k < atlas->width; k++)
         tex32[k + j*stride] = frame32[k + j*pitch];

   return font;
}
Пример #9
0
static void *switch_font_init_font(void *data, const char *font_path,
                                   float font_size, bool is_threaded)
{
      switch_font_t *font = (switch_font_t *)calloc(1, sizeof(switch_font_t));

      if (!font)
            return NULL;

      if (!font_renderer_create_default((const void **)&font->font_driver,
                                        &font->font_data, font_path, font_size))
      {
            RARCH_WARN("Couldn't initialize font renderer.\n");
            free(font);
            return NULL;
      }

      font->atlas = font->font_driver->get_atlas(font->font_data);

      RARCH_LOG("Switch font driver initialized with backend %s\n", font->font_driver->ident);

      return font;
}
Пример #10
0
static void sdl2_init_font(sdl2_video_t *vid, const char *font_path,
                          unsigned font_size)
{
   int i, r, g, b;
   SDL_Color colors[256];
   SDL_Surface *tmp = NULL;
   SDL_Palette *pal = NULL;
   const struct font_atlas *atlas = NULL;
   settings_t *settings = config_get_ptr();

   if (!settings->video.font_enable)
      return;

   if (!font_renderer_create_default(&vid->font_driver, &vid->font_data,
                                    *font_path ? font_path : NULL, font_size))
   {
      RARCH_WARN("[SDL]: Could not initialize fonts.\n");
      return;
   }

   r = settings->video.msg_color_r * 255;
   g = settings->video.msg_color_g * 255;
   b = settings->video.msg_color_b * 255;

   r = (r < 0) ? 0 : (r > 255 ? 255 : r);
   g = (g < 0) ? 0 : (g > 255 ? 255 : g);
   b = (b < 0) ? 0 : (b > 255 ? 255 : b);

   vid->font_r = r;
   vid->font_g = g;
   vid->font_b = b;

   atlas = vid->font_driver->get_atlas(vid->font_data);

   tmp = SDL_CreateRGBSurfaceFrom(atlas->buffer, atlas->width,
         atlas->height, 8, atlas->width,
         0, 0, 0, 0);

   for (i = 0; i < 256; ++i)
   {
      colors[i].r = colors[i].g = colors[i].b = i;
      colors[i].a = 255;
   }

   pal = SDL_AllocPalette(256);
   SDL_SetPaletteColors(pal, colors, 0, 256);
   SDL_SetSurfacePalette(tmp, pal);
   SDL_SetColorKey(tmp, SDL_TRUE, 0);

   vid->font.tex  = SDL_CreateTextureFromSurface(vid->renderer, tmp);

   if (vid->font.tex)
   {
      vid->font.w      = atlas->width;
      vid->font.h      = atlas->height;
      vid->font.active = true;

      SDL_SetTextureBlendMode(vid->font.tex, SDL_BLENDMODE_ADD);
   }
   else
      RARCH_WARN("[SDL]: Failed to initialize font texture: %s\n", SDL_GetError());

   SDL_FreePalette(pal);
   SDL_FreeSurface(tmp);
}
Пример #11
0
static void *vg_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
   vg_t *vg = (vg_t*)calloc(1, sizeof(vg_t));
   if (!vg)
      return NULL;

   vg->driver = gfx_ctx_init_first(GFX_CTX_OPENVG_API, 0, 0);

   if (!vg->driver)
   {
      free(vg);
      return NULL;
   }

   vg->driver->get_video_size(&vg->mScreenWidth, &vg->mScreenHeight);
   RARCH_LOG("Detecting screen resolution %ux%u.\n", vg->mScreenWidth, vg->mScreenHeight);

   vg->driver->swap_interval(video->vsync ? 1 : 0);
   vg->driver->update_window_title();

   vg->mTexType = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565;
   vg->mKeepAspect = video->force_aspect;

   unsigned win_width  = video->width;
   unsigned win_height = video->height;
   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      win_width  = vg->mScreenWidth;
      win_height = vg->mScreenHeight;
   }

   if (!vg->driver->set_video_mode(win_width, win_height, video->fullscreen))
   {
      free(vg);
      return NULL;
   }

   vg->driver->get_video_size(&vg->mScreenWidth, &vg->mScreenHeight);
   RARCH_LOG("Verified window resolution %ux%u.\n", vg->mScreenWidth, vg->mScreenHeight);
   vg->should_resize = true;

   if (vg->driver->translate_aspect)
      vg->mScreenAspect = vg->driver->translate_aspect(vg->mScreenWidth, vg->mScreenHeight);
   else
      vg->mScreenAspect = (float)vg->mScreenWidth / vg->mScreenHeight;

   VGfloat clearColor[4] = {0, 0, 0, 1};
   vgSetfv(VG_CLEAR_COLOR, 4, clearColor);

   vg->mTextureWidth = vg->mTextureHeight = video->input_scale * RARCH_SCALE_BASE;
   vg->mImage = vgCreateImage(vg->mTexType, vg->mTextureWidth, vg->mTextureHeight,
         video->smooth ? VG_IMAGE_QUALITY_BETTER : VG_IMAGE_QUALITY_NONANTIALIASED);
   vg_set_nonblock_state(vg, !video->vsync);

   vg->driver->input_driver(input, input_data);

   if (g_settings.video.font_enable && font_renderer_create_default(&vg->font_driver, &vg->mFontRenderer))
   {
      vg->mFont = vgCreateFont(0);

      if (vg->mFont != VG_INVALID_HANDLE)
      {
         vg->mFontsOn = true;

         vg->mFontHeight = g_settings.video.font_size * (g_settings.video.font_scale ? (float) vg->mScreenWidth / 1280.0f : 1.0f);

         vg->mPaintFg = vgCreatePaint();
         vg->mPaintBg = vgCreatePaint();
         VGfloat paintFg[] = { g_settings.video.msg_color_r, g_settings.video.msg_color_g, g_settings.video.msg_color_b, 1.0f };
         VGfloat paintBg[] = { g_settings.video.msg_color_r / 2.0f, g_settings.video.msg_color_g / 2.0f, g_settings.video.msg_color_b / 2.0f, 0.5f };

         vgSetParameteri(vg->mPaintFg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(vg->mPaintFg, VG_PAINT_COLOR, 4, paintFg);

         vgSetParameteri(vg->mPaintBg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(vg->mPaintBg, VG_PAINT_COLOR, 4, paintBg);
      }
   }

   if (vg_query_extension("KHR_EGL_image") && vg->driver->init_egl_image_buffer(video))
   {
      pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)vg->driver->get_proc_address("vgCreateEGLImageTargetKHR");

      if (pvgCreateEGLImageTargetKHR)
      {
         RARCH_LOG("[VG] Using EGLImage buffer\n");
         vg->mEglImageBuf = true;
      }
   }

#if 0
   const char *ext = (const char*)vgGetString(VG_EXTENSIONS);
   if (ext)
      RARCH_LOG("[VG] Supported extensions: %s\n", ext);
#endif

   return vg;
}
Пример #12
0
static void *vg_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
   unsigned temp_width = 0, temp_height = 0;
   VGfloat clearColor[4] = {0, 0, 0, 1};
   settings_t        *settings = config_get_ptr();
   driver_t            *driver = driver_get_ptr();
   const gfx_ctx_driver_t *ctx = NULL;
   vg_t                    *vg = (vg_t*)calloc(1, sizeof(vg_t));

   if (!vg)
      goto error;

   ctx = gfx_ctx_init_first(vg, settings->video.context_driver,
         GFX_CTX_OPENVG_API, 0, 0, false);

   if (!ctx)
      goto error;

   driver->video_context = ctx;

   gfx_ctx_get_video_size(vg, &temp_width, &temp_height);
   RARCH_LOG("Detecting screen resolution %ux%u.\n", temp_width, temp_height);

   if (temp_width != 0 && temp_height != 0)
   {
      video_driver_set_size_width(temp_width);
      video_driver_set_size_width(temp_height);
   }

   gfx_ctx_swap_interval(vg, video->vsync ? 1 : 0);

   gfx_ctx_update_window_title(vg);

   vg->mTexType    = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565;
   vg->keep_aspect = video->force_aspect;

   unsigned win_width  = video->width;
   unsigned win_height = video->height;
   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      video_driver_get_size(&temp_width, &temp_height);

      win_width  = temp_width;
      win_height = temp_height;
   }

   if (!gfx_ctx_set_video_mode(vg, win_width, win_height, video->fullscreen))
      goto error;

   video_driver_get_size(&temp_width, &temp_height);

   temp_width  = 0;
   temp_height = 0;
   gfx_ctx_get_video_size(vg, &temp_width, &temp_height);
   vg->should_resize = true;

   if (temp_width != 0 && temp_height != 0)
   {
      RARCH_LOG("Verified window resolution %ux%u.\n", temp_width, temp_height);
      video_driver_set_size_width(temp_width);
      video_driver_set_size_height(temp_height);
   }

   video_driver_get_size(&temp_width, &temp_height);

   vg->mScreenAspect = (float)temp_width / temp_height;

   gfx_ctx_translate_aspect(vg, &vg->mScreenAspect, temp_width, temp_height);

   vgSetfv(VG_CLEAR_COLOR, 4, clearColor);

   vg->mTextureWidth = vg->mTextureHeight = video->input_scale * RARCH_SCALE_BASE;
   vg->mImage = vgCreateImage(vg->mTexType, vg->mTextureWidth, vg->mTextureHeight,
         video->smooth ? VG_IMAGE_QUALITY_BETTER : VG_IMAGE_QUALITY_NONANTIALIASED);
   vg_set_nonblock_state(vg, !video->vsync);

   gfx_ctx_input_driver(vg, input, input_data);

   if (settings->video.font_enable && font_renderer_create_default(&vg->font_driver, &vg->mFontRenderer,
            *settings->video.font_path ? settings->video.font_path : NULL, settings->video.font_size))
   {
      vg->mFont            = vgCreateFont(0);

      if (vg->mFont != VG_INVALID_HANDLE)
      {
         vg->mFontsOn      = true;
         vg->mFontHeight   = settings->video.font_size;
         vg->mPaintFg      = vgCreatePaint();
         vg->mPaintBg      = vgCreatePaint();
         VGfloat paintFg[] = { settings->video.msg_color_r, settings->video.msg_color_g, settings->video.msg_color_b, 1.0f };
         VGfloat paintBg[] = { settings->video.msg_color_r / 2.0f, settings->video.msg_color_g / 2.0f, settings->video.msg_color_b / 2.0f, 0.5f };

         vgSetParameteri(vg->mPaintFg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(vg->mPaintFg, VG_PAINT_COLOR, 4, paintFg);

         vgSetParameteri(vg->mPaintBg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(vg->mPaintBg, VG_PAINT_COLOR, 4, paintBg);
      }
   }

   if (vg_query_extension("KHR_EGL_image") && gfx_ctx_image_buffer_init(vg, video))
   {
      pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)gfx_ctx_get_proc_address("vgCreateEGLImageTargetKHR");

      if (pvgCreateEGLImageTargetKHR)
      {
         RARCH_LOG("[VG] Using EGLImage buffer\n");
         vg->mEglImageBuf = true;
      }
   }

#if 0
   const char *ext = (const char*)vgGetString(VG_EXTENSIONS);
   if (ext)
      RARCH_LOG("[VG] Supported extensions: %s\n", ext);
#endif

   return vg;

error:
   if (vg)
      free(vg);
   if (driver)
      driver->video_context = NULL;
   return NULL;
}