graphics: Detect maximum texture size for each environment

Fixes #537, #539

See also #541
This commit is contained in:
Hajime Hoshi 2018-03-09 11:03:55 +09:00
parent 0418ce0761
commit e977019d2f
10 changed files with 66 additions and 17 deletions

View File

@ -103,8 +103,8 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error {
if c.offsetX > 0 || c.offsetY > 0 {
op := &DrawImageOptions{}
w, h := emptyImage.Size()
// graphics.MaxImageSize should be the maximum size of framebuffer.
op.GeoM.Scale(graphics.MaxImageSize/float64(w), graphics.MaxImageSize/float64(h))
s := float64(graphics.MaxImageSize())
op.GeoM.Scale(s/float64(w), s/float64(h))
op.CompositeMode = CompositeModeCopy
c.screen.DrawImage(emptyImage, op)
}

View File

@ -552,5 +552,7 @@ func newImageWithScreenFramebuffer(width, height int) *Image {
return i
}
// MaxImageSize represents the maximum width/height of an image.
const MaxImageSize = graphics.MaxImageSize
// MaxImageSize is deprecated as of 1.7.0-alpha. No replacement so far.
//
// TODO: Make this replacement (#541)
var MaxImageSize = 4096

View File

@ -332,11 +332,12 @@ func checkSize(width, height int) {
if height < 1 {
panic(fmt.Sprintf("graphics: height (%d) must be equal or more than 1.", height))
}
if width > MaxImageSize {
panic(fmt.Sprintf("graphics: width (%d) must be less than or equal to %d", width, MaxImageSize))
m := MaxImageSize()
if width > m {
panic(fmt.Sprintf("graphics: width (%d) must be less than or equal to %d", width, m))
}
if height > MaxImageSize {
panic(fmt.Sprintf("graphics: height (%d) must be less than or equal to %d", height, MaxImageSize))
if height > m {
panic(fmt.Sprintf("graphics: height (%d) must be less than or equal to %d", height, m))
}
}

View File

@ -66,11 +66,6 @@ func newScreenFramebuffer(width, height int) *framebuffer {
}
}
// defaultViewportSize is the default size (width or height) of viewport.
//
// defaultViewportSize also represents the maximum size of a framebuffer.
const defaultViewportSize = 4096
// viewportSize returns the viewport size of the framebuffer.
func (f *framebuffer) viewportSize() (int, int) {
// On some browsers, viewport size must be within the framebuffer size.
@ -80,7 +75,8 @@ func (f *framebuffer) viewportSize() (int, int) {
}
// If possible, always use the same viewport size to reduce draw calls.
return defaultViewportSize, defaultViewportSize
m := MaxImageSize()
return m, m
}
// setAsViewport sets the framebuffer as the current viewport.

View File

@ -18,8 +18,31 @@ import (
"github.com/hajimehoshi/ebiten/internal/affine"
"github.com/hajimehoshi/ebiten/internal/math"
"github.com/hajimehoshi/ebiten/internal/opengl"
"github.com/hajimehoshi/ebiten/internal/sync"
)
var (
// maxTextureSize is the maximum texture size
//
// maxTextureSize also represents the default size (width or height) of viewport.
maxTextureSize = 0
maxTextureSizeLock sync.Mutex
)
// MaxImageSize returns the maximum of width/height of an image.
func MaxImageSize() int {
maxTextureSizeLock.Lock()
if maxTextureSize == 0 {
maxTextureSize = opengl.GetContext().MaxTextureSize()
if maxTextureSize == 0 {
panic("graphics: failed to get the max texture size")
}
}
s := maxTextureSize
maxTextureSizeLock.Unlock()
return s
}
// Image represents an image that is implemented with OpenGL.
type Image struct {
texture *texture
@ -28,9 +51,6 @@ type Image struct {
height int
}
// MaxImageSize is the maximum of width/height of an image.
const MaxImageSize = defaultViewportSize
func NewImage(width, height int) *Image {
i := &Image{
width: width,

View File

@ -147,6 +147,7 @@ func (s *openGLState) reset() error {
if err := opengl.GetContext().Reset(); err != nil {
return err
}
s.lastProgram = zeroProgram
s.lastProjectionMatrix = nil
s.lastColorMatrix = nil

View File

@ -51,6 +51,7 @@ type Context struct {
lastViewportWidth int
lastViewportHeight int
lastCompositeMode CompositeMode
maxTextureSize int
context
}
@ -93,3 +94,10 @@ func (c *Context) ResetViewportSize() {
c.lastViewportWidth = 0
c.lastViewportHeight = 0
}
func (c *Context) MaxTextureSize() int {
if c.maxTextureSize == 0 {
c.maxTextureSize = c.maxTextureSizeImpl()
}
return c.maxTextureSize
}

View File

@ -494,6 +494,17 @@ func (c *Context) DrawElements(mode Mode, len int, offsetInBytes int) {
})
}
func (c *Context) maxTextureSizeImpl() int {
size := 0
_ = c.runOnContextThread(func() error {
s := int32(0)
gl.GetIntegerv(gl.MAX_TEXTURE_SIZE, &s)
size = int(s)
return nil
})
return size
}
func (c *Context) Flush() {
_ = c.runOnContextThread(func() error {
gl.Flush()

View File

@ -379,6 +379,11 @@ func (c *Context) DrawElements(mode Mode, len int, offsetInBytes int) {
gl.DrawElements(int(mode), len, gl.UNSIGNED_SHORT, offsetInBytes)
}
func (c *Context) maxTextureSizeImpl() int {
gl := c.gl
return gl.GetParameter(gl.MAX_TEXTURE_SIZE).Int()
}
func (c *Context) Flush() {
gl := c.gl
gl.Flush()

View File

@ -399,6 +399,11 @@ func (c *Context) DrawElements(mode Mode, len int, offsetInBytes int) {
gl.DrawElements(mgl.Enum(mode), len, mgl.UNSIGNED_SHORT, offsetInBytes)
}
func (c *Context) maxTextureSizeImpl() int {
gl := c.gl
return gl.GetInteger(mgl.MAX_TEXTURE_SIZE)
}
func (c *Context) Flush() {
gl := c.gl
gl.Flush()