Skip to content

Commit 5d55301

Browse files
Copilotriccardobl
andcommitted
Address review: add setMaxSinglePassLightBatchSize, pin size in set, use FastMath.nearestPowerOfTwo
Co-authored-by: riccardobl <4943530+riccardobl@users.noreply.github.com> Agent-Logs-Url: https://github.com/jMonkeyEngine/jmonkeyengine/sessions/0fb649f6-9ff3-4f61-99a2-9adfd5d4a981
1 parent 32a65d7 commit 5d55301

1 file changed

Lines changed: 39 additions & 19 deletions

File tree

jme3-core/src/main/java/com/jme3/renderer/RenderManager.java

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.jme3.material.RenderState;
4545
import com.jme3.material.Technique;
4646
import com.jme3.material.TechniqueDef;
47+
import com.jme3.math.FastMath;
4748
import com.jme3.math.Matrix4f;
4849
import com.jme3.post.SceneProcessor;
4950
import com.jme3.profile.AppProfiler;
@@ -108,7 +109,7 @@ public class RenderManager {
108109
private LightFilter lightFilter = new DefaultLightFilter();
109110
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
110111
private int singlePassLightBatchSize = 1;
111-
private static final int MAX_SINGLE_PASS_LIGHT_BATCH_SIZE = 16;
112+
private int maxSinglePassLightBatchSize = 16;
112113
private final MatParamOverride boundDrawBufferId = new MatParamOverride(VarType.Int, "BoundDrawBuffer", 0);
113114
private Predicate<Geometry> renderFilter;
114115

@@ -777,10 +778,10 @@ public void renderGeometry(Geometry geom, LightList lightList) {
777778
}
778779

779780
// Auto-scale singlePassLightBatchSize exponentially (powers of 2) up to
780-
// MAX_SINGLE_PASS_LIGHT_BATCH_SIZE to reduce shader recompilations.
781+
// maxSinglePassLightBatchSize to reduce shader recompilations.
781782
int nLights = lightList.size();
782-
if (nLights > singlePassLightBatchSize && singlePassLightBatchSize < MAX_SINGLE_PASS_LIGHT_BATCH_SIZE) {
783-
singlePassLightBatchSize = Math.min(nextPowerOfTwo(nLights), MAX_SINGLE_PASS_LIGHT_BATCH_SIZE);
783+
if (nLights > singlePassLightBatchSize && singlePassLightBatchSize < maxSinglePassLightBatchSize) {
784+
singlePassLightBatchSize = Math.min(FastMath.nearestPowerOfTwo(nLights), maxSinglePassLightBatchSize);
784785
}
785786

786787
this.renderer.pushDebugGroup(geom.getName());
@@ -1065,7 +1066,7 @@ public TechniqueDef.LightMode getPreferredLightMode() {
10651066
* Returns the number of lights used for each pass when the light mode is single pass.
10661067
*
10671068
* <p>This value is automatically scaled up (in powers of two, up to
1068-
* {@value #MAX_SINGLE_PASS_LIGHT_BATCH_SIZE}) during rendering whenever a geometry
1069+
* {@link #getMaxSinglePassLightBatchSize()}) during rendering whenever a geometry
10691070
* has more lights than the current batch size, reducing the number of rendering passes
10701071
* and shader recompilations.
10711072
*
@@ -1076,30 +1077,49 @@ public int getSinglePassLightBatchSize() {
10761077
}
10771078

10781079
/**
1079-
* Sets the number of lights to use for each pass when the light mode is single pass.
1080+
* Sets the number of lights to use for each pass when the light mode is single pass,
1081+
* and simultaneously sets the maximum batch size to the same value.
10801082
*
1081-
* <p>The value will be automatically scaled up during rendering (in powers of two,
1082-
* up to {@value #MAX_SINGLE_PASS_LIGHT_BATCH_SIZE}) when geometries with more lights
1083-
* are encountered. Setting this value explicitly will override the current auto-scaled
1084-
* value, but it may be increased again by subsequent rendering calls.
1083+
* <p>This effectively pins the batch size and disables the automatic scaling,
1084+
* which is useful when you know in advance how many lights your scene uses and
1085+
* want predictable shader compilation.
10851086
*
1086-
* @param singlePassLightBatchSize the number of lights.
1087+
* <p>To set only the upper limit while still allowing automatic scaling,
1088+
* use {@link #setMaxSinglePassLightBatchSize(int)} instead.
1089+
*
1090+
* @param singlePassLightBatchSize the number of lights (minimum 1).
10871091
*/
10881092
public void setSinglePassLightBatchSize(int singlePassLightBatchSize) {
1089-
// Ensure the batch size is no less than 1
10901093
this.singlePassLightBatchSize = Math.max(singlePassLightBatchSize, 1);
1094+
this.maxSinglePassLightBatchSize = this.singlePassLightBatchSize;
10911095
}
10921096

10931097
/**
1094-
* Returns the smallest power of two that is greater than or equal to {@code n}.
1098+
* Returns the maximum number of lights allowed in a single pass batch.
1099+
*
1100+
* <p>The batch size will never be auto-scaled beyond this value.
1101+
* The default is 16.
10951102
*
1096-
* @param n the value
1097-
* @return the smallest power of two &ge; {@code n}, or 1 if {@code n} &le; 1
1103+
* @return the maximum single pass light batch size.
10981104
*/
1099-
private static int nextPowerOfTwo(int n) {
1100-
if (n <= 1) return 1;
1101-
int highest = Integer.highestOneBit(n);
1102-
return highest < n ? highest << 1 : highest;
1105+
public int getMaxSinglePassLightBatchSize() {
1106+
return maxSinglePassLightBatchSize;
1107+
}
1108+
1109+
/**
1110+
* Sets the maximum number of lights allowed in a single pass batch.
1111+
*
1112+
* <p>If the current {@link #getSinglePassLightBatchSize() batch size} exceeds the
1113+
* new maximum, it is clamped down to the new maximum. Otherwise the current
1114+
* batch size is left unchanged and will continue to auto-scale up to the new limit.
1115+
*
1116+
* @param maxSinglePassLightBatchSize the maximum number of lights (minimum 1).
1117+
*/
1118+
public void setMaxSinglePassLightBatchSize(int maxSinglePassLightBatchSize) {
1119+
this.maxSinglePassLightBatchSize = Math.max(maxSinglePassLightBatchSize, 1);
1120+
if (singlePassLightBatchSize > this.maxSinglePassLightBatchSize) {
1121+
singlePassLightBatchSize = this.maxSinglePassLightBatchSize;
1122+
}
11031123
}
11041124

11051125
/**

0 commit comments

Comments
 (0)