DynamicUniformStorage.java
net.minecraft.client.renderer.DynamicUniformStorage
信息
- 全限定名:net.minecraft.client.renderer.DynamicUniformStorage
- 类型:public class
- 包:net.minecraft.client.renderer
- 源码路径:src/main/java/net/minecraft/client/renderer/DynamicUniformStorage.java
- 起始行号:L18
- 实现:AutoCloseable
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L19 - 说明:
TODO
- 类型:
-
oldBuffers- 类型:
List<MappableRingBuffer> - 修饰符:
private final - 源码定位:
L20 - 说明:
TODO
- 类型:
-
blockSize- 类型:
int - 修饰符:
private final - 源码定位:
L21 - 说明:
TODO
- 类型:
-
ringBuffer- 类型:
MappableRingBuffer - 修饰符:
private - 源码定位:
L22 - 说明:
TODO
- 类型:
-
nextBlock- 类型:
int - 修饰符:
private - 源码定位:
L23 - 说明:
TODO
- 类型:
-
capacity- 类型:
int - 修饰符:
private - 源码定位:
L24 - 说明:
TODO
- 类型:
-
lastUniform- 类型:
T - 修饰符:
private - 源码定位:
L25 - 说明:
TODO
- 类型:
-
label- 类型:
String - 修饰符:
private final - 源码定位:
L26 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.client.renderer.DynamicUniformStorage.DynamicUniform- 类型:
interface - 修饰符:
public - 源码定位:
L124 - 说明:
TODO
- 类型:
构造器
public DynamicUniformStorage(String label, int uboSize, int initialCapacity) @ L28
- 构造器名:DynamicUniformStorage
- 源码定位:L28
- 修饰符:public
参数:
- label: String
- uboSize: int
- initialCapacity: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void endFrame() @ L37
- 方法名:endFrame
- 源码定位:L37
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void resizeBuffers(int newCapacity) @ L50
- 方法名:resizeBuffers
- 源码定位:L50
- 返回类型:void
- 修饰符:private
参数:
- newCapacity: int
说明:
TODO
public GpuBufferSlice writeUniform(T uniform) @ L58
- 方法名:writeUniform
- 源码定位:L58
- 返回类型:GpuBufferSlice
- 修饰符:public
参数:
- uniform: T
说明:
TODO
public GpuBufferSlice[] writeUniforms(T[] uniforms) @ L82
- 方法名:writeUniforms
- 源码定位:L82
- 返回类型:GpuBufferSlice[]
- 修饰符:public
参数:
- uniforms: T[]
说明:
TODO
public void close() @ L114
- 方法名:close
- 源码定位:L114
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class DynamicUniformStorage<T extends DynamicUniformStorage.DynamicUniform> implements AutoCloseable {
private static final Logger LOGGER = LogUtils.getLogger();
private final List<MappableRingBuffer> oldBuffers = new ArrayList<>();
private final int blockSize;
private MappableRingBuffer ringBuffer;
private int nextBlock;
private int capacity;
private @Nullable T lastUniform;
private final String label;
public DynamicUniformStorage(String label, int uboSize, int initialCapacity) {
GpuDevice device = RenderSystem.getDevice();
this.blockSize = Mth.roundToward(uboSize, device.getUniformOffsetAlignment());
this.capacity = Mth.smallestEncompassingPowerOfTwo(initialCapacity);
this.nextBlock = 0;
this.ringBuffer = new MappableRingBuffer(() -> label + " x" + this.blockSize, 130, this.blockSize * this.capacity);
this.label = label;
}
public void endFrame() {
this.nextBlock = 0;
this.lastUniform = null;
this.ringBuffer.rotate();
if (!this.oldBuffers.isEmpty()) {
for (MappableRingBuffer oldBuffer : this.oldBuffers) {
oldBuffer.close();
}
this.oldBuffers.clear();
}
}
private void resizeBuffers(int newCapacity) {
this.capacity = newCapacity;
this.nextBlock = 0;
this.lastUniform = null;
this.oldBuffers.add(this.ringBuffer);
this.ringBuffer = new MappableRingBuffer(() -> this.label + " x" + this.blockSize, 130, this.blockSize * this.capacity);
}
public GpuBufferSlice writeUniform(T uniform) {
if (this.lastUniform != null && this.lastUniform.equals(uniform)) {
return this.ringBuffer.currentBuffer().slice((this.nextBlock - 1) * this.blockSize, this.blockSize);
} else {
if (this.nextBlock >= this.capacity) {
int newCapacity = this.capacity * 2;
LOGGER.info("Resizing {}, capacity limit of {} reached during a single frame. New capacity will be {}.", this.label, this.capacity, newCapacity);
this.resizeBuffers(newCapacity);
}
int offset = this.nextBlock * this.blockSize;
try (GpuBuffer.MappedView view = RenderSystem.getDevice()
.createCommandEncoder()
.mapBuffer(this.ringBuffer.currentBuffer().slice(offset, this.blockSize), false, true)) {
uniform.write(view.data());
}
this.nextBlock++;
this.lastUniform = uniform;
return this.ringBuffer.currentBuffer().slice(offset, this.blockSize);
}
}
public GpuBufferSlice[] writeUniforms(T[] uniforms) {
if (uniforms.length == 0) {
return new GpuBufferSlice[0];
} else {
if (this.nextBlock + uniforms.length > this.capacity) {
int newCapacity = Mth.smallestEncompassingPowerOfTwo(Math.max(this.capacity + 1, uniforms.length));
LOGGER.info("Resizing {}, capacity limit of {} reached during a single frame. New capacity will be {}.", this.label, this.capacity, newCapacity);
this.resizeBuffers(newCapacity);
}
int firstOffset = this.nextBlock * this.blockSize;
GpuBufferSlice[] result = new GpuBufferSlice[uniforms.length];
try (GpuBuffer.MappedView view = RenderSystem.getDevice()
.createCommandEncoder()
.mapBuffer(this.ringBuffer.currentBuffer().slice(firstOffset, uniforms.length * this.blockSize), false, true)) {
ByteBuffer byteBuffer = view.data();
for (int i = 0; i < uniforms.length; i++) {
T uniform = uniforms[i];
result[i] = this.ringBuffer.currentBuffer().slice(firstOffset + i * this.blockSize, this.blockSize);
byteBuffer.position(i * this.blockSize);
uniform.write(byteBuffer);
}
}
this.nextBlock += uniforms.length;
this.lastUniform = uniforms[uniforms.length - 1];
return result;
}
}
@Override
public void close() {
for (MappableRingBuffer oldBuffer : this.oldBuffers) {
oldBuffer.close();
}
this.ringBuffer.close();
}
@OnlyIn(Dist.CLIENT)
public interface DynamicUniform {
void write(ByteBuffer byteBuffer);
}
}引用的其他类
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RenderSystem.getDevice()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
MappableRingBuffer()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.roundToward(), Mth.smallestEncompassingPowerOfTwo()
- 引用位置: