graphicsutil: Extract matrix applying for performance

This commit is contained in:
Hajime Hoshi 2018-06-17 19:45:09 +09:00
parent 9f34b79297
commit ac24a8382f
7 changed files with 32 additions and 30 deletions

View File

@ -61,6 +61,10 @@ func (g *GeoM) apply32(x, y float32) (x2, y2 float32) {
return (g.a_1+1)*x + g.b*y + g.tx, g.c*x + (g.d_1+1)*y + g.ty
}
func (g *GeoM) elements() (a, b, c, d, tx, ty float32) {
return g.a_1 + 1, g.b, g.c, g.d_1 + 1, g.tx, g.ty
}
// Element returns a value of a matrix at (i, j).
func (g *GeoM) Element(i, j int) float64 {
switch {
@ -136,6 +140,10 @@ func (g *GeoM) Translate(tx, ty float64) {
// Rotate rotates the matrix by theta.
// The unit is radian.
func (g *GeoM) Rotate(theta float64) {
if theta == 0 {
return
}
sin64, cos64 := math.Sincos(theta)
sin, cos := float32(sin64), float32(cos64)

View File

@ -130,8 +130,8 @@ type geoM32 struct {
inner *GeoM
}
func (g geoM32) Apply(x, y float32) (x2, y2 float32) {
return g.inner.apply32(x, y)
func (g geoM32) Elements() (a, b, c, d, tx, ty float32) {
return g.inner.elements()
}
// DrawImage draws the given image on the image i.

View File

@ -44,7 +44,7 @@ func (v *verticesBackend) sliceForOneQuad() []float32 {
}
type GeoM interface {
Apply(x, y float32) (x2, y2 float32)
Elements() (a, b, c, d, tx, ty float32)
}
func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, geom GeoM) []float32 {
@ -55,9 +55,6 @@ func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, geom GeoM) []float3
return nil
}
x0, y0 := float32(0.0), float32(0.0)
x1, y1 := float32(sx1-sx0), float32(sy1-sy0)
// it really feels like we should be able to cache this computation
// but it may not matter.
w := 1
@ -71,16 +68,16 @@ func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, geom GeoM) []float3
wf := float32(w)
hf := float32(h)
u0, v0, u1, v1 := float32(sx0)/wf, float32(sy0)/hf, float32(sx1)/wf, float32(sy1)/hf
return quadVerticesImpl(u0, v0, u1, v1, x0, y0, x1, y1, geom)
return quadVerticesImpl(float32(sx1-sx0), float32(sy1-sy0), u0, v0, u1, v1, geom)
}
func quadVerticesImpl(u0, v0, u1, v1, x0, y0, x1, y1 float32, geom GeoM) []float32 {
func quadVerticesImpl(x, y, u0, v0, u1, v1 float32, geom GeoM) []float32 {
vs := theVerticesBackend.sliceForOneQuad()
x, y := geom.Apply(x0, y0)
a, b, c, d, tx, ty := geom.Elements()
// Vertex coordinates
vs[0] = x
vs[1] = y
vs[0] = tx
vs[1] = ty
// Texture coordinates: first 2 values indicates the actual coodinate, and
// the second indicates diagonally opposite coodinates.
@ -91,25 +88,22 @@ func quadVerticesImpl(u0, v0, u1, v1, x0, y0, x1, y1 float32, geom GeoM) []float
vs[5] = v1
// and the same for the other three coordinates
x, y = geom.Apply(x1, y0)
vs[6] = x
vs[7] = y
vs[6] = a*x + tx
vs[7] = c*x + ty
vs[8] = u1
vs[9] = v0
vs[10] = u0
vs[11] = v1
x, y = geom.Apply(x0, y1)
vs[12] = x
vs[13] = y
vs[12] = b*y + tx
vs[13] = d*y + ty
vs[14] = u0
vs[15] = v1
vs[16] = u1
vs[17] = v0
x, y = geom.Apply(x1, y1)
vs[18] = x
vs[19] = y
vs[18] = a*x + b*y + tx
vs[19] = c*x + d*y + ty
vs[20] = u1
vs[21] = v1
vs[22] = u0

View File

@ -129,8 +129,8 @@ type geoM struct {
ty float32
}
func (g *geoM) Apply(x, y float32) (float32, float32) {
return x*g.scaleX + g.tx, y*g.scaleY + g.ty
func (g *geoM) Elements() (a, b, c, d, tx, ty float32) {
return g.scaleX, 0, 0, g.scaleY, g.tx, g.ty
}
// ReplacePixels replaces the image pixels with the given pixels slice.

View File

@ -107,8 +107,8 @@ var (
type idGeoM struct{}
func (idGeoM) Apply(x, y float32) (x2, y2 float32) {
return x, y
func (idGeoM) Elements() (a, b, c, d, tx, ty float32) {
return 1, 0, 0, 1, 0, 0
}
func TestRestoreChain(t *testing.T) {
@ -267,8 +267,8 @@ type geoM struct {
ty float32
}
func (g *geoM) Apply(x, y float32) (x2, y2 float32) {
return x + g.tx, y + g.ty
func (g *geoM) Elements() (a, b, c, d, tx, ty float32) {
return 1, 0, 0, 1, g.tx, g.ty
}
func TestRestoreComplexGraph(t *testing.T) {

View File

@ -100,8 +100,8 @@ type Image struct {
type idGeoM struct{}
func (idGeoM) Apply(x, y float32) (x2, y2 float32) {
return x, y
func (idGeoM) Elements() (a, b, c, d, tx, ty float32) {
return 1, 0, 0, 1, 0, 0
}
func (i *Image) ensureNotShared() {

View File

@ -50,8 +50,8 @@ type geoM struct {
ty float32
}
func (g *geoM) Apply(x, y float32) (x2, y2 float32) {
return x + g.tx, y + g.ty
func (g *geoM) Elements() (a, b, c, d, tx, ty float32) {
return 1, 0, 0, 1, g.tx, g.ty
}
func TestEnsureNotShared(t *testing.T) {