static void dump_crtcs(int gfx_fd, drmModeRes *resources) { int i; printf("CRTCs:\n"); printf("id\tfb\tpos\tsize\n"); for (i = 0; i < resources->count_crtcs; i++) { drmModeCrtc *crtc; crtc = drmModeGetCrtc(gfx_fd, resources->crtcs[i]); if (!crtc) { printf("could not get crtc %i: %s\n", resources->crtcs[i], strerror(errno)); continue; } printf("%d\t%d\t(%d,%d)\t(%dx%d)\n", crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, crtc->width, crtc->height); dump_mode(&crtc->mode); drmModeFreeCrtc(crtc); } printf("\n"); }
static bool reset_scan_out_buffer_if_needed (ply_renderer_backend_t *backend, ply_renderer_head_t *head) { drmModeCrtc *controller; bool did_reset = false; if (!ply_terminal_is_active (backend->terminal)) return false; controller = drmModeGetCrtc (backend->device_fd, head->controller_id); if (controller == NULL) return false; if (controller->buffer_id != head->scan_out_buffer_id) { ply_renderer_head_set_scan_out_buffer (backend, head, head->scan_out_buffer_id); did_reset = true; } drmModeFreeCrtc (controller); return did_reset; }
/** * Remember the original CRTC status and set the CRTC */ static boolean drm_display_set_crtc(struct native_display *ndpy, int crtc_idx, uint32_t buffer_id, uint32_t x, uint32_t y, uint32_t *connectors, int num_connectors, drmModeModeInfoPtr mode) { struct drm_display *drmdpy = drm_display(ndpy); struct drm_crtc *drmcrtc = &drmdpy->saved_crtcs[crtc_idx]; uint32_t crtc_id; int err; if (drmcrtc->crtc) { crtc_id = drmcrtc->crtc->crtc_id; } else { int count = 0, i; /* * Choose the CRTC once. It could be more dynamic, but let's keep it * simple for now. */ crtc_id = drm_display_choose_crtc(&drmdpy->base, connectors, num_connectors); /* save the original CRTC status */ drmcrtc->crtc = drmModeGetCrtc(drmdpy->fd, crtc_id); if (!drmcrtc->crtc) return FALSE; for (i = 0; i < drmdpy->num_connectors; i++) { struct drm_connector *drmconn = &drmdpy->connectors[i]; drmModeConnectorPtr connector = drmconn->connector; drmModeEncoderPtr encoder; encoder = drmModeGetEncoder(drmdpy->fd, connector->encoder_id); if (encoder) { if (encoder->crtc_id == crtc_id) { drmcrtc->connectors[count++] = connector->connector_id; if (count >= Elements(drmcrtc->connectors)) break; } drmModeFreeEncoder(encoder); } } drmcrtc->num_connectors = count; } err = drmModeSetCrtc(drmdpy->fd, crtc_id, buffer_id, x, y, connectors, num_connectors, mode); if (err) { drmModeFreeCrtc(drmcrtc->crtc); drmcrtc->crtc = NULL; drmcrtc->num_connectors = 0; return FALSE; } return TRUE; }
bool CDRMUtils::GetCrtc() { for(auto i = 0; i < m_drm_resources->count_crtcs; i++) { m_crtc->crtc = drmModeGetCrtc(m_fd, m_drm_resources->crtcs[i]); if(m_crtc->crtc->crtc_id == m_encoder->encoder->crtc_id) { CLog::Log(LOGDEBUG, "CDRMUtils::%s - found crtc: %d", __FUNCTION__, m_crtc->crtc->crtc_id); m_crtc_index = i; break; } drmModeFreeCrtc(m_crtc->crtc); m_crtc->crtc = nullptr; } if(!m_crtc->crtc) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not get crtc: %s", __FUNCTION__, strerror(errno)); return false; } if (!GetProperties(m_fd, m_crtc->crtc->crtc_id, DRM_MODE_OBJECT_CRTC, m_crtc)) { CLog::Log(LOGERROR, "CDRMUtils::%s - could not get crtc %u properties: %s", __FUNCTION__, m_crtc->crtc->crtc_id, strerror(errno)); return false; } return true; }
bool drm_atomic_save_old_state(struct drm_atomic_context *ctx) { if (ctx->old_state.saved) return false; bool ret = true; drmModeCrtc *crtc = drmModeGetCrtc(ctx->fd, ctx->crtc->id); if (crtc == NULL) return false; ctx->old_state.crtc.mode.mode = crtc->mode; drmModeFreeCrtc(crtc); if (0 > drm_object_get_property(ctx->crtc, "ACTIVE", &ctx->old_state.crtc.active)) ret = false; if (0 > drm_object_get_property(ctx->connector, "CRTC_ID", &ctx->old_state.connector.crtc_id)) ret = false; if (!drm_atomic_save_plane_state(ctx->osd_plane, &ctx->old_state.osd_plane)) ret = false; if (!drm_atomic_save_plane_state(ctx->video_plane, &ctx->old_state.video_plane)) ret = false; ctx->old_state.saved = true; return ret; }
int main(int, char **) { EGLDeviceEXT device = 0; EGLStreamKHR stream = 0; EGLOutputLayerEXT layer = 0; drmModeCrtcPtr currentMode = drmModeGetCrtc(0, 0); return EGL_DRM_CRTC_EXT; }
void drm_setup(int fd) { g_crtc_id = g_drm_encoder->crtc_id; g_connector_id = g_drm_connector->connector_id; g_orig_crtc = drmModeGetCrtc(fd, g_crtc_id); if (!g_orig_crtc) RARCH_WARN("[DRM]: Cannot find original CRTC.\n"); }
bool CDRMUtils::InitDrm() { if(m_fd >= 0) { /* caps need to be set before allocating connectors, encoders, crtcs, and planes */ auto ret = drmSetClientCap(m_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret) { CLog::Log(LOGERROR, "CDRMUtils::%s - failed to set Universal planes capability: %s", __FUNCTION__, strerror(errno)); return false; } if(!GetResources()) { return false; } if(!GetConnector()) { return false; } if(!GetEncoder()) { return false; } if(!GetCrtc()) { return false; } if(!GetPlanes()) { return false; } } drmModeFreeResources(m_drm_resources); m_drm_resources = nullptr; if(m_fd < 0) { return false; } if(!GetPreferredMode()) { return false; } drmSetMaster(m_fd); m_orig_crtc = drmModeGetCrtc(m_fd, m_crtc->crtc->crtc_id); return true; }
/** * Return the size of the gamma ramps on a CRTC * * @param connection The identifier for the connection to the card * @param crtc_index The index of the CRTC * @return The size of the gamma ramps on a CRTC */ int blueshift_drm_gamma_size(int connection, int crtc_index) { card_connection* card = card_connections + connection; drmModeCrtc* crtc = drmModeGetCrtc(card->fd, *(card->res->crtcs + crtc_index)); int gamma_size = crtc->gamma_size; drmModeFreeCrtc(crtc); return gamma_size; }
int main(int argc, char **argv) { int ret, fd; const char *card; struct modeset_dev *iter; struct modeset_buf *buf; /* check which DRM device to open */ if (argc > 1) card = argv[1]; else card = "/dev/dri/card0"; fprintf(stderr, "using card '%s'\n", card); /* open the DRM device */ ret = modeset_open(&fd, card); if (ret) goto out_return; /* prepare all connectors and CRTCs */ ret = modeset_prepare(fd); if (ret) goto out_close; /* perform actual modesetting on each found connector+CRTC */ for (iter = modeset_list; iter; iter = iter->next) { iter->saved_crtc = drmModeGetCrtc(fd, iter->crtc); buf = &iter->bufs[iter->front_buf]; ret = drmModeSetCrtc(fd, iter->crtc, buf->fb, 0, 0, &iter->conn, 1, &iter->mode); if (ret) fprintf(stderr, "cannot set CRTC for connector %u (%d): %m\n", iter->conn, errno); } /* draw some colors for 5seconds */ modeset_draw(fd); /* cleanup everything */ modeset_cleanup(fd); ret = 0; out_close: close(fd); out_return: if (ret) { errno = -ret; fprintf(stderr, "modeset failed with error %d: %m\n", errno); } else { fprintf(stderr, "exiting\n"); } return ret; }
static void crtc_check_current_state(struct kms_atomic_crtc_state *crtc, struct kms_atomic_plane_state *primary, enum kms_atomic_check_relax relax) { struct kms_atomic_crtc_state crtc_kernel; drmModeCrtcPtr legacy; legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc->obj); igt_assert(legacy); igt_assert_eq_u32(legacy->crtc_id, crtc->obj); igt_assert_eq_u32(legacy->x, primary->src_x >> 16); igt_assert_eq_u32(legacy->y, primary->src_y >> 16); if (crtc->active) igt_assert_eq_u32(legacy->buffer_id, primary->fb_id); else igt_assert_eq_u32(legacy->buffer_id, 0); if (legacy->mode_valid) { igt_assert_neq(legacy->mode_valid, 0); igt_assert_eq(crtc->mode.len, sizeof(struct drm_mode_modeinfo)); do_or_die(memcmp(&legacy->mode, crtc->mode.data, crtc->mode.len)); igt_assert_eq(legacy->width, legacy->mode.hdisplay); igt_assert_eq(legacy->height, legacy->mode.vdisplay); } else { igt_assert_eq(legacy->mode_valid, 0); } memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel)); crtc_get_current_state(&crtc_kernel); if (crtc_kernel.mode.id != 0) igt_assert_eq(crtc_kernel.mode.len, sizeof(struct drm_mode_modeinfo)); /* Optionally relax the check for MODE_ID: using the legacy SetCrtc * API can potentially change MODE_ID even if the mode itself remains * unchanged. */ if (((relax & CRTC_RELAX_MODE) && (crtc_kernel.mode.id != crtc->mode.id && crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) && memcmp(crtc_kernel.mode.data, crtc->mode.data, sizeof(struct drm_mode_modeinfo)) == 0) { crtc_kernel.mode.id = crtc->mode.id; crtc_kernel.mode.data = crtc->mode.data; } do_or_die(memcmp(&crtc_kernel, crtc, sizeof(crtc_kernel))); drmModeFreeCrtc(legacy); }
static bool crtc_setup(struct MPGLContext *ctx) { struct priv *p = ctx->priv; if (p->active) return true; p->old_crtc = drmModeGetCrtc(p->kms->fd, p->kms->crtc_id); int ret = drmModeSetCrtc(p->kms->fd, p->kms->crtc_id, p->fb.id, 0, 0, &p->kms->connector->connector_id, 1, &p->kms->mode); p->active = true; return ret == 0; }
static gboolean device_find_crtc (Device *device) { gboolean ret = FALSE; drmModeRes *resources; drmModeConnector *connector; drmModeEncoder *encoder; drmModeCrtc *crtc; int i; resources = drmModeGetResources (device->fd); if (resources == NULL) { g_warning ("Unable to get DRI device resources fd=%d: %m", device->fd); goto out; } /* Find the first active connector to display on. */ for (i = 0; i < resources->count_connectors; i++) { connector = drmModeGetConnector (device->fd, resources->connectors[i]); if (connector == NULL) continue; if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) break; drmModeFreeConnector(connector); } if (i == resources->count_connectors) { g_warning ("Could not find an active connector"); goto out; } /* Find an associated encoder for that connector. */ encoder = drmModeGetEncoder (device->fd, connector->encoder_id); /* Now grab the CRTC for that encoder. */ crtc = drmModeGetCrtc (device->fd, encoder->crtc_id); device->resources = resources; device->connector = connector; device->crtc = crtc; ret = TRUE; out: return ret; }
static drmModeCrtc * find_crtc_for_connector (int fd, drmModeRes * res, drmModeConnector * conn, guint * pipe) { int i; int crtc_id; drmModeEncoder *enc; drmModeCrtc *crtc; guint32 crtcs_for_connector = 0; crtc_id = -1; for (i = 0; i < res->count_encoders; i++) { enc = drmModeGetEncoder (fd, res->encoders[i]); if (enc) { if (enc->encoder_id == conn->encoder_id) { crtc_id = enc->crtc_id; drmModeFreeEncoder (enc); break; } drmModeFreeEncoder (enc); } } /* If no active crtc was found, pick the first possible crtc */ if (crtc_id == -1) { for (i = 0; i < conn->count_encoders; i++) { enc = drmModeGetEncoder (fd, conn->encoders[i]); crtcs_for_connector |= enc->possible_crtcs; drmModeFreeEncoder (enc); } if (crtcs_for_connector != 0) crtc_id = res->crtcs[ffs (crtcs_for_connector) - 1]; } if (crtc_id == -1) return NULL; for (i = 0; i < res->count_crtcs; i++) { crtc = drmModeGetCrtc (fd, res->crtcs[i]); if (crtc) { if (crtc_id == crtc->crtc_id) { if (pipe) *pipe = i; return crtc; } drmModeFreeCrtc (crtc); } } return NULL; }
void QKmsScreen::initializeScreenMode() { //Determine optimal mode for screen drmModeRes *resources = drmModeGetResources(m_device->fd()); if (!resources) qFatal("drmModeGetResources failed"); drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId); drmModeModeInfo *mode = 0; for (int i = 0; i < connector->count_modes; ++i) { if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) { mode = &connector->modes[i]; break; } } if (!mode) mode = &builtin_1024x768; drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]); if (encoder == 0) qFatal("No encoder for connector."); int i; for (i = 0; i < resources->count_crtcs; i++) { if (encoder->possible_crtcs & (1 << i)) break; } if (i == resources->count_crtcs) qFatal("No usable crtc for encoder."); m_oldCrtc = drmModeGetCrtc(m_device->fd(), encoder->crtc_id); m_crtcId = resources->crtcs[i]; m_mode = *mode; m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay); qDebug() << "kms initialized with geometry" << m_geometry; m_depth = 32; m_format = QImage::Format_RGB32; m_physicalSize = QSizeF(connector->mmWidth, connector->mmHeight); m_gbmSurface = gbm_surface_create(m_device->gbmDevice(), m_mode.hdisplay, m_mode.vdisplay, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); qDebug() << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay; //Cleanup drmModeFreeEncoder(encoder); drmModeFreeConnector(connector); drmModeFreeResources(resources); }
static void printCRTCs(int fd, uint32_t* ids, uint32_t count) { int i; for (i = 0; i < count; i++) { drmModeCrtc *crtc; crtc = drmModeGetCrtc(fd, ids[i]); fprintf(stdout, " CRTC %u:\n", crtc->crtc_id); fprintf(stdout, " Dimensions: %u x %u\n", crtc->width, crtc->height); fprintf(stdout, " Buffer: %u\n", crtc->buffer_id); fprintf(stdout, " Position: %u, %u\n", crtc->x, crtc->y); fprintf(stdout, " Gamma size: %u\n", crtc->gamma_size); fprintf(stdout, " Mode: %s\n", crtc->mode_valid ? getModeLine(&crtc->mode) : "(invalid)"); fprintf(stdout, "\n"); drmModeFreeCrtc(crtc); } }
static int set_initial_crtc(struct gbm_dev *dev, uint32_t fb_id) { dev->saved_crtc = drmModeGetCrtc(dev->fd, dev->crtc); if (drmModeSetCrtc(dev->fd, dev->crtc, fb_id, 0, 0, /* x/y */ &dev->conn, 1, &dev->mode)) { fprintf(stderr, "Failed to set drm mode: %m\n"); return errno; } return 0; }
void QEglFSKmsEglDeviceScreen::waitForFlip() { QKmsOutput &op(output()); const int fd = device()->fd(); const uint32_t w = op.modes[op.mode].hdisplay; const uint32_t h = op.modes[op.mode].vdisplay; if (!op.mode_set) { op.mode_set = true; drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id); const bool alreadySet = currentMode && currentMode->width == w && currentMode->height == h; if (currentMode) drmModeFreeCrtc(currentMode); if (alreadySet) { // Maybe detecting the DPMS mode could help here, but there are no properties // exposed on the connector apparently. So rely on an env var for now. static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); if (!alwaysDoSet) { qCDebug(qLcEglfsKmsDebug, "Mode already set"); return; } } qCDebug(qLcEglfsKmsDebug, "Setting mode"); int ret = drmModeSetCrtc(fd, op.crtc_id, uint32_t(-1), 0, 0, &op.connector_id, 1, &op.modes[op.mode]); if (ret) qErrnoWarning(errno, "drmModeSetCrtc failed"); } if (!op.plane_set) { op.plane_set = true; if (op.wants_plane) { qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.plane_id); int ret = drmModeSetPlane(fd, op.plane_id, op.crtc_id, uint32_t(-1), 0, 0, 0, w, h, 0 << 16, 0 << 16, w << 16, h << 16); if (ret == -1) qErrnoWarning(errno, "drmModeSetPlane failed"); } } }
uint32_t IntelHWComposerDrm::getCrtcId(int disp) { if (mDrmFd < 0) { ALOGE("%s: invalid drm FD\n", __func__); return 0; } drmModeEncoderPtr encoder = NULL; drmModeResPtr resources = NULL; drmModeCrtcPtr crtc = NULL; uint32_t crtc_id = 0; int i = 0; if ((encoder = getEncoder(disp)) == NULL) return 0; crtc_id = encoder->crtc_id; freeEncoder(encoder); if (crtc_id == 0) { /* Query an available crtc to use */ if ((resources = drmModeGetResources(mDrmFd)) == NULL) return 0; if (!resources->crtcs) return 0; for (i = 0; i < resources->count_crtcs; i++) { crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[i]); if (!crtc) { ALOGE("%s: Failed to get crtc %d, error is %s", __func__, resources->crtcs[i], strerror(errno)); continue; } if (crtc->buffer_id == 0) { crtc_id = crtc->crtc_id; drmModeFreeCrtc(crtc); break; } drmModeFreeCrtc(crtc); } } return crtc_id; }
static void drmmode_crtc_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) { xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; crtc = xf86CrtcCreate(scrn, &drmmode_crtc_funcs); if (crtc == NULL) return; drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; crtc->driver_private = drmmode_crtc; return; }
static uint32_t get_console_buffer_id (ply_renderer_backend_t *backend, uint32_t controller_id) { drmModeCrtc *controller; uint32_t console_buffer_id; console_buffer_id = 0; controller = drmModeGetCrtc (backend->device_fd, controller_id); if (controller == NULL) return 0; console_buffer_id = controller->buffer_id; drmModeFreeCrtc (controller); return console_buffer_id; }
void xorg_crtc_init(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); xf86CrtcPtr crtc; drmModeResPtr res; drmModeCrtcPtr drm_crtc = NULL; struct crtc_private *crtcp; int c; res = drmModeGetResources(ms->fd); if (res == 0) { ErrorF("Failed drmModeGetResources %d\n", errno); return; } for (c = 0; c < res->count_crtcs; c++) { drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); if (!drm_crtc) continue; crtc = xf86CrtcCreate(pScrn, &crtc_funcs); if (crtc == NULL) goto out; crtcp = calloc(1, sizeof(struct crtc_private)); if (!crtcp) { xf86CrtcDestroy(crtc); goto out; } crtcp->drm_crtc = drm_crtc; crtcp->entry.pixmap = NULL; WSBMINITLISTHEAD(&crtcp->entry.scanout_head); crtc->driver_private = crtcp; } out: drmModeFreeResources(res); }
static void listCrtcProperties(void) { int i; drmModeCrtcPtr c; for (i = 0; i < res->count_crtcs; i++) { c = drmModeGetCrtc(fd, res->crtcs[i]); if (!c) { fprintf(stderr, "Could not get crtc %u: %s\n", res->crtcs[i], strerror(errno)); continue; } printf("CRTC %u\n", c->crtc_id); listObjectProperties(c->crtc_id, DRM_MODE_OBJECT_CRTC); drmModeFreeCrtc(c); } }
static drmModeCrtc * find_crtc_for_connector (int fd, drmModeRes * res, drmModeConnector * conn, guint * pipe) { int i; int crtc_id; drmModeEncoder *enc; drmModeCrtc *crtc; crtc_id = -1; for (i = 0; i < res->count_encoders; i++) { enc = drmModeGetEncoder (fd, res->encoders[i]); if (enc) { if (enc->encoder_id == conn->encoder_id) { crtc_id = enc->crtc_id; drmModeFreeEncoder (enc); break; } drmModeFreeEncoder (enc); } } if (crtc_id == -1) return NULL; for (i = 0; i < res->count_crtcs; i++) { crtc = drmModeGetCrtc (fd, res->crtcs[i]); if (crtc) { if (crtc_id == crtc->crtc_id) { if (pipe) *pipe = i; return crtc; } drmModeFreeCrtc (crtc); } } return NULL; }
static drmModeCrtc * find_controller_for_encoder (ply_renderer_backend_t *backend, drmModeEncoder *encoder) { drmModeCrtc *controller; controller = NULL; /* Monitor is already lit. We'll use the same controller. */ if (encoder->crtc_id != 0) { controller = drmModeGetCrtc (backend->device_fd, encoder->crtc_id); if (controller != NULL) { ply_trace ("Found already lit monitor"); return controller; } } return NULL; }
static void reset_scan_out_buffer_if_needed (ply_renderer_backend_t *backend, ply_renderer_head_t *head) { drmModeCrtc *controller; if (!ply_terminal_is_active (backend->terminal)) return; controller = drmModeGetCrtc (backend->device_fd, head->controller_id); if (controller == NULL) return; if (controller->buffer_id != head->scan_out_buffer_id) { ply_trace ("Something stole the monitor"); ply_renderer_head_set_scan_out_buffer (backend, head, head->scan_out_buffer_id); } drmModeFreeCrtc (controller); }
static void dump_crtcs_fd(int drmfd) { int i; drmModeRes *mode_resources = drmModeGetResources(drmfd); igt_info("CRTCs:\n"); igt_info("id\tfb\tpos\tsize\n"); for (i = 0; i < mode_resources->count_crtcs; i++) { drmModeCrtc *crtc; crtc = drmModeGetCrtc(drmfd, mode_resources->crtcs[i]); if (!crtc) { igt_warn("could not get crtc %i: %s\n", mode_resources->crtcs[i], strerror(errno)); continue; } igt_info("%d\t%d\t(%d,%d)\t(%dx%d)\n", crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, crtc->width, crtc->height); kmstest_dump_mode(&crtc->mode); drmModeFreeCrtc(crtc); } igt_info("\n"); drmModeFreeResources(mode_resources); }
/* Prevents some glitch if Chromium OS keeps cursor enabled (#2878). */ static void drm_disable_cursor() { int i, fd; drmModeRes* resources; if (!orig_open) preload_init(); fd = orig_open("/dev/dri/card0", O_RDWR, 0); TRACE("%s %d\n", __func__, fd); if (fd < 0) return; resources = drmModeGetResources(fd); if (!resources) goto closefd; TRACE("%s res=%p\n", __func__, resources); for (i = 0; i < resources->count_crtcs; i++) { drmModeCrtc* crtc; crtc = drmModeGetCrtc(fd, resources->crtcs[i]); TRACE("%s crtc %d %p\n", __func__, i, crtc); if (crtc) { drmModeSetCursor(fd, crtc->crtc_id, 0, 0, 0); drmModeFreeCrtc(crtc); } } drmModeFreeResources(resources); closefd: orig_close(fd); }
int main(int argc, char *argv[]) { EGLDisplay dpy; EGLContext ctx; EGLSurface surface; EGLConfig config; EGLint major, minor, n; const char *ver; uint32_t handle, stride; struct kms kms; int ret, fd; struct gbm_device *gbm; struct gbm_bo *bo; drmModeCrtcPtr saved_crtc; struct gbm_surface *gs; fd = open(device_name, O_RDWR); if (fd < 0) { /* Probably permissions error */ fprintf(stderr, "couldn't open %s, skipping\n", device_name); return -1; } gbm = gbm_create_device(fd); if (gbm == NULL) { fprintf(stderr, "couldn't create gbm device\n"); ret = -1; goto close_fd; } dpy = eglGetDisplay(gbm); if (dpy == EGL_NO_DISPLAY) { fprintf(stderr, "eglGetDisplay() failed\n"); ret = -1; goto destroy_gbm_device; } if (!eglInitialize(dpy, &major, &minor)) { printf("eglInitialize() failed\n"); ret = -1; goto egl_terminate; } ver = eglQueryString(dpy, EGL_VERSION); printf("EGL_VERSION = %s\n", ver); if (!setup_kms(fd, &kms)) { ret = -1; goto egl_terminate; } eglBindAPI(EGL_OPENGL_API); if (!eglChooseConfig(dpy, attribs, &config, 1, &n) || n != 1) { fprintf(stderr, "failed to choose argb config\n"); goto egl_terminate; } ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); if (ctx == NULL) { fprintf(stderr, "failed to create context\n"); ret = -1; goto egl_terminate; } gs = gbm_surface_create(gbm, kms.mode.hdisplay, kms.mode.vdisplay, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); surface = eglCreateWindowSurface(dpy, config, gs, NULL); if (!eglMakeCurrent(dpy, surface, surface, ctx)) { fprintf(stderr, "failed to make context current\n"); ret = -1; goto destroy_context; } render_stuff(kms.mode.hdisplay, kms.mode.vdisplay); eglSwapBuffers(dpy, surface); bo = gbm_surface_lock_front_buffer(gs); handle = gbm_bo_get_handle(bo).u32; stride = gbm_bo_get_stride(bo); printf("handle=%d, stride=%d\n", handle, stride); ret = drmModeAddFB(fd, kms.mode.hdisplay, kms.mode.vdisplay, 24, 32, stride, handle, &kms.fb_id); if (ret) { fprintf(stderr, "failed to create fb\n"); goto rm_fb; } saved_crtc = drmModeGetCrtc(fd, kms.encoder->crtc_id); if (saved_crtc == NULL) goto rm_fb; ret = drmModeSetCrtc(fd, kms.encoder->crtc_id, kms.fb_id, 0, 0, &kms.connector->connector_id, 1, &kms.mode); if (ret) { fprintf(stderr, "failed to set mode: %m\n"); goto free_saved_crtc; } getchar(); ret = drmModeSetCrtc(fd, saved_crtc->crtc_id, saved_crtc->buffer_id, saved_crtc->x, saved_crtc->y, &kms.connector->connector_id, 1, &saved_crtc->mode); if (ret) { fprintf(stderr, "failed to restore crtc: %m\n"); } free_saved_crtc: drmModeFreeCrtc(saved_crtc); rm_fb: drmModeRmFB(fd, kms.fb_id); eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); destroy_context: eglDestroyContext(dpy, ctx); egl_terminate: eglTerminate(dpy); destroy_gbm_device: gbm_device_destroy(gbm); close_fd: close(fd); return ret; }
static CoglOutputKMS * find_output (int _index, int fd, drmModeRes *resources, int *excluded_connectors, int n_excluded_connectors, CoglError **error) { char *connector_env_name = g_strdup_printf ("COGL_KMS_CONNECTOR%d", _index); char *mode_env_name; drmModeConnector *connector; drmModeEncoder *encoder; CoglOutputKMS *output; drmModeModeInfo *modes; int n_modes; if (getenv (connector_env_name)) { unsigned long id = strtoul (getenv (connector_env_name), NULL, 10); connector = drmModeGetConnector (fd, id); } else connector = NULL; g_free (connector_env_name); if (connector == NULL) connector = find_connector (fd, resources, excluded_connectors, n_excluded_connectors); if (connector == NULL) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "No currently active connector found"); return NULL; } /* XXX: At this point it seems connector->encoder_id may be an invalid id of 0 * even though the connector is marked as connected. Referencing ->encoders[0] * seems more reliable. */ encoder = drmModeGetEncoder (fd, connector->encoders[0]); output = g_slice_new0 (CoglOutputKMS); output->connector = connector; output->encoder = encoder; output->saved_crtc = drmModeGetCrtc (fd, encoder->crtc_id); if (is_panel (connector->connector_type)) { n_modes = connector->count_modes + 1; modes = g_new (drmModeModeInfo, n_modes); memcpy (modes, connector->modes, sizeof (drmModeModeInfo) * connector->count_modes); /* TODO: parse EDID */ modes[n_modes - 1] = builtin_1024x768; } else { n_modes = connector->count_modes; modes = g_new (drmModeModeInfo, n_modes); memcpy (modes, connector->modes, sizeof (drmModeModeInfo) * n_modes); } mode_env_name = g_strdup_printf ("COGL_KMS_CONNECTOR%d_MODE", _index); if (getenv (mode_env_name)) { const char *name = getenv (mode_env_name); int i; CoglBool found = FALSE; drmModeModeInfo mode; for (i = 0; i < n_modes; i++) { if (strcmp (modes[i].name, name) == 0) { found = TRUE; break; } } if (!found) { g_free (mode_env_name); _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "COGL_KMS_CONNECTOR%d_MODE of %s could not be found", _index, name); return NULL; } n_modes = 1; mode = modes[i]; g_free (modes); modes = g_new (drmModeModeInfo, 1); modes[0] = mode; } g_free (mode_env_name); output->modes = modes; output->n_modes = n_modes; return output; }