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; }
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; }
static gboolean _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; CoglDisplay *display = context->display; CoglDisplayEGL *egl_display = display->winsys; CoglDisplayKMS *kms_display = egl_display->platform; CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererKMS *kms_renderer = egl_renderer->platform; CoglOnscreenEGL *egl_onscreen; CoglOnscreenKMS *kms_onscreen; int i; _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); onscreen->winsys = g_slice_new0 (CoglOnscreenEGL); egl_onscreen = onscreen->winsys; kms_onscreen = g_slice_new0 (CoglOnscreenKMS); egl_onscreen->platform = kms_onscreen; context->glGenRenderbuffers (2, kms_onscreen->color_rb); for (i = 0; i < 2; i++) { uint32_t handle, stride; kms_onscreen->bo[i] = gbm_bo_create (kms_renderer->gbm, kms_display->mode.hdisplay, kms_display->mode.vdisplay, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!kms_onscreen->bo[i]) { g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Failed to allocate buffer"); return FALSE; } kms_onscreen->image[i] = _cogl_egl_create_image (context, EGL_NATIVE_PIXMAP_KHR, kms_onscreen->bo[i], NULL); if (kms_onscreen->image[i] == EGL_NO_IMAGE_KHR) { g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Failed to create EGL image"); return FALSE; } context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, kms_onscreen->color_rb[i]); context->glEGLImageTargetRenderbufferStorage (GL_RENDERBUFFER, kms_onscreen->image[i]); context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, 0); handle = gbm_bo_get_handle (kms_onscreen->bo[i]).u32; stride = gbm_bo_get_pitch (kms_onscreen->bo[i]); if (drmModeAddFB (kms_renderer->fd, kms_display->mode.hdisplay, kms_display->mode.vdisplay, 24, 32, stride, handle, &kms_onscreen->fb_id[i]) != 0) { g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Failed to create framebuffer from buffer"); return FALSE; } } context->glGenFramebuffers (1, &kms_onscreen->fb); context->glBindFramebuffer (GL_FRAMEBUFFER_EXT, kms_onscreen->fb); context->glGenRenderbuffers (1, &kms_onscreen->depth_rb); context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, kms_onscreen->depth_rb); context->glRenderbufferStorage (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, kms_display->mode.hdisplay, kms_display->mode.vdisplay); context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, 0); context->glFramebufferRenderbuffer (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, kms_onscreen->depth_rb); kms_onscreen->current_frame = 0; _cogl_winsys_onscreen_swap_buffers (onscreen); _cogl_framebuffer_winsys_update_size (framebuffer, kms_display->width, kms_display->height); return TRUE; }
CoglTexture2D * cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx, struct wl_buffer *buffer, CoglError **error) { if (wl_buffer_is_shm (buffer)) { int stride = wl_shm_buffer_get_stride (buffer); CoglPixelFormat format; CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY; switch (wl_shm_buffer_get_format (buffer)) { #if G_BYTE_ORDER == G_BIG_ENDIAN case WL_SHM_FORMAT_ARGB8888: format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; break; case WL_SHM_FORMAT_XRGB32: format = COGL_PIXEL_FORMAT_ARGB_8888; internal_format = COGL_PIXEL_FORMAT_RGB_888; break; #elif G_BYTE_ORDER == G_LITTLE_ENDIAN case WL_SHM_FORMAT_ARGB8888: format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; break; case WL_SHM_FORMAT_XRGB8888: format = COGL_PIXEL_FORMAT_BGRA_8888; internal_format = COGL_PIXEL_FORMAT_BGR_888; break; #endif default: g_warn_if_reached (); format = COGL_PIXEL_FORMAT_ARGB_8888; } return cogl_texture_2d_new_from_data (ctx, buffer->width, buffer->height, format, internal_format, stride, wl_shm_buffer_get_data (buffer), error); } else { EGLImageKHR image; CoglTexture2D *tex; _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & COGL_RENDERER_CONSTRAINT_USES_EGL, NULL); image = _cogl_egl_create_image (ctx, EGL_WAYLAND_BUFFER_WL, buffer, NULL); tex = _cogl_egl_texture_2d_new_from_image (ctx, buffer->width, buffer->height, COGL_PIXEL_FORMAT_ARGB_8888_PRE, image, error); _cogl_egl_destroy_image (ctx, image); return tex; } }