These are chat archives for AvaloniaUI/Avalonia

17th
Aug 2017
Matthijs ter Woord
@mterwoord
Aug 17 2017 06:13
@kekekeks @danwalmsley No! I want a corner radius on my buttons
on some of my buttons, hence the Round selector/class
if i replace the template in the main style, it works for pointerover (which is great), but pressed then doesn't use the same template
something seems off there
danwalmsley
@danwalmsley
Aug 17 2017 08:35
you want rounded corners all the time?
or just when you have it pressed or pointer over?
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:39
all the time
danwalmsley
@danwalmsley
Aug 17 2017 08:39
just trying it now
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:40
@grokys In general, replacing the template for a control shouldn't be a problem imo (even perf wise), switchign templates on hover should be prevented if possible
(but should still be possible)
@danwalmsley right now, that doesn't work for the pressed class (throws error), but the button does expect that you do that
@danwalmsley my situation: i want rounded corners for buttons. works great by replacing the template (Selector="Button")
Works for the selectors normal and :pointerover, but not for :pressed
that's bug (?) number 1
danwalmsley
@danwalmsley
Aug 17 2017 08:44
I see it
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:44
then i tried to replace the template of the :pressed, that results in an error (bug 2, imo)
both bugs?
danwalmsley
@danwalmsley
Aug 17 2017 08:45
i think this must be a bug with style selectors
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:45
souds like a difficult one to fix..
danwalmsley
@danwalmsley
Aug 17 2017 08:45
 <Style Selector="Button.RoundedButton">
      <Setter Property="Template">
        <ControlTemplate>
          <Border Background="Red" CornerRadius="8">
            <ContentPresenter Content="{TemplateBinding Content}"/>
          </Border>
        </ControlTemplate>
      </Setter>
    </Style>
