From 507b1a44bd72830c136e6ecf7c05f9089796d572 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Sun, 6 Nov 2016 13:21:55 +1100 Subject: [PATCH] vector: measure the fixed point rasterizer's accuracy. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When commit 8874bef1 changed ϕ from 10 to 9, this total diff grew from: Total diff = 3051, n = 208, avg = 14.66827 out of 65535, or 0.02238%. to: Total diff = 6412, n = 208, avg = 30.82692 out of 65535, or 0.04704%. Also fix a comment typo. Change-Id: I91cc861a3d3ab282b5431cfb141fb010fd1f8d14 Reviewed-on: https://go-review.googlesource.com/32771 Reviewed-by: David Crawshaw --- vector/acc_test.go | 37 +++++++++++++++++++++++++++++++++++++ vector/raster_fixed.go | 4 ++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/vector/acc_test.go b/vector/acc_test.go index 0e2ae58..d80f765 100644 --- a/vector/acc_test.go +++ b/vector/acc_test.go @@ -612,3 +612,40 @@ var flMask16 = []uint32{ 0x00d4, 0xa6a1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd54d, 0x8399, 0xffff, 0xffff, 0x764b, 0x0000, 0x001b, 0x4ffc, 0xbb4a, 0xe3f5, 0xeee3, 0xbd4c, 0x7e42, 0x0900, 0x1b0c, 0xb6fc, 0xb6fc, 0x7e04, } + +// TestFixedFloatingCloseness compares the closeness of the fixed point and +// floating point rasterizer. +func TestFixedFloatingCloseness(t *testing.T) { + if len(fxMask16) != len(flMask16) { + t.Fatalf("len(fxMask16) != len(flMask16)") + } + + total := uint32(0) + for i := range fxMask16 { + a := fxMask16[i] + b := flMask16[i] + if a > b { + total += a - b + } else { + total += b - a + } + } + n := len(fxMask16) + + // This log message is useful when changing the fixed point rasterizer + // implementation, such as by changing ϕ. Assuming that the floating point + // rasterizer is accurate, the average difference is a measure of how + // inaccurate the (faster) fixed point rasterizer is. + // + // Smaller is better. + percent := float64(total*100) / float64(n*65535) + t.Logf("Comparing closeness of the fixed point and floating point rasterizer.\n"+ + "Specifically, the elements of fxMask16 and flMask16.\n"+ + "Total diff = %d, n = %d, avg = %.5f out of 65535, or %.5f%%.\n", + total, n, float64(total)/float64(n), percent) + + const thresholdPercent = 1.0 + if percent > thresholdPercent { + t.Errorf("average difference: got %.5f%%, want <= %.5f%%", percent, thresholdPercent) + } +} diff --git a/vector/raster_fixed.go b/vector/raster_fixed.go index ccfa342..5b0fe7a 100644 --- a/vector/raster_fixed.go +++ b/vector/raster_fixed.go @@ -127,8 +127,8 @@ func (z *Rasterizer) fixedLineTo(bx, by float32) { if i := clamp(x0i, width); i < uint(len(buf)) { // In ideal math: buf[i] += uint32(d * a0) - D := oneMinusX0fSquared // D ranges up to ±1<<(1*ϕ). - D *= d // D ranges up to ±1<<(2*ϕ). + D := oneMinusX0fSquared // D ranges up to ±1<<(2*ϕ). + D *= d // D ranges up to ±1<<(3*ϕ). D /= twoOverS buf[i] += uint32(D) }