graphics: Move the vertices backend to ebiten package

Now restorable/sharable packages cannot use the same vertices
backend, but I think this won't affect the performance
significantly.
This commit is contained in:
Hajime Hoshi 2019-06-22 00:00:37 +09:00
parent 69ebc481e8
commit f3cdb0537b
8 changed files with 71 additions and 54 deletions

View File

@ -71,7 +71,7 @@ func (m *mipmap) level(r image.Rectangle, level int) *shareable.Image {
}
s := shareable.NewImage(w2, h2)
var src *shareable.Image
vs := graphics.VertexSlice(4)
vs := vertexSlice(4)
if l := len(imgs); l == 0 {
src = m.orig
src.PutQuadVertices(vs, r.Min.X, r.Min.Y, r.Max.X, r.Max.Y, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
@ -355,7 +355,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
if level == 0 {
src := img.mipmap.original()
vs := graphics.VertexSlice(4)
vs := vertexSlice(4)
src.PutQuadVertices(vs, bounds.Min.X, bounds.Min.Y, bounds.Max.X, bounds.Max.Y, a, b, c, d, tx, ty, cr, cg, cb, ca)
is := graphics.QuadIndices()
i.mipmap.original().DrawTriangles(src, vs, is, colorm, mode, filter, graphics.AddressClampToZero)
@ -366,7 +366,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
b *= float32(s)
c *= float32(s)
d *= float32(s)
vs := graphics.VertexSlice(4)
vs := vertexSlice(4)
src.PutQuadVertices(vs, 0, 0, w, h, a, b, c, d, tx, ty, cr, cg, cb, ca)
is := graphics.QuadIndices()
i.mipmap.original().DrawTriangles(src, vs, is, colorm, mode, filter, graphics.AddressClampToZero)
@ -481,7 +481,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
filter = graphics.Filter(img.filter)
}
vs := graphics.VertexSlice(len(vertices))
vs := vertexSlice(len(vertices))
src := img.mipmap.original()
r := img.Bounds()
for idx, v := range vertices {

View File

@ -14,53 +14,11 @@
package graphics
import (
"sync"
)
var (
theVerticesBackend = &verticesBackend{}
)
type verticesBackend struct {
backend []float32
head int
m sync.Mutex
}
const (
IndicesNum = (1 << 16) / 3 * 3 // Adjust num for triangles.
VertexFloatNum = 12
)
func (v *verticesBackend) slice(n int) []float32 {
v.m.Lock()
need := n * VertexFloatNum
if v.head+need > len(v.backend) {
v.backend = nil
v.head = 0
}
if v.backend == nil {
l := 1024
if n > l {
l = n
}
v.backend = make([]float32, VertexFloatNum*l)
}
s := v.backend[v.head : v.head+need]
v.head += need
v.m.Unlock()
return s
}
func VertexSlice(n int) []float32 {
return theVerticesBackend.slice(n)
}
type VertexPutter interface {
PutVertex(dst []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32)
}

View File

@ -69,7 +69,7 @@ func TestClear(t *testing.T) {
src := NewImage(w/2, h/2)
dst := NewImage(w, h)
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
graphics.PutQuadVertices(vs, &testVertexPutter{w / 2, h / 2}, 0, 0, w/2, h/2, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices()
dst.DrawTriangles(src, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
@ -97,7 +97,7 @@ func TestReplacePixelsPartAfterDrawTriangles(t *testing.T) {
clr := NewImage(w, h)
src := NewImage(16, 16)
dst := NewImage(w, h)
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
graphics.PutQuadVertices(vs, &testVertexPutter{w / 2, h / 2}, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices()
dst.DrawTriangles(clr, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)

View File

@ -195,7 +195,7 @@ func (i *Image) fill(r, g, b, a uint8) {
// As emptyImage is a priority image, this is restored before other regular images are restored.
dw, dh := i.internalSize()
sw, sh := emptyImage.Size()
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
graphics.PutQuadVertices(vs, i, 0, 0, sw, sh,
float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh), 0, 0,
rf, gf, bf, af)

View File

@ -106,7 +106,7 @@ func TestRestoreWithoutDraw(t *testing.T) {
}
func quadVertices(src *Image, sw, sh, x, y int) []float32 {
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
graphics.PutQuadVertices(vs, src, 0, 0, sw, sh,
1, 0, 0, 1, float32(x), float32(y),
1, 1, 1, 1)

View File

@ -171,7 +171,7 @@ func (i *Image) ensureNotShared() {
_, _, w, h := i.region()
newImg := restorable.NewImage(w, h)
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
i.PutQuadVertices(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices()
newImg.DrawTriangles(i.backend.restorable, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)

View File

@ -84,7 +84,7 @@ func TestEnsureNotShared(t *testing.T) {
dy1 = size * 3 / 4
)
// img4.ensureNotShared() should be called.
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
img3.PutQuadVertices(vs, 0, 0, size/2, size/2, 1, 0, 0, 1, size/4, size/4, 1, 1, 1, 1)
is := graphics.QuadIndices()
img4.DrawTriangles(img3, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
@ -149,7 +149,7 @@ func TestReshared(t *testing.T) {
}
// Use img1 as a render target.
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
img2.PutQuadVertices(vs, 0, 0, size, size, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices()
img1.DrawTriangles(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
@ -276,7 +276,7 @@ func TestReplacePixelsAfterDrawTriangles(t *testing.T) {
}
src.ReplacePixels(pix)
vs := graphics.VertexSlice(4)
vs := make([]float32, 4*graphics.VertexFloatNum)
src.PutQuadVertices(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices()
dst.DrawTriangles(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)

59
vertex.go Normal file
View File

@ -0,0 +1,59 @@
// Copyright 2019 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ebiten
import (
"sync"
"github.com/hajimehoshi/ebiten/internal/graphics"
)
var (
theVerticesBackend = &verticesBackend{}
)
type verticesBackend struct {
backend []float32
head int
m sync.Mutex
}
func (v *verticesBackend) slice(n int) []float32 {
v.m.Lock()
need := n * graphics.VertexFloatNum
if v.head+need > len(v.backend) {
v.backend = nil
v.head = 0
}
if v.backend == nil {
l := 1024
if n > l {
l = n
}
v.backend = make([]float32, graphics.VertexFloatNum*l)
}
s := v.backend[v.head : v.head+need]
v.head += need
v.m.Unlock()
return s
}
func vertexSlice(n int) []float32 {
return theVerticesBackend.slice(n)
}