mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
mipmap: Bug fix: Too big scale tried to allocate too big images
Fixes #1399
This commit is contained in:
parent
a3cb78558b
commit
e7d080ca4a
@ -148,12 +148,12 @@ func (g *Game) Update() error {
|
||||
}
|
||||
|
||||
if ebiten.IsKeyPressed(ebiten.KeyQ) {
|
||||
if g.camera.ZoomFactor > -240 {
|
||||
if g.camera.ZoomFactor > -2400 {
|
||||
g.camera.ZoomFactor -= 1
|
||||
}
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyE) {
|
||||
if g.camera.ZoomFactor < 240 {
|
||||
if g.camera.ZoomFactor < 2400 {
|
||||
g.camera.ZoomFactor += 1
|
||||
}
|
||||
}
|
||||
|
@ -2149,3 +2149,14 @@ func TestImageDrawImageTooSmallScale(t *testing.T) {
|
||||
op.GeoM.Scale(1e-10, 1e-10)
|
||||
dst.DrawImage(src, op)
|
||||
}
|
||||
|
||||
// Issue #1399
|
||||
func TestImageDrawImageCannotCreateMiamap(t *testing.T) {
|
||||
dst := NewImage(1, 1)
|
||||
src := NewImage(4096, 4096)
|
||||
|
||||
op := &DrawImageOptions{}
|
||||
op.GeoM.Scale(64, 64)
|
||||
dst.DrawImage(src, op)
|
||||
dst.At(0, 0)
|
||||
}
|
||||
|
@ -230,6 +230,13 @@ func (m *Mipmap) level(level int) *buffered.Image {
|
||||
m.imgs[level] = nil
|
||||
return nil
|
||||
}
|
||||
// buffered.NewImage panics with a too big size when actual allocation happens.
|
||||
// 4096 should be a safe size in most environments (#1399).
|
||||
// Unfortunately a precise max image size cannot be obtained here since this requires GPU access.
|
||||
if w2 > 4096 || h2 > 4096 {
|
||||
m.imgs[level] = nil
|
||||
return nil
|
||||
}
|
||||
s := buffered.NewImage(w2, h2)
|
||||
s.SetVolatile(m.volatile)
|
||||
s.DrawTriangles([graphics.ShaderImageNum]*buffered.Image{src}, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||
@ -262,8 +269,10 @@ func (m *Mipmap) MarkDisposed() {
|
||||
|
||||
func (m *Mipmap) disposeMipmaps() {
|
||||
for _, img := range m.imgs {
|
||||
if img != nil {
|
||||
img.MarkDisposed()
|
||||
}
|
||||
}
|
||||
for k := range m.imgs {
|
||||
delete(m.imgs, k)
|
||||
}
|
||||
@ -271,7 +280,7 @@ func (m *Mipmap) disposeMipmaps() {
|
||||
|
||||
// mipmapLevel returns an appropriate mipmap level for the given distance.
|
||||
func mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1 float32, filter driver.Filter) int {
|
||||
const maxScale = 6
|
||||
const maxLevel = 6
|
||||
|
||||
if filter == driver.FilterScreen {
|
||||
return 0
|
||||
@ -287,7 +296,7 @@ func mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1 float32, fil
|
||||
// Scale can be infinite when the specified scale is extremely big (#1398).
|
||||
if math.IsInf(float64(scale), 0) {
|
||||
if filter == driver.FilterNearest {
|
||||
return -maxScale
|
||||
return -maxLevel
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@ -327,8 +336,8 @@ func mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1 float32, fil
|
||||
|
||||
// If tooBigScale is 32, level -6 means that the maximum scale is 32 * 2^6 = 2048. This should be
|
||||
// enough.
|
||||
if level < -maxScale {
|
||||
level = -maxScale
|
||||
if level < -maxLevel {
|
||||
level = -maxLevel
|
||||
}
|
||||
return level
|
||||
}
|
||||
@ -361,8 +370,8 @@ func mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1 float32, fil
|
||||
}
|
||||
}
|
||||
|
||||
if level > maxScale {
|
||||
level = maxScale
|
||||
if level > maxLevel {
|
||||
level = maxLevel
|
||||
}
|
||||
|
||||
return level
|
||||
|
Loading…
Reference in New Issue
Block a user