*/
typedef FASTCALL uint32_t (*fetchFromRegionProc)(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc32 fetch, pixman_box32_t *box);
+/*
+ * There are two properties we can make use of when fetching pixels
+ *
+ * (a) Is the source clip just the image itself?
+ *
+ * (b) Do we know the coordinates of the pixel to fetch are
+ * within the image boundaries;
+ *
+ * Source clips are almost never used, so the important case to optimize
+ * for is when src_clip is false. Since inside_bounds is statically known,
+ * the last part of the if statement will normally be optimized away.
+ */
static inline uint32_t
-fbFetchFromNoRegion(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc32 fetch, pixman_box32_t *box)
+do_fetch (bits_image_t *pict, int x, int y, fetchPixelProc32 fetch,
+ pixman_bool_t src_clip,
+ pixman_bool_t inside_bounds)
{
- return fetch (pict, x, y);
-}
-
-static uint32_t
-fbFetchFromNRectangles(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc32 fetch, pixman_box32_t *box)
-{
- pixman_box32_t box2;
- if (pixman_region32_contains_point (pict->common.src_clip, x, y, &box2))
- return fbFetchFromNoRegion(pict, x, y, buffer, fetch, box);
+ if (src_clip)
+ {
+ if (pixman_region32_contains_point (pict->common.src_clip, x, y,NULL))
+ return fetch (pict, x, y);
+ else
+ return 0;
+ }
+ else if (inside_bounds)
+ {
+ return fetch (pict, x, y);
+ }
else
- return 0;
-}
-
-static uint32_t
-fbFetchFromOneRectangle(bits_image_t *pict, int x, int y, uint32_t *buffer, fetchPixelProc32 fetch, pixman_box32_t *box)
-{
- pixman_box32_t box2 = *box;
- return ((x < box2.x1) | (x >= box2.x2) | (y < box2.y1) | (y >= box2.y2)) ?
- 0 : fbFetchFromNoRegion(pict, x, y, buffer, fetch, box);
+ {
+ if (x >= 0 && x < pict->width && y >= 0 && y < pict->height)
+ return fetch (pict, x, y);
+ else
+ return 0;
+ }
}
/*
static void
fbFetchTransformed_Nearest_Normal(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t* box = NULL;
fetchPixelProc32 fetch;
- fetchFromRegionProc fetchFromRegion;
+ pixman_bool_t src_clip;
int x, y, i;
/* initialize the two function pointers */
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- if(pixman_region32_n_rects (pict->common.src_clip) == 1)
- fetchFromRegion = fbFetchFromNoRegion;
- else
- fetchFromRegion = fbFetchFromNRectangles;
+ src_clip = pict->common.src_clip != &(pict->common.full_region);
for ( i = 0; i < width; ++i)
{
y = MOD(v.vector[1]>>16, pict->height);
x = MOD(v.vector[0]>>16, pict->width);
}
- *(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box);
+
+ *(buffer + i) = do_fetch (pict, x, y, fetch, src_clip, TRUE);
}
}
static void
fbFetchTransformed_Nearest_Pad(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t *box = NULL;
- fetchPixelProc32 fetch;
- fetchFromRegionProc fetchFromRegion;
+ pixman_bool_t src_clip;
+ fetchPixelProc32 fetch;
int x, y, i;
/* initialize the two function pointers */
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- if(pixman_region32_n_rects (pict->common.src_clip) == 1)
- fetchFromRegion = fbFetchFromNoRegion;
- else
- fetchFromRegion = fbFetchFromNRectangles;
+ src_clip = pict->common.src_clip != &(pict->common.full_region);
for (i = 0; i < width; ++i)
{
x = CLIP(v.vector[0]>>16, 0, pict->width-1);
}
- *(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box);
+ *(buffer + i) = do_fetch (pict, x, y, fetch, src_clip, TRUE);
}
}
static void
fbFetchTransformed_Nearest_General(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t *box = NULL;
fetchPixelProc32 fetch;
- fetchFromRegionProc fetchFromRegion;
+ pixman_bool_t src_clip;
int x, y, i;
- /* initialize the two function pointers */
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- if(pixman_region32_n_rects (pict->common.src_clip) == 1)
- {
- box = &(pict->common.src_clip->extents);
- fetchFromRegion = fbFetchFromOneRectangle;
- }
- else
- {
- fetchFromRegion = fbFetchFromNRectangles;
- }
+ src_clip = pict->common.src_clip != &(pict->common.full_region);
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
y = v.vector[1]>>16;
x = v.vector[0]>>16;
}
- *(buffer + i) = fetchFromRegion(pict, x, y, buffer, fetch, box);
+
+ *(buffer + i) = do_fetch (pict, x, y, fetch, src_clip, FALSE);
}
}
v.vector[0] += unit.vector[0];
static void
fbFetchTransformed_Bilinear_Normal(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t *box = NULL;
+ pixman_bool_t src_clip;
fetchPixelProc32 fetch;
- fetchFromRegionProc fetchFromRegion;
int i;
- /* initialize the two function pointers */
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- if(pixman_region32_n_rects (pict->common.src_clip) == 1)
- fetchFromRegion = fbFetchFromNoRegion;
- else
- fetchFromRegion = fbFetchFromNRectangles;
+ src_clip = pict->common.src_clip != &(pict->common.full_region);
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
y1 = MOD (y1, pict->height);
y2 = MOD (y2, pict->height);
- tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box);
- tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box);
- bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box);
- br = fetchFromRegion(pict, x2, y2, buffer, fetch, box);
+ tl = do_fetch (pict, x1, y1, fetch, src_clip, TRUE);
+ tr = do_fetch (pict, x2, y1, fetch, src_clip, TRUE);
+ bl = do_fetch (pict, x1, y2, fetch, src_clip, TRUE);
+ br = do_fetch (pict, x2, y2, fetch, src_clip, TRUE);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
static void
fbFetchTransformed_Bilinear_Pad(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t *box = NULL;
+ pixman_bool_t src_clip;
fetchPixelProc32 fetch;
- fetchFromRegionProc fetchFromRegion;
int i;
/* initialize the two function pointers */
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- if(pixman_region32_n_rects (pict->common.src_clip) == 1)
- fetchFromRegion = fbFetchFromNoRegion;
- else
- fetchFromRegion = fbFetchFromNRectangles;
+ src_clip = pict->common.src_clip != &(pict->common.full_region);
for (i = 0; i < width; ++i) {
if (!mask || mask[i] & maskBits)
y1 = CLIP (y1, 0, pict->height-1);
y2 = CLIP (y2, 0, pict->height-1);
- tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box);
- tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box);
- bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box);
- br = fetchFromRegion(pict, x2, y2, buffer, fetch, box);
+ tl = do_fetch(pict, x1, y1, fetch, src_clip, TRUE);
+ tr = do_fetch(pict, x2, y1, fetch, src_clip, TRUE);
+ bl = do_fetch(pict, x1, y2, fetch, src_clip, TRUE);
+ br = do_fetch(pict, x2, y2, fetch, src_clip, TRUE);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
static void
fbFetchTransformed_Bilinear_General(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t *box = NULL;
+ pixman_bool_t src_clip;
fetchPixelProc32 fetch;
- fetchFromRegionProc fetchFromRegion;
int i;
/* initialize the two function pointers */
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- if(pixman_region32_n_rects (pict->common.src_clip) == 1)
- {
- box = &(pict->common.src_clip->extents);
- fetchFromRegion = fbFetchFromOneRectangle;
- }
- else
- {
- fetchFromRegion = fbFetchFromNRectangles;
- }
+ src_clip = pict->common.src_clip != &(pict->common.full_region);
for (i = 0; i < width; ++i)
{
idistx = 256 - distx;
idisty = 256 - disty;
- tl = fetchFromRegion(pict, x1, y1, buffer, fetch, box);
- tr = fetchFromRegion(pict, x2, y1, buffer, fetch, box);
- bl = fetchFromRegion(pict, x1, y2, buffer, fetch, box);
- br = fetchFromRegion(pict, x2, y2, buffer, fetch, box);
+ tl = do_fetch(pict, x1, y1, fetch, src_clip, FALSE);
+ tr = do_fetch(pict, x2, y1, fetch, src_clip, FALSE);
+ bl = do_fetch(pict, x1, y2, fetch, src_clip, FALSE);
+ br = do_fetch(pict, x2, y2, fetch, src_clip, FALSE);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
static void
fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
{
- pixman_box32_t dummy;
fetchPixelProc32 fetch;
int i;
default:
tx = x;
}
- if (pixman_region32_contains_point (pict->common.src_clip, tx, ty, &dummy)) {
+ if (pixman_region32_contains_point (pict->common.src_clip, tx, ty, NULL)) {
uint32_t c = fetch(pict, tx, ty);
srtot += Red(c) * *p;