rdprail_gbm.c
unknown
plain_text
a month ago
5.0 kB
1
Indexable
#include <assert.h> #include <stdlib.h> #include <unistd.h> #include <gbm.h> #include <wlr/util/log.h> #include "rdprail.h" struct wlr_rdp_gbm_allocator { struct wlr_allocator base; GfxRedirServerContext *redir_ctx; struct gbm_device *gbm; }; struct wlr_rdp_gbm_buffer { struct wlr_buffer buffer; uint32_t pool_id; uint32_t buffer_id; struct gbm_bo *bo; void *map_data; void *rdp_memory; // Direct mapped memory size_t rdp_memory_size; int width; int height; int fd; // -1 since we're using direct mapping bool data_access_in_progress; uint32_t stride; }; static struct wlr_buffer *rdp_gbm_allocator_create_buffer( struct wlr_allocator *alloc, int width, int height, const struct wlr_drm_format *format) { struct wlr_rdp_gbm_allocator *rdp_alloc = (struct wlr_rdp_gbm_allocator *)alloc; // Create GBM buffer with known working settings struct gbm_bo *bo = gbm_bo_create(rdp_alloc->gbm, width, height, GBM_FORMAT_XRGB8888, // Known working format GBM_BO_USE_SCANOUT); // Known working flag if (!bo) { wlr_log(WLR_ERROR, "Failed to create GBM buffer"); return NULL; } // Create RDP pool GFXREDIR_OPEN_POOL_PDU open_pool = {0}; if (rdp_alloc->redir_ctx->OpenPool(rdp_alloc->redir_ctx, &open_pool) != 0) { wlr_log(WLR_ERROR, "Failed to open RDP pool"); gbm_bo_destroy(bo); return NULL; } // Create buffer in RDP GFXREDIR_CREATE_BUFFER_PDU create_buffer = { .poolId = open_pool.poolId, .width = width, .height = height, .format = 0 // Format value from your RDP implementation }; if (rdp_alloc->redir_ctx->CreateBuffer(rdp_alloc->redir_ctx, &create_buffer) != 0) { wlr_log(WLR_ERROR, "Failed to create RDP buffer"); gbm_bo_destroy(bo); return NULL; } struct wlr_rdp_gbm_buffer *buffer = calloc(1, sizeof(*buffer)); if (buffer == NULL) { gbm_bo_destroy(bo); return NULL; } buffer->pool_id = open_pool.poolId; buffer->buffer_id = create_buffer.bufferId; buffer->bo = bo; buffer->width = width; buffer->height = height; buffer->fd = -1; // No fd since we're using direct mapping buffer->data_access_in_progress = false; // Map the buffer for CPU access void *data = NULL; void *map_data = gbm_bo_map(bo, 0, 0, width, height, GBM_BO_TRANSFER_WRITE | GBM_BO_TRANSFER_READ, &buffer->stride, &data); if (!map_data || !data) { wlr_log(WLR_ERROR, "Failed to map GBM buffer"); free(buffer); gbm_bo_destroy(bo); return NULL; } buffer->map_data = map_data; buffer->rdp_memory = data; buffer->rdp_memory_size = buffer->stride * height; // Initialize wlr_buffer wlr_buffer_init(&buffer->buffer, &buffer_impl, width, height); return &buffer->buffer; } static void rdp_gbm_buffer_destroy(struct wlr_buffer *wlr_buffer) { struct wlr_rdp_gbm_buffer *buffer = (struct wlr_rdp_gbm_buffer *)wlr_buffer; if (buffer->data_access_in_progress) { wlr_rdp_buffer_end_data_ptr_access(wlr_buffer); } if (buffer->map_data) { gbm_bo_unmap(buffer->bo, buffer->map_data); } if (buffer->bo) { gbm_bo_destroy(buffer->bo); } free(buffer); } static bool rdp_gbm_buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer, uint32_t flags, void **data, uint32_t *stride) { struct wlr_rdp_gbm_buffer *buffer = (struct wlr_rdp_gbm_buffer *)wlr_buffer; *data = buffer->rdp_memory; *stride = buffer->stride; buffer->data_access_in_progress = true; return true; } static void rdp_gbm_buffer_end_data_ptr_access(struct wlr_buffer *wlr_buffer) { struct wlr_rdp_gbm_buffer *buffer = (struct wlr_rdp_gbm_buffer *)wlr_buffer; buffer->data_access_in_progress = false; } static const struct wlr_buffer_impl buffer_impl = { .destroy = rdp_gbm_buffer_destroy, .begin_data_ptr_access = rdp_gbm_buffer_begin_data_ptr_access, .end_data_ptr_access = rdp_gbm_buffer_end_data_ptr_access, }; static void rdp_gbm_allocator_destroy(struct wlr_allocator *wlr_alloc) { struct wlr_rdp_gbm_allocator *alloc = (struct wlr_rdp_gbm_allocator *)wlr_alloc; if (alloc == NULL) { return; } free(alloc); } static const struct wlr_allocator_interface rdp_gbm_allocator_impl = { .create_buffer = rdp_gbm_allocator_create_buffer, .destroy = rdp_gbm_allocator_destroy, }; struct wlr_allocator *wlr_rdp_gbm_allocator_create( GfxRedirServerContext *redir_ctx, struct gbm_device *gbm) { struct wlr_rdp_gbm_allocator *alloc = calloc(1, sizeof(*alloc)); if (alloc == NULL) { return NULL; } wlr_allocator_init(&alloc->base, &rdp_gbm_allocator_impl, WLR_BUFFER_CAP_DATA_PTR); alloc->redir_ctx = redir_ctx; alloc->gbm = gbm; return &alloc->base; }
Editor is loading...
Leave a Comment