Resource type sensitive ResourceManager reloading, Disabled by default, but may increase performance. (#4658)

This commit is contained in:
gegy1000 authored and LexManos committed 2018-07-28 17:47:01 -07:00
1 parent 4c3e6ed139
commit a935859b24
18 files changed
+493 -40

No files matched your search

@@ -19,8 +19,12 @@
package net.minecraftforge.client;
import javax.annotation.Nonnull;
import java.nio.ByteBuffer;
import java.util.function.Predicate;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.VanillaResourceType;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
@@ -36,14 +40,14 @@ import net.minecraft.client.renderer.vertex.VertexBuffer;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
public class CloudRenderer implements IResourceManagerReloadListener
public class CloudRenderer implements ISelectiveResourceReloadListener
{
// Shared constants.
private static final float PX_SIZE = 1 / 256F;
@@ -478,8 +482,11 @@ public class CloudRenderer implements IResourceManagerReloadListener
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager)
public void onResourceManagerReload(@Nonnull IResourceManager resourceManager, @Nonnull Predicate<IResourceType> resourcePredicate)
{
reloadTextures();
if (resourcePredicate.test(VanillaResourceType.TEXTURES))
{
reloadTextures();
}
}
}
@@ -40,6 +40,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.ISound;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.gui.BossInfoClient;
import net.minecraft.client.gui.FontRenderer;
@@ -47,11 +48,13 @@ import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BlockFaceUV;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -71,8 +74,13 @@ import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormatElement.EnumUsage;
import net.minecraft.client.resources.FoliageColorReloadListener;
import net.minecraft.client.resources.GrassColorReloadListener;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.resources.LanguageManager;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.util.SearchTreeManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.passive.EntityHorse;
@@ -112,6 +120,9 @@ import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.client.model.ModelDynBucket;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.SelectiveReloadStateHandler;
import net.minecraftforge.client.resource.VanillaResourceType;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.ForgeVersion.Status;
@@ -128,6 +139,8 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import java.util.function.Predicate;
import com.google.common.collect.Maps;
public class ForgeHooksClient
@@ -746,4 +759,26 @@ public class ForgeHooksClient
if(texture == null) texture = horse.getHorseArmorType().getTextureName();
return texture;
}
public static boolean shouldUseVanillaReloadableListener(IResourceManagerReloadListener listener)
{
Predicate<IResourceType> predicate = SelectiveReloadStateHandler.INSTANCE.get();
if (listener instanceof ModelManager || listener instanceof RenderItem)
return predicate.test(VanillaResourceType.MODELS);
else if (listener instanceof BlockRendererDispatcher || listener instanceof RenderGlobal)
return predicate.test(VanillaResourceType.MODELS);
else if (listener instanceof TextureManager || listener instanceof FontRenderer)
return predicate.test(VanillaResourceType.TEXTURES);
else if (listener instanceof FoliageColorReloadListener || listener instanceof GrassColorReloadListener)
return predicate.test(VanillaResourceType.TEXTURES);
else if (listener instanceof SoundHandler)
return predicate.test(VanillaResourceType.SOUNDS);
else if (listener instanceof EntityRenderer)
return predicate.test(VanillaResourceType.SHADERS);
else if (listener instanceof LanguageManager || listener instanceof SearchTreeManager)
return predicate.test(VanillaResourceType.LANGUAGES);
return true;
}
}
@@ -19,11 +19,30 @@
package net.minecraftforge.client.model;
import java.util.function.Predicate;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
import net.minecraftforge.client.resource.VanillaResourceType;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.util.ResourceLocation;
public interface ICustomModelLoader extends IResourceManagerReloadListener
public interface ICustomModelLoader extends ISelectiveResourceReloadListener
{
@Override
void onResourceManagerReload(IResourceManager resourceManager);
@Override
default void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate)
{
if (resourcePredicate.test(VanillaResourceType.MODELS))
{
onResourceManagerReload(resourceManager);
}
}
/*
* Checks if given model should be loaded by this loader.
* Reading file contents is inadvisable, if possible decision should be made based on the location alone.
@@ -0,0 +1,31 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.resource;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* Represents a generic type of reloadable resource. Used for resource reload filtering.
*/
@SideOnly(Side.CLIENT)
public interface IResourceType
{
}
@@ -0,0 +1,46 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.resource;
import java.util.function.Predicate;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
public interface ISelectiveResourceReloadListener extends IResourceManagerReloadListener
{
@Override
default void onResourceManagerReload(IResourceManager resourceManager)
{
// For compatibility, call the selective version from the non-selective function
onResourceManagerReload(resourceManager, SelectiveReloadStateHandler.INSTANCE.get());
}
/**
* A version of onResourceManager that selectively chooses {@link net.minecraftforge.client.resource.IResourceType}s
* to reload.
* When using this, the given predicate should be called to ensure the relevant resources should
* be reloaded at this time.
*
* @param resourceManager the resource manager being reloaded
* @param resourcePredicate predicate to test whether any given resource type should be reloaded
*/
void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate);
}
@@ -0,0 +1,57 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.resource;
import java.util.Set;
import java.util.function.Predicate;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import com.google.common.collect.Sets;
/**
* Holds methods to create standard predicates to select {@link IResourceType}s that should be reloaded.
*/
@SideOnly(Side.CLIENT)
public final class ReloadRequirements
{
/**
* Creates a reload predicate accepting all resource types.
*
* @return a predicate accepting all types
*/
public static Predicate<IResourceType> all()
{
return type -> true;
}
/**
* Creates an inclusive reload predicate. Only given resource types will be loaded along with this.
*
* @param inclusion the set of resource types to be included in the reload
* @return an inclusion predicate based on the given types
*/
public static Predicate<IResourceType> include(IResourceType... inclusion)
{
Set<IResourceType> inclusionSet = Sets.newHashSet(inclusion);
return inclusionSet::contains;
}
}
@@ -0,0 +1,76 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.resource;
import javax.annotation.Nullable;
import java.util.function.Predicate;
import net.minecraftforge.common.ForgeModContainer;
/**
* Handles reload parameters for selective loaders.
*/
public enum SelectiveReloadStateHandler
{
INSTANCE;
@Nullable
private Predicate<IResourceType> currentPredicate = null;
/***
* Pushes a resource type predicate for the current reload.
* Should only be called when initiating a resource reload.
* If a reload is already in progress when this is called, an exception will be thrown.
*
* @param resourcePredicate the resource requirement predicate for the current reload
*/
public void beginReload(Predicate<IResourceType> resourcePredicate)
{
if (this.currentPredicate != null)
{
throw new IllegalStateException("Recursive resource reloading detected");
}
this.currentPredicate = resourcePredicate;
}
/**
* Gets the current reload resource predicate for the initiated reload.
*
* @return the active reload resource predicate, or an accepting one if none in progress
*/
public Predicate<IResourceType> get()
{
if (this.currentPredicate == null || !ForgeModContainer.selectiveResourceReloadEnabled)
{
return ReloadRequirements.all();
}
return this.currentPredicate;
}
/**
* Finishes the current reload and deletes the previously added reload predicate.
*/
public void endReload()
{
this.currentPredicate = null;
}
}
@@ -0,0 +1,58 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.resource;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* An enum of all {@link IResourceType}s used by the Vanilla game. These should be used if handling vanilla-related
* resources.
*/
@SideOnly(Side.CLIENT)
public enum VanillaResourceType implements IResourceType
{
/**
* Used when block and item models are reloaded and rebaked. This also includes the texture-stitching from that
* phase.
*/
MODELS,
/**
* Used when textures from the {@link net.minecraft.client.renderer.texture.TextureManager} are reloaded. Does not
* effect block or item textures on the texture atlas.
*/
TEXTURES,
/**
* Used when all game sounds are reloaded.
*/
SOUNDS,
/**
* Used when the current language is reloaded.
*/
LANGUAGES,
/**
* Used when all shaders are reloaded.
*/
SHADERS,
}
@@ -0,0 +1,26 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraftforge.client.resource;
import javax.annotation.ParametersAreNonnullByDefault;
import mcp.MethodsReturnNonnullByDefault;
@@ -115,6 +115,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
public static boolean shouldSortRecipies = true;
public static boolean disableVersionCheck = false;
public static boolean forgeLightPipelineEnabled = true;
public static boolean selectiveResourceReloadEnabled = false;
@Deprecated // TODO remove in 1.13
public static boolean replaceVanillaBucketModel = true;
public static boolean zoomInMissingModelTextInGui = false;
@@ -358,6 +359,12 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
prop.setLanguageKey("forge.configgui.forgeLightPipelineEnabled");
propOrder.add(prop.getName());
prop = config.get(Configuration.CATEGORY_CLIENT, "selectiveResourceReloadEnabled", false,
"When enabled, makes specific reload tasks such as language changing quicker to run.");
selectiveResourceReloadEnabled = prop.getBoolean(false);
prop.setLanguageKey("forge.configgui.selectiveResourceReloadEnabled");
propOrder.add(prop.getName());
config.setCategoryPropertyOrder(CATEGORY_CLIENT, propOrder);
if (config.hasChanged())
@@ -33,6 +33,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
@@ -52,6 +53,7 @@ import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.AbstractResourcePack;
import net.minecraft.client.resources.FallbackResourceManager;
import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.client.resources.LegacyV2Adapter;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
@@ -84,6 +86,9 @@ import net.minecraft.world.storage.SaveFormatOld;
import net.minecraftforge.client.CloudRenderer;
import net.minecraftforge.client.IRenderHandler;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.ReloadRequirements;
import net.minecraftforge.client.resource.SelectiveReloadStateHandler;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.common.util.CompoundDataFixer;
@@ -133,6 +138,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -1103,4 +1109,27 @@ public class FMLClientHandler implements IFMLSidedHandler
}
return getCloudRenderer().render(cloudTicks, partialTicks);
}
public void refreshResources(IResourceType... inclusion)
{
this.refreshResources(ReloadRequirements.include(inclusion));
}
// Wrapper around the existing refreshResources with given reload predicates
public void refreshResources(Predicate<IResourceType> resourcePredicate)
{
SelectiveReloadStateHandler.INSTANCE.beginReload(resourcePredicate);
this.client.refreshResources();
SelectiveReloadStateHandler.INSTANCE.endReload();
}
public ListenableFuture<Object> scheduleResourcesRefresh(IResourceType... inclusion)
{
return this.scheduleResourcesRefresh(ReloadRequirements.include(inclusion));
}
public ListenableFuture<Object> scheduleResourcesRefresh(Predicate<IResourceType> resourcePredicate)
{
return this.client.addScheduledTask(() -> this.refreshResources(resourcePredicate));
}
}