mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
mipmap: Bug fix: Too big scale tried to allocate too big images
Fixes #1399
This commit is contained in:
parent
356391a36c
commit
4c7eaeaf02
@ -148,12 +148,12 @@ func (g *Game) Update() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyQ) {
|
if ebiten.IsKeyPressed(ebiten.KeyQ) {
|
||||||
if g.camera.ZoomFactor > -240 {
|
if g.camera.ZoomFactor > -2400 {
|
||||||
g.camera.ZoomFactor -= 1
|
g.camera.ZoomFactor -= 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyE) {
|
if ebiten.IsKeyPressed(ebiten.KeyE) {
|
||||||
if g.camera.ZoomFactor < 240 {
|
if g.camera.ZoomFactor < 2400 {
|
||||||
g.camera.ZoomFactor += 1
|
g.camera.ZoomFactor += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2149,3 +2149,14 @@ func TestImageDrawImageTooSmallScale(t *testing.T) {
|
|||||||
op.GeoM.Scale(1e-10, 1e-10)
|
op.GeoM.Scale(1e-10, 1e-10)
|
||||||
dst.DrawImage(src, op)
|
dst.DrawImage(src, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #1399
|
||||||
|
func TestImageDrawImageCannotAllocateImageForMipmap(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)
|
||||||
|
}
|
||||||
|
@ -236,6 +236,13 @@ func (m *Mipmap) level(level int) *buffered.Image {
|
|||||||
m.imgs[level] = nil
|
m.imgs[level] = nil
|
||||||
return 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 := buffered.NewImage(w2, h2)
|
||||||
s.SetVolatile(m.volatile)
|
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)
|
s.DrawTriangles([graphics.ShaderImageNum]*buffered.Image{src}, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
@ -268,7 +275,9 @@ func (m *Mipmap) MarkDisposed() {
|
|||||||
|
|
||||||
func (m *Mipmap) disposeMipmaps() {
|
func (m *Mipmap) disposeMipmaps() {
|
||||||
for _, img := range m.imgs {
|
for _, img := range m.imgs {
|
||||||
img.MarkDisposed()
|
if img != nil {
|
||||||
|
img.MarkDisposed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for k := range m.imgs {
|
for k := range m.imgs {
|
||||||
delete(m.imgs, k)
|
delete(m.imgs, k)
|
||||||
@ -277,7 +286,7 @@ func (m *Mipmap) disposeMipmaps() {
|
|||||||
|
|
||||||
// mipmapLevel returns an appropriate mipmap level for the given distance.
|
// 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 {
|
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 {
|
if filter == driver.FilterScreen {
|
||||||
return 0
|
return 0
|
||||||
@ -293,7 +302,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).
|
// Scale can be infinite when the specified scale is extremely big (#1398).
|
||||||
if math.IsInf(float64(scale), 0) {
|
if math.IsInf(float64(scale), 0) {
|
||||||
if filter == driver.FilterNearest {
|
if filter == driver.FilterNearest {
|
||||||
return -maxScale
|
return -maxLevel
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -333,8 +342,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
|
// If tooBigScale is 32, level -6 means that the maximum scale is 32 * 2^6 = 2048. This should be
|
||||||
// enough.
|
// enough.
|
||||||
if level < -maxScale {
|
if level < -maxLevel {
|
||||||
level = -maxScale
|
level = -maxLevel
|
||||||
}
|
}
|
||||||
return level
|
return level
|
||||||
}
|
}
|
||||||
@ -367,8 +376,8 @@ func mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1 float32, fil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if level > maxScale {
|
if level > maxLevel {
|
||||||
level = maxScale
|
level = maxLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
return level
|
return level
|
||||||
|
Loading…
Reference in New Issue
Block a user