summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorSoren Sandmann Pedersen <ssp@dhcp83-218.boston.redhat.com>2007-04-19 18:19:34 -0400
committerSoren Sandmann Pedersen <ssp@dhcp83-218.boston.redhat.com>2007-04-19 18:19:34 -0400
commit0a9239ec258828ec1da6c208634a55fc4053d7da (patch)
tree94cbfdc17c409f9c1cb609edb7eb5cd0974ee954 /render
parentd0e55774e0da641ba85c5173f27f68de27372747 (diff)
Merge David Reveman's gradient optimization patch from pixman
Diffstat (limited to 'render')
-rw-r--r--render/picture.c106
-rw-r--r--render/picturestr.h26
2 files changed, 57 insertions, 75 deletions
diff --git a/render/picture.c b/render/picture.c
index c30649c6b..3f64182f3 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -890,54 +890,22 @@ static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
return x;
}
-static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+CARD32
+PictureGradientColor (PictGradientStopPtr stop1,
+ PictGradientStopPtr stop2,
+ CARD32 x)
{
- int begin_pos, end_pos;
- xFixed incr, dpos;
- int pos, current_stop;
- PictGradientStopPtr stops = pGradient->linear.stops;
- int nstops = pGradient->linear.nstops;
-
- /* The position where the gradient begins and ends */
- begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
- end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
-
- pos = 0; /* The position in the color table. */
-
- /* Up to first point */
- while (pos <= begin_pos) {
- pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
- ++pos;
- }
-
- incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
- dpos = incr * pos; /* The position in terms of 0-1. */
-
- current_stop = 0; /* We always interpolate between current and current + 1. */
-
- /* Gradient area */
- while (pos < end_pos) {
- unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
- unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+ CARD32 current_color, next_color;
+ int dist, idist;
- int dist = (int)(256*(dpos - stops[current_stop].x)
- / (stops[current_stop+1].x - stops[current_stop].x));
- int idist = 256 - dist;
+ current_color = xRenderColorToCard32 (stop1->color);
+ next_color = xRenderColorToCard32 (stop2->color);
- pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
-
- ++pos;
- dpos += incr;
-
- if (dpos > stops[current_stop + 1].x)
- ++current_stop;
- }
+ dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
+ idist = 256 - dist;
- /* After last point */
- while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
- pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
- ++pos;
- }
+ return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
+ next_color, dist));
}
static void initGradient(SourcePictPtr pGradient, int stopCount,
@@ -953,26 +921,30 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
dpos = -1;
for (i = 0; i < stopCount; ++i) {
- if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ if (stopPoints[i] < dpos || stopPoints[i] > (1<<16)) {
*error = BadValue;
return;
}
dpos = stopPoints[i];
}
- pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
- if (!pGradient->linear.stops) {
+ pGradient->gradient.stops = xalloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->gradient.stops) {
*error = BadAlloc;
return;
}
- pGradient->linear.nstops = stopCount;
+ pGradient->gradient.nstops = stopCount;
for (i = 0; i < stopCount; ++i) {
- pGradient->linear.stops[i].x = stopPoints[i];
- pGradient->linear.stops[i].color = stopColors[i];
+ pGradient->gradient.stops[i].x = stopPoints[i];
+ pGradient->gradient.stops[i].color = stopColors[i];
}
- initGradientColorTable(pGradient, error);
+
+ pGradient->gradient.class = SourcePictClassUnknown;
+ pGradient->gradient.stopRange = 0xffff;
+ pGradient->gradient.colorTable = NULL;
+ pGradient->gradient.colorTableSize = 0;
}
static PicturePtr createSourcePicture(void)
@@ -980,9 +952,9 @@ static PicturePtr createSourcePicture(void)
PicturePtr pPicture;
pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
pPicture->pDrawable = 0;
- pPicture->format = PICT_a8r8g8b8;
pPicture->pFormat = 0;
pPicture->pNext = 0;
+ pPicture->format = PICT_a8r8g8b8;
pPicture->devPrivates = 0;
SetPictureToDefaults(pPicture);
@@ -1027,10 +999,6 @@ CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
*error = BadAlloc;
return 0;
}
- if (p1->x == p2->x && p1->y == p2->y) {
- *error = BadValue;
- return 0;
- }
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
@@ -1072,14 +1040,6 @@ CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer
*error = BadAlloc;
return 0;
}
- {
- double dx = (double)(inner->x - outer->x);
- double dy = (double)(inner->y - outer->y);
- if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
- *error = BadValue;
- return 0;
- }
- }
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
@@ -1627,13 +1587,17 @@ FreePicture (pointer value,
{
if (pPicture->transform)
xfree (pPicture->transform);
- if (!pPicture->pDrawable) {
- if (pPicture->pSourcePict) {
- if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
- xfree(pPicture->pSourcePict->linear.stops);
- xfree(pPicture->pSourcePict);
- }
- } else {
+
+ if (pPicture->pSourcePict)
+ {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ xfree(pPicture->pSourcePict->linear.stops);
+
+ xfree(pPicture->pSourcePict);
+ }
+
+ if (pPicture->pDrawable)
+ {
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
diff --git a/render/picturestr.h b/render/picturestr.h
index f1617f627..3f3c600f8 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -68,8 +68,13 @@ typedef struct _PictTransform {
#define SourcePictTypeRadial 2
#define SourcePictTypeConical 3
+#define SourcePictClassUnknown 0
+#define SourcePictClassHorizontal 1
+#define SourcePictClassVertical 2
+
typedef struct _PictSolidFill {
unsigned int type;
+ unsigned int class;
CARD32 color;
} PictSolidFill, *PictSolidFillPtr;
@@ -80,16 +85,22 @@ typedef struct _PictGradientStop {
typedef struct _PictGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
} PictGradient, *PictGradientPtr;
typedef struct _PictLinearGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
xPointFixed p1;
xPointFixed p2;
} PictLinearGradient, *PictLinearGradientPtr;
@@ -98,7 +109,6 @@ typedef struct _PictRadialGradient {
unsigned int type;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
double fx;
double fy;
double dx;
@@ -110,9 +120,12 @@ typedef struct _PictRadialGradient {
typedef struct _PictConicalGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
xPointFixed center;
xFixed angle;
} PictConicalGradient, *PictConicalGradientPtr;
@@ -624,6 +637,11 @@ Bool
PictureTransformPoint3d (PictTransformPtr transform,
PictVectorPtr vector);
+CARD32
+PictureGradientColor (PictGradientStopPtr stop1,
+ PictGradientStopPtr stop2,
+ CARD32 x);
+
void RenderExtensionInit (void);
Bool