From e8e4d6afeb1efb4679c8dcac00fe573d62bf85c5 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Wed, 22 Jul 2015 01:11:14 +0200 Subject: [PATCH] Cache empty tiles to speed up seeding. Enforce Go 1.4 for the ability to compress better. --- README.md | 4 ++-- common/basetilecreator.go | 36 +++++++++++++++++++++++++++--------- common/image.go | 10 ++++++++++ common/renderer.go | 11 +++++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 872c419..be590a5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ on YouTube. A live map of an online world can be viewed [here](http://maps.mt.sha-bang.de/). See [COMPILE](https://bitbucket.org/s_l_teichmann/mtsatellite/src/default/COMPILE.md) how to compile -MTSatellite. Essentially you need Go 1.3 (or higher) and a GNU/Linux system. +MTSatellite. Essentially you need Go 1.4 (or higher) and a GNU/Linux system. See [SETUP](https://bitbucket.org/s_l_teichmann/mtsatellite/src/default/SETUP.md) how to bring MTSatellite to life. @@ -39,4 +39,4 @@ the map has to be pre-rendered with **mtseeder**. This is Free Software under the terms of the MIT license. See [LICENSE](LICENSE) file for details. -(c) 2014 by Sascha L. Teichmann \ No newline at end of file +(c) 2014 by Sascha L. Teichmann diff --git a/common/basetilecreator.go b/common/basetilecreator.go index 83fb8a2..84e2003 100644 --- a/common/basetilecreator.go +++ b/common/basetilecreator.go @@ -6,6 +6,7 @@ package common import ( "image/color" + "io/ioutil" "log" "path/filepath" "strconv" @@ -41,13 +42,16 @@ var tileDepths = [...][2]int16{ {-1024, -257}, {-1934, -1025}} +var BackgroundColor = color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + type BaseTileCreator struct { - client *RedisClient - colors *Colors - renderer *Renderer - yOrder *YOrder - baseDir string - update bool + client *RedisClient + colors *Colors + renderer *Renderer + yOrder *YOrder + baseDir string + update bool + emptyImage []byte } func NewBaseTileCreator( @@ -116,11 +120,25 @@ func (btc *BaseTileCreator) CreateTile(x, z int16, i, j int) error { oareas, nareas = nareas, oareas[0:0] } + path := filepath.Join(btc.baseDir, strconv.Itoa(i), strconv.Itoa(j)+".png") + + // Empty images are likely to be produced during seeding. + if !btc.update && btc.renderer.IsEmpty() { + // To avoid redundant encoding cache the resulting empty image. + if btc.emptyImage == nil { + var err error + m := BackgroundImage((tileWidth-2)*16, (tileHeight-2)*16, BackgroundColor) + if btc.emptyImage, err = EncodeToMem(m); err != nil { + return err + } + } + log.Printf("Writing empty (%d, %d) to file %s\n", x, z, path) + return ioutil.WriteFile(path, btc.emptyImage, 0666) + } + image := btc.renderer.CreateShadedImage( 16, 16, (tileWidth-2)*16, (tileHeight-2)*16, - btc.colors, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}) - - path := filepath.Join(btc.baseDir, strconv.Itoa(i), strconv.Itoa(j)+".png") + btc.colors, BackgroundColor) log.Printf("Writing (%d, %d) to file %s\n", x, z, path) diff --git a/common/image.go b/common/image.go index 1e2f81f..8ac0d98 100644 --- a/common/image.go +++ b/common/image.go @@ -6,6 +6,7 @@ package common import ( "bufio" + "bytes" "errors" "image" "image/png" @@ -35,6 +36,15 @@ func nextSuffix() string { return strconv.Itoa(int(1e9 + r%1e9))[1:] } +func EncodeToMem(img image.Image) ([]byte, error) { + var buf bytes.Buffer + enc := png.Encoder{png.BestCompression} + if err := enc.Encode(&buf, img); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + func SaveAsPNG(path string, img image.Image) (err error) { var file *os.File if file, err = os.Create(path); err != nil { diff --git a/common/renderer.go b/common/renderer.go index 1af1c8d..778de37 100644 --- a/common/renderer.go +++ b/common/renderer.go @@ -8,6 +8,7 @@ import ( "container/heap" "image" "image/color" + "image/draw" "math" ) @@ -181,6 +182,10 @@ func (r *Renderer) IsFilled() bool { return true } +func (r *Renderer) IsEmpty() bool { + return r.SolidBlocks == 0 && r.TransparentBlocks == 0 +} + func (r *Renderer) RenderBlock(block *Block, colors *Colors) (err error) { bx := block.Coord.X - r.xOfs @@ -392,6 +397,12 @@ func safeColor(x int32) uint8 { } } +func BackgroundImage(width, height int, bg color.RGBA) *image.RGBA { + m := image.NewRGBA(image.Rect(0, 0, width, height)) + draw.Draw(m, m.Bounds(), &image.Uniform{bg}, image.ZP, draw.Src) + return m +} + func (r *Renderer) CreateShadedImage( xOfs, zOfs, width, height int, cols *Colors, background color.RGBA) *image.RGBA {