graphicsdriver/opengl: Rename Driver -> Graphics

This commit is contained in:
Hajime Hoshi 2020-04-04 17:20:08 +09:00
parent 01d1afa25c
commit eabe4152a7
6 changed files with 105 additions and 105 deletions

View File

@ -16,10 +16,10 @@ package opengl
// framebuffer is a wrapper of OpenGL's framebuffer.
type framebuffer struct {
driver *Driver
native framebufferNative
width int
height int
graphics *Graphics
native framebufferNative
width int
height int
}
// newFramebufferFromTexture creates a framebuffer from the given texture.

View File

@ -23,13 +23,13 @@ import (
"github.com/hajimehoshi/ebiten/internal/thread"
)
var theDriver Driver
var theGraphics Graphics
func Get() *Driver {
return &theDriver
func Get() *Graphics {
return &theGraphics
}
type Driver struct {
type Graphics struct {
state openGLState
context context
@ -37,32 +37,32 @@ type Driver struct {
drawCalled bool
}
func (d *Driver) SetThread(thread *thread.Thread) {
d.context.t = thread
func (g *Graphics) SetThread(thread *thread.Thread) {
g.context.t = thread
}
func (d *Driver) Begin() {
func (g *Graphics) Begin() {
// Do nothing.
}
func (d *Driver) End() {
func (g *Graphics) End() {
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
// TODO: examples/sprites worked without this. Is this really needed?
d.context.flush()
g.context.flush()
}
func (d *Driver) SetTransparent(transparent bool) {
func (g *Graphics) SetTransparent(transparent bool) {
// Do nothings.
}
func (d *Driver) checkSize(width, height int) {
func (g *Graphics) checkSize(width, height int) {
if width < 1 {
panic(fmt.Sprintf("opengl: width (%d) must be equal or more than %d", width, 1))
}
if height < 1 {
panic(fmt.Sprintf("opengl: height (%d) must be equal or more than %d", height, 1))
}
m := d.context.getMaxTextureSize()
m := g.context.getMaxTextureSize()
if width > m {
panic(fmt.Sprintf("opengl: width (%d) must be less than or equal to %d", width, m))
}
@ -71,16 +71,16 @@ func (d *Driver) checkSize(width, height int) {
}
}
func (d *Driver) NewImage(width, height int) (driver.Image, error) {
func (g *Graphics) NewImage(width, height int) (driver.Image, error) {
i := &Image{
driver: d,
width: width,
height: height,
graphics: g,
width: width,
height: height,
}
w := graphics.InternalImageSize(width)
h := graphics.InternalImageSize(height)
d.checkSize(w, h)
t, err := d.context.newTexture(w, h)
g.checkSize(w, h)
t, err := g.context.newTexture(w, h)
if err != nil {
return nil, err
}
@ -88,63 +88,63 @@ func (d *Driver) NewImage(width, height int) (driver.Image, error) {
return i, nil
}
func (d *Driver) NewScreenFramebufferImage(width, height int) (driver.Image, error) {
d.checkSize(width, height)
func (g *Graphics) NewScreenFramebufferImage(width, height int) (driver.Image, error) {
g.checkSize(width, height)
i := &Image{
driver: d,
width: width,
height: height,
screen: true,
graphics: g,
width: width,
height: height,
screen: true,
}
return i, nil
}
// Reset resets or initializes the current OpenGL state.
func (d *Driver) Reset() error {
return d.state.reset(&d.context)
func (g *Graphics) Reset() error {
return g.state.reset(&g.context)
}
func (d *Driver) SetVertices(vertices []float32, indices []uint16) {
func (g *Graphics) SetVertices(vertices []float32, indices []uint16) {
// Note that the vertices passed to BufferSubData is not under GC management
// in opengl package due to unsafe-way.
// See BufferSubData in context_mobile.go.
d.context.arrayBufferSubData(vertices)
d.context.elementArrayBufferSubData(indices)
g.context.arrayBufferSubData(vertices)
g.context.elementArrayBufferSubData(indices)
}
func (d *Driver) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
d.drawCalled = true
if err := d.useProgram(mode, colorM, filter, address); err != nil {
func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
g.drawCalled = true
if err := g.useProgram(mode, colorM, filter, address); err != nil {
return err
}
d.context.drawElements(indexLen, indexOffset*2) // 2 is uint16 size in bytes
g.context.drawElements(indexLen, indexOffset*2) // 2 is uint16 size in bytes
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419),
// but basically this pass the tests (esp. TestImageTooManyFill).
// As glFlush() causes performance problems, this should be avoided as much as possible.
// Let's wait and see, and file a new issue when this problem is newly found.
// Let's wait and see, and file a new issue when this problem is newly foung.
return nil
}
func (d *Driver) SetVsyncEnabled(enabled bool) {
func (g *Graphics) SetVsyncEnabled(enabled bool) {
// Do nothing
}
func (d *Driver) VDirection() driver.VDirection {
func (g *Graphics) VDirection() driver.VDirection {
return driver.VDownward
}
func (d *Driver) NeedsRestoring() bool {
return d.context.needsRestoring()
func (g *Graphics) NeedsRestoring() bool {
return g.context.needsRestoring()
}
func (d *Driver) IsGL() bool {
func (g *Graphics) IsGL() bool {
return true
}
func (d *Driver) HasHighPrecisionFloat() bool {
return d.context.hasHighPrecisionFloat()
func (g *Graphics) HasHighPrecisionFloat() bool {
return g.context.hasHighPrecisionFloat()
}
func (d *Driver) MaxImageSize() int {
return d.context.getMaxTextureSize()
func (g *Graphics) MaxImageSize() int {
return g.context.getMaxTextureSize()
}

View File

@ -20,6 +20,6 @@ import (
"golang.org/x/mobile/gl"
)
func (d *Driver) SetMobileGLContext(context gl.Context) {
d.context.gl = context
func (g *Graphics) SetMobileGLContext(context gl.Context) {
g.context.gl = context
}

View File

@ -20,7 +20,7 @@ import (
)
type Image struct {
driver *Driver
graphics *Graphics
textureNative textureNative
framebuffer *framebuffer
pbo buffer
@ -30,30 +30,30 @@ type Image struct {
}
func (i *Image) IsInvalidated() bool {
return !i.driver.context.isTexture(i.textureNative)
return !i.graphics.context.isTexture(i.textureNative)
}
func (i *Image) Dispose() {
if !i.pbo.equal(*new(buffer)) {
i.driver.context.deleteBuffer(i.pbo)
i.graphics.context.deleteBuffer(i.pbo)
}
if i.framebuffer != nil {
i.framebuffer.delete(&i.driver.context)
i.framebuffer.delete(&i.graphics.context)
}
if !i.textureNative.equal(*new(textureNative)) {
i.driver.context.deleteTexture(i.textureNative)
i.graphics.context.deleteTexture(i.textureNative)
}
}
func (i *Image) SetAsDestination() {
i.driver.state.destination = i
i.graphics.state.destination = i
}
func (i *Image) setViewport() error {
if err := i.ensureFramebuffer(); err != nil {
return err
}
i.driver.context.setViewport(i.framebuffer)
i.graphics.context.setViewport(i.framebuffer)
return nil
}
@ -61,7 +61,7 @@ func (i *Image) Pixels() ([]byte, error) {
if err := i.ensureFramebuffer(); err != nil {
return nil, err
}
p, err := i.driver.context.framebufferPixels(i.framebuffer, i.width, i.height)
p, err := i.graphics.context.framebufferPixels(i.framebuffer, i.width, i.height)
if err != nil {
return nil, err
}
@ -77,12 +77,12 @@ func (i *Image) ensureFramebuffer() error {
// The (default) framebuffer size can't be converted to a power of 2.
// On browsers, c.width and c.height are used as viewport size and
// Edge can't treat a bigger viewport than the drawing area (#71).
i.framebuffer = newScreenFramebuffer(&i.driver.context, i.width, i.height)
i.framebuffer = newScreenFramebuffer(&i.graphics.context, i.width, i.height)
return nil
}
w, h := graphics.InternalImageSize(i.width), graphics.InternalImageSize(i.height)
f, err := newFramebufferFromTexture(&i.driver.context, i.textureNative, w, h)
f, err := newFramebufferFromTexture(&i.graphics.context, i.textureNative, w, h)
if err != nil {
return err
}
@ -100,26 +100,26 @@ func (i *Image) ReplacePixels(args []*driver.ReplacePixelsArgs) {
// glFlush is necessary on Android.
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
if i.driver.drawCalled {
i.driver.context.flush()
if i.graphics.drawCalled {
i.graphics.context.flush()
}
i.driver.drawCalled = false
i.graphics.drawCalled = false
w, h := i.width, i.height
if !i.driver.context.canUsePBO() {
i.driver.context.texSubImage2D(i.textureNative, w, h, args)
if !i.graphics.context.canUsePBO() {
i.graphics.context.texSubImage2D(i.textureNative, w, h, args)
return
}
if i.pbo.equal(*new(buffer)) {
i.pbo = i.driver.context.newPixelBufferObject(w, h)
i.pbo = i.graphics.context.newPixelBufferObject(w, h)
}
if i.pbo.equal(*new(buffer)) {
panic("opengl: newPixelBufferObject failed")
}
i.driver.context.replacePixelsWithPBO(i.pbo, i.textureNative, w, h, args)
i.graphics.context.replacePixelsWithPBO(i.pbo, i.textureNative, w, h, args)
}
func (i *Image) SetAsSource() {
i.driver.state.source = i
i.graphics.state.source = i
}

View File

@ -255,12 +255,12 @@ func areSameFloat32Array(a, b []float32) bool {
}
// useProgram uses the program (programTexture).
func (d *Driver) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
destination := d.state.destination
func (g *Graphics) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
destination := g.state.destination
if destination == nil {
panic("destination image is not set")
}
source := d.state.source
source := g.state.source
if source == nil {
panic("source image is not set")
}
@ -271,73 +271,73 @@ func (d *Driver) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, fi
dstW := destination.width
srcW, srcH := source.width, source.height
d.context.blendFunc(mode)
g.context.blendFunc(mode)
program := d.state.programs[programKey{
program := g.state.programs[programKey{
useColorM: colorM != nil,
filter: filter,
address: address,
}]
if !d.state.lastProgram.equal(program) {
d.context.useProgram(program)
if d.state.lastProgram.equal(zeroProgram) {
theArrayBufferLayout.enable(&d.context, program)
d.context.bindBuffer(arrayBuffer, d.state.arrayBuffer)
d.context.bindBuffer(elementArrayBuffer, d.state.elementArrayBuffer)
d.context.uniformInt(program, "texture", 0)
if !g.state.lastProgram.equal(program) {
g.context.useProgram(program)
if g.state.lastProgram.equal(zeroProgram) {
theArrayBufferLayout.enable(&g.context, program)
g.context.bindBuffer(arrayBuffer, g.state.arrayBuffer)
g.context.bindBuffer(elementArrayBuffer, g.state.elementArrayBuffer)
g.context.uniformInt(program, "texture", 0)
}
d.state.lastProgram = program
d.state.lastViewportWidth = 0
d.state.lastViewportHeight = 0
d.state.lastColorMatrix = nil
d.state.lastColorMatrixTranslation = nil
d.state.lastSourceWidth = 0
d.state.lastSourceHeight = 0
g.state.lastProgram = program
g.state.lastViewportWidth = 0
g.state.lastViewportHeight = 0
g.state.lastColorMatrix = nil
g.state.lastColorMatrixTranslation = nil
g.state.lastSourceWidth = 0
g.state.lastSourceHeight = 0
}
vw := destination.framebuffer.width
vh := destination.framebuffer.height
if d.state.lastViewportWidth != vw || d.state.lastViewportHeight != vh {
d.context.uniformFloats(program, "viewport_size", []float32{float32(vw), float32(vh)})
d.state.lastViewportWidth = vw
d.state.lastViewportHeight = vh
if g.state.lastViewportWidth != vw || g.state.lastViewportHeight != vh {
g.context.uniformFloats(program, "viewport_size", []float32{float32(vw), float32(vh)})
g.state.lastViewportWidth = vw
g.state.lastViewportHeight = vh
}
if colorM != nil {
esBody, esTranslate := colorM.UnsafeElements()
if !areSameFloat32Array(d.state.lastColorMatrix, esBody) {
d.context.uniformFloats(program, "color_matrix_body", esBody)
if !areSameFloat32Array(g.state.lastColorMatrix, esBody) {
g.context.uniformFloats(program, "color_matrix_body", esBody)
// ColorM's elements are immutable. It's OK to hold the reference without copying.
d.state.lastColorMatrix = esBody
g.state.lastColorMatrix = esBody
}
if !areSameFloat32Array(d.state.lastColorMatrixTranslation, esTranslate) {
d.context.uniformFloats(program, "color_matrix_translation", esTranslate)
if !areSameFloat32Array(g.state.lastColorMatrixTranslation, esTranslate) {
g.context.uniformFloats(program, "color_matrix_translation", esTranslate)
// ColorM's elements are immutable. It's OK to hold the reference without copying.
d.state.lastColorMatrixTranslation = esTranslate
g.state.lastColorMatrixTranslation = esTranslate
}
}
if filter != driver.FilterNearest {
sw := graphics.InternalImageSize(srcW)
sh := graphics.InternalImageSize(srcH)
if d.state.lastSourceWidth != sw || d.state.lastSourceHeight != sh {
d.context.uniformFloats(program, "source_size", []float32{float32(sw), float32(sh)})
d.state.lastSourceWidth = sw
d.state.lastSourceHeight = sh
if g.state.lastSourceWidth != sw || g.state.lastSourceHeight != sh {
g.context.uniformFloats(program, "source_size", []float32{float32(sw), float32(sh)})
g.state.lastSourceWidth = sw
g.state.lastSourceHeight = sh
}
}
if filter == driver.FilterScreen {
scale := float32(dstW) / float32(srcW)
d.context.uniformFloat(program, "scale", scale)
g.context.uniformFloat(program, "scale", scale)
}
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture
// See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
d.context.bindTexture(source.textureNative)
g.context.bindTexture(source.textureNative)
d.state.source = nil
d.state.destination = nil
g.state.source = nil
g.state.destination = nil
return nil
}

View File

@ -290,7 +290,7 @@ func (u *UserInterface) run(context driver.UIContext, mainloop bool) (err error)
} else {
ctx, u.glWorker = gl.NewContext()
}
u.Graphics().(*opengl.Driver).SetMobileGLContext(ctx)
u.Graphics().(*opengl.Graphics).SetMobileGLContext(ctx)
} else {
u.t = thread.New()
u.Graphics().SetThread(u.t)