Parallelization genmaps

This commit is contained in:
Tnze
2021-03-13 10:13:50 +08:00
parent 03eada08a2
commit 24c057da26
2 changed files with 82 additions and 39 deletions

View File

@ -12,10 +12,14 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"sync"
"unsafe" "unsafe"
) )
var colors []color.RGBA64 var colors []color.RGBA64
var regionWorkerNum = runtime.NumCPU()
var sectionWorkerNum = 1
var ( var (
regionsFold = flag.String("region", filepath.Join(os.Getenv("AppData"), ".minecraft", "saves", "World", "region"), "region directory path") regionsFold = flag.String("region", filepath.Join(os.Getenv("AppData"), ".minecraft", "saves", "World", "region"), "region directory path")
@ -65,10 +69,36 @@ func main() {
} }
} }
}() }()
// draw columns
for pos, r := range rs { for pos, r := range rs {
var column save.Column
img := image.NewRGBA(image.Rect(0, 0, 32*16, 32*16)) img := image.NewRGBA(image.Rect(0, 0, 32*16, 32*16))
type task struct {
data []byte
pos [2]int
}
c := make(chan task)
var wg sync.WaitGroup
for i := 0; i < regionWorkerNum; i++ {
go func() {
var column save.Column
for task := range c {
if err := column.Load(task.data); err != nil {
log.Printf("Decode column (%d.%d) error: %v", task.pos[0], task.pos[1], err)
}
pos := [2]int{int(column.Level.PosX), int(column.Level.PosZ)}
if pos != task.pos {
fmt.Printf("chunk position not match: want %v, get %v\n", task.pos, pos)
}
draw.Draw(
img, image.Rect(task.pos[0]*16, task.pos[1]*16, task.pos[0]*16+16, task.pos[1]*16+16),
drawColumn(&column), image.Pt(0, 0),
draw.Over,
)
wg.Done()
}
}()
}
for x := 0; x < 32; x++ { for x := 0; x < 32; x++ {
for z := 0; z < 32; z++ { for z := 0; z < 32; z++ {
if !r.ExistSector(x, z) { if !r.ExistSector(x, z) {
@ -78,33 +108,47 @@ func main() {
if err != nil { if err != nil {
log.Printf("Read sector (%d.%d) error: %v", x, z, err) log.Printf("Read sector (%d.%d) error: %v", x, z, err)
} }
if err := column.Load(data); err != nil { wg.Add(1)
log.Printf("Decode column (%d.%d) error: %v", x, z, err) c <- task{data: data, pos: [2]int{x, z}}
}
draw.Draw(
img, image.Rect(x*16, z*16, x*16+16, z*16+16),
drawColumn(&column), image.Pt(0, 0),
draw.Over,
)
} }
} }
close(c)
wg.Wait()
savePng(img, fmt.Sprintf("r.%d.%d.png", pos[0], pos[1])) savePng(img, fmt.Sprintf("r.%d.%d.png", pos[0], pos[1]))
log.Print(pos, r) log.Print("Draw: ", pos)
} }
} }
func drawColumn(column *save.Column) (img *image.RGBA) { func drawColumn(column *save.Column) (img *image.RGBA) {
img = image.NewRGBA(image.Rect(0, 0, 16, 16)) img = image.NewRGBA(image.Rect(0, 0, 16, 16))
s := column.Level.Sections s := column.Level.Sections
c := make(chan *save.Chunk)
var wg sync.WaitGroup
for i := 0; i < sectionWorkerNum; i++ {
go func() {
for s := range c {
drawSection(s, img)
wg.Done()
}
}()
}
defer close(c)
wg.Add(len(s))
for i := range s { for i := range s {
s := s[i] c <- &s[i]
}
wg.Wait()
return
}
func drawSection(s *save.Chunk, img *image.RGBA) {
// calculate bits per block // calculate bits per block
bpb := len(s.BlockStates) * 64 / (16 * 16 * 16) bpb := len(s.BlockStates) * 64 / (16 * 16 * 16)
// skip empty // skip empty
if len(s.BlockStates) == 0 { if len(s.BlockStates) == 0 {
continue return
} }
// decode section // decode section
//n := int(math.Max(4, math.Ceil(math.Log2(float64(len(s.Palette)))))) //n := int(math.Max(4, math.Ceil(math.Log2(float64(len(s.Palette))))))
@ -125,6 +169,5 @@ func drawColumn(column *save.Column) (img *image.RGBA) {
draw.Over, draw.Over,
) )
} }
}
return return
} }

View File

@ -31,7 +31,7 @@ type Column struct {
LastUpdate int64 LastUpdate int64
Status string Status string
PosX int32 `nbt:"xPos"` PosX int32 `nbt:"xPos"`
PosY int32 `nbt:"yPos"` PosZ int32 `nbt:"zPos"`
Biomes []int32 Biomes []int32
} }
} }