Pass explicit dimensions when creating a buffer.

Replace omap_bo_new interface from libdrm omap layer with omap_bo_new_with_dim,
which takes width, height and bpp instead of a size. This enables the
pitch and size calculations from the DRM driver to be used by the DDX driver.

Change-Id: I84543860f9b149fefbb65c6100eb7bf00598be78

Conflicts:

	src/omap_driver.c
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4e41266..c55f81e 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -238,8 +238,6 @@
 	fb_id = omap_bo_get_fb(pOMAP->scanout);
 
 	if (fb_id == 0) {
-		unsigned int pitch =
-				OMAPCalculateStride(pScrn->virtualX, pScrn->bitsPerPixel);
 
 		DEBUG_MSG("create framebuffer: %dx%d",
 				pScrn->virtualX, pScrn->virtualY);
@@ -247,7 +245,7 @@
 		ret = drmModeAddFB(drmmode->fd,
 				pScrn->virtualX, pScrn->virtualY,
 				pScrn->depth, pScrn->bitsPerPixel,
-				pitch, omap_bo_handle(pOMAP->scanout),
+				omap_bo_pitch(pOMAP->scanout), omap_bo_handle(pOMAP->scanout),
 				&fb_id);
 		if (ret < 0) {
 			// Fixme - improve this error message:
@@ -494,11 +492,11 @@
 	}
 
 	cursor->ovr = ovr;
-	cursor->bo  = omap_bo_new(pOMAP->dev, w*h*4,
+	cursor->bo  = omap_bo_new_with_dim(pOMAP->dev, w, h, 32,
 			OMAP_BO_SCANOUT | OMAP_BO_WC);
 
 	handles[0] = omap_bo_handle(cursor->bo);
-	pitches[0] = w*4;
+	pitches[0] = omap_bo_pitch(cursor->bo);
 	offsets[0] = 0;
 
 	if (drmModeAddFB2(drmmode->fd, w, h, DRM_FORMAT_ARGB8888,
@@ -1028,10 +1026,9 @@
 {
 	OMAPPtr pOMAP = OMAPPTR(pScrn);
 	ScreenPtr pScreen = pScrn->pScreen;
-	unsigned int pitch;
 	struct omap_bo *new_scanout;
 	int res;
-	uint32_t new_fb_id;
+	uint32_t new_fb_id, pitch;
 	drmmode_ptr drmmode = drmmode_from_scrn(pScrn);
 
 	TRACE_ENTER();
@@ -1043,18 +1040,18 @@
 	pScrn->virtualX = width;
 	pScrn->virtualY = height;
 
-	pitch = OMAPCalculateStride(width, pScrn->bitsPerPixel);
-
-	if ((pitch * height) != omap_bo_size(pOMAP->scanout)) {
+	if (  (width != omap_bo_width(pOMAP->scanout))
+	      || (height != omap_bo_height(pOMAP->scanout))
+	      || (pScrn->bitsPerPixel != omap_bo_bpp(pOMAP->scanout)) ) {
 
 		/* delete old scanout buffer */
 		omap_bo_del(pOMAP->scanout);
 
-		DEBUG_MSG("allocating new scanout buffer: %dx%d (%d)",
-				width, height, pitch);
+		DEBUG_MSG("allocating new scanout buffer: %dx%d",
+				width, height);
 
 		/* allocate new scanout buffer */
-		new_scanout = omap_bo_new(pOMAP->dev, height * pitch,
+		new_scanout = omap_bo_new_with_dim(pOMAP->dev, width, height, pScrn->bitsPerPixel,
 				OMAP_BO_SCANOUT | OMAP_BO_WC);
 
 		if (!new_scanout) {
@@ -1062,6 +1059,7 @@
 					"Error reallocating scanout buffer\n");
 			return FALSE;
 		}
+		pitch = omap_bo_pitch(new_scanout);
 
 		res = drmModeAddFB(drmmode->fd,
 				width, height,
@@ -1079,6 +1077,8 @@
 		set_scanout_bo(pScrn, new_scanout);
 
 		pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8);
+	}else{
+		pitch = omap_bo_pitch(pOMAP->scanout);
 	}
 
 	if (pScreen && pScreen->ModifyPixmapHeader) {
diff --git a/src/omap_driver.c b/src/omap_driver.c
index ec695da..9b3caad 100644
--- a/src/omap_driver.c
+++ b/src/omap_driver.c
@@ -179,51 +179,23 @@
 	}
 }
 
-
-
-/**
- * Helper function for calculating the stride of pixmaps.
- * TODO get stride requirements from kernel driver, or from EXA module,
- * rather than hard-coding..
- */
-#define STRIDE_BOUNDARY 2
-unsigned int
-OMAPCalculateStride(unsigned int width, unsigned int bitsPerPixel)
-{
-	unsigned int alignedWidth;
-	alignedWidth = (width + (STRIDE_BOUNDARY - 1)) & ~(STRIDE_BOUNDARY - 1);
-	return ((alignedWidth * bitsPerPixel) + 7) / 8;
-}
-#define TILED_STRIDE_BOUNDARY 4096
-unsigned int
-OMAPCalculateTiledStride(unsigned int width, unsigned int bitsPerPixel)
-{
-	unsigned int stride = OMAPCalculateStride(width, bitsPerPixel);
-	stride = (stride + (4096 - 1)) & ~(4096 - 1);
-	return stride;
-}
-
-
 static Bool
 OMAPMapMem(ScrnInfoPtr pScrn)
 {
 	OMAPPtr pOMAP = OMAPPTR(pScrn);
-	int pitch;
 
-	pitch = OMAPCalculateStride(pScrn->virtualX, pScrn->bitsPerPixel);
+	DEBUG_MSG("allocating new scanout buffer: %dx%d",
+			pScrn->virtualX, pScrn->virtualY);
 
-	DEBUG_MSG("allocating new scanout buffer: %dx%d (%d)",
-			pScrn->virtualX, pScrn->virtualY, pitch);
-
-	pOMAP->scanout = omap_bo_new(pOMAP->dev, pScrn->virtualY * pitch,
-			OMAP_BO_SCANOUT | OMAP_BO_WC);
+	pOMAP->scanout = omap_bo_new_with_dim(pOMAP->dev, pScrn->virtualX, pScrn->virtualY,
+			pScrn->bitsPerPixel, OMAP_BO_SCANOUT | OMAP_BO_WC);
 	if (!pOMAP->scanout) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "Error allocating scanout buffer\n");
 		return FALSE;
 	}
 
-	pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8);
+	pScrn->displayWidth = omap_bo_pitch(pOMAP->scanout) / (pScrn->bitsPerPixel / 8);
 
 	return TRUE;
 }
diff --git a/src/omap_driver.h b/src/omap_driver.h
index 33ed51a..d2d28fd 100644
--- a/src/omap_driver.h
+++ b/src/omap_driver.h
@@ -107,15 +107,6 @@
 				##__VA_ARGS__); } while (0)
 
 
-/* Forward declarations: */
-struct _OMAPRec;
-
-extern unsigned int
-OMAPCalculateStride(unsigned int fbWidth, unsigned int bitsPerPixel);
-extern unsigned int
-OMAPCalculateTiledStride(unsigned int width, unsigned int bitsPerPixel);
-
-
 
 /** The driver's Screen-specific, "private" data structure. */
 typedef struct _OMAPRec
diff --git a/src/omap_drmif_fb.h b/src/omap_drmif_fb.h
index d94fdfa..4fcf0b9 100644
--- a/src/omap_drmif_fb.h
+++ b/src/omap_drmif_fb.h
@@ -46,5 +46,12 @@
 void omap_bo_set_fb(struct omap_bo *bo, uint32_t fb_id);
 uint32_t omap_bo_get_fb(struct omap_bo *bo);
 
+struct omap_bo *omap_bo_new_with_dim(struct omap_device *dev, uint32_t width,
+			uint32_t height, uint32_t bpp, uint32_t flags);
+uint32_t omap_bo_width(struct omap_bo *bo);
+uint32_t omap_bo_height(struct omap_bo *bo);
+uint32_t omap_bo_bpp(struct omap_bo *bo);
+uint32_t omap_bo_pitch(struct omap_bo *bo);
+
 #endif /* OMAP_DRMIF_FB_H_ */
 
diff --git a/src/omap_dumb.c b/src/omap_dumb.c
index c23cb29..5734368 100644
--- a/src/omap_dumb.c
+++ b/src/omap_dumb.c
@@ -24,7 +24,9 @@
 #include <stdlib.h>
 #include <sys/mman.h>
 #include <assert.h>
+#include <errno.h>
 
+#include <xf86.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
@@ -41,6 +43,10 @@
 	int from_name;
 	void *map_addr;
 	int fb_id;
+	uint32_t width;
+	uint32_t height;
+	uint32_t bpp;
+	uint32_t pitch;
 };
 
 /* device related functions:
@@ -64,7 +70,8 @@
 /* buffer-object related functions:
  */
 
-struct omap_bo *omap_bo_new(struct omap_device *dev, uint32_t size, uint32_t flags)
+struct omap_bo *omap_bo_new_with_dim(struct omap_device *dev,
+			uint32_t width, uint32_t height, uint32_t bpp, uint32_t flags)
 {
 	struct drm_mode_create_dumb create_dumb;
 	struct omap_bo *new_buf;
@@ -74,22 +81,18 @@
 	if (!new_buf)
 		return NULL;
 
-	/* The dumb interface requires width, height and bpp but we only have the final size, so fake those to make them
-	 * add up to size. This is OK as we get the real dimensions in drmAddFB.
-	 */
-	create_dumb.height = size / 2;
-	if (create_dumb.height == 0)
-	{
-		create_dumb.height = 1;
-	}
-	create_dumb.width = 1;
-	create_dumb.bpp = 16;
+	create_dumb.height = height;
+	create_dumb.width = width;
+	create_dumb.bpp = bpp;
 	create_dumb.flags = flags;
 
 	res = drmIoctl(dev->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
 	if (res)
 	{
 		free(new_buf);
+		xf86DrvMsg(-1, X_ERROR, "_CREATE_DUMB("
+				"{height: 0x%X, width: 0x%X, bpp: 0x%X, flags: 0x%X}) "
+				"failed. errno:0x%X",height,width,bpp,flags,errno);
 		return NULL;
 	}
 
@@ -99,6 +102,11 @@
 	new_buf->from_name = 0;
 	new_buf->map_addr = NULL;
 	new_buf->fb_id = 0;
+	new_buf->pitch = create_dumb.pitch;
+
+	new_buf->width = create_dumb.width;
+	new_buf->height = create_dumb.height;
+	new_buf->bpp = create_dumb.bpp;
 
 	return new_buf;
 }
@@ -195,6 +203,26 @@
 	return bo->size;
 }
 
+uint32_t omap_bo_width(struct omap_bo *bo)
+{
+	return bo->width;
+}
+
+uint32_t omap_bo_height(struct omap_bo *bo)
+{
+	return bo->height;
+}
+
+uint32_t omap_bo_bpp(struct omap_bo *bo)
+{
+	return bo->bpp;
+}
+
+uint32_t omap_bo_pitch(struct omap_bo *bo)
+{
+	return bo->pitch;
+}
+
 void *omap_bo_map(struct omap_bo *bo)
 {
 	if (!bo->map_addr)
diff --git a/src/omap_exa.c b/src/omap_exa.c
index 3d175fa..05c6ab4 100644
--- a/src/omap_exa.c
+++ b/src/omap_exa.c
@@ -89,7 +89,7 @@
 	OMAPPixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap);
 	ScrnInfoPtr pScrn = pix2scrn(pPixmap);
 	OMAPPtr pOMAP = OMAPPTR(pScrn);
-	uint32_t size, flags = OMAP_BO_WC;
+	uint32_t flags = OMAP_BO_WC;
 	Bool ret;
 
 	ret = miModifyPixmapHeader(pPixmap, width, height, depth,
@@ -146,26 +146,25 @@
 		default:
 			break;
 		}
-		pPixmap->devKind = OMAPCalculateTiledStride(width, bitsPerPixel);
-	} else {
-		pPixmap->devKind = OMAPCalculateStride(width, bitsPerPixel);
 	}
 
