static void init_crtc_rotations (MetaMonitorManager *manager, MetaCRTC *crtc, unsigned int idx) { MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); drmModeObjectPropertiesPtr props; drmModePlaneRes *planes; drmModePlane *drm_plane; MetaCRTCKms *crtc_kms; unsigned int i; crtc_kms = crtc->driver_private; planes = drmModeGetPlaneResources(manager_kms->fd); if (planes == NULL) return; for (i = 0; i < planes->count_planes; i++) { drmModePropertyPtr prop; drm_plane = drmModeGetPlane (manager_kms->fd, planes->planes[i]); if (!drm_plane) continue; if ((drm_plane->possible_crtcs & (1 << idx))) { props = drmModeObjectGetProperties (manager_kms->fd, drm_plane->plane_id, DRM_MODE_OBJECT_PLANE); if (props && is_primary_plane (manager, props)) { int rotation_idx; crtc_kms->primary_plane_id = drm_plane->plane_id; rotation_idx = find_property_index (manager, props, "rotation", &prop); if (rotation_idx >= 0) { crtc_kms->rotation_prop_id = props->props[rotation_idx]; parse_transforms (manager, prop, crtc); drmModeFreeProperty (prop); } } if (props) drmModeFreeObjectProperties (props); } drmModeFreePlane (drm_plane); } drmModeFreePlaneResources (planes); }
/* Pick a plane.. something that at a minimum can be connected to * the chosen crtc, but prefer primary plane. * * Seems like there is some room for a drmModeObjectGetNamedProperty() * type helper in libdrm.. */ static int get_plane_id(void) { drmModePlaneResPtr plane_resources; uint32_t i, j; int ret = -EINVAL; int found_primary = 0; plane_resources = drmModeGetPlaneResources(drm.fd); if (!plane_resources) { printf("drmModeGetPlaneResources failed: %s\n", strerror(errno)); return -1; } for (i = 0; (i < plane_resources->count_planes) && !found_primary; i++) { uint32_t id = plane_resources->planes[i]; drmModePlanePtr plane = drmModeGetPlane(drm.fd, id); if (!plane) { printf("drmModeGetPlane(%u) failed: %s\n", id, strerror(errno)); continue; } if (plane->possible_crtcs & (1 << drm.crtc_index)) { drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(drm.fd, id, DRM_MODE_OBJECT_PLANE); /* primary or not, this plane is good enough to use: */ ret = id; for (j = 0; j < props->count_props; j++) { drmModePropertyPtr p = drmModeGetProperty(drm.fd, props->props[j]); if ((strcmp(p->name, "type") == 0) && (props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY)) { /* found our primary plane, lets use that: */ found_primary = 1; } drmModeFreeProperty(p); } drmModeFreeObjectProperties(props); } drmModeFreePlane(plane); } drmModeFreePlaneResources(plane_resources); return ret; }
int drm_get_overlay_plane(int drm_fd, int crtc_pipe, uint32_t format, uint32_t *plane_id) { drmModePlaneRes *res; drmModePlane *p; uint32_t id = 0; int i, j; if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { ErrorMsg("Failed to set universal planes CAP\n"); goto err; } res = drmModeGetPlaneResources(drm_fd); if (!res) goto err; for (i = 0; i < res->count_planes && !id; i++) { p = drmModeGetPlane(drm_fd, res->planes[i]); if (!p) continue; if (!p->crtc_id && (p->possible_crtcs & (1 << crtc_pipe))) { if (drm_plane_type(drm_fd, p->plane_id) == DRM_PLANE_TYPE_OVERLAY) { for (j = 0; j < p->count_formats; j++) { if (p->formats[j] == format) { id = p->plane_id; break; } } } } drmModeFreePlane(p); } drmModeFreePlaneResources(res); if (!id) goto err; *plane_id = id; return 0; err: ErrorMsg("Failed to get overlay plane\n"); return -EFAULT; }
static int find_plane(int drmfd, struct setup *s) { drmModePlaneResPtr planes; drmModePlanePtr plane; unsigned int i; unsigned int j; int ret = 0; planes = drmModeGetPlaneResources(drmfd); if (WARN_ON(!planes, "drmModeGetPlaneResources failed: %s\n", ERRSTR)) return -1; for (i = 0; i < planes->count_planes; ++i) { plane = drmModeGetPlane(drmfd, planes->planes[i]); if (WARN_ON(!planes, "drmModeGetPlane failed: %s\n", ERRSTR)) break; if (!(plane->possible_crtcs & (1 << s->crtIdx))) { drmModeFreePlane(plane); continue; } for (j = 0; j < plane->count_formats; ++j) { if (plane->formats[j] == s->out_fourcc) break; } if (j == plane->count_formats) { drmModeFreePlane(plane); continue; } s->planeId = plane->plane_id; drmModeFreePlane(plane); break; } if (i == planes->count_planes) ret = -1; drmModeFreePlaneResources(planes); return ret; }
int DrmResources::Init() { char path[PROPERTY_VALUE_MAX]; property_get("hwc.drm.device", path, "/dev/dri/card0"); /* TODO: Use drmOpenControl here instead */ fd_ = open(path, O_RDWR); if (fd_ < 0) { ALOGE("Failed to open dri- %s", strerror(-errno)); return -ENODEV; } int ret = drmSetClientCap(fd_, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret) { ALOGE("Failed to set universal plane cap %d", ret); return ret; } ret = drmSetClientCap(fd_, DRM_CLIENT_CAP_ATOMIC, 1); if (ret) { ALOGE("Failed to set atomic cap %d", ret); return ret; } drmModeResPtr res = drmModeGetResources(fd_); if (!res) { ALOGE("Failed to get DrmResources resources"); return -ENODEV; } bool found_primary = false; int display_num = 1; for (int i = 0; !ret && i < res->count_crtcs; ++i) { drmModeCrtcPtr c = drmModeGetCrtc(fd_, res->crtcs[i]); if (!c) { ALOGE("Failed to get crtc %d", res->crtcs[i]); ret = -ENODEV; break; } DrmCrtc *crtc = new DrmCrtc(this, c, i); drmModeFreeCrtc(c); if (!crtc) { ALOGE("Failed to allocate crtc %d", res->crtcs[i]); ret = -ENOMEM; break; } ret = crtc->Init(); if (ret) { ALOGE("Failed to initialize crtc %d", res->crtcs[i]); delete crtc; break; } crtcs_.push_back(crtc); } for (int i = 0; !ret && i < res->count_encoders; ++i) { drmModeEncoderPtr e = drmModeGetEncoder(fd_, res->encoders[i]); if (!e) { ALOGE("Failed to get encoder %d", res->encoders[i]); ret = -ENODEV; break; } std::vector<DrmCrtc *> possible_crtcs; DrmCrtc *current_crtc = NULL; for (std::vector<DrmCrtc *>::const_iterator iter = crtcs_.begin(); iter != crtcs_.end(); ++iter) { if ((1 << (*iter)->pipe()) & e->possible_crtcs) possible_crtcs.push_back(*iter); if ((*iter)->id() == e->crtc_id) current_crtc = (*iter); } DrmEncoder *enc = new DrmEncoder(e, current_crtc, possible_crtcs); drmModeFreeEncoder(e); if (!enc) { ALOGE("Failed to allocate enc %d", res->encoders[i]); ret = -ENOMEM; break; } encoders_.push_back(enc); } for (int i = 0; !ret && i < res->count_connectors; ++i) { drmModeConnectorPtr c = drmModeGetConnector(fd_, res->connectors[i]); if (!c) { ALOGE("Failed to get connector %d", res->connectors[i]); ret = -ENODEV; break; } std::vector<DrmEncoder *> possible_encoders; DrmEncoder *current_encoder = NULL; for (int j = 0; j < c->count_encoders; ++j) { for (std::vector<DrmEncoder *>::const_iterator iter = encoders_.begin(); iter != encoders_.end(); ++iter) { if ((*iter)->id() == c->encoders[j]) possible_encoders.push_back((*iter)); if ((*iter)->id() == c->encoder_id) current_encoder = *iter; } } DrmConnector *conn = new DrmConnector(this, c, current_encoder, possible_encoders); drmModeFreeConnector(c); if (!conn) { ALOGE("Failed to allocate conn %d", res->connectors[i]); ret = -ENOMEM; break; } ret = conn->Init(); if (ret) { ALOGE("Init connector %d failed", res->connectors[i]); delete conn; break; } connectors_.push_back(conn); if (conn->built_in() && !found_primary) { conn->set_display(0); found_primary = true; } else { conn->set_display(display_num); ++display_num; } } if (res) drmModeFreeResources(res); // Catch-all for the above loops if (ret) return ret; drmModePlaneResPtr plane_res = drmModeGetPlaneResources(fd_); if (!plane_res) { ALOGE("Failed to get plane resources"); return -ENOENT; } for (uint32_t i = 0; i < plane_res->count_planes; ++i) { drmModePlanePtr p = drmModeGetPlane(fd_, plane_res->planes[i]); if (!p) { ALOGE("Failed to get plane %d", plane_res->planes[i]); ret = -ENODEV; break; } DrmPlane *plane = new DrmPlane(this, p); drmModeFreePlane(p); if (!plane) { ALOGE("Allocate plane %d failed", plane_res->planes[i]); ret = -ENOMEM; break; } ret = plane->Init(); if (ret) { ALOGE("Init plane %d failed", plane_res->planes[i]); delete plane; break; } planes_.push_back(plane); } drmModeFreePlaneResources(plane_res); if (ret) return ret; return compositor_.Init(); }
bool CDRMUtils::GetPlanes() { drmModePlaneResPtr plane_resources; uint32_t primary_plane_id = 0; uint32_t overlay_plane_id = 0; uint32_t fourcc = 0; plane_resources = drmModeGetPlaneResources(m_fd); if (!plane_resources) { CLog::Log(LOGERROR, "CDRMUtils::%s - drmModeGetPlaneResources failed: %s", __FUNCTION__, strerror(errno)); return false; } for (uint32_t i = 0; i < plane_resources->count_planes; i++) { uint32_t id = plane_resources->planes[i]; drmModePlanePtr plane = drmModeGetPlane(m_fd, id); if (!plane) { CLog::Log(LOGERROR, "CDRMUtils::%s - drmModeGetPlane(%u) failed: %s", __FUNCTION__, id, strerror(errno)); continue; } if (plane->possible_crtcs & (1 << m_crtc_index)) { drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(m_fd, id, DRM_MODE_OBJECT_PLANE); for (uint32_t j = 0; j < props->count_props; j++) { drmModePropertyPtr p = drmModeGetProperty(m_fd, props->props[j]); if ((strcmp(p->name, "type") == 0) && (props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY) && (primary_plane_id == 0)) { CLog::Log(LOGDEBUG, "CDRMUtils::%s - found primary plane: %u", __FUNCTION__, id); primary_plane_id = id; } else if ((strcmp(p->name, "type") == 0) && (props->prop_values[j] == DRM_PLANE_TYPE_OVERLAY) && (overlay_plane_id == 0)) { CLog::Log(LOGDEBUG, "CDRMUtils::%s - found overlay plane: %u", __FUNCTION__, id); overlay_plane_id = id; } drmModeFreeProperty(p); } drmModeFreeObjectProperties(props); } drmModeFreePlane(plane); } drmModeFreePlaneResources(plane_resources); // primary plane m_primary_plane->plane = drmModeGetPlane(m_fd, primary_plane_id); if (!m_primary_plane->plane) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not get primary plane %u: %s", __FUNCTION__, primary_plane_id, strerror(errno)); return false; } if (!GetProperties(m_fd, primary_plane_id, DRM_MODE_OBJECT_PLANE, m_primary_plane)) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not get primary plane %u properties: %s", __FUNCTION__, primary_plane_id, strerror(errno)); return false; } for (uint32_t i = 0; i < m_primary_plane->plane->count_formats; i++) { /* we want an alpha layer so break if we find one */ if (m_primary_plane->plane->formats[i] == DRM_FORMAT_XRGB8888) { fourcc = DRM_FORMAT_XRGB8888; m_primary_plane->format = fourcc; } else if (m_primary_plane->plane->formats[i] == DRM_FORMAT_ARGB8888) { fourcc = DRM_FORMAT_ARGB8888; m_primary_plane->format = fourcc; break; } } if (fourcc == 0) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not find a suitable primary plane format", __FUNCTION__); return false; } CLog::Log(LOGDEBUG, "CDRMUtils::%s - primary plane format: %c%c%c%c", __FUNCTION__, fourcc, fourcc >> 8, fourcc >> 16, fourcc >> 24); if (overlay_plane_id != 0) { // overlay plane m_overlay_plane->plane = drmModeGetPlane(m_fd, overlay_plane_id); if (!m_overlay_plane->plane) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not get overlay plane %u: %s", __FUNCTION__, overlay_plane_id, strerror(errno)); return false; } if (!GetProperties(m_fd, overlay_plane_id, DRM_MODE_OBJECT_PLANE, m_overlay_plane)) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not get overlay plane %u properties: %s", __FUNCTION__, overlay_plane_id, strerror(errno)); return false; } fourcc = 0; for (uint32_t i = 0; i < m_overlay_plane->plane->count_formats; i++) { /* we want an alpha layer so break if we find one */ if (m_overlay_plane->plane->formats[i] == DRM_FORMAT_XRGB8888) { fourcc = DRM_FORMAT_XRGB8888; m_overlay_plane->format = fourcc; } else if(m_overlay_plane->plane->formats[i] == DRM_FORMAT_ARGB8888) { fourcc = DRM_FORMAT_ARGB8888; m_overlay_plane->format = fourcc; break; } } if (fourcc == 0) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not find a suitable overlay plane format", __FUNCTION__); return false; } CLog::Log(LOGDEBUG, "CDRMUtils::%s - overlay plane format: %c%c%c%c", __FUNCTION__, fourcc, fourcc >> 8, fourcc >> 16, fourcc >> 24); }
struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, int crtc_id, int connector_id, int osd_plane_id, int video_plane_id) { drmModePlaneRes *plane_res = NULL; drmModeRes *res = NULL; struct drm_object *plane = NULL; struct drm_atomic_context *ctx; int crtc_index = -1; int layercount = -1; int primary_id = 0; int overlay_id = 0; uint64_t value; res = drmModeGetResources(fd); if (!res) { mp_err(log, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno)); goto fail; } plane_res = drmModeGetPlaneResources(fd); if (!plane_res) { mp_err(log, "Cannot retrieve plane ressources: %s\n", mp_strerror(errno)); goto fail; } ctx = talloc_zero(NULL, struct drm_atomic_context); if (!ctx) { mp_err(log, "Out of memory\n"); goto fail; } ctx->fd = fd; ctx->crtc = drm_object_create(log, ctx->fd, crtc_id, DRM_MODE_OBJECT_CRTC); if (!ctx->crtc) { mp_err(log, "Failed to create CRTC object\n"); goto fail; } for (int i = 0; i < res->count_crtcs; i++) { if (res->crtcs[i] == crtc_id) { crtc_index = i; break; } } for (int i = 0; i < res->count_connectors; i++) { drmModeConnector *connector = drmModeGetConnector(fd, res->connectors[i]); if (connector) { if (connector->connector_id == connector_id) ctx->connector = drm_object_create(log, ctx->fd, connector->connector_id, DRM_MODE_OBJECT_CONNECTOR); drmModeFreeConnector(connector); if (ctx->connector) break; } } for (unsigned int j = 0; j < plane_res->count_planes; j++) { drmModePlane *drmplane = drmModeGetPlane(ctx->fd, plane_res->planes[j]); const uint32_t possible_crtcs = drmplane->possible_crtcs; const uint32_t plane_id = drmplane->plane_id; drmModeFreePlane(drmplane); drmplane = NULL; if (possible_crtcs & (1 << crtc_index)) { plane = drm_object_create(log, ctx->fd, plane_id, DRM_MODE_OBJECT_PLANE); if (!plane) { mp_err(log, "Failed to create Plane object from plane ID %d\n", plane_id); goto fail; } if (drm_object_get_property(plane, "TYPE", &value) == -EINVAL) { mp_err(log, "Unable to retrieve type property from plane %d\n", j); goto fail; } if (value != DRM_PLANE_TYPE_CURSOR) { // Skip cursor planes layercount++; if ((!primary_id) && (value == DRM_PLANE_TYPE_PRIMARY)) primary_id = plane_id; if ((!overlay_id) && (value == DRM_PLANE_TYPE_OVERLAY)) overlay_id = plane_id; if (layercount == osd_plane_id) { ctx->osd_plane = plane; continue; } if (layercount == video_plane_id) { ctx->video_plane = plane; continue; } } drm_object_free(plane); plane = NULL; } } // default OSD plane to primary if unspecified if (!ctx->osd_plane) { if (primary_id) { mp_verbose(log, "Using default plane %d for OSD\n", primary_id); ctx->osd_plane = drm_object_create(log, ctx->fd, primary_id, DRM_MODE_OBJECT_PLANE); } else { mp_err(log, "Failed to find OSD plane with id=%d\n", osd_plane_id); goto fail; } } else { mp_verbose(log, "Found OSD plane with ID %d\n", ctx->osd_plane->id); } // default video plane to overlay if unspecified if (!ctx->video_plane) { if (overlay_id) { mp_verbose(log, "Using default plane %d for video\n", overlay_id); ctx->video_plane = drm_object_create(log, ctx->fd, overlay_id, DRM_MODE_OBJECT_PLANE); } else { mp_verbose(log, "Failed to find video plane with id=%d. drmprime-drm hwdec interop will not work\n", video_plane_id); } } else { mp_verbose(log, "Found video plane with ID %d\n", ctx->video_plane->id); } drmModeFreePlaneResources(plane_res); drmModeFreeResources(res); return ctx; fail: if (res) drmModeFreeResources(res); if (plane_res) drmModeFreePlaneResources(plane_res); if (plane) drm_object_free(plane); return NULL; }
static gboolean gst_kms_sink_start (GstBaseSink * bsink) { GstKMSSink *self; drmModeRes *res; drmModeConnector *conn; drmModeCrtc *crtc; drmModePlaneRes *pres; drmModePlane *plane; gboolean universal_planes; gboolean ret; self = GST_KMS_SINK (bsink); universal_planes = FALSE; ret = FALSE; res = NULL; conn = NULL; crtc = NULL; pres = NULL; plane = NULL; if (self->devname) self->fd = drmOpen (self->devname, NULL); else self->fd = kms_open (&self->devname); if (self->fd < 0) goto open_failed; log_drm_version (self); if (!get_drm_caps (self)) goto bail; res = drmModeGetResources (self->fd); if (!res) goto resources_failed; if (self->conn_id == -1) conn = find_main_monitor (self->fd, res); else conn = drmModeGetConnector (self->fd, self->conn_id); if (!conn) goto connector_failed; crtc = find_crtc_for_connector (self->fd, res, conn, &self->pipe); if (!crtc) goto crtc_failed; retry_find_plane: if (universal_planes && drmSetClientCap (self->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) goto set_cap_failed; pres = drmModeGetPlaneResources (self->fd); if (!pres) goto plane_resources_failed; if (self->plane_id == -1) plane = find_plane_for_crtc (self->fd, res, pres, crtc->crtc_id); else plane = drmModeGetPlane (self->fd, self->plane_id); if (!plane) goto plane_failed; /* let's get the available color formats in plane */ if (!ensure_allowed_caps (self, plane, res)) goto bail; self->conn_id = conn->connector_id; self->crtc_id = crtc->crtc_id; self->plane_id = plane->plane_id; GST_INFO_OBJECT (self, "connector id = %d / crtc id = %d / plane id = %d", self->conn_id, self->crtc_id, self->plane_id); self->hdisplay = crtc->mode.hdisplay; self->vdisplay = crtc->mode.vdisplay; self->buffer_id = crtc->buffer_id; self->mm_width = conn->mmWidth; self->mm_height = conn->mmHeight; GST_INFO_OBJECT (self, "display size: pixels = %dx%d / millimeters = %dx%d", self->hdisplay, self->vdisplay, self->mm_width, self->mm_height); self->pollfd.fd = self->fd; gst_poll_add_fd (self->poll, &self->pollfd); gst_poll_fd_ctl_read (self->poll, &self->pollfd, TRUE); ret = TRUE; bail: if (plane) drmModeFreePlane (plane); if (pres) drmModeFreePlaneResources (pres); if (crtc) drmModeFreeCrtc (crtc); if (conn) drmModeFreeConnector (conn); if (res) drmModeFreeResources (res); if (!ret && self->fd >= 0) { drmClose (self->fd); self->fd = -1; } return ret; /* ERRORS */ open_failed: { GST_ERROR_OBJECT (self, "Could not open DRM module %s: %s", GST_STR_NULL (self->devname), strerror (errno)); return FALSE; } resources_failed: { GST_ERROR_OBJECT (self, "drmModeGetResources failed: %s (%d)", strerror (errno), errno); goto bail; } connector_failed: { GST_ERROR_OBJECT (self, "Could not find a valid monitor connector"); goto bail; } crtc_failed: { GST_ERROR_OBJECT (self, "Could not find a crtc for connector"); goto bail; } set_cap_failed: { GST_ERROR_OBJECT (self, "Could not set universal planes capability bit"); goto bail; } plane_resources_failed: { GST_ERROR_OBJECT (self, "drmModeGetPlaneResources failed: %s (%d)", strerror (errno), errno); goto bail; } plane_failed: { if (universal_planes) { GST_ERROR_OBJECT (self, "Could not find a plane for crtc"); goto bail; } else { universal_planes = TRUE; goto retry_find_plane; } } }
static void atomic_setup(struct kms_atomic_state *state) { struct kms_atomic_desc *desc = state->desc; drmModeResPtr res; drmModePlaneResPtr res_plane; int i; desc->fd = drm_open_driver_master(DRIVER_INTEL); igt_assert_fd(desc->fd); do_or_die(drmSetClientCap(desc->fd, DRM_CLIENT_CAP_ATOMIC, 1)); res = drmModeGetResources(desc->fd); res_plane = drmModeGetPlaneResources(desc->fd); igt_assert(res); igt_assert(res_plane); igt_assert_lt(0, res->count_crtcs); state->num_crtcs = res->count_crtcs; state->crtcs = calloc(state->num_crtcs, sizeof(*state->crtcs)); igt_assert(state->crtcs); igt_assert_lt(0, res_plane->count_planes); state->num_planes = res_plane->count_planes; state->planes = calloc(state->num_planes, sizeof(*state->planes)); igt_assert(state->planes); igt_assert_lt(0, res->count_connectors); state->num_connectors = res->count_connectors; state->connectors = calloc(state->num_connectors, sizeof(*state->connectors)); igt_assert(state->connectors); fill_obj_props(desc->fd, res->crtcs[0], DRM_MODE_OBJECT_CRTC, NUM_CRTC_PROPS, crtc_prop_names, desc->props_crtc); fill_obj_props(desc->fd, res_plane->planes[0], DRM_MODE_OBJECT_PLANE, NUM_PLANE_PROPS, plane_prop_names, desc->props_plane); fill_obj_prop_map(desc->fd, res_plane->planes[0], DRM_MODE_OBJECT_PLANE, "type", NUM_PLANE_TYPE_PROPS, plane_type_prop_names, desc->props_plane_type); fill_obj_props(desc->fd, res->connectors[0], DRM_MODE_OBJECT_CONNECTOR, NUM_CONNECTOR_PROPS, connector_prop_names, desc->props_connector); for (i = 0; i < state->num_crtcs; i++) { struct kms_atomic_crtc_state *crtc = &state->crtcs[i]; crtc->state = state; crtc->obj = res->crtcs[i]; crtc->idx = i; crtc_get_current_state(crtc); /* The blob pointed to by MODE_ID could well be transient, * and lose its last reference as we switch away from it. * Duplicate the blob here so we have a reference we know we * own. */ if (crtc->mode.id != 0) crtc->mode.id = blob_duplicate(desc->fd, crtc->mode.id); } for (i = 0; i < state->num_planes; i++) { drmModePlanePtr plane = drmModeGetPlane(desc->fd, res_plane->planes[i]); igt_assert(plane); state->planes[i].state = state; state->planes[i].obj = res_plane->planes[i]; state->planes[i].crtc_mask = plane->possible_crtcs; plane_get_current_state(&state->planes[i]); } for (i = 0; i < state->num_connectors; i++) { state->connectors[i].state = state; state->connectors[i].obj = res->connectors[i]; connector_get_current_state(&state->connectors[i]); } drmModeFreePlaneResources(res_plane); drmModeFreeResources(res); }
int gralloc_kms_planes_init(struct gralloc_drm_t *drm) { drmModeResPtr resources; drmModePlaneResPtr planes; int i, order; /* What else than the ordering in the main resources would reliably tell us what the possible_crtcs field for the planes mean? Way to save overhead! */ resources = drmModeGetResources(drm->fd); if (!resources) { LOGE("Failed to get KMS resources\n"); return -EINVAL; } for (order = 0; order < resources->count_crtcs; order++) if (resources->crtcs[order] == drm->crtc_id) break; if (order == resources->count_crtcs) { LOGE("Failed to find crtc %d in KMS resources\n", drm->crtc_id); drmModeFreeResources(resources); return -EINVAL; } drmModeFreeResources(resources); planes = drmModeGetPlaneResources(drm->fd); if (!planes) { LOGE("Failed to get KMS Plane resources\n"); return -EINVAL; } for (i = 0; i < (int) planes->count_planes; i++) { drmModePlanePtr plane = drmModeGetPlane(drm->fd, planes->planes[i]); if (!plane) { LOGE("Failed to get Plane %d: %s\n", planes->planes[i], strerror(errno)); return errno; } if (plane->possible_crtcs & (1 << order)) { int ret = gralloc_kms_plane_add(drm, plane); if (ret) { drmModeFreePlane(plane); drmModeFreePlaneResources(planes); return ret; } } drmModeFreePlane(plane); } drmModeFreePlaneResources(planes); LOGI("%s: %d planes\n", __func__, drm->plane_count); for (i = 0; i < drm->plane_count; i++) { char buffer[1024]; int j; for (j = 0; j < drm->planes[i]->format_count; j++) sprintf(buffer + 6 * j, " %c%c%c%c,", drm->planes[i]->formats[j] & 0xFF, (drm->planes[i]->formats[j] >> 8) & 0xFF, (drm->planes[i]->formats[j] >> 16) & 0xFF, (drm->planes[i]->formats[j] >> 24) & 0xFF); LOGI("\t%d: %s", drm->planes[i]->id, buffer); } return 0; }
struct sp_dev* create_sp_dev(void) { struct sp_dev *dev; int ret, fd, i, j; drmModeRes *r = NULL; drmModePlaneRes *pr = NULL; fd = open("/dev/dri/card0", O_RDWR); if (fd < 0) { printf("failed to open card0\n"); return NULL; } dev = calloc(1, sizeof(*dev)); if (!dev) { printf("failed to allocate dev\n"); return NULL; } dev->fd = fd; #if 0 ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1); if (ret) { printf("failed to set client cap atomic\n"); goto err; } ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret) { printf("failed to set client cap\n"); goto err; } #endif r = drmModeGetResources(dev->fd); if (!r) { printf("failed to get r\n"); goto err; } dev->num_connectors = r->count_connectors; dev->connectors = calloc(dev->num_connectors, sizeof(*dev->connectors)); if (!dev->connectors) { printf("failed to allocate connectors\n"); goto err; } for (i = 0; i < dev->num_connectors; i++) { dev->connectors[i] = drmModeGetConnector(dev->fd, r->connectors[i]); if (!dev->connectors[i]) { printf("failed to get connector %d\n", i); goto err; } } dev->num_encoders = r->count_encoders; dev->encoders = calloc(dev->num_encoders, sizeof(*dev->encoders)); if (!dev->encoders) { printf("failed to allocate encoders\n"); goto err; } for (i = 0; i < dev->num_encoders; i++) { dev->encoders[i] = drmModeGetEncoder(dev->fd, r->encoders[i]); if (!dev->encoders[i]) { printf("failed to get encoder %d\n", i); goto err; } } dev->num_crtcs = r->count_crtcs; dev->crtcs = calloc(dev->num_crtcs, sizeof(struct sp_crtc)); if (!dev->crtcs) { printf("failed to allocate crtcs\n"); goto err; } for (i = 0; i < dev->num_crtcs; i++) { dev->crtcs[i].crtc = drmModeGetCrtc(dev->fd, r->crtcs[i]); if (!dev->crtcs[i].crtc) { printf("failed to get crtc %d\n", i); goto err; } dev->crtcs[i].scanout = NULL; dev->crtcs[i].pipe = i; dev->crtcs[i].num_planes = 0; } pr = drmModeGetPlaneResources(dev->fd); if (!pr) { printf("failed to get plane resources\n"); goto err; } dev->num_planes = pr->count_planes; dev->planes = calloc(dev->num_planes, sizeof(struct sp_plane)); for (i = 0; i < dev->num_planes; i++) { drmModeObjectPropertiesPtr props; struct sp_plane *plane = &dev->planes[i]; plane->dev = dev; plane->plane = drmModeGetPlane(dev->fd, pr->planes[i]); if (!plane->plane) { printf("failed to get plane %d\n", i); goto err; } plane->bo = NULL; plane->in_use = 0; ret = get_supported_format(plane, &plane->format); if (ret) { printf("failed to get supported format: %d\n", ret); goto err; } for (j = 0; j < dev->num_crtcs; j++) { if (plane->plane->possible_crtcs & (1 << j)) dev->crtcs[j].num_planes++; } props = drmModeObjectGetProperties(dev->fd, pr->planes[i], DRM_MODE_OBJECT_PLANE); if (!props) { printf("failed to get plane properties\n"); goto err; } #if 0//def USE_ATOMIC_API plane->crtc_pid = get_prop_id(dev, props, "CRTC_ID"); if (!plane->crtc_pid) { drmModeFreeObjectProperties(props); goto err; } plane->fb_pid = get_prop_id(dev, props, "FB_ID"); if (!plane->fb_pid) { drmModeFreeObjectProperties(props); goto err; } plane->crtc_x_pid = get_prop_id(dev, props, "CRTC_X"); if (!plane->crtc_x_pid) { drmModeFreeObjectProperties(props); goto err; } plane->crtc_y_pid = get_prop_id(dev, props, "CRTC_Y"); if (!plane->crtc_y_pid) { drmModeFreeObjectProperties(props); goto err; } plane->crtc_w_pid = get_prop_id(dev, props, "CRTC_W"); if (!plane->crtc_w_pid) { drmModeFreeObjectProperties(props); goto err; } plane->crtc_h_pid = get_prop_id(dev, props, "CRTC_H"); if (!plane->crtc_h_pid) { drmModeFreeObjectProperties(props); goto err; } plane->src_x_pid = get_prop_id(dev, props, "SRC_X"); if (!plane->src_x_pid) { drmModeFreeObjectProperties(props); goto err; } plane->src_y_pid = get_prop_id(dev, props, "SRC_Y"); if (!plane->src_y_pid) { drmModeFreeObjectProperties(props); goto err; } plane->src_w_pid = get_prop_id(dev, props, "SRC_W"); if (!plane->src_w_pid) { drmModeFreeObjectProperties(props); goto err; } plane->src_h_pid = get_prop_id(dev, props, "SRC_H"); if (!plane->src_h_pid) { drmModeFreeObjectProperties(props); goto err; } #endif drmModeFreeObjectProperties(props); } if (pr) drmModeFreePlaneResources(pr); if (r) drmModeFreeResources(r); return dev; err: if (pr) drmModeFreePlaneResources(pr); if (r) drmModeFreeResources(r); destroy_sp_dev(dev); return NULL; }