mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
parent
5705dc79fb
commit
ddfb8adbc4
@ -325,7 +325,7 @@ type Graphics struct {
|
|||||||
|
|
||||||
transparent bool
|
transparent bool
|
||||||
maxImageSize int
|
maxImageSize int
|
||||||
tmpTexture mtl.Texture
|
tmpTextures []mtl.Texture
|
||||||
|
|
||||||
pool unsafe.Pointer
|
pool unsafe.Pointer
|
||||||
}
|
}
|
||||||
@ -343,7 +343,7 @@ func (g *Graphics) Begin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) End() {
|
func (g *Graphics) End() {
|
||||||
g.flushIfNeeded(false, true)
|
g.flushIfNeeded(true)
|
||||||
g.screenDrawable = ca.MetalDrawable{}
|
g.screenDrawable = ca.MetalDrawable{}
|
||||||
C.releaseAutoreleasePool(g.pool)
|
C.releaseAutoreleasePool(g.pool)
|
||||||
g.pool = nil
|
g.pool = nil
|
||||||
@ -371,7 +371,7 @@ func (g *Graphics) SetVertices(vertices []float32, indices []uint16) {
|
|||||||
g.ib = g.view.getMTLDevice().MakeBufferWithBytes(unsafe.Pointer(&indices[0]), unsafe.Sizeof(indices[0])*uintptr(len(indices)), resourceStorageMode)
|
g.ib = g.view.getMTLDevice().MakeBufferWithBytes(unsafe.Pointer(&indices[0]), unsafe.Sizeof(indices[0])*uintptr(len(indices)), resourceStorageMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) flushIfNeeded(wait bool, present bool) {
|
func (g *Graphics) flushIfNeeded(present bool) {
|
||||||
if g.cb == (mtl.CommandBuffer{}) {
|
if g.cb == (mtl.CommandBuffer{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -380,9 +380,11 @@ func (g *Graphics) flushIfNeeded(wait bool, present bool) {
|
|||||||
g.cb.PresentDrawable(g.screenDrawable)
|
g.cb.PresentDrawable(g.screenDrawable)
|
||||||
}
|
}
|
||||||
g.cb.Commit()
|
g.cb.Commit()
|
||||||
if wait {
|
|
||||||
g.cb.WaitUntilCompleted()
|
for _, t := range g.tmpTextures {
|
||||||
|
t.Release()
|
||||||
}
|
}
|
||||||
|
g.tmpTextures = nil
|
||||||
|
|
||||||
g.cb = mtl.CommandBuffer{}
|
g.cb = mtl.CommandBuffer{}
|
||||||
}
|
}
|
||||||
@ -863,7 +865,7 @@ func (i *Image) Sync() <-chan struct{} {
|
|||||||
return i.sync
|
return i.sync
|
||||||
}
|
}
|
||||||
|
|
||||||
i.graphics.flushIfNeeded(false, false)
|
i.graphics.flushIfNeeded(false)
|
||||||
|
|
||||||
// Calling SynchronizeTexture is ignored on iOS (see mtl.m), but it looks like committing BlitCommandEncoder
|
// Calling SynchronizeTexture is ignored on iOS (see mtl.m), but it looks like committing BlitCommandEncoder
|
||||||
// is necessary (#1337).
|
// is necessary (#1337).
|
||||||
@ -903,39 +905,23 @@ func (i *Image) ReplacePixels(args []*driver.ReplacePixelsArgs) {
|
|||||||
i.waitUntilSyncFinishes()
|
i.waitUntilSyncFinishes()
|
||||||
|
|
||||||
g := i.graphics
|
g := i.graphics
|
||||||
g.flushIfNeeded(true, false)
|
|
||||||
|
|
||||||
// If the memory is shared (e.g., iOS), texture data doen't have to be synced. Send the data directly.
|
// Use a temporary texture to send pixels asynchrounsly, whichever the memory is shared (e.g., iOS) or
|
||||||
if storageMode == mtl.StorageModeShared {
|
// managed (e.g., macOS). (#1418)
|
||||||
for _, a := range args {
|
|
||||||
i.texture.ReplaceRegion(mtl.Region{
|
|
||||||
Origin: mtl.Origin{X: a.X, Y: a.Y, Z: 0},
|
|
||||||
Size: mtl.Size{Width: a.Width, Height: a.Height, Depth: 1},
|
|
||||||
}, 0, unsafe.Pointer(&a.Pixels[0]), 4*a.Width)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the memory is managed (e.g., macOS), texture data cannot be sent to the destination directly because
|
|
||||||
// this requires synchronizing data between CPU and GPU. As synchronizing is inefficient, let's send the
|
|
||||||
// data to a temporary texture once, and then copy it in GPU.
|
|
||||||
w, h := i.texture.Width(), i.texture.Height()
|
w, h := i.texture.Width(), i.texture.Height()
|
||||||
if g.tmpTexture == (mtl.Texture{}) || w > g.tmpTexture.Width() || h > g.tmpTexture.Height() {
|
td := mtl.TextureDescriptor{
|
||||||
if g.tmpTexture != (mtl.Texture{}) {
|
TextureType: mtl.TextureType2D,
|
||||||
g.tmpTexture.Release()
|
PixelFormat: mtl.PixelFormatRGBA8UNorm,
|
||||||
}
|
Width: w,
|
||||||
td := mtl.TextureDescriptor{
|
Height: h,
|
||||||
TextureType: mtl.TextureType2D,
|
StorageMode: storageMode,
|
||||||
PixelFormat: mtl.PixelFormatRGBA8UNorm,
|
Usage: mtl.TextureUsageShaderRead | mtl.TextureUsageRenderTarget,
|
||||||
Width: w,
|
|
||||||
Height: h,
|
|
||||||
StorageMode: storageMode,
|
|
||||||
Usage: mtl.TextureUsageShaderRead | mtl.TextureUsageRenderTarget,
|
|
||||||
}
|
|
||||||
g.tmpTexture = g.view.getMTLDevice().MakeTexture(td)
|
|
||||||
}
|
}
|
||||||
|
t := g.view.getMTLDevice().MakeTexture(td)
|
||||||
|
g.tmpTextures = append(g.tmpTextures, t)
|
||||||
|
|
||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
g.tmpTexture.ReplaceRegion(mtl.Region{
|
t.ReplaceRegion(mtl.Region{
|
||||||
Origin: mtl.Origin{X: a.X, Y: a.Y, Z: 0},
|
Origin: mtl.Origin{X: a.X, Y: a.Y, Z: 0},
|
||||||
Size: mtl.Size{Width: a.Width, Height: a.Height, Depth: 1},
|
Size: mtl.Size{Width: a.Width, Height: a.Height, Depth: 1},
|
||||||
}, 0, unsafe.Pointer(&a.Pixels[0]), 4*a.Width)
|
}, 0, unsafe.Pointer(&a.Pixels[0]), 4*a.Width)
|
||||||
@ -948,7 +934,7 @@ func (i *Image) ReplacePixels(args []*driver.ReplacePixelsArgs) {
|
|||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
o := mtl.Origin{X: a.X, Y: a.Y, Z: 0}
|
o := mtl.Origin{X: a.X, Y: a.Y, Z: 0}
|
||||||
s := mtl.Size{Width: a.Width, Height: a.Height, Depth: 1}
|
s := mtl.Size{Width: a.Width, Height: a.Height, Depth: 1}
|
||||||
bce.CopyFromTexture(g.tmpTexture, 0, 0, o, s, i.texture, 0, 0, o)
|
bce.CopyFromTexture(t, 0, 0, o, s, i.texture, 0, 0, o)
|
||||||
}
|
}
|
||||||
bce.EndEncoding()
|
bce.EndEncoding()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user