Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce RenderOptions.RequiresFullOpacityHandling #12572

Conversation

Gillibald
Copy link
Contributor

What does the pull request do?

  <Grid
    RenderOptions.RequiresFullOpacityHandling="True"
    Height="200" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center" 
    Background="Silver">
    <StackPanel Margin="10" Orientation="Horizontal"
      HorizontalAlignment="Center" VerticalAlignment="Top">
      <Ellipse Margin="0,0,-20,0" Width="80" Height="80" Fill="Green" />
      <Ellipse Margin="-20,0,0,0" Width="80" Height="80" Fill="Blue" />
    </StackPanel>
    <StackPanel Margin="10" Orientation="Horizontal"
      HorizontalAlignment="Center" VerticalAlignment="Bottom" Opacity="0.5">
      <Ellipse Margin="0,0,-20,0" Width="80" Height="80" Fill="Green" />
      <Ellipse Margin="-20,0,0,0" Width="80" Height="80" Fill="Blue" />
    </StackPanel>
  </Grid>

Screenshot 2023-08-17 133746

What is the current behavior?

What is the updated/expected behavior with this PR?

How was the solution implemented (if it's not obvious)?

Checklist

Breaking changes

Obsoletions / Deprecations

Fixed issues

@Gillibald Gillibald changed the title Introduce RequiresFullOpacityHandling Introduce RenderOptions.RequiresFullOpacityHandling Aug 17, 2023
@timunie
Copy link
Contributor

timunie commented Aug 17, 2023

@Gillibald I guess there are issues that would be solved? e.g.: #9227

@Gillibald
Copy link
Contributor Author

Gillibald commented Aug 17, 2023

Yes, it gives control over layered opacity handling per visual so the performance impact isn't that high anymore. It still applies to the whole sub-scene so if you define this on the TopLevel it behaves the same as if you enable it globally via the UserOpacitySaveLayer option.

@avaloniaui-team
Copy link
Contributor

You can test this PR using the following package version. 11.0.999-cibuild0038506-beta. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@@ -189,7 +189,10 @@ public void DrawBitmap(IBitmapImpl source, double opacity, Rect sourceRect, Rect
var d = destRect.ToSKRect();

var paint = SKPaintCache.Shared.Get();
paint.Color = new SKColor(255, 255, 255, (byte)(255 * opacity * (_useOpacitySaveLayer ? 1 : _currentOpacity)));

var useOpacitySaveLayer = _useOpacitySaveLayer || RenderOptions.RequiresFullOpacityHandling == true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to push the _currentOpacity value and set it to 1. Otherwise rendering will be broken with the following visual tree structure:

- Border №1 - opacity: 0.8
  - Border №2 - opacity: 0.8, requires full opacity: true
     - Border №3 - opacity: 0.8, requires full opacity: true

In this case Border №3 would get rendered with 0.64 opacity into a layer created by Border №2, while it should be rendered with 0.8.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another problem I think we have is the first two borders: we don't take the accumulated _currentOpacity from Border №1 when rendering the layer from Border №2.

if(_useOpacitySaveLayer)
var useOpacitySaveLayer = _useOpacitySaveLayer || RenderOptions.RequiresFullOpacityHandling == true;

if (useOpacitySaveLayer)
{
if (bounds.HasValue)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in this branch we still need to use the opacity stack, but instead of _currentOpacity *= opacity; we need _currentOpacity = 1

@billhenn
Copy link
Contributor

Just curious, once this attached property gets added, would .With(new SkiaOptions { UseOpacitySaveLayer = true }); still need to be used or will this new RenderOptions property work independently of the other setting? From the last post's code it looks like either one will activate the feature, correct?

@Gillibald
Copy link
Contributor Author

Just curious, once this attached property gets added, would .With(new SkiaOptions { UseOpacitySaveLayer = true }); still need to be used or will this new RenderOptions property work independently of the other setting? From the last post's code it looks like either one will activate the feature, correct?

Correct. With the small difference that the Skia option applies globally.

@billhenn
Copy link
Contributor

That's great, it will be much nicer to have this render option available to only affect small subtrees where needed.

@Gillibald Gillibald force-pushed the feature/renderOptionsRequiresFullOpacityHandling branch from 4b998b1 to 4b5c680 Compare August 18, 2023 14:22
@avaloniaui-team
Copy link
Contributor

You can test this PR using the following package version. 11.0.999-cibuild0038568-beta. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@kekekeks kekekeks added this pull request to the merge queue Aug 19, 2023
Merged via the queue into AvaloniaUI:master with commit b98cec5 Aug 19, 2023
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants