Untitled

 avatar
unknown
plain_text
a month ago
2.7 kB
2
Indexable
Here's the EGL/DMA-BUF integration code needed:

Add EGL texture creation in render/gles2/texture.c:

cCopyEGLImage create_egl_image_from_buffer(struct wlr_egl *egl, 
                                     struct wlr_udmabuf_buffer *buffer) {
    EGLint attribs[] = {
        EGL_WIDTH, buffer->dmabuf.width,
        EGL_HEIGHT, buffer->dmabuf.height,
        EGL_LINUX_DRM_FOURCC_EXT, buffer->dmabuf.format,
        EGL_DMA_BUF_PLANE0_FD_EXT, buffer->dmabuf.fd[0],
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, buffer->dmabuf.offset[0],
        EGL_DMA_BUF_PLANE0_PITCH_EXT, buffer->dmabuf.stride[0],
        EGL_NONE
    };

    return eglCreateImageKHR(egl->display, EGL_NO_CONTEXT,
                            EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
}

Add texture interface implementation:

cCopystatic const struct wlr_texture_impl texture_impl = {
    .get_size = texture_get_size,
    .write_pixels = texture_write_pixels,
    .destroy = texture_destroy,
};

struct wlr_texture *import_dmabuf(struct wlr_renderer *renderer,
                                struct wlr_udmabuf_buffer *buffer) {
    struct wlr_gles2_texture *texture = calloc(1, sizeof(*texture));
    if (!texture) return NULL;

    wlr_texture_init(&texture->base, &texture_impl, buffer->width, buffer->height);
    texture->target = GL_TEXTURE_2D;
    
    EGLImage image = create_egl_image_from_buffer(renderer->egl, buffer);
    if (image == EGL_NO_IMAGE) {
        free(texture);
        return NULL;
    }

    glGenTextures(1, &texture->tex);
    glBindTexture(GL_TEXTURE_2D, texture->tex);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    
    eglDestroyImageKHR(renderer->egl->display, image);

    return &texture->base;
}

Add synchronization in buffer.c:

cCopystruct wlr_udmabuf_buffer_sync {
    EGLSyncKHR sync;
    struct wl_event_source *event_source;
};

static void buffer_begin_data_ptr_access(struct wlr_buffer *buffer) {
    struct wlr_udmabuf_buffer *udmabuf = get_udmabuf_buffer(buffer);
    glFinish(); // Ensure GPU is done
}

static void buffer_end_data_ptr_access(struct wlr_buffer *buffer) {
    struct wlr_udmabuf_buffer *udmabuf = get_udmabuf_buffer(buffer);
    // Create fence for GPU sync
    udmabuf->sync = eglCreateSyncKHR(egl->display, EGL_SYNC_FENCE_KHR, NULL);
}
Add these function pointers to your buffer_impl:
cCopystatic const struct wlr_buffer_impl buffer_impl = {
    .destroy = buffer_destroy,
    .get_shm = buffer_get_shm,  
    .get_dmabuf = buffer_get_dmabuf,
    .begin_data_ptr_access = buffer_begin_data_ptr_access,
    .end_data_ptr_access = buffer_end_data_ptr_access,
};
This completes the integration between udmabuf and wlroots' rendering system.
Leave a Comment