Skip to content

Commit 07c794b

Browse files
committed
perf: [Wasm] Improve text set color
1 parent c1a776b commit 07c794b

File tree

12 files changed

+232
-13
lines changed

12 files changed

+232
-13
lines changed

src/SourceGenerators/Uno.UI.SourceGenerators/TSBindings/TSBindingsGenerator.cs

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class TSBindingsGenerator : ISourceGenerator
2727

2828
private static INamedTypeSymbol _stringSymbol;
2929
private static INamedTypeSymbol _intSymbol;
30+
private static INamedTypeSymbol _uintSymbol;
3031
private static INamedTypeSymbol _floatSymbol;
3132
private static INamedTypeSymbol _doubleSymbol;
3233
private static INamedTypeSymbol _byteSymbol;
@@ -54,6 +55,7 @@ public void Execute(GeneratorExecutionContext context)
5455
{
5556
_stringSymbol = context.Compilation.GetTypeByMetadataName("System.String");
5657
_intSymbol = context.Compilation.GetTypeByMetadataName("System.Int32");
58+
_uintSymbol = context.Compilation.GetTypeByMetadataName("System.UInt32") ?? throw new Exception($"System.UInt32");
5759
_floatSymbol = context.Compilation.GetTypeByMetadataName("System.Single");
5860
_doubleSymbol = context.Compilation.GetTypeByMetadataName("System.Double");
5961
_byteSymbol = context.Compilation.GetTypeByMetadataName("System.Byte");
@@ -108,7 +110,7 @@ from type in GetNamespaceTypes(module)
108110

109111
if (messageType.Name.EndsWith("Params"))
110112
{
111-
GenerateUmarshaler(messageType, sb, packValue);
113+
GenerateUnmarshaler(messageType, sb, packValue);
112114
}
113115

114116
if (messageType.Name.EndsWith("Return"))
@@ -263,7 +265,7 @@ private void GenerateMarshaler(INamedTypeSymbol parametersType, IndentedStringBu
263265
}
264266
}
265267

266-
private void GenerateUmarshaler(INamedTypeSymbol parametersType, IndentedStringBuilder sb, int packValue)
268+
private void GenerateUnmarshaler(INamedTypeSymbol parametersType, IndentedStringBuilder sb, int packValue)
267269
{
268270
using (sb.BlockInvariant($"public static unmarshal(pData:number) : {parametersType.Name}"))
269271
{
@@ -344,7 +346,14 @@ private void GenerateUmarshaler(INamedTypeSymbol parametersType, IndentedStringB
344346
}
345347
else
346348
{
347-
sb.AppendLineInvariant($"ret.{field.Name} = {GetTSType(field.Type)}(Module.getValue(pData + {fieldOffset}, \"{GetEMField(field.Type)}\"));");
349+
if (CanUseEMHeapProperty(field.Type))
350+
{
351+
sb.AppendLineInvariant($"ret.{field.Name} = Module.{GetEMHeapProperty(field.Type)}[(pData + {fieldOffset}) >> {GetEMTypeShift(field)}];");
352+
}
353+
else
354+
{
355+
sb.AppendLineInvariant($"ret.{field.Name} = {GetTSType(field.Type)}(Module.getValue(pData + {fieldOffset}, \"{GetEMField(field.Type)}\"));");
356+
}
348357
}
349358
}
350359
}
@@ -362,11 +371,15 @@ private void GenerateUmarshaler(INamedTypeSymbol parametersType, IndentedStringB
362371
}
363372
}
364373

