ByteBufferBuilder.java
com.mojang.blaze3d.vertex.ByteBufferBuilder
信息
- 全限定名:com.mojang.blaze3d.vertex.ByteBufferBuilder
- 类型:public class
- 包:com.mojang.blaze3d.vertex
- 源码路径:src/main/java/com/mojang/blaze3d/vertex/ByteBufferBuilder.java
- 起始行号:L17
- 实现:AutoCloseable
- 职责:
TODO
字段/常量
-
MEMORY_POOL- 类型:
MemoryPool - 修饰符:
private static final - 源码定位:
L18 - 说明:
TODO
- 类型:
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L19 - 说明:
TODO
- 类型:
-
ALLOCATOR- 类型:
MemoryAllocator - 修饰符:
private static final - 源码定位:
L20 - 说明:
TODO
- 类型:
-
DEFAULT_MAX_CAPACITY- 类型:
long - 修饰符:
private static final - 源码定位:
L21 - 说明:
TODO
- 类型:
-
MAX_GROWTH_SIZE- 类型:
int - 修饰符:
private static final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
BUFFER_FREED_GENERATION- 类型:
int - 修饰符:
private static final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
pointer- 类型:
long - 修饰符:
private - 源码定位:
L24 - 说明:
TODO
- 类型:
-
capacity- 类型:
long - 修饰符:
private - 源码定位:
L25 - 说明:
TODO
- 类型:
-
maxCapacity- 类型:
long - 修饰符:
private final - 源码定位:
L26 - 说明:
TODO
- 类型:
-
writeOffset- 类型:
long - 修饰符:
private - 源码定位:
L27 - 说明:
TODO
- 类型:
-
nextResultOffset- 类型:
long - 修饰符:
private - 源码定位:
L28 - 说明:
TODO
- 类型:
-
resultCount- 类型:
int - 修饰符:
private - 源码定位:
L29 - 说明:
TODO
- 类型:
-
generation- 类型:
int - 修饰符:
private - 源码定位:
L30 - 说明:
TODO
- 类型:
内部类/嵌套类型
com.mojang.blaze3d.vertex.ByteBufferBuilder.Result- 类型:
class - 修饰符:
public - 源码定位:
L151 - 说明:
TODO
- 类型:
构造器
public ByteBufferBuilder(int initialCapacity, long maxCapacity) @ L32
- 构造器名:ByteBufferBuilder
- 源码定位:L32
- 修饰符:public
参数:
- initialCapacity: int
- maxCapacity: long
说明:
TODO
public ByteBufferBuilder(int initialCapacity) @ L42
- 构造器名:ByteBufferBuilder
- 源码定位:L42
- 修饰符:public
参数:
- initialCapacity: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
public static ByteBufferBuilder exactlySized(int capacity) @ L46
- 方法名:exactlySized
- 源码定位:L46
- 返回类型:ByteBufferBuilder
- 修饰符:public static
参数:
- capacity: int
说明:
TODO
public long reserve(int size) @ L50
- 方法名:reserve
- 源码定位:L50
- 返回类型:long
- 修饰符:public
参数:
- size: int
说明:
TODO
private void ensureCapacity(long requiredCapacity) @ L58
- 方法名:ensureCapacity
- 源码定位:L58
- 返回类型:void
- 修饰符:private
参数:
- requiredCapacity: long
说明:
TODO
private void resize(long newCapacity) @ L70
- 方法名:resize
- 源码定位:L70
- 返回类型:void
- 修饰符:private
参数:
- newCapacity: long
说明:
TODO
public ByteBufferBuilder.Result build() @ L82
- 方法名:build
- 源码定位:L82
- 返回类型:ByteBufferBuilder.Result
- 修饰符:public
参数:
- 无
说明:
TODO
public void clear() @ L97
- 方法名:clear
- 源码定位:L97
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void discard() @ L105
- 方法名:discard
- 源码定位:L105
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private boolean isValid(int generation) @ L113
- 方法名:isValid
- 源码定位:L113
- 返回类型:boolean
- 修饰符:private
参数:
- generation: int
说明:
TODO
private void freeResult() @ L117
- 方法名:freeResult
- 源码定位:L117
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void discardResults() @ L123
- 方法名:discardResults
- 源码定位:L123
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void close() @ L134
- 方法名:close
- 源码定位:L134
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void checkOpen() @ L144
- 方法名:checkOpen
- 源码定位:L144
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class ByteBufferBuilder implements AutoCloseable {
private static final MemoryPool MEMORY_POOL = TracyClient.createMemoryPool("ByteBufferBuilder");
private static final Logger LOGGER = LogUtils.getLogger();
private static final MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false);
private static final long DEFAULT_MAX_CAPACITY = 4294967295L;
private static final int MAX_GROWTH_SIZE = 2097152;
private static final int BUFFER_FREED_GENERATION = -1;
private long pointer;
private long capacity;
private final long maxCapacity;
private long writeOffset;
private long nextResultOffset;
private int resultCount;
private int generation;
public ByteBufferBuilder(int initialCapacity, long maxCapacity) {
this.capacity = initialCapacity;
this.maxCapacity = maxCapacity;
this.pointer = ALLOCATOR.malloc(initialCapacity);
MEMORY_POOL.malloc(this.pointer, initialCapacity);
if (this.pointer == 0L) {
throw new OutOfMemoryError("Failed to allocate " + initialCapacity + " bytes");
}
}
public ByteBufferBuilder(int initialCapacity) {
this(initialCapacity, 4294967295L);
}
public static ByteBufferBuilder exactlySized(int capacity) {
return new ByteBufferBuilder(capacity, capacity);
}
public long reserve(int size) {
long offset = this.writeOffset;
long nextOffset = Math.addExact(offset, (long)size);
this.ensureCapacity(nextOffset);
this.writeOffset = nextOffset;
return Math.addExact(this.pointer, offset);
}
private void ensureCapacity(long requiredCapacity) {
if (requiredCapacity > this.capacity) {
if (requiredCapacity > this.maxCapacity) {
throw new IllegalArgumentException("Maximum capacity of ByteBufferBuilder (" + this.maxCapacity + ") exceeded, required " + requiredCapacity);
}
long preferredGrowth = Math.min(this.capacity, 2097152L);
long newCapacity = Mth.clamp(this.capacity + preferredGrowth, requiredCapacity, this.maxCapacity);
this.resize(newCapacity);
}
}
private void resize(long newCapacity) {
MEMORY_POOL.free(this.pointer);
this.pointer = ALLOCATOR.realloc(this.pointer, newCapacity);
MEMORY_POOL.malloc(this.pointer, (int)Math.min(newCapacity, 2147483647L));
LOGGER.debug("Needed to grow BufferBuilder buffer: Old size {} bytes, new size {} bytes.", this.capacity, newCapacity);
if (this.pointer == 0L) {
throw new OutOfMemoryError("Failed to resize buffer from " + this.capacity + " bytes to " + newCapacity + " bytes");
} else {
this.capacity = newCapacity;
}
}
public ByteBufferBuilder.@Nullable Result build() {
this.checkOpen();
long offset = this.nextResultOffset;
long size = this.writeOffset - offset;
if (size == 0L) {
return null;
} else if (size > 2147483647L) {
throw new IllegalStateException("Cannot build buffer larger than 2147483647 bytes (was " + size + ")");
} else {
this.nextResultOffset = this.writeOffset;
this.resultCount++;
return new ByteBufferBuilder.Result(offset, (int)size, this.generation);
}
}
public void clear() {
if (this.resultCount > 0) {
LOGGER.warn("Clearing BufferBuilder with unused batches");
}
this.discard();
}
public void discard() {
this.checkOpen();
if (this.resultCount > 0) {
this.discardResults();
this.resultCount = 0;
}
}
private boolean isValid(int generation) {
return generation == this.generation;
}
private void freeResult() {
if (--this.resultCount <= 0) {
this.discardResults();
}
}
private void discardResults() {
long currentSize = this.writeOffset - this.nextResultOffset;
if (currentSize > 0L) {
MemoryUtil.memCopy(this.pointer + this.nextResultOffset, this.pointer, currentSize);
}
this.writeOffset = currentSize;
this.nextResultOffset = 0L;
this.generation++;
}
@Override
public void close() {
if (this.pointer != 0L) {
MEMORY_POOL.free(this.pointer);
ALLOCATOR.free(this.pointer);
this.pointer = 0L;
this.generation = -1;
}
}
private void checkOpen() {
if (this.pointer == 0L) {
throw new IllegalStateException("Buffer has been freed");
}
}
@OnlyIn(Dist.CLIENT)
public class Result implements AutoCloseable {
private final long offset;
private final int capacity;
private final int generation;
private boolean closed;
private Result(long offset, int capacity, int generation) {
Objects.requireNonNull(ByteBufferBuilder.this);
super();
this.offset = offset;
this.capacity = capacity;
this.generation = generation;
}
public ByteBuffer byteBuffer() {
if (!ByteBufferBuilder.this.isValid(this.generation)) {
throw new IllegalStateException("Buffer is no longer valid");
} else {
return MemoryUtil.memByteBuffer(ByteBufferBuilder.this.pointer + this.offset, this.capacity);
}
}
@Override
public void close() {
if (!this.closed) {
this.closed = true;
if (ByteBufferBuilder.this.isValid(this.generation)) {
ByteBufferBuilder.this.freeResult();
}
}
}
}
}引用的其他类
- Mth
- 引用位置:
方法调用 - 关联成员:
Mth.clamp()
- 引用位置: