Repository: godotengine/godot
File: editor/plugins/texture_editor_plugin.cpp (C++)

Code before:
				Ref<Font> metadata_label_font = get_theme_font(SNAME("expression"), EditorStringName(EditorFonts));
				metadata_label->add_theme_font_override(SceneStringName(font), metadata_label_font);
			}

			checkerboard->set_texture(get_editor_theme_icon(SNAME("Checkerboard")));
		} break;
	}
}

void TexturePreview::_update_metadata_label_text() {
	const Ref<Texture2D> texture = texture_display->get_texture();

	String format;
	if (Object::cast_to<ImageTexture>(*texture)) {
		format = Image::get_format_name(Object::cast_to<ImageTexture>(*texture)->get_format());
	} else if (Object::cast_to<CompressedTexture2D>(*texture)) {
		format = Image::get_format_name(Object::cast_to<CompressedTexture2D>(*texture)->get_format());
	} else {
		format = texture->get_class();
	}

	const Ref<Image> image = texture->get_image();
	if (image.is_valid()) {
		const int mipmaps = image->get_mipmap_count();
		// Avoid signed integer overflow that could occur with huge texture sizes by casting everything to uint64_t.
		uint64_t memory = uint64_t(image->get_width()) * uint64_t(image->get_height()) * uint64_t(Image::get_format_pixel_size(image->get_format()));
		// Handle VRAM-compressed formats that are stored with 4 bpp.
		memory >>= Image::get_format_pixel_rshift(image->get_format());

		float mipmaps_multiplier = 1.0;
		float mipmap_increase = 0.25;
		for (int i = 0; i < mipmaps; i++) {
			// Each mip adds 25% memory usage of the previous one.
			// With a complete mipmap chain, memory usage increases by ~33%.
			mipmaps_multiplier += mipmap_increase;
			mipmap_increase *= 0.25;
		}
		memory *= mipmaps_multiplier;

		if (mipmaps >= 1) {
			metadata_label->set_text(
					vformat(String::utf8("%d×%d %s\n") + TTR("%s Mipmaps") + "\n" + TTR("Memory: %s"),
							texture->get_width(),
							texture->get_height(),
							format,
							mipmaps,
							String::humanize_size(memory)));
		} else {
			// "No Mipmaps" is easier to distinguish than "0 Mipmaps",
			// especially since 0, 6, and 8 look quite close with the default code font.
			metadata_label->set_text(

Review comment (performance):
Scale the outline width on hiDPI displays:

```suggestion
	const float scaled_width = Math::round(outline_width * EDSCALE);
	const Rect2 outline_rect = Rect2(Vector2(), texture_display->get_size()).grow(scaled_width * 0.5);
	texture_display->draw_rect(outline_rect, cached_outline_color, false, scaled_width);
```

Code after:

			if (metadata_label) {
				Ref<Font> metadata_label_font = get_theme_font(SNAME("expression"), EditorStringName(EditorFonts));
				metadata_label->add_theme_font_override(SceneStringName(font), metadata_label_font);
			}

			bg_rect->set_color(get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor)));
			checkerboard->set_texture(get_editor_theme_icon(SNAME("Checkerboard")));
			cached_outline_color = get_theme_color(SNAME("extra_border_color_1"), EditorStringName(Editor));
		} break;
	}
}

void TexturePreview::_draw_outline() {
	const float outline_width = Math::round(EDSCALE);
	const Rect2 outline_rect = Rect2(Vector2(), texture_display->get_size()).grow(outline_width * 0.5);
	texture_display->draw_rect(outline_rect, cached_outline_color, false, outline_width);
}

void TexturePreview::_update_texture_display_ratio() {
	if (texture_display->get_texture().is_valid()) {
		centering_container->set_ratio(texture_display->get_texture()->get_size().aspect());
	}
}

void TexturePreview::_update_metadata_label_text() {
	const Ref<Texture2D> texture = texture_display->get_texture();

	String format;
	if (Object::cast_to<ImageTexture>(*texture)) {
		format = Image::get_format_name(Object::cast_to<ImageTexture>(*texture)->get_format());
	} else if (Object::cast_to<CompressedTexture2D>(*texture)) {
		format = Image::get_format_name(Object::cast_to<CompressedTexture2D>(*texture)->get_format());
	} else {
		format = texture->get_class();
	}

	const Ref<Image> image = texture->get_image();
	if (image.is_valid()) {
		const int mipmaps = image->get_mipmap_count();
		// Avoid signed integer overflow that could occur with huge texture sizes by casting everything to uint64_t.
		uint64_t memory = uint64_t(image->get_width()) * uint64_t(image->get_height()) * uint64_t(Image::get_format_pixel_size(image->get_format()));
		// Handle VRAM-compressed formats that are stored with 4 bpp.
		memory >>= Image::get_format_pixel_rshift(image->get_format());

		float mipmaps_multiplier = 1.0;
		float mipmap_increase = 0.25;
		for (int i = 0; i < mipmaps; i++) {
			// Each mip adds 25% memory usage of the previous one.
			// With a complete mipmap chain, memory usage increases by ~33%.
			mipmaps_multiplier += mipmap_increase;