From 5ad8edbc0454e93e41d48085a227807293cb845c Mon Sep 17 00:00:00 2001 From: Soreepeong Date: Sun, 3 Mar 2024 21:00:37 +0900 Subject: [PATCH] Move save get/save functions to ITextureReadbackProvider --- .../Windows/Data/Widgets/TexWidget.cs | 36 +++--- .../TextureManager.FromExistingTexture.cs | 8 +- .../Textures/Internal/TextureManager.Wic.cs | 4 +- .../Textures/Internal/TextureManager.cs | 3 +- ...tionArgs.cs => TextureModificationArgs.cs} | 8 +- Dalamud/Plugin/Services/ITextureProvider.cs | 92 +--------------- .../Services/ITextureReadbackProvider.cs | 104 ++++++++++++++++++ 7 files changed, 135 insertions(+), 120 deletions(-) rename Dalamud/Interface/Textures/{ExistingTextureModificationArgs.cs => TextureModificationArgs.cs} (92%) create mode 100644 Dalamud/Plugin/Services/ITextureReadbackProvider.cs diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs index 6de891189..092b3f74f 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs @@ -51,7 +51,7 @@ internal class TexWidget : IDataWindowWidget private Vector2 inputTexScale = Vector2.Zero; private TextureManager textureManager = null!; private FileDialogManager fileDialogManager = null!; - private ExistingTextureModificationArgs existingTextureModificationArgs; + private TextureModificationArgs textureModificationArgs; private ImGuiViewportTextureArgs viewportTextureArgs; private int viewportIndexInt; @@ -88,7 +88,7 @@ internal class TexWidget : IDataWindowWidget this.supportedRenderTargetFormatNames = null; this.renderTargetChoiceInt = 0; this.fileDialogManager = new(); - this.existingTextureModificationArgs = new() + this.textureModificationArgs = new() { Uv0 = new(0.25f), Uv1 = new(0.75f), @@ -231,7 +231,7 @@ internal class TexWidget : IDataWindowWidget return; var texTask = this.textureManager.CreateFromExistingTextureAsync( source.CreateWrapSharingLowLevelResource(), - this.existingTextureModificationArgs with + this.textureModificationArgs with { Format = supportedFormats[this.renderTargetChoiceInt], }); @@ -626,9 +626,9 @@ internal class TexWidget : IDataWindowWidget private void DrawExistingTextureModificationArgs() { - var b = this.existingTextureModificationArgs.MakeOpaque; - if (ImGui.Checkbox(nameof(this.existingTextureModificationArgs.MakeOpaque), ref b)) - this.existingTextureModificationArgs.MakeOpaque = b; + var b = this.textureModificationArgs.MakeOpaque; + if (ImGui.Checkbox(nameof(this.textureModificationArgs.MakeOpaque), ref b)) + this.textureModificationArgs.MakeOpaque = b; if (this.supportedRenderTargetFormats is null) { @@ -642,29 +642,29 @@ internal class TexWidget : IDataWindowWidget this.supportedRenderTargetFormatNames ??= this.supportedRenderTargetFormats.Select(Enum.GetName).ToArray(); ImGui.Combo( - nameof(this.existingTextureModificationArgs.DxgiFormat), + nameof(this.textureModificationArgs.DxgiFormat), ref this.renderTargetChoiceInt, this.supportedRenderTargetFormatNames, this.supportedRenderTargetFormatNames.Length); Span wh = stackalloc int[2]; - wh[0] = this.existingTextureModificationArgs.NewWidth; - wh[1] = this.existingTextureModificationArgs.NewHeight; + wh[0] = this.textureModificationArgs.NewWidth; + wh[1] = this.textureModificationArgs.NewHeight; if (ImGui.InputInt2( - $"{nameof(this.existingTextureModificationArgs.NewWidth)}/{nameof(this.existingTextureModificationArgs.NewHeight)}", + $"{nameof(this.textureModificationArgs.NewWidth)}/{nameof(this.textureModificationArgs.NewHeight)}", ref wh[0])) { - this.existingTextureModificationArgs.NewWidth = wh[0]; - this.existingTextureModificationArgs.NewHeight = wh[1]; + this.textureModificationArgs.NewWidth = wh[0]; + this.textureModificationArgs.NewHeight = wh[1]; } - var vec2 = this.existingTextureModificationArgs.Uv0; - if (ImGui.InputFloat2(nameof(this.existingTextureModificationArgs.Uv0), ref vec2)) - this.existingTextureModificationArgs.Uv0 = vec2; + var vec2 = this.textureModificationArgs.Uv0; + if (ImGui.InputFloat2(nameof(this.textureModificationArgs.Uv0), ref vec2)) + this.textureModificationArgs.Uv0 = vec2; - vec2 = this.existingTextureModificationArgs.Uv1; - if (ImGui.InputFloat2(nameof(this.existingTextureModificationArgs.Uv1), ref vec2)) - this.existingTextureModificationArgs.Uv1 = vec2; + vec2 = this.textureModificationArgs.Uv1; + if (ImGui.InputFloat2(nameof(this.textureModificationArgs.Uv1), ref vec2)) + this.textureModificationArgs.Uv1 = vec2; ImGuiHelpers.ScaledDummy(10); } diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs b/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs index 067368ce5..2f9874217 100644 --- a/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs +++ b/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs @@ -45,7 +45,7 @@ internal sealed partial class TextureManager /// public Task CreateFromExistingTextureAsync( IDalamudTextureWrap wrap, - ExistingTextureModificationArgs args = default, + TextureModificationArgs args = default, bool leaveWrapOpen = false, CancellationToken cancellationToken = default) { @@ -94,9 +94,9 @@ internal sealed partial class TextureManager } /// - public async Task<(RawImageSpecification Specification, byte[] RawData)> GetRawDataFromExistingTextureAsync( + public async Task<(RawImageSpecification Specification, byte[] RawData)> GetRawImageAsync( IDalamudTextureWrap wrap, - ExistingTextureModificationArgs args = default, + TextureModificationArgs args = default, bool leaveWrapOpen = false, CancellationToken cancellationToken = default) { @@ -197,7 +197,7 @@ internal sealed partial class TextureManager private async Task> NoThrottleCreateFromExistingTextureAsync( IDalamudTextureWrap wrap, - ExistingTextureModificationArgs args) + TextureModificationArgs args) { args.ThrowOnInvalidValues(); diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.Wic.cs b/Dalamud/Interface/Textures/Internal/TextureManager.Wic.cs index b35864a17..3f8d9897c 100644 --- a/Dalamud/Interface/Textures/Internal/TextureManager.Wic.cs +++ b/Dalamud/Interface/Textures/Internal/TextureManager.Wic.cs @@ -71,7 +71,7 @@ internal sealed partial class TextureManager using var istream = ManagedIStream.Create(stream, leaveStreamOpen); - var (specs, bytes) = await this.GetRawDataFromExistingTextureAsync( + var (specs, bytes) = await this.GetRawImageAsync( wrap, new() { @@ -164,7 +164,7 @@ internal sealed partial class TextureManager this.Wic.GetSupportedDecoderInfos(); /// - IEnumerable ITextureProvider.GetSupportedImageEncoderInfos() => + IEnumerable ITextureReadbackProvider.GetSupportedImageEncoderInfos() => this.Wic.GetSupportedEncoderInfos(); /// Creates a texture from the given bytes of an image file. Skips the load throttler; intended to be used diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.cs b/Dalamud/Interface/Textures/Internal/TextureManager.cs index 921febe94..07f721587 100644 --- a/Dalamud/Interface/Textures/Internal/TextureManager.cs +++ b/Dalamud/Interface/Textures/Internal/TextureManager.cs @@ -29,7 +29,8 @@ namespace Dalamud.Interface.Textures.Internal; [ResolveVia] [ResolveVia] #pragma warning restore SA1015 -internal sealed partial class TextureManager : IServiceType, IDisposable, ITextureProvider, ITextureSubstitutionProvider +internal sealed partial class TextureManager + : IServiceType, IDisposable, ITextureProvider, ITextureSubstitutionProvider, ITextureReadbackProvider { private static readonly ModuleLog Log = new(nameof(TextureManager)); diff --git a/Dalamud/Interface/Textures/ExistingTextureModificationArgs.cs b/Dalamud/Interface/Textures/TextureModificationArgs.cs similarity index 92% rename from Dalamud/Interface/Textures/ExistingTextureModificationArgs.cs rename to Dalamud/Interface/Textures/TextureModificationArgs.cs index d4558c7eb..fac04189c 100644 --- a/Dalamud/Interface/Textures/ExistingTextureModificationArgs.cs +++ b/Dalamud/Interface/Textures/TextureModificationArgs.cs @@ -6,8 +6,8 @@ using TerraFX.Interop.DirectX; namespace Dalamud.Interface.Textures; -/// Describes how to modify an existing texture. -public record struct ExistingTextureModificationArgs() +/// Describes how to modify a texture. +public record struct TextureModificationArgs() { /// Gets or sets a value indicating whether to make the texture opaque. /// If true, then the alpha channel values will be filled with 1.0. @@ -52,10 +52,10 @@ public record struct ExistingTextureModificationArgs() /// Gets the effective value of . internal Vector2 Uv1Effective => this.Uv1 == Vector2.Zero ? Vector2.One : this.Uv1; - /// Test if this instance of does not instruct to change the + /// Test if this instance of does not instruct to change the /// underlying data of a texture. /// The texture description to test against. - /// true if this instance of does not instruct to + /// true if this instance of does not instruct to /// change the underlying data of a texture. internal bool IsCompleteSourceCopy(in D3D11_TEXTURE2D_DESC desc) => this.Uv0 == Vector2.Zero diff --git a/Dalamud/Plugin/Services/ITextureProvider.cs b/Dalamud/Plugin/Services/ITextureProvider.cs index f007b4649..59c9af2fc 100644 --- a/Dalamud/Plugin/Services/ITextureProvider.cs +++ b/Dalamud/Plugin/Services/ITextureProvider.cs @@ -41,7 +41,7 @@ public partial interface ITextureProvider /// This function may throw an exception. Task CreateFromExistingTextureAsync( IDalamudTextureWrap wrap, - ExistingTextureModificationArgs args = default, + TextureModificationArgs args = default, bool leaveWrapOpen = false, CancellationToken cancellationToken = default); @@ -151,17 +151,6 @@ public partial interface ITextureProvider /// IEnumerable GetSupportedImageDecoderInfos(); - /// Gets the supported bitmap encoders. - /// The supported bitmap encoders. - /// - /// The following function supports the files of the container types pointed by yielded values. - ///
    - ///
  • - ///
- /// This function may throw an exception. - ///
- IEnumerable GetSupportedImageEncoderInfos(); - /// Gets a shared texture corresponding to the given game resource icon specifier. /// A game icon specifier. /// The shared texture that you may use to obtain the loaded texture wrap and load states. @@ -208,85 +197,6 @@ public partial interface ITextureProvider /// This function does not throw exceptions. bool TryGetIconPath(in GameIconLookup lookup, [NotNullWhen(true)] out string? path); - /// Gets the raw data of a texture wrap. - /// The source texture wrap. - /// The texture modification arguments. - /// Whether to leave non-disposed when the returned - /// completes. - /// The cancellation token. - /// The raw data and its specifications. - /// - /// The length of the returned RawData may not match - /// * . - /// This function may throw an exception. - /// - Task<(RawImageSpecification Specification, byte[] RawData)> GetRawDataFromExistingTextureAsync( - IDalamudTextureWrap wrap, - ExistingTextureModificationArgs args = default, - bool leaveWrapOpen = false, - CancellationToken cancellationToken = default); - - /// Saves a texture wrap to a stream in an image file format. - /// The texture wrap to save. - /// The container GUID, obtained from . - /// The stream to save to. - /// Properties to pass to the encoder. See remarks for valid values. - /// Whether to leave non-disposed when the returned - /// completes. - /// Whether to leave open when the returned - /// completes. - /// The cancellation token. - /// A task representing the save process. - /// - /// must not be disposed until the task finishes. - /// See the following webpages for the valid values for per - /// . - /// - /// This function may throw an exception. - /// - Task SaveToStreamAsync( - IDalamudTextureWrap wrap, - Guid containerGuid, - Stream stream, - IReadOnlyDictionary? props = null, - bool leaveWrapOpen = false, - bool leaveStreamOpen = false, - CancellationToken cancellationToken = default); - - /// Saves a texture wrap to a file as an image file. - /// The texture wrap to save. - /// The container GUID, obtained from . - /// The target file path. The target file will be overwritten if it exist. - /// Properties to pass to the encoder. See remarks for valid values. - /// Whether to leave non-disposed when the returned - /// completes. - /// The cancellation token. - /// A task representing the save process. - /// - /// must not be disposed until the task finishes. - /// See the following webpages for the valid values for per - /// . - /// - /// This function may throw an exception. - /// - Task SaveToFileAsync( - IDalamudTextureWrap wrap, - Guid containerGuid, - string path, - IReadOnlyDictionary? props = null, - bool leaveWrapOpen = false, - CancellationToken cancellationToken = default); - /// /// Determines whether the system supports the given DXGI format. /// For use with . diff --git a/Dalamud/Plugin/Services/ITextureReadbackProvider.cs b/Dalamud/Plugin/Services/ITextureReadbackProvider.cs new file mode 100644 index 000000000..fa666c3c2 --- /dev/null +++ b/Dalamud/Plugin/Services/ITextureReadbackProvider.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +using Dalamud.Interface.Internal; +using Dalamud.Interface.Textures; + +namespace Dalamud.Plugin.Services; + +/// Service that grants you to read instances of . +public interface ITextureReadbackProvider +{ + /// Gets the raw data of a texture wrap. + /// The source texture wrap. + /// The texture modification arguments. + /// Whether to leave non-disposed when the returned + /// completes. + /// The cancellation token. + /// The raw data and its specifications. + /// + /// The length of the returned RawData may not match + /// * . + /// This function may throw an exception. + /// + Task<(RawImageSpecification Specification, byte[] RawData)> GetRawImageAsync( + IDalamudTextureWrap wrap, + TextureModificationArgs args = default, + bool leaveWrapOpen = false, + CancellationToken cancellationToken = default); + + /// Gets the supported bitmap encoders. + /// The supported bitmap encoders. + /// + /// The following functions support the files of the container types pointed by yielded values. + ///
    + ///
  • + ///
  • + ///
+ /// This function may throw an exception. + ///
+ IEnumerable GetSupportedImageEncoderInfos(); + + /// Saves a texture wrap to a stream in an image file format. + /// The texture wrap to save. + /// The container GUID, obtained from . + /// The stream to save to. + /// Properties to pass to the encoder. See remarks for valid values. + /// Whether to leave non-disposed when the returned + /// completes. + /// Whether to leave open when the returned + /// completes. + /// The cancellation token. + /// A task representing the save process. + /// + /// must not be disposed until the task finishes. + /// See the following webpages for the valid values for per + /// . + /// + /// This function may throw an exception. + /// + Task SaveToStreamAsync( + IDalamudTextureWrap wrap, + Guid containerGuid, + Stream stream, + IReadOnlyDictionary? props = null, + bool leaveWrapOpen = false, + bool leaveStreamOpen = false, + CancellationToken cancellationToken = default); + + /// Saves a texture wrap to a file as an image file. + /// The texture wrap to save. + /// The container GUID, obtained from . + /// The target file path. The target file will be overwritten if it exist. + /// Properties to pass to the encoder. See remarks for valid values. + /// Whether to leave non-disposed when the returned + /// completes. + /// The cancellation token. + /// A task representing the save process. + /// + /// must not be disposed until the task finishes. + /// See the following webpages for the valid values for per + /// . + /// + /// This function may throw an exception. + /// + Task SaveToFileAsync( + IDalamudTextureWrap wrap, + Guid containerGuid, + string path, + IReadOnlyDictionary? props = null, + bool leaveWrapOpen = false, + CancellationToken cancellationToken = default); +}