Esempio n. 1
0
static void 
_evas_outbuf_buffer_put(Outbuf *ob, Buffer *buffer, Eina_Rectangle *rects, unsigned int count)
{
   /* validate input params */
   if ((!ob) || (!buffer)) return;

#ifdef DRM_MODE_FEATURE_DIRTYFB
   drmModeClip *clip;
   unsigned int i = 0;
   int ret;

   clip = alloca(count * sizeof(drmModeClip));
   for (i = 0; i < count; i++)
     {
        clip[i].x1 = rects[i].x;
        clip[i].y1 = rects[i].y;
        clip[i].x2 = rects[i].w;
        clip[i].y2 = rects[i].h;
     }

   /* DBG("Marking FB Dirty: %d", buffer->fb); */
   ret = drmModeDirtyFB(ob->priv.fd, buffer->fb, clip, count);
   if (ret)
     {
        if (ret == -EINVAL)
          ERR("Could not set FB Dirty: %m");
     }
#endif
}
static void
end_flush (ply_renderer_driver_t *driver,
           uint32_t               buffer_id)
{
        ply_renderer_buffer_t *buffer;

        buffer = get_buffer_from_id (driver, buffer_id);

        assert (buffer != NULL);

        if (driver->requires_explicit_flushing) {
                struct drm_clip_rect flush_area;
                int ret;

                flush_area.x1 = 0;
                flush_area.y1 = 0;
                flush_area.x2 = buffer->width;
                flush_area.y2 = buffer->height;

                ret = drmModeDirtyFB (driver->device_fd, buffer->id, &flush_area, 1);

                if (ret == -ENOSYS)
                        driver->requires_explicit_flushing = false;
        }
}
Esempio n. 3
0
static int test2(void)
{
	drm_intel_bo *test_intel_bo;
	uint32_t fb_id;
	drmModeClip clip;
	int prime_fd;
	uint32_t udl_handle;
	int ret;

	test_intel_bo = drm_intel_bo_alloc(bufmgr, "test bo", BO_SIZE, 4096);

	drm_intel_bo_gem_export_to_prime(test_intel_bo, &prime_fd);

	ret = drmPrimeFDToHandle(udl_fd, prime_fd, &udl_handle);
	if (ret)
		goto out;

	ret = drmModeAddFB(udl_fd, 640, 480, 16, 16, 640, udl_handle, &fb_id);
	if (ret)
		goto out;

	clip.x1 = 0;
	clip.y1 = 0;
	clip.x2 = 10;
	clip.y2 = 10;
	ret = drmModeDirtyFB(udl_fd, fb_id, &clip, 1);
	if (ret) {
		return ret;
	}
out:
	dumb_bo_destroy(udl_fd, udl_handle);
	drm_intel_bo_unreference(test_intel_bo);
	return ret;
}
Esempio n. 4
0
static int
dispatch_dirty_region(ScrnInfoPtr scrn,
                      PixmapPtr pixmap, DamagePtr damage, int fb_id)
{
    modesettingPtr ms = modesettingPTR(scrn);
    RegionPtr dirty = DamageRegion(damage);
    unsigned num_cliprects = REGION_NUM_RECTS(dirty);
    int ret = 0;

    if (num_cliprects) {
        drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip));
        BoxPtr rect = REGION_RECTS(dirty);
        int i;

        if (!clip)
            return -ENOMEM;

        /* XXX no need for copy? */
        for (i = 0; i < num_cliprects; i++, rect++) {
            clip[i].x1 = rect->x1;
            clip[i].y1 = rect->y1;
            clip[i].x2 = rect->x2;
            clip[i].y2 = rect->y2;
        }

        /* TODO query connector property to see if this is needed */
        ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
        free(clip);
        DamageEmpty(damage);
    }
    return ret;
}
Esempio n. 5
0
static boolean
drm_surface_flush_frontbuffer(struct native_surface *nsurf)
{
#ifdef DRM_MODE_FEATURE_DIRTYFB
   struct drm_surface *drmsurf = drm_surface(nsurf);
   struct drm_display *drmdpy = drmsurf->drmdpy;

   if (drmsurf->front_fb.is_passive)
      drmModeDirtyFB(drmdpy->fd, drmsurf->front_fb.buffer_id, NULL, 0);
#endif

   return TRUE;
}
/*
 * 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;
}
Esempio n. 7
0
static void draw_rect(struct igt_fb *fb, enum igt_draw_method method,
		      uint32_t color)
{
	drmModeClip clip;
	int rc;

	switch (opts.draw_size) {
	case 0:
		clip.x1 = fb->width / 2 - 32;
		clip.x2 = fb->width / 2 + 32;
		clip.y1 = fb->height / 2 - 32;
		clip.y2 = fb->height / 2 + 32;
		break;
	case 1:
		clip.x1 = fb->width / 4;
		clip.x2 = fb->width / 4 + fb->width / 2;
		clip.y1 = fb->height / 4;
		clip.y2 = fb->height / 4 + fb->height / 2;
		break;
	case 2:
		clip.x1 = 0;
		clip.x2 = fb->width;
		clip.y1 = 0;
		clip.y2 = fb->height;
		break;
	default:
		igt_assert(false);
	}

	igt_draw_rect_fb(drm.fd, drm.bufmgr, NULL, fb, method, clip.x1, clip.y1,
			 clip.x2 - clip.x1, clip.y2 - clip.y1, color);

	if (method == IGT_DRAW_MMAP_WC) {
		rc = drmModeDirtyFB(drm.fd, fb->fb_id, &clip, 1);
		igt_assert(rc == 0 || rc == -ENOSYS);
	}
}
/*
 * Post a bo.  This is not thread-safe.
 */
