diff options
author | Alexei Shlychkov <x0177296@ti.com> | 2012-09-13 04:24:10 -0700 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 13:00:59 +0200 |
commit | d041ff1f03bf2a876cd93dfd9b9c145675b6b5e0 (patch) | |
tree | 0ca0fd89786e1aad6405482b44a0f01ffc2fbf1e | |
parent | a3f4ba4e4d609eb4a2171da3c4352e43428382ca (diff) | |
download | kernel_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.c | 221 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcbv.c | 9 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcbv.h | 34 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcfill.c | 24 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcfilter.c | 8 | ||||
-rw-r--r-- | drivers/misc/gcx/gcbv/gcparser.c | 185 |
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, |