These are chat archives for AvaloniaUI/Avalonia

29th
Nov 2017
ksigne
@ksigne
Nov 29 2017 14:07
hi guys!
is there any way to get drawingcontext over writeablebitmap?
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:24
You are probably looking for RenderTargetBitmap
ksigne
@ksigne
Nov 29 2017 14:26
RenderTargetBitmap requires Visual to render
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:26
It doesn't
ksigne
@ksigne
Nov 29 2017 14:27
??
public void Render(IVisual visual) => ImmediateRenderer.Render(visual, this);
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer vbr) => PlatformImpl.CreateDrawingContext(vbr);
that's all it have
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:28
You can use CreateDrawingContext
ksigne
@ksigne
Nov 29 2017 14:28
but it brings me IDrawingContextImpl instead of DrawingContext
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:29
You can create DrawingContext from IDrawingContextImpl
ksigne
@ksigne
Nov 29 2017 14:29
how can i?
ksigne
@ksigne
Nov 29 2017 14:29
k
and what should i pass to IVisualBrushRenderer?
null?
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:30
You can safely pass null if you don't plan to render any visuals
ksigne
@ksigne
Nov 29 2017 14:31
k
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:31
@grokys we probably need a separate implementation of IVisualBrushRenderer that doesn't require render root like ImmediateRenderer does
@ksigne
Note: this part of the API is unstable and might change in further versions
ksigne
@ksigne
Nov 29 2017 14:32
who cares:)
Steven Kirk
@grokys
Nov 29 2017 14:37
i think you'll always be able to pass null for the visual brush renderer
we should probably make creating a drawing context for a writable bitmap a bit easier though!
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:39
RenderTargetBitmap
WritableBitmap should implement IFramebufferPlatformSurface, so it could be passed to any rendering subsystem
It would be inefficient, but WritableBitmap is supposed to provide raw access to pixel data anyway
ksigne
@ksigne
Nov 29 2017 14:51
ho, so i don't have any way to wrap RenderTargetBitmap into WriteableBitmap and get raw pixel data? until i save Bitmap to stream?
Nikita Tsukanov
@kekekeks
Nov 29 2017 14:52
You can implement IFramebufferPlatformSurface
And call WritableBitmap.Lock() from there
Then you can pass your IFramebufferPlatformSurface implementation to AvaloniaLocator.Current.GetService<IPlatformRenderInterface>().CreateRenderTarget
ksigne
@ksigne
Nov 29 2017 15:00
hmm, and can this implementation get current DPI through locator?
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:01
There is no such thing as "current dpi"
DPI is per-window
Or, in our case, per-TopLevel
ksigne
@ksigne
Nov 29 2017 15:02
ah, ok
when i create WriteableBitmap, it creates ILockedFramebuffer, which has Dpi property
but WriteableBitmap doesn't have Dpi in constructor or smth
so IPlatformRenderInterface should decide implicitly what Dpi it will be
ksigne
@ksigne
Nov 29 2017 15:08
public Vector Dpi { get; } = new Vector(96, 96);
and that's all
Whoops
It's hardcoded
ksigne
@ksigne
Nov 29 2017 15:10
yep, that's really bad
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:10
AvaloniaUI/Avalonia#1292
Tracked here
ksigne
@ksigne
Nov 29 2017 15:11
my original idea (implemented in wpf) is to apply pixel effects to controls
figure masking, blurring, etc
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:11
I think we already have geometry clip support
ksigne
@ksigne
Nov 29 2017 15:12
that's all nice, but that's already written, interface-isolated things :)
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:14
Passing bitmaps back and forth between CPU and GPU is really bad for performance
BTW, we really need to support some pixel effects
ksigne
@ksigne
Nov 29 2017 15:14
that's not a problem, because it's done only once
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:14
like blur and dropshadow
both Skia and Direct2D have support for them
ksigne
@ksigne
Nov 29 2017 15:15
this is actually specialized charts, so i just draw them once, do all the processing, and keep rendered picture
doing that on GPU will make it totally non-portable
ksigne
@ksigne
Nov 29 2017 15:23
RotateTransform doesn't have origin, wow
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:27
RenderTransformOrigins are different in WPF and Avalonia: If you apply a RenderTransform, keep in mind that our default value for the RenderTransformOrigin is RelativePoint.Center. In WPF the default value is RelativePoint.TopLeft (0, 0). In controls like Viewbox (currently being developed) the same code will lead to a different rendering behavior:
ksigne
@ksigne
Nov 29 2017 15:27
sorry, i speak about RenderTransform in drawing
so i have to do something like this, if i understood it right
using (var ptc1 = _drawingContext.PushPreTransform(new TranslateTransform(-x1, -y1).Value)) using (var ptc2 = _drawingContext.PushPreTransform(new RotateTransform(angle / Math.PI * 180).Value)) using (var ptc3 = _drawingContext.PushPreTransform(new TranslateTransform(x1, y1).Value)) DrawText(x1, y1, obj);
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:28
drawing code uses matrices directly
ksigne
@ksigne
Nov 29 2017 15:28
yeah, but wpf had rotate matrix factory with origin
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:28
It's better to multiply transformations manually
since you are using only PushPreTransform
so it would be PushPreTransform(Matrix.CreateTranslation(-x1, -y1) * Matrix.CreateRotation(angle / Math.PI * 180) * Matrix.CreateTranslation(x1, y1)
Not sure about the order, you might need to flip translation matrices
ksigne
@ksigne
Nov 29 2017 15:33
translation (-x1, -y1) will place point (x1,y1) to (0,0), which is rotation origin. wrong?
Nikita Tsukanov
@kekekeks
Nov 29 2017 15:38
It should
I always forget the order of matrix multiplication
ksigne
@ksigne
Nov 29 2017 18:20
btw
hittest works such way that transparent background wont be hitted
but if you do FillRectangle(Brushes.Transparent), it will
so
Nikita Tsukanov
@kekekeks
Nov 29 2017 18:22
Works as intended
It's the same in WPF
ksigne
@ksigne
Nov 29 2017 18:22
i know
but that makes scene more complex
Nikita Tsukanov
@kekekeks
Nov 29 2017 18:23
I think it's a no-op during rendering anyway
ksigne
@ksigne
Nov 29 2017 18:23
y?
i tried the following
i made a simple datagrid, which created 1000+ datacells with textblock on my screen
and when i check pointer over cells and borders to display column resize cursor
i got thousands of hit tests calls
each of all involves testing textblock, which is not cheap anyway
Nikita Tsukanov
@kekekeks
Nov 29 2017 18:25
Our hittest algorithm might be ignoring control bounds or something like that
ksigne
@ksigne
Nov 29 2017 18:26
no, i suppose you move pointer in realtime
and everytime you do, complex hit test is called
what i've came to
i did IsHitTest = false for each cell
filled datagrid bottom layer with transparent rectangle
and reimplemented hit test
this solution seems acceptable, but not elegant anyway
what i can suggest - is to switch hittest between "render-base" and "bounds-base"
so control (visual?) can claim itself "bounds based hittested" and hit test will be done by layout manager not by renderer
Steven Kirk
@grokys
Nov 29 2017 18:58
@ksigne yeah that would be do-able i think, though it wouldn't work with render transforms
oh, yeah mean change it globally?
ksigne
@ksigne
Nov 29 2017 18:58
render-based hit test is default as i think
Steven Kirk
@grokys
Nov 29 2017 18:59

each of all involves testing textblock, which is not cheap anyway

this shouldn't be the case, the hit-test tests the scene graph which will already have this info

ksigne
@ksigne
Nov 29 2017 18:59
and when you come to ultra-complex visual trees, like datagrid or what
you can reduce complexity of hittest
that's what i mean
Steven Kirk
@grokys
Nov 29 2017 19:00
are you seeing perf problems?
ksigne
@ksigne
Nov 29 2017 19:01
not much. but anyway i'd like to get rid of "transparent rectangle" on controls
Steven Kirk
@grokys
Nov 29 2017 19:26
transparent rectangles on controls?
oh, i think i understand
tbh all other xaml frameworks work like that so i'd be hesitant to change it