109 lines
3.2 KiB
Java
109 lines
3.2 KiB
Java
package com.mojang.blaze3d;
|
|
|
|
import com.mojang.blaze3d.buffers.BufferType;
|
|
import com.mojang.blaze3d.buffers.BufferUsage;
|
|
import com.mojang.blaze3d.buffers.GpuBuffer;
|
|
import com.mojang.blaze3d.buffers.GpuFence;
|
|
import com.mojang.blaze3d.pipeline.RenderTarget;
|
|
import com.mojang.blaze3d.pipeline.TextureTarget;
|
|
import com.mojang.blaze3d.platform.GlStateManager;
|
|
import com.mojang.jtracy.TracyClient;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class TracyFrameCapture implements AutoCloseable {
|
|
private static final int MAX_WIDTH = 320;
|
|
private static final int MAX_HEIGHT = 180;
|
|
private static final int BYTES_PER_PIXEL = 4;
|
|
private int targetWidth;
|
|
private int targetHeight;
|
|
private int width;
|
|
private int height;
|
|
private final RenderTarget frameBuffer = new TextureTarget(320, 180, false);
|
|
private final GpuBuffer pixelbuffer = new GpuBuffer(BufferType.PIXEL_PACK, BufferUsage.STREAM_READ, 0);
|
|
@Nullable
|
|
private GpuFence fence;
|
|
private int lastCaptureDelay;
|
|
private boolean capturedThisFrame;
|
|
|
|
private void resize(int i, int j) {
|
|
float f = (float)i / j;
|
|
if (i > 320) {
|
|
i = 320;
|
|
j = (int)(320.0F / f);
|
|
}
|
|
|
|
if (j > 180) {
|
|
i = (int)(180.0F * f);
|
|
j = 180;
|
|
}
|
|
|
|
i = i / 4 * 4;
|
|
j = j / 4 * 4;
|
|
if (this.width != i || this.height != j) {
|
|
this.width = i;
|
|
this.height = j;
|
|
this.frameBuffer.resize(i, j);
|
|
this.pixelbuffer.resize(i * j * 4);
|
|
if (this.fence != null) {
|
|
this.fence.close();
|
|
this.fence = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void capture(RenderTarget renderTarget) {
|
|
if (this.fence == null && !this.capturedThisFrame) {
|
|
this.capturedThisFrame = true;
|
|
if (renderTarget.width != this.targetWidth || renderTarget.height != this.targetHeight) {
|
|
this.targetWidth = renderTarget.width;
|
|
this.targetHeight = renderTarget.height;
|
|
this.resize(this.targetWidth, this.targetHeight);
|
|
}
|
|
|
|
GlStateManager._glBindFramebuffer(36009, this.frameBuffer.frameBufferId);
|
|
GlStateManager._glBindFramebuffer(36008, renderTarget.frameBufferId);
|
|
GlStateManager._glBlitFrameBuffer(0, 0, renderTarget.width, renderTarget.height, 0, 0, this.width, this.height, 16384, 9729);
|
|
GlStateManager._glBindFramebuffer(36008, 0);
|
|
GlStateManager._glBindFramebuffer(36009, 0);
|
|
this.pixelbuffer.bind();
|
|
GlStateManager._glBindFramebuffer(36008, this.frameBuffer.frameBufferId);
|
|
GlStateManager._readPixels(0, 0, this.width, this.height, 6408, 5121, 0L);
|
|
GlStateManager._glBindFramebuffer(36008, 0);
|
|
this.fence = new GpuFence();
|
|
this.lastCaptureDelay = 0;
|
|
}
|
|
}
|
|
|
|
public void upload() {
|
|
if (this.fence != null) {
|
|
if (this.fence.awaitCompletion(0L)) {
|
|
this.fence = null;
|
|
|
|
try (GpuBuffer.ReadView readView = this.pixelbuffer.read()) {
|
|
if (readView != null) {
|
|
TracyClient.frameImage(readView.data(), this.width, this.height, this.lastCaptureDelay, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void endFrame() {
|
|
this.lastCaptureDelay++;
|
|
this.capturedThisFrame = false;
|
|
TracyClient.markFrame();
|
|
}
|
|
|
|
public void close() {
|
|
if (this.fence != null) {
|
|
this.fence.close();
|
|
this.fence = null;
|
|
}
|
|
|
|
this.pixelbuffer.close();
|
|
this.frameBuffer.destroyBuffers();
|
|
}
|
|
}
|