Skip to content
This repository has been archived by the owner on Mar 30, 2019. It is now read-only.

[Win8.1] SwapChainPanel scaling is ignored #287

Closed
kobush opened this issue Feb 20, 2014 · 9 comments
Closed

[Win8.1] SwapChainPanel scaling is ignored #287

kobush opened this issue Feb 20, 2014 · 9 comments

Comments

@kobush
Copy link
Contributor

kobush commented Feb 20, 2014

I really appreciate that you have already integrated supported for SwapChainPanel control. However when runing sample app on Surface Pro device the output isn't scaled correctly to screen size. See screenshot where I added colored rectangles to indicate bounds. Notice how that game content overlaps with these bounds.

swapchainpanel1

You can reproduce this in simulator by changing resolution (monitor button) to 1920x1080 (140%). In this case windows applies scaling to adjust the logical DPI. You can read more here.

Here is mention of SwapChainPanel size synchronization in this post: http://blogs.windows.com/windows/b/appbuilder/archive/2013/11/19/what-s-new-for-xaml-and-directx-interop-in-windows-8-1.aspx

There are CompositionScaleX/Y properties exposed specifically to accomodate this. Usage with DirectX can be found in this sample http://code.msdn.microsoft.com/windowsapps/XAML-SwapChainPanel-00cb688b

I've tried to implement this in SharpDX adding this code to SwapChainGraphicsPresenter (here scaling values are hard-coded):

        var compositionScaleX = 1.4f;
        var compositionScaleY = 1.4f;

        var swapChain2 = new SwapChain2(swapChain1.NativePointer);

        Matrix3x2 invertScale = new Matrix3x2(0);
        invertScale.M11 = 1f / compositionScaleX;
        invertScale.M22 = 1f / compositionScaleY;
        swapChain2.MatrixTransform = invertScale;

There are few more places where DPI scaling should be applied but this change seems to fix the issue. See the 2nd screenshot.

swapchainpanel2

Notice however that there is 1px black line on right and bottom edge. For some reason size used to create back buffer is one-pixel shorter than it should be.

Finally DisplayProperties.LogicalDpi is deprecated and DisplayInformation.LogicalDpi should be used instead.

@TheWhiteAmbit
Copy link
Contributor

You are right, DPI-Scaling is not yet implemented for the outer Direct3DUserControl. However, there is a callback method called DisplayProperties_LogicalDpiChanged. The name remains from deprecated DisplayProperties.LogicalDpi, but in fact it uses DisplayInformation.LogicalDpi. Feel free to rename the method and implement your solution in place. Creating a Pull request for your changes would let others participate in your enhancement. Even better would be looking for a solution not to scale the SwapChain in View, but to resize the render area. This reduces calculations and improves picture quality. So I did not implement it, because this might be to much for some users not prefering to have the render area resized by DPI-scaling.

@TheWhiteAmbit
Copy link
Contributor

I just offered a Pull-Request renaming the method an adding a

//TODO: handle other value affected by DPI change

@kobush
Copy link
Contributor Author

kobush commented Feb 20, 2014

Actually if I understand this correctly the solution I described above does exactly that. Currently the element is scalled up by WinRT logical scaling. But if you apply inversed scale on swapChain2.MatrixTransform it will be scalled back to hardware resolution so its effect is canceled out. I tested it on the device and I couldn't see any scaling artifacts.

@kobush
Copy link
Contributor Author

kobush commented Feb 20, 2014

Thanks for the Pull-Request. I will try to implement this in this method.

@TheWhiteAmbit
Copy link
Contributor

Cool :)

@TheWhiteAmbit
Copy link
Contributor

I also added a stub for CompositionScaleChanged event. I think you will need it also :)

@TheWhiteAmbit
Copy link
Contributor

This should be best visible not on downscaling, but on upscaling. Have you tried this with a scale factor of 2x or 3x. If pixels are still 1:1 crips then, it is perfect :) I think it is save to create a swapChain2 instead of swapChain1 initially. This would make your cast

        var swapChain2 = new SwapChain2(swapChain1.NativePointer);

unnecessary. Also you could try using double or different rounding strategy on the float-values to avoid 1px gap. But you probably know by yourself, and this is fine tuning I would do as a final step.

@kobush
Copy link
Contributor Author

kobush commented Feb 20, 2014

I have implemented these changes and created a pull request (I'm a GitHub noob, so let me know if this isn't the right way to do publish changes). I've added two sliders on MainPage so you can test with different transformations.

I didn't make it clear in the bug report but what I was originally looking for is implementing this in the Toolkit. It seems more complex to plug this into exisitng architecture so I appreciate if someone could point me in right direction.

@TheWhiteAmbit
Copy link
Contributor

I will look at it soon, at first it looks good. Are changes in "SharpDX.sln.DotSettings" really needed?
"XAML SwapChainPanel DirectX interop sample" demonstrates it at

"3. Scale DirectX content smoothly and precisely
This scenario shows how to scale DirectX content in a ScrollViewer control."

But I think even this sample is not completely DPI-Scale aware. Did you try it on your Surface Pro? Same steps should be done but completely in C#. Did you lookup the class where SwapChain1 was defined? You maybe can avoid the cast.

@xoofx xoofx closed this as completed Mar 15, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants