Optimize atlas skin element
Achieved with CryCry 3
This commit is contained in:
parent
f7c3f5efeb
commit
980e2a8f30
@ -12,6 +12,7 @@ import net.minecraft.resources.ResourceLocation
|
|||||||
import net.minecraft.util.Mth
|
import net.minecraft.util.Mth
|
||||||
import org.lwjgl.opengl.GL11.GL_ALWAYS
|
import org.lwjgl.opengl.GL11.GL_ALWAYS
|
||||||
import ru.dbotthepony.mc.otm.isClient
|
import ru.dbotthepony.mc.otm.isClient
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
class AtlasSkinElement(
|
class AtlasSkinElement(
|
||||||
@ -30,6 +31,30 @@ class AtlasSkinElement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimistic: we should not create a lot of instances of this class
|
||||||
|
synchronized(listeners) {
|
||||||
|
listeners.add(WeakReference(this))
|
||||||
|
val iterator = listeners.listIterator()
|
||||||
|
|
||||||
|
for (ref in iterator) {
|
||||||
|
val value = ref.get()
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
iterator.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWidgetAtlasAvailable) {
|
||||||
|
earlyBindingImpl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun earlyBindingImpl() {
|
||||||
|
if (WidgetAtlasHolder.INSTANCE.once) {
|
||||||
|
textureAtlasSpriteImpl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var changeset = -1
|
private var changeset = -1
|
||||||
@ -39,10 +64,20 @@ class AtlasSkinElement(
|
|||||||
check(isClient) { "Invalid realm" }
|
check(isClient) { "Invalid realm" }
|
||||||
val _textureAtlasSprite = _textureAtlasSprite
|
val _textureAtlasSprite = _textureAtlasSprite
|
||||||
|
|
||||||
if (_textureAtlasSprite == null || _textureAtlasSprite.name.let { it.namespace == "minecraft" && it.path == "missingno" } || changeset != WidgetAtlasHolder.INSTANCE.changeset || WidgetAtlasHolder.INSTANCE.speculateIfMinecraftEngineIsDumDum()) {
|
if (
|
||||||
|
_textureAtlasSprite == null ||
|
||||||
|
_textureAtlasSprite.name.let { it.namespace == "minecraft" && it.path == "missingno" } ||
|
||||||
|
changeset != WidgetAtlasHolder.INSTANCE.changeset
|
||||||
|
) {
|
||||||
val get = WidgetAtlasHolder.INSTANCE.getSprite(location)
|
val get = WidgetAtlasHolder.INSTANCE.getSprite(location)
|
||||||
this._textureAtlasSprite = get
|
this._textureAtlasSprite = get
|
||||||
changeset = WidgetAtlasHolder.INSTANCE.changeset
|
changeset = WidgetAtlasHolder.INSTANCE.changeset
|
||||||
|
|
||||||
|
u0 = get.u0
|
||||||
|
v0 = get.v0
|
||||||
|
u1 = get.u1 - (get.u1 - get.u0) * (1f - width / spriteWidth)
|
||||||
|
v1 = get.v1 - (get.v1 - get.v0) * (1f - height / spriteHeight)
|
||||||
|
|
||||||
return get
|
return get
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,10 +89,15 @@ class AtlasSkinElement(
|
|||||||
return textureAtlasSpriteImpl
|
return textureAtlasSpriteImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
override val u0 get() = textureAtlasSprite.u0
|
override var u0 = 0f
|
||||||
override val v0 get() = textureAtlasSprite.v0
|
private set
|
||||||
override val u1 get() = textureAtlasSprite.u1 - (textureAtlasSprite.u1 - textureAtlasSprite.u0) * (1f - width / spriteWidth)
|
override var v0 = 0f
|
||||||
override val v1 get() = textureAtlasSprite.v1 - (textureAtlasSprite.v1 - textureAtlasSprite.v0) * (1f - height / spriteHeight)
|
private set
|
||||||
|
override var u1 = 0f
|
||||||
|
private set
|
||||||
|
override var v1 = 0f
|
||||||
|
private set
|
||||||
|
|
||||||
override val texture: ResourceLocation get() = WidgetAtlasHolder.LOCATION
|
override val texture: ResourceLocation get() = WidgetAtlasHolder.LOCATION
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@ -80,8 +120,25 @@ class AtlasSkinElement(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val keys = HashSet<ResourceLocation>()
|
private val keys = HashSet<ResourceLocation>()
|
||||||
|
private val listeners = ArrayList<WeakReference<AtlasSkinElement>>()
|
||||||
val keysStream: Stream<ResourceLocation> get() = keys.stream()
|
val keysStream: Stream<ResourceLocation> get() = keys.stream()
|
||||||
|
|
||||||
|
fun notifyListeners() {
|
||||||
|
synchronized(listeners) {
|
||||||
|
val iterator = listeners.listIterator()
|
||||||
|
|
||||||
|
for (ref in iterator) {
|
||||||
|
val value = ref.get()
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
iterator.remove()
|
||||||
|
} else {
|
||||||
|
value.textureAtlasSpriteImpl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun queueRebuild() {
|
private fun queueRebuild() {
|
||||||
WidgetAtlasHolder.INSTANCE.queueRebuild()
|
WidgetAtlasHolder.INSTANCE.queueRebuild()
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,7 @@ class DynamicBufferSource(val minimalBufferSize: Int = 0) : MultiBufferSource {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val GUI = DynamicBufferSource()
|
val GUI = DynamicBufferSource()
|
||||||
val WORLD = DynamicBufferSource(8192)
|
val WORLD = DynamicBufferSource(2 shl 16)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from LevelRenderer
|
* Called from LevelRenderer
|
||||||
|
@ -28,20 +28,14 @@ class WidgetAtlasHolder private constructor(manager: TextureManager) : TextureAt
|
|||||||
private set
|
private set
|
||||||
var demandsRebuild = false
|
var demandsRebuild = false
|
||||||
private set
|
private set
|
||||||
var demandsRebuildAt = 0L
|
|
||||||
private set
|
|
||||||
var dirtyUntil = 0L
|
|
||||||
private set
|
|
||||||
|
|
||||||
private var resourceManager by Delegates.notNull<ResourceManager>()
|
private var resourceManager by Delegates.notNull<ResourceManager>()
|
||||||
private var profileManager by Delegates.notNull<ProfilerFiller>()
|
private var profileManager by Delegates.notNull<ProfilerFiller>()
|
||||||
|
|
||||||
override fun prepare(p_118891_: ResourceManager, p_118892_: ProfilerFiller): TextureAtlas.Preparations {
|
override fun prepare(p_118891_: ResourceManager, p_118892_: ProfilerFiller): TextureAtlas.Preparations {
|
||||||
once = true
|
|
||||||
resourceManager = p_118891_
|
resourceManager = p_118891_
|
||||||
profileManager = p_118892_
|
profileManager = p_118892_
|
||||||
changeset++
|
changeset++
|
||||||
dirtyUntil = System.nanoTime() + 100_000_000L
|
|
||||||
return super.prepare(p_118891_, p_118892_)
|
return super.prepare(p_118891_, p_118892_)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,36 +44,28 @@ class WidgetAtlasHolder private constructor(manager: TextureManager) : TextureAt
|
|||||||
resourceManager = p_118895_
|
resourceManager = p_118895_
|
||||||
profileManager = p_118896_
|
profileManager = p_118896_
|
||||||
changeset++
|
changeset++
|
||||||
dirtyUntil = System.nanoTime() + 100_000_000L
|
|
||||||
super.apply(p_118894_, p_118895_, p_118896_)
|
super.apply(p_118894_, p_118895_, p_118896_)
|
||||||
|
AtlasSkinElement.notifyListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rebuildIfRequired(): Boolean {
|
fun rebuildIfRequired(): Boolean {
|
||||||
if (once && demandsRebuild && demandsRebuildAt <= System.nanoTime() && isClientThread()) {
|
if (once && demandsRebuild && isClientThread()) {
|
||||||
apply(prepare(resourceManager, profileManager), resourceManager, profileManager)
|
apply(prepare(resourceManager, profileManager), resourceManager, profileManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
return demandsRebuild
|
return demandsRebuild
|
||||||
}
|
}
|
||||||
|
|
||||||
fun speculateIfMinecraftEngineIsDumDum(): Boolean {
|
|
||||||
return demandsRebuild || dirtyUntil >= System.nanoTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun getSprite(p_118902_: ResourceLocation): TextureAtlasSprite {
|
public override fun getSprite(p_118902_: ResourceLocation): TextureAtlasSprite {
|
||||||
if (!once) {
|
if (!once) {
|
||||||
throw IllegalStateException("Trying to get sprite too early")
|
throw IllegalStateException("Trying to get sprite too early")
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildIfRequired()
|
|
||||||
return super.getSprite(p_118902_)
|
return super.getSprite(p_118902_)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun queueRebuild() {
|
fun queueRebuild() {
|
||||||
if (!demandsRebuild) {
|
|
||||||
demandsRebuild = true
|
demandsRebuild = true
|
||||||
demandsRebuildAt = System.nanoTime() + 100_000_000L
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getResourcesToLoad(): Stream<ResourceLocation> {
|
override fun getResourcesToLoad(): Stream<ResourceLocation> {
|
||||||
@ -101,5 +87,12 @@ class WidgetAtlasHolder private constructor(manager: TextureManager) : TextureAt
|
|||||||
event.registerReloadListener(INSTANCE)
|
event.registerReloadListener(INSTANCE)
|
||||||
isWidgetAtlasAvailable = true
|
isWidgetAtlasAvailable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun renderGameHook() {
|
||||||
|
if (isWidgetAtlasAvailable) {
|
||||||
|
INSTANCE.rebuildIfRequired()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,6 +685,27 @@ function initializeCoreMod() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'GameRenderer#render hook': {
|
||||||
|
'target': {
|
||||||
|
'type': 'METHOD',
|
||||||
|
'class': 'net.minecraft.client.renderer.GameRenderer',
|
||||||
|
'methodName': ASMAPI.mapMethod('m_109093_'), // render
|
||||||
|
'methodDesc': '(FJZ)V'
|
||||||
|
},
|
||||||
|
|
||||||
|
'transformer': function(node) {
|
||||||
|
node.instructions.insert(new MethodInsnNode(
|
||||||
|
opcodesRemapped.invokestatic,
|
||||||
|
'ru/dbotthepony/mc/otm/client/render/WidgetAtlasHolder',
|
||||||
|
'renderGameHook',
|
||||||
|
'()V',
|
||||||
|
false
|
||||||
|
))
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
'LevelRenderer DynamicBufferSource callback': {
|
'LevelRenderer DynamicBufferSource callback': {
|
||||||
'target': {
|
'target': {
|
||||||
'type': 'METHOD',
|
'type': 'METHOD',
|
||||||
|
Loading…
Reference in New Issue
Block a user