Пример #1
0
static DFBResult
drmkmsSetRegion( CoreLayer                  *layer,
                 void                       *driver_data,
                 void                       *layer_data,
                 void                       *region_data,
                 CoreLayerRegionConfig      *config,
                 CoreLayerRegionConfigFlags  updated,
                 CoreSurface                *surface,
                 CorePalette                *palette,
                 CoreSurfaceBufferLock      *left_lock,
                 CoreSurfaceBufferLock      *right_lock )
{
     int               ret;
     DRMKMSData       *drmkms = driver_data;
     DRMKMSDataShared *shared = drmkms->shared;
     DRMKMSLayerData  *data   = layer_data;

     D_DEBUG_AT( DRMKMS_Layer, "%s()\n", __FUNCTION__ );

     if (!drmkms->resources)
          return DFB_OK;

     if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_BUFFERMODE | CLRCF_SOURCE)) {
          int i, index = data->layer_index;

          for (i=0; i<shared->enabled_crtcs; i++) {
               if (shared->mirror_outputs)
                    index = i;

               if (shared->clone_outputs) {
                    ret = drmModeSetCrtc( drmkms->fd, drmkms->encoder[index]->crtc_id, (u32)(long)left_lock->handle, config->source.x, config->source.y,
                                          shared->cloned_connectors, shared->cloned_count, &shared->mode[index] );
               }
               else {
                    ret = drmModeSetCrtc( drmkms->fd, drmkms->encoder[index]->crtc_id, (u32)(long)left_lock->handle, config->source.x, config->source.y,
                                          &drmkms->connector[index]->connector_id, 1, &shared->mode[index] );
               }

               if (ret) {
                    D_PERROR( "DirectFB/DRMKMS: drmModeSetCrtc( fd %d, index %d, crtc 0x%x, fb_id 0x%lx, xy %d,%d, cloned %p, count %d ) failed! (%d)\n",
                              drmkms->fd, index, drmkms->encoder[index]->crtc_id, (long) left_lock->handle, config->source.x, config->source.y,
                              shared->cloned_connectors, shared->cloned_count, ret );
                    D_DEBUG_AT( DRMKMS_Mode, " crtc_id: %d connector_id %d, mode %dx%d\n",
                                drmkms->encoder[index]->crtc_id, drmkms->connector[index]->connector_id,
                                shared->mode[index].hdisplay, shared->mode[index].vdisplay );
                    return DFB_FAILURE;
               }

               if (!shared->mirror_outputs)
                    break;
          }

          shared->primary_dimension[data->layer_index] = surface->config.size;
          shared->primary_rect                         = config->source;
          shared->primary_fb                           = (u32)(long)left_lock->handle;
     }

     return DFB_OK;
}
Пример #2
0
static void
output_free (int fd, CoglOutputKMS *output)
{
  if (output->modes)
    g_free (output->modes);

  if (output->encoder)
    drmModeFreeEncoder (output->encoder);

  if (output->connector)
    {
      if (output->saved_crtc)
        {
          int ret = drmModeSetCrtc (fd,
                                    output->saved_crtc->crtc_id,
                                    output->saved_crtc->buffer_id,
                                    output->saved_crtc->x,
                                    output->saved_crtc->y,
                                    &output->connector->connector_id, 1,
                                    &output->saved_crtc->mode);
          if (ret)
            g_warning (G_STRLOC ": Error restoring saved CRTC");
        }
      drmModeFreeConnector (output->connector);
    }

  g_slice_free (CoglOutputKMS, output);
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
static void gfx_ctx_drm_egl_destroy_resources(gfx_ctx_drm_egl_data_t *drm)
{
   if (!drm)
      return;

   /* Make sure we acknowledge all page-flips. */

   if (waiting_for_flip)
      wait_flip(true);

   if (drm->g_egl_dpy)
   {
      if (drm->g_egl_ctx)
      {
         eglMakeCurrent(drm->g_egl_dpy,
               EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
         eglDestroyContext(drm->g_egl_dpy, drm->g_egl_ctx);
      }

      if (drm->g_egl_hw_ctx)
         eglDestroyContext(drm->g_egl_dpy, drm->g_egl_hw_ctx);

      if (drm->g_egl_surf)
         eglDestroySurface(drm->g_egl_dpy, drm->g_egl_surf);
      eglTerminate(drm->g_egl_dpy);
   }

   /* Be as careful as possible in deinit.
    * If we screw up, the KMS tty will not restore.
    */

   drm->g_egl_ctx     = NULL;
   drm->g_egl_hw_ctx  = NULL;
   drm->g_egl_surf    = NULL;
   drm->g_egl_dpy     = NULL;
   drm->g_config      = 0;

   /* Restore original CRTC. */
   if (drm->g_orig_crtc)
   {
      drmModeSetCrtc(drm->g_drm_fd, drm->g_orig_crtc->crtc_id,
            drm->g_orig_crtc->buffer_id,
            drm->g_orig_crtc->x,
            drm->g_orig_crtc->y,
            &drm->g_connector_id, 1, &drm->g_orig_crtc->mode);
   }

   free_drm_resources(drm);

   drm->g_drm_mode = NULL;
   g_quit         = 0;
   drm->g_crtc_id      = 0;
   drm->g_connector_id = 0;

   drm->g_fb_width  = 0;
   drm->g_fb_height = 0;

   drm->g_bo      = NULL;
   drm->g_next_bo = NULL;
}
Пример #5
0
static void crtc_release(struct MPGLContext *ctx)
{
    struct priv *p = ctx->priv;

    if (!p->active)
        return;
    p->active = false;

    // wait for current page flip
    while (p->waiting_for_flip) {
        int ret = drmHandleEvent(p->kms->fd, &p->ev);
        if (ret) {
            MP_ERR(ctx->vo, "drmHandleEvent failed: %i\n", ret);
            break;
        }
    }

    if (p->old_crtc) {
        drmModeSetCrtc(p->kms->fd,
                       p->old_crtc->crtc_id, p->old_crtc->buffer_id,
                       p->old_crtc->x, p->old_crtc->y,
                       &p->kms->connector->connector_id, 1,
                       &p->old_crtc->mode);
        drmModeFreeCrtc(p->old_crtc);
        p->old_crtc = NULL;
    }
}
Пример #6
0
static DFBResult
mesaSetRegion( CoreLayer                  *layer,
               void                       *driver_data,
               void                       *layer_data,
               void                       *region_data,
               CoreLayerRegionConfig      *config,
               CoreLayerRegionConfigFlags  updated,
               CoreSurface                *surface,
               CorePalette                *palette,
               CoreSurfaceBufferLock      *left_lock,
               CoreSurfaceBufferLock      *right_lock )
{
     int       ret;
     MesaData *mesa = driver_data;

     D_DEBUG_AT( Mesa_Layer, "%s()\n", __FUNCTION__ );

     ret = drmModeSetCrtc( mesa->fd, mesa->encoder->crtc_id, (u32)(long)left_lock->handle, 0, 0,
                           &mesa->connector->connector_id, 1, &mesa->mode );
     if (ret) {
          D_PERROR( "DirectFB/Mesa: drmModeSetCrtc() failed! (%d)\n", ret );
          return DFB_FAILURE;
     }

     return DFB_OK;
}
Пример #7
0
static void display_deactivate(struct uterm_display *disp)
{
	if (!display_is_online(disp))
		return;

	if (disp->dumb.saved_crtc) {
		if (disp->video->flags & VIDEO_AWAKE) {
			drmModeSetCrtc(disp->video->dumb.fd,
					disp->dumb.saved_crtc->crtc_id,
					disp->dumb.saved_crtc->buffer_id,
					disp->dumb.saved_crtc->x,
					disp->dumb.saved_crtc->y,
					&disp->dumb.conn_id,
					1,
					&disp->dumb.saved_crtc->mode);
		}
		drmModeFreeCrtc(disp->dumb.saved_crtc);
		disp->dumb.saved_crtc = NULL;
	}

	destroy_rb(disp, &disp->dumb.rb[1]);
	destroy_rb(disp, &disp->dumb.rb[0]);
	disp->current_mode = NULL;
	disp->flags &= ~(DISPLAY_ONLINE | DISPLAY_VSYNC);
	log_info("deactivating display %p", disp);
}
Пример #8
0
static void
_cogl_winsys_egl_cleanup_context (CoglDisplay *display)
{
  CoglDisplayEGL *egl_display = display->winsys;
  CoglDisplayKMS *kms_display = egl_display->platform;
  CoglRenderer *renderer = display->renderer;
  CoglRendererEGL *egl_renderer = renderer->winsys;
  CoglRendererKMS *kms_renderer = egl_renderer->platform;

  /* Restore the saved CRTC - this failing should not propagate an error */
  if (kms_display->saved_crtc)
    {
      int ret = drmModeSetCrtc (kms_renderer->fd,
                                kms_display->saved_crtc->crtc_id,
                                kms_display->saved_crtc->buffer_id,
                                kms_display->saved_crtc->x,
                                kms_display->saved_crtc->y,
                                &kms_display->connector->connector_id, 1,
                                &kms_display->saved_crtc->mode);
      if (ret)
        g_critical (G_STRLOC ": Error restoring saved CRTC");

      drmModeFreeCrtc (kms_display->saved_crtc);
    }
}
Пример #9
0
static void modeset_cleanup(int fd)
{
	struct modeset_dev *iter;

	while (modeset_list) {
		/* remove from global list */
		iter = modeset_list;
		modeset_list = iter->next;

		/* restore saved CRTC configuration */
		drmModeSetCrtc(fd,
			       iter->saved_crtc->crtc_id,
			       iter->saved_crtc->buffer_id,
			       iter->saved_crtc->x,
			       iter->saved_crtc->y,
			       &iter->conn,
			       1,
			       &iter->saved_crtc->mode);
		drmModeFreeCrtc(iter->saved_crtc);

		/* destroy framebuffers */
		modeset_destroy_fb(fd, &iter->bufs[1]);
		modeset_destroy_fb(fd, &iter->bufs[0]);

		/* free allocated memory */
		free(iter);
	}
}
Пример #10
0
bool CDRMUtils::RestoreOriginalMode()
{
  if(!m_orig_crtc)
  {
    return false;
  }

  auto ret = drmModeSetCrtc(m_fd,
                            m_orig_crtc->crtc_id,
                            m_orig_crtc->buffer_id,
                            m_orig_crtc->x,
                            m_orig_crtc->y,
                            &m_connector->connector->connector_id,
                            1,
                            &m_orig_crtc->mode);

  if(ret)
  {
    CLog::Log(LOGERROR, "CDRMUtils::%s - failed to set original crtc mode", __FUNCTION__);
    return false;
  }

  CLog::Log(LOGDEBUG, "CDRMUtils::%s - set original crtc mode", __FUNCTION__);

  drmModeFreeCrtc(m_orig_crtc);
  m_orig_crtc = nullptr;

  return true;
}
Пример #11
0
static bool
ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend,
                                       ply_renderer_head_t    *head,
                                       uint32_t                buffer_id)
{
  drmModeModeInfo *mode;
  uint32_t *connector_ids;
  int number_of_connectors;

  connector_ids = (uint32_t *) ply_array_get_uint32_elements (head->connector_ids);
  number_of_connectors = ply_array_get_size (head->connector_ids);

  mode = &head->connector0->modes[head->connector0_mode_index];

  ply_trace ("Setting scan out buffer of %ldx%ld head to our buffer",
             head->area.width, head->area.height);

  /* Tell the controller to use the allocated scan out buffer on each connectors
  */
  if (drmModeSetCrtc (backend->device_fd, head->controller_id, buffer_id,
                      0, 0, connector_ids, number_of_connectors, mode) < 0)
    {
      ply_trace ("Couldn't set scan out buffer for head with controller id %d",
                 head->controller_id);
      return false;
    }

  return true;
}
Пример #12
0
static DFBResult
drmkmsSetEncoderConfig( CoreScreen                   *screen,
                        void                         *driver_data,
                        void                         *screen_data,
                        int                           encoder,
                        const DFBScreenEncoderConfig *config )
{
     int ret = 0;

     DRMKMSData       *drmkms = driver_data;
     DRMKMSDataShared *shared = drmkms->shared;

     DFBScreenEncoderFrequency dse_freq;
     DFBScreenOutputResolution dso_res;

     D_DEBUG_AT( DRMKMS_Screen, "%s()\n", __FUNCTION__ );

     if (!(config->flags & (DSECONF_FREQUENCY | DSECONF_RESOLUTION)))
          return DFB_INVARG;

     drmkms_mode_to_dsor_dsef( &shared->mode[encoder], &dso_res, &dse_freq );

     if (config->flags & DSECONF_FREQUENCY) {
          D_DEBUG_AT( DRMKMS_Screen, "   -> requested frequency change \n" );
          dse_freq = config->frequency;
     }

     if (config->flags & DSECONF_RESOLUTION) {
          D_DEBUG_AT( DRMKMS_Screen, "   -> requested resolution change \n" );
          dso_res = config->resolution;
     }

     drmModeModeInfo *videomode = drmkms_dsor_freq_to_mode( encoder, dso_res, dse_freq );

     if (!videomode)
          return DFB_INVARG;

     if ((shared->primary_dimension[encoder].w && (shared->primary_dimension[encoder].w < videomode->hdisplay) ) ||
         (shared->primary_dimension[encoder].h && (shared->primary_dimension[encoder].h < videomode->vdisplay ))) {

          D_DEBUG_AT( DRMKMS_Screen, "    -> cannot switch to mode to something that is bigger than the current primary layer\n" );

          return DFB_INVARG;
     }

     if (shared->primary_fb)
          ret = drmModeSetCrtc( drmkms->fd, drmkms->encoder[encoder]->crtc_id, shared->primary_fb, shared->primary_rect.x, shared->primary_rect.y,
                                &drmkms->connector[encoder]->connector_id, 1, videomode );

     if (ret) {
          D_DEBUG_AT( DRMKMS_Screen, " crtc_id: %d connector_id %d, mode %dx%d\n", drmkms->encoder[encoder]->crtc_id, drmkms->connector[encoder]->connector_id, shared->mode[encoder].hdisplay, shared->mode[encoder].vdisplay );
          D_PERROR( "DirectFB/DRMKMS: drmModeSetCrtc() failed! (%d)\n", ret );
          return DFB_FAILURE;
     }

     shared->mode[encoder] = *videomode;

     return DFB_OK;
}
Пример #13
0
void QEglFSKmsGbmScreen::flip()
{
    if (!m_gbm_surface) {
        qWarning("Cannot sync before platform init!");
        return;
    }

    m_gbm_bo_next = gbm_surface_lock_front_buffer(m_gbm_surface);
    if (!m_gbm_bo_next) {
        qWarning("Could not lock GBM surface front buffer!");
        return;
    }

    FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next);

    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) {
        int ret = drmModeSetCrtc(fd,
                                 op.crtc_id,
                                 fb->fb,
                                 0, 0,
                                 &op.connector_id, 1,
                                 &op.modes[op.mode]);

        if (ret == -1) {
            qErrnoWarning(errno, "Could not set DRM mode!");
        } else {
            op.mode_set = true;
            setPowerState(PowerStateOn);

            if (!op.plane_set) {
                op.plane_set = true;
                if (op.wants_plane) {
                    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");
                }
            }
        }
    }

    int ret = drmModePageFlip(fd,
                              op.crtc_id,
                              fb->fb,
                              DRM_MODE_PAGE_FLIP_EVENT,
                              this);
    if (ret) {
        qErrnoWarning("Could not queue DRM page flip!");
        gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next);
        m_gbm_bo_next = Q_NULLPTR;
    }
}
Пример #14
0
static void gfx_ctx_drm_egl_destroy(void *data)
{
   (void)data;
   // Make sure we acknowledge all page-flips.
   if (waiting_for_flip)
      wait_flip(true);

   if (g_egl_dpy)
   {
      if (g_egl_ctx)
      {
         eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
         eglDestroyContext(g_egl_dpy, g_egl_ctx);
      }

      if (g_egl_hw_ctx)
         eglDestroyContext(g_egl_dpy, g_egl_hw_ctx);

      if (g_egl_surf)
         eglDestroySurface(g_egl_dpy, g_egl_surf);
      eglTerminate(g_egl_dpy);
   }

   // Be as careful as possible in deinit.
   // If we screw up, the KMS tty will not restore.

   g_egl_ctx     = NULL;
   g_egl_hw_ctx  = NULL;
   g_egl_surf    = NULL;
   g_egl_dpy     = NULL;
   g_config      = 0;

   // Restore original CRTC.
   if (g_orig_crtc)
   {
      drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id,
            g_orig_crtc->buffer_id,
            g_orig_crtc->x,
            g_orig_crtc->y,
            &g_connector_id, 1, &g_orig_crtc->mode);
   }

   free_drm_resources();

   g_drm_mode = NULL;

   g_quit         = 0;
   g_crtc_id      = 0;
   g_connector_id = 0;

   g_fb_width  = 0;
   g_fb_height = 0;

   g_bo      = NULL;
   g_next_bo = NULL;

   g_inited = false;
}
Пример #15
0
static void crtc_commit_legacy(struct kms_atomic_crtc_state *crtc,
			       struct kms_atomic_plane_state *plane,
			       enum kms_atomic_check_relax relax)
{
	drmModeObjectPropertiesPtr props;
	uint32_t *connectors;
	int num_connectors = 0;
	int i;

