mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/graphicscommand: move the choice of graphics drivers to internal/ui
This commit is contained in:
parent
1d9982ee6d
commit
4cbce71b2b
@ -22,7 +22,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/atlas"
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
// availableFilename returns a filename that is valid as a new file or directory.
|
// availableFilename returns a filename that is valid as a new file or directory.
|
||||||
@ -72,7 +72,7 @@ func dumpInternalImages() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := atlas.DumpImages(dir); err != nil {
|
if err := ui.DumpImages(dir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,13 +14,17 @@
|
|||||||
|
|
||||||
package atlas
|
package atlas
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BaseCountToPutOnAtlas = baseCountToPutOnAtlas
|
BaseCountToPutOnAtlas = baseCountToPutOnAtlas
|
||||||
PaddingSize = paddingSize
|
PaddingSize = paddingSize
|
||||||
)
|
)
|
||||||
|
|
||||||
func PutImagesOnAtlasForTesting() error {
|
func PutImagesOnAtlasForTesting(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
return putImagesOnAtlas()
|
return putImagesOnAtlas(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -117,11 +117,11 @@ func resolveDeferred() {
|
|||||||
// Actual time duration is increased in an exponential way for each usages as a rendering target.
|
// Actual time duration is increased in an exponential way for each usages as a rendering target.
|
||||||
const baseCountToPutOnAtlas = 10
|
const baseCountToPutOnAtlas = 10
|
||||||
|
|
||||||
func putImagesOnAtlas() error {
|
func putImagesOnAtlas(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
for i := range imagesToPutOnAtlas {
|
for i := range imagesToPutOnAtlas {
|
||||||
i.usedAsSourceCount++
|
i.usedAsSourceCount++
|
||||||
if i.usedAsSourceCount >= baseCountToPutOnAtlas*(1<<uint(min(i.isolatedCount, 31))) {
|
if i.usedAsSourceCount >= baseCountToPutOnAtlas*(1<<uint(min(i.isolatedCount, 31))) {
|
||||||
if err := i.putOnAtlas(); err != nil {
|
if err := i.putOnAtlas(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.usedAsSourceCount = 0
|
i.usedAsSourceCount = 0
|
||||||
@ -304,7 +304,7 @@ func (i *Image) ensureIsolated() {
|
|||||||
i.isolatedCount++
|
i.isolatedCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) putOnAtlas() error {
|
func (i *Image) putOnAtlas(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if i.backend == nil {
|
if i.backend == nil {
|
||||||
i.allocate(true)
|
i.allocate(true)
|
||||||
return nil
|
return nil
|
||||||
@ -327,7 +327,7 @@ func (i *Image) putOnAtlas() error {
|
|||||||
pixels := make([]byte, 4*i.width*i.height)
|
pixels := make([]byte, 4*i.width*i.height)
|
||||||
for y := 0; y < i.height; y++ {
|
for y := 0; y < i.height; y++ {
|
||||||
for x := 0; x < i.width; x++ {
|
for x := 0; x < i.width; x++ {
|
||||||
r, g, b, a, err := i.at(x+paddingSize, y+paddingSize)
|
r, g, b, a, err := i.at(graphicsDriver, x+paddingSize, y+paddingSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -598,7 +598,7 @@ func (i *Image) replacePixels(pix []byte) {
|
|||||||
i.backend.restorable.ReplacePixels(pixb, x, y, w, h)
|
i.backend.restorable.ReplacePixels(pixb, x, y, w, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (img *Image) Pixels(x, y, width, height int) ([]byte, error) {
|
func (img *Image) Pixels(graphicsDriver graphicsdriver.Graphics, x, y, width, height int) ([]byte, error) {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
@ -609,7 +609,7 @@ func (img *Image) Pixels(x, y, width, height int) ([]byte, error) {
|
|||||||
idx := 0
|
idx := 0
|
||||||
for j := y; j < y+height; j++ {
|
for j := y; j < y+height; j++ {
|
||||||
for i := x; i < x+width; i++ {
|
for i := x; i < x+width; i++ {
|
||||||
r, g, b, a, err := img.at(i, j)
|
r, g, b, a, err := img.at(graphicsDriver, i, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ func (img *Image) Pixels(x, y, width, height int) ([]byte, error) {
|
|||||||
return bs, nil
|
return bs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) at(x, y int) (byte, byte, byte, byte, error) {
|
func (i *Image) at(graphicsDriver graphicsdriver.Graphics, x, y int) (byte, byte, byte, byte, error) {
|
||||||
if i.backend == nil {
|
if i.backend == nil {
|
||||||
return 0, 0, 0, 0, nil
|
return 0, 0, 0, 0, nil
|
||||||
}
|
}
|
||||||
@ -633,7 +633,7 @@ func (i *Image) at(x, y int) (byte, byte, byte, byte, error) {
|
|||||||
return 0, 0, 0, 0, nil
|
return 0, 0, 0, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return i.backend.restorable.At(x+ox, y+oy)
|
return i.backend.restorable.At(graphicsDriver, x+ox, y+oy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkDisposed marks the image as disposed. The actual operation is deferred.
|
// MarkDisposed marks the image as disposed. The actual operation is deferred.
|
||||||
@ -790,11 +790,11 @@ func (i *Image) allocate(putOnAtlas bool) {
|
|||||||
i.node = n
|
i.node = n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DumpScreenshot(path string, blackbg bool) error {
|
func (i *Image) DumpScreenshot(graphicsDriver graphicsdriver.Graphics, path string, blackbg bool) error {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
return i.backend.restorable.Dump(path, blackbg, image.Rect(paddingSize, paddingSize, paddingSize+i.width, paddingSize+i.height))
|
return i.backend.restorable.Dump(graphicsDriver, path, blackbg, image.Rect(paddingSize, paddingSize, paddingSize+i.width, paddingSize+i.height))
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewScreenFramebufferImage(width, height int) *Image {
|
func NewScreenFramebufferImage(width, height int) *Image {
|
||||||
@ -807,20 +807,20 @@ func NewScreenFramebufferImage(width, height int) *Image {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func EndFrame() error {
|
func EndFrame(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
|
|
||||||
theTemporaryPixels.resetAtFrameEnd()
|
theTemporaryPixels.resetAtFrameEnd()
|
||||||
|
|
||||||
return restorable.ResolveStaleImages()
|
return restorable.ResolveStaleImages(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BeginFrame() error {
|
func BeginFrame(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
initOnce.Do(func() {
|
initOnce.Do(func() {
|
||||||
err = restorable.InitializeGraphicsDriverState()
|
err = restorable.InitializeGraphicsDriverState(graphicsDriver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -828,22 +828,22 @@ func BeginFrame() error {
|
|||||||
panic("atlas: all the images must be not on an atlas before the game starts")
|
panic("atlas: all the images must be not on an atlas before the game starts")
|
||||||
}
|
}
|
||||||
minSize = 1024
|
minSize = 1024
|
||||||
maxSize = restorable.MaxImageSize()
|
maxSize = restorable.MaxImageSize(graphicsDriver)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveDeferred()
|
resolveDeferred()
|
||||||
if err := putImagesOnAtlas(); err != nil {
|
if err := putImagesOnAtlas(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return restorable.RestoreIfNeeded()
|
return restorable.RestoreIfNeeded(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DumpImages(dir string) error {
|
func DumpImages(graphicsDriver graphicsdriver.Graphics, dir string) error {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
return restorable.DumpImages(dir)
|
return restorable.DumpImages(graphicsDriver, dir)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
t "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
t "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -109,7 +110,7 @@ func TestEnsureIsolated(t *testing.T) {
|
|||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
pix, err := img4.Pixels(0, 0, size, size)
|
pix, err := img4.Pixels(ui.GraphicsDriverForTesting(), 0, 0, size, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -189,7 +190,7 @@ func TestReputOnAtlas(t *testing.T) {
|
|||||||
// Use the doubled count since img1 was on a texture atlas and became an isolated image once.
|
// Use the doubled count since img1 was on a texture atlas and became an isolated image once.
|
||||||
// Then, img1 requires longer time to recover to be on a textur atlas again.
|
// Then, img1 requires longer time to recover to be on a textur atlas again.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnAtlas*2; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnAtlas*2; i++ {
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
img0.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{img1}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
img0.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{img1}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
@ -197,11 +198,11 @@ func TestReputOnAtlas(t *testing.T) {
|
|||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pix, err := img1.Pixels(0, 0, size, size)
|
pix, err := img1.Pixels(ui.GraphicsDriverForTesting(), 0, 0, size, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ func TestReputOnAtlas(t *testing.T) {
|
|||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
pix, err = img1.Pixels(0, 0, size, size)
|
pix, err = img1.Pixels(ui.GraphicsDriverForTesting(), 0, 0, size, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -252,7 +253,7 @@ func TestReputOnAtlas(t *testing.T) {
|
|||||||
// Use img1 as a render source, but call ReplacePixels.
|
// Use img1 as a render source, but call ReplacePixels.
|
||||||
// Now use 4x count as img1 became an isolated image again.
|
// Now use 4x count as img1 became an isolated image again.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnAtlas*4; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnAtlas*4; i++ {
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
img1.ReplacePixels(make([]byte, 4*size*size))
|
img1.ReplacePixels(make([]byte, 4*size*size))
|
||||||
@ -261,7 +262,7 @@ func TestReputOnAtlas(t *testing.T) {
|
|||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +274,7 @@ func TestReputOnAtlas(t *testing.T) {
|
|||||||
|
|
||||||
// Use img3 as a render source. As img3 is volatile, img3 is never on an atlas.
|
// Use img3 as a render source. As img3 is volatile, img3 is never on an atlas.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnAtlas*2; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnAtlas*2; i++ {
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
img0.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{img3}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
img0.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{img3}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
@ -313,7 +314,7 @@ func TestExtend(t *testing.T) {
|
|||||||
// Ensure to allocate
|
// Ensure to allocate
|
||||||
img1.ReplacePixels(p1)
|
img1.ReplacePixels(p1)
|
||||||
|
|
||||||
pix0, err := img0.Pixels(0, 0, w0, h0)
|
pix0, err := img0.Pixels(ui.GraphicsDriverForTesting(), 0, 0, w0, h0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -332,7 +333,7 @@ func TestExtend(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pix1, err := img1.Pixels(0, 0, w1, h1)
|
pix1, err := img1.Pixels(ui.GraphicsDriverForTesting(), 0, 0, w1, h1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -379,7 +380,7 @@ func TestReplacePixelsAfterDrawTriangles(t *testing.T) {
|
|||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
dst.ReplacePixels(pix)
|
dst.ReplacePixels(pix)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, w, h)
|
pix, err := dst.Pixels(ui.GraphicsDriverForTesting(), 0, 0, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -426,7 +427,7 @@ func TestSmallImages(t *testing.T) {
|
|||||||
}
|
}
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, w, h)
|
pix, err := dst.Pixels(ui.GraphicsDriverForTesting(), 0, 0, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -474,7 +475,7 @@ func TestLongImages(t *testing.T) {
|
|||||||
}
|
}
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, dstW, dstH)
|
pix, err := dst.Pixels(ui.GraphicsDriverForTesting(), 0, 0, dstW, dstH)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -568,7 +569,7 @@ func TestDisposedAndReputOnAtlas(t *testing.T) {
|
|||||||
|
|
||||||
// Use src as a render source.
|
// Use src as a render source.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnAtlas/2; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnAtlas/2; i++ {
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
@ -584,7 +585,7 @@ func TestDisposedAndReputOnAtlas(t *testing.T) {
|
|||||||
atlas.ResolveDeferredForTesting()
|
atlas.ResolveDeferredForTesting()
|
||||||
|
|
||||||
// Confirm that PutImagesOnAtlasForTesting doesn't panic.
|
// Confirm that PutImagesOnAtlasForTesting doesn't panic.
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,7 +620,7 @@ func TestImageIsNotReputOnAtlasWithoutUsingAsSource(t *testing.T) {
|
|||||||
// Update the count without using src2 as a rendering source.
|
// Update the count without using src2 as a rendering source.
|
||||||
// This should not affect whether src2 is on an atlas or not.
|
// This should not affect whether src2 is on an atlas or not.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnAtlas; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnAtlas; i++ {
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if got, want := src2.IsOnAtlasForTesting(), false; got != want {
|
if got, want := src2.IsOnAtlasForTesting(), false; got != want {
|
||||||
@ -629,7 +630,7 @@ func TestImageIsNotReputOnAtlasWithoutUsingAsSource(t *testing.T) {
|
|||||||
|
|
||||||
// Update the count with using src2 as a rendering source.
|
// Update the count with using src2 as a rendering source.
|
||||||
for i := 0; i < atlas.BaseCountToPutOnAtlas; i++ {
|
for i := 0; i < atlas.BaseCountToPutOnAtlas; i++ {
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src2}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src2}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
@ -638,7 +639,7 @@ func TestImageIsNotReputOnAtlasWithoutUsingAsSource(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := atlas.PutImagesOnAtlasForTesting(); err != nil {
|
if err := atlas.PutImagesOnAtlasForTesting(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if got, want := src2.IsOnAtlasForTesting(), true; got != want {
|
if got, want := src2.IsOnAtlasForTesting(), true; got != want {
|
||||||
|
@ -21,9 +21,9 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/affine"
|
"github.com/hajimehoshi/ebiten/v2/internal/affine"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/atlas"
|
"github.com/hajimehoshi/ebiten/v2/internal/atlas"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShaderFillTwice(t *testing.T) {
|
func TestShaderFillTwice(t *testing.T) {
|
||||||
@ -39,17 +39,19 @@ func TestShaderFillTwice(t *testing.T) {
|
|||||||
Width: w,
|
Width: w,
|
||||||
Height: h,
|
Height: h,
|
||||||
}
|
}
|
||||||
p0 := etesting.ShaderProgramFill(graphicscommand.NeedsInvertY(), 0xff, 0xff, 0xff, 0xff)
|
g := ui.GraphicsDriverForTesting()
|
||||||
|
needsInvertY := g.FramebufferYDirection() != g.NDCYDirection()
|
||||||
|
p0 := etesting.ShaderProgramFill(needsInvertY, 0xff, 0xff, 0xff, 0xff)
|
||||||
s0 := atlas.NewShader(&p0)
|
s0 := atlas.NewShader(&p0)
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, s0, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, s0, nil, false)
|
||||||
|
|
||||||
// Vertices must be recreated (#1755)
|
// Vertices must be recreated (#1755)
|
||||||
vs = quadVertices(w, h, 0, 0, 1)
|
vs = quadVertices(w, h, 0, 0, 1)
|
||||||
p1 := etesting.ShaderProgramFill(graphicscommand.NeedsInvertY(), 0x80, 0x80, 0x80, 0xff)
|
p1 := etesting.ShaderProgramFill(needsInvertY, 0x80, 0x80, 0x80, 0xff)
|
||||||
s1 := atlas.NewShader(&p1)
|
s1 := atlas.NewShader(&p1)
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, s1, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, s1, nil, false)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, w, h)
|
pix, err := dst.Pixels(g, 0, 0, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -81,7 +83,7 @@ func TestImageDrawTwice(t *testing.T) {
|
|||||||
vs = quadVertices(w, h, 0, 0, 1)
|
vs = quadVertices(w, h, 0, 0, 1)
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src1}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*atlas.Image{src1}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, w, h)
|
pix, err := dst.Pixels(ui.GraphicsDriverForTesting(), 0, 0, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,15 @@ type Image struct {
|
|||||||
needsToResolvePixels bool
|
needsToResolvePixels bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func BeginFrame() error {
|
func BeginFrame(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if err := atlas.BeginFrame(); err != nil {
|
if err := atlas.BeginFrame(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return flushDelayedCommands()
|
return flushDelayedCommands()
|
||||||
}
|
}
|
||||||
|
|
||||||
func EndFrame() error {
|
func EndFrame(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
return atlas.EndFrame()
|
return atlas.EndFrame(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImage(width, height int) *Image {
|
func NewImage(width, height int) *Image {
|
||||||
@ -138,7 +138,7 @@ func (i *Image) MarkDisposed() {
|
|||||||
i.img.MarkDisposed()
|
i.img.MarkDisposed()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (img *Image) Pixels(x, y, width, height int) (pix []byte, err error) {
|
func (img *Image) Pixels(graphicsDriver graphicsdriver.Graphics, x, y, width, height int) (pix []byte, err error) {
|
||||||
checkDelayedCommandsFlushed("Pixels")
|
checkDelayedCommandsFlushed("Pixels")
|
||||||
|
|
||||||
if !image.Rect(x, y, x+width, y+height).In(image.Rect(0, 0, img.width, img.height)) {
|
if !image.Rect(x, y, x+width, y+height).In(image.Rect(0, 0, img.width, img.height)) {
|
||||||
@ -148,7 +148,7 @@ func (img *Image) Pixels(x, y, width, height int) (pix []byte, err error) {
|
|||||||
pix = make([]byte, 4*width*height)
|
pix = make([]byte, 4*width*height)
|
||||||
|
|
||||||
if img.pixels == nil {
|
if img.pixels == nil {
|
||||||
pix, err := img.img.Pixels(0, 0, img.width, img.height)
|
pix, err := img.img.Pixels(graphicsDriver, 0, 0, img.width, img.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -161,12 +161,12 @@ func (img *Image) Pixels(x, y, width, height int) (pix []byte, err error) {
|
|||||||
return pix, nil
|
return pix, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DumpScreenshot(name string, blackbg bool) error {
|
func (i *Image) DumpScreenshot(graphicsDriver graphicsdriver.Graphics, name string, blackbg bool) error {
|
||||||
checkDelayedCommandsFlushed("Dump")
|
checkDelayedCommandsFlushed("Dump")
|
||||||
return i.img.DumpScreenshot(name, blackbg)
|
return i.img.DumpScreenshot(graphicsDriver, name, blackbg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) error {
|
func (i *Image) ReplacePixels(graphicsDriver graphicsdriver.Graphics, pix []byte, x, y, width, height int) error {
|
||||||
if l := 4 * width * height; len(pix) != l {
|
if l := 4 * width * height; len(pix) != l {
|
||||||
panic(fmt.Sprintf("buffered: len(pix) was %d but must be %d", len(pix), l))
|
panic(fmt.Sprintf("buffered: len(pix) was %d but must be %d", len(pix), l))
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) error {
|
|||||||
copied := make([]byte, len(pix))
|
copied := make([]byte, len(pix))
|
||||||
copy(copied, pix)
|
copy(copied, pix)
|
||||||
if tryAddDelayedCommand(func() error {
|
if tryAddDelayedCommand(func() error {
|
||||||
i.ReplacePixels(copied, x, y, width, height)
|
i.ReplacePixels(graphicsDriver, copied, x, y, width, height)
|
||||||
return nil
|
return nil
|
||||||
}) {
|
}) {
|
||||||
return nil
|
return nil
|
||||||
@ -194,7 +194,7 @@ func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) error {
|
|||||||
|
|
||||||
// TODO: Can we use (*restorable.Image).ReplacePixels?
|
// TODO: Can we use (*restorable.Image).ReplacePixels?
|
||||||
if i.pixels == nil {
|
if i.pixels == nil {
|
||||||
pix, err := i.img.Pixels(0, 0, i.width, i.height)
|
pix, err := i.img.Pixels(graphicsDriver, 0, 0, i.width, i.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -345,8 +345,8 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FlushCommands flushes the command queue.
|
// FlushCommands flushes the command queue.
|
||||||
func FlushCommands() error {
|
func FlushCommands(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
return theCommandQueue.Flush(graphicsDriver())
|
return theCommandQueue.Flush(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// drawTrianglesCommand represents a drawing command to draw an image on another image.
|
// drawTrianglesCommand represents a drawing command to draw an image on another image.
|
||||||
@ -692,17 +692,17 @@ func (c *newShaderCommand) Exec(graphicsDriver graphicsdriver.Graphics, indexOff
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InitializeGraphicsDriverState initialize the current graphics driver state.
|
// InitializeGraphicsDriverState initialize the current graphics driver state.
|
||||||
func InitializeGraphicsDriverState() (err error) {
|
func InitializeGraphicsDriverState(graphicsDriver graphicsdriver.Graphics) (err error) {
|
||||||
runOnRenderingThread(func() {
|
runOnRenderingThread(func() {
|
||||||
err = graphicsDriver().Initialize()
|
err = graphicsDriver.Initialize()
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetGraphicsDriverState resets the current graphics driver state.
|
// ResetGraphicsDriverState resets the current graphics driver state.
|
||||||
// If the graphics driver doesn't have an API to reset, ResetGraphicsDriverState does nothing.
|
// If the graphics driver doesn't have an API to reset, ResetGraphicsDriverState does nothing.
|
||||||
func ResetGraphicsDriverState() (err error) {
|
func ResetGraphicsDriverState(graphicsDriver graphicsdriver.Graphics) (err error) {
|
||||||
if r, ok := graphicsDriver().(interface{ Reset() error }); ok {
|
if r, ok := graphicsDriver.(interface{ Reset() error }); ok {
|
||||||
runOnRenderingThread(func() {
|
runOnRenderingThread(func() {
|
||||||
err = r.Reset()
|
err = r.Reset()
|
||||||
})
|
})
|
||||||
@ -711,10 +711,10 @@ func ResetGraphicsDriverState() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MaxImageSize returns the maximum size of an image.
|
// MaxImageSize returns the maximum size of an image.
|
||||||
func MaxImageSize() int {
|
func MaxImageSize(graphicsDriver graphicsdriver.Graphics) int {
|
||||||
var size int
|
var size int
|
||||||
runOnRenderingThread(func() {
|
runOnRenderingThread(func() {
|
||||||
size = graphicsDriver().MaxImageSize()
|
size = graphicsDriver.MaxImageSize()
|
||||||
})
|
})
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
// Copyright 2022 The Ebiten Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package graphicscommand
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Drawer interface {
|
|
||||||
Draw(screenScale float64, offsetX, offsetY float64, needsClearingScreen bool, framebufferYDirection graphicsdriver.YDirection, screenClearedEveryFrame, filterEnabled bool) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func Draw(drawer Drawer, screenScale float64, offsetX, offsetY float64, screenClearedEveryFrame, filterEnabled bool) error {
|
|
||||||
return drawer.Draw(screenScale, offsetX, offsetY, graphicsDriver().NeedsClearingScreen(), graphicsDriver().FramebufferYDirection(), screenClearedEveryFrame, filterEnabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Reduce these 'getter' global functions if possible.
|
|
||||||
|
|
||||||
func NeedsInvertY() bool {
|
|
||||||
return graphicsDriver().FramebufferYDirection() != graphicsDriver().NDCYDirection()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NeedsRestoring() bool {
|
|
||||||
return graphicsDriver().NeedsRestoring()
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsGL() bool {
|
|
||||||
return graphicsDriver().IsGL()
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetVsyncEnabled(enabled bool) {
|
|
||||||
graphicsDriver().SetVsyncEnabled(enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetTransparent(transparent bool) {
|
|
||||||
graphicsDriver().SetTransparent(transparent)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetFullscreen(fullscreen bool) {
|
|
||||||
graphicsDriver().SetFullscreen(fullscreen)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetWindow(window uintptr) {
|
|
||||||
if g, ok := graphicsDriver().(interface{ SetWindow(uintptr) }); ok {
|
|
||||||
g.SetWindow(window)
|
|
||||||
}
|
|
||||||
}
|
|
@ -167,14 +167,14 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [gra
|
|||||||
|
|
||||||
// ReadPixels reads the image's pixels.
|
// ReadPixels reads the image's pixels.
|
||||||
// ReadPixels returns an error when an error happens in the graphics driver.
|
// ReadPixels returns an error when an error happens in the graphics driver.
|
||||||
func (i *Image) ReadPixels(buf []byte) error {
|
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, buf []byte) error {
|
||||||
i.resolveBufferedReplacePixels()
|
i.resolveBufferedReplacePixels()
|
||||||
c := &pixelsCommand{
|
c := &pixelsCommand{
|
||||||
img: i,
|
img: i,
|
||||||
result: buf,
|
result: buf,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
if err := theCommandQueue.Flush(graphicsDriver()); err != nil {
|
if err := theCommandQueue.Flush(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -210,7 +210,7 @@ func (i *Image) IsInvalidated() bool {
|
|||||||
// If blackbg is true, any alpha values in the dumped image will be 255.
|
// If blackbg is true, any alpha values in the dumped image will be 255.
|
||||||
//
|
//
|
||||||
// This is for testing usage.
|
// This is for testing usage.
|
||||||
func (i *Image) Dump(path string, blackbg bool, rect image.Rectangle) error {
|
func (i *Image) Dump(graphicsDriver graphicsdriver.Graphics, path string, blackbg bool, rect image.Rectangle) error {
|
||||||
// Screen image cannot be dumped.
|
// Screen image cannot be dumped.
|
||||||
if i.screen {
|
if i.screen {
|
||||||
return nil
|
return nil
|
||||||
@ -224,7 +224,7 @@ func (i *Image) Dump(path string, blackbg bool, rect image.Rectangle) error {
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
pix := make([]byte, 4*i.width*i.height)
|
pix := make([]byte, 4*i.width*i.height)
|
||||||
if err := i.ReadPixels(pix); err != nil {
|
if err := i.ReadPixels(graphicsDriver, pix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -54,7 +55,7 @@ func TestClear(t *testing.T) {
|
|||||||
dst.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeClear, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeClear, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
|
|
||||||
pix := make([]byte, 4*w*h)
|
pix := make([]byte, 4*w*h)
|
||||||
if err := dst.ReadPixels(pix); err != nil {
|
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for j := 0; j < h/2; j++ {
|
for j := 0; j < h/2; j++ {
|
||||||
@ -103,12 +104,14 @@ func TestShader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{clr}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeClear, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{clr}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeClear, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
|
|
||||||
ir := etesting.ShaderProgramFill(graphicscommand.NeedsInvertY(), 0xff, 0, 0, 0xff)
|
g := ui.GraphicsDriverForTesting()
|
||||||
|
needsInvertY := g.FramebufferYDirection() != g.NDCYDirection()
|
||||||
|
ir := etesting.ShaderProgramFill(needsInvertY, 0xff, 0, 0, 0xff)
|
||||||
s := graphicscommand.NewShader(&ir)
|
s := graphicscommand.NewShader(&ir)
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
|
dst.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
|
||||||
|
|
||||||
pix := make([]byte, 4*w*h)
|
pix := make([]byte, 4*w*h)
|
||||||
if err := dst.ReadPixels(pix); err != nil {
|
if err := dst.ReadPixels(g, pix); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for j := 0; j < h; j++ {
|
for j := 0; j < h; j++ {
|
||||||
|
@ -67,20 +67,20 @@ func (m *Mipmap) SetVolatile(volatile bool) {
|
|||||||
m.orig.SetVolatile(volatile)
|
m.orig.SetVolatile(volatile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) DumpScreenshot(name string, blackbg bool) error {
|
func (m *Mipmap) DumpScreenshot(graphicsDriver graphicsdriver.Graphics, name string, blackbg bool) error {
|
||||||
return m.orig.DumpScreenshot(name, blackbg)
|
return m.orig.DumpScreenshot(graphicsDriver, name, blackbg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) ReplacePixels(pix []byte, x, y, width, height int) error {
|
func (m *Mipmap) ReplacePixels(graphicsDriver graphicsdriver.Graphics, pix []byte, x, y, width, height int) error {
|
||||||
if err := m.orig.ReplacePixels(pix, x, y, width, height); err != nil {
|
if err := m.orig.ReplacePixels(graphicsDriver, pix, x, y, width, height); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.disposeMipmaps()
|
m.disposeMipmaps()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) Pixels(x, y, width, height int) ([]byte, error) {
|
func (m *Mipmap) Pixels(graphicsDriver graphicsdriver.Graphics, x, y, width, height int) ([]byte, error) {
|
||||||
return m.orig.Pixels(x, y, width, height)
|
return m.orig.Pixels(graphicsDriver, x, y, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms [][]float32, evenOdd bool, canSkipMipmap bool) {
|
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms [][]float32, evenOdd bool, canSkipMipmap bool) {
|
||||||
|
@ -447,12 +447,12 @@ func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageNum]*Image,
|
|||||||
i.drawTrianglesHistory = append(i.drawTrianglesHistory, item)
|
i.drawTrianglesHistory = append(i.drawTrianglesHistory, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) readPixelsFromGPUIfNeeded() error {
|
func (i *Image) readPixelsFromGPUIfNeeded(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if len(i.drawTrianglesHistory) > 0 || i.stale {
|
if len(i.drawTrianglesHistory) > 0 || i.stale {
|
||||||
if err := graphicscommand.FlushCommands(); err != nil {
|
if err := graphicscommand.FlushCommands(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := i.readPixelsFromGPU(); err != nil {
|
if err := i.readPixelsFromGPU(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,12 +462,12 @@ func (i *Image) readPixelsFromGPUIfNeeded() error {
|
|||||||
// At returns a color value at (x, y).
|
// At returns a color value at (x, y).
|
||||||
//
|
//
|
||||||
// Note that this must not be called until context is available.
|
// Note that this must not be called until context is available.
|
||||||
func (i *Image) At(x, y int) (byte, byte, byte, byte, error) {
|
func (i *Image) At(graphicsDriver graphicsdriver.Graphics, x, y int) (byte, byte, byte, byte, error) {
|
||||||
if x < 0 || y < 0 || i.width <= x || i.height <= y {
|
if x < 0 || y < 0 || i.width <= x || i.height <= y {
|
||||||
return 0, 0, 0, 0, nil
|
return 0, 0, 0, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := i.readPixelsFromGPUIfNeeded(); err != nil {
|
if err := i.readPixelsFromGPUIfNeeded(graphicsDriver); err != nil {
|
||||||
return 0, 0, 0, 0, err
|
return 0, 0, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,9 +496,9 @@ func (i *Image) makeStaleIfDependingOnShader(shader *Shader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state.
|
// readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state.
|
||||||
func (i *Image) readPixelsFromGPU() error {
|
func (i *Image) readPixelsFromGPU(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
pix := make([]byte, 4*i.width*i.height)
|
pix := make([]byte, 4*i.width*i.height)
|
||||||
if err := i.image.ReadPixels(pix); err != nil {
|
if err := i.image.ReadPixels(graphicsDriver, pix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
@ -509,7 +509,7 @@ func (i *Image) readPixelsFromGPU() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolveStale resolves the image's 'stale' state.
|
// resolveStale resolves the image's 'stale' state.
|
||||||
func (i *Image) resolveStale() error {
|
func (i *Image) resolveStale(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if !NeedsRestoring() {
|
if !NeedsRestoring() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -523,7 +523,7 @@ func (i *Image) resolveStale() error {
|
|||||||
if !i.stale {
|
if !i.stale {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return i.readPixelsFromGPU()
|
return i.readPixelsFromGPU(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// dependsOn reports whether the image depends on target.
|
// dependsOn reports whether the image depends on target.
|
||||||
@ -574,7 +574,7 @@ func (i *Image) hasDependency() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore restores *graphicscommand.Image from the pixels using its state.
|
// Restore restores *graphicscommand.Image from the pixels using its state.
|
||||||
func (i *Image) restore() error {
|
func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
w, h := i.width, i.height
|
w, h := i.width, i.height
|
||||||
// Do not dispose the image here. The image should be already disposed.
|
// Do not dispose the image here. The image should be already disposed.
|
||||||
|
|
||||||
@ -627,7 +627,7 @@ func (i *Image) restore() error {
|
|||||||
if len(i.drawTrianglesHistory) > 0 {
|
if len(i.drawTrianglesHistory) > 0 {
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
pix := make([]byte, 4*w*h)
|
pix := make([]byte, 4*w*h)
|
||||||
if err := gimg.ReadPixels(pix); err != nil {
|
if err := gimg.ReadPixels(graphicsDriver, pix); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.basePixels.AddOrReplace(pix, 0, 0, w, h)
|
i.basePixels.AddOrReplace(pix, 0, 0, w, h)
|
||||||
@ -654,16 +654,16 @@ func (i *Image) Dispose() {
|
|||||||
// isInvalidated returns a boolean value indicating whether the image is invalidated.
|
// isInvalidated returns a boolean value indicating whether the image is invalidated.
|
||||||
//
|
//
|
||||||
// If an image is invalidated, GL context is lost and all the images should be restored asap.
|
// If an image is invalidated, GL context is lost and all the images should be restored asap.
|
||||||
func (i *Image) isInvalidated() (bool, error) {
|
func (i *Image) isInvalidated(graphicsDriver graphicsdriver.Graphics) (bool, error) {
|
||||||
// FlushCommands is required because c.offscreen.impl might not have an actual texture.
|
// FlushCommands is required because c.offscreen.impl might not have an actual texture.
|
||||||
if err := graphicscommand.FlushCommands(); err != nil {
|
if err := graphicscommand.FlushCommands(graphicsDriver); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return i.image.IsInvalidated(), nil
|
return i.image.IsInvalidated(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Dump(path string, blackbg bool, rect image.Rectangle) error {
|
func (i *Image) Dump(graphicsDriver graphicsdriver.Graphics, path string, blackbg bool, rect image.Rectangle) error {
|
||||||
return i.image.Dump(path, blackbg, rect)
|
return i.image.Dump(graphicsDriver, path, blackbg, rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) clearDrawTrianglesHistory() {
|
func (i *Image) clearDrawTrianglesHistory() {
|
||||||
|
@ -26,12 +26,11 @@ import (
|
|||||||
// forceRestoring reports whether restoring forcely happens or not.
|
// forceRestoring reports whether restoring forcely happens or not.
|
||||||
var forceRestoring = false
|
var forceRestoring = false
|
||||||
|
|
||||||
|
var needsRestoringByGraphicsDriver bool
|
||||||
|
|
||||||
// NeedsRestoring reports whether restoring process works or not.
|
// NeedsRestoring reports whether restoring process works or not.
|
||||||
func NeedsRestoring() bool {
|
func NeedsRestoring() bool {
|
||||||
if forceRestoring {
|
return forceRestoring || needsRestoringByGraphicsDriver
|
||||||
return true
|
|
||||||
}
|
|
||||||
return graphicscommand.NeedsRestoring()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableRestoringForTesting forces to enable restoring for testing.
|
// EnableRestoringForTesting forces to enable restoring for testing.
|
||||||
@ -57,7 +56,7 @@ var theImages = &images{
|
|||||||
// all stale images.
|
// all stale images.
|
||||||
//
|
//
|
||||||
// ResolveStaleImages is intended to be called at the end of a frame.
|
// ResolveStaleImages is intended to be called at the end of a frame.
|
||||||
func ResolveStaleImages() error {
|
func ResolveStaleImages(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if debug.IsDebug {
|
if debug.IsDebug {
|
||||||
debug.Logf("Internal image sizes:\n")
|
debug.Logf("Internal image sizes:\n")
|
||||||
imgs := make([]*graphicscommand.Image, 0, len(theImages.images))
|
imgs := make([]*graphicscommand.Image, 0, len(theImages.images))
|
||||||
@ -67,19 +66,19 @@ func ResolveStaleImages() error {
|
|||||||
graphicscommand.LogImagesInfo(imgs)
|
graphicscommand.LogImagesInfo(imgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := graphicscommand.FlushCommands(); err != nil {
|
if err := graphicscommand.FlushCommands(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !NeedsRestoring() {
|
if !NeedsRestoring() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return theImages.resolveStaleImages()
|
return theImages.resolveStaleImages(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RestoreIfNeeded restores the images.
|
// RestoreIfNeeded restores the images.
|
||||||
//
|
//
|
||||||
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
|
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
|
||||||
func RestoreIfNeeded() error {
|
func RestoreIfNeeded(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if !NeedsRestoring() {
|
if !NeedsRestoring() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -98,7 +97,7 @@ func RestoreIfNeeded() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
r, err = img.isInvalidated()
|
r, err = img.isInvalidated(graphicsDriver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -111,22 +110,22 @@ func RestoreIfNeeded() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := graphicscommand.ResetGraphicsDriverState()
|
err := graphicscommand.ResetGraphicsDriverState(graphicsDriver)
|
||||||
if err == graphicsdriver.GraphicsNotReady {
|
if err == graphicsdriver.GraphicsNotReady {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return theImages.restore()
|
return theImages.restore(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DumpImages dumps all the current images to the specified directory.
|
// DumpImages dumps all the current images to the specified directory.
|
||||||
//
|
//
|
||||||
// This is for testing usage.
|
// This is for testing usage.
|
||||||
func DumpImages(dir string) error {
|
func DumpImages(graphicsDriver graphicsdriver.Graphics, dir string) error {
|
||||||
for img := range theImages.images {
|
for img := range theImages.images {
|
||||||
if err := img.Dump(filepath.Join(dir, "*.png"), false, image.Rect(0, 0, img.width, img.height)); err != nil {
|
if err := img.Dump(graphicsDriver, filepath.Join(dir, "*.png"), false, image.Rect(0, 0, img.width, img.height)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,10 +153,10 @@ func (i *images) removeShader(shader *Shader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolveStaleImages resolves stale images.
|
// resolveStaleImages resolves stale images.
|
||||||
func (i *images) resolveStaleImages() error {
|
func (i *images) resolveStaleImages(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
i.lastTarget = nil
|
i.lastTarget = nil
|
||||||
for img := range i.images {
|
for img := range i.images {
|
||||||
if err := img.resolveStale(); err != nil {
|
if err := img.resolveStale(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +193,7 @@ func (i *images) makeStaleIfDependingOnShader(shader *Shader) {
|
|||||||
// restore restores the images.
|
// restore restores the images.
|
||||||
//
|
//
|
||||||
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
|
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
|
||||||
func (i *images) restore() error {
|
func (i *images) restore(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
if !NeedsRestoring() {
|
if !NeedsRestoring() {
|
||||||
panic("restorable: restore cannot be called when restoring is disabled")
|
panic("restorable: restore cannot be called when restoring is disabled")
|
||||||
}
|
}
|
||||||
@ -267,7 +266,7 @@ func (i *images) restore() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, img := range sorted {
|
for _, img := range sorted {
|
||||||
if err := img.restore(); err != nil {
|
if err := img.restore(graphicsDriver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,14 +279,15 @@ func (i *images) restore() error {
|
|||||||
var graphicsDriverInitialized bool
|
var graphicsDriverInitialized bool
|
||||||
|
|
||||||
// InitializeGraphicsDriverState initializes the graphics driver state.
|
// InitializeGraphicsDriverState initializes the graphics driver state.
|
||||||
func InitializeGraphicsDriverState() error {
|
func InitializeGraphicsDriverState(graphicsDriver graphicsdriver.Graphics) error {
|
||||||
graphicsDriverInitialized = true
|
graphicsDriverInitialized = true
|
||||||
return graphicscommand.InitializeGraphicsDriverState()
|
needsRestoringByGraphicsDriver = graphicsDriver.NeedsRestoring()
|
||||||
|
return graphicscommand.InitializeGraphicsDriverState(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaxImageSize returns the maximum size of an image.
|
// MaxImageSize returns the maximum size of an image.
|
||||||
func MaxImageSize() int {
|
func MaxImageSize(graphicsDriver graphicsdriver.Graphics) int {
|
||||||
return graphicscommand.MaxImageSize()
|
return graphicscommand.MaxImageSize(graphicsDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnContextLost is called when the context lost is detected in an explicit way.
|
// OnContextLost is called when the context lost is detected in an explicit way.
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/restorable"
|
"github.com/hajimehoshi/ebiten/v2/internal/restorable"
|
||||||
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -61,10 +62,10 @@ func TestRestore(t *testing.T) {
|
|||||||
|
|
||||||
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
|
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
|
||||||
img0.ReplacePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, 1, 1)
|
img0.ReplacePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, 1, 1)
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := clr0
|
want := clr0
|
||||||
@ -80,10 +81,10 @@ func TestRestoreWithoutDraw(t *testing.T) {
|
|||||||
|
|
||||||
// If there is no drawing command on img0, img0 is cleared when restored.
|
// If there is no drawing command on img0, img0 is cleared when restored.
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,10 +141,10 @@ func TestRestoreChain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*restorable.Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*restorable.Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
}
|
}
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := clr
|
want := clr
|
||||||
@ -192,10 +193,10 @@ func TestRestoreChain2(t *testing.T) {
|
|||||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*restorable.Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*restorable.Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for i, img := range imgs {
|
for i, img := range imgs {
|
||||||
@ -239,10 +240,10 @@ func TestRestoreOverrideSource(t *testing.T) {
|
|||||||
img3.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img2}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img3.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img2}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
img0.ReplacePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, 0, 0, w, h)
|
img0.ReplacePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, 0, 0, w, h)
|
||||||
img1.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img1.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -341,10 +342,10 @@ func TestRestoreComplexGraph(t *testing.T) {
|
|||||||
img7.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img2}, offsets, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img7.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img2}, offsets, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
vs = quadVertices(w, h, 2, 0)
|
vs = quadVertices(w, h, 2, 0)
|
||||||
img7.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img3}, offsets, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img7.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img3}, offsets, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -440,10 +441,10 @@ func TestRestoreRecursive(t *testing.T) {
|
|||||||
}
|
}
|
||||||
img1.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 1, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img1.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 1, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
img0.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 1, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img0.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 1, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -488,7 +489,7 @@ func TestReplacePixels(t *testing.T) {
|
|||||||
// Check the region (5, 7)-(9, 11). Outside state is indeterministic.
|
// Check the region (5, 7)-(9, 11). Outside state is indeterministic.
|
||||||
for j := 7; j < 11; j++ {
|
for j := 7; j < 11; j++ {
|
||||||
for i := 5; i < 9; i++ {
|
for i := 5; i < 9; i++ {
|
||||||
r, g, b, a, err := img.At(i, j)
|
r, g, b, a, err := img.At(ui.GraphicsDriverForTesting(), i, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -499,15 +500,15 @@ func TestReplacePixels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for j := 7; j < 11; j++ {
|
for j := 7; j < 11; j++ {
|
||||||
for i := 5; i < 9; i++ {
|
for i := 5; i < 9; i++ {
|
||||||
r, g, b, a, err := img.At(i, j)
|
r, g, b, a, err := img.At(ui.GraphicsDriverForTesting(), i, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -542,13 +543,13 @@ func TestDrawTrianglesAndReplacePixels(t *testing.T) {
|
|||||||
img1.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img1.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
r, g, b, a, err := img1.At(0, 0)
|
r, g, b, a, err := img1.At(ui.GraphicsDriverForTesting(), 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -586,13 +587,13 @@ func TestDispose(t *testing.T) {
|
|||||||
img0.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
img0.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, nil, nil, false)
|
||||||
img1.Dispose()
|
img1.Dispose()
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
r, g, b, a, err := img0.At(0, 0)
|
r, g, b, a, err := img0.At(ui.GraphicsDriverForTesting(), 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -718,10 +719,10 @@ func TestReplacePixelsOnly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := color.RGBA{1, 2, 3, 4}
|
want := color.RGBA{1, 2, 3, 4}
|
||||||
@ -762,7 +763,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
|||||||
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
||||||
// stale.
|
// stale.
|
||||||
want := byte(0xff)
|
want := byte(0xff)
|
||||||
got, _, _, _, err := dst.At(0, 0)
|
got, _, _, _, err := dst.At(ui.GraphicsDriverForTesting(), 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -836,7 +837,7 @@ func TestExtend(t *testing.T) {
|
|||||||
|
|
||||||
for j := 0; j < h*2; j++ {
|
for j := 0; j < h*2; j++ {
|
||||||
for i := 0; i < w*2; i++ {
|
for i := 0; i < w*2; i++ {
|
||||||
got, _, _, _, err := extended.At(i, j)
|
got, _, _, _, err := extended.At(ui.GraphicsDriverForTesting(), i, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -892,21 +893,21 @@ func TestMutateSlices(t *testing.T) {
|
|||||||
for i := range is {
|
for i := range is {
|
||||||
is[i] = 0
|
is[i] = 0
|
||||||
}
|
}
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := 0; j < h; j++ {
|
for j := 0; j < h; j++ {
|
||||||
for i := 0; i < w; i++ {
|
for i := 0; i < w; i++ {
|
||||||
r, g, b, a, err := src.At(i, j)
|
r, g, b, a, err := src.At(ui.GraphicsDriverForTesting(), i, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := color.RGBA{r, g, b, a}
|
want := color.RGBA{r, g, b, a}
|
||||||
r, g, b, a, err = dst.At(i, j)
|
r, g, b, a, err = dst.At(ui.GraphicsDriverForTesting(), i, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,17 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/affine"
|
"github.com/hajimehoshi/ebiten/v2/internal/affine"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/restorable"
|
"github.com/hajimehoshi/ebiten/v2/internal/restorable"
|
||||||
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
etesting "github.com/hajimehoshi/ebiten/v2/internal/testing"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func needsInvertY() bool {
|
||||||
|
g := ui.GraphicsDriverForTesting()
|
||||||
|
return g.FramebufferYDirection() != g.NDCYDirection()
|
||||||
|
}
|
||||||
|
|
||||||
func clearImage(img *restorable.Image, w, h int) {
|
func clearImage(img *restorable.Image, w, h int) {
|
||||||
emptyImage := restorable.NewImage(3, 3)
|
emptyImage := restorable.NewImage(3, 3)
|
||||||
defer emptyImage.Dispose()
|
defer emptyImage.Dispose()
|
||||||
@ -58,7 +63,7 @@ func TestShader(t *testing.T) {
|
|||||||
img := restorable.NewImage(1, 1)
|
img := restorable.NewImage(1, 1)
|
||||||
defer img.Dispose()
|
defer img.Dispose()
|
||||||
|
|
||||||
ir := etesting.ShaderProgramFill(graphicscommand.NeedsInvertY(), 0xff, 0, 0, 0xff)
|
ir := etesting.ShaderProgramFill(needsInvertY(), 0xff, 0, 0, 0xff)
|
||||||
s := restorable.NewShader(&ir)
|
s := restorable.NewShader(&ir)
|
||||||
dr := graphicsdriver.Region{
|
dr := graphicsdriver.Region{
|
||||||
X: 0,
|
X: 0,
|
||||||
@ -68,10 +73,10 @@ func TestShader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
img.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
|
img.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +98,7 @@ func TestShaderChain(t *testing.T) {
|
|||||||
|
|
||||||
imgs[0].ReplacePixels([]byte{0xff, 0, 0, 0xff}, 0, 0, 1, 1)
|
imgs[0].ReplacePixels([]byte{0xff, 0, 0, 0xff}, 0, 0, 1, 1)
|
||||||
|
|
||||||
ir := etesting.ShaderProgramImages(graphicscommand.NeedsInvertY(), 1)
|
ir := etesting.ShaderProgramImages(needsInvertY(), 1)
|
||||||
s := restorable.NewShader(&ir)
|
s := restorable.NewShader(&ir)
|
||||||
for i := 0; i < num-1; i++ {
|
for i := 0; i < num-1; i++ {
|
||||||
dr := graphicsdriver.Region{
|
dr := graphicsdriver.Region{
|
||||||
@ -105,10 +110,10 @@ func TestShaderChain(t *testing.T) {
|
|||||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*restorable.Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
|
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*restorable.Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, graphicsdriver.CompositeModeCopy, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, dr, graphicsdriver.Region{}, s, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +137,7 @@ func TestShaderMultipleSources(t *testing.T) {
|
|||||||
|
|
||||||
dst := restorable.NewImage(1, 1)
|
dst := restorable.NewImage(1, 1)
|
||||||
|
|
||||||
ir := etesting.ShaderProgramImages(graphicscommand.NeedsInvertY(), 3)
|
ir := etesting.ShaderProgramImages(needsInvertY(), 3)
|
||||||
s := restorable.NewShader(&ir)
|
s := restorable.NewShader(&ir)
|
||||||
var offsets [graphics.ShaderImageNum - 1][2]float32
|
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||||
dr := graphicsdriver.Region{
|
dr := graphicsdriver.Region{
|
||||||
@ -146,10 +151,10 @@ func TestShaderMultipleSources(t *testing.T) {
|
|||||||
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
||||||
clearImage(srcs[0], 1, 1)
|
clearImage(srcs[0], 1, 1)
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +176,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
|
|||||||
|
|
||||||
dst := restorable.NewImage(1, 1)
|
dst := restorable.NewImage(1, 1)
|
||||||
|
|
||||||
ir := etesting.ShaderProgramImages(graphicscommand.NeedsInvertY(), 3)
|
ir := etesting.ShaderProgramImages(needsInvertY(), 3)
|
||||||
s := restorable.NewShader(&ir)
|
s := restorable.NewShader(&ir)
|
||||||
offsets := [graphics.ShaderImageNum - 1][2]float32{
|
offsets := [graphics.ShaderImageNum - 1][2]float32{
|
||||||
{1, 0},
|
{1, 0},
|
||||||
@ -188,10 +193,10 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
|
|||||||
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
||||||
clearImage(srcs[0], 3, 1)
|
clearImage(srcs[0], 3, 1)
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +211,7 @@ func TestShaderDispose(t *testing.T) {
|
|||||||
img := restorable.NewImage(1, 1)
|
img := restorable.NewImage(1, 1)
|
||||||
defer img.Dispose()
|
defer img.Dispose()
|
||||||
|
|
||||||
ir := etesting.ShaderProgramFill(graphicscommand.NeedsInvertY(), 0xff, 0, 0, 0xff)
|
ir := etesting.ShaderProgramFill(needsInvertY(), 0xff, 0, 0, 0xff)
|
||||||
s := restorable.NewShader(&ir)
|
s := restorable.NewShader(&ir)
|
||||||
dr := graphicsdriver.Region{
|
dr := graphicsdriver.Region{
|
||||||
X: 0,
|
X: 0,
|
||||||
@ -220,10 +225,10 @@ func TestShaderDispose(t *testing.T) {
|
|||||||
// stale.
|
// stale.
|
||||||
s.Dispose()
|
s.Dispose()
|
||||||
|
|
||||||
if err := restorable.ResolveStaleImages(); err != nil {
|
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := restorable.RestoreIfNeeded(); err != nil {
|
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/clock"
|
"github.com/hajimehoshi/ebiten/v2/internal/clock"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/debug"
|
"github.com/hajimehoshi/ebiten/v2/internal/debug"
|
||||||
graphicspkg "github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
graphicspkg "github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
||||||
)
|
)
|
||||||
@ -83,7 +82,7 @@ func (c *contextImpl) updateFrameImpl(updateCount int, outsideWidth, outsideHeig
|
|||||||
|
|
||||||
debug.Logf("----\n")
|
debug.Logf("----\n")
|
||||||
|
|
||||||
if err := buffered.BeginFrame(); err != nil {
|
if err := buffered.BeginFrame(graphicsDriver()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,14 +110,14 @@ func (c *contextImpl) updateFrameImpl(updateCount int, outsideWidth, outsideHeig
|
|||||||
|
|
||||||
// Draw the game.
|
// Draw the game.
|
||||||
screenScale, offsetX, offsetY := c.screenScaleAndOffsets(deviceScaleFactor)
|
screenScale, offsetX, offsetY := c.screenScaleAndOffsets(deviceScaleFactor)
|
||||||
if err := graphicscommand.Draw(c.game, screenScale, offsetX, offsetY, theGlobalState.isScreenClearedEveryFrame(), theGlobalState.isScreenFilterEnabled()); err != nil {
|
if err := c.game.Draw(screenScale, offsetX, offsetY, graphicsDriver().NeedsClearingScreen(), graphicsDriver().FramebufferYDirection(), theGlobalState.isScreenClearedEveryFrame(), theGlobalState.isScreenFilterEnabled()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// All the vertices data are consumed at the end of the frame, and the data backend can be
|
// All the vertices data are consumed at the end of the frame, and the data backend can be
|
||||||
// available after that. Until then, lock the vertices backend.
|
// available after that. Until then, lock the vertices backend.
|
||||||
return graphicspkg.LockAndResetVertices(func() error {
|
return graphicspkg.LockAndResetVertices(func() error {
|
||||||
if err := buffered.EndFrame(); err != nil {
|
if err := buffered.EndFrame(graphicsDriver()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -12,17 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build android || ios
|
package ui
|
||||||
// +build android ios
|
|
||||||
|
|
||||||
package graphicscommand
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/mobile/gl"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetGomobileGLContext(ctx gl.Context) {
|
func GraphicsDriverForTesting() graphicsdriver.Graphics {
|
||||||
graphicsDriver().(*opengl.Graphics).SetGomobileGLContext(ctx)
|
return graphicsDriver()
|
||||||
}
|
}
|
@ -15,7 +15,7 @@
|
|||||||
//go:build !ios && !ebitengl && !ebitencbackend
|
//go:build !ios && !ebitengl && !ebitencbackend
|
||||||
// +build !ios,!ebitengl,!ebitencbackend
|
// +build !ios,!ebitengl,!ebitencbackend
|
||||||
|
|
||||||
package graphicscommand
|
package ui
|
||||||
|
|
||||||
// #cgo CFLAGS: -x objective-c
|
// #cgo CFLAGS: -x objective-c
|
||||||
// #cgo LDFLAGS: -framework Foundation
|
// #cgo LDFLAGS: -framework Foundation
|
@ -15,7 +15,7 @@
|
|||||||
//go:build ios && !ebitengl && !ebitencbackend
|
//go:build ios && !ebitengl && !ebitencbackend
|
||||||
// +build ios,!ebitengl,!ebitencbackend
|
// +build ios,!ebitengl,!ebitencbackend
|
||||||
|
|
||||||
package graphicscommand
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
@ -15,7 +15,7 @@
|
|||||||
//go:build ios && !ebitengl && !ebitencbackend
|
//go:build ios && !ebitengl && !ebitencbackend
|
||||||
// +build ios,!ebitengl,!ebitencbackend
|
// +build ios,!ebitengl,!ebitencbackend
|
||||||
|
|
||||||
package graphicscommand
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
@ -15,7 +15,7 @@
|
|||||||
//go:build !darwin || ebitencbackend || ebitengl
|
//go:build !darwin || ebitencbackend || ebitengl
|
||||||
// +build !darwin ebitencbackend ebitengl
|
// +build !darwin ebitencbackend ebitengl
|
||||||
|
|
||||||
package graphicscommand
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
@ -16,6 +16,7 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/affine"
|
"github.com/hajimehoshi/ebiten/v2/internal/affine"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/atlas"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/mipmap"
|
"github.com/hajimehoshi/ebiten/v2/internal/mipmap"
|
||||||
@ -60,15 +61,15 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) error {
|
func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) error {
|
||||||
return i.mipmap.ReplacePixels(pix, x, y, width, height)
|
return i.mipmap.ReplacePixels(graphicsDriver(), pix, x, y, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Pixels(x, y, width, height int) ([]byte, error) {
|
func (i *Image) Pixels(x, y, width, height int) ([]byte, error) {
|
||||||
return i.mipmap.Pixels(x, y, width, height)
|
return i.mipmap.Pixels(graphicsDriver(), x, y, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DumpScreenshot(name string, blackbg bool) error {
|
func (i *Image) DumpScreenshot(name string, blackbg bool) error {
|
||||||
return i.mipmap.DumpScreenshot(name, blackbg)
|
return i.mipmap.DumpScreenshot(graphicsDriver(), name, blackbg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) SetIndependent(independent bool) {
|
func (i *Image) SetIndependent(independent bool) {
|
||||||
@ -78,3 +79,7 @@ func (i *Image) SetIndependent(independent bool) {
|
|||||||
func (i *Image) SetVolatile(volatile bool) {
|
func (i *Image) SetVolatile(volatile bool) {
|
||||||
i.mipmap.SetVolatile(volatile)
|
i.mipmap.SetVolatile(volatile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DumpImages(dir string) error {
|
||||||
|
return atlas.DumpImages(graphicsDriver(), dir)
|
||||||
|
}
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/mipmap"
|
"github.com/hajimehoshi/ebiten/v2/internal/mipmap"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shader"
|
"github.com/hajimehoshi/ebiten/v2/internal/shader"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||||
@ -117,7 +116,7 @@ func NewShader(src []byte) (*Shader, error) {
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
buf.Write(src)
|
buf.Write(src)
|
||||||
buf.WriteString(shaderSuffix)
|
buf.WriteString(shaderSuffix)
|
||||||
if graphicscommand.NeedsInvertY() {
|
if graphicsDriver().FramebufferYDirection() != graphicsDriver().NDCYDirection() {
|
||||||
buf.WriteString(`
|
buf.WriteString(`
|
||||||
func __vertex(position vec2, texCoord vec2, color vec4) (vec4, vec2, vec4) {
|
func __vertex(position vec2, texCoord vec2, color vec4) (vec4, vec2, vec4) {
|
||||||
return mat4(
|
return mat4(
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/devicescale"
|
"github.com/hajimehoshi/ebiten/v2/internal/devicescale"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/glfw"
|
"github.com/hajimehoshi/ebiten/v2/internal/glfw"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||||
)
|
)
|
||||||
@ -668,7 +667,7 @@ func (u *UserInterface) createWindow(width, height int) error {
|
|||||||
// Ensure to consume this callback.
|
// Ensure to consume this callback.
|
||||||
u.waitForFramebufferSizeCallback(u.window, nil)
|
u.waitForFramebufferSizeCallback(u.window, nil)
|
||||||
|
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
u.window.MakeContextCurrent()
|
u.window.MakeContextCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,7 +721,7 @@ func (u *UserInterface) registerWindowSetSizeCallback() {
|
|||||||
u.err = err
|
u.err = err
|
||||||
}
|
}
|
||||||
|
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
u.swapBuffers()
|
u.swapBuffers()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -816,7 +815,7 @@ event:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) init() error {
|
func (u *UserInterface) init() error {
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI)
|
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI)
|
||||||
glfw.WindowHint(glfw.ContextVersionMajor, 2)
|
glfw.WindowHint(glfw.ContextVersionMajor, 2)
|
||||||
glfw.WindowHint(glfw.ContextVersionMinor, 1)
|
glfw.WindowHint(glfw.ContextVersionMinor, 1)
|
||||||
@ -837,7 +836,7 @@ func (u *UserInterface) init() error {
|
|||||||
transparent = glfw.True
|
transparent = glfw.True
|
||||||
}
|
}
|
||||||
glfw.WindowHint(glfw.TransparentFramebuffer, transparent)
|
glfw.WindowHint(glfw.TransparentFramebuffer, transparent)
|
||||||
graphicscommand.SetTransparent(u.isInitScreenTransparent())
|
graphicsDriver().SetTransparent(u.isInitScreenTransparent())
|
||||||
|
|
||||||
// Before creating a window, set it unresizable no matter what u.isInitWindowResizable() is (#1987).
|
// Before creating a window, set it unresizable no matter what u.isInitWindowResizable() is (#1987).
|
||||||
// Making the window resizable here doesn't work correctly when switching to enable resizing.
|
// Making the window resizable here doesn't work correctly when switching to enable resizing.
|
||||||
@ -889,7 +888,9 @@ func (u *UserInterface) init() error {
|
|||||||
|
|
||||||
u.window.Show()
|
u.window.Show()
|
||||||
|
|
||||||
graphicscommand.SetWindow(u.nativeWindow())
|
if g, ok := graphicsDriver().(interface{ SetWindow(uintptr) }); ok {
|
||||||
|
g.SetWindow(u.nativeWindow())
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1066,7 +1067,7 @@ func (u *UserInterface) loop() error {
|
|||||||
// swapBuffers also checks IsGL, so this condition is redundant.
|
// swapBuffers also checks IsGL, so this condition is redundant.
|
||||||
// However, (*thread).Call is not good for performance due to channels.
|
// However, (*thread).Call is not good for performance due to channels.
|
||||||
// Let's avoid this whenever possible (#1367).
|
// Let's avoid this whenever possible (#1367).
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
u.t.Call(u.swapBuffers)
|
u.t.Call(u.swapBuffers)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,7 +1089,7 @@ func (u *UserInterface) loop() error {
|
|||||||
|
|
||||||
// swapBuffers must be called from the main thread.
|
// swapBuffers must be called from the main thread.
|
||||||
func (u *UserInterface) swapBuffers() {
|
func (u *UserInterface) swapBuffers() {
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
u.window.SwapBuffers()
|
u.window.SwapBuffers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1145,7 +1146,7 @@ func (u *UserInterface) adjustWindowSizeBasedOnSizeLimitsInDIP(width, height int
|
|||||||
func (u *UserInterface) setWindowSizeInDIP(width, height int, fullscreen bool) {
|
func (u *UserInterface) setWindowSizeInDIP(width, height int, fullscreen bool) {
|
||||||
width, height = u.adjustWindowSizeBasedOnSizeLimitsInDIP(width, height)
|
width, height = u.adjustWindowSizeBasedOnSizeLimitsInDIP(width, height)
|
||||||
|
|
||||||
graphicscommand.SetFullscreen(fullscreen)
|
graphicsDriver().SetFullscreen(fullscreen)
|
||||||
|
|
||||||
scale := u.deviceScaleFactor(u.currentMonitor())
|
scale := u.deviceScaleFactor(u.currentMonitor())
|
||||||
if u.windowWidthInDIP == width && u.windowHeightInDIP == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == scale {
|
if u.windowWidthInDIP == width && u.windowHeightInDIP == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == scale {
|
||||||
@ -1219,7 +1220,7 @@ func (u *UserInterface) setWindowSizeInDIPImpl(width, height int, fullscreen boo
|
|||||||
|
|
||||||
// Swapping buffer is necesary to prevent the image lag (#1004).
|
// Swapping buffer is necesary to prevent the image lag (#1004).
|
||||||
// TODO: This might not work when vsync is disabled.
|
// TODO: This might not work when vsync is disabled.
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
glfw.PollEvents()
|
glfw.PollEvents()
|
||||||
u.swapBuffers()
|
u.swapBuffers()
|
||||||
}
|
}
|
||||||
@ -1266,7 +1267,7 @@ func (u *UserInterface) setWindowSizeInDIPImpl(width, height int, fullscreen boo
|
|||||||
|
|
||||||
// updateVsync must be called on the main thread.
|
// updateVsync must be called on the main thread.
|
||||||
func (u *UserInterface) updateVsync() {
|
func (u *UserInterface) updateVsync() {
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
// SwapInterval is affected by the current monitor of the window.
|
// SwapInterval is affected by the current monitor of the window.
|
||||||
// This needs to be called at least after SetMonitor.
|
// This needs to be called at least after SetMonitor.
|
||||||
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
|
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
|
||||||
@ -1280,7 +1281,7 @@ func (u *UserInterface) updateVsync() {
|
|||||||
glfw.SwapInterval(0)
|
glfw.SwapInterval(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphicscommand.SetVsyncEnabled(u.fpsMode == FPSModeVsyncOn)
|
graphicsDriver().SetVsyncEnabled(u.fpsMode == FPSModeVsyncOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentMonitor returns the current active monitor.
|
// currentMonitor returns the current active monitor.
|
||||||
|
@ -227,7 +227,6 @@ import "C"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/glfw"
|
"github.com/hajimehoshi/ebiten/v2/internal/glfw"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// clearVideoModeScaleCache must be called from the main thread.
|
// clearVideoModeScaleCache must be called from the main thread.
|
||||||
@ -317,7 +316,7 @@ func (u *UserInterface) setNativeFullscreen(fullscreen bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) adjustViewSize() {
|
func (u *UserInterface) adjustViewSize() {
|
||||||
if graphicscommand.IsGL() {
|
if graphicsDriver().IsGL() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
C.adjustViewSize(C.uintptr_t(u.window.GetCocoaWindow()))
|
C.adjustViewSize(C.uintptr_t(u.window.GetCocoaWindow()))
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/devicescale"
|
"github.com/hajimehoshi/ebiten/v2/internal/devicescale"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepad"
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepad"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/restorable"
|
"github.com/hajimehoshi/ebiten/v2/internal/restorable"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||||
@ -276,7 +277,7 @@ func (u *UserInterface) run(game Game, mainloop bool) (err error) {
|
|||||||
// When mainloop is true, gomobile-build is used. In this case, GL functions must be called via
|
// When mainloop is true, gomobile-build is used. In this case, GL functions must be called via
|
||||||
// gl.Context so that they are called on the appropriate thread.
|
// gl.Context so that they are called on the appropriate thread.
|
||||||
ctx := <-glContextCh
|
ctx := <-glContextCh
|
||||||
graphicscommand.SetGomobileGLContext(ctx)
|
graphicsDriver().(*opengl.Graphics).SetGomobileGLContext(ctx)
|
||||||
} else {
|
} else {
|
||||||
u.t = thread.NewOSThread()
|
u.t = thread.NewOSThread()
|
||||||
graphicscommand.SetRenderingThread(u.t)
|
graphicscommand.SetRenderingThread(u.t)
|
||||||
|
Loading…
Reference in New Issue
Block a user