Move ImageLoader and CompressedImageSaver to bevy_image. (#15812)

# Objective

This is a follow-up to #15650. While the core `Image` stuff moved from
`bevy_render` to `bevy_image`, the `ImageLoader` and the
`CompressedImageSaver` remained in `bevy_render`.

## Solution

I moved `ImageLoader` and `CompressedImageSaver` to `bevy_image` and
re-exported everything out from `bevy_render`. The second step isn't
strictly necessary, but `bevy_render` is already doing this for all the
other `bevy_image` types, so I kept it the same for consistency.

Unfortunately I had to give `ImageLoader` a constructor so I can keep
the `RenderDevice` stuff in `bevy_render`.

## Testing

It compiles!

## Migration Guide

- `ImageLoader` can no longer be initialized directly through
`init_asset_loader`. Now you must use
`app.register_asset_loader(ImageLoader::new(supported_compressed_formats))`
(check out the implementation of `bevy_render::ImagePlugin`). This only
affects you if you are initializing the loader manually and does not
affect users of `bevy_render::ImagePlugin`.

## Followup work

- We should be able to move most of the `ImagePlugin` to `bevy_image`.
This would likely require an `ImagePlugin` and a `RenderImagePlugin` or
something though.
This commit is contained in:
andriyDev 2024-10-14 19:18:10 -07:00 committed by GitHub
parent 345f935b1a
commit 73f7fd0c12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 34 additions and 36 deletions

View file

@ -1,4 +1,5 @@
use super::{Image, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderSettings};
use crate::{Image, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderSettings};
use bevy_asset::saver::{AssetSaver, SavedAsset};
use derive_more::derive::{Display, Error, From};
use futures_lite::AsyncWriteExt;

View file

@ -1,13 +1,7 @@
use bevy_asset::{io::Reader, AssetLoader, LoadContext};
use bevy_ecs::prelude::{FromWorld, World};
use crate::image::{Image, ImageFormat, ImageType, TextureError};
use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages};
use derive_more::derive::{Display, Error, From};
use crate::{
render_asset::RenderAssetUsages,
renderer::RenderDevice,
texture::{Image, ImageFormat, ImageType, TextureError},
};
use super::{CompressedImageFormats, ImageSampler};
use serde::{Deserialize, Serialize};
@ -17,6 +11,15 @@ pub struct ImageLoader {
supported_compressed_formats: CompressedImageFormats,
}
impl ImageLoader {
/// Creates a new image loader that supports the provided formats.
pub fn new(supported_compressed_formats: CompressedImageFormats) -> Self {
Self {
supported_compressed_formats,
}
}
}
#[derive(Serialize, Deserialize, Default, Debug)]
pub enum ImageFormatSetting {
#[default]
@ -106,19 +109,6 @@ impl AssetLoader for ImageLoader {
}
}
impl FromWorld for ImageLoader {
fn from_world(world: &mut World) -> Self {
let supported_compressed_formats = match world.get_resource::<RenderDevice>() {
Some(render_device) => CompressedImageFormats::from_features(render_device.features()),
None => CompressedImageFormats::NONE,
};
Self {
supported_compressed_formats,
}
}
}
/// An error that occurs when loading a texture from a file.
#[derive(Error, Display, Debug)]
#[display("Error reading image file {path}: {error}, this is an error in `bevy_render`.")]

View file

@ -6,23 +6,29 @@ mod image;
pub use self::image::*;
#[cfg(feature = "basis-universal")]
mod basis;
#[cfg(feature = "basis-universal")]
mod compressed_image_saver;
#[cfg(feature = "dds")]
mod dds;
#[cfg(feature = "exr")]
mod exr_texture_loader;
#[cfg(feature = "hdr")]
mod hdr_texture_loader;
mod image_loader;
#[cfg(feature = "ktx2")]
mod ktx2;
#[cfg(feature = "ktx2")]
pub use self::ktx2::*;
#[cfg(feature = "basis-universal")]
pub use compressed_image_saver::*;
#[cfg(feature = "dds")]
pub use dds::*;
#[cfg(feature = "exr")]
pub use exr_texture_loader::*;
#[cfg(feature = "hdr")]
pub use hdr_texture_loader::*;
pub use image_loader::*;
#[cfg(feature = "ktx2")]
pub use ktx2::*;
pub(crate) mod image_texture_conversion;
pub use image_texture_conversion::IntoDynamicImageError;

View file

@ -10,7 +10,7 @@ keywords = ["bevy"]
[features]
# Texture formats (require more than just image support)
basis-universal = ["dep:basis-universal", "bevy_image/basis-universal"]
basis-universal = ["bevy_image/basis-universal"]
dds = ["bevy_image/dds"]
exr = ["bevy_image/exr"]
hdr = ["bevy_image/hdr"]
@ -85,8 +85,6 @@ derive_more = { version = "1", default-features = false, features = [
] }
futures-lite = "2.0.1"
ktx2 = { version = "0.3.0", optional = true }
# For transcoding of UASTC/ETC1S universal formats, and for .basis file support
basis-universal = { version = "0.3.0", optional = true }
encase = { version = "0.10", features = ["glam"] }
# For wgpu profiling using tracing. Use `RUST_LOG=info` to also capture the wgpu spans.
profiling = { version = "1", features = [

View file

@ -1,8 +1,5 @@
#[cfg(feature = "basis-universal")]
mod compressed_image_saver;
mod fallback_image;
mod gpu_image;
mod image_loader;
mod texture_attachment;
mod texture_cache;
@ -12,15 +9,15 @@ pub use bevy_image::ExrTextureLoader;
#[cfg(feature = "hdr")]
pub use bevy_image::HdrTextureLoader;
pub use bevy_image::{
BevyDefault, CompressedImageFormats, Image, ImageAddressMode, ImageFilterMode, ImageFormat,
ImageSampler, ImageSamplerDescriptor, ImageType, IntoDynamicImageError, TextureError,
TextureFormatPixelInfo,
BevyDefault, CompressedImageFormats, FileTextureError, Image, ImageAddressMode,
ImageFilterMode, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderError,
ImageLoaderSettings, ImageSampler, ImageSamplerDescriptor, ImageType, IntoDynamicImageError,
TextureError, TextureFormatPixelInfo,
};
#[cfg(feature = "basis-universal")]
pub use compressed_image_saver::*;
pub use bevy_image::{CompressedImageSaver, CompressedImageSaverError};
pub use fallback_image::*;
pub use gpu_image::*;
pub use image_loader::*;
pub use texture_attachment::*;
pub use texture_cache::*;
@ -121,7 +118,13 @@ impl Plugin for ImagePlugin {
fn finish(&self, app: &mut App) {
if !ImageFormat::SUPPORTED.is_empty() {
app.init_asset_loader::<ImageLoader>();
let supported_compressed_formats = match app.world().get_resource::<RenderDevice>() {
Some(render_device) => {
CompressedImageFormats::from_features(render_device.features())
}
None => CompressedImageFormats::NONE,
};
app.register_asset_loader(ImageLoader::new(supported_compressed_formats));
}
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {