Repository navigation
feat: font_src on TextShape, UiText, UiInput and UiDropdown #10118
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
Changes from all commits
3880741
a05c42e
2fd622f
9142740
c7db4f8
55d6cfd
1d8ed3f
10188df
9b079ec
c70e8ff
899edc6
d8e9089
8a6f22c
236b2b9
6ac7057
06f2cc4
8774df3
b26d961
a69a152
86e4ca0
13370a2
9e7cc84
4966c7b
753b1d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,20 +29,18 @@ public ReleaseReferenceComponentsSystem(World world, IComponentPoolsRegistry com | |
| protected override void Update(float _) | ||
| { | ||
| Query query = World.Query(in queryDescription); | ||
| ReleaseComponentsToPool(in query); | ||
| ReleaseComponentsToPool(in query, componentPoolsRegistry, respectDeferredDeletion: true); | ||
| } | ||
|
|
||
| public void FinalizeComponents(in Query query) | ||
| { | ||
| ReleaseComponentsToPool(in query); | ||
| ReleaseComponentsToPool(in query, componentPoolsRegistry); | ||
| } | ||
|
|
||
| private void ReleaseComponentsToPool(in Query query) | ||
| { | ||
| ReleaseComponentsToPool(query, componentPoolsRegistry); | ||
| } | ||
| public static void ReleaseComponentsToPool(in Query query, IComponentPoolsRegistry componentPoolsRegistry) => | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2 — R24] Scope: The change itself is correct and well-tested ( |
||
| ReleaseComponentsToPool(in query, componentPoolsRegistry, respectDeferredDeletion: false); | ||
|
|
||
| public static void ReleaseComponentsToPool(in Query query, IComponentPoolsRegistry componentPoolsRegistry) | ||
| private static void ReleaseComponentsToPool(in Query query, IComponentPoolsRegistry componentPoolsRegistry, bool respectDeferredDeletion) | ||
| { | ||
| // Profiling required, O(N^4) | ||
| foreach (ref Chunk chunk in query.GetChunkIterator()) | ||
|
|
@@ -52,6 +50,9 @@ public static void ReleaseComponentsToPool(in Query query, IComponentPoolsRegist | |
|
|
||
| foreach (int entityIndex in chunk) | ||
| { | ||
| if (respectDeferredDeletion && chunk.Get<DeleteEntityIntention>(entityIndex).DeferDeletion) | ||
| continue; | ||
|
|
||
| for (var i = 0; i < array2D.Length; i++) | ||
| { | ||
| // if it is called on a value type it will cause an allocation | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| using System.IO; | ||
| using TMPro; | ||
| using UnityEngine; | ||
| using UnityEngine.TextCore.LowLevel; | ||
| using UnityEngine.TextCore.Text; | ||
|
|
||
| namespace ECS.TestSuite | ||
| { | ||
| public static class TestFonts | ||
| { | ||
| public static readonly string PATH = Path.Combine(Application.dataPath, "DCL/SDKComponents/Fonts/LiberationSans-Regular.ttf"); | ||
|
|
||
| private const int SAMPLING_POINT_SIZE = 90; | ||
| private const int ATLAS_PADDING = 9; | ||
| private const int ATLAS_SIZE = 1024; | ||
|
|
||
| public static TMP_FontAsset CreateTextMeshProFont() => | ||
| TMP_FontAsset.CreateFontAsset(PATH, 0, SAMPLING_POINT_SIZE, ATLAS_PADDING, GlyphRenderMode.SDFAA, ATLAS_SIZE, ATLAS_SIZE); | ||
|
|
||
| public static FontAsset CreateUIToolkitFont() => | ||
| FontAsset.CreateFontAsset(PATH, 0, SAMPLING_POINT_SIZE, ATLAS_PADDING, GlyphRenderMode.SDFAA, ATLAS_SIZE, ATLAS_SIZE); | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| using Cysharp.Threading.Tasks; | ||
| using DCL.Diagnostics; | ||
| using DCL.Profiling; | ||
| using Unity.Profiling; | ||
|
|
||
| namespace ECS.StreamableLoading.Fonts | ||
| { | ||
| public class FontData : StreamableRefCountData<FontFamilyAssets> | ||
| { | ||
| private readonly FontFileStore.Lease?[] files; | ||
|
|
||
| public FontData(FontFamilyAssets assets, params FontFileStore.Lease?[] files) : base(assets, ReportCategory.SDK_FONTS) | ||
| { | ||
| this.files = files; | ||
| ProfilingCounters.FontsAmount.Value++; | ||
| } | ||
|
|
||
| protected override ref ProfilerCounterValue<int> totalCount => ref ProfilingCounters.FontsAmount; | ||
|
|
||
| protected override ref ProfilerCounterValue<int> referencedCount => ref ProfilingCounters.FontsReferenced; | ||
|
|
||
| protected override void DestroyObject() | ||
| { | ||
| Asset.Destroy(); | ||
| FontFileStore.ReleaseAfterDestructionAsync(files).Forget(e => ReportHub.LogException(e, ReportCategory.SDK_FONTS)); | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| using System; | ||
| using System.Text; | ||
| using UnityEngine.Networking; | ||
|
|
||
| namespace ECS.StreamableLoading.Fonts | ||
| { | ||
| public class FontDownloadHandler : DownloadHandlerScript | ||
| { | ||
| private const int CHUNK_BYTES = 64 * 1024; | ||
|
|
||
| private readonly int maxBytes; | ||
| private byte[] buffer = Array.Empty<byte>(); | ||
| private int length; | ||
|
|
||
| public bool LimitExceeded { get; private set; } | ||
|
|
||
| public FontDownloadHandler(int maxBytes) : base(new byte[CHUNK_BYTES]) | ||
| { | ||
| this.maxBytes = maxBytes; | ||
| } | ||
|
|
||
| protected override void ReceiveContentLengthHeader(ulong contentLength) => | ||
| LimitExceeded |= contentLength > (ulong)maxBytes; | ||
|
|
||
| protected override bool ReceiveData(byte[] receivedData, int dataLength) | ||
| { | ||
| if (LimitExceeded || dataLength > maxBytes - length) | ||
| { | ||
| LimitExceeded = true; | ||
| return false; | ||
| } | ||
|
|
||
| int required = length + dataLength; | ||
|
|
||
| if (required > buffer.Length) | ||
| Array.Resize(ref buffer, Math.Min(maxBytes, Math.Max(required, Math.Max(CHUNK_BYTES, buffer.Length * 2)))); | ||
|
|
||
| Buffer.BlockCopy(receivedData, 0, buffer, length, dataLength); | ||
| length = required; | ||
| return true; | ||
| } | ||
|
|
||
| protected override byte[] GetData() | ||
| { | ||
| var result = new byte[length]; | ||
| Buffer.BlockCopy(buffer, 0, result, 0, length); | ||
| return result; | ||
| } | ||
|
|
||
| protected override string GetText() => | ||
| Encoding.UTF8.GetString(buffer, 0, length); | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| using System.Collections.Generic; | ||
| using TMPro; | ||
| using UnityEngine.TextCore.Text; | ||
| using Utility; | ||
|
|
||
| namespace ECS.StreamableLoading.Fonts | ||
| { | ||
| public class FontFamilyAssets | ||
| { | ||
| private readonly List<TMP_FontAsset> textMeshProAssets; | ||
| private readonly List<FontAsset> uiToolkitAssets; | ||
|
|
||
| public TMP_FontAsset TextMeshProFont { get; } | ||
|
|
||
| public FontAsset UIToolkitFont { get; } | ||
|
|
||
| public FontFamilyAssets(TMP_FontAsset textMeshProFont, FontAsset uiToolkitFont, List<TMP_FontAsset> textMeshProAssets, List<FontAsset> uiToolkitAssets) | ||
| { | ||
| TextMeshProFont = textMeshProFont; | ||
| UIToolkitFont = uiToolkitFont; | ||
| this.textMeshProAssets = textMeshProAssets; | ||
| this.uiToolkitAssets = uiToolkitAssets; | ||
| } | ||
|
|
||
| public void Destroy() => | ||
| Destroy(textMeshProAssets, uiToolkitAssets); | ||
|
|
||
| public static void Destroy(List<TMP_FontAsset> textMeshProAssets, List<FontAsset> uiToolkitAssets) | ||
| { | ||
| foreach (TMP_FontAsset asset in textMeshProAssets) | ||
| { | ||
| TMP_ResourceManager.RemoveFontAsset(asset); | ||
| UnityObjectUtils.SafeDestroy(asset); | ||
| } | ||
|
|
||
| foreach (FontAsset asset in uiToolkitAssets) | ||
| UnityObjectUtils.SafeDestroy(asset); | ||
|
|
||
| textMeshProAssets.Clear(); | ||
| uiToolkitAssets.Clear(); | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReleaseReferenceComponentsSystem: please move this change to its own PRThe
respectDeferredDeletionchange isn't related tofont_src, but it changes cleanup for every pooled reference component in every scene world. I don't think it should be hidden inside a 3.7k-line feature PR.As far as I can tell, it also has no effect at runtime today:
ReleaseReferenceComponentsSystemis only added to scene worlds (ECSWorldFactory.cs:95).DeferDeletion = true. The only places that set it are in the global world (AvatarShapeHandlerSystem,ResolveSceneStateByIncreasingRadiusSystem,RapidSceneReloadDebugSystem, andAvatarCleanUpSystemresetting it to
false). This PR only reads the flag outside of tests.continueonly runs inReleaseReferenceComponentsSystemShould.The fix itself makes sense as a guard for the future. It lines up with
ReleasePoolableComponentSystemandDestroyEntitiesSystem. It would also stop repeated double-releases to the pool if a scene-world system ever defers deletion. Butthat's a speculative change to shared ECS cleanup, and it deserves its own PR and review: something like
fix: don't release pooled components of deferred-deletion entities, together withReleaseReferenceComponentsSystemShould. It alsokeeps the font feature easy to revert or bisect.
A small nit for when it moves: the public 2-argument overload (which means
false) next to a private 3-argument one is a bit awkward. Putting the check inline inUpdate(), or giving the flag a default value, would be simpler.The same applies, less strongly, to the
if (deleteEntityIntention.DeferDeletion) return;early-outs in the newReleaseTextShapeSystem/UITextReleaseSystem/UIInputReleaseSystem/UIDropdownReleaseSystem. They can't trigger inscene worlds either, though at least they follow the existing
ReleasePoolableComponentSystempattern.