Fixes in intersection + checks

Fix a bug in the extents of an intersection.
Add some checks and assert that helps when using the remoteFx encoder.
A speedup for intersection when bands are above the target rect.
This commit is contained in:
Hardening 2014-02-07 16:43:48 +01:00
parent 0915060f40
commit 115a1e863d
3 changed files with 65 additions and 7 deletions

View File

@ -667,7 +667,7 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) {
endPtr = rect + nbRects;
for (endPtr = rect + nbRects; rect < endPtr; rect++)
for (endPtr = rect + nbRects; (rect < endPtr) && (arg2->bottom > rect->top); rect++)
{
if (rectangles_intersects(rect, arg2))
return TRUE;
@ -715,7 +715,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE
/* accumulate intersecting rectangles, the final region16_simplify_bands() will
* do all the bad job to recreate correct rectangles
*/
for(endPtr = srcPtr + nbRects; srcPtr < endPtr; srcPtr++)
for(endPtr = srcPtr + nbRects; (srcPtr < endPtr) && (rect->bottom > srcPtr->top); srcPtr++)
{
if (rectangles_intersection(srcPtr, rect, &common))
{
@ -726,7 +726,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE
newExtents.top = MIN(common.top, newExtents.top);
newExtents.left = MIN(common.left, newExtents.left);
newExtents.bottom = MAX(common.bottom, newExtents.bottom);
newExtents.right = MIN(common.right, newExtents.right);
newExtents.right = MAX(common.right, newExtents.right);
}
}

View File

@ -1144,10 +1144,11 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta
}
static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region)
static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region, int width, int height)
{
int i;
const RFX_RECT *rect = rects;
const RECTANGLE_16 mainRect = { 0, 0, width, height };
for(i = 0; i < numRects; i++, rect++) {
RECTANGLE_16 rect16;
@ -1160,7 +1161,8 @@ static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region)
if (!region16_union_rect(region, region, &rect16))
return FALSE;
}
return TRUE;
return region16_intersect_rect(region, region, &mainRect);
}
#define TILE_NO(v) ((v) / 64)
@ -1202,6 +1204,13 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int
const RECTANGLE_16 *regionRect;
const RECTANGLE_16 *extents;
assert(data);
assert(rects);
assert(numRects > 0);
assert(width > 0);
assert(height > 0);
assert(scanline > 0);
message = (RFX_MESSAGE *)calloc(1, sizeof(RFX_MESSAGE));
if (!message)
return NULL;
@ -1222,13 +1231,15 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int
message->numQuant = context->numQuant;
message->quantVals = context->quants;
rfxRect = (RFX_RECT *)&rects[0];
bytesPerPixel = (context->bits_per_pixel / 8);
region16_init(&rectsRegion);
if (!computeRegion(rects, numRects, &rectsRegion))
if (!computeRegion(rects, numRects, &rectsRegion, width, height))
goto out_free_message;
extents = region16_extents(&rectsRegion);
assert(extents->right - extents->left > 0);
assert(extents->bottom - extents->top > 0);
maxTilesX = 1 + TILE_NO(extents->right - 1) - TILE_NO(extents->left);
maxTilesY = 1 + TILE_NO(extents->bottom - 1) - TILE_NO(extents->top);

View File

@ -618,6 +618,52 @@ out:
return retCode;
}
static int test_norbert_case() {
REGION16 region, intersection;
int retCode = -1;
const RECTANGLE_16 *rects;
int nbRects, i;
RECTANGLE_16 inRectangles[5] = {
{1680, 0, 1920, 242},
{ 294, 242, 971, 776},
{1680, 242, 1920, 776},
{1680, 776, 1920, 1036},
{ 2, 1040, 53, 1078}
};
RECTANGLE_16 screenRect = {
0, 0, 1920, 1080
};
RECTANGLE_16 expected_inter_extents = {
0, 0, 1920, 1078
};
region16_init(&region);
region16_init(&intersection);
for (i = 0; i < 5; i++)
{
if (!region16_union_rect(&region, &region, &inRectangles[i]))
goto out;
}
if (!region16_intersect_rect(&intersection, &region, &screenRect))
goto out;
rects = region16_rects(&intersection, &nbRects);
if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects))
goto out;
if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1) )
goto out;
retCode = 0;
out:
region16_uninit(&intersection);
region16_uninit(&region);
return retCode;
}
typedef int (*TestFunction)();
struct UnitaryTest {
@ -637,6 +683,7 @@ struct UnitaryTest tests[] = {
{"data from weston", test_from_weston},
{"R1 & R3", test_r1_inter_r3},
{"(R1+R3)&R11 (band merge)",test_r1_r3_inter_r11},
{"norbert case", test_norbert_case},
{NULL, NULL}
};