mtwebmapper: Added fast path for rendering RGBA sub base level tiles. Up to 5-10x faster.

This commit is contained in:
Sascha L. Teichmann 2014-09-20 23:53:09 +02:00
parent 8c29975d27
commit 2709761255

View File

@ -7,7 +7,6 @@ package main
import ( import (
"fmt" "fmt"
"image" "image"
"image/color"
"image/png" "image/png"
"log" "log"
"net/http" "net/http"
@ -105,7 +104,56 @@ func (sb *subBaseLine) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
func blowUp(src image.Image) *image.RGBA { func blowUp(src image.Image) *image.RGBA {
// TODO: Fast path for image.RGBA // Fast path for RGBA -> RGBA
if rgba, ok := src.(*image.RGBA); ok {
return blowUpRGBA(rgba)
}
// Fallback
dst := image.NewRGBA(image.Rect(0, 0, 256, 256))
// fix point numbers x:8
dx, dy := src.Bounds().Dx(), src.Bounds().Dy()
bx, by := src.Bounds().Min.X<<8, src.Bounds().Min.Y<<8
//start := time.Now()
pix := dst.Pix
lineOfs := dst.PixOffset(0, 0) // Should be 0.
py := by
var r, g, b, a uint8
for y := 0; y < 256; y++ {
sy := (py >> 8) & 0xff
ox := -1
px := bx
ofs := lineOfs // Should not really b needed
lineOfs += dst.Stride
for x := 0; x < 256; x++ {
sx := (px >> 8) & 0xff
if sx != ox { // Minimize interface indirection access.
ox = sx
xr, xg, xb, xa := src.At(sx, sy).RGBA()
r, g, b, a = uint8(xr), uint8(xg), uint8(xb), uint8(xa)
}
pix[ofs] = r
pix[ofs+1] = g
pix[ofs+2] = b
pix[ofs+3] = a
ofs += 4
px += dx
}
py += dy
}
//log.Printf("Rendering took: %s", time.Since(start))
return dst
}
func blowUpRGBA(src *image.RGBA) *image.RGBA {
dst := image.NewRGBA(image.Rect(0, 0, 256, 256)) dst := image.NewRGBA(image.Rect(0, 0, 256, 256))
@ -114,24 +162,31 @@ func blowUp(src image.Image) *image.RGBA {
bx, by := src.Bounds().Min.X<<8, src.Bounds().Min.Y<<8 bx, by := src.Bounds().Min.X<<8, src.Bounds().Min.Y<<8
//start := time.Now()
sPix := src.Pix
dPix := dst.Pix
py := by py := by
for y := 0; y < 256; y++ { // Assuming memory layout is packed 256*256*4 with stride of 4*256.
// for dLineOfs, dEnd := dst.PixOffset(0, 0), dst.PixOffset(0, 256); dLineOfs < dEnd; dLineOfs += dst.Stride {
for ofs := 0; ofs < 256*256*4; {
sy := (py >> 8) & 0xff sy := (py >> 8) & 0xff
ox := -1 sLineOfs := src.PixOffset(0, sy)
px := bx px := bx
var col color.Color // ofs := dLineOfs
for x := 0; x < 256; x++ { for end := ofs + 4*256; ofs < end; ofs += 4 {
sx := (px >> 8) & 0xff sOfs := sLineOfs + ((px >> 6) & 0x3fc)
if sx != ox { // Minimize interface indirection access.
ox = sx
col = src.At(sx, sy)
}
dst.Set(x, y, col)
px += dx px += dx
dPix[ofs] = sPix[sOfs]
dPix[ofs+1] = sPix[sOfs+1]
dPix[ofs+2] = sPix[sOfs+2]
dPix[ofs+3] = sPix[sOfs+3]
} }
py += dy py += dy
} }
//log.Printf("Rendering took: %s", time.Since(start))
return dst return dst
} }