Skip to content

Commit 59517a6

Browse files
maxkatz6danwalmsley
authored andcommitted
Merge pull request #7416 from AvaloniaUI/fixes/wasm-resizing
WASM: optimize inital setup and fix initial render pass.
1 parent 133c1bd commit 59517a6

File tree

1 file changed

+65
-72
lines changed

1 file changed

+65
-72
lines changed

src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs

+65-72
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public partial class AvaloniaView : ITextInputMethodImpl
2626
private InputHelperInterop _canvasHelper = null!;
2727
private ElementReference _htmlCanvas;
2828
private ElementReference _inputElement;
29-
private double _dpi;
30-
private SKSize _canvasSize;
29+
private double _dpi = 1;
30+
private SKSize _canvasSize = new (100, 100);
3131

3232
private GRContext? _context;
3333
private GRGlInterface? _glInterface;
@@ -249,71 +249,55 @@ private void OnInput(ChangeEventArgs e)
249249
[Parameter(CaptureUnmatchedValues = true)]
250250
public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
251251

252-
protected override void OnAfterRender(bool firstRender)
252+
protected override async Task OnAfterRenderAsync(bool firstRender)
253253
{
254254
if (firstRender)
255255
{
256-
Threading.Dispatcher.UIThread.Post(async () =>
256+
_inputHelper = await InputHelperInterop.ImportAsync(Js, _inputElement);
257+
_canvasHelper = await InputHelperInterop.ImportAsync(Js, _htmlCanvas);
258+
259+
_inputHelper.Hide();
260+
_canvasHelper.SetCursor("default");
261+
_topLevelImpl.SetCssCursor = x =>
262+
{
263+
_inputHelper.SetCursor(x); //macOS
264+
_canvasHelper.SetCursor(x); //windows
265+
};
266+
267+
Console.WriteLine("starting html canvas setup");
268+
_interop = await SKHtmlCanvasInterop.ImportAsync(Js, _htmlCanvas, OnRenderFrame);
269+
270+
Console.WriteLine("Interop created");
271+
_jsGlInfo = _interop.InitGL();
272+
273+
Console.WriteLine("jsglinfo created - init gl");
274+
275+
// create the SkiaSharp context
276+
if (_context == null)
257277
{
258-
_inputHelper = await InputHelperInterop.ImportAsync(Js, _inputElement);
259-
_canvasHelper = await InputHelperInterop.ImportAsync(Js, _htmlCanvas);
260-
261-
_inputHelper.Hide();
262-
_canvasHelper.SetCursor("default");
263-
_topLevelImpl.SetCssCursor = x =>
264-
{
265-
_inputHelper.SetCursor(x);//macOS
266-
_canvasHelper.SetCursor(x);//windows
267-
};
268-
269-
Console.WriteLine("starting html canvas setup");
270-
_interop = await SKHtmlCanvasInterop.ImportAsync(Js, _htmlCanvas, OnRenderFrame);
271-
272-
Console.WriteLine("Interop created");
273-
_jsGlInfo = _interop.InitGL();
274-
275-
Console.WriteLine("jsglinfo created - init gl");
276-
277-
_sizeWatcher = await SizeWatcherInterop.ImportAsync(Js, _htmlCanvas, OnSizeChanged);
278-
_dpiWatcher = await DpiWatcherInterop.ImportAsync(Js, OnDpiChanged);
279-
280-
Console.WriteLine("watchers created.");
281-
282-
// create the SkiaSharp context
283-
if (_context == null)
284-
{
285-
Console.WriteLine("create glcontext");
286-
_glInterface = GRGlInterface.Create();
287-
_context = GRContext.CreateGl(_glInterface);
288-
289-
var options = AvaloniaLocator.Current.GetService<SkiaOptions>();
290-
// bump the default resource cache limit
291-
_context.SetResourceCacheLimit(options?.MaxGpuResourceSizeBytes ?? 32 * 1024 * 1024);
292-
Console.WriteLine("glcontext created and resource limit set");
293-
}
294-
295-
_topLevelImpl.SetSurface(_context, _jsGlInfo, ColorType,
296-
new PixelSize((int)_canvasSize.Width, (int)_canvasSize.Height), _dpi);
297-
298-
_initialised = true;
299-
300-
_topLevel.Prepare();
301-
302-
_topLevel.Renderer.Start();
303-
304-
// Note: this is technically a hack, but it's a kinda unique use case when
305-
// we want to blit the previous frame
306-
// renderer doesn't have much control over the render target
307-
// we render on the UI thread
308-
// We also don't want to have it as a meaningful public API.
309-
// Therefore we have InternalsVisibleTo hack here.
310-
if (_topLevel.Renderer is DeferredRenderer dr)
311-
{
312-
dr.Render(true);
313-
}
314-
315-
Invalidate();
316-
});
278+
Console.WriteLine("create glcontext");
279+
_glInterface = GRGlInterface.Create();
280+
_context = GRContext.CreateGl(_glInterface);
281+
282+
var options = AvaloniaLocator.Current.GetService<SkiaOptions>();
283+
// bump the default resource cache limit
284+
_context.SetResourceCacheLimit(options?.MaxGpuResourceSizeBytes ?? 32 * 1024 * 1024);
285+
Console.WriteLine("glcontext created and resource limit set");
286+
}
287+
288+
_topLevelImpl.SetSurface(_context, _jsGlInfo, ColorType,
289+
new PixelSize((int)_canvasSize.Width, (int)_canvasSize.Height), _dpi);
290+
291+
_initialised = true;
292+
293+
_topLevel.Prepare();
294+
295+
_topLevel.Renderer.Start();
296+
297+
Invalidate();
298+
299+
_sizeWatcher = await SizeWatcherInterop.ImportAsync(Js, _htmlCanvas, OnSizeChanged);
300+
_dpiWatcher = await DpiWatcherInterop.ImportAsync(Js, OnDpiChanged);
317301
}
318302
}
319303

