mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-02 13:53:40 +01:00
More cleanup
This commit is contained in:
parent
3415df5d40
commit
3853191c48
7 changed files with 226 additions and 196 deletions
|
|
@ -216,13 +216,37 @@ internal class TexWidget : IDataWindowWidget
|
||||||
if (this.renderTargetChoiceInt < 0 || this.renderTargetChoiceInt >= supportedFormats.Length)
|
if (this.renderTargetChoiceInt < 0 || this.renderTargetChoiceInt >= supportedFormats.Length)
|
||||||
return;
|
return;
|
||||||
var texTask = this.textureManager.CreateFromExistingTextureAsync(
|
var texTask = this.textureManager.CreateFromExistingTextureAsync(
|
||||||
source,
|
source.CreateWrapSharingLowLevelResource(),
|
||||||
new(0.25f),
|
new(0.25f),
|
||||||
new(0.75f),
|
new(0.75f),
|
||||||
supportedFormats[this.renderTargetChoiceInt]);
|
supportedFormats[this.renderTargetChoiceInt]);
|
||||||
this.addedTextures.Add(new() { Api10 = texTask });
|
this.addedTextures.Add(new() { Api10 = texTask });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
if (t.GetTexture(this.textureManager) is { } source)
|
||||||
|
{
|
||||||
|
var psrv = (ID3D11ShaderResourceView*)source.ImGuiHandle;
|
||||||
|
var rcsrv = psrv->AddRef() - 1;
|
||||||
|
psrv->Release();
|
||||||
|
|
||||||
|
var pres = default(ID3D11Resource*);
|
||||||
|
psrv->GetResource(&pres);
|
||||||
|
var rcres = pres->AddRef() - 1;
|
||||||
|
pres->Release();
|
||||||
|
pres->Release();
|
||||||
|
|
||||||
|
ImGui.TextUnformatted($"RC: Resource({rcres})/View({rcsrv})");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("RC: -");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,6 @@ using ImGuiScene;
|
||||||
|
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
|
|
||||||
using SharpDX;
|
|
||||||
using SharpDX.Direct3D11;
|
|
||||||
using SharpDX.DXGI;
|
|
||||||
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
|
|
||||||
namespace Dalamud.Interface.ManagedFontAtlas.Internals;
|
namespace Dalamud.Interface.ManagedFontAtlas.Internals;
|
||||||
|
|
@ -249,31 +245,12 @@ internal sealed partial class FontAtlasFactory
|
||||||
var fileIndex = textureIndex / 4;
|
var fileIndex = textureIndex / 4;
|
||||||
var channelIndex = FdtReader.FontTableEntry.TextureChannelOrder[textureIndex % 4];
|
var channelIndex = FdtReader.FontTableEntry.TextureChannelOrder[textureIndex % 4];
|
||||||
wraps[textureIndex] ??= this.GetChannelTexture(texPathFormat, fileIndex, channelIndex);
|
wraps[textureIndex] ??= this.GetChannelTexture(texPathFormat, fileIndex, channelIndex);
|
||||||
return CloneTextureWrap(wraps[textureIndex]);
|
return wraps[textureIndex].CreateWrapSharingLowLevelResource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T ExtractResult<T>(Task<T> t) => t.IsCompleted ? t.Result : t.GetAwaiter().GetResult();
|
private static T ExtractResult<T>(Task<T> t) => t.IsCompleted ? t.Result : t.GetAwaiter().GetResult();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clones a texture wrap, by getting a new reference to the underlying <see cref="ShaderResourceView"/> and the
|
|
||||||
/// texture behind.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="wrap">The <see cref="IDalamudTextureWrap"/> to clone from.</param>
|
|
||||||
/// <returns>The cloned <see cref="IDalamudTextureWrap"/>.</returns>
|
|
||||||
private static IDalamudTextureWrap CloneTextureWrap(IDalamudTextureWrap wrap)
|
|
||||||
{
|
|
||||||
var srv = CppObject.FromPointer<ShaderResourceView>(wrap.ImGuiHandle);
|
|
||||||
using var res = srv.Resource;
|
|
||||||
using var tex2D = res.QueryInterface<Texture2D>();
|
|
||||||
var description = tex2D.Description;
|
|
||||||
return new DalamudTextureWrap(
|
|
||||||
new D3DTextureWrap(
|
|
||||||
srv.QueryInterface<ShaderResourceView>(),
|
|
||||||
description.Width,
|
|
||||||
description.Height));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static unsafe void ExtractChannelFromB8G8R8A8(
|
private static unsafe void ExtractChannelFromB8G8R8A8(
|
||||||
Span<byte> target,
|
Span<byte> target,
|
||||||
ReadOnlySpan<byte> source,
|
ReadOnlySpan<byte> source,
|
||||||
|
|
@ -384,7 +361,9 @@ internal sealed partial class FontAtlasFactory
|
||||||
texFile.Header.Width,
|
texFile.Header.Width,
|
||||||
texFile.Header.Height,
|
texFile.Header.Height,
|
||||||
texFile.Header.Width * bpp,
|
texFile.Header.Width * bpp,
|
||||||
(int)(targetIsB4G4R4A4 ? Format.B4G4R4A4_UNorm : Format.B8G8R8A8_UNorm)),
|
(int)(targetIsB4G4R4A4
|
||||||
|
? DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM
|
||||||
|
: DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM)),
|
||||||
buffer));
|
buffer));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -72,18 +72,21 @@ internal class TextureLoadThrottler : IServiceType, IDisposable
|
||||||
/// <param name="basis">The throttle basis.</param>
|
/// <param name="basis">The throttle basis.</param>
|
||||||
/// <param name="immediateLoadFunction">The immediate load function.</param>
|
/// <param name="immediateLoadFunction">The immediate load function.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <param name="disposables">Disposables to dispose when the task completes.</param>
|
||||||
/// <returns>The task.</returns>
|
/// <returns>The task.</returns>
|
||||||
public Task<IDalamudTextureWrap> LoadTextureAsync(
|
public Task<IDalamudTextureWrap> LoadTextureAsync(
|
||||||
IThrottleBasisProvider basis,
|
IThrottleBasisProvider basis,
|
||||||
Func<CancellationToken, Task<IDalamudTextureWrap>> immediateLoadFunction,
|
Func<CancellationToken, Task<IDalamudTextureWrap>> immediateLoadFunction,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken,
|
||||||
|
params IDisposable?[] disposables)
|
||||||
{
|
{
|
||||||
var work = new WorkItem(basis, immediateLoadFunction, cancellationToken);
|
var work = new WorkItem(basis, immediateLoadFunction, cancellationToken, disposables);
|
||||||
|
|
||||||
return
|
if (this.newItemChannel.Writer.TryWrite(work))
|
||||||
this.newItemChannel.Writer.TryWrite(work)
|
return work.Task;
|
||||||
? work.Task
|
|
||||||
: Task.FromException<IDalamudTextureWrap>(new ObjectDisposedException(nameof(TextureLoadThrottler)));
|
work.Dispose();
|
||||||
|
return Task.FromException<IDalamudTextureWrap>(new ObjectDisposedException(nameof(TextureLoadThrottler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoopAddWorkItemAsync()
|
private async Task LoopAddWorkItemAsync()
|
||||||
|
|
@ -118,6 +121,7 @@ internal class TextureLoadThrottler : IServiceType, IDisposable
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
await work.Process(this.disposeCancellationTokenSource.Token);
|
await work.Process(this.disposeCancellationTokenSource.Token);
|
||||||
|
work.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,6 +140,7 @@ internal class TextureLoadThrottler : IServiceType, IDisposable
|
||||||
{
|
{
|
||||||
if (itemRef.CancelAsRequested())
|
if (itemRef.CancelAsRequested())
|
||||||
{
|
{
|
||||||
|
itemRef.Dispose();
|
||||||
itemRef = lastRef;
|
itemRef = lastRef;
|
||||||
this.workItemPending.RemoveAt(this.workItemPending.Count - 1);
|
this.workItemPending.RemoveAt(this.workItemPending.Count - 1);
|
||||||
break;
|
break;
|
||||||
|
|
@ -152,7 +157,13 @@ internal class TextureLoadThrottler : IServiceType, IDisposable
|
||||||
|
|
||||||
var last = this.workItemPending[^1];
|
var last = this.workItemPending[^1];
|
||||||
this.workItemPending.RemoveAt(this.workItemPending.Count - 1);
|
this.workItemPending.RemoveAt(this.workItemPending.Count - 1);
|
||||||
return last.CancelAsRequested() ? null : last;
|
if (last.CancelAsRequested())
|
||||||
|
{
|
||||||
|
last.Dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,26 +182,34 @@ internal class TextureLoadThrottler : IServiceType, IDisposable
|
||||||
public long LatestRequestedTick { get; init; } = Environment.TickCount64;
|
public long LatestRequestedTick { get; init; } = Environment.TickCount64;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WorkItem : IComparable<WorkItem>
|
private sealed class WorkItem : IComparable<WorkItem>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TaskCompletionSource<IDalamudTextureWrap> taskCompletionSource;
|
private readonly TaskCompletionSource<IDalamudTextureWrap> taskCompletionSource;
|
||||||
private readonly IThrottleBasisProvider basis;
|
private readonly IThrottleBasisProvider basis;
|
||||||
private readonly CancellationToken cancellationToken;
|
private readonly CancellationToken cancellationToken;
|
||||||
private readonly Func<CancellationToken, Task<IDalamudTextureWrap>> immediateLoadFunction;
|
private readonly Func<CancellationToken, Task<IDalamudTextureWrap>> immediateLoadFunction;
|
||||||
|
private readonly IDisposable?[] disposables;
|
||||||
|
|
||||||
public WorkItem(
|
public WorkItem(
|
||||||
IThrottleBasisProvider basis,
|
IThrottleBasisProvider basis,
|
||||||
Func<CancellationToken, Task<IDalamudTextureWrap>> immediateLoadFunction,
|
Func<CancellationToken, Task<IDalamudTextureWrap>> immediateLoadFunction,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken, IDisposable?[] disposables)
|
||||||
{
|
{
|
||||||
this.taskCompletionSource = new();
|
this.taskCompletionSource = new();
|
||||||
this.basis = basis;
|
this.basis = basis;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
|
this.disposables = disposables;
|
||||||
this.immediateLoadFunction = immediateLoadFunction;
|
this.immediateLoadFunction = immediateLoadFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IDalamudTextureWrap> Task => this.taskCompletionSource.Task;
|
public Task<IDalamudTextureWrap> Task => this.taskCompletionSource.Task;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (ref var d in this.disposables.AsSpan())
|
||||||
|
Interlocked.Exchange(ref d, null)?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
public int CompareTo(WorkItem other)
|
public int CompareTo(WorkItem other)
|
||||||
{
|
{
|
||||||
if (this.basis.IsOpportunistic != other.basis.IsOpportunistic)
|
if (this.basis.IsOpportunistic != other.basis.IsOpportunistic)
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@ using Dalamud.Utility;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
using SharpDX.Direct3D11;
|
|
||||||
using SharpDX.DXGI;
|
|
||||||
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
|
|
@ -28,14 +25,8 @@ internal sealed partial class TextureManager
|
||||||
this.IsDxgiFormatSupportedForCreateFromExistingTextureAsync((DXGI_FORMAT)dxgiFormat);
|
this.IsDxgiFormatSupportedForCreateFromExistingTextureAsync((DXGI_FORMAT)dxgiFormat);
|
||||||
|
|
||||||
/// <inheritdoc cref="ITextureProvider.IsDxgiFormatSupportedForCreateFromExistingTextureAsync"/>
|
/// <inheritdoc cref="ITextureProvider.IsDxgiFormatSupportedForCreateFromExistingTextureAsync"/>
|
||||||
public bool IsDxgiFormatSupportedForCreateFromExistingTextureAsync(DXGI_FORMAT dxgiFormat)
|
public unsafe bool IsDxgiFormatSupportedForCreateFromExistingTextureAsync(DXGI_FORMAT dxgiFormat)
|
||||||
{
|
{
|
||||||
if (this.interfaceManager.Scene is not { } scene)
|
|
||||||
{
|
|
||||||
_ = Service<InterfaceManager.InterfaceManagerWithScene>.Get();
|
|
||||||
scene = this.interfaceManager.Scene ?? throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (dxgiFormat)
|
switch (dxgiFormat)
|
||||||
{
|
{
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format
|
// https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format
|
||||||
|
|
@ -48,12 +39,14 @@ internal sealed partial class TextureManager
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var format = (Format)dxgiFormat;
|
D3D11_FORMAT_SUPPORT supported;
|
||||||
var support = scene.Device.CheckFormatSupport(format);
|
if (this.Device.Get()->CheckFormatSupport(dxgiFormat, (uint*)&supported).FAILED)
|
||||||
const FormatSupport required =
|
return false;
|
||||||
FormatSupport.RenderTarget |
|
|
||||||
FormatSupport.Texture2D;
|
const D3D11_FORMAT_SUPPORT required =
|
||||||
return (support & required) == required;
|
D3D11_FORMAT_SUPPORT.D3D11_FORMAT_SUPPORT_TEXTURE2D
|
||||||
|
| D3D11_FORMAT_SUPPORT.D3D11_FORMAT_SUPPORT_RENDER_TARGET;
|
||||||
|
return (supported & required) == required;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
@ -62,61 +55,56 @@ internal sealed partial class TextureManager
|
||||||
Vector2 uv0,
|
Vector2 uv0,
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
int dxgiFormat,
|
int dxgiFormat,
|
||||||
|
bool leaveWrapOpen,
|
||||||
CancellationToken cancellationToken) =>
|
CancellationToken cancellationToken) =>
|
||||||
this.CreateFromExistingTextureAsync(wrap, uv0, uv1, (DXGI_FORMAT)dxgiFormat, cancellationToken);
|
this.CreateFromExistingTextureAsync(
|
||||||
|
wrap,
|
||||||
|
uv0,
|
||||||
|
uv1,
|
||||||
|
(DXGI_FORMAT)dxgiFormat,
|
||||||
|
leaveWrapOpen,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
/// <inheritdoc cref="ITextureProvider.CreateFromExistingTextureAsync"/>
|
/// <inheritdoc cref="ITextureProvider.CreateFromExistingTextureAsync"/>
|
||||||
public Task<IDalamudTextureWrap> CreateFromExistingTextureAsync(
|
public Task<IDalamudTextureWrap> CreateFromExistingTextureAsync(
|
||||||
IDalamudTextureWrap wrap,
|
IDalamudTextureWrap wrap,
|
||||||
Vector2 uv0,
|
Vector2 uv0,
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
DXGI_FORMAT format,
|
DXGI_FORMAT format = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var wrapCopy = wrap.CreateWrapSharingLowLevelResource();
|
|
||||||
return this.textureLoadThrottler.LoadTextureAsync(
|
return this.textureLoadThrottler.LoadTextureAsync(
|
||||||
new TextureLoadThrottler.ReadOnlyThrottleBasisProvider(),
|
new TextureLoadThrottler.ReadOnlyThrottleBasisProvider(),
|
||||||
async _ =>
|
ImmediateLoadFunction,
|
||||||
{
|
cancellationToken,
|
||||||
using var tex = await this.NoThrottleCreateFromExistingTextureAsync(
|
leaveWrapOpen ? null : wrap);
|
||||||
wrapCopy,
|
|
||||||
uv0,
|
|
||||||
uv1,
|
|
||||||
format);
|
|
||||||
using var device = default(ComPtr<ID3D11Device>);
|
|
||||||
using var srv = default(ComPtr<ID3D11ShaderResourceView>);
|
|
||||||
var desc = default(D3D11_TEXTURE2D_DESC);
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
tex.Get()->GetDevice(device.GetAddressOf());
|
|
||||||
|
|
||||||
var srvDesc = new D3D11_SHADER_RESOURCE_VIEW_DESC(
|
async Task<IDalamudTextureWrap> ImmediateLoadFunction(CancellationToken ct)
|
||||||
tex,
|
{
|
||||||
D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D);
|
using var tex = await this.NoThrottleCreateFromExistingTextureAsync(wrap, uv0, uv1, format);
|
||||||
device.Get()->CreateShaderResourceView(
|
|
||||||
(ID3D11Resource*)tex.Get(),
|
|
||||||
&srvDesc,
|
|
||||||
srv.GetAddressOf())
|
|
||||||
.ThrowOnError();
|
|
||||||
|
|
||||||
tex.Get()->GetDesc(&desc);
|
unsafe
|
||||||
|
{
|
||||||
|
var srvDesc = new D3D11_SHADER_RESOURCE_VIEW_DESC(
|
||||||
|
tex,
|
||||||
|
D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D);
|
||||||
|
using var srv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||||
|
this.Device.Get()->CreateShaderResourceView(
|
||||||
|
(ID3D11Resource*)tex.Get(),
|
||||||
|
&srvDesc,
|
||||||
|
srv.GetAddressOf())
|
||||||
|
.ThrowOnError();
|
||||||
|
|
||||||
return new UnknownTextureWrap(
|
var desc = default(D3D11_TEXTURE2D_DESC);
|
||||||
(IUnknown*)srv.Get(),
|
tex.Get()->GetDesc(&desc);
|
||||||
(int)desc.Width,
|
return new UnknownTextureWrap(
|
||||||
(int)desc.Height,
|
(IUnknown*)srv.Get(),
|
||||||
true);
|
(int)desc.Width,
|
||||||
}
|
(int)desc.Height,
|
||||||
},
|
true);
|
||||||
cancellationToken)
|
}
|
||||||
.ContinueWith(
|
}
|
||||||
r =>
|
|
||||||
{
|
|
||||||
wrapCopy.Dispose();
|
|
||||||
return r;
|
|
||||||
},
|
|
||||||
default(CancellationToken))
|
|
||||||
.Unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
@ -125,34 +113,37 @@ internal sealed partial class TextureManager
|
||||||
Vector2 uv0,
|
Vector2 uv0,
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
int dxgiFormat,
|
int dxgiFormat,
|
||||||
|
bool leaveWrapOpen,
|
||||||
CancellationToken cancellationToken) =>
|
CancellationToken cancellationToken) =>
|
||||||
this.GetRawDataFromExistingTextureAsync(wrap, uv0, uv1, (DXGI_FORMAT)dxgiFormat, cancellationToken);
|
this.GetRawDataFromExistingTextureAsync(
|
||||||
|
wrap,
|
||||||
|
uv0,
|
||||||
|
uv1,
|
||||||
|
(DXGI_FORMAT)dxgiFormat,
|
||||||
|
leaveWrapOpen,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
/// <inheritdoc cref="ITextureProvider.GetRawDataFromExistingTextureAsync"/>
|
/// <inheritdoc cref="ITextureProvider.GetRawDataFromExistingTextureAsync"/>
|
||||||
public async Task<(RawImageSpecification Specification, byte[] RawData)> GetRawDataFromExistingTextureAsync(
|
public async Task<(RawImageSpecification Specification, byte[] RawData)> GetRawDataFromExistingTextureAsync(
|
||||||
IDalamudTextureWrap wrap,
|
IDalamudTextureWrap wrap,
|
||||||
Vector2 uv0,
|
Vector2 uv0,
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
DXGI_FORMAT dxgiFormat,
|
DXGI_FORMAT dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN,
|
||||||
CancellationToken cancellationToken)
|
bool leaveWrapOpen = false,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
using var resUnk = default(ComPtr<IUnknown>);
|
using var wrapDispose = leaveWrapOpen ? null : wrap;
|
||||||
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||||
using var device = default(ComPtr<ID3D11Device>);
|
|
||||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||||
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
||||||
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
resUnk.Attach((IUnknown*)wrap.ImGuiHandle);
|
fixed (Guid* piid = &IID.IID_ID3D11ShaderResourceView)
|
||||||
resUnk.Get()->AddRef();
|
((IUnknown*)wrap.ImGuiHandle)->QueryInterface(piid, (void**)texSrv.GetAddressOf()).ThrowOnError();
|
||||||
|
|
||||||
resUnk.As(&texSrv).ThrowOnError();
|
this.Device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||||
|
|
||||||
texSrv.Get()->GetDevice(device.GetAddressOf());
|
|
||||||
|
|
||||||
device.Get()->GetImmediateContext(context.GetAddressOf());
|
|
||||||
|
|
||||||
using (var texRes = default(ComPtr<ID3D11Resource>))
|
using (var texRes = default(ComPtr<ID3D11Resource>))
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +168,7 @@ internal sealed partial class TextureManager
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
return await this.interfaceManager.RunBeforePresent(
|
return await this.interfaceManager.RunBeforePresent(
|
||||||
() => ExtractMappedResource(device, context, tex2D, cancellationToken));
|
() => ExtractMappedResource(this.Device, context, tex2D, cancellationToken));
|
||||||
|
|
||||||
static unsafe (RawImageSpecification Specification, byte[] RawData) ExtractMappedResource(
|
static unsafe (RawImageSpecification Specification, byte[] RawData) ExtractMappedResource(
|
||||||
ComPtr<ID3D11Device> device,
|
ComPtr<ID3D11Device> device,
|
||||||
|
|
@ -242,28 +233,17 @@ internal sealed partial class TextureManager
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
DXGI_FORMAT format)
|
DXGI_FORMAT format)
|
||||||
{
|
{
|
||||||
using var resUnk = default(ComPtr<IUnknown>);
|
|
||||||
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||||
using var device = default(ComPtr<ID3D11Device>);
|
|
||||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||||
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
||||||
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
resUnk.Attach((IUnknown*)wrap.ImGuiHandle);
|
fixed (Guid* piid = &IID.IID_ID3D11ShaderResourceView)
|
||||||
resUnk.Get()->AddRef();
|
((IUnknown*)wrap.ImGuiHandle)->QueryInterface(piid, (void**)texSrv.GetAddressOf()).ThrowOnError();
|
||||||
|
|
||||||
using (var texSrv2 = default(ComPtr<ID3D11ShaderResourceView>))
|
this.Device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||||
{
|
|
||||||
resUnk.As(&texSrv2).ThrowOnError();
|
|
||||||
texSrv.Attach(texSrv2);
|
|
||||||
texSrv2.Detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
texSrv.Get()->GetDevice(device.GetAddressOf());
|
|
||||||
|
|
||||||
device.Get()->GetImmediateContext(context.GetAddressOf());
|
|
||||||
|
|
||||||
using (var texRes = default(ComPtr<ID3D11Resource>))
|
using (var texRes = default(ComPtr<ID3D11Resource>))
|
||||||
{
|
{
|
||||||
|
|
@ -274,6 +254,9 @@ internal sealed partial class TextureManager
|
||||||
tex2D.Get()->GetDesc(&texDesc);
|
tex2D.Get()->GetDesc(&texDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (format == DXGI_FORMAT.DXGI_FORMAT_UNKNOWN)
|
||||||
|
format = texDesc.Format;
|
||||||
|
|
||||||
var newWidth = checked((uint)MathF.Round((uv1.X - uv0.X) * texDesc.Width));
|
var newWidth = checked((uint)MathF.Round((uv1.X - uv0.X) * texDesc.Width));
|
||||||
var newHeight = checked((uint)MathF.Round((uv1.Y - uv0.Y) * texDesc.Height));
|
var newHeight = checked((uint)MathF.Round((uv1.Y - uv0.Y) * texDesc.Height));
|
||||||
|
|
||||||
|
|
@ -289,11 +272,12 @@ internal sealed partial class TextureManager
|
||||||
Format = format,
|
Format = format,
|
||||||
SampleDesc = new(1, 0),
|
SampleDesc = new(1, 0),
|
||||||
Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT,
|
Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT,
|
||||||
BindFlags = (uint)(D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_FLAG.D3D11_BIND_RENDER_TARGET),
|
BindFlags =
|
||||||
|
(uint)(D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_FLAG.D3D11_BIND_RENDER_TARGET),
|
||||||
CPUAccessFlags = 0u,
|
CPUAccessFlags = 0u,
|
||||||
MiscFlags = 0u,
|
MiscFlags = 0u,
|
||||||
};
|
};
|
||||||
device.Get()->CreateTexture2D(&tex2DCopyTempDesc, null, tex2DCopyTemp.GetAddressOf()).ThrowOnError();
|
this.Device.Get()->CreateTexture2D(&tex2DCopyTempDesc, null, tex2DCopyTemp.GetAddressOf()).ThrowOnError();
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.interfaceManager.RunBeforePresent(
|
await this.interfaceManager.RunBeforePresent(
|
||||||
|
|
@ -305,13 +289,13 @@ internal sealed partial class TextureManager
|
||||||
var rtvCopyTempDesc = new D3D11_RENDER_TARGET_VIEW_DESC(
|
var rtvCopyTempDesc = new D3D11_RENDER_TARGET_VIEW_DESC(
|
||||||
tex2DCopyTemp,
|
tex2DCopyTemp,
|
||||||
D3D11_RTV_DIMENSION.D3D11_RTV_DIMENSION_TEXTURE2D);
|
D3D11_RTV_DIMENSION.D3D11_RTV_DIMENSION_TEXTURE2D);
|
||||||
device.Get()->CreateRenderTargetView(
|
this.Device.Get()->CreateRenderTargetView(
|
||||||
(ID3D11Resource*)tex2DCopyTemp.Get(),
|
(ID3D11Resource*)tex2DCopyTemp.Get(),
|
||||||
&rtvCopyTempDesc,
|
&rtvCopyTempDesc,
|
||||||
rtvCopyTemp.GetAddressOf()).ThrowOnError();
|
rtvCopyTemp.GetAddressOf()).ThrowOnError();
|
||||||
|
|
||||||
this.drawsOneSquare ??= new();
|
this.drawsOneSquare ??= new();
|
||||||
this.drawsOneSquare.Setup(device.Get());
|
this.drawsOneSquare.Setup(this.Device.Get());
|
||||||
|
|
||||||
context.Get()->OMSetRenderTargets(1u, rtvCopyTemp.GetAddressOf(), null);
|
context.Get()->OMSetRenderTargets(1u, rtvCopyTemp.GetAddressOf(), null);
|
||||||
this.drawsOneSquare.Draw(
|
this.drawsOneSquare.Draw(
|
||||||
|
|
@ -593,6 +577,9 @@ internal sealed partial class TextureManager
|
||||||
ctx->DSSetShader(null, null, 0);
|
ctx->DSSetShader(null, null, 0);
|
||||||
ctx->CSSetShader(null, null, 0);
|
ctx->CSSetShader(null, null, 0);
|
||||||
ctx->DrawIndexed(6, 0, 0);
|
ctx->DrawIndexed(6, 0, 0);
|
||||||
|
|
||||||
|
var ppn = default(ID3D11ShaderResourceView*);
|
||||||
|
ctx->PSSetShaderResources(0, 1, &ppn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,23 +37,21 @@ internal sealed partial class TextureManager
|
||||||
IDalamudTextureWrap wrap,
|
IDalamudTextureWrap wrap,
|
||||||
Guid containerGuid,
|
Guid containerGuid,
|
||||||
Stream stream,
|
Stream stream,
|
||||||
bool leaveOpen = false,
|
|
||||||
IReadOnlyDictionary<string, object>? props = null,
|
IReadOnlyDictionary<string, object>? props = null,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
|
bool leaveStreamOpen = false,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
using var istream = ManagedIStream.Create(stream, leaveOpen);
|
using var wrapDispose = leaveWrapOpen ? null : wrap;
|
||||||
|
using var istream = ManagedIStream.Create(stream, leaveStreamOpen);
|
||||||
|
|
||||||
RawImageSpecification specs;
|
var (specs, bytes) = await this.GetRawDataFromExistingTextureAsync(
|
||||||
byte[] bytes;
|
wrap,
|
||||||
using (var wrapCopy = wrap.CreateWrapSharingLowLevelResource())
|
|
||||||
{
|
|
||||||
(specs, bytes) = await this.GetRawDataFromExistingTextureAsync(
|
|
||||||
wrapCopy,
|
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
Vector2.One,
|
Vector2.One,
|
||||||
DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM,
|
DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
true,
|
||||||
cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
}
|
|
||||||
|
|
||||||
this.Wic.SaveToStreamUsingWic(
|
this.Wic.SaveToStreamUsingWic(
|
||||||
specs,
|
specs,
|
||||||
|
|
@ -70,12 +68,21 @@ internal sealed partial class TextureManager
|
||||||
Guid containerGuid,
|
Guid containerGuid,
|
||||||
string path,
|
string path,
|
||||||
IReadOnlyDictionary<string, object>? props = null,
|
IReadOnlyDictionary<string, object>? props = null,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
using var wrapDispose = leaveWrapOpen ? null : wrap;
|
||||||
var pathTemp = $"{path}.{GetCurrentThreadId():X08}{Environment.TickCount64:X16}.tmp";
|
var pathTemp = $"{path}.{GetCurrentThreadId():X08}{Environment.TickCount64:X16}.tmp";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await this.SaveToStreamAsync(wrap, containerGuid, File.Create(pathTemp), false, props, cancellationToken);
|
await this.SaveToStreamAsync(
|
||||||
|
wrap,
|
||||||
|
containerGuid,
|
||||||
|
File.Create(pathTemp),
|
||||||
|
props,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
cancellationToken);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,8 @@ using Dalamud.Utility;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
|
|
||||||
using SharpDX;
|
|
||||||
using SharpDX.Direct3D;
|
|
||||||
using SharpDX.Direct3D11;
|
|
||||||
using SharpDX.DXGI;
|
|
||||||
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
namespace Dalamud.Interface.Textures.Internal;
|
namespace Dalamud.Interface.Textures.Internal;
|
||||||
|
|
||||||
|
|
@ -67,6 +63,23 @@ internal sealed partial class TextureManager : IServiceType, IDisposable, ITextu
|
||||||
this.wicManager = new(this);
|
this.wicManager = new(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Gets the D3D11 Device used to create textures.</summary>
|
||||||
|
public unsafe ComPtr<ID3D11Device> Device
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.interfaceManager.Scene is not { } scene)
|
||||||
|
{
|
||||||
|
_ = Service<InterfaceManager.InterfaceManagerWithScene>.Get();
|
||||||
|
scene = this.interfaceManager.Scene ?? throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var device = default(ComPtr<ID3D11Device>);
|
||||||
|
device.Attach((ID3D11Device*)scene.Device.NativePointer);
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Gets the shared texture manager.</summary>
|
/// <summary>Gets the shared texture manager.</summary>
|
||||||
public SharedTextureManager Shared =>
|
public SharedTextureManager Shared =>
|
||||||
this.sharedTextureManager ??
|
this.sharedTextureManager ??
|
||||||
|
|
@ -183,65 +196,54 @@ internal sealed partial class TextureManager : IServiceType, IDisposable, ITextu
|
||||||
this.IsDxgiFormatSupported((DXGI_FORMAT)dxgiFormat);
|
this.IsDxgiFormatSupported((DXGI_FORMAT)dxgiFormat);
|
||||||
|
|
||||||
/// <inheritdoc cref="ITextureProvider.IsDxgiFormatSupported"/>
|
/// <inheritdoc cref="ITextureProvider.IsDxgiFormatSupported"/>
|
||||||
public bool IsDxgiFormatSupported(DXGI_FORMAT dxgiFormat)
|
public unsafe bool IsDxgiFormatSupported(DXGI_FORMAT dxgiFormat)
|
||||||
{
|
{
|
||||||
if (this.interfaceManager.Scene is not { } scene)
|
D3D11_FORMAT_SUPPORT supported;
|
||||||
{
|
if (this.Device.Get()->CheckFormatSupport(dxgiFormat, (uint*)&supported).FAILED)
|
||||||
_ = Service<InterfaceManager.InterfaceManagerWithScene>.Get();
|
return false;
|
||||||
scene = this.interfaceManager.Scene ?? throw new InvalidOperationException();
|
|
||||||
}
|
const D3D11_FORMAT_SUPPORT required = D3D11_FORMAT_SUPPORT.D3D11_FORMAT_SUPPORT_TEXTURE2D;
|
||||||
|
return (supported & required) == required;
|
||||||
var format = (Format)dxgiFormat;
|
|
||||||
var support = scene.Device.CheckFormatSupport(format);
|
|
||||||
const FormatSupport required = FormatSupport.Texture2D;
|
|
||||||
return (support & required) == required;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ITextureProvider.CreateFromRaw"/>
|
/// <inheritdoc cref="ITextureProvider.CreateFromRaw"/>
|
||||||
internal IDalamudTextureWrap NoThrottleCreateFromRaw(
|
internal unsafe IDalamudTextureWrap NoThrottleCreateFromRaw(
|
||||||
RawImageSpecification specs,
|
RawImageSpecification specs,
|
||||||
ReadOnlySpan<byte> bytes)
|
ReadOnlySpan<byte> bytes)
|
||||||
{
|
{
|
||||||
if (this.interfaceManager.Scene is not { } scene)
|
var device = this.Device;
|
||||||
|
|
||||||
|
var texd = new D3D11_TEXTURE2D_DESC
|
||||||
{
|
{
|
||||||
_ = Service<InterfaceManager.InterfaceManagerWithScene>.Get();
|
Width = (uint)specs.Width,
|
||||||
scene = this.interfaceManager.Scene ?? throw new InvalidOperationException();
|
Height = (uint)specs.Height,
|
||||||
}
|
MipLevels = 1,
|
||||||
|
ArraySize = 1,
|
||||||
ShaderResourceView resView;
|
Format = (DXGI_FORMAT)specs.DxgiFormat,
|
||||||
unsafe
|
SampleDesc = new(1, 0),
|
||||||
|
Usage = D3D11_USAGE.D3D11_USAGE_IMMUTABLE,
|
||||||
|
BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE,
|
||||||
|
CPUAccessFlags = 0,
|
||||||
|
MiscFlags = 0,
|
||||||
|
};
|
||||||
|
using var texture = default(ComPtr<ID3D11Texture2D>);
|
||||||
|
fixed (void* dataPtr = bytes)
|
||||||
{
|
{
|
||||||
fixed (void* pData = bytes)
|
var subrdata = new D3D11_SUBRESOURCE_DATA { pSysMem = dataPtr, SysMemPitch = (uint)specs.Pitch };
|
||||||
{
|
device.Get()->CreateTexture2D(&texd, &subrdata, texture.GetAddressOf()).ThrowOnError();
|
||||||
var texDesc = new Texture2DDescription
|
|
||||||
{
|
|
||||||
Width = specs.Width,
|
|
||||||
Height = specs.Height,
|
|
||||||
MipLevels = 1,
|
|
||||||
ArraySize = 1,
|
|
||||||
Format = (Format)specs.DxgiFormat,
|
|
||||||
SampleDescription = new(1, 0),
|
|
||||||
Usage = ResourceUsage.Immutable,
|
|
||||||
BindFlags = BindFlags.ShaderResource,
|
|
||||||
CpuAccessFlags = CpuAccessFlags.None,
|
|
||||||
OptionFlags = ResourceOptionFlags.None,
|
|
||||||
};
|
|
||||||
|
|
||||||
using var texture = new Texture2D(scene.Device, texDesc, new DataRectangle(new(pData), specs.Pitch));
|
|
||||||
resView = new(
|
|
||||||
scene.Device,
|
|
||||||
texture,
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Format = texDesc.Format,
|
|
||||||
Dimension = ShaderResourceViewDimension.Texture2D,
|
|
||||||
Texture2D = { MipLevels = texDesc.MipLevels },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var viewDesc = new D3D11_SHADER_RESOURCE_VIEW_DESC
|
||||||
|
{
|
||||||
|
Format = texd.Format,
|
||||||
|
ViewDimension = D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D,
|
||||||
|
Texture2D = new() { MipLevels = texd.MipLevels },
|
||||||
|
};
|
||||||
|
using var view = default(ComPtr<ID3D11ShaderResourceView>);
|
||||||
|
device.Get()->CreateShaderResourceView((ID3D11Resource*)texture.Get(), &viewDesc, view.GetAddressOf())
|
||||||
|
.ThrowOnError();
|
||||||
|
|
||||||
// no sampler for now because the ImGui implementation we copied doesn't allow for changing it
|
return new UnknownTextureWrap((IUnknown*)view.Get(), specs.Width, specs.Height, true);
|
||||||
return new DalamudTextureWrap(new D3DTextureWrap(resView, specs.Width, specs.Height));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Creates a texture from the given <see cref="TexFile"/>. Skips the load throttler; intended to be used
|
/// <summary>Creates a texture from the given <see cref="TexFile"/>. Skips the load throttler; intended to be used
|
||||||
|
|
@ -257,7 +259,7 @@ internal sealed partial class TextureManager : IServiceType, IDisposable, ITextu
|
||||||
if (conversion != TexFile.DxgiFormatConversion.NoConversion ||
|
if (conversion != TexFile.DxgiFormatConversion.NoConversion ||
|
||||||
!this.IsDxgiFormatSupported((DXGI_FORMAT)dxgiFormat))
|
!this.IsDxgiFormatSupported((DXGI_FORMAT)dxgiFormat))
|
||||||
{
|
{
|
||||||
dxgiFormat = (int)Format.B8G8R8A8_UNorm;
|
dxgiFormat = (int)DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
buffer = buffer.Filter(0, 0, TexFile.TextureFormat.B8G8R8A8);
|
buffer = buffer.Filter(0, 0, TexFile.TextureFormat.B8G8R8A8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,9 @@ public partial interface ITextureProvider
|
||||||
/// without having to wait for the completion of the returned <see cref="Task{TResult}"/>.</param>
|
/// without having to wait for the completion of the returned <see cref="Task{TResult}"/>.</param>
|
||||||
/// <param name="uv0">The left top coordinates relative to the size of the source texture.</param>
|
/// <param name="uv0">The left top coordinates relative to the size of the source texture.</param>
|
||||||
/// <param name="uv1">The right bottom coordinates relative to the size of the source texture.</param>
|
/// <param name="uv1">The right bottom coordinates relative to the size of the source texture.</param>
|
||||||
/// <param name="dxgiFormat">The desired target format.</param>
|
/// <param name="dxgiFormat">The desired target format. Use 0 to use the source format.</param>
|
||||||
|
/// <param name="leaveWrapOpen">Whether to leave <paramref name="wrap"/> non-disposed when the returned
|
||||||
|
/// <see cref="Task{TResult}"/> completes.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A <see cref="Task{TResult}"/> containing the copied texture on success. Dispose after use.</returns>
|
/// <returns>A <see cref="Task{TResult}"/> containing the copied texture on success. Dispose after use.</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
|
@ -49,7 +51,8 @@ public partial interface ITextureProvider
|
||||||
IDalamudTextureWrap wrap,
|
IDalamudTextureWrap wrap,
|
||||||
Vector2 uv0,
|
Vector2 uv0,
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
int dxgiFormat,
|
int dxgiFormat = 0,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>Gets a texture from the given bytes, trying to interpret it as a .tex file or other well-known image
|
/// <summary>Gets a texture from the given bytes, trying to interpret it as a .tex file or other well-known image
|
||||||
|
|
@ -185,12 +188,13 @@ public partial interface ITextureProvider
|
||||||
bool TryGetIconPath(in GameIconLookup lookup, [NotNullWhen(true)] out string? path);
|
bool TryGetIconPath(in GameIconLookup lookup, [NotNullWhen(true)] out string? path);
|
||||||
|
|
||||||
/// <summary>Gets the raw data of a texture wrap.</summary>
|
/// <summary>Gets the raw data of a texture wrap.</summary>
|
||||||
/// <param name="wrap">The source texture wrap. The passed value may be disposed once this function returns,
|
/// <param name="wrap">The source texture wrap.</param>
|
||||||
/// without having to wait for the completion of the returned <see cref="Task{TResult}"/>.</param>
|
|
||||||
/// <param name="uv0">The left top coordinates relative to the size of the source texture.</param>
|
/// <param name="uv0">The left top coordinates relative to the size of the source texture.</param>
|
||||||
/// <param name="uv1">The right bottom coordinates relative to the size of the source texture.</param>
|
/// <param name="uv1">The right bottom coordinates relative to the size of the source texture.</param>
|
||||||
/// <param name="dxgiFormat">The desired target format.
|
/// <param name="dxgiFormat">The desired target format.
|
||||||
/// If 0 (unknown) is passed, then the format will not be converted.</param>
|
/// If 0 (unknown) is passed, then the format will not be converted.</param>
|
||||||
|
/// <param name="leaveWrapOpen">Whether to leave <paramref name="wrap"/> non-disposed when the returned
|
||||||
|
/// <see cref="Task{TResult}"/> completes.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The raw data and its specifications.</returns>
|
/// <returns>The raw data and its specifications.</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
|
@ -206,27 +210,32 @@ public partial interface ITextureProvider
|
||||||
Vector2 uv0,
|
Vector2 uv0,
|
||||||
Vector2 uv1,
|
Vector2 uv1,
|
||||||
int dxgiFormat = 0,
|
int dxgiFormat = 0,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>Saves a texture wrap to a stream in an image file format.</summary>
|
/// <summary>Saves a texture wrap to a stream in an image file format.</summary>
|
||||||
/// <param name="wrap">The texture wrap to save.</param>
|
/// <param name="wrap">The texture wrap to save.</param>
|
||||||
/// <param name="containerGuid">The container GUID, obtained from <see cref="GetSupportedImageEncoderInfos"/>.</param>
|
/// <param name="containerGuid">The container GUID, obtained from <see cref="GetSupportedImageEncoderInfos"/>.</param>
|
||||||
/// <param name="stream">The stream to save to.</param>
|
/// <param name="stream">The stream to save to.</param>
|
||||||
/// <param name="leaveOpen">Whether to leave <paramref name="stream"/> open.</param>
|
|
||||||
/// <param name="props">Properties to pass to the encoder. See
|
/// <param name="props">Properties to pass to the encoder. See
|
||||||
/// <a href="https://learn.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder#encoder-options">Microsoft
|
/// <a href="https://learn.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder#encoder-options">Microsoft
|
||||||
/// Learn</a> for available parameters.</param>
|
/// Learn</a> for available parameters.</param>
|
||||||
|
/// <param name="leaveWrapOpen">Whether to leave <paramref name="wrap"/> non-disposed when the returned
|
||||||
|
/// <see cref="Task{TResult}"/> completes.</param>
|
||||||
|
/// <param name="leaveStreamOpen">Whether to leave <paramref name="stream"/> open when the returned
|
||||||
|
/// <see cref="Task{TResult}"/> completes.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A task representing the save process.</returns>
|
/// <returns>A task representing the save process.</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para><paramref name="wrap"/> may be disposed as soon as this function returns.</para>
|
/// <para><paramref name="wrap"/> must not be disposed until the task finishes.</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
Task SaveToStreamAsync(
|
Task SaveToStreamAsync(
|
||||||
IDalamudTextureWrap wrap,
|
IDalamudTextureWrap wrap,
|
||||||
Guid containerGuid,
|
Guid containerGuid,
|
||||||
Stream stream,
|
Stream stream,
|
||||||
bool leaveOpen = false,
|
|
||||||
IReadOnlyDictionary<string, object>? props = null,
|
IReadOnlyDictionary<string, object>? props = null,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
|
bool leaveStreamOpen = false,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>Saves a texture wrap to a file as an image file.</summary>
|
/// <summary>Saves a texture wrap to a file as an image file.</summary>
|
||||||
|
|
@ -236,16 +245,19 @@ public partial interface ITextureProvider
|
||||||
/// <param name="props">Properties to pass to the encoder. See
|
/// <param name="props">Properties to pass to the encoder. See
|
||||||
/// <a href="https://learn.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder#encoder-options">Microsoft
|
/// <a href="https://learn.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder#encoder-options">Microsoft
|
||||||
/// Learn</a> for available parameters.</param>
|
/// Learn</a> for available parameters.</param>
|
||||||
|
/// <param name="leaveWrapOpen">Whether to leave <paramref name="wrap"/> non-disposed when the returned
|
||||||
|
/// <see cref="Task{TResult}"/> completes.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>A task representing the save process.</returns>
|
/// <returns>A task representing the save process.</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para><paramref name="wrap"/> may be disposed as soon as this function returns.</para>
|
/// <para><paramref name="wrap"/> must not be disposed until the task finishes.</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
Task SaveToFileAsync(
|
Task SaveToFileAsync(
|
||||||
IDalamudTextureWrap wrap,
|
IDalamudTextureWrap wrap,
|
||||||
Guid containerGuid,
|
Guid containerGuid,
|
||||||
string path,
|
string path,
|
||||||
IReadOnlyDictionary<string, object>? props = null,
|
IReadOnlyDictionary<string, object>? props = null,
|
||||||
|
bool leaveWrapOpen = false,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue