diff --git a/util/display-kms.c b/util/display-kms.c
index 808945ca0c0b2501e22a3b10d0d3f2005be17a62..74b59fd28b955e56cf6a3579fa9efb09b37a975e 100644 (file)
--- a/util/display-kms.c
+++ b/util/display-kms.c
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "util.h"
+#include <libdce.h>
#include <xf86drmMode.h>
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);
}
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;
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]) {
+ omap_bo_del(disp->buf[i]->bo[0]);
+ if(disp->multiplanar){
+ 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:
/* 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;
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")) {
ERROR("invalid arg: %s", argv[i]);
goto fail;
}
+ disp_kms->bo_flags |= OMAP_BO_SCANOUT;
} else {
/* ignore */
continue;
}
}
- 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;