Nir Hasson
Topic Author
Posts: 71
Joined: 10 Nov 2013, 21:20
Contact:

Predict Off-screen Render Target Size

10 Dec 2013, 13:14

Hi,

I'm getting the following error on several controls I created:
Offscreen atlas texture is full. Can't find space for 776x301 rectangle. Please increase Offscreen size in renderer
So far I solved this issue by increasing the offscreen render target size using the IRenderere::SetOffscreenSize method.

I would like to make sure that our application won't get any error of this kind during it's runtime.
What is the best way to deal with this error ?
SImply increase the offscreen size of any control I created ? (That sounds like a waste of resources)
Testing every control until we get no errors ?
Can I compute the needed offscreen size and apply it to each renderer ?

Regards,
Nir
 
User avatar
sfernandez
Site Admin
Posts: 3222
Joined: 22 Dec 2011, 19:20

Re: Predict Off-screen Render Target Size

11 Dec 2013, 11:08

Offscreen render target is used to render opacity groups (element trees with an Opacity < 1.0 or using an OpacityMask). This render target is used as a texture atlas that is filled each frame with the rects needed to render each opacity group at one level (level known as all the opacity groups that should be generated at the same time because they are siblings).

The following example will require that your offscreen render target has space for 2 rects (100x50 and 200x100) that are generated at the same time because they are siblings. Requiring a total space of 300x100 or 200x150.
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Border Background="Red" Width="100" Height="50" Opacity="0.5"/>
        <Border Background="Green" Width="200" Height="100" Opacity="0.5"/>
    </StackPanel>
</Grid>
However, the following example will only require an offscreen render target of 200x100 (the bigger rect), because only one opacity group is rendered at a time.
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Border Background="Red" Width="200" Height="100" Opacity="0.5">
        <Border Background="Green" Width="150" Height="75" Opacity="0.5">
            <Border Background="Blue" Width="100" Height="50" Opacity="0.5"/>
        </Border>
    </Border>
</Grid>
So, to predict the size of the offscreen render target, you have to know how many UI elements with Opacity/OpacityGroup in your XAML will be rendered at the same time (not nested).

NOTE: Offscreen size is specified relative to the size of the main render target (window/screen). An offscreen size of 1,1 creates an offscreen render target with the same size than the main render target.
 
User avatar
jsantos
Site Admin
Posts: 4266
Joined: 20 Jan 2012, 17:18
Contact:

Re: Predict Off-screen Render Target Size

12 Dec 2013, 01:35

Note that the offscreen must be set by application (in fact, per renderer, but usually you only have one per camera) not by control.

In previous version of Noesis this setup was done automatically behind the walls but it was giving performance problems (we had to create rendertargets in the middle of the execution which is a bad idea if you want to avoid spikes). So now setting the offscreen is like setting the max memory avaliable to your application. You have to test it to be sure that there is enough memory. But at least the results are deterministics.

Anyway, our advice: try to minimize these numbers as much as possible (more than 100% is probably a bad number) because many cases of opacity groups can be avoided. Of course 0% is the best, although even our themes aren't yet optimized to that level.
 
Nir Hasson
Topic Author
Posts: 71
Joined: 10 Nov 2013, 21:20
Contact:

Re: Predict Off-screen Render Target Size

12 Dec 2013, 05:26

In my case I'm creating elements dynamically and add them to some ItemsControl so I can't calculate a static size before execution - Am I wrong ?

In my opinion the automatic approach is better but the offscreen size API should be kept and it will determine the quality of the output result. Your renderer will have to fit all needed elements into the given offscreen texture atlas.
In this way the application will always work, and the developer will have full control over how much GPU resources he would like to allocate. You can pre-allocate these resources in order to avoid runtime spikes.

Beside that - can't you use staright forward rendering to accomplish the UI rendering in one pass ? I guess you'll have the overhead of changing states (Alpha blend/test ) and maybe some kind of sorting but it might worth the effort. If you can do that you'll have a fallback when the offsreen target is not suitable.
 
User avatar
sfernandez
Site Admin
Posts: 3222
Joined: 22 Dec 2011, 19:20

Re: Predict Off-screen Render Target Size

12 Dec 2013, 14:45

Opacity groups is a complex problem (specially nested opacity groups) that requires the use of extra buffers to achieve a correct result.

Imagine the following scenarios (using pseudo code):
<page bg=white>
    <rect bg=red opacity=0.5>
        <rect bg=blue opacity=0.5/>
    </rect>
</page>

<page bg=white>
    <ellipse bg=red opacity=0.5>
        <ellipse bg=red opacity=0.5/>
    </ellipse>
</page>
Using a straight forward solution does not solve nested opacities correctly, because blending is not solved in the correct order. You would get something like this:
forward-blending.png
forward-blending.png (4.2 KiB) Viewed 5748 times
The expected and visually correct result should be:
opacity-group.png
opacity-group.png (3.44 KiB) Viewed 5748 times
About managing the offscreen buffers automatically, in dynamic scenarios (like the one you are describing), we cannot pre-allocate to avoid runtime spikes. An automatic solution will require to create a new extra buffer when the previous one becomes full. Maybe is the only solution to avoid runtime crashes, but we need to think about it and evaluate the pros and cons.

