Repository: godotengine/godot
File: editor/import/resource_importer_texture_atlas.cpp (C++)

Code before:

	for (int i = 0; i < pack_data_files.size(); i++) {
		PackData &pack_data = pack_data_files.write[i];

		for (int j = 0; j < pack_data.chart_pieces.size(); j++) {
			const EditorAtlasPacker::Chart &chart = charts[pack_data.chart_pieces[j]];
			for (int k = 0; k < chart.faces.size(); k++) {
				Vector2i positions[3];
				for (int l = 0; l < 3; l++) {
					int vertex_idx = chart.faces[k].vertex[l];
					positions[l] = Vector2i(chart.vertices[vertex_idx]);
				}

				_plot_triangle(positions, Vector2i(chart.final_offset), chart.transposed, new_atlas, pack_data.image);
			}
		}
	}

	//save the atlas

	new_atlas->save_png(p_group_file);

	//update cache if existing, else create
	Ref<Texture2D> cache;
	if (ResourceCache::has(p_group_file)) {
		Resource *resptr = ResourceCache::get(p_group_file);
		cache.reference_ptr(resptr);
	} else {
		Ref<ImageTexture> res_cache;
		res_cache.instantiate();
		res_cache->create_from_image(new_atlas);
		res_cache->set_path(p_group_file);
		cache = res_cache;
	}

	//save the images
	idx = 0;
	for (const KeyValue<String, HashMap<StringName, Variant>> &E : p_source_file_options) {
		PackData &pack_data = pack_data_files.write[idx];

		Ref<Texture2D> texture;

		if (!pack_data.is_mesh) {
			Vector2 offset = charts[pack_data.chart_pieces[0]].vertices[0] + charts[pack_data.chart_pieces[0]].final_offset;

			//region
			Ref<AtlasTexture> atlas_texture;
			atlas_texture.instantiate();
			atlas_texture->set_atlas(cache);
			atlas_texture->set_region(Rect2(offset, pack_data.region.size));


Review comment (bug):
Would it be interesting that `ResourceCache` had a function like `get_or_create_ref()` one can use in cases like this to ensure no race conditions between two threads trying to create a resource with the same path?

Code after:

	for (int i = 0; i < pack_data_files.size(); i++) {
		PackData &pack_data = pack_data_files.write[i];

		for (int j = 0; j < pack_data.chart_pieces.size(); j++) {
			const EditorAtlasPacker::Chart &chart = charts[pack_data.chart_pieces[j]];
			for (int k = 0; k < chart.faces.size(); k++) {
				Vector2i positions[3];
				for (int l = 0; l < 3; l++) {
					int vertex_idx = chart.faces[k].vertex[l];
					positions[l] = Vector2i(chart.vertices[vertex_idx]);
				}

				_plot_triangle(positions, Vector2i(chart.final_offset), chart.transposed, new_atlas, pack_data.image);
			}
		}
	}

	//save the atlas

	new_atlas->save_png(p_group_file);

	//update cache if existing, else create
	Ref<Texture2D> cache;
	cache = ResourceCache::get_ref(p_group_file);
	if (!cache.is_valid()) {
		Ref<ImageTexture> res_cache;
		res_cache.instantiate();
		res_cache->create_from_image(new_atlas);
		res_cache->set_path(p_group_file);
		cache = res_cache;
	}

	//save the images
	idx = 0;
	for (const KeyValue<String, HashMap<StringName, Variant>> &E : p_source_file_options) {
		PackData &pack_data = pack_data_files.write[idx];

		Ref<Texture2D> texture;

		if (!pack_data.is_mesh) {
			Vector2 offset = charts[pack_data.chart_pieces[0]].vertices[0] + charts[pack_data.chart_pieces[0]].final_offset;

			//region
			Ref<AtlasTexture> atlas_texture;
			atlas_texture.instantiate();
			atlas_texture->set_atlas(cache);
			atlas_texture->set_region(Rect2(offset, pack_data.region.size));

			if (!pack_data.is_cropped) {
				atlas_texture->set_margin(Rect2(pack_data.region.position, pack_data.image->get_size() - pack_data.region.size));