-
Bug
-
Resolution: Fixed
-
Minecraft 1.6.4, Minecraft 13w39b, Minecraft 13w41a, Minecraft 1.8, Minecraft 1.8.1, Minecraft 1.8.2-pre1, Minecraft 1.8.3, Minecraft 1.8.9, Minecraft 15w51b, Minecraft 1.9 Pre-Release 4, Minecraft 1.9, Minecraft 1.10.2, Minecraft 16w32b, Minecraft 16w43a, Minecraft 16w44a, Minecraft 1.11 Pre-Release 1, Minecraft 1.11, Minecraft 16w50a, Minecraft 1.11.2, Minecraft 17w06a, Minecraft 1.12.1, Minecraft 1.12.2, Minecraft 17w43a, Minecraft 17w43b, Minecraft 17w45b, Minecraft 17w46a, Minecraft 17w47a, Minecraft 17w47b, Minecraft 17w48a, Minecraft 17w50a
-
Confirmed
The bug
While taking a screenshot using the in-game F2 key, the game freezes for a second and does not take an accurate screenshot.
Code analysis
The reason why this is happening is because saving the screenshot is not done by a seperate thread. This means the lag time is determined by the writing speed of your harddrive.
Another reason which has probably a rather small impact is that in case frame buffering is enabled Minecraft iterates over all pixels in the screenshot and sets them in a BufferedImage. I do not see any advantage of this.
Here is a "fix" that solves this problem, however the ScreenshotSavingThread is only used as a local variable to demonstrate that it solves the problem. It should be rather in the class itself and also set the error message in case it fails:
saveScreenshot(File p_148259_0_, String p_148259_1_, int p_148259_2_, int p_148259_3_, Framebuffer p_148259_4_) method of the net.minecraft.util.ScreenShotHelper class (MCP 1.8 names)
// Is there any advantage from this? if (OpenGlHelper.isFramebufferEnabled()) { var7 = new BufferedImage(p_148259_4_.framebufferWidth, p_148259_4_.framebufferHeight, 1); int var8 = p_148259_4_.framebufferTextureHeight - p_148259_4_.framebufferHeight; for (int var9 = var8; var9 < p_148259_4_.framebufferTextureHeight; ++var9) { for (int var10 = 0; var10 < p_148259_4_.framebufferWidth; ++var10) { var7.setRGB(var10, var9 - var8, pixelValues[var9 * p_148259_4_.framebufferTextureWidth + var10]); } } } else { var7 = new BufferedImage(p_148259_2_, p_148259_3_, 1); var7.setRGB(0, 0, p_148259_2_, p_148259_3_, pixelValues, 0, p_148259_2_); } File var12; if (p_148259_1_ == null) { var12 = getTimestampedPNGFileForDirectory(var5); } else { var12 = new File(var5, p_148259_1_); } // Create an empty file to make sure a ScreenshotSavingThreads do not override it by accident var12.createNewFile(); //ImageIO.write(var7, "png", var12); class ScreenshotSavingThread extends Thread { private final BufferedImage bufferedImage; private final File file; private ScreenshotSavingThread(BufferedImage bufferedImage, File file) { this.bufferedImage = bufferedImage; this.file = file; } @Override public void run() { try { ImageIO.write(bufferedImage, "png", file); } catch (IOException e) { // TODO Print the error message in chat and in the log } } } new ScreenshotSavingThread(var7, var12).start();
Flaws with this design
- Stopping Minecraft could cause half-finished screenshots (unlikely); thread could be non-daemon
- Taking screenshots to often results in a OutOfMemoryError (unlikely, that would need with 500KB per screenshot and 500MB allocated RAM about 1000 ScreenshotSavingThreads running at once)
- Reporting error or success would have to be synchronized and would appear delayed which could be confusing
- is duplicated by
-
MC-62470 Lag "Spikes" when taking screenshots
- Resolved