コード例 #1
0
static CoglBool
_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
{
  CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
  CoglContext *ctx = tex->context;
  CoglTexturePixmapEGL *egl_tex_pixmap;
  EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
  CoglPixelFormat texture_format;
  CoglRendererEGL *egl_renderer;

  egl_renderer = ctx->display->renderer->winsys;

  if (!(egl_renderer->private_features &
        COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) ||
      !_cogl_has_private_feature
      (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE))
    {
      tex_pixmap->winsys = NULL;
      return FALSE;
    }

  egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1);

  egl_tex_pixmap->image =
    _cogl_egl_create_image (ctx,
                            EGL_NATIVE_PIXMAP_KHR,
                            (EGLClientBuffer)tex_pixmap->pixmap,
                            attribs);
  if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR)
    {
      g_free (egl_tex_pixmap);
      return FALSE;
    }

  texture_format = (tex_pixmap->depth >= 32 ?
                    COGL_PIXEL_FORMAT_RGBA_8888_PRE :
                    COGL_PIXEL_FORMAT_RGB_888);

  egl_tex_pixmap->texture = COGL_TEXTURE (
    cogl_egl_texture_2d_new_from_image (ctx,
                                        tex->width,
                                        tex->height,
                                        texture_format,
                                        egl_tex_pixmap->image,
                                        NULL));

  tex_pixmap->winsys = egl_tex_pixmap;

  return TRUE;
}
コード例 #2
0
ファイル: cogl-texture-2d.c プロジェクト: collinss/muffin
CoglTexture2D *
cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx,
                                         struct wl_resource *buffer,
                                         CoglError **error)
{
  struct wl_shm_buffer *shm_buffer;
  CoglTexture2D *tex = NULL;

  shm_buffer = wl_shm_buffer_get (buffer);

  if (shm_buffer)
    {
      int stride = wl_shm_buffer_get_stride (shm_buffer);
      int width = wl_shm_buffer_get_width (shm_buffer);
      int height = wl_shm_buffer_get_height (shm_buffer);
      CoglPixelFormat format;
      CoglTextureComponents components;
      CoglBitmap *bmp;

      shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);

      bmp = cogl_bitmap_new_for_data (ctx,
                                      width, height,
                                      format,
                                      stride,
                                      wl_shm_buffer_get_data (shm_buffer));

      tex = cogl_texture_2d_new_from_bitmap (bmp);

      cogl_texture_set_components (COGL_TEXTURE (tex), components);

      cogl_object_unref (bmp);

      if (!cogl_texture_allocate (COGL_TEXTURE (tex), error))
        {
          cogl_object_unref (tex);
          return NULL;
        }
      else
        return tex;
    }
  else
    {
      int format, width, height;

      if (_cogl_egl_query_wayland_buffer (ctx,
                                          buffer,
                                          EGL_TEXTURE_FORMAT,
                                          &format) &&
          _cogl_egl_query_wayland_buffer (ctx,
                                          buffer,
                                          EGL_WIDTH,
                                          &width) &&
          _cogl_egl_query_wayland_buffer (ctx,
                                          buffer,
                                          EGL_HEIGHT,
                                          &height))
        {
          EGLImageKHR image;
          CoglPixelFormat internal_format;

          _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints &
                                    COGL_RENDERER_CONSTRAINT_USES_EGL,
                                    NULL);

          switch (format)
            {
            case EGL_TEXTURE_RGB:
              internal_format = COGL_PIXEL_FORMAT_RGB_888;
              break;
            case EGL_TEXTURE_RGBA:
              internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
              break;
            default:
              _cogl_set_error (error,
                               COGL_SYSTEM_ERROR,
                               COGL_SYSTEM_ERROR_UNSUPPORTED,
                               "Can't create texture from unknown "
                               "wayland buffer format %d\n", format);
              return NULL;
            }

          image = _cogl_egl_create_image (ctx,
                                          EGL_WAYLAND_BUFFER_WL,
                                          buffer,
                                          NULL);
          tex = cogl_egl_texture_2d_new_from_image (ctx,
                                                    width, height,
                                                    internal_format,
                                                    image,
                                                    error);
          _cogl_egl_destroy_image (ctx, image);
          return tex;
        }
    }

  _cogl_set_error (error,
                   COGL_SYSTEM_ERROR,
                   COGL_SYSTEM_ERROR_UNSUPPORTED,
                   "Can't create texture from unknown "
                   "wayland buffer type\n");
  return NULL;
}
コード例 #3
0
ファイル: meta-wayland-buffer.c プロジェクト: endlessm/mutter
static gboolean
egl_image_buffer_attach (MetaWaylandBuffer  *buffer,
                         CoglTexture       **texture,
                         gboolean           *changed_texture,
                         GError            **error)
{
  MetaBackend *backend = meta_get_backend ();
  MetaEgl *egl = meta_backend_get_egl (backend);
  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
  CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
  EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
  int format, width, height, y_inverted;
  CoglPixelFormat cogl_format;
  EGLImageKHR egl_image;
  CoglTexture2D *texture_2d;

  if (buffer->egl_image.texture)
    {
      *changed_texture = *texture != buffer->egl_image.texture;
      cogl_clear_object (texture);
      *texture = cogl_object_ref (buffer->egl_image.texture);
      return TRUE;
    }

  if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
                                      EGL_TEXTURE_FORMAT, &format,
                                      error))
    return FALSE;

  if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
                                      EGL_WIDTH, &width,
                                      error))
    return FALSE;

  if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
                                      EGL_HEIGHT, &height,
                                      error))
    return FALSE;

  if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
                                      EGL_WAYLAND_Y_INVERTED_WL, &y_inverted,
                                      NULL))
    y_inverted = EGL_TRUE;

  switch (format)
    {
    case EGL_TEXTURE_RGB:
      cogl_format = COGL_PIXEL_FORMAT_RGB_888;
      break;
    case EGL_TEXTURE_RGBA:
      cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
      break;
    default:
      g_set_error (error, G_IO_ERROR,
                   G_IO_ERROR_FAILED,
                   "Unsupported buffer format %d", format);
      return FALSE;
    }

  /* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used
   * in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
  egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
                                     EGL_WAYLAND_BUFFER_WL, buffer->resource,
                                     NULL,
                                     error);
  if (egl_image == EGL_NO_IMAGE_KHR)
    return FALSE;

  texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context,
                                                   width, height,
                                                   cogl_format,
                                                   egl_image,
                                                   error);

  meta_egl_destroy_image (egl, egl_display, egl_image, NULL);

  if (!texture_2d)
    return FALSE;

  buffer->egl_image.texture = COGL_TEXTURE (texture_2d);
  buffer->is_y_inverted = !!y_inverted;

  cogl_clear_object (texture);
  *texture = cogl_object_ref (buffer->egl_image.texture);
  *changed_texture = TRUE;

  return TRUE;
}