static uint32_t create_buffer (ply_renderer_driver_t *driver, unsigned long width, unsigned long height, unsigned long *row_stride) { ply_renderer_buffer_t *buffer; buffer = ply_renderer_buffer_new (driver, width, height); if (buffer == NULL) { ply_trace ("Could not allocate GEM object for frame buffer: %m"); return 0; } if (drmModeAddFB (driver->device_fd, width, height, 24, 32, buffer->row_stride, buffer->handle, &buffer->id) != 0) { ply_trace ("Could not set up GEM object as frame buffer: %m"); ply_renderer_buffer_free (driver, buffer); return 0; } *row_stride = buffer->row_stride; buffer->added_fb = true; ply_hashtable_insert (driver->buffers, (void *) (uintptr_t) buffer->id, buffer); return buffer->id; }
static bool create_heads_for_active_connectors (ply_renderer_backend_t *backend) { int i; drmModeConnector *connector; ply_hashtable_t *heads_by_controller_id; heads_by_controller_id = ply_hashtable_new (NULL, NULL); for (i = 0; i < backend->resources->count_connectors; i++) { ply_renderer_head_t *head; drmModeEncoder *encoder; uint32_t encoder_id; drmModeCrtc *controller; uint32_t controller_id; uint32_t console_buffer_id; int connector_mode_index; connector = drmModeGetConnector (backend->device_fd, backend->resources->connectors[i]); if (connector == NULL) continue; if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector (connector); continue; } if (connector->count_modes <= 0) { drmModeFreeConnector (connector); continue; } encoder = find_encoder_for_connector (backend, connector); if (encoder == NULL) { drmModeFreeConnector (connector); continue; } encoder_id = encoder->encoder_id; controller = find_controller_for_encoder (backend, encoder); drmModeFreeEncoder (encoder); if (controller == NULL) { drmModeFreeConnector (connector); continue; } controller_id = controller->crtc_id; connector_mode_index = get_index_of_active_mode (backend, controller, connector); /* If we couldn't find the current active mode, fall back to the first available. */ if (connector_mode_index < 0) { ply_trace ("falling back to first available mode"); connector_mode_index = 0; } console_buffer_id = controller->buffer_id; drmModeFreeCrtc (controller); head = ply_hashtable_lookup (heads_by_controller_id, (void *) (intptr_t) controller_id); if (head == NULL) { head = ply_renderer_head_new (backend, connector, connector_mode_index, encoder_id, controller_id, console_buffer_id); ply_list_append_data (backend->heads, head); ply_hashtable_insert (heads_by_controller_id, (void *) (intptr_t) controller_id, head); } else { if (!ply_renderer_head_add_connector (head, connector, connector_mode_index)) { ply_trace ("couldn't connect monitor to existing head"); } drmModeFreeConnector (connector); } } ply_hashtable_free (heads_by_controller_id); #ifdef PLY_ENABLE_DEPRECATED_GDM_TRANSITION /* If the driver doesn't support mapping the fb console * then we can't get a smooth crossfade transition to * the display manager unless we use the /dev/fb interface * or the plymouth deactivate interface. * * In multihead configurations, we'd rather have working * multihead, but otherwise bail now. */ if (!backend->driver_supports_mapping_console && ply_list_get_length (backend->heads) == 1) { ply_list_node_t *node; ply_renderer_head_t *head; node = ply_list_get_first_node (backend->heads); head = (ply_renderer_head_t *) ply_list_node_get_data (node); if (ply_array_get_size (head->connector_ids) == 1) { ply_trace ("Only one monitor configured, and driver doesn't " "support mapping console, so letting frame-buffer " "take over"); free_heads (backend); return false; } } #endif return ply_list_get_length (backend->heads) > 0; }