that should have been sufficient
on its own
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:46
yeah, that's my point (bug 1)
danwalmsley
@danwalmsley
Aug 17 2017 08:46
but sounds like style selectors are not inheriting
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:46
well, it does for :pointerover, but not for :pressed
(re-verifying that now)
danwalmsley
@danwalmsley
Aug 17 2017 08:48
yes it works
have you added an issue?
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:48
no, first wanted to verify i'm not mistaken :)
danwalmsley
@danwalmsley
Aug 17 2017 08:49
I'm adding one now
id say that's definitely a bug
the template shouldn't be getting swapped out
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:49
as an open source maintainer (different project), i hate clutter of the issues database..
danwalmsley
@danwalmsley
Aug 17 2017 08:49
i know what you mean
AvaloniaUI/Avalonia#1102
Matthijs ter Woord
@mterwoord
Aug 17 2017 08:58
i would personally have split the issue though..
but that might also depend on how things work internally..
danwalmsley
@danwalmsley
Aug 17 2017 09:00
yes, but it may turn out the second item isn't a bug
its just a hint to check if that works after fixing the first item
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:02
it might be related to multiple pseudo classes being applied
(when its pressed, it's also pointerover)
danwalmsley
@danwalmsley
Aug 17 2017 09:03
yes, but if you change the template with no pseudo classes
it should be inherited
i.e. if you did this...
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:03
yes, but i mean, that the inheritance doesn't work when multiple pseudo-classes are active
danwalmsley
@danwalmsley
Aug 17 2017 09:03
<Style Selector="Button.RoundedButton">
      <Setter Property="Background" Value="Green" />
    </Style>
then all should be green
ok
let me see if it works with no classes
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:04
understand what i mean?
danwalmsley
@danwalmsley
Aug 17 2017 09:04
yes
just the the combination of pseudo classes somehow breaks inheritance
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:16
it's not the multiple-active-pseudoclasses thing i mentioned..
i changed the click code to first remove pointer over
doesnt help
danwalmsley
@danwalmsley
Aug 17 2017 09:17
@grokys I moved
RenderComposite(scene);
inside
if (scene.Generation != _lastSceneId)
                {
and tested on skia and direct2d on windows
no flickering?
and cpu usage is now 0% at idle
or have I missed something?
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:21
@danwalmsley i wish i could help with the styling thing, but to me it feels like some relly-low-level issue..
danwalmsley
@danwalmsley
Aug 17 2017 09:22
I'm not sure I can do much either
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:22
didn't mean to say that ;)
danwalmsley
@danwalmsley
Aug 17 2017 09:22
just going to step through in a minute see if I can get an idea of whats happening
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:26
unrelated question (to all): how do you guys work with the avalonia designer? to me, using it means getting build errors because files are in use
danwalmsley
@danwalmsley
Aug 17 2017 09:27
I have the same experience as you
Matthijs ter Woord
@mterwoord
Aug 17 2017 09:27
i do see the problem with shadowing (ie, getting garbage), but doing some cleanup there shouldn't be much of an issue
(also, %temp% is getting garbaged a lot anyway, so putting stuff there shouldn't be much of a problem)
or put it in obj folder somewhere, and try to cleanup un-used versions
other option is to load from ram
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:18

but doing some cleanup there shouldn't be much of an issue

the thing is that

But the time you are getting those errors
All designer processes are long dead
Since they are being killed on build
I have no idea, why files are still locked at that stage
It might be not designer process at all
danwalmsley
@danwalmsley
Aug 17 2017 10:19
@kekekeks any input on #1103?
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:20
nope
I think that we can skip rendering completely
It won't cause issues with Direct2D being double buffered
We could also use triple buffering
i. e. render to offscreen surface, copy to back buffer, flip
danwalmsley
@danwalmsley
Aug 17 2017 10:23
@grokys thought that that code change should cause flickering
but its not flickering for me
and cpu usage goes right down
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:23
It's OK to skip rendering completely
But not OK to re-render only dirty rects
Steven Kirk
@grokys
Aug 17 2017 10:23
hmm really, no flickering? have you tried with RenderTest too?
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:24
Direct2D continue presenting the fron buffer if there were no EndDraw calls
Steven Kirk
@grokys
Aug 17 2017 10:25
i was definitely getting flickering when i was working on it
danwalmsley
@danwalmsley
Aug 17 2017 10:25
@grokys is rendertest a branch?
danwalmsley
@danwalmsley
Aug 17 2017 10:26
just trying it now
Avalon studio and control catalog no flickering what so ever
i tried on both skia and direct2d
btw you may want to try a clean install of visual studio
if just done that last night
and so far its been a lot better
render test no flickering either
Steven Kirk
@grokys
Aug 17 2017 10:30
and you're using D2d?
danwalmsley
@danwalmsley
Aug 17 2017 10:31
hard coded to .UseWin32().UseDirect2D1()
to make sure
Steven Kirk
@grokys
Aug 17 2017 10:32
interesting! not sure what's going on ther ethen
if you'd like to submit a PR (that works with the overlay) i will take a look!
danwalmsley
@danwalmsley
Aug 17 2017 10:32
ok so with the overlay
what would I need to check
to decide if I'm going to render overlay?
also @kekekeks says completely skip render, perhaps I could try this too?
Steven Kirk
@grokys
Aug 17 2017 10:34
not sure what the best solution is for render overlay - you need to detect if it's changed from the last render
danwalmsley
@danwalmsley
Aug 17 2017 10:34
and the fps?
Steven Kirk
@grokys
Aug 17 2017 10:34
that's part of the overlay
danwalmsley
@danwalmsley
Aug 17 2017 10:35
the overlay is only for debugging right?
Steven Kirk
@grokys
Aug 17 2017 10:35
yeah
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:35
For overlay we could use that tripple buffering thingy
danwalmsley
@danwalmsley
Aug 17 2017 10:35
so could we just say
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:35
Keep scene rendered to a texture
copy it to the back buffer
And render overlay on top of that
danwalmsley
@danwalmsley
Aug 17 2017 10:35
if(DrawFPS || ShowDirtyRects)
?
Steven Kirk
@grokys
Aug 17 2017 10:36
i dunno tbh, if i'd figured it out i would've done it ;)
danwalmsley
@danwalmsley
Aug 17 2017 10:36

@kekekeks when you say skip render all together, how would I do that, you mean move the
if (scene.Generation != _lastSceneId)

to where render is called?

Nikita Tsukanov
@kekekeks
Aug 17 2017 10:39
Yep, something like that
But we might still need to re-render it
if window was unminimized, for example
danwalmsley
@danwalmsley
Aug 17 2017 10:42
this would still work though
and its almost as good as not calling render
oops
private void Render(Scene scene)
        {
            if (DrawDirtyRects || DrawFps)
            {
                RenderOverlay(scene);
            }

            if (scene.Generation != _lastSceneId)
            {
                if (scene.Size != Size.Empty)
                {
                    _dirtyRectsDisplay.Tick();

                    _layers.Update(scene);
                    RenderToLayers(scene);

                    if (DebugFramesPath != null)
                    {
                        SaveDebugFrames(scene.Generation);
                    }

                    _lastSceneId = scene.Generation;

                    RenderComposite(scene);
                }
            }
        }
hmm actually no that would also be the same,
how would we know if we un-minimized?
but does un-minimize require ui update?
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:47
wait
there is no point
in calling RenderOverlay
Without RenderComposite
overlay is rendered to a surface
So screen won't be updated at all
danwalmsley
@danwalmsley
Aug 17 2017 10:49
ok I think I have a solution
this
_dirtyRectsDisplay.Tick();
can return true or false
if it made a change
and then you know if you have to do a RenderComposite
I think
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:50
I'd say skip Render pass completely if FPS and dirty rects are disabled
And do full render pass (RenderOverlay+RenderComposite) if at least of of them is enabled
That will speed up rendering in production code
And keep debug mode operational
The proper way would be to have an intermediate surface in debug mode
Steven Kirk
@grokys
Aug 17 2017 10:52
thing is there's not really any point in displaying FPS if in displaying it it destroys FPS...
but i't'd be ok temporarily i guess
Nikita Tsukanov
@kekekeks
Aug 17 2017 10:52
so for now wrap entire method contents into if(scene.Generation != _lastSceneId || DrawDirtyRects || DrawFps){...}
I'll take a look later
Preferably after migration to Texture2D
BTW
We should probably use ID2D1BitmapRenderTarget
But the problem is that they are tied to render target
Steven Kirk
@grokys
Aug 17 2017 10:58
i was thinking that maybe we need something like interface IComposableRenderTarget : IRenderTarget { IRenderTargetBitmap CreateLayer(Size size); } for the top level render target?
Nikita Tsukanov
@kekekeks
Aug 17 2017 11:00
That won't solve performance issues with regular RenderTargetBitmaps
danwalmsley
@danwalmsley
Aug 17 2017 11:01
ok I'll do a quick PR where its just wrapped in this
if(scene.Generation != _lastSceneId || DrawDirtyRects || DrawFps){...}
and then we can do a better fix later
it gives me a massive performance increase for now
Steven Kirk
@grokys
Aug 17 2017 11:02
what i was intending is that a different type of IRenderTargetBitmapImpl with a different underlying D2D type could be created from render targets for layers
Nikita Tsukanov
@kekekeks
Aug 17 2017 11:02
You are also recreating device context
from time to time
Steven Kirk
@grokys
Aug 17 2017 11:03
layers would have to be thrown away when that happens obv
Nikita Tsukanov
@kekekeks
Aug 17 2017 11:03
Hm
Wait
We don't even have ID2D1RenderTarget anymore
Only device context
Oh, right, DeviceContext serves as ID2D1RenderTarget, I see
Yep, ID2D1RenderTarget::CreateCompatibleRenderTarget might work in that case
But we need some logic to check if layers are still valid
Matthijs ter Woord
@mterwoord
Aug 17 2017 11:07
@danwalmsley did you find something with some quick stepping?
danwalmsley
@danwalmsley
Aug 17 2017 11:19
@grokys @kekekeks if you have a few minutes to quickly review #1103 I think its ready
Nikita Tsukanov
@kekekeks
Aug 17 2017 11:22

couldn't we just dispose of any existing layers here?

DeviceContext is being recreated inside CreateDrawingContext call

Matthijs ter Woord
@mterwoord
Aug 17 2017 16:49
@danwalmsley If i would want to start digging (first time real digging into avalonia), would the selector issue be a wise thing to start with?
Steven Kirk
@grokys
Aug 17 2017 16:57
@mterwoord i think it would be a good thing to start digging into!
try to create a failing test for it first
Matthijs ter Woord
@mterwoord
Aug 17 2017 16:58
ok, how to start?
ah
hmm
Steven Kirk
@grokys
Aug 17 2017 16:58
(sorry i said failing PR, i meant failing test, got PRs on the brain atm)
you'll want to create a test that fails to match when you apply the classes
Matthijs ter Woord
@mterwoord
Aug 17 2017 17:11
Simple test doesn't repro:
            var control = new Control1();
            var pseudoClasses = (IPseudoClasses)control.Classes;
            var target = default(Selector).Class("Round");
            var activator = target.Match(control).ObservableResult;

            Assert.False(await activator.Take(1));
            control.Classes.Add("Round");
            Assert.True(await activator.Take(1));
            pseudoClasses.Add(":pointerover");
            Assert.True(await activator.Take(1));
            pseudoClasses.Remove(":pointerover");
            pseudoClasses.Add(":pressed");
            Assert.True(await activator.Take(1));
what code should be reacting to normal class changes?
hmm, shoot. back tomorrow.
Jeremy Koritzinsky
@jkoritzinsky
Aug 17 2017 22:07
@kekekeks instead of using compatible render targets we could use a ID2D1CommandList. That was part of the Platform Update for Windows 7 we already require.