int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo)
{
	struct gralloc_drm_t *drm = bo->drm;
	int ret;

	if (!bo->fb_id && drm->swap_mode != DRM_SWAP_COPY) {
		LOGE("unable to post bo %p without fb", bo);
		return -EINVAL;
	}

	/* TODO spawn a thread to avoid waiting and race */

	if (drm->first_post) {
		if (drm->swap_mode == DRM_SWAP_COPY) {
			struct gralloc_drm_bo_t *dst;

			dst = (drm->next_front) ?
				drm->next_front :
				drm->current_front;
			drm->drv->copy(drm->drv, dst, bo, 0, 0,
					bo->handle->width,
					bo->handle->height);
			bo = dst;
		}

		ret = drm_kms_set_crtc(drm, bo->fb_id);
		if (!ret) {
			drm->first_post = 0;
			drm->current_front = bo;
			if (drm->next_front == bo)
				drm->next_front = NULL;
		}

		return ret;
	}

	switch (drm->swap_mode) {
	case DRM_SWAP_FLIP:
		if (drm->swap_interval > 1)
			drm_kms_wait_for_post(drm, 1);
		ret = drm_kms_page_flip(drm, bo);
		if (drm->next_front) {
			/*
			 * wait if the driver says so or the current front
			 * will be written by CPU
			 */
			if (drm->mode_sync_flip ||
			    (drm->current_front->handle->usage &
			     GRALLOC_USAGE_SW_WRITE_MASK))
				drm_kms_page_flip(drm, NULL);
		}
		break;
	case DRM_SWAP_COPY:
		drm_kms_wait_for_post(drm, 0);
		drm->drv->copy(drm->drv, drm->current_front,
				bo, 0, 0,
				bo->handle->width,
				bo->handle->height);
		if (drm->mode_quirk_vmwgfx)
			ret = drmModeDirtyFB(drm->fd, drm->current_front->fb_id, &drm->clip, 1);
		ret = 0;
		break;
	case DRM_SWAP_SETCRTC:
		drm_kms_wait_for_post(drm, 0);
		ret = drm_kms_set_crtc(drm, bo->fb_id);
		drm->current_front = bo;
		break;
	default:
		/* no-op */
		ret = 0;
		break;
	}

	return ret;
}
Esempio n. 9
0
static Bool
CreateScreenResources(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    modesettingPtr ms = modesettingPTR(pScrn);
    PixmapPtr rootPixmap;
    Bool ret;
    void *pixels = NULL;
    int err;

    pScreen->CreateScreenResources = ms->createScreenResources;
    ret = pScreen->CreateScreenResources(pScreen);
    pScreen->CreateScreenResources = CreateScreenResources;

    if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
        return FALSE;

    if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
        return FALSE;

    drmmode_uevent_init(pScrn, &ms->drmmode);

    if (!ms->drmmode.sw_cursor)
        drmmode_map_cursor_bos(pScrn, &ms->drmmode);

    if (!ms->drmmode.gbm) {
        pixels = drmmode_map_front_bo(&ms->drmmode);
        if (!pixels)
            return FALSE;
    }

    rootPixmap = pScreen->GetScreenPixmap(pScreen);

    if (ms->drmmode.shadow_enable)
        pixels = ms->drmmode.shadow_fb;

    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels))
        FatalError("Couldn't adjust screen pixmap\n");

    if (ms->drmmode.shadow_enable) {
        if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked,
                       msShadowWindow, 0, 0))
            return FALSE;
    }

    err = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, NULL, 0);

    if (err != -EINVAL && err != -ENOSYS) {
        ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
                                  pScreen, rootPixmap);

        if (ms->damage) {
            DamageRegister(&rootPixmap->drawable, ms->damage);
            ms->dirty_enabled = TRUE;
            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
        }
        else {
            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                       "Failed to create screen damage record\n");
            return FALSE;
        }
    }
    return ret;
}