Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-33383

Lag while taking screenshot with F2 in singleplayer

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Resolution: Fixed
    • Affects Version/s: 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
    • Labels:
    • Confirmation Status:
      Confirmed

      Description

      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)

      saveScreenshot(File p_148259_0_, String p_148259_1_, int p_148259_2_, int p_148259_3_, Framebuffer p_148259_4_)
      // 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

        Attachments

        1. Dev Console Output.txt
          29 kB
          Andrew Thomas
        2. FPS dropped (second screenshot).png
          714 kB
          [Mod] Marcono1234
        3. FPS normal (first screenshot).png
          711 kB
          [Mod] Marcono1234
        4. screenshot_2.txt
          12 kB
          Andrew Thomas

          Issue Links

            Activity

              People

              Assignee:
              grum [Mojang] Grum (Erik Broes)
              Reporter:
              greatmastermario Andrew Thomas
              Votes:
              23 Vote for this issue
              Watchers:
              13 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                CHK: