`SolidColorBrush` is now mutable. There are immutable versions of
brushes in the `Avalona.Media.Immutable` namespace and the static
`Brushes.Xxx` properties return these.
And make an immutable `SceneImageBrush` and `SceneVisualBrush` which
clone the mutable `ImageBrush` and `VisualBrush` for use in the scene
graph, as we shouldn't be accessing mutable state from the render
thread.
Run deferred render tests on a background thread to expose any threading
errors in the deferred rendering path. And threading errors found. Also
had to decrease the timeout for D2D render tests as
`renderTarget.EndDraw` is hanging when an exception is thrown between
`renderTarget.BeginDraw` and `EndDraw`.
`VisualBrush`es need to get delegated back to the renderer for
rendering, so added an `IVisualBrushRenderer` interface which is
implemented by the renderers, and pass this when creating drawing
contexts. Only currently implemented/tested for D2D and
`ImmediateRenderer`.
Don't try to render `VisualBrush`es in TileBrushImpl - visual brushes
need first to be transformed into images and then rendered as an
`ImageBrush`. To this end, renamed `TileBrushImpl` as `ImageBrushImpl`
(in D2D backend only for now as that's what I'll get working first).
Actual visual brush implementation not yet done.
If we have e.g. a named UserControl in a window then we want that
control to be findable by name from the Window, so register with both
name scopes. This differs from WPF's behavior in that XAML manually
registers controls with name scopes based on the XAML file in which the
name attribute appears, but we're trying to avoid XAML magic in Avalonia
in order to made code-created UIs easy. This will cause problems if a
UserControl declares a name in its XAML and that control is included
multiple times in a parent control
(as the name will be duplicated), however at the moment I'm fine with
saying "don't do that".
Fixes#829.
Layers are now calculated by SceneBuilder and stored in Scene. This
means we are no longer accessing `visual.Opacity` from the render thread
(and `VerifyAccess` calls have been placed in AvaloniaObject.GetValue
and friends to ensure this cannot happen). ControlCatalog is now
rendering mostly fine.
Because it needs to be shared between the UI thread and the render
thread. This also required making it non-disposable like the other
graphics primitive impls.