aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexei Shlychkov <x0177296@ti.com>2012-09-13 04:24:10 -0700
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:00:59 +0200
commitd041ff1f03bf2a876cd93dfd9b9c145675b6b5e0 (patch)
tree0ca0fd89786e1aad6405482b44a0f01ffc2fbf1e
parenta3f4ba4e4d609eb4a2171da3c4352e43428382ca (diff)
downloadkernel_samsung_tuna-d041ff1f03bf2a876cd93dfd9b9c145675b6b5e0.zip
kernel_samsung_tuna-d041ff1f03bf2a876cd93dfd9b9c145675b6b5e0.tar.gz
kernel_samsung_tuna-d041ff1f03bf2a876cd93dfd9b9c145675b6b5e0.tar.bz2
gcx: destination setup enhanced.
Separated common setup shared between all operations from parameters that only apply for bitblt. Scaler will have different setup for those parameters (for ex. rotation). Change-Id: Ib85e288dbc59aa5b86b6dc810d3eb8c78471d91d Signed-off-by: Alexei Shlychkov <x0177296@ti.com>
-rw-r--r--drivers/misc/gcx/gcbv/gcblit.c221
-rw-r--r--drivers/misc/gcx/gcbv/gcbv.c9
-rw-r--r--drivers/misc/gcx/gcbv/gcbv.h34
-rw-r--r--drivers/misc/gcx/gcbv/gcfill.c24
-rw-r--r--drivers/misc/gcx/gcbv/gcfilter.c8
-rw-r--r--drivers/misc/gcx/gcbv/gcparser.c185
6 files changed, 288 insertions, 193 deletions
diff --git a/drivers/misc/gcx/gcbv/gcblit.c b/drivers/misc/gcx/gcbv/gcblit.c
index 030a329..23ae521 100644
--- a/drivers/misc/gcx/gcbv/gcblit.c
+++ b/drivers/misc/gcx/gcbv/gcblit.c
@@ -102,8 +102,8 @@ static enum bverror do_blit_end(struct bvbltparams *bvbltparams,
gcmobltconfig->multisource.raw = 0;
gcmobltconfig->multisource.reg.srccount = gcblit->srccount - 1;
- GCDBG(GCZONE_BLIT, "blockenable = %d\n", batch->blockenable);
- if (batch->blockenable) {
+ GCDBG(GCZONE_BLIT, "blockenable = %d\n", gcblit->blockenable);
+ if (gcblit->blockenable) {
gcmobltconfig->multisource.reg.horblock
= GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL16;
gcmobltconfig->multisource.reg.verblock
@@ -181,6 +181,7 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
struct gcmosrc *gcmosrc;
struct gcmoxsrcalpha *gcmoxsrcalpha;
+ struct gcblit *gcblit;
unsigned int index;
struct bvbuffmap *dstmap = NULL;
@@ -188,13 +189,13 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
struct surfaceinfo *dstinfo;
int dstshiftX, dstshiftY;
- int dstalign, dstbyteshift;
+ int dstpixalign, dstbyteshift;
+ int dstoffsetX, dstoffsetY;
int srcshiftX, srcshiftY;
- int srcalign, srcbyteshift;
+ int srcpixalign, srcbyteshift;
int srcleft, srctop;
- struct gcrect dstadjusted;
int srcsurfwidth, srcsurfheight;
unsigned int physwidth, physheight;
int orthogonal;
@@ -205,6 +206,15 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
/* Get a shortcut to the destination surface. */
dstinfo = &batch->dstinfo;
+ /* Parse destination parameters. */
+ bverror = parse_destination(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Setup rotation. */
+ process_dest_rotation(bvbltparams, batch);
+
+
/***********************************************************************
* Determine source surface alignment offset.
*/
@@ -213,46 +223,34 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
* to each other. */
orthogonal = (srcinfo->angle % 2) != (dstinfo->angle % 2);
- /* Compute adjusted destination rectangle. */
- dstadjusted.left = batch->dstclipped.left + batch->dstoffsetX;
- dstadjusted.top = batch->dstclipped.top + batch->dstoffsetY;
- dstadjusted.right = batch->dstclipped.right + batch->dstoffsetX;
- dstadjusted.bottom = batch->dstclipped.bottom + batch->dstoffsetY;
-
/* Compute clipped source origin. */
srcleft = srcinfo->rect.left + batch->clipdelta.left;
srctop = srcinfo->rect.top + batch->clipdelta.top;
- GCDBG(GCZONE_SURF, "adjusted dstrect = (%d,%d)-(%d,%d), %dx%d\n",
- dstadjusted.left, dstadjusted.top,
- dstadjusted.right, dstadjusted.bottom,
- dstadjusted.right - dstadjusted.left,
- dstadjusted.bottom - dstadjusted.top);
-
/* Compute the source surface shift. */
switch (srcinfo->angle) {
case ROT_ANGLE_0:
- srcshiftX = srcleft - dstadjusted.left;
- srcshiftY = srctop - dstadjusted.top;
+ srcshiftX = srcleft - batch->dstadjusted.left;
+ srcshiftY = srctop - batch->dstadjusted.top;
break;
case ROT_ANGLE_90:
- srcshiftX = srctop - dstadjusted.top;
+ srcshiftX = srctop - batch->dstadjusted.top;
srcshiftY = (srcinfo->geom->width - srcleft)
- - (batch->dstwidth - dstadjusted.left);
+ - (batch->dstwidth - batch->dstadjusted.left);
break;
case ROT_ANGLE_180:
srcshiftX = (srcinfo->geom->width - srcleft)
- - (batch->dstwidth - dstadjusted.left);
+ - (batch->dstwidth - batch->dstadjusted.left);
srcshiftY = (srcinfo->geom->height - srctop)
- - (batch->dstheight - dstadjusted.top);
+ - (batch->dstheight - batch->dstadjusted.top);
break;
case ROT_ANGLE_270:
srcshiftX = (srcinfo->geom->height - srctop)
- - (batch->dstheight - dstadjusted.top);
- srcshiftY = srcleft - dstadjusted.left;
+ - (batch->dstheight - batch->dstadjusted.top);
+ srcshiftY = srcleft - batch->dstadjusted.left;
break;
default:
@@ -266,37 +264,38 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
/* Compute the source offset in pixels needed to compensate
* for the surface base address misalignment if any. */
- srcalign = get_pixel_offset(srcinfo, srcbyteshift);
+ srcpixalign = get_pixel_offset(srcinfo, srcbyteshift);
GCDBG(GCZONE_SURF, "source surface %d:\n", srcinfo->index + 1);
GCDBG(GCZONE_SURF, " surface offset (pixels) = %d,%d\n",
srcshiftX, srcshiftY);
GCDBG(GCZONE_SURF, " surface offset (bytes) = 0x%08X\n",
srcbyteshift);
- GCDBG(GCZONE_SURF, " srcalign = %d\n",
- srcalign);
+ GCDBG(GCZONE_SURF, " srcpixalign = %d\n",
+ srcpixalign);
/* Apply the source alignment. */
- srcbyteshift += srcalign * (int) srcinfo->format.bitspp / 8;
- srcshiftX += srcalign;
+ srcbyteshift += srcpixalign * (int) srcinfo->format.bitspp / 8;
+ srcshiftX += srcpixalign;
GCDBG(GCZONE_SURF, " adjusted surface offset (pixels) = %d,%d\n",
srcshiftX, srcshiftY);
GCDBG(GCZONE_SURF, " adjusted surface offset (bytes) = 0x%08X\n",
srcbyteshift);
- /* Determine the destination surface shift. */
+ /* Determine the destination surface shift. Vertical shift only applies
+ * if the destination angle is ahead by 270 degrees. */
dstshiftX = dstinfo->pixalign;
dstshiftY = (((srcinfo->angle + 3) % 4) == dstinfo->angle)
- ? srcalign : 0;
+ ? srcpixalign : 0;
/* Compute the destination surface offset in bytes. */
dstbyteshift = dstshiftY * (int) dstinfo->geom->virtstride
+ dstshiftX * (int) dstinfo->format.bitspp / 8;
/* Compute the destination offset in pixels needed to compensate
- * for the surface base address misalignment if any. */
- dstalign = get_pixel_offset(dstinfo, dstbyteshift);
+ * for the surface base address misalignment if any. */
+ dstpixalign = get_pixel_offset(dstinfo, dstbyteshift);
GCDBG(GCZONE_SURF, "destination surface:\n");
GCDBG(GCZONE_SURF, " surface offset (pixels) = %d,%d\n",
@@ -304,21 +303,21 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
GCDBG(GCZONE_SURF, " surface offset (bytes) = 0x%08X\n",
dstbyteshift);
GCDBG(GCZONE_SURF, " realignment = %d\n",
- dstalign);
+ dstpixalign);
if ((srcinfo->format.format == GCREG_DE_FORMAT_NV12) ||
- (dstalign != 0) ||
- ((srcalign != 0) && (srcinfo->angle == dstinfo->angle))) {
+ (dstpixalign != 0) ||
+ ((srcpixalign != 0) && (srcinfo->angle == dstinfo->angle))) {
/* Compute the source offset in pixels needed to compensate
* for the surface base address misalignment if any. */
- srcalign = get_pixel_offset(srcinfo, 0);
+ srcpixalign = get_pixel_offset(srcinfo, 0);
/* Compute the surface offsets in bytes. */
- srcbyteshift = srcalign * (int) srcinfo->format.bitspp / 8;
+ srcbyteshift = srcpixalign * (int) srcinfo->format.bitspp / 8;
GCDBG(GCZONE_SURF, "recomputed for single-source setup:\n");
- GCDBG(GCZONE_SURF, " srcalign = %d\n",
- srcalign);
+ GCDBG(GCZONE_SURF, " srcpixalign = %d\n",
+ srcpixalign);
GCDBG(GCZONE_SURF, " srcsurf offset (bytes) = 0x%08X\n",
srcbyteshift);
GCDBG(GCZONE_SURF, " dstsurf offset (bytes) = 0x%08X\n",
@@ -327,31 +326,31 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
switch (srcinfo->angle) {
case ROT_ANGLE_0:
/* Adjust left coordinate. */
- srcleft -= srcalign;
+ srcleft -= srcpixalign;
/* Determine source size. */
- srcsurfwidth = srcinfo->geom->width - srcalign;
+ srcsurfwidth = srcinfo->geom->width - srcpixalign;
srcsurfheight = srcinfo->geom->height;
break;
case ROT_ANGLE_90:
/* Adjust top coordinate. */
- srctop -= srcalign;
+ srctop -= srcpixalign;
/* Determine source size. */
- srcsurfwidth = srcinfo->geom->height - srcalign;
+ srcsurfwidth = srcinfo->geom->height - srcpixalign;
srcsurfheight = srcinfo->geom->width;
break;
case ROT_ANGLE_180:
/* Determine source size. */
- srcsurfwidth = srcinfo->geom->width - srcalign;
+ srcsurfwidth = srcinfo->geom->width - srcpixalign;
srcsurfheight = srcinfo->geom->height;
break;
case ROT_ANGLE_270:
/* Determine source size. */
- srcsurfwidth = srcinfo->geom->height - srcalign;
+ srcsurfwidth = srcinfo->geom->height - srcpixalign;
srcsurfheight = srcinfo->geom->width;
break;
@@ -365,6 +364,10 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
GCDBG(GCZONE_SURF, "source physical size = %dx%d\n",
srcsurfwidth, srcsurfheight);
+ /* No adjustment necessary for single-source. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
/* Set the physical destination size. */
physwidth = dstinfo->physwidth;
physheight = dstinfo->physheight;
@@ -382,55 +385,73 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
/* Adjust the destination to match the source geometry. */
switch (srcinfo->angle) {
case ROT_ANGLE_0:
- dstadjusted.left -= srcalign;
- dstadjusted.right -= srcalign;
+ /* Adjust the destination horizontally. */
+ dstoffsetX = srcpixalign;
+ dstoffsetY = 0;
/* Apply the source alignment. */
if ((dstinfo->angle == ROT_ANGLE_0) ||
(dstinfo->angle == ROT_ANGLE_180)) {
- physwidth = dstinfo->physwidth - srcalign;
+ physwidth = dstinfo->physwidth
+ - srcpixalign;
physheight = dstinfo->physheight;
} else {
- physwidth = dstinfo->physwidth;
- physheight = dstinfo->physheight - srcalign;
+ physwidth = dstinfo->physwidth;
+ physheight = dstinfo->physheight
+ - srcpixalign;
}
break;
case ROT_ANGLE_90:
- dstadjusted.top -= srcalign;
- dstadjusted.bottom -= srcalign;
+ /* Adjust the destination vertically. */
+ dstoffsetX = 0;
+ dstoffsetY = srcpixalign;
/* Apply the source alignment. */
if ((dstinfo->angle == ROT_ANGLE_0) ||
(dstinfo->angle == ROT_ANGLE_180)) {
- physwidth = dstinfo->physwidth;
- physheight = dstinfo->physheight - srcalign;
+ physwidth = dstinfo->physwidth;
+ physheight = dstinfo->physheight
+ - srcpixalign;
} else {
- physwidth = dstinfo->physwidth - srcalign;
+ physwidth = dstinfo->physwidth
+ - srcpixalign;
physheight = dstinfo->physheight;
}
break;
case ROT_ANGLE_180:
+ /* No adjustment necessary. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
/* Apply the source alignment. */
if ((dstinfo->angle == ROT_ANGLE_0) ||
(dstinfo->angle == ROT_ANGLE_180)) {
- physwidth = dstinfo->physwidth - srcalign;
+ physwidth = dstinfo->physwidth
+ - srcpixalign;
physheight = dstinfo->physheight;
} else {
- physwidth = dstinfo->physwidth;
- physheight = dstinfo->physheight - srcalign;
+ physwidth = dstinfo->physwidth;
+ physheight = dstinfo->physheight
+ - srcpixalign;
}
break;
case ROT_ANGLE_270:
+ /* No adjustment necessary. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
/* Apply the source alignment. */
if ((dstinfo->angle == ROT_ANGLE_0) ||
(dstinfo->angle == ROT_ANGLE_180)) {
- physwidth = dstinfo->physwidth;
- physheight = dstinfo->physheight - srcalign;
+ physwidth = dstinfo->physwidth;
+ physheight = dstinfo->physheight
+ - srcpixalign;
} else {
- physwidth = dstinfo->physwidth - srcalign;
+ physwidth = dstinfo->physwidth
+ - srcpixalign;
physheight = dstinfo->physheight;
}
break;
@@ -438,6 +459,8 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
default:
physwidth = 0;
physheight = 0;
+ dstoffsetX = 0;
+ dstoffsetY = 0;
}
/* Source geometry is now the same as the destination. */
@@ -454,16 +477,22 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
GCDBG(GCZONE_SURF, "multi-source enabled.\n");
}
- /* Verify if the destination has been modified. */
+ /* Misaligned source may cause the destination parameters
+ * to change, verify whether this has happened. */
if ((batch->dstbyteshift != dstbyteshift) ||
- (batch->physwidth != physwidth) ||
- (batch->physheight != physheight)) {
+ (batch->dstphyswidth != physwidth) ||
+ (batch->dstphysheight != physheight) ||
+ (batch->dstoffsetX != dstoffsetX) ||
+ (batch->dstoffsetY != dstoffsetY)) {
/* Set new values. */
batch->dstbyteshift = dstbyteshift;
- batch->physwidth = physwidth;
- batch->physheight = physheight;
+ batch->dstphyswidth = physwidth;
+ batch->dstphysheight = physheight;
+ batch->dstoffsetX = dstoffsetX;
+ batch->dstoffsetY = dstoffsetY;
- /* Mark as modified. */
+ /* Now we need to end the current batch and program
+ * the hardware with the new destination. */
batch->batchflags |= BVBATCH_DST;
}
@@ -480,33 +509,39 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
if (bverror != BVERR_NONE)
goto exit;
- /* Initialize the new batch. */
+ /* Blit batch. */
batch->batchend = do_blit_end;
- batch->blockenable = 0;
- batch->op.blit.srccount = 0;
- batch->op.blit.multisrc = multisrc;
- batch->op.blit.rop = srcinfo->rop;
- }
- /* Set destination coordinates. */
- batch->op.blit.dstrect = dstadjusted;
-
- /* Map the destination. */
- bverror = do_map(dstinfo->buf.desc, batch, &dstmap);
- if (bverror != BVERR_NONE) {
- bvbltparams->errdesc = gccontext->bverrorstr;
- goto exit;
- }
+ /* Initialize the new batch. */
+ gcblit = &batch->op.blit;
+ gcblit->blockenable = 0;
+ gcblit->srccount = 0;
+ gcblit->multisrc = multisrc;
+ gcblit->rop = srcinfo->rop;
+
+ /* Set the destination coordinates. */
+ gcblit->dstrect.left = batch->dstadjusted.left - dstoffsetX;
+ gcblit->dstrect.top = batch->dstadjusted.top - dstoffsetY;
+ gcblit->dstrect.right = batch->dstadjusted.right - dstoffsetX;
+ gcblit->dstrect.bottom = batch->dstadjusted.bottom - dstoffsetY;
+
+ /* Map the destination. */
+ bverror = do_map(dstinfo->buf.desc, batch, &dstmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
- /* Set the new destination. */
- bverror = set_dst(bvbltparams, batch, dstmap);
- if (bverror != BVERR_NONE)
- goto exit;
+ /* Set the new destination. */
+ bverror = set_dst(bvbltparams, batch, dstmap);
+ if (bverror != BVERR_NONE)
+ goto exit;
- /* Reset the modified flag. */
- batch->batchflags &= ~(BVBATCH_DST |
- BVBATCH_CLIPRECT |
- BVBATCH_DESTRECT);
+ /* Reset the modified flag. */
+ batch->batchflags &= ~(BVBATCH_DST |
+ BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT);
+ }
/* Map the source. */
bverror = do_map(srcinfo->buf.desc, batch, &srcmap);
@@ -521,7 +556,7 @@ enum bverror do_blit(struct bvbltparams *bvbltparams,
/* We need to walk in blocks if the source and the destination
* surfaces are orthogonal to each other. */
- batch->blockenable = orthogonal;
+ batch->op.blit.blockenable |= orthogonal;
/* Allocate command buffer. */
bverror = claim_buffer(bvbltparams, batch,
diff --git a/drivers/misc/gcx/gcbv/gcbv.c b/drivers/misc/gcx/gcbv/gcbv.c
index a91cbab..9872881 100644
--- a/drivers/misc/gcx/gcbv/gcbv.c
+++ b/drivers/misc/gcx/gcbv/gcbv.c
@@ -523,10 +523,10 @@ enum bverror set_dst(struct bvbltparams *bvbltparams,
/* Set surface width and height. */
gcmodst->rotation.raw = 0;
- gcmodst->rotation.reg.surf_width = batch->physwidth;
+ gcmodst->rotation.reg.surf_width = batch->dstphyswidth;
gcmodst->rotationheight_ldst = gcmodst_rotationheight_ldst;
gcmodst->rotationheight.raw = 0;
- gcmodst->rotationheight.reg.height = batch->physheight;
+ gcmodst->rotationheight.reg.height = batch->dstphysheight;
/* Disable hardware clipping. */
gcmodst->clip_ldst = gcmodst_clip_ldst;
@@ -1109,11 +1109,6 @@ enum bverror bv_blt(struct bvbltparams *bvbltparams)
goto exit;
}
- /* Parse destination parameters. */
- bverror = parse_destination(bvbltparams, gcbatch);
- if (bverror != BVERR_NONE)
- goto exit;
-
/* Reset the number of sources. */
srccount = 0;
diff --git a/drivers/misc/gcx/gcbv/gcbv.h b/drivers/misc/gcx/gcbv/gcbv.h
index 48f23d6..486e476 100644
--- a/drivers/misc/gcx/gcbv/gcbv.h
+++ b/drivers/misc/gcx/gcbv/gcbv.h
@@ -385,6 +385,9 @@ struct gcblit {
* setup can be modified to match new destination and source
* geometry. */
struct gcrect dstrect;
+
+ /* Block walker enable. */
+ int blockenable;
};
/* Filter states. */
@@ -418,34 +421,35 @@ struct gcbatch {
/* Destination surface. */
struct surfaceinfo dstinfo;
- /* Clipping deltas; used to correct the source coordinates for
- * single source blits. */
- struct gcrect clipdelta;
-
/* Clipped destination rectangle coordinates. */
struct gcrect dstclipped;
struct gcrect dstclippedaux;
- /* Destination origin offset caused by surface base misalignment. */
- unsigned int dstoffsetX;
- unsigned int dstoffsetY;
+ /* Destination rectangles that were clipped and adjusted for
+ * surface misalignment if any. */
+ struct gcrect dstadjusted;
+ struct gcrect dstadjustedaux;
+
+ /* Clipping deltas; used to correct the source coordinates for
+ * single source blits. */
+ struct gcrect clipdelta;
/* Adjusted geometry size of the destination surface. */
unsigned int dstwidth;
unsigned int dstheight;
- /* Physical size of the matched destination and source surfaces
- * for multi-source setup. */
- unsigned int physwidth;
- unsigned int physheight;
+ /* Physical size of the destination surface. */
+ unsigned int dstphyswidth;
+ unsigned int dstphysheight;
/* Alignment byte offset for the destination surface; in multi-
* source setup can be modified to match new destination and source
* geometry. */
int dstbyteshift;
- /* Block walker enable. */
- int blockenable;
+ /* Destination rectangle adjustment offsets. */
+ int dstoffsetX;
+ int dstoffsetY;
#if GCDEBUG_ENABLE
/* Rectangle validation storage. */
@@ -491,6 +495,10 @@ enum bverror parse_source(struct bvbltparams *bvbltparams,
enum bverror parse_scalemode(struct bvbltparams *bvbltparams,
struct gcbatch *batch);
+/* Setup destination rotation parameters. */
+void process_dest_rotation(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch);
+
/* Return surface alignment offset. */
int get_pixel_offset(struct surfaceinfo *surfaceinfo, int offset);
diff --git a/drivers/misc/gcx/gcbv/gcfill.c b/drivers/misc/gcx/gcbv/gcfill.c
index 252713b..4882b88 100644
--- a/drivers/misc/gcx/gcbv/gcfill.c
+++ b/drivers/misc/gcx/gcbv/gcfill.c
@@ -162,17 +162,25 @@ enum bverror do_fill(struct bvbltparams *bvbltparams,
if (bverror != BVERR_NONE)
goto exit;
+ /* Parse destination parameters. */
+ bverror = parse_destination(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Setup rotation. */
+ process_dest_rotation(bvbltparams, batch);
+
/* Get a shortcut to the destination surface. */
dstinfo = &batch->dstinfo;
/* Verify if the destination parameter have been modified. */
if ((batch->dstbyteshift != dstinfo->bytealign) ||
- (batch->physwidth != dstinfo->physwidth) ||
- (batch->physheight != dstinfo->physheight)) {
+ (batch->dstphyswidth != dstinfo->physwidth) ||
+ (batch->dstphysheight != dstinfo->physheight)) {
/* Set new values. */
batch->dstbyteshift = dstinfo->bytealign;
- batch->physwidth = dstinfo->physwidth;
- batch->physheight = dstinfo->physheight;
+ batch->dstphyswidth = dstinfo->physwidth;
+ batch->dstphysheight = dstinfo->physheight;
/* Mark as modified. */
batch->batchflags |= BVBATCH_DST;
@@ -260,10 +268,10 @@ enum bverror do_fill(struct bvbltparams *bvbltparams,
gcmofill->startde.cmd.fld = gcfldstartde;
/* Set destination rectangle. */
- gcmofill->rect.left = batch->dstclipped.left + batch->dstoffsetX;
- gcmofill->rect.top = batch->dstclipped.top + batch->dstoffsetY;
- gcmofill->rect.right = batch->dstclipped.right + batch->dstoffsetX;
- gcmofill->rect.bottom = batch->dstclipped.bottom + batch->dstoffsetY;
+ gcmofill->rect.left = batch->dstadjusted.left;
+ gcmofill->rect.top = batch->dstadjusted.top;
+ gcmofill->rect.right = batch->dstadjusted.right;
+ gcmofill->rect.bottom = batch->dstadjusted.bottom;
exit:
GCEXITARG(GCZONE_FILL, "bv%s = %d\n",
diff --git a/drivers/misc/gcx/gcbv/gcfilter.c b/drivers/misc/gcx/gcbv/gcfilter.c
index 99d9f9a..aa7d489 100644
--- a/drivers/misc/gcx/gcbv/gcfilter.c
+++ b/drivers/misc/gcx/gcbv/gcfilter.c
@@ -991,6 +991,14 @@ enum bverror do_filter(struct bvbltparams *bvbltparams,
if (bverror != BVERR_NONE)
goto exit;
+ /* Parse destination parameters. */
+ bverror = parse_destination(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Setup rotation. */
+ process_dest_rotation(bvbltparams, batch);
+
/* Additional stride requirements. */
if (srcinfo->format.format == GCREG_DE_FORMAT_NV12) {
/* Nv12 may be shifted up to 32 bytes for alignment.
diff --git a/drivers/misc/gcx/gcbv/gcparser.c b/drivers/misc/gcx/gcbv/gcparser.c
index b0a64c3..4b47eb8 100644
--- a/drivers/misc/gcx/gcbv/gcparser.c
+++ b/drivers/misc/gcx/gcbv/gcparser.c
@@ -1410,72 +1410,6 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
dstinfo->bytealign = (dstinfo->pixalign
* (int) dstinfo->format.bitspp) / 8;
- switch (dstinfo->angle) {
- case ROT_ANGLE_0:
- /* Determine the physical size. */
- dstinfo->physwidth = dstinfo->geom->width
- - dstinfo->pixalign;
- dstinfo->physheight = dstinfo->geom->height;
-
- /* Determine geometry size. */
- batch->dstwidth = dstinfo->geom->width
- - dstinfo->pixalign;
- batch->dstheight = dstinfo->geom->height;
-
- /* Determine the origin offset. */
- batch->dstoffsetX = -dstinfo->pixalign;
- batch->dstoffsetY = 0;
- break;
-
- case ROT_ANGLE_90:
- /* Determine the physical size. */
- dstinfo->physwidth = dstinfo->geom->height
- - dstinfo->pixalign;
- dstinfo->physheight = dstinfo->geom->width;
-
- /* Determine geometry size. */
- batch->dstwidth = dstinfo->geom->width;
- batch->dstheight = dstinfo->geom->height
- - dstinfo->pixalign;
-
- /* Determine the origin offset. */
- batch->dstoffsetX = 0;
- batch->dstoffsetY = -dstinfo->pixalign;
- break;
-
- case ROT_ANGLE_180:
- /* Determine the physical size. */
- dstinfo->physwidth = dstinfo->geom->width
- - dstinfo->pixalign;
- dstinfo->physheight = dstinfo->geom->height;
-
- /* Determine geometry size. */
- batch->dstwidth = dstinfo->geom->width
- - dstinfo->pixalign;
- batch->dstheight = dstinfo->geom->height;
-
- /* Determine the origin offset. */
- batch->dstoffsetX = 0;
- batch->dstoffsetY = 0;
- break;
-
- case ROT_ANGLE_270:
- /* Determine the physical size. */
- dstinfo->physwidth = dstinfo->geom->height
- - dstinfo->pixalign;
- dstinfo->physheight = dstinfo->geom->width;
-
- /* Determine geometry size. */
- batch->dstwidth = dstinfo->geom->width;
- batch->dstheight = dstinfo->geom->height
- - dstinfo->pixalign;
-
- /* Determine the origin offset. */
- batch->dstoffsetX = 0;
- batch->dstoffsetY = 0;
- break;
- }
-
GCDBG(GCZONE_DEST, "destination surface:\n");
GCDBG(GCZONE_DEST, " rotation %d degrees.\n",
dstinfo->angle * 90);
@@ -1495,14 +1429,10 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
dstinfo->geom->virtstride);
GCDBG(GCZONE_DEST, " geometry size = %dx%d\n",
dstinfo->geom->width, dstinfo->geom->height);
- GCDBG(GCZONE_DEST, " aligned geometry size = %dx%d\n",
- batch->dstwidth, batch->dstheight);
- GCDBG(GCZONE_DEST, " aligned physical size = %dx%d\n",
- dstinfo->physwidth, dstinfo->physheight);
- GCDBG(GCZONE_DEST, " origin offset (pixels) = %d,%d\n",
- batch->dstoffsetX, batch->dstoffsetY);
GCDBG(GCZONE_DEST, " surface offset (pixels) = %d,0\n",
dstinfo->pixalign);
+ GCDBG(GCZONE_DEST, " surface offset (bytes) = %d\n",
+ dstinfo->bytealign);
}
/* Did clipping/destination rects change? */
@@ -1674,6 +1604,117 @@ exit:
return bverror;
}
+void process_dest_rotation(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ GCENTER(GCZONE_DEST);
+
+ /* Did clipping/destination rects change? */
+ if ((batch->batchflags & (BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT |
+ BVBATCH_DST)) != 0) {
+ struct surfaceinfo *dstinfo;
+ int dstoffsetX, dstoffsetY;
+
+ /* Initialize the destination descriptor. */
+ dstinfo = &batch->dstinfo;
+
+ switch (dstinfo->angle) {
+ case ROT_ANGLE_0:
+ /* Determine the origin offset. */
+ dstoffsetX = dstinfo->pixalign;
+ dstoffsetY = 0;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->pixalign;
+ batch->dstheight = dstinfo->geom->height;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = batch->dstwidth;
+ dstinfo->physheight = batch->dstheight;
+ break;
+
+ case ROT_ANGLE_90:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = dstinfo->pixalign;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->pixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->height
+ - dstinfo->pixalign;
+ dstinfo->physheight = dstinfo->geom->width;
+ break;
+
+ case ROT_ANGLE_180:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->pixalign;
+ batch->dstheight = dstinfo->geom->height;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = batch->dstwidth;
+ dstinfo->physheight = batch->dstheight;
+ break;
+
+ case ROT_ANGLE_270:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->pixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->height
+ - dstinfo->pixalign;
+ dstinfo->physheight = dstinfo->geom->width;
+ break;
+
+ default:
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+ }
+
+ /* Compute adjusted destination rectangles. */
+ batch->dstadjusted.left
+ = batch->dstclipped.left
+ - dstoffsetX;
+ batch->dstadjusted.top
+ = batch->dstclipped.top
+ - dstoffsetY;
+ batch->dstadjusted.right
+ = batch->dstclipped.right
+ - dstoffsetX;
+ batch->dstadjusted.bottom
+ = batch->dstclipped.bottom
+ - dstoffsetY;
+
+ GCPRINT_RECT(GCZONE_DEST, "adjusted dest",
+ &batch->dstadjusted);
+
+ GCDBG(GCZONE_DEST, "aligned geometry size = %dx%d\n",
+ batch->dstwidth, batch->dstheight);
+ GCDBG(GCZONE_DEST, "aligned physical size = %dx%d\n",
+ dstinfo->physwidth, dstinfo->physheight);
+ GCDBG(GCZONE_DEST, "origin offset (pixels) = %d,%d\n",
+ dstoffsetX, dstoffsetY);
+ }
+
+ GCEXIT(GCZONE_DEST);
+}
+
enum bverror parse_source(struct bvbltparams *bvbltparams,
struct gcbatch *batch,
struct bvrect *srcrect,