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);
    }
}

引用的其他类

  • GpuBufferSlice

    • 引用位置: 返回值
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.getDevice()
  • MappableRingBuffer

    • 引用位置: 字段/构造调用
    • 关联成员: MappableRingBuffer()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.roundToward(), Mth.smallestEncompassingPowerOfTwo()