mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 10:42:42 +01:00
internal/affine: Improve ColorM Scale's performance
The benchmark result comparing the previous commit and this commit is this: ``` name old time/op new time/op delta ColorMScale-8 9.75µs ± 6% 1.30µs ±22% -86.67% (p=0.000 n=10+9) name old alloc/op new alloc/op delta ColorMScale-8 1.34kB ±100% 1.19kB ±19% ~ (p=0.421 n=10+8) name old allocs/op new allocs/op delta ColorMScale-8 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.000 n=10+10) ``` Updates #1658
This commit is contained in:
parent
79e067b0f8
commit
59aa41a3c2
@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"math"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ColorMDim is a dimension of a ColorM.
|
||||
@ -104,7 +103,7 @@ func (c ColorMIdentity) IsIdentity() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) IsIdentity() bool {
|
||||
func (c colorMImplScale) IsIdentity() bool {
|
||||
return c.scale == [4]float32{1, 1, 1, 1}
|
||||
}
|
||||
|
||||
@ -116,7 +115,7 @@ func (c ColorMIdentity) ScaleOnly() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) ScaleOnly() bool {
|
||||
func (c colorMImplScale) ScaleOnly() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -169,7 +168,7 @@ func (c ColorMIdentity) UnsafeScaleElements() *[4]float32 {
|
||||
return &[...]float32{1, 1, 1, 1}
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) UnsafeScaleElements() *[4]float32 {
|
||||
func (c colorMImplScale) UnsafeScaleElements() *[4]float32 {
|
||||
return &c.scale
|
||||
}
|
||||
|
||||
@ -200,7 +199,7 @@ func (c ColorMIdentity) Apply(clr color.Color) color.Color {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) Apply(clr color.Color) color.Color {
|
||||
func (c colorMImplScale) Apply(clr color.Color) color.Color {
|
||||
rf, gf, bf, af := colorToFloat32s(clr)
|
||||
rf *= c.scale[0]
|
||||
gf *= c.scale[1]
|
||||
@ -242,7 +241,7 @@ func (c ColorMIdentity) UnsafeElements() (*[16]float32, *[4]float32) {
|
||||
return &colorMIdentityBody, &colorMIdentityTranslate
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) UnsafeElements() (*[16]float32, *[4]float32) {
|
||||
func (c colorMImplScale) UnsafeElements() (*[16]float32, *[4]float32) {
|
||||
return &[...]float32{
|
||||
c.scale[0], 0, 0, 0,
|
||||
0, c.scale[1], 0, 0,
|
||||
@ -290,7 +289,7 @@ func (c ColorMIdentity) IsInvertible() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) IsInvertible() bool {
|
||||
func (c colorMImplScale) IsInvertible() bool {
|
||||
return c.scale[0] != 0 && c.scale[1] != 0 && c.scale[2] != 0 && c.scale[3] != 0
|
||||
}
|
||||
|
||||
@ -302,8 +301,8 @@ func (c ColorMIdentity) Invert() ColorM {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) Invert() ColorM {
|
||||
return &colorMImplScale{
|
||||
func (c colorMImplScale) Invert() ColorM {
|
||||
return colorMImplScale{
|
||||
scale: [4]float32{
|
||||
1 / c.scale[0],
|
||||
1 / c.scale[1],
|
||||
@ -449,7 +448,7 @@ func (c ColorMIdentity) Equals(other ColorM) bool {
|
||||
return other.IsIdentity()
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) Equals(other ColorM) bool {
|
||||
func (c colorMImplScale) Equals(other ColorM) bool {
|
||||
if !other.ScaleOnly() {
|
||||
return false
|
||||
}
|
||||
@ -472,7 +471,7 @@ func (c ColorMIdentity) Concat(other ColorM) ColorM {
|
||||
return other
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) Concat(other ColorM) ColorM {
|
||||
func (c colorMImplScale) Concat(other ColorM) ColorM {
|
||||
if other.IsIdentity() {
|
||||
return c
|
||||
}
|
||||
@ -518,11 +517,13 @@ func (c *colorMImplBodyTranslate) Concat(other ColorM) ColorM {
|
||||
}
|
||||
|
||||
func (c ColorMIdentity) Scale(r, g, b, a float32) ColorM {
|
||||
return getCachedScalingColorM(r, g, b, a)
|
||||
return colorMImplScale{
|
||||
scale: [...]float32{r, g, b, a},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) Scale(r, g, b, a float32) ColorM {
|
||||
return &colorMImplScale{
|
||||
func (c colorMImplScale) Scale(r, g, b, a float32) ColorM {
|
||||
return colorMImplScale{
|
||||
scale: [...]float32{
|
||||
c.scale[0] * r,
|
||||
c.scale[1] * g,
|
||||
@ -535,7 +536,9 @@ func (c *colorMImplScale) Scale(r, g, b, a float32) ColorM {
|
||||
func (c *colorMImplBodyTranslate) Scale(r, g, b, a float32) ColorM {
|
||||
if c.ScaleOnly() {
|
||||
s := c.UnsafeScaleElements()
|
||||
return getCachedScalingColorM(r*s[0], g*s[1], b*s[2], a*s[3])
|
||||
return colorMImplScale{
|
||||
scale: [...]float32{r * s[0], g * s[1], b * s[2], a * s[3]},
|
||||
}
|
||||
}
|
||||
|
||||
eb := c.body
|
||||
@ -566,7 +569,7 @@ func (c ColorMIdentity) Translate(r, g, b, a float32) ColorM {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *colorMImplScale) Translate(r, g, b, a float32) ColorM {
|
||||
func (c colorMImplScale) Translate(r, g, b, a float32) ColorM {
|
||||
return &colorMImplBodyTranslate{
|
||||
body: [...]float32{
|
||||
c.scale[0], 0, 0, 0,
|
||||
@ -647,48 +650,3 @@ type cachedScalingColorMValue struct {
|
||||
c *colorMImplScale
|
||||
atime uint64
|
||||
}
|
||||
|
||||
var (
|
||||
cachedScalingColorM = map[cachedScalingColorMKey]*cachedScalingColorMValue{}
|
||||
cachedScalingColorMM sync.Mutex
|
||||
cacheMonotonicClock uint64
|
||||
)
|
||||
|
||||
func getCachedScalingColorM(r, g, b, a float32) ColorM {
|
||||
key := cachedScalingColorMKey{r, g, b, a}
|
||||
|
||||
cachedScalingColorMM.Lock()
|
||||
defer cachedScalingColorMM.Unlock()
|
||||
|
||||
cacheMonotonicClock++
|
||||
now := cacheMonotonicClock
|
||||
|
||||
if v, ok := cachedScalingColorM[key]; ok {
|
||||
v.atime = now
|
||||
return v.c
|
||||
}
|
||||
|
||||
const maxCacheSize = 512 // An arbitrary number
|
||||
|
||||
for len(cachedScalingColorM) >= maxCacheSize {
|
||||
var oldest uint64 = math.MaxUint64
|
||||
var oldestKey cachedScalingColorMKey
|
||||
for k, v := range cachedScalingColorM {
|
||||
if v.atime < oldest {
|
||||
oldestKey = k
|
||||
oldest = v.atime
|
||||
}
|
||||
}
|
||||
delete(cachedScalingColorM, oldestKey)
|
||||
}
|
||||
|
||||
v := &cachedScalingColorMValue{
|
||||
c: &colorMImplScale{
|
||||
scale: [...]float32{r, g, b, a},
|
||||
},
|
||||
atime: now,
|
||||
}
|
||||
cachedScalingColorM[key] = v
|
||||
|
||||
return v.c
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user