374+
private bool CanUseEMHeapProperty(ITypeSymbol type)
375+
=> SymbolEqualityComparer.Default.Equals(type, _uintSymbol);
376+
365377
private int GetNativeFieldSize(IFieldSymbol field)
366378
{
367-
if(
379+
if (
368380
SymbolEqualityComparer.Default.Equals(field.Type, _stringSymbol)
369381
|| SymbolEqualityComparer.Default.Equals(field.Type, _intSymbol)
382+
|| SymbolEqualityComparer.Default.Equals(field.Type, _uintSymbol)
370383
|| SymbolEqualityComparer.Default.Equals(field.Type, _intPtrSymbol)
371384
|| SymbolEqualityComparer.Default.Equals(field.Type, _floatSymbol)
372385
|| SymbolEqualityComparer.Default.Equals(field.Type, _boolSymbol)
@@ -375,7 +388,7 @@ private int GetNativeFieldSize(IFieldSymbol field)
375388
{
376389
return 4;
377390
}
378-
else if(SymbolEqualityComparer.Default.Equals(field.Type, _doubleSymbol))
391+
else if (SymbolEqualityComparer.Default.Equals(field.Type, _doubleSymbol))
379392
{
380393
return 8;
381394
}
@@ -385,6 +398,52 @@ private int GetNativeFieldSize(IFieldSymbol field)
385398
}
386399
}
387400

401+
private int GetEMTypeShift(IFieldSymbol field)
402+
{
403+
var fieldType = field.Type;
404+
405+
if (
406+
SymbolEqualityComparer.Default.Equals(fieldType, _stringSymbol)
407+
|| SymbolEqualityComparer.Default.Equals(fieldType, _intPtrSymbol)
408+
|| fieldType is IArrayTypeSymbol
409+
)
410+
{
411+
return 2;
412+
}
413+
else if (
414+
SymbolEqualityComparer.Default.Equals(fieldType, _intSymbol)
415+
|| SymbolEqualityComparer.Default.Equals(fieldType, _uintSymbol)
416+
|| SymbolEqualityComparer.Default.Equals(fieldType, _boolSymbol)
417+
)
418+
{
419+
return 2;
420+
}
421+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _longSymbol))
422+
{
423+
return 3;
424+
}
425+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _shortSymbol))
426+
{
427+
return 1;
428+
}
429+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _byteSymbol))
430+
{
431+
return 0;
432+
}
433+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _floatSymbol))
434+
{
435+
return 2;
436+
}
437+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _doubleSymbol))
438+
{
439+
return 3;
440+
}
441+
else
442+
{
443+
throw new NotSupportedException($"Unsupported EM type conversion [{fieldType}]");
444+
}
445+
}
446+
388447
private static string GetEMField(ITypeSymbol fieldType)
389448
{
390449
if (
@@ -397,6 +456,7 @@ private static string GetEMField(ITypeSymbol fieldType)
397456
}
398457
else if (
399458
SymbolEqualityComparer.Default.Equals(fieldType, _intSymbol)
459+
|| SymbolEqualityComparer.Default.Equals(fieldType, _uintSymbol)
400460
|| SymbolEqualityComparer.Default.Equals(fieldType, _boolSymbol)
401461
)
402462
{
@@ -428,6 +488,49 @@ private static string GetEMField(ITypeSymbol fieldType)
428488
}
429489
}
430490

