summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2009-11-29 14:43:11 -0800
committerAaron Plattner <aplattner@nvidia.com>2009-11-29 14:43:11 -0800
commit22eaa2e3cdb42fdb8dc391e786ae272212b90f20 (patch)
tree52b0dc1b3435313b961ca283954fea7ca5869212
parent2d33078e72a251cc9fa99f71220342fc436932d3 (diff)
Add a convolution test
-rw-r--r--main.c4
-rw-r--r--surface.c79
-rw-r--r--testscenarios.c13
-rw-r--r--testscenarios.h1
4 files changed, 95 insertions, 2 deletions
diff --git a/main.c b/main.c
index e1cb8a9..d20aad0 100644
--- a/main.c
+++ b/main.c
@@ -158,7 +158,7 @@ display_help()
printf("\t -argb\t\tuses a 32-bit ARGB window\n");
printf("\t -ops ops\tconfigures which ops to test\n");
printf("\t -tests type\truns only specified tests\n");
- printf("\t\ttype can be: plain, alpha, mask, transformation and filter\n");
+ printf("\t\ttype can be: plain, alpha, mask, transformation, filter, and convolution\n");
printf("\t \n");
}
@@ -218,6 +218,8 @@ process_args(int argc, char **argv)
test_type = TransformationTest;
} else if (!strcmp("filter", arg)) {
test_type = FilterTest;
+ } else if (!strcmp("convolution", arg)) {
+ test_type = ConvolutionTest;
} else {
fprintf(stderr, "Unrecognized test type: '%s'\n", arg);
}
diff --git a/surface.c b/surface.c
index 022a935..ad60e32 100644
--- a/surface.c
+++ b/surface.c
@@ -1,5 +1,7 @@
#include "surface.h"
+#include <assert.h>
+#include <math.h>
#include <stdlib.h>
#include <stdio.h>
@@ -78,6 +80,80 @@ xrender_surf_populate(Display *disp, XRenderSurf *rs, int w, int h,
XFreeGC(disp, gc);
}
+/* this is similar to create_gaussian_kernel_1d() except for the fact that I use
+** a naive (or let's call it: brute-force) 2d implementation of a gaussian-blur
+** to be able to compare the performance... and the performance non-surprisingly
+** sucks... 2 pass 1d gauss. blur is faster than 1 pass 2d gauss. blur */
+static XFixed*
+create_gaussian_kernel_2d (int iRadius,
+ int* piSize)
+{
+ double fSigma = (double) iRadius / 2.0f;
+ double fScale1;
+ double fScale2;
+ double* pTmpKernel = NULL;
+ XFixed* pKernel = NULL;
+ double fU;
+ double fV;
+ int iX;
+ int iY;
+ double fSum = 0.0f;
+
+ assert (piSize != NULL);
+
+ fScale2 = 2.0f * fSigma * fSigma;
+ fScale1 = 1.0f / (M_PI * fScale2);
+
+ *piSize = (2 * iRadius+1) * (2 * iRadius+1);
+ pTmpKernel = (double*) calloc (*piSize, sizeof (double));
+ if (!pTmpKernel)
+ return NULL;
+
+ for (iX = 0; iX < 2 * iRadius+1; iX++)
+ {
+ for (iY = 0; iY < 2 * iRadius+1; iY++)
+ {
+ fU = (double) iX;
+ fV = (double) iY;
+ pTmpKernel[iX+iY*(2*iRadius+1)] = fScale1 * exp (-(fU*fU+fV*fV) / fScale2);
+ }
+ }
+
+ for (iX = 0; iX < *piSize; iX++)
+ fSum += pTmpKernel[iX];
+
+ for (iX = 0; iX < *piSize; iX++)
+ pTmpKernel[iX] /= fSum;
+
+ pKernel = (XFixed*) calloc (*piSize + 2, sizeof (XFixed));
+ if (!pKernel)
+ {
+ free (pTmpKernel);
+ return NULL;
+ }
+
+ for (iX = 0; iX < *piSize; iX++)
+ pKernel[iX + 2] = XDoubleToFixed (pTmpKernel[iX]);
+
+ free (pTmpKernel);
+
+ *piSize += 2;
+ pKernel[0] = (2 * iRadius + 1) <<16;
+ pKernel[1] = (2 * iRadius + 1) << 16;
+
+ return pKernel;
+}
+
+static void
+set_convolution(Display *disp, XRenderSurf *rs)
+{
+ int kernel_size;
+ XFixed *blur_kernel = create_gaussian_kernel_2d(20, &kernel_size);
+
+ XRenderSetPictureFilter(disp, rs->pic, FilterConvolution, blur_kernel,
+ kernel_size);
+}
+
void
xrender_surf_prepare(Display *disp, XRenderSurf *src, int w, int h,
int transformations, SurfaceFilter filter)
@@ -98,6 +174,9 @@ xrender_surf_prepare(Display *disp, XRenderSurf *src, int w, int h,
case SurfaceNearest:
XRenderSetPictureFilter(disp, src->pic, "nearest", NULL, 0);
break;
+ case SurfaceConvolution:
+ set_convolution(disp, src);
+ break;
default:
break;
}
diff --git a/testscenarios.c b/testscenarios.c
index 9f51586..88677fc 100644
--- a/testscenarios.c
+++ b/testscenarios.c
@@ -12,7 +12,7 @@ TestScenario * create_test_scenarios(Display *disp, Window win, int w, int h, in
{
TestScenario *scenarios;
- *number = 6;
+ *number = 7;
scenarios = (TestScenario*)malloc(sizeof(TestScenario) * (*number));
int currentNumber = 0;
@@ -79,6 +79,17 @@ TestScenario * create_test_scenarios(Display *disp, Window win, int w, int h, in
xrender_surf_prepare(disp, current->src, current->src->w, current->src->h, 1,
SurfaceBilinear);
+ current = &scenarios[currentNumber++];
+ /*********************************/
+ current->types = ConvolutionTest;
+ current->name = strdup("Convolution");
+ current->dst = xrender_surf_adopt(disp, win, w, h);
+ current->mask = 0;
+ current->src = xrender_surf_new(disp, win, PictStandardARGB32, 128, 128, False);
+ populate_from_file(disp, current->src, "images/xorg-small.png");
+ xrender_surf_prepare(disp, current->src, current->src->w, current->src->h, 0,
+ SurfaceConvolution);
+
assert(*number == currentNumber);
return scenarios;
}
diff --git a/testscenarios.h b/testscenarios.h
index de031bc..98d96c7 100644
--- a/testscenarios.h
+++ b/testscenarios.h
@@ -10,6 +10,7 @@ typedef enum _TestType {
MaskTest = 1 << 2,
TransformationTest = 1 << 3,
FilterTest = 1 << 4,
+ ConvolutionTest = 1 << 5,
AllTests
} TestType;