Allocate backing bo in CreatePixmap2 where it can safely fail

Previously we waited until ModifyPixmapHeader to
allocate the backing dumb_bo for the pixmap. If
this allocation failed, X would ignore it and end
up dereferencing a NULL pointer later on.

As CreatePixmap2 gives us all the info needed to
calculate the backing dumb_bo size, we can just
allocate it here. If this entrypoint fails, X will
report the error back to the client and carry on
normally.

Change-Id: I3de512c3e8981af4b4455796c8180101b6996512
diff --git a/src/omap_dri2.c b/src/omap_dri2.c
index cc7e418..237efac 100644
--- a/src/omap_dri2.c
+++ b/src/omap_dri2.c
@@ -184,12 +184,20 @@
 		pPixmap = createpix(pDraw);
 	}
 
+	if (!pPixmap)
+	{
+		assert(attachment != DRI2BufferFrontLeft);
+		ERROR_MSG("Failed to create back buffer for window");
+		free(buf);
+		return NULL;
+	}
+
 	bo = OMAPPixmapBo(pPixmap);
 	if (!bo)
 	{
 		ERROR_MSG("Attempting to DRI2 wrap a pixmap with no DRM buffer object backing");
-		/* TODO: MIDEGL-1462: Returning NULL here ends up in a segfault all the way in pixman which has no backtrace.
-		 * We get a more friendly segfault if we just let it be dereferenced in a few lines */
+		free(buf);
+		return NULL;
 	}
 
 	DRIBUF(buf)->attachment = attachment;
diff --git a/src/omap_exa.c b/src/omap_exa.c
index b1f40c0..69b6e1a 100644
--- a/src/omap_exa.c
+++ b/src/omap_exa.c
@@ -77,13 +77,36 @@
 }
 
 _X_EXPORT void *
-OMAPCreatePixmap (ScreenPtr pScreen, int width, int height,
+OMAPCreatePixmap2 (ScreenPtr pScreen, int width, int height,
 		int depth, int usage_hint, int bitsPerPixel,
 		int *new_fb_pitch)
 {
 	OMAPPixmapPrivPtr priv = calloc(sizeof(OMAPPixmapPrivRec), 1);
+	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+	OMAPPtr pOMAP = OMAPPTR(pScrn);
 
-	/* actual allocation of buffer is in OMAPModifyPixmapHeader */
+	enum omap_buf_type buf_type = OMAP_BO_NON_SCANOUT;
+	if (usage_hint & OMAP_CREATE_PIXMAP_SCANOUT)
+	{
+		buf_type = OMAP_BO_SCANOUT;
+	}
+
+	if (width > 0 && height > 0 && depth > 0 && bitsPerPixel > 0)
+	{
+		priv->bo = omap_bo_new_with_dim(pOMAP->dev,
+				width,
+				height,
+				depth,
+				bitsPerPixel, buf_type);
+		if (!priv->bo)
+		{
+			ERROR_MSG("failed to allocate %dx%d bo, buf_type = %d",
+					width, height, buf_type);
+			free(priv);
+			return NULL;
+		}
+		*new_fb_pitch = omap_bo_pitch(priv->bo);
+	}
 
 	/* The usage_hint field of the Pixmap passed to ModifyPixmapHeader is not
 	 * set to the usage_hint parameter passed to CreatePixmap.
diff --git a/src/omap_exa.h b/src/omap_exa.h
index 0ccc1d1..e8952f2 100644
--- a/src/omap_exa.h
+++ b/src/omap_exa.h
@@ -134,7 +134,7 @@
 #define OMAP_CREATE_PIXMAP_TILED   0x40000000
 
 
-void * OMAPCreatePixmap (ScreenPtr pScreen, int width, int height,
+void * OMAPCreatePixmap2 (ScreenPtr pScreen, int width, int height,
 		int depth, int usage_hint, int bitsPerPixel,
 		int *new_fb_pitch);
 void OMAPDestroyPixmap(ScreenPtr pScreen, void *driverPriv);
diff --git a/src/omap_exa_null.c b/src/omap_exa_null.c
index 259be33..b821d30 100644
--- a/src/omap_exa_null.c
+++ b/src/omap_exa_null.c
@@ -120,7 +120,7 @@
 
 	/* Required EXA functions: */
 	exa->WaitMarker = OMAPWaitMarker;
-	exa->CreatePixmap2 = OMAPCreatePixmap;
+	exa->CreatePixmap2 = OMAPCreatePixmap2;
 	exa->DestroyPixmap = OMAPDestroyPixmap;
 	exa->ModifyPixmapHeader = OMAPModifyPixmapHeader;