491+
private object GetEMHeapProperty(ITypeSymbol fieldType)
492+
{
493+
if (
494+
SymbolEqualityComparer.Default.Equals(fieldType, _stringSymbol)
495+
|| SymbolEqualityComparer.Default.Equals(fieldType, _intPtrSymbol)
496+
|| fieldType is IArrayTypeSymbol
497+
|| SymbolEqualityComparer.Default.Equals(fieldType, _intSymbol)
498+
|| SymbolEqualityComparer.Default.Equals(fieldType, _boolSymbol)
499+
)
500+
{
501+
return "HEAP32";
502+
}
503+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _uintSymbol))
504+
{
505+
return "HEAPU32";
506+
}
507+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _longSymbol))
508+
{
509+
// Might overflow
510+
return "HEAP32";
511+
}
512+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _shortSymbol))
513+
{
514+
return "HEAP16";
515+
}
516+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _byteSymbol))
517+
{
518+
return "HEAP8";
519+
}
520+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _floatSymbol))
521+
{
522+
return "HEAPF32";
523+
}
524+
else if (SymbolEqualityComparer.Default.Equals(fieldType, _doubleSymbol))
525+
{
526+
return "HEAPF64";
527+
}
528+
else
529+
{
530+
throw new NotSupportedException($"Unsupported EM type conversion [{fieldType}]");
531+
}
532+
}
533+
431534
private static string GetTSType(ITypeSymbol type)
432535
{
433536
if (type == null)
@@ -445,6 +548,7 @@ private static string GetTSType(ITypeSymbol type)
445548
}
446549
else if (
447550
SymbolEqualityComparer.Default.Equals(type, _intSymbol)
551+
|| SymbolEqualityComparer.Default.Equals(type, _uintSymbol)
448552
|| SymbolEqualityComparer.Default.Equals(type, _floatSymbol)
449553
|| SymbolEqualityComparer.Default.Equals(type, _doubleSymbol)
450554
|| SymbolEqualityComparer.Default.Equals(type, _byteSymbol)
@@ -481,6 +585,7 @@ private static string GetTSFieldType(ITypeSymbol type)
481585
}
482586
else if (
483587
SymbolEqualityComparer.Default.Equals(type, _intSymbol)
588+
|| SymbolEqualityComparer.Default.Equals(type, _uintSymbol)
484589
|| SymbolEqualityComparer.Default.Equals(type, _floatSymbol)
485590
|| SymbolEqualityComparer.Default.Equals(type, _doubleSymbol)
486591
|| SymbolEqualityComparer.Default.Equals(type, _byteSymbol)

src/Uno.UI/UI/Xaml/Controls/TextBlock/TextBlock.wasm.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Uno.Extensions;
77
using Uno.Foundation;
88
using System.Linq;
9-
using Uno.UI.UI.Xaml.Documents;
109
using Microsoft.Extensions.Logging;
1110
using Windows.UI.Text;
1211
using Windows.UI.Xaml.Media;

src/Uno.UI/UI/Xaml/Controls/TextBox/TextBox.wasm.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Uno.Extensions;
2-
using Uno.UI.UI.Xaml.Documents;
32
using Windows.UI.Xaml.Input;
43
using Windows.UI.Xaml.Media;
54

src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.wasm.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using Uno.Logging;
88
using Windows.Foundation;
99
using System.Globalization;
10-
using Uno.UI.UI.Xaml.Documents;
1110
using Uno.Disposables;
1211

1312
namespace Windows.UI.Xaml.Controls

src/Uno.UI/UI/Xaml/Documents/Run.wasm.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Web;
2-
using Uno.UI.UI.Xaml.Documents;
32

43
namespace Windows.UI.Xaml.Documents
54
{

src/Uno.UI/UI/Xaml/Documents/TextElement.wasm.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using Uno.UI.UI.Xaml.Documents;
2-
3-
namespace Windows.UI.Xaml.Documents
1+
namespace Windows.UI.Xaml.Documents
42
{
53
partial class TextElement
64
{

src/Uno.UI/UI/Xaml/UIElement.TextHelper.wasm.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Uno.Collections;
1010
using Uno.Disposables;
1111
using Uno.Extensions;
12+
using Uno.UI.Xaml;
1213

1314
namespace Windows.UI.Xaml
1415
{
@@ -155,7 +156,7 @@ internal void SetForeground(object localValue)
155156
switch (localValue)
156157
{
157158
case SolidColorBrush scb:
158-
this.SetStyle("color", scb.ColorWithOpacity.ToHexString());
159+
WindowManagerInterop.SetElementColor(HtmlId, scb.ColorWithOpacity);
159160
break;
160161
case GradientBrush gradient:
161162
this.SetStyle(

src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Uno.Foundation;
1111
using Uno.Foundation.Interop;
1212
using Windows.Foundation;
13+
using Windows.UI;
1314
using Windows.UI.Xaml;
1415

1516
namespace Uno.UI.Xaml
@@ -826,6 +827,43 @@ private struct WindowManagerSetPropertyParams
826827

827828
#endregion
828829

830+
#region SetVisibility
831+
832+
internal static void SetElementColor(IntPtr htmlId, Color color)
833+
{
834+
var colorAsInteger =
835+
(uint)(color.R << 24)
836+
| (uint)(color.G << 16)
837+
| (uint)(color.B << 8)
838+
| color.A;
839+
840+
if (UseJavascriptEval)
841+
{
842+
var command = $"Uno.UI.WindowManager.current.setElementColor(\"{htmlId}\", {color});";
843+
WebAssemblyRuntime.InvokeJS(command);
844+
}
845+
else
846+
{
847+
var parms = new WindowManagerSetElementColorParams()
848+
{
849+
HtmlId = htmlId,
850+
Color = colorAsInteger,
851+
};
852+
853+
TSInteropMarshaller.InvokeJS("Uno:setElementColorNative", parms);
854+
}
855+
}
856+
857+
[TSInteropMessage]
858+
[StructLayout(LayoutKind.Sequential, Pack = 4)]
859+
private struct WindowManagerSetElementColorParams
860+
{
861+
public IntPtr HtmlId;
862+
863+
public uint Color;
864+
}
865+
#endregion
866+
829867
#region RemoveView
830868
internal static void RemoveView(IntPtr htmlId, IntPtr childId)
831869
{

src/Uno.UI/WasmScripts/Uno.UI.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,12 @@ declare namespace Uno.UI {
318318
private setAsArranged;
319319
private setAsUnarranged;
320320
/**
321+
* Sets the visibility of the specified element
322+
*/
323+
setElementColor(elementId: number, color: number): string;
324+
setElementColorNative(pParam: number): boolean;
325+
private setElementColorInternal;
326+
/**
321327
* Sets the transform matrix of an element
322328
*
323329
*/
@@ -1332,6 +1338,11 @@ declare class WindowManagerSetContentHtmlParams {
13321338
Html: string;
13331339
static unmarshal(pData: number): WindowManagerSetContentHtmlParams;
13341340
}
1341+
declare class WindowManagerSetElementColorParams {
1342+
HtmlId: number;
1343+
Color: number;
1344+
static unmarshal(pData: number): WindowManagerSetElementColorParams;
1345+
}
13351346
declare class WindowManagerSetElementTransformParams {
13361347
HtmlId: number;
13371348
M11: number;

src/Uno.UI/WasmScripts/Uno.UI.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,22 @@ var Uno;
830830
}
831831
}
832832
/**
833+
* Sets the visibility of the specified element
834+
*/
835+
setElementColor(elementId, color) {
836+
this.setElementColorInternal(elementId, color);
837+
return "ok";
838+
}
839+
setElementColorNative(pParam) {
840+
const params = WindowManagerSetElementColorParams.unmarshal(pParam);
841+
this.setElementColorInternal(params.HtmlId, params.Color);
842+
return true;
843+
}
844+
setElementColorInternal(elementId, color) {
845+
const element = this.getView(elementId);
846+
element.style.setProperty("color", "#" + color.toString(16).padStart(8, '0'));
847+
}
848+
/**
833849
* Sets the transform matrix of an element
834850
*
835851
*/
@@ -4783,6 +4799,19 @@ class WindowManagerSetContentHtmlParams {
47834799
}
47844800
}
47854801
/* TSBindingsGenerator Generated code -- this code is regenerated on each build */
4802+
class WindowManagerSetElementColorParams {
4803+
static unmarshal(pData) {
4804+
const ret = new WindowManagerSetElementColorParams();
4805+
{
4806+
ret.HtmlId = Number(Module.getValue(pData + 0, "*"));
4807+
}
4808+
{
4809+
ret.Color = Module.HEAPU32[(pData + 4) >> 2];
4810+
}
4811+
return ret;
4812+
}
4813+
}
4814+
/* TSBindingsGenerator Generated code -- this code is regenerated on each build */
47864815
class WindowManagerSetElementTransformParams {
47874816
static unmarshal(pData) {
47884817
const ret = new WindowManagerSetElementTransformParams();

0 commit comments

Comments
 (0)