@@ -26,8 +26,8 @@ public partial class AvaloniaView : ITextInputMethodImpl
26
26
private InputHelperInterop _canvasHelper = null ! ;
27
27
private ElementReference _htmlCanvas ;
28
28
private ElementReference _inputElement ;
29
- private double _dpi ;
30
- private SKSize _canvasSize ;
29
+ private double _dpi = 1 ;
30
+ private SKSize _canvasSize = new ( 100 , 100 ) ;
31
31
32
32
private GRContext ? _context ;
33
33
private GRGlInterface ? _glInterface ;
@@ -249,71 +249,55 @@ private void OnInput(ChangeEventArgs e)
249
249
[ Parameter ( CaptureUnmatchedValues = true ) ]
250
250
public IReadOnlyDictionary < string , object > ? AdditionalAttributes { get ; set ; }
251
251
252
- protected override void OnAfterRender ( bool firstRender )
252
+ protected override async Task OnAfterRenderAsync ( bool firstRender )
253
253
{
254
254
if ( firstRender )
255
255
{
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 )
257
277
{
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 ) ;
317
301
}
318
302
}
319
303
@@ -335,16 +319,28 @@ public void Dispose()
335
319
_interop . Dispose ( ) ;
336
320
}
337
321
338
- private void OnDpiChanged ( double newDpi )
322
+ private void ForceBlit ( )
339
323
{
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.
341
330
342
- _topLevelImpl . SetClientSize ( _canvasSize , _dpi ) ;
343
-
344
331
if ( _topLevel . Renderer is DeferredRenderer dr )
345
332
{
346
333
dr . Render ( true ) ;
347
334
}
335
+ }
336
+
337
+ private void OnDpiChanged ( double newDpi )
338
+ {
339
+ _dpi = newDpi ;
340
+
341
+ _topLevelImpl . SetClientSize ( _canvasSize , _dpi ) ;
342
+
343
+ ForceBlit ( ) ;
348
344
349
345
Invalidate ( ) ;
350
346
}
@@ -357,17 +353,14 @@ private void OnSizeChanged(SKSize newSize)
357
353
358
354
_topLevelImpl . SetClientSize ( _canvasSize , _dpi ) ;
359
355
360
- if ( _topLevel . Renderer is DeferredRenderer dr )
361
- {
362
- dr . Render ( true ) ;
363
- }
356
+ ForceBlit ( ) ;
364
357
365
358
Invalidate ( ) ;
366
359
}
367
360
368
361
public void Invalidate ( )
369
362
{
370
- if ( ! _initialised || _canvasSize . Width <= 0 || _canvasSize . Height <= 0 || _dpi <= 0 || _jsGlInfo == null )
363
+ if ( ! _initialised || _jsGlInfo == null )
371
364
{
372
365
Console . WriteLine ( "invalidate ignored" ) ;
373
366
return ;
0 commit comments