mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-25 22:46:26 +01:00
Keeping our priorities straight
- Implement backend priority system - Give indirect priority 1000 and instancing 500 - Generate the sorted list of backends on demand in case one changes priority at runtime
This commit is contained in:
parent
a5f49c6738
commit
1a8ed8db28
4 changed files with 56 additions and 29 deletions
|
@ -14,9 +14,15 @@ public interface Backend {
|
||||||
Engine createEngine(LevelAccessor level);
|
Engine createEngine(LevelAccessor level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a fallback backend in case this backend is not supported.
|
* The priority of this backend.
|
||||||
|
* <p>The backend with the highest priority upon first launch will be chosen as the default backend.
|
||||||
|
*
|
||||||
|
* <p>If the selected backend becomes unavailable for whatever reason, the next supported backend
|
||||||
|
* with a LOWER priority than the selected one will be chosen.
|
||||||
|
*
|
||||||
|
* @return The priority of this backend.
|
||||||
*/
|
*/
|
||||||
Backend findFallback();
|
int priority();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if this backend is supported.
|
* Check if this backend is supported.
|
||||||
|
|
|
@ -17,6 +17,7 @@ public final class Backends {
|
||||||
*/
|
*/
|
||||||
public static final Backend INSTANCING = SimpleBackend.builder()
|
public static final Backend INSTANCING = SimpleBackend.builder()
|
||||||
.engineFactory(level -> new EngineImpl(level, new InstancedDrawManager(InstancingPrograms.get()), 256))
|
.engineFactory(level -> new EngineImpl(level, new InstancedDrawManager(InstancingPrograms.get()), 256))
|
||||||
|
.priority(500)
|
||||||
.supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
|
.supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
|
||||||
.register(Flywheel.rl("instancing"));
|
.register(Flywheel.rl("instancing"));
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ public final class Backends {
|
||||||
*/
|
*/
|
||||||
public static final Backend INDIRECT = SimpleBackend.builder()
|
public static final Backend INDIRECT = SimpleBackend.builder()
|
||||||
.engineFactory(level -> new EngineImpl(level, new IndirectDrawManager(IndirectPrograms.get()), 256))
|
.engineFactory(level -> new EngineImpl(level, new IndirectDrawManager(IndirectPrograms.get()), 256))
|
||||||
.fallback(() -> Backends.INSTANCING)
|
.priority(1000)
|
||||||
.supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
|
.supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
|
||||||
.register(Flywheel.rl("indirect"));
|
.register(Flywheel.rl("indirect"));
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,20 @@ package dev.engine_room.flywheel.lib.backend;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.backend.Backend;
|
import dev.engine_room.flywheel.api.backend.Backend;
|
||||||
import dev.engine_room.flywheel.api.backend.BackendManager;
|
|
||||||
import dev.engine_room.flywheel.api.backend.Engine;
|
import dev.engine_room.flywheel.api.backend.Engine;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
|
||||||
public final class SimpleBackend implements Backend {
|
public final class SimpleBackend implements Backend {
|
||||||
private final Function<LevelAccessor, Engine> engineFactory;
|
private final Function<LevelAccessor, Engine> engineFactory;
|
||||||
private final Supplier<Backend> fallback;
|
private final int priority;
|
||||||
private final BooleanSupplier isSupported;
|
private final BooleanSupplier isSupported;
|
||||||
|
|
||||||
public SimpleBackend(Function<LevelAccessor, Engine> engineFactory, Supplier<Backend> fallback, BooleanSupplier isSupported) {
|
public SimpleBackend(int priority, Function<LevelAccessor, Engine> engineFactory, BooleanSupplier isSupported) {
|
||||||
|
this.priority = priority;
|
||||||
this.engineFactory = engineFactory;
|
this.engineFactory = engineFactory;
|
||||||
this.fallback = fallback;
|
|
||||||
this.isSupported = isSupported;
|
this.isSupported = isSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,13 +30,8 @@ public final class SimpleBackend implements Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Backend findFallback() {
|
public int priority() {
|
||||||
if (isSupported()) {
|
return priority;
|
||||||
return this;
|
|
||||||
} else {
|
|
||||||
return fallback.get()
|
|
||||||
.findFallback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,7 +41,7 @@ public final class SimpleBackend implements Backend {
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
private Function<LevelAccessor, Engine> engineFactory;
|
private Function<LevelAccessor, Engine> engineFactory;
|
||||||
private Supplier<Backend> fallback = BackendManager::offBackend;
|
private int priority = 0;
|
||||||
private BooleanSupplier isSupported;
|
private BooleanSupplier isSupported;
|
||||||
|
|
||||||
public Builder engineFactory(Function<LevelAccessor, Engine> engineFactory) {
|
public Builder engineFactory(Function<LevelAccessor, Engine> engineFactory) {
|
||||||
|
@ -56,8 +49,8 @@ public final class SimpleBackend implements Backend {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder fallback(Supplier<Backend> fallback) {
|
public Builder priority(int priority) {
|
||||||
this.fallback = fallback;
|
this.priority = priority;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,10 +61,9 @@ public final class SimpleBackend implements Backend {
|
||||||
|
|
||||||
public Backend register(ResourceLocation id) {
|
public Backend register(ResourceLocation id) {
|
||||||
Objects.requireNonNull(engineFactory);
|
Objects.requireNonNull(engineFactory);
|
||||||
Objects.requireNonNull(fallback);
|
|
||||||
Objects.requireNonNull(isSupported);
|
Objects.requireNonNull(isSupported);
|
||||||
|
|
||||||
return Backend.REGISTRY.registerAndGet(id, new SimpleBackend(engineFactory, fallback, isSupported));
|
return Backend.REGISTRY.registerAndGet(id, new SimpleBackend(priority, engineFactory, isSupported));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package dev.engine_room.flywheel.impl;
|
package dev.engine_room.flywheel.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.api.backend.Backend;
|
import dev.engine_room.flywheel.api.backend.Backend;
|
||||||
import dev.engine_room.flywheel.backend.Backends;
|
|
||||||
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
|
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||||
import dev.engine_room.flywheel.lib.backend.SimpleBackend;
|
import dev.engine_room.flywheel.lib.backend.SimpleBackend;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
@ -31,21 +32,48 @@ public final class BackendManagerImpl {
|
||||||
return backend != OFF_BACKEND;
|
return backend != OFF_BACKEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't store this statically because backends can theoretically change their priorities at runtime.
|
||||||
|
private static ArrayList<Backend> backendsByPriority() {
|
||||||
|
var backends = new ArrayList<>(Backend.REGISTRY.getAll());
|
||||||
|
|
||||||
|
// Sort with keys backwards so that the highest priority is first.
|
||||||
|
backends.sort((a, b) -> Integer.compare(b.priority(), a.priority()));
|
||||||
|
return backends;
|
||||||
|
}
|
||||||
|
|
||||||
private static Backend findDefaultBackend() {
|
private static Backend findDefaultBackend() {
|
||||||
// TODO: Automatically select the best default config based on the user's driver
|
var backendsByPriority = backendsByPriority();
|
||||||
// TODO: Figure out how this will work if custom backends are registered and without hardcoding the default backends
|
if (backendsByPriority.isEmpty()) {
|
||||||
return Backends.INDIRECT;
|
// This probably shouldn't happen, but fail gracefully.
|
||||||
|
FlwImpl.LOGGER.warn("No backends registered, defaulting to 'flywheel:off'");
|
||||||
|
return OFF_BACKEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return backendsByPriority.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void chooseBackend() {
|
private static void chooseBackend() {
|
||||||
var preferred = FlwConfig.INSTANCE.backend();
|
var preferred = FlwConfig.INSTANCE.backend();
|
||||||
var actual = preferred.findFallback();
|
if (preferred.isSupported()) {
|
||||||
|
backend = preferred;
|
||||||
if (preferred != actual) {
|
return;
|
||||||
FlwImpl.LOGGER.warn("Flywheel backend fell back from '{}' to '{}'", Backend.REGISTRY.getIdOrThrow(preferred), Backend.REGISTRY.getIdOrThrow(actual));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backend = actual;
|
var backendsByPriority = backendsByPriority();
|
||||||
|
|
||||||
|
var startIndex = backendsByPriority.indexOf(preferred) + 1;
|
||||||
|
|
||||||
|
// For safety in case we don't find anything
|
||||||
|
backend = OFF_BACKEND;
|
||||||
|
for (int i = startIndex; i < backendsByPriority.size(); i++) {
|
||||||
|
var candidate = backendsByPriority.get(i);
|
||||||
|
if (candidate.isSupported()) {
|
||||||
|
backend = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlwImpl.LOGGER.warn("Flywheel backend fell back from '{}' to '{}'", Backend.REGISTRY.getIdOrThrow(preferred), Backend.REGISTRY.getIdOrThrow(backend));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBackendString() {
|
public static String getBackendString() {
|
||||||
|
|
Loading…
Reference in a new issue