	if (!crtc->active) {
		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
					 crtc->obj, 0, 0, 0, NULL, 0, NULL));
		return;
	}

	connectors = calloc(crtc->state->num_connectors,
			    sizeof(*connectors));
	igt_assert(connectors);

	igt_assert_neq_u32(crtc->mode.id, 0);

	for (i = 0; i < crtc->state->num_connectors; i++) {
		struct kms_atomic_connector_state *connector =
			&crtc->state->connectors[i];

		if (connector->crtc_id != crtc->obj)
			continue;

		connectors[num_connectors++] = connector->obj;
	}

	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc->obj,
	                         plane->fb_id,
				 plane->src_x >> 16, plane->src_y >> 16,
				 (num_connectors) ? connectors : NULL,
				 num_connectors,
				 crtc->mode.data));
	/* When doing a legacy commit, the core may update MODE_ID to be a new
	 * blob implicitly created by the legacy request. Hence we backfill
	 * the value in the state object to ensure they match. */
	props = drmModeObjectGetProperties(crtc->state->desc->fd, crtc->obj,
					   DRM_MODE_OBJECT_CRTC);
	igt_assert(props);

	for (i = 0; i < props->count_props; i++) {
		if (props->props[i] !=
		    crtc->state->desc->props_crtc[CRTC_MODE_ID])
			continue;
		crtc->mode.id = props->prop_values[i];
		break;
	}

	drmModeFreeObjectProperties(props);

	crtc_check_current_state(crtc, plane, relax);
	plane_check_current_state(plane, relax);
}
Пример #16
0
static Bool
crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
		    Rotation rotation, int x, int y)
{
    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
    modesettingPtr ms = modesettingPTR(crtc->scrn);
    xf86OutputPtr output = NULL;
    struct crtc_private *crtcp = crtc->driver_private;
    drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
    drmModeModeInfo drm_mode;
    int i, ret;
    unsigned int connector_id;

    for (i = 0; i < config->num_output; output = NULL, i++) {
	output = config->output[i];

	if (output->crtc == crtc)
	    break;
    }

    if (!output)
	return FALSE;

    connector_id = xorg_output_get_id(output);

    drm_mode.clock = mode->Clock;
    drm_mode.hdisplay = mode->HDisplay;
    drm_mode.hsync_start = mode->HSyncStart;
    drm_mode.hsync_end = mode->HSyncEnd;
    drm_mode.htotal = mode->HTotal;
    drm_mode.vdisplay = mode->VDisplay;
    drm_mode.vsync_start = mode->VSyncStart;
    drm_mode.vsync_end = mode->VSyncEnd;
    drm_mode.vtotal = mode->VTotal;
    drm_mode.flags = mode->Flags;
    drm_mode.hskew = mode->HSkew;
    drm_mode.vscan = mode->VScan;
    drm_mode.vrefresh = mode->VRefresh;
    if (!mode->name)
	xf86SetModeDefaultName(mode);
    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
    drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0';

    ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
			 &connector_id, 1, &drm_mode);

    if (ret)
	return FALSE;

    crtc->x = x;
    crtc->y = y;
    crtc->mode = *mode;
    crtc->rotation = rotation;

    return TRUE;
}
static void drm_disable_crtc(int drm_fd, drmModeCrtc *crtc) {
    if (crtc) {
        drmModeSetCrtc(drm_fd, crtc->crtc_id,
                       0, // fb_id
                       0, 0,  // x,y
                       NULL,  // connectors
                       0,     // connector_count
                       NULL); // mode
    }
}
Пример #18
0
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;
}
Пример #19
0
void
NativeStateDRM::flip()
{
    gbm_bo* next = gbm_surface_lock_front_buffer(surface_);
    fb_ = fb_get_from_bo(next);
    unsigned int waiting(1);

    if (!crtc_set_) {
        int status = drmModeSetCrtc(fd_, encoder_->crtc_id, fb_->fb_id, 0, 0,
                                    &connector_->connector_id, 1, mode_);
        if (status >= 0) {
            crtc_set_ = true;
            bo_ = next;
        }
        else {
            Log::error("Failed to set crtc: %d\n", status);
        }
        return;
    }

    int status = drmModePageFlip(fd_, encoder_->crtc_id, fb_->fb_id,
                                 DRM_MODE_PAGE_FLIP_EVENT, &waiting);
    if (status < 0) {
        Log::error("Failed to enqueue page flip: %d\n", status);
        return;
    }

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(fd_, &fds);
    drmEventContext evCtx;
    evCtx.version = DRM_EVENT_CONTEXT_VERSION;
    evCtx.page_flip_handler = page_flip_handler;

    while (waiting) {
        status = select(fd_ + 1, &fds, 0, 0, 0);
        if (status < 0) {
            // Most of the time, select() will return an error because the
            // user pressed Ctrl-C.  So, only print out a message in debug
            // mode, and just check for the likely condition and release
            // the current buffer object before getting out.
            Log::debug("Error in select\n");
            if (should_quit()) {
                gbm_surface_release_buffer(surface_, bo_);
                bo_ = next;
            }
            return;
        }
        drmHandleEvent(fd_, &evCtx);
    }

    gbm_surface_release_buffer(surface_, bo_);
    bo_ = next;
}
Пример #20
0
static void do_set_stereo_mode(struct connector *c)
{
	uint32_t fb_id;

	fb_id = igt_create_stereo_fb(drm_fd, &c->mode,
				     igt_bpp_depth_to_drm_format(bpp, depth),
				     tiling);

	igt_warn_on_f(drmModeSetCrtc(drm_fd, c->crtc, fb_id, 0, 0, &c->id, 1, &c->mode),
		      "failed to set mode (%dx%d@%dHz): %s\n", width, height, c->mode.vrefresh, strerror(errno));
}
Пример #21
0
QKmsScreen::~QKmsScreen()
{
    delete m_cursor;
    drmModeSetCrtc(m_device->fd(), m_oldCrtc->crtc_id, m_oldCrtc->buffer_id,
                   m_oldCrtc->x, m_oldCrtc->y,
                   &m_connectorId, 1, &m_oldCrtc->mode);
    drmModeFreeCrtc(m_oldCrtc);
    if (m_eglWindowSurface != EGL_NO_SURFACE)
        eglDestroySurface(m_device->eglDisplay(), m_eglWindowSurface);
    gbm_surface_destroy(m_gbmSurface);
}
Пример #22
0
void mgm::RealKMSOutput::restore_saved_crtc()
{
    if (!using_saved_crtc)
    {
        drmModeSetCrtc(drm_fd, saved_crtc.crtc_id, saved_crtc.buffer_id,
                       saved_crtc.x, saved_crtc.y,
                       &connector->connector_id, 1, &saved_crtc.mode);

        using_saved_crtc = true;
    }
}
Пример #23
0
static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
                         igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s)
{
    igt_display_t *display = &data->display;

    igt_output_set_pipe(output, pipe);

    /* create the pipe_crc object for this pipe */
    igt_pipe_crc_free(data->pipe_crc);
    data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);

    /* before allocating, free if any older fb */
    if (data->fb_id1) {
        igt_remove_fb(data->drm_fd, &data->fb1);
        data->fb_id1 = 0;
    }

    /* allocate fb for plane 1 */
    data->fb_id1 = igt_create_fb(data->drm_fd,
                                 mode->hdisplay, mode->vdisplay,
                                 DRM_FORMAT_XRGB8888,
                                 LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
                                 &data->fb1);
    igt_assert(data->fb_id1);

    paint_color(data, &data->fb1, mode->hdisplay, mode->vdisplay);

    /*
     * We always set the primary plane to actually enable the pipe as
     * there's no way (that works) to light up a pipe with only a sprite
     * plane enabled at the moment.
     */
    if (!plane->is_primary) {
        igt_plane_t *primary;

        primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
        igt_plane_set_fb(primary, &data->fb1);
    }

    igt_plane_set_fb(plane, &data->fb1);
    if (s == COMMIT_LEGACY) {
        int ret;
        ret = drmModeSetCrtc(data->drm_fd,
                             output->config.crtc->crtc_id,
                             data->fb_id1,
                             plane->pan_x, plane->pan_y,
                             &output->id,
                             1,
                             mode);
        igt_assert_eq(ret, 0);
    } else {
        igt_display_commit2(display, s);
    }
}
Пример #24
0
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;
}
Пример #25
0
/* Restore the original CRTC. */
static void restore_crtc(struct exynos_drm *d, int fd) {
  if (d->orig_crtc == NULL) return;

  drmModeSetCrtc(fd, d->orig_crtc->crtc_id,
                 d->orig_crtc->buffer_id,
                 d->orig_crtc->x,
                 d->orig_crtc->y,
                 &d->connector_id, 1, &d->orig_crtc->mode);

  drmModeFreeCrtc(d->orig_crtc);
  d->orig_crtc = NULL;
}
Пример #26
0
/* Restore the original CRTC. */
void drm_restore_crtc(void)
{
   if (!g_orig_crtc)
      return;

   drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id,
         g_orig_crtc->buffer_id,
         g_orig_crtc->x,
         g_orig_crtc->y,
         &g_connector_id, 1, &g_orig_crtc->mode);

   drmModeFreeCrtc(g_orig_crtc);
   g_orig_crtc = NULL;
}
static void drm_enable_crtc(int drm_fd, drmModeCrtc *crtc,
                            struct drm_surface *surface) {
    int32_t ret;

    ret = drmModeSetCrtc(drm_fd, crtc->crtc_id,
                         surface->fb_id,
                         0, 0,  // x,y
                         &main_monitor_connector->connector_id,
                         1,  // connector_count
                         &main_monitor_crtc->mode);

    if (ret)
        printf("drmModeSetCrtc failed ret=%d\n", ret);
}
Пример #28
0
static bool
ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend,
                                       ply_renderer_head_t    *head,
                                       uint32_t                buffer_id)
{

  /* Tell the controller to use the allocated scan out buffer
   */
  if (drmModeSetCrtc (backend->device_fd, head->controller_id, buffer_id,
                      0, 0, &head->connector->connector_id, 1, head->mode) < 0)
    return false;

  return true;
}
Пример #29
0
void DisplayOzone::presentScreen()
{
    if (!mCRTC)
    {
        // no monitor
        return;
    }

    // see if pending flip has finished, without blocking
    int fd = gbm_device_get_fd(mGBM);
    if (mPending)
    {
        pollfd pfd;
        pfd.fd     = fd;
        pfd.events = POLLIN;
        if (poll(&pfd, 1, 0) < 0)
        {
            std::cerr << "poll failed: " << errno << " " << strerror(errno) << std::endl;
        }
        if (pfd.revents & POLLIN)
        {
            drmEventContext event;
            event.version           = DRM_EVENT_CONTEXT_VERSION;
            event.page_flip_handler = pageFlipHandler;
            drmHandleEvent(fd, &event);
        }
    }

    // if pending flip has finished, schedule next one
    if (!mPending && mDrawing)
    {
        flushGL();
        if (mSetCRTC)
        {
            if (drmModeSetCrtc(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), 0, 0,
                               &mConnector->connector_id, 1, mMode))
            {
                std::cerr << "set crtc failed: " << errno << " " << strerror(errno) << std::endl;
            }
            mSetCRTC = false;
        }
        if (drmModePageFlip(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), DRM_MODE_PAGE_FLIP_EVENT,
                            this))
        {
            std::cerr << "page flip failed: " << errno << " " << strerror(errno) << std::endl;
        }
        mPending = mDrawing;
        mDrawing = nullptr;
    }
}
/*
 * Program CRTC.
 */
static int drm_kms_set_crtc(struct gralloc_drm_t *drm, int fb_id)
{
	int ret;

	ret = drmModeSetCrtc(drm->fd, drm->crtc_id, fb_id,
			0, 0, &drm->connector_id, 1, &drm->mode);
	if (ret) {
		LOGE("failed to set crtc");
		return ret;
	}

	if (drm->mode_quirk_vmwgfx)
		ret = drmModeDirtyFB(drm->fd, fb_id, &drm->clip, 1);

	return ret;
}