I want to remark the following: the rule is, the more 'opacity' attributes you have in your document, the more it's going to hurt performance. You should think carefully before using this attribute, and make absolutely sure that you can't achieve the same effect using the brush-opacity attributes.
 
Nir Hasson
Topic Author
Posts: 71
Joined: 10 Nov 2013, 21:20
Contact:

Re: Predict Off-screen Render Target Size

12 Dec 2013, 15:06

Thanks for the detailed explanation and examples.. I see the problem now.

As for my case - I didn't use any opacity groups explicitly in the source XAML file, but I guess they are coming from my custom Theme that is based on your own provided Theme.
These themes contain multiple references to Opacity property that are activated on visual state transitions..
I guess that in case I'll eliminate their usage I could reduce the offscreen usage dramatically.

Beside performance issues that you've mentioned, the application stability is much more important to me so please consider an alternative approach to this issue. Even unexpected visual rendering is preferred over runtime crash on our customers sites...
 
User avatar
sfernandez
Site Admin
Posts: 3222
Joined: 22 Dec 2011, 19:20

Re: Predict Off-screen Render Target Size

13 Dec 2013, 11:12

Our NoesisStyle contains lots of element opacity animations we want to change, because most of them can be brush opacity animations that are more efficient.

We will consider an alternative approach for the offscreen render targets, runtime crashes should not happen.
 
User avatar
ai_enabled
Posts: 231
Joined: 18 Jul 2013, 05:28
Contact:

Re: Predict Off-screen Render Target Size

14 Dec 2013, 02:36

This is really annoying problem. In the our project we have already minimized using of opacity groups, but knowledge that our game can crash in any time just because we was wrong when set the offscreen render size is terrifying. So I vote for automatically increasing of the off-screen size when it's required (with error notification to editor log, or warning notification to game log) in the future versions of the NoesisGUI.

sfernandez, "Our NoesisStyle contains lots of element opacity animations we want to change, because most of them can be brush opacity animations that are more efficient."
Is not the brush opacity also uses off-screen render? I'm little bit confused with it.
And what is better approach to animate solid color brush - by changing it's Alpha color or by changing the Opacity property?
AtomicTorch Studio Pte. Ltd. http://atomictorch.com
 
User avatar
sfernandez
Site Admin
Posts: 3222
Joined: 22 Dec 2011, 19:20

Re: Predict Off-screen Render Target Size

15 Dec 2013, 12:14

sfernandez, "Our NoesisStyle contains lots of element opacity animations we want to change, because most of them can be brush opacity animations that are more efficient."
Is not the brush opacity also uses off-screen render? I'm little bit confused with it.
And what is better approach to animate solid color brush - by changing it's Alpha color or by changing the Opacity property?
The only properties that start an opacity group (which uses off-screen render) are UIElement.Opacity and UIElement.OpacityMask, because they apply to the whole element subtree.

Setting Brush.Opacity or the alpha channel of the color of any Brush only affects that Brush resource.

So, avoid:
<Rectangle Fill="Red" Opacity="0.5"/>
When you can have this:
<Rectangle Fill="#80FF0000"/>
<Rectangle>
    <Rectangle.Fill>
        <SolidColorBrush Color="Red" Opacity="0.5"/>
    </Rectangle.Fill>
</Rectangle>
Element opacity groups should only be used when the opacity has to be applied to a group of elements:
<Grid Opacity="0.5">
    <Rectangle Fill="Red"/>
    <Ellipse Fill="Blue"/>
</Grid>
;)
 
User avatar
jsantos
Site Admin
Posts: 4266
Joined: 20 Jan 2012, 17:18
Contact:

Re: Predict Off-screen Render Target Size

16 Dec 2013, 04:26

This is really annoying problem. In the our project we have already minimized using of opacity groups, but knowledge that our game can crash in any time just because we was wrong when set the offscreen render size is terrifying. So I vote for automatically increasing of the off-screen size when it's required (with error notification to editor log, or warning notification to game log) in the future versions of the NoesisGUI.
It won't crash if you tested all states of your gui. The behaviour is deterministic, it won't randomly crash. I see it very similar to being constrained by a limited size of memory.

Anyway, our current implementation can be improved. For example:
  • Detect cases where the opacity is not needed and generate a warning in the log or even being smart and try to carry the opacity to the brush of the internal node. I would say this will eliminate a very high percentage of offscreen uses.
  • If there is not enough space in the offscreen texture instead of giving an error we could render the node without opacity with straight forward render. Although this will render the xaml incorrectly.

Who is online

Users browsing this forum: Ahrefs [Bot], Semrush [Bot], sunyan and 1 guest