diff --git a/util/display-kms.c b/util/display-kms.c
index 882117b970a21c16a1524ee63c365e08f835c34c..b892dbc4a4e3aa34252946c9d7f5cc817fb26b6a 100644 (file)
--- a/util/display-kms.c
+++ b/util/display-kms.c
uint32_t fb_id;
};
+static int global_fd = 0;
+static uint32_t used_planes = 0;
+static int ndisplays = 0;
+
static struct omap_bo *
alloc_bo(struct display *disp, uint32_t bpp, uint32_t width, uint32_t height,
uint32_t *bo_handle, uint32_t *pitch)
bo_flags |= OMAP_BO_TILED_32;
}
}
-
bo_flags |= OMAP_BO_WC;
if (bo_flags & OMAP_BO_TILED) {
- bo = omap_bo_new_tiled(disp->dev, width, height, bo_flags);
+ bo = omap_bo_new_tiled(disp->dev, ALIGN2(width,7), height, bo_flags);
} else {
bo = omap_bo_new(disp->dev, width * height * bpp / 8, bo_flags);
}
buf->fourcc = fourcc;
buf->width = w;
buf->height = h;
+ buf->multiplanar = true;
buf->nbo = 1;
&bo_handles[0], &buf->pitches[0]);
break;
case FOURCC('N','V','1','2'):
- buf->nbo = 2;
- buf->bo[0] = alloc_bo(disp, 8, buf->width, buf->height,
- &bo_handles[0], &buf->pitches[0]);
- buf->bo[1] = alloc_bo(disp, 16, buf->width/2, buf->height/2,
- &bo_handles[1], &buf->pitches[1]);
+ if (disp->multiplanar) {
+ buf->nbo = 2;
+ buf->bo[0] = alloc_bo(disp, 8, buf->width, buf->height,
+ &bo_handles[0], &buf->pitches[0]);
+ buf->fd[0] = omap_bo_dmabuf(buf->bo[0]);
+ buf->bo[1] = alloc_bo(disp, 16, buf->width/2, buf->height/2,
+ &bo_handles[1], &buf->pitches[1]);
+ buf->fd[1] = omap_bo_dmabuf(buf->bo[1]);
+ } else {
+ buf->nbo = 1;
+ buf->bo[0] = alloc_bo(disp, 8, buf->width, buf->height * 3 / 2,
+ &bo_handles[0], &buf->pitches[0]);
+ buf->fd[0] = omap_bo_dmabuf(buf->bo[0]);
+ bo_handles[1] = bo_handles[0];
+ buf->pitches[1] = buf->pitches[0];
+ offsets[1] = buf->width * buf->height;
+ buf->multiplanar = false;
+ }
break;
case FOURCC('I','4','2','0'):
buf->nbo = 3;
return NULL;
}
+void
+free_buffers(struct display *disp, uint32_t n)
+{
+ uint32_t i;
+ for (i = 0; i < n; i++) {
+ if (disp->buf[i]) {
+ close(disp->buf[i]->fd[0]);
+ omap_bo_del(disp->buf[i]->bo[0]);
+ if(disp->multiplanar){
+ close(disp->buf[i]->fd[1]);
+ omap_bo_del(disp->buf[i]->bo[1]);
+ }
+ }
+ }
+free(disp->buf);
+}
+
static struct buffer **
alloc_buffers(struct display *disp, uint32_t n,
uint32_t fourcc, uint32_t w, uint32_t h)
goto fail;
}
}
-
+ disp->buf=bufs;
return bufs;
fail:
return last_err;
}
+int
+get_overlay_plane(struct display *disp, struct buffer *buf)
+{
+ struct display_kms *disp_kms = to_display_kms(disp);
+ uint32_t i, ret;
+
+ for (i = 0; i < disp_kms->connectors_count; i++) {
+ struct connector *connector = &disp_kms->connector[i];
+ drmModeModeInfo *mode = connector->mode;
+
+ disp_kms->ovr[i] = drmModeGetPlane(disp->fd,
+ disp_kms->plane_resources->planes[1]);
+
+ ret = drmModeObjectSetProperty(disp->fd,
+ disp_kms->ovr[i]->plane_id, DRM_MODE_OBJECT_PLANE, 7, 3);
+ if (ret < 0) {
+ MSG("Could not set Z order for plane");
+ return ret;
+ }
+ }
+ return 0;
+}
+
static int
post_vid_buffer(struct display *disp, struct buffer *buf,
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
/* ensure we have the overlay setup: */
for (i = 0; i < disp_kms->connectors_count; i++) {
struct connector *connector = &disp_kms->connector[i];
- uint32_t used_planes = 0;
drmModeModeInfo *mode = connector->mode;
if (! mode) {
if (! disp_kms->ovr[i]) {
for (j = 0; j < disp_kms->plane_resources->count_planes; j++) {
+ if (used_planes & (1 << j)) {
+ continue;
+ }
drmModePlane *ovr = drmModeGetPlane(disp->fd,
disp_kms->plane_resources->planes[j]);
- if ((ovr->possible_crtcs & (1 << connector->pipe)) &&
- !(used_planes & (1 << j))) {
+ if (ovr->possible_crtcs & (1 << connector->pipe)) {
disp_kms->ovr[i] = ovr;
used_planes |= (1 << j);
break;
continue;
}
- ret = drmModeSetPlane(disp->fd, disp_kms->ovr[i]->plane_id,
+ if(buf->noScale) {
+ ret = drmModeSetPlane(disp->fd, disp_kms->ovr[i]->plane_id,
+ connector->crtc, buf_kms->fb_id, 0,
+ /* Use x and y as co-ordinates of overlay */
+ x, y, buf->width, buf->height,
+ /* Consider source x and y is 0 always */
+ 0, 0, w << 16, h << 16);
+ } else {
+ ret = drmModeSetPlane(disp->fd, disp_kms->ovr[i]->plane_id,
connector->crtc, buf_kms->fb_id, 0,
/* make video fullscreen: */
0, 0, mode->hdisplay, mode->vdisplay,
/* source/cropping coordinates are given in Q16 */
x << 16, y << 16, w << 16, h << 16);
+ }
if (ret) {
ERROR("failed to enable plane %d: %s",
disp_kms->ovr[i]->plane_id, strerror(errno));
return ret;
}
+static void
+close_kms(struct display *disp)
+{
+ omap_device_del(disp->dev);
+ disp->dev = NULL;
+ if (used_planes) {
+ used_planes >>= 1;
+ }
+ if (--ndisplays == 0) {
+ close(global_fd);
+ }
+}
+
static void
connector_find_mode(struct display *disp, struct connector *c)
{
disp_kms_usage(void)
{
MSG("KMS Display Options:");
+ MSG("\t-1 \t\tforce single-plane buffers");
MSG("\t-t <tiled-mode>\t8, 16, 32, or auto");
MSG("\t-s <connector_id>:<mode>\tset a mode");
MSG("\t-s <connector_id>@<crtc_id>:<mode>\tset a mode");
}
disp = &disp_kms->base;
- disp->fd = drmOpen("omapdrm", NULL);
- if (disp->fd < 0) {
- ERROR("could not open drm device: %s (%d)", strerror(errno), errno);
- goto fail;
+ if (!global_fd) {
+ global_fd = drmOpen("omapdrm", NULL);
+ if (global_fd < 0) {
+ ERROR("could not open drm device: %s (%d)", strerror(errno), errno);
+ goto fail;
+ }
}
+ disp->fd = global_fd;
+ ndisplays++; /* increment the number of displays counter */
+
disp->dev = omap_device_new(disp->fd);
if (!disp->dev) {
ERROR("couldn't create device");
disp->get_vid_buffers = get_vid_buffers;
disp->post_buffer = post_buffer;
disp->post_vid_buffer = post_vid_buffer;
-
+ disp->close = close_kms;
+ disp->disp_free_buf = free_buffers ;
disp_kms->resources = drmModeGetResources(disp->fd);
if (!disp_kms->resources) {
ERROR("drmModeGetResources failed: %s", strerror(errno));
goto fail;
}
+ disp->multiplanar = true;
+
/* note: set args to NULL after we've parsed them so other modules know
* that it is already parsed (since the arg parsing is decentralized)
*/
if (!argv[i]) {
continue;
}
- if (!strcmp("-t", argv[i])) {
+ if (!strcmp("-1", argv[i])) {
+ disp->multiplanar = false;
+ } else if (!strcmp("-t", argv[i])) {
int n;
argv[i++] = NULL;
if (!strcmp(argv[i], "auto")) {
}
}
- MSG("using %d connectors, %dx%d display",
- disp_kms->connectors_count, disp->width, disp->height);
+ MSG("using %d connectors, %dx%d display, multiplanar: %d",
+ disp_kms->connectors_count, disp->width, disp->height, disp->multiplanar);
return disp;