summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2010-10-05 13:04:21 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-10-05 13:04:21 -0400
commit67599cc03195212a4241cf510691b4234b00132a (patch)
tree2ea287b664ad48665a3a490fc643f031d453d18e
parent32f2c996980ac547a56e5627e9062c000adf5f05 (diff)
a bunch of stuffcomposite-test-more-ops
-rw-r--r--pixman/pixman-combine.c.template32
-rw-r--r--test/composite.c150
2 files changed, 168 insertions, 14 deletions
diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index 0d3b95d4..8409f113 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -477,13 +477,13 @@ combine_multiply_ca (pixman_implementation_t *imp,
comp4_t d = *(dest + i);
comp4_t r = d;
comp4_t dest_ia = ALPHA_c (~d);
-
- combine_mask_value_ca (&s, &m);
-
+
+ combine_mask_ca (&s, &m);
+
UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (r, ~m, s, dest_ia);
UNcx4_MUL_UNcx4 (d, s);
UNcx4_ADD_UNcx4 (r, d);
-
+
*(dest + i) = r;
}
}
@@ -506,15 +506,17 @@ combine_multiply_ca (pixman_implementation_t *imp,
comp1_t da = ALPHA_c (d); \
comp1_t ida = ~da; \
comp4_t result; \
- \
+ comp4_t tmp; \
+ \
result = d; \
UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
\
- *(dest + i) = result + \
- (DIV_ONE_UNc (sa * da) << A_SHIFT) + \
- (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \
- (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \
+ tmp = (DIV_ONE_UNc (sa * da) << A_SHIFT) | \
+ (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) | \
+ (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) | \
(blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \
+ UNcx4_ADD_UNcx4 (result, tmp); \
+ *(dest + i) = result; \
} \
} \
\
@@ -534,17 +536,19 @@ combine_multiply_ca (pixman_implementation_t *imp,
comp1_t da = ALPHA_c (d); \
comp1_t ida = ~da; \
comp4_t result; \
+ comp4_t tmp; \
\
- combine_mask_value_ca (&s, &m); \
+ combine_mask_ca (&s, &m); \
\
result = d; \
UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \
\
- result += \
- (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) + \
- (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \
- (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \
+ tmp = \
+ (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) | \
+ (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) | \
+ (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) | \
(blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \
+ UNcx4_ADD_UNcx4 (result, tmp); \
\
*(dest + i) = result; \
} \
diff --git a/test/composite.c b/test/composite.c
index de195339..b2e1c113 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -53,7 +53,9 @@ struct format_t
static const color_t colors[] =
{
{ 1.0, 1.0, 1.0, 1.0 },
+#if 0
{ 1.0, 1.0, 1.0, 0.0 },
+#endif
{ 0.0, 0.0, 0.0, 1.0 },
{ 0.0, 0.0, 0.0, 0.0 },
{ 1.0, 0.0, 0.0, 1.0 },
@@ -204,6 +206,19 @@ static const operator_t operators[] =
P(CONJOINT_ATOP),
P(CONJOINT_ATOP_REVERSE),
P(CONJOINT_XOR),
+
+ P(MULTIPLY),
+ P(SCREEN),
+ P(OVERLAY),
+ P(DARKEN),
+ P(LIGHTEN),
+ P(COLOR_DODGE),
+ P(COLOR_BURN),
+ P(HARD_LIGHT),
+ P(SOFT_LIGHT),
+ P(DIFFERENCE),
+ P(EXCLUSION),
+
#undef P
};
@@ -433,6 +448,124 @@ calc_op_porter_duff (pixman_op_t op, double src, double dst, double srca, double
#undef mult_chan
}
+static double
+calc_op_separable_pdf (pixman_op_t op, double src, double dst, double srca, double dsta)
+{
+ double result = (1 - srca) * dst + (1 - dsta) * src;
+ double dsa, sda;
+
+ switch (op)
+ {
+ case PIXMAN_OP_MULTIPLY:
+ result += src * dst;
+ break;
+
+ case PIXMAN_OP_SCREEN:
+ result += srca * dst + dsta * src - src * dst;
+ break;
+
+ case PIXMAN_OP_OVERLAY:
+ if (2 * dst < dsta)
+ result += 2 * src * dst;
+ else
+ result += srca * dsta - 2 * (dsta - dst) * (srca - src);
+ break;
+
+ case PIXMAN_OP_DARKEN:
+ if (src * dsta > dst * srca)
+ result += dst * srca;
+ else
+ result += src * dsta;
+ break;
+
+ case PIXMAN_OP_LIGHTEN:
+ if (src * dsta > dst * srca)
+ result += src * dsta;
+ else
+ result += dst * srca;
+ break;
+
+ case PIXMAN_OP_COLOR_DODGE:
+ if (src >= srca)
+ {
+ if (dst != 0.0)
+ result += srca * dsta;
+ }
+ else
+ {
+ double r = dst * srca / (srca - src);
+
+ result += srca * min (r, dsta);
+ }
+ break;
+
+ case PIXMAN_OP_COLOR_BURN:
+ if (src == 0.0)
+ {
+ if (dst >= dsta)
+ result += srca * dsta;
+ }
+ else
+ {
+ double r = (dsta - dst) * srca / src;
+
+ result += srca * (max (r, dsta) - r);
+ }
+ break;
+
+ case PIXMAN_OP_HARD_LIGHT:
+ if (2 * src < srca)
+ result += 2 * src * dst;
+ else
+ result += srca * dsta - 2 * (dsta - dst) * (srca - src);
+ break;
+
+ case PIXMAN_OP_SOFT_LIGHT:
+ if (2 * src < srca)
+ {
+ if (dsta == 0.0)
+ result += dst * srca;
+ else
+ result += dst * srca - dst * (dsta - dst) * (srca - 2 * src) / dsta;
+ }
+ else if (dsta == 0.0)
+ {
+ result += 0.0;
+ }
+ else if (4 * dst <= dsta)
+ {
+ result += dst * srca + (2 * src - srca) * dst * ((16 * dst / dsta - 12) * dst / dsta + 3);
+ }
+ else
+ {
+ result += dst * srca + (sqrt (dst * dsta) - dst) * (2 * src - srca);
+ }
+ break;
+
+ case PIXMAN_OP_DIFFERENCE:
+ dsa = dst * srca;
+ sda = src * dsta;
+
+ result += fabs (sda - dsa);
+ break;
+
+ case PIXMAN_OP_EXCLUSION:
+ result += src * dsta + dst * srca - 2 * dst * src;
+ break;
+
+ default:
+ abort();
+ break;
+ }
+
+ if (result > 1)
+ result = 1;
+ if (result < 0)
+ result = 0;
+
+ return result;
+}
+
static void
calc_op (pixman_op_t op, color_t *result,
const color_t *src,
@@ -486,6 +619,23 @@ calc_op (pixman_op_t op, color_t *result,
result->b = calc_op_porter_duff (op, src->b, dst->b, src_a->b, dst_a);
break;
+ case PIXMAN_OP_MULTIPLY:
+ case PIXMAN_OP_SCREEN:
+ case PIXMAN_OP_OVERLAY:
+ case PIXMAN_OP_DARKEN:
+ case PIXMAN_OP_LIGHTEN:
+ case PIXMAN_OP_COLOR_DODGE:
+ case PIXMAN_OP_COLOR_BURN:
+ case PIXMAN_OP_HARD_LIGHT:
+ case PIXMAN_OP_SOFT_LIGHT:
+ case PIXMAN_OP_DIFFERENCE:
+ case PIXMAN_OP_EXCLUSION:
+ result->a = src->a + dst->a - src->a * dst->a;
+ result->r = calc_op_separable_pdf (op, src->r, dst->r, src_a->r, dst_a);
+ result->g = calc_op_separable_pdf (op, src->g, dst->g, src_a->g, dst_a);
+ result->b = calc_op_separable_pdf (op, src->b, dst->b, src_a->b, dst_a);
+ break;
+
default:
abort();
}