-	size = pPixmap->devKind * height;
-
-	if ((!priv->bo) || (omap_bo_size(priv->bo) != size)) {
+	if ((!priv->bo) || (omap_bo_width(priv->bo) != width)
+	                || (omap_bo_height(priv->bo) != height)
+	                || (omap_bo_bpp(priv->bo) != bitsPerPixel)) {
 		/* re-allocate buffer! */
 		omap_bo_del(priv->bo);
 		if (flags & OMAP_BO_TILED) {
 			priv->bo = omap_bo_new_tiled(pOMAP->dev, width, height, flags);
 		} else {
-			priv->bo = omap_bo_new(pOMAP->dev, size, flags);
+			priv->bo = omap_bo_new_with_dim(pOMAP->dev, width, height, bitsPerPixel, flags);
 		}
 	}
 
-	if (!priv->bo) {
-		DEBUG_MSG("failed to allocate %dx%d bo, size=%d, flags=%08x",
-				width, height, size, flags);
+	if (priv->bo) {
+		pPixmap->devKind = omap_bo_pitch(priv->bo);
+	}else{
+		DEBUG_MSG("failed to allocate %dx%d bo, flags=%08x",
+				width, height, flags);
 	}
 
 	return priv->bo != NULL;
diff --git a/src/omap_exa_null.c b/src/omap_exa_null.c
index b6cdb9d..7d1f295 100644
--- a/src/omap_exa_null.c
+++ b/src/omap_exa_null.c
@@ -112,7 +112,7 @@
 	exa->exa_minor = EXA_VERSION_MINOR;
 
 	exa->pixmapOffsetAlign = 0;
-	exa->pixmapPitchAlign = 32 * 4; // see OMAPCalculateStride()
+	exa->pixmapPitchAlign = 32;
 	exa->flags = EXA_OFFSCREEN_PIXMAPS |
 			EXA_HANDLES_PIXMAPS | EXA_SUPPORTS_PREPARE_AUX;
 	exa->maxX = 4096;