summaryrefslogtreecommitdiff
path: root/src/nouveau_xv.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-04-17 09:30:49 +1000
committerBen Skeggs <bskeggs@redhat.com>2012-04-17 11:28:07 +1000
commitec019b3a50475b7ff1b5e0a5dbe14e5ef677bd9e (patch)
tree69b9d11c5b8c43025b077784f6d4a62626d58c38 /src/nouveau_xv.c
parentfb3a36b1e5af0f81bb266da894d3442eed8e4e55 (diff)
Keep a single buffer for random accel data, rather than 3 different ones
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'src/nouveau_xv.c')
-rw-r--r--src/nouveau_xv.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c
index 9ada296..aea6c39 100644
--- a/src/nouveau_xv.c
+++ b/src/nouveau_xv.c
@@ -2141,7 +2141,6 @@ NVTakedownVideo(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
- nouveau_bo_ref(NULL, &pNv->xv_filtertable_mem);
if (pNv->blitAdaptor)
NVFreePortMemory(pScrn, GET_BLIT_PRIVATE(pNv));
if (pNv->textureAdaptor[0]) {
@@ -2154,3 +2153,45 @@ NVTakedownVideo(ScrnInfoPtr pScrn)
}
}
+/* The filtering function used for video scaling. We use a cubic filter as
+ * defined in "Reconstruction Filters in Computer Graphics" Mitchell &
+ * Netravali in SIGGRAPH '88
+ */
+static float filter_func(float x)
+{
+ const double B=0.75;
+ const double C=(1.0-B)/2.0;
+ double x1=fabs(x);
+ double x2=fabs(x)*x1;
+ double x3=fabs(x)*x2;
+
+ if (fabs(x)<1.0)
+ return ( (12.0-9.0*B-6.0*C)*x3+(-18.0+12.0*B+6.0*C)*x2+(6.0-2.0*B) )/6.0;
+ else
+ return ( (-B-6.0*C)*x3+(6.0*B+30.0*C)*x2+(-12.0*B-48.0*C)*x1+(8.0*B+24.0*C) )/6.0;
+}
+
+static int8_t f32tosb8(float v)
+{
+ return (int8_t)(v*127.0);
+}
+
+void
+NVXVComputeBicubicFilter(struct nouveau_bo *bo, unsigned offset, unsigned size)
+{
+ int8_t *t = (int8_t *)(bo->map + offset);
+ int i;
+
+ for(i = 0; i < size; i++) {
+ float x = (i + 0.5) / size;
+ float w0 = filter_func(x+1.0);
+ float w1 = filter_func(x);
+ float w2 = filter_func(x-1.0);
+ float w3 = filter_func(x-2.0);
+
+ t[4*i+2]=f32tosb8(1.0+x-w1/(w0+w1));
+ t[4*i+1]=f32tosb8(1.0-x+w3/(w2+w3));
+ t[4*i+0]=f32tosb8(w0+w1);
+ t[4*i+3]=f32tosb8(0.0);
+ }
+}