]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/omapdrmtest.git/blobdiff - util/display-kms.c
display-kms: Removed unnecessary include of libdce
[glsdk/omapdrmtest.git] / util / display-kms.c
index 808945ca0c0b2501e22a3b10d0d3f2005be17a62..b892dbc4a4e3aa34252946c9d7f5cc817fb26b6a 100644 (file)
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "util.h"
 
 #include <xf86drmMode.h>
@@ -59,6 +63,10 @@ struct buffer_kms {
        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)
@@ -77,11 +85,10 @@ alloc_bo(struct display *disp, uint32_t bpp, uint32_t width, uint32_t height,
                        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);
        }
@@ -89,6 +96,8 @@ alloc_bo(struct display *disp, uint32_t bpp, uint32_t width, uint32_t height,
        if (bo) {
                *bo_handle = omap_bo_handle(bo);
                *pitch = width * bpp / 8;
+               if (bo_flags & OMAP_BO_TILED)
+                       *pitch = ALIGN2(*pitch, PAGE_SHIFT);
        }
 
        return bo;
@@ -112,6 +121,7 @@ alloc_buffer(struct display *disp, uint32_t fourcc, uint32_t w, uint32_t h)
        buf->fourcc = fourcc;
        buf->width = w;
        buf->height = h;
+       buf->multiplanar = true;
 
        buf->nbo = 1;
 
@@ -131,11 +141,24 @@ alloc_buffer(struct display *disp, uint32_t fourcc, uint32_t w, uint32_t h)
                                &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;
@@ -165,6 +188,23 @@ fail:
        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)
@@ -185,7 +225,7 @@ alloc_buffers(struct display *disp, uint32_t n,
                        goto fail;
                }
        }
-
+       disp->buf=bufs;
        return bufs;
 
 fail:
@@ -294,6 +334,29 @@ post_buffer(struct display *disp, struct buffer *buf)
        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)
@@ -306,7 +369,6 @@ post_vid_buffer(struct display *disp, struct buffer *buf,
        /* 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) {
@@ -316,10 +378,12 @@ post_vid_buffer(struct display *disp, struct buffer *buf,
                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;
@@ -334,12 +398,21 @@ post_vid_buffer(struct display *disp, struct buffer *buf,
                        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));
@@ -349,6 +422,19 @@ post_vid_buffer(struct display *disp, struct buffer *buf,
        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)
 {
@@ -431,6 +517,7 @@ void
 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");
@@ -450,12 +537,17 @@ disp_kms_open(int argc, char **argv)
        }
        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");
@@ -466,7 +558,8 @@ disp_kms_open(int argc, char **argv)
        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));
@@ -479,6 +572,8 @@ disp_kms_open(int argc, char **argv)
                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)
         */
@@ -486,7 +581,9 @@ disp_kms_open(int argc, char **argv)
                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")) {
@@ -526,6 +623,7 @@ disp_kms_open(int argc, char **argv)
                                ERROR("invalid arg: %s", argv[i]);
                                goto fail;
                        }
+                       disp_kms->bo_flags |= OMAP_BO_SCANOUT;
                } else {
                        /* ignore */
                        continue;
@@ -547,8 +645,8 @@ disp_kms_open(int argc, char **argv)
                }
        }
 
-       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;