Beispiel #1
0
static int copy_pixels(struct evdi_framebuffer *ufb,
			char __user *buffer,
			int buf_byte_stride,
			int num_rects, struct drm_clip_rect *rects,
			int const max_x,
			int const max_y,
			struct evdi_cursor *cursor_copy)
{
	struct drm_framebuffer *fb = &ufb->base;
	struct drm_clip_rect *r;

	EVDI_CHECKPT();

	for (r = rects; r != rects + num_rects; ++r) {
		const int byte_offset = r->x1 * 4;
		const int byte_span = (r->x2 - r->x1) * 4;
		const int src_offset = fb->pitches[0] * r->y1 + byte_offset;
		const char *src = (char *)ufb->obj->vmapping + src_offset;
		const int dst_offset = buf_byte_stride * r->y1 + byte_offset;
		char __user *dst = buffer + dst_offset;
		int y = r->y2 - r->y1;

		/* rect size may correspond to previous resolution */
		if (max_x < r->x2 || max_y < r->y2) {
			EVDI_WARN("Rect size beyond expected dimensions\n");
			return -EFAULT;
		}

		EVDI_VERBOSE("copy rect %d,%d-%d,%d\n", r->x1, r->y1, r->x2,
			     r->y2);

		for (; y > 0; --y) {
			if (copy_to_user(dst, src, byte_span))
				return -EFAULT;

			src += fb->pitches[0];
			dst += buf_byte_stride;
		}
	}

	return evdi_cursor_composing_and_copy(cursor_copy,
				       ufb,
				       buffer,
				       buf_byte_stride,
				       max_x, max_y);
}
Beispiel #2
0
int evdi_handle_damage(struct evdi_framebuffer *fb,
                       int x,
                       int y,
                       int width,
                       int height)
{
  struct drm_device *dev = fb->base.dev;
  struct evdi_device *evdi = dev->dev_private;

  EVDI_CHECKPT();

  if (!fb->obj->vmapping) {
    if (evdi_gem_vmap(fb->obj) == -ENOMEM) {
      DRM_ERROR("failed to vmap fb\n");
      return 0;
    }
    if (!fb->obj->vmapping) {
      DRM_ERROR("failed to vmapping\n");
      return 0;
    }
  }

  {
    const int line_offset = fb->base.pitches[0] * y;
    const int byte_offset = line_offset + (x * 4); //RG24
    const char* pix = (char*)fb->obj->vmapping + byte_offset;

    EVDI_VERBOSE("%p %d,%d-%dx%d %02x%02x%02x%02x%02x%02x%02x%02x\n",
               fb, x, y, width, height,
               ((int)(pix[0])&0xff),
               ((int)(pix[1])&0xff),
               ((int)(pix[2])&0xff),
               ((int)(pix[3])&0xff),
               ((int)(pix[4])&0xff),
               ((int)(pix[5])&0xff),
               ((int)(pix[6])&0xff),
               ((int)(pix[7])&0xff));
  }

  {
    struct drm_clip_rect rect = { x, y, x + width, y + height };
    evdi_painter_mark_dirty(evdi, fb, &rect);
  }

  return 0;
}
Beispiel #3
0
void evdi_painter_mark_dirty(struct evdi_device *evdi,
			     const struct drm_clip_rect *dirty_rect)
{
	struct drm_clip_rect rect;
	struct evdi_framebuffer *efb = NULL;
	struct evdi_painter *painter = evdi->painter;

	painter_lock(evdi->painter);
	efb = evdi->painter->scanout_fb;
	if (!efb) {
		EVDI_WARN("Skip clip rect. Scanout buffer not set.\n");
		goto unlock;
	}

	rect = evdi_framebuffer_sanitize_rect(efb, dirty_rect);

	EVDI_VERBOSE("(dev=%d) %d,%d-%d,%d\n", evdi->dev_index, rect.x1,
		     rect.y1, rect.x2, rect.y2);

	if (painter->num_dirts == MAX_DIRTS)
		merge_dirty_rects(&painter->dirty_rects[0],
				  &painter->num_dirts);

	if (painter->num_dirts == MAX_DIRTS)
		collapse_dirty_rects(&painter->dirty_rects[0],
				     &painter->num_dirts);

	memcpy(&painter->dirty_rects[painter->num_dirts], &rect, sizeof(rect));
	painter->num_dirts++;

	if (painter->was_update_requested) {
		evdi_painter_send_update_ready(painter);
		painter->was_update_requested = false;
	}

unlock:
	painter_unlock(evdi->painter);
}