diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2009-11-29 14:43:11 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2009-11-29 14:43:11 -0800 |
commit | 22eaa2e3cdb42fdb8dc391e786ae272212b90f20 (patch) | |
tree | 52b0dc1b3435313b961ca283954fea7ca5869212 | |
parent | 2d33078e72a251cc9fa99f71220342fc436932d3 (diff) |
Add a convolution test
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | surface.c | 79 | ||||
-rw-r--r-- | testscenarios.c | 13 | ||||
-rw-r--r-- | testscenarios.h | 1 |
4 files changed, 95 insertions, 2 deletions
@@ -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); } @@ -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; |