@@ -335,16 +319,28 @@ public void Dispose()
335319
_interop.Dispose();
336320
}
337321

338-
private void OnDpiChanged(double newDpi)
322+
private void ForceBlit()
339323
{
340-
_dpi = newDpi;
324+
// Note: this is technically a hack, but it's a kinda unique use case when
325+
// we want to blit the previous frame
326+
// renderer doesn't have much control over the render target
327+
// we render on the UI thread
328+
// We also don't want to have it as a meaningful public API.
329+
// Therefore we have InternalsVisibleTo hack here.
341330

342-
_topLevelImpl.SetClientSize(_canvasSize, _dpi);
343-
344331
if (_topLevel.Renderer is DeferredRenderer dr)
345332
{
346333
dr.Render(true);
347334
}
335+
}
336+
337+
private void OnDpiChanged(double newDpi)
338+
{
339+
_dpi = newDpi;
340+
341+
_topLevelImpl.SetClientSize(_canvasSize, _dpi);
342+
343+
ForceBlit();
348344

349345
Invalidate();
350346
}
@@ -357,17 +353,14 @@ private void OnSizeChanged(SKSize newSize)
357353

358354
_topLevelImpl.SetClientSize(_canvasSize, _dpi);
359355

360-
if (_topLevel.Renderer is DeferredRenderer dr)
361-
{
362-
dr.Render(true);
363-
}
356+
ForceBlit();
364357

365358
Invalidate();
366359
}
367360

368361
public void Invalidate()
369362
{
370-
if (!_initialised || _canvasSize.Width <= 0 || _canvasSize.Height <= 0 || _dpi <= 0 || _jsGlInfo == null)
363+
if (!_initialised || _jsGlInfo == null)
371364
{
372365
Console.WriteLine("invalidate ignored");
373366
return;

0 commit comments

Comments
 (0)