summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-12-28 12:49:24 -0800
committerEric Anholt <eric@anholt.net>2006-12-28 12:49:24 -0800
commite889bde13dcc2438181a03319e204ae7b9235a78 (patch)
tree489b799fe302754c54c7decc3cbf329ad7781632
parentc7083a6f30fdf1859f60beba4c352bd790af4773 (diff)
Draw textured video to the backing pixmap in the composited case.
Currently, when the backing pixmap is not in framebuffer, we just BadAlloc rather than drawing garbage to the front buffer. This can be fixed with EXA.
-rw-r--r--src/i830_video.c27
-rw-r--r--src/i830_video.h4
-rw-r--r--src/i915_video.c34
-rw-r--r--src/i965_video.c32
4 files changed, 71 insertions, 26 deletions
diff --git a/src/i830_video.c b/src/i830_video.c
index 76d4f9c8..b50b21b9 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -76,6 +76,8 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86fbman.h"
#include "regionstr.h"
#include "randrstr.h"
+#include "windowstr.h"
+#include "damage.h"
#include "i830.h"
#include "i830_video.h"
#include "xf86xv.h"
@@ -2016,7 +2018,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
OVERLAY_UPDATE;
}
-
#ifdef I830_USE_EXA
static void
I830VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area)
@@ -2167,6 +2168,7 @@ I830PutImage(ScrnInfoPtr pScrn,
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
I830OverlayRegPtr overlay =
(I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ PixmapPtr pPixmap;
INT32 x1, x2, y1, y2;
int srcPitch, srcPitch2 = 0, dstPitch, destId;
int top, left, npixels, nlines, size, loops;
@@ -2380,6 +2382,21 @@ I830PutImage(ScrnInfoPtr pScrn,
break;
}
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr)pDraw);
+ } else {
+ pPixmap = (PixmapPtr)pDraw;
+ }
+
+ if (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) ||
+ ((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase +
+ pI830->FbMapSize)) {
+ /* If the pixmap wasn't in framebuffer, then we have no way in XAA to
+ * force it there. So, we simply refuse to draw and fail.
+ */
+ return BadAlloc;
+ }
+
if (!pPriv->textured) {
/* update cliplist */
if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
@@ -2392,12 +2409,16 @@ I830PutImage(ScrnInfoPtr pScrn,
} else if (IS_I965G(pI830)) {
I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
dstPitch, x1, y1, x2, y2,
- src_w, src_h, drw_w, drw_h, pDraw);
+ src_w, src_h, drw_w, drw_h, pPixmap);
} else {
I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
dstPitch, x1, y1, x2, y2,
- src_w, src_h, drw_w, drw_h, pDraw);
+ src_w, src_h, drw_w, drw_h, pPixmap);
}
+ if (pPriv->textured) {
+ DamageDamageRegion(pDraw, clipBoxes);
+ }
+
pPriv->videoStatus = CLIENT_VIDEO_ON;
return Success;
diff --git a/src/i830_video.h b/src/i830_video.h
index 90c58b76..854d0b80 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -92,7 +92,7 @@ void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
- DrawablePtr pDraw);
+ PixmapPtr pPixmap);
void I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
int id, RegionPtr dstRegion, short width,
@@ -100,4 +100,4 @@ void I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
- DrawablePtr pDraw);
+ PixmapPtr pPixmap);
diff --git a/src/i915_video.c b/src/i915_video.c
index 636b2cbd..52fe1a51 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -57,12 +57,12 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
short width, short height, int video_pitch,
int x1, int y1, int x2, int y2,
short src_w, short src_h, short drw_w, short drw_h,
- DrawablePtr pDraw)
+ PixmapPtr pPixmap)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 format, ms3, s2, s5;
BoxPtr pbox;
- int nbox, dxo, dyo;
+ int nbox, dxo, dyo, pix_xoff, pix_yoff;
Bool planar;
#if 0
@@ -103,7 +103,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
/* draw rect -- just clipping */
OUT_RING(_3DSTATE_DRAW_RECT_CMD);
- OUT_RING(DRAW_DITHER_OFS_X(pDraw->x & 3)| DRAW_DITHER_OFS_Y(pDraw->y & 3)); /* flags */
+ OUT_RING(DRAW_DITHER_OFS_X(pPixmap->drawable.x & 3) |
+ DRAW_DITHER_OFS_Y(pPixmap->drawable.y & 3));
OUT_RING(0x00000000); /* ymin, xmin */
OUT_RING((pScrn->virtualX - 1) |
(pScrn->virtualY - 1) << 16); /* ymax, xmax */
@@ -155,8 +156,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
/* front buffer, pitch, offset */
OUT_RING(_3DSTATE_BUF_INFO_CMD);
OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
- (((pI830->displayWidth * pI830->cpp) / 4) << 2));
- OUT_RING(pI830->bufferOffset);
+ BUF_3D_PITCH(pPixmap->devKind));
+ OUT_RING(BUF_3D_ADDR((long)pPixmap->devPrivate.ptr - (long)pI830->FbBase));
ADVANCE_LP_RING();
if (!planar) {
@@ -340,6 +341,17 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
ADVANCE_LP_RING();
}
+ /* Set up the offset for translating from the given region (in screen
+ * coordinates) to the backing pixmap.
+ */
+#ifdef COMPOSITE
+ pix_xoff = -pPixmap->screen_x + pPixmap->drawable.x;
+ pix_yoff = -pPixmap->screen_y + pPixmap->drawable.y;
+#else
+ pix_xoff = 0;
+ pix_yoff = 0;
+#endif
+
dxo = dstRegion->extents.x1;
dyo = dstRegion->extents.y1;
@@ -380,8 +392,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
(vert_data_count - 1));
/* bottom right */
- OUT_RING_F(box_x2);
- OUT_RING_F(box_y2);
+ OUT_RING_F(box_x2 + pix_xoff);
+ OUT_RING_F(box_y2 + pix_yoff);
if (!planar) {
OUT_RING_F((box_x2 - dxo) * src_scale_x);
OUT_RING_F((box_y2 - dyo) * src_scale_y);
@@ -393,8 +405,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
}
/* bottom left */
- OUT_RING_F(box_x1);
- OUT_RING_F(box_y2);
+ OUT_RING_F(box_x1 + pix_xoff);
+ OUT_RING_F(box_y2 + pix_yoff);
if (!planar) {
OUT_RING_F((box_x1 - dxo) * src_scale_x);
OUT_RING_F((box_y2 - dyo) * src_scale_y);
@@ -406,8 +418,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
}
/* top left */
- OUT_RING_F(box_x1);
- OUT_RING_F(box_y1);
+ OUT_RING_F(box_x1 + pix_xoff);
+ OUT_RING_F(box_y1 + pix_yoff);
if (!planar) {
OUT_RING_F((box_x1 - dxo) * src_scale_x);
OUT_RING_F((box_y1 - dyo) * src_scale_y);
diff --git a/src/i965_video.c b/src/i965_video.c
index af22cb24..0d1bec69 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -149,11 +149,11 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
- DrawablePtr pDraw)
+ PixmapPtr pPixmap)
{
I830Ptr pI830 = I830PTR(pScrn);
BoxPtr pbox;
- int nbox, dxo, dyo;
+ int nbox, dxo, dyo, pix_xoff, pix_yoff;
int urb_vs_start, urb_vs_size;
int urb_gs_start, urb_gs_size;
int urb_clip_start, urb_clip_size;
@@ -381,12 +381,13 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
dest_surf_state->ss0.mipmap_layout_mode = 0;
dest_surf_state->ss0.render_cache_read_mode = 0;
- dest_surf_state->ss1.base_addr = pI830->FrontBuffer.Start;
+ dest_surf_state->ss1.base_addr = (long)pPixmap->devPrivate.ptr -
+ (long)pI830->FbBase;
dest_surf_state->ss2.height = pScrn->virtualY - 1;
dest_surf_state->ss2.width = pScrn->virtualX - 1;
dest_surf_state->ss2.mip_count = 0;
dest_surf_state->ss2.render_target_rotation = 0;
- dest_surf_state->ss3.pitch = (pI830->displayWidth * pI830->cpp) - 1;
+ dest_surf_state->ss3.pitch = pPixmap->devKind - 1;
/* Set up the source surface state buffer */
memset(src_surf_state, 0, sizeof(*src_surf_state));
@@ -656,6 +657,17 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
ADVANCE_LP_RING();
}
+ /* Set up the offset for translating from the given region (in screen
+ * coordinates) to the backing pixmap.
+ */
+#ifdef COMPOSITE
+ pix_xoff = -pPixmap->screen_x + pPixmap->drawable.x;
+ pix_yoff = -pPixmap->screen_y + pPixmap->drawable.y;
+#else
+ pix_xoff = 0;
+ pix_yoff = 0;
+#endif
+
dxo = dstRegion->extents.x1;
dyo = dstRegion->extents.y1;
@@ -685,18 +697,18 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
i = 0;
vb[i++] = (box_x2 - dxo) * src_scale_x;
vb[i++] = (box_y2 - dyo) * src_scale_y;
- vb[i++] = (float) box_x2;
- vb[i++] = (float) box_y2;
+ vb[i++] = (float) box_x2 + pix_xoff;
+ vb[i++] = (float) box_y2 + pix_yoff;
vb[i++] = (box_x1 - dxo) * src_scale_x;
vb[i++] = (box_y2 - dyo) * src_scale_y;
- vb[i++] = (float) box_x1;
- vb[i++] = (float) box_y2;
+ vb[i++] = (float) box_x1 + pix_xoff;
+ vb[i++] = (float) box_y2 + pix_yoff;
vb[i++] = (box_x1 - dxo) * src_scale_x;
vb[i++] = (box_y1 - dyo) * src_scale_y;
- vb[i++] = (float) box_x1;
- vb[i++] = (float) box_y1;
+ vb[i++] = (float) box_x1 + pix_xoff;
+ vb[i++] = (float) box_y1 + pix_yoff;
#if 0
ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",