Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISIT: remove api9 compat, IDAM: make Empty4X4 transparent #1877

Merged
merged 2 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Dalamud/DalamudAsset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ public enum DalamudAsset
/// <summary>
/// Nothing.
/// </summary>
[DalamudAsset(DalamudAssetPurpose.Empty, data: new byte[0])]
[DalamudAsset(DalamudAssetPurpose.Empty, data: [])]
Unspecified = 0,

/// <summary>
/// <see cref="DalamudAssetPurpose.TextureFromRaw"/>: The fallback empty texture.
/// <see cref="DalamudAssetPurpose.TextureFromRaw"/>: A texture that is completely transparent.
/// </summary>
[DalamudAsset(DalamudAssetPurpose.TextureFromRaw, data: new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 })]
[DalamudAsset(DalamudAssetPurpose.TextureFromRaw, data: [0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF])]
[DalamudAssetRawTexture(4, 4, DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM, 8)]
Empty4X4 = 1000,

/// <summary>
/// <see cref="DalamudAssetPurpose.TextureFromRaw"/>: The fallback empty texture.
/// <see cref="DalamudAssetPurpose.TextureFromRaw"/>: A texture that is completely white.
/// </summary>
[DalamudAsset(DalamudAssetPurpose.TextureFromRaw, data: new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 })]
[DalamudAsset(DalamudAssetPurpose.TextureFromRaw, data: [0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0])]
[DalamudAssetRawTexture(4, 4, DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM, 8)]
White4X4 = 1014,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,6 @@ private unsafe void DrawLoadedTextures(ICollection<SharedImmediateTexture> textu
ImGui.TableSetupColumn("Source", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("RefCount", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("RefCount__").X);
ImGui.TableSetupColumn("SelfRef", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("00.000___").X);
ImGui.TableSetupColumn("CanRevive", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("CanRevive__").X);
ImGui.TableSetupColumn(
"Actions",
ImGuiTableColumnFlags.WidthFixed,
Expand Down Expand Up @@ -582,9 +581,6 @@ private unsafe void DrawLoadedTextures(ICollection<SharedImmediateTexture> textu
ImGui.TableNextColumn();
this.TextCopiable(remain <= 0 ? "-" : $"{remain:00.000}", true, true);

ImGui.TableNextColumn();
ImGui.TextUnformatted(texture.HasRevivalPossibility ? "Yes" : "No");

ImGui.TableNextColumn();
if (ImGuiComponents.IconButton(FontAwesomeIcon.Save))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ internal abstract class SharedImmediateTexture
private bool resourceReleased;
private int refCount;
private long selfReferenceExpiry;
private IDalamudTextureWrap? availableOnAccessWrapForApi9;
private CancellationTokenSource? cancellationTokenSource;
private NotOwnedTextureWrap? nonOwningWrap;

Expand Down Expand Up @@ -67,10 +66,6 @@ protected SharedImmediateTexture(string sourcePathForDebug)
/// <summary>Gets the source path. Debug use only.</summary>
public string SourcePathForDebug { get; }

/// <summary>Gets a value indicating whether this instance of <see cref="SharedImmediateTexture"/> supports revival.
/// </summary>
public bool HasRevivalPossibility => this.RevivalPossibility?.TryGetTarget(out _) is true;

/// <summary>Gets or sets the underlying texture wrap.</summary>
public Task<IDalamudTextureWrap>? UnderlyingWrap { get; set; }

Expand All @@ -91,16 +86,6 @@ protected SharedImmediateTexture(string sourcePathForDebug)
/// Intended to be called from implementors' constructors and <see cref="LoadUnderlyingWrap"/>.</summary>
protected CancellationToken LoadCancellationToken => this.cancellationTokenSource?.Token ?? default;

/// <summary>Gets or sets a weak reference to an object that demands this objects to be alive.</summary>
/// <remarks>
/// TextureManager must keep references to all shared textures, regardless of whether textures' contents are
/// flushed, because API9 functions demand that the returned textures may be stored so that they can used anytime,
/// possibly reviving a dead-inside object. The object referenced by this property is given out to such use cases,
/// which gets created from <see cref="GetAvailableOnAccessWrapForApi9"/>. If this no longer points to an alive
/// object, and <see cref="availableOnAccessWrapForApi9"/> is null, then this object is not used from API9 use case.
/// </remarks>
private WeakReference<IDalamudTextureWrap>? RevivalPossibility { get; set; }

/// <inheritdoc/>
public int AddRef() => this.TryAddRef(out var newRefCount) switch
{
Expand Down Expand Up @@ -180,7 +165,6 @@ public int ReleaseSelfReference(bool immediate)
if (exp != Interlocked.CompareExchange(ref this.selfReferenceExpiry, SelfReferenceExpiryExpired, exp))
continue;

this.availableOnAccessWrapForApi9 = null;
return this.Release();
}
}
Expand Down Expand Up @@ -255,35 +239,6 @@ public async Task<IDalamudTextureWrap> RentAsync(CancellationToken cancellationT
return new RefCountableWrappingTextureWrap(dtw, this);
}

/// <summary>Gets a texture wrap which ensures that the values will be populated on access.</summary>
/// <returns>The texture wrap, or null if failed.</returns>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public IDalamudTextureWrap? GetAvailableOnAccessWrapForApi9()
{
if (this.availableOnAccessWrapForApi9 is not null)
return this.availableOnAccessWrapForApi9;

lock (this.reviveLock)
{
if (this.availableOnAccessWrapForApi9 is not null)
return this.availableOnAccessWrapForApi9;

if (this.RevivalPossibility?.TryGetTarget(out this.availableOnAccessWrapForApi9) is true)
return this.availableOnAccessWrapForApi9;

var newRefTask = this.RentAsync(this.LoadCancellationToken);
newRefTask.Wait(this.LoadCancellationToken);
if (!newRefTask.IsCompletedSuccessfully)
return null;
newRefTask.Result.Dispose();

this.availableOnAccessWrapForApi9 = new AvailableOnAccessTextureWrap(this);
this.RevivalPossibility = new(this.availableOnAccessWrapForApi9);
}

return this.availableOnAccessWrapForApi9;
}

/// <summary>Adds a plugin to <see cref="ownerPlugins"/>, in a thread-safe way.</summary>
/// <param name="plugin">The plugin to add.</param>
public void AddOwnerPlugin(LocalPlugin plugin)
Expand Down Expand Up @@ -383,9 +338,6 @@ private IRefCountable.RefCountResult TryAddRef(out int newRefCount)
throw;
}

if (this.RevivalPossibility?.TryGetTarget(out var target) is true)
this.availableOnAccessWrapForApi9 = target;

Interlocked.Increment(ref this.refCount);
this.resourceReleased = false;
return IRefCountable.RefCountResult.StillAlive;
Expand Down Expand Up @@ -468,12 +420,6 @@ public bool TryGetWrap([NotNullWhen(true)] out IDalamudTextureWrap? texture, out
public Task<IDalamudTextureWrap> RentAsync(CancellationToken cancellationToken = default) =>
this.inner.RentAsync(cancellationToken);

/// <inheritdoc cref="SharedImmediateTexture.GetAvailableOnAccessWrapForApi9"/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IDalamudTextureWrap? GetAvailableOnAccessWrapForApi9() =>
this.inner.GetAvailableOnAccessWrapForApi9();

/// <inheritdoc cref="SharedImmediateTexture.AddOwnerPlugin"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddOwnerPlugin(LocalPlugin plugin) =>
Expand Down Expand Up @@ -562,56 +508,4 @@ protected override void Dispose(bool disposing)
}
}
}

/// <summary>A texture wrap that revives and waits for the underlying texture as needed on every access.</summary>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
private sealed class AvailableOnAccessTextureWrap : ForwardingTextureWrap
{
private readonly SharedImmediateTexture inner;

/// <summary>Initializes a new instance of the <see cref="AvailableOnAccessTextureWrap"/> class.</summary>
/// <param name="inner">The shared texture.</param>
public AvailableOnAccessTextureWrap(SharedImmediateTexture inner) => this.inner = inner;

/// <inheritdoc/>
public override IDalamudTextureWrap CreateWrapSharingLowLevelResource()
{
this.inner.AddRef();
try
{
if (!this.inner.TryGetWrapCore(out var wrap, out _))
{
this.inner.UnderlyingWrap?.Wait();

if (!this.inner.TryGetWrapCore(out wrap, out _))
{
// Calling dispose on Empty4x4 is a no-op, so we can just return that.
this.inner.Release();
return Service<DalamudAssetManager>.Get().Empty4X4;
}
}

return new RefCountableWrappingTextureWrap(wrap, this.inner);
}
catch
{
this.inner.Release();
throw;
}
}

/// <inheritdoc/>
public override string ToString() => $"{nameof(AvailableOnAccessTextureWrap)}({this.inner})";

/// <inheritdoc/>
protected override bool TryGetWrap(out IDalamudTextureWrap? wrap)
{
if (this.inner.TryGetWrapCore(out var t, out _))
wrap = t;

this.inner.UnderlyingWrap?.Wait();
wrap = this.inner.nonOwningWrap ?? Service<DalamudAssetManager>.Get().Empty4X4;
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public void FlushFromGameCache(string path)
{
if (this.gameDict.TryRemove(path, out var r))
{
if (r.ReleaseSelfReference(true) != 0 || r.HasRevivalPossibility)
if (r.ReleaseSelfReference(true) != 0)
{
lock (this.invalidatedTextures)
this.invalidatedTextures.Add(r);
Expand Down Expand Up @@ -201,7 +201,7 @@ static void RemoveFinalReleased<T>(ConcurrentDictionary<T, SharedImmediateTextur

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static bool TextureFinalReleasePredicate(SharedImmediateTexture v) =>
v.ContentQueried && v.ReleaseSelfReference(false) == 0 && !v.HasRevivalPossibility;
v.ContentQueried && v.ReleaseSelfReference(false) == 0;
}
}
}
Loading