[Xorg-driver-geode] [PATCH 1/5] Correctly calculate the rendering region with the mask picture
Mart Raudsepp
leio at gentoo.org
Sun Jul 4 22:13:42 PDT 2010
Hello,
So some reviewing on the first patch:
On Fri, 2010-07-02 at 15:59 +0800, Huang, FrankR wrote:
> From: Frank Huang <frankr.huang at amd.com>
>
> *Add a maskflag variable to record if the type is COMP_TYPE_MASK
> *Add the calculation of the rendering region if there is a mask
> picture
>
> Signed-off-by: Frank Huang <frankr.huang at amd.com>
> ---
> src/lx_exa.c | 41 +++++++++++++++++++++++++++++++++--------
> 1 files changed, 33 insertions(+), 8 deletions(-)
>
> diff --git a/src/lx_exa.c b/src/lx_exa.c
> index 14980ae..e0def8f 100644
> --- a/src/lx_exa.c
> +++ b/src/lx_exa.c
> @@ -949,6 +949,8 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
>
> unsigned int dstOffset, srcOffset = 0;
>
> + int maskflag = 0;
> +
Why do we need a temporary variable for this?
Looks like just checking below (inside the while loop) for
if (exaScratch.type == COMP_TYPE_MASK)
should suffice. Just like is done before entering the loop.
I understand this remained from a now deleted code, so this patch
shouldn't add this unnecessary variable I think.
Of course if this is removed, the commit message line of "Add a
maskflag variable to record if the type is COMP_TYPE_MASK" is redundant
as well.
Also I think the other part would sound better in the log as something
like this:
If the operation is with a shifted position mask, then adjust the
operation region based on the operations mask width and height
parameters (instead of clipping based on source width/height).
> xPointFixed srcPoint;
>
> int opX = dstX;
> @@ -1009,13 +1011,28 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
> srcPoint.y = F(0);
> }
>
> + /* Get the source point offset position */
> +
> srcOffset = GetSrcOffset(I(srcPoint.x), I(srcPoint.y));
>
> - if (exaScratch.srcWidth < opWidth)
> - opWidth = exaScratch.srcWidth;
> + /* When mask exists, exaScratch.srcWidth and exaScratch.srcHeight are
> + * the source width and source height; Otherwise, they are mask width
> + * and mask height */
Isn't that the other way around? When mask exists, exaScratch.srcWidth
and exaScratch.srcHeight are the mask width and mask height?
Furthermore, I propose that in a later commit we rename these confusing
srcWidth and srcHeight members to something less confusing, that doesn't
make one believe they are always source width/height, but dependent on
the mask existing or not.
> + /* exaScratch.repeat is the source repeat attribute */
> + /* If type is COMP_TYPE_MASK, maskX and maskY are not zero, we should
> + * minus them to do the opeartion in the correct region */
s/minus/subtract/g
s/opeartion/operation/g
Though still a bit confusing wording to me
> - if (exaScratch.srcHeight < opHeight)
> - opHeight = exaScratch.srcHeight;
> + if (exaScratch.type == COMP_TYPE_MASK) {
> + if ((exaScratch.srcWidth - maskX) < opWidth)
> + opWidth = exaScratch.srcWidth - maskX;
> + if ((exaScratch.srcHeight - maskY) < opHeight)
> + opHeight = exaScratch.srcHeight - maskY;
exaScratch.srcWidth and exaScratch.srcHeight are unsigned integers,
whereas maskX and maskY are signed integers.
So if maskX is a bigger number, GCC will be doing unsigned integer math
as the left operand (exaScratch.srcWidth) is unsigned, so if srcWidth is
10 and maskX is 80, it will compare ((unsigned int)10 - (int)80 < 40)
which will be converted by GCC to
((unsigned int)10 - (unsigned int)80 < 40), resulting in:
(4294967226 < 40)
Of course if it did integer math instead, it would end up with opWidth
as a negative number instead, and that would get passed to Cimarron
functions, which take unsigned integers, so the compiler would convert
it to unsigned, resulting in a huge width value being used.
So maybe this logic can be restructured to not issue warnings from a
more verbose compiler:
warning: comparison between signed and unsigned integer expressions
Do you know what should happen if the mask region is completely (or
partially) out of opWidth/opHeight area?
I'm a bit hesitant in us adding this new mishandled case in the code
with this patch. Maybe I'll be happy if a FIXME comment is added, or if
lx_check_composite immediately fallbacks to software if maskX > opWidth
or maskY > opHeight
> + } else {
> + if (exaScratch.srcWidth < opWidth)
> + opWidth = exaScratch.srcWidth;
> + if (exaScratch.srcHeight < opHeight)
> + opHeight = exaScratch.srcHeight;
> + }
>
> while (1) {
>
> @@ -1027,6 +1044,7 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
> int direction =
> (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1;
>
> + maskflag = 1;
> if (direction == 1) {
> dstOffset =
> GetPixmapOffset(exaScratch.srcPixmap, opX, opY);
> @@ -1067,10 +1085,17 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
> break;
> }
>
> - opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ?
> - exaScratch.srcWidth : (dstX + width) - opX;
> - opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ?
> - exaScratch.srcHeight : (dstY + height) - opY;
> + if (maskflag == 1) {
> + opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - maskX)
> + ? (exaScratch.srcWidth - maskX) : (dstX + width) - opX;
> + opHeight = ((dstY + height) - opY) > (exaScratch.srcHeight - maskY)
> + ? (exaScratch.srcHeight - maskY) : (dstY + height) - opY;
> + } else {
> + opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ?
> + exaScratch.srcWidth : (dstX + width) - opX;
> + opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ?
> + exaScratch.srcHeight : (dstY + height) - opY;
> + }
> }
> }
Regards,
Mart Raudsepp
More information about the Xorg-driver-geode
mailing list