pixman: Branch 'master' - 5 commits
Søren Sandmann Pedersen
sandmann at kemper.freedesktop.org
Thu Oct 20 06:31:06 PDT 2011
Makefile.am | 4
pixman/pixman-gradient-walker.c | 175 +++++++++-------------------------------
pixman/pixman-image.c | 73 ++++++++++++++++
pixman/pixman-private.h | 16 +--
4 files changed, 124 insertions(+), 144 deletions(-)
New commits:
commit 6131707e8fc39187d1d358481f7c57c57cfab206
Merge: 3d4d705... ec7c9c2...
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Thu Oct 20 09:13:12 2011 -0400
Merge branch 'gradients'
commit ec7c9c2b6865b48b8bd14e4509538f8fcbe93463
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Oct 14 09:04:48 2011 -0400
Simplify gradient_walker_reset()
The code that searches for the closest color stop to the given
position is duplicated across the various repeat modes. Replace the
switch with two if/else constructions, and put the search code between
them.
diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
index 3848247..048039e 100644
--- a/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman-gradient-walker.c
@@ -56,57 +56,40 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
int n, count = walker->num_stops;
pixman_gradient_stop_t *stops = walker->stops;
- switch (walker->repeat)
+ if (walker->repeat == PIXMAN_REPEAT_NORMAL)
{
- case PIXMAN_REPEAT_NORMAL:
- x = (int32_t)pos & 0xFFFF;
- for (n = 0; n < count; n++)
- {
- if (x < stops[n].x)
- break;
- }
-
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
-
- right_x = stops[n].x;
- right_c = &stops[n].color;
-
- left_x += (pos - x);
- right_x += (pos - x);
- break;
-
- case PIXMAN_REPEAT_PAD:
- for (n = 0; n < count; n++)
- {
- if (pos < stops[n].x)
- break;
- }
-
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
-
- right_x = stops[n].x;
- right_c = &stops[n].color;
- break;
-
- case PIXMAN_REPEAT_REFLECT:
- x = (int32_t)pos & 0xFFFF;
+ x = (int32_t)pos & 0xffff;
+ }
+ else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
+ {
+ x = (int32_t)pos & 0xffff;
if ((int32_t)pos & 0x10000)
x = 0x10000 - x;
-
- for (n = 0; n < count; n++)
- {
- if (x < stops[n].x)
- break;
- }
-
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
-
- right_x = stops[n].x;
- right_c = &stops[n].color;
-
+ }
+ else
+ {
+ x = pos;
+ }
+
+ for (n = 0; n < count; n++)
+ {
+ if (x < stops[n].x)
+ break;
+ }
+
+ left_x = stops[n - 1].x;
+ left_c = &stops[n - 1].color;
+
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
+
+ if (walker->repeat == PIXMAN_REPEAT_NORMAL)
+ {
+ left_x += (pos - x);
+ right_x += (pos - x);
+ }
+ else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
+ {
if ((int32_t)pos & 0x10000)
{
pixman_color_t *tmp_c;
@@ -124,20 +107,6 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
}
left_x += (pos - x);
right_x += (pos - x);
- break;
-
- default: /* REPEAT_NONE */
- for (n = 0; n < count; n++)
- {
- if (pos < stops[n].x)
- break;
- }
-
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
-
- right_x = stops[n].x;
- right_c = &stops[n].color;
}
walker->left_x = left_x;
commit 2d0da8ab8d8fef60ed1bbb9d6b75f66577c3f85d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Oct 14 09:02:14 2011 -0400
Use sentinels instead of special casing first and last stops
When storing the gradient stops internally, allocate two more stops,
one before the beginning of the stop list and one after the
end. Initialize those stops based on the repeat property of the
gradient.
This allows gradient_walker_reset() to be simplified because it can
now simply pick the two closest stops to the position without special
casing the first and last stops.
diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
index 53d0b30..3848247 100644
--- a/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman-gradient-walker.c
@@ -56,8 +56,6 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
int n, count = walker->num_stops;
pixman_gradient_stop_t *stops = walker->stops;
- static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
-
switch (walker->repeat)
{
case PIXMAN_REPEAT_NORMAL:
@@ -68,27 +66,12 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
break;
}
- if (n == 0)
- {
- left_x = stops[count - 1].x - 0x10000;
- left_c = &stops[count - 1].color;
- }
- else
- {
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
- }
+ left_x = stops[n - 1].x;
+ left_c = &stops[n - 1].color;
+
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
- if (n == count)
- {
- right_x = stops[0].x + 0x10000;
- right_c = &stops[0].color;
- }
- else
- {
- right_x = stops[n].x;
- right_c = &stops[n].color;
- }
left_x += (pos - x);
right_x += (pos - x);
break;
@@ -100,27 +83,11 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
break;
}
- if (n == 0)
- {
- left_x = INT32_MIN;
- left_c = &stops[0].color;
- }
- else
- {
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
- }
+ left_x = stops[n - 1].x;
+ left_c = &stops[n - 1].color;
- if (n == count)
- {
- right_x = INT32_MAX;
- right_c = &stops[n - 1].color;
- }
- else
- {
- right_x = stops[n].x;
- right_c = &stops[n].color;
- }
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
break;
case PIXMAN_REPEAT_REFLECT:
@@ -134,27 +101,11 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
break;
}
- if (n == 0)
- {
- left_x = -stops[0].x;
- left_c = &stops[0].color;
- }
- else
- {
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
- }
+ left_x = stops[n - 1].x;
+ left_c = &stops[n - 1].color;
- if (n == count)
- {
- right_x = 0x20000 - stops[n - 1].x;
- right_c = &stops[n - 1].color;
- }
- else
- {
- right_x = stops[n].x;
- right_c = &stops[n].color;
- }
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
if ((int32_t)pos & 0x10000)
{
@@ -182,25 +133,11 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
break;
}
- if (n == 0)
- {
- left_x = INT32_MIN;
- right_x = stops[0].x;
- left_c = right_c = (pixman_color_t*) &transparent_black;
- }
- else if (n == count)
- {
- left_x = stops[n - 1].x;
- right_x = INT32_MAX;
- left_c = right_c = (pixman_color_t*) &transparent_black;
- }
- else
- {
- left_x = stops[n - 1].x;
- right_x = stops[n].x;
- left_c = &stops[n - 1].color;
- right_c = &stops[n].color;
- }
+ left_x = stops[n - 1].x;
+ left_c = &stops[n - 1].color;
+
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
}
walker->left_x = left_x;
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index afe587f..09d7cbc 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -31,6 +31,50 @@
#include "pixman-private.h"
+static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
+
+static void
+gradient_property_changed (pixman_image_t *image)
+{
+ gradient_t *gradient = &image->gradient;
+ int n = gradient->n_stops;
+ pixman_gradient_stop_t *stops = gradient->stops;
+ pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
+ pixman_gradient_stop_t *end = &(gradient->stops[n]);
+
+ switch (gradient->common.repeat)
+ {
+ default:
+ case PIXMAN_REPEAT_NONE:
+ begin->x = INT32_MIN;
+ begin->color = transparent_black;
+ end->x = INT32_MAX;
+ end->color = transparent_black;
+ break;
+
+ case PIXMAN_REPEAT_NORMAL:
+ begin->x = stops[n - 1].x - pixman_fixed_1;
+ begin->color = stops[n - 1].color;
+ end->x = stops[0].x + pixman_fixed_1;
+ end->color = stops[0].color;
+ break;
+
+ case PIXMAN_REPEAT_REFLECT:
+ begin->x = - stops[0].x;
+ begin->color = stops[0].color;
+ end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
+ end->color = stops[n - 1].color;
+ break;
+
+ case PIXMAN_REPEAT_PAD:
+ begin->x = INT32_MIN;
+ begin->color = stops[0].color;
+ end->x = INT32_MAX;
+ end->color = stops[n - 1].color;
+ break;
+ }
+}
+
pixman_bool_t
_pixman_init_gradient (gradient_t * gradient,
const pixman_gradient_stop_t *stops,
@@ -38,14 +82,27 @@ _pixman_init_gradient (gradient_t * gradient,
{
return_val_if_fail (n_stops > 0, FALSE);
- gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
+ /* We allocate two extra stops, one before the beginning of the stop list,
+ * and one after the end. These stops are initialized to whatever color
+ * would be used for positions outside the range of the stop list.
+ *
+ * This saves a bit of computation in the gradient walker.
+ *
+ * The pointer we store in the gradient_t struct still points to the
+ * first user-supplied struct, so when freeing, we will have to
+ * subtract one.
+ */
+ gradient->stops =
+ pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
if (!gradient->stops)
return FALSE;
+ gradient->stops += 1;
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
-
gradient->n_stops = n_stops;
+ gradient->common.property_changed = gradient_property_changed;
+
return TRUE;
}
@@ -102,7 +159,17 @@ _pixman_image_fini (pixman_image_t *image)
image->type == CONICAL)
{
if (image->gradient.stops)
- free (image->gradient.stops);
+ {
+ /* See _pixman_init_gradient() for an explanation of the - 1 */
+ free (image->gradient.stops - 1);
+ }
+
+ /* This will trigger if someone adds a property_changed
+ * method to the linear/radial/conical gradient overwriting
+ * the general one.
+ */
+ assert (
+ image->common.property_changed == gradient_property_changed);
}
if (image->type == BITS && image->bits.free_me)
commit 84d6ca7c891601b019d4862a556ed98b7e6fe525
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Oct 14 07:42:00 2011 -0400
gradient walker: Correct types and fix formatting
The type of pos in gradient_walker_reset() and gradient_walker_pixel()
is pixman_fixed_48_16_t and not pixman_fixed_32_32. The types of the
positions in the walker struct are pixman_fixed_t and not int32_t, and
need_reset is a boolean, not an integer. The spread field should be
called repeat and have the type pixman_repeat_t.
Also fix some formatting issues, make gradient_walker_reset() static,
and delete the pointless PIXMAN_GRADIENT_WALKER_NEED_RESET() macro.
diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
index dd666b4..53d0b30 100644
--- a/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman-gradient-walker.c
@@ -31,7 +31,7 @@
void
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
gradient_t * gradient,
- unsigned int spread)
+ pixman_repeat_t repeat)
{
walker->num_stops = gradient->n_stops;
walker->stops = gradient->stops;
@@ -42,29 +42,32 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
walker->left_rb = 0;
walker->right_ag = 0;
walker->right_rb = 0;
- walker->spread = spread;
+ walker->repeat = repeat;
walker->need_reset = TRUE;
}
-void
-_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t pos)
+static void
+gradient_walker_reset (pixman_gradient_walker_t *walker,
+ pixman_fixed_48_16_t pos)
{
int32_t x, left_x, right_x;
- pixman_color_t *left_c, *right_c;
+ pixman_color_t *left_c, *right_c;
int n, count = walker->num_stops;
- pixman_gradient_stop_t * stops = walker->stops;
+ pixman_gradient_stop_t *stops = walker->stops;
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
- switch (walker->spread)
+ switch (walker->repeat)
{
case PIXMAN_REPEAT_NORMAL:
x = (int32_t)pos & 0xFFFF;
for (n = 0; n < count; n++)
+ {
if (x < stops[n].x)
break;
+ }
+
if (n == 0)
{
left_x = stops[count - 1].x - 0x10000;
@@ -92,8 +95,10 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
case PIXMAN_REPEAT_PAD:
for (n = 0; n < count; n++)
+ {
if (pos < stops[n].x)
break;
+ }
if (n == 0)
{
@@ -122,9 +127,12 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
x = (int32_t)pos & 0xFFFF;
if ((int32_t)pos & 0x10000)
x = 0x10000 - x;
+
for (n = 0; n < count; n++)
+ {
if (x < stops[n].x)
break;
+ }
if (n == 0)
{
@@ -169,8 +177,10 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
default: /* REPEAT_NONE */
for (n = 0; n < count; n++)
+ {
if (pos < stops[n].x)
break;
+ }
if (n == 0)
{
@@ -201,8 +211,8 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
if (walker->left_x == walker->right_x ||
- ( walker->left_ag == walker->right_ag &&
- walker->left_rb == walker->right_rb ) )
+ (walker->left_ag == walker->right_ag &&
+ walker->left_rb == walker->right_rb))
{
walker->stepper = 0;
}
@@ -215,20 +225,15 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
walker->need_reset = FALSE;
}
-#define PIXMAN_GRADIENT_WALKER_NEED_RESET(w, x) \
- ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
-
-
-/* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t x)
+ pixman_fixed_48_16_t x)
{
int dist, idist;
uint32_t t1, t2, a, color;
- if (PIXMAN_GRADIENT_WALKER_NEED_RESET (walker, x))
- _pixman_gradient_walker_reset (walker, x);
+ if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
+ gradient_walker_reset (walker, x);
dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
idist = 256 - dist;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index cbd48f3..1443bfb 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -299,29 +299,29 @@ typedef struct
uint32_t left_rb;
uint32_t right_ag;
uint32_t right_rb;
- int32_t left_x;
- int32_t right_x;
- int32_t stepper;
+ pixman_fixed_t left_x;
+ pixman_fixed_t right_x;
+ pixman_fixed_t stepper;
pixman_gradient_stop_t *stops;
int num_stops;
- unsigned int spread;
+ pixman_repeat_t repeat;
- int need_reset;
+ pixman_bool_t need_reset;
} pixman_gradient_walker_t;
void
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
gradient_t * gradient,
- unsigned int spread);
+ pixman_repeat_t repeat);
void
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t pos);
+ pixman_fixed_48_16_t pos);
uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t x);
+ pixman_fixed_48_16_t x);
/*
* Edges
commit ace225b53dee88d134753ac901f26ba3db6781da
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Tue Oct 11 16:12:24 2011 -0400
Add stable release / development snapshot to draft release notes
This will hopefully serve as a reminder to me that I should put this
information in the release notes.
diff --git a/Makefile.am b/Makefile.am
index ff87e26..df8677a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -87,6 +87,8 @@ release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md
scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)
ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)"
+RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi)
+
release-publish-message: $(HASHFILES) ensure-prev
@echo "Please follow the instructions in RELEASING to push stuff out and"
@echo "send out the announcement mails. Here is the excerpt you need:"
@@ -94,7 +96,7 @@ release-publish-message: $(HASHFILES) ensure-prev
@echo "Lists: $(RELEASE_ANNOUNCE_LIST)"
@echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available"
@echo "============================== CUT HERE =============================="
- @echo "A new $(PACKAGE) release $(VERSION) is now available"
+ @echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)"
@echo ""
@echo "tar.gz:"
@echo " $(RELEASE_CAIRO_URL)/$(tar_gz)"
More information about the xorg-commit
mailing list