Fullscreen Exclusive: How to change the native resolution? - directx

I can successfully control the native refresh-rate by specifying the refresh rate in DXGI_SWAP_CHAIN_FULLSCREEN_DESC which is passed to CreateSwapChainForHwnd.
I was expecting native resolution to change to that specified by the hight and width of the swapchain. However, I was not this lucky.
Moreover, the CreateSwapChainForHwnd suggests that you cant control the native resolution of the monitor since you can specify DXGI_SWAP_CHAIN_FULLSCREEN_DESC has a scaling parameter
typedef enum DXGI_MODE_SCALING {
DXGI_MODE_SCALING_UNSPECIFIED = 0,
DXGI_MODE_SCALING_CENTERED = 1,
DXGI_MODE_SCALING_STRETCHED = 2
} DXGI_MODE_SCALING;
But, video games are clearly trigging a mode change (temporary black screen) when they change resolution in fullscreen exclusive. So they must be able to change the native resolution. How are they doing this?
Also, I was wondering why DXGI_MODE_SCALING_STRETCHED only fills a sub-rectangle of screen (DXGI_MODE_SCALING_CENTERED centres on this sub-rectangle, and DXGI_MODE_SCALING_UNSPECIFIED aligns the swapchain's top right corner with the top-right of this sub-rectangle). This sub-rectangle also changes as the hight and width passed to CreateSwapChainForHwnd changes. Maybe it's that I'm really in Fullscreen Optimizations rather than Fullscreen Exclusive and this sub-rectangle is the same size of my window(changing the window size didn't affect the observed behaviour).

DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
Set this flag to enable an application to switch modes by calling IDXGISwapChain::ResizeTarget.
When switching from windowed to full-screen mode, the display mode (or monitor resolution) will be changed to match the dimensions of the application window.
https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ne-dxgi-dxgi_swap_chain_flag
Interestingly, the mode switch works correctly without the flag when changing refresh-rates but will not when changing resolutions

Related

How to judge the iPhone is iPhoneX series?

Is there any way to judge the iPhone is iPhoneX series(iPhone X XR XS XSmax)?
My way is:
#define iPhoneXSeries (([[UIApplication sharedApplication] statusBarFrame].size.height == 44.0f) ? (YES):(NO))
Is there any hidden trouble?
Or is there any better way?
I need to know because iPhoneX series statusbar's height are immutable but other iPhone's statusbar's height can change
So you don't really need to know whether your app is running on an iPhone X-series phone at all — what you're really trying to find out is whether the status bar height can change. And I'll be that you don't really even care about the status bar so much as you want to know where you can put content in your view so that it will always be unobscured by the status bar and other system objects. Whether that's the case or not, you should make sure that you're asking the right question. Don't rely on the device model to tell you about features, and don't rely on particular features to tell you the device model.
iOS usually gives you a way to find out about the features you need. If your goal is to keep your content visible, you should use UIView's safeAreaInsets property and also the safeAreaInsetsDidChange() method, which the system will call when the safe area changes (e.g. when the status bar height changes). You can then adjust your content to fit the new safe insets. Building your app this way means that you don't have to worry about your app breaking on new device models that have feature sets you don't expect, and you don't have to worry about future iOS updates undermining your assumptions.
Try this:
let size = UIScreen.mainScreen().bounds.size
print("Your device size: \(size)");
if size.height == 814 {
print("This is an iPhone X")
}

UITabBar Large Content Size Image (HUD) doesn't display in Large Text mode

iOS 11 has an accessibility feature that shows a large version of a tabbar icon in a pop-up HUD when long pressed. In a WWDC presentation, it was mentioned this just involves turning on:
Settings -> General -> Accessibility -> Larger Text
..and adding:
tabBarItem.largeContentSizeImage = UIImage(named: "myHud")
Alternatively, you can add a vector image as the main tool-bar image, with 'Preserve Vector Data' checked in the asset catalog.
I've tried all combinations of this, and a long press does not show the HUD. I also tested with the Files app on my iPad running iOS 11b4 with no luck. This is the app that was demoed at WWDC.
Is there some other accessibility setting I'm missing to enable this feature? Or is it not available in beta 4?
It isn't enough to turn on Larger Text. You also have to use Larger Text — i.e. slide the slider way to right.
Then it works — well, the HUD appears. But the icon is not being enlarged within the HUD, so I don't quite see the point:
(As you can see, I'm doing this in a test project where I'm experimenting with the vector PDF image feature.)
This feature implementation and an example with tab bar are perfectly explained with illustrations on this accessibility site but here are the outlines :
Under Xcode, import the image to be enlarged with a pdf extension and a x1 resolution in the xcassets catalog.
In the new Image Set, tick Preserve Vector Data and specify Single Scale as Scales attribute.
If a storyboard is used for this image, tick Adjusts Image Size in the Image View section, otherwise put the adjustsImageSizeForAccessibilityContentSizeCategory image property to true in code.
For your tab bar or tool bar used in the application, first repeat the previous 3 steps for each image included in the items to be enlarged in the middle of the screen and then link the accessibility image to its appropriate item.
This feature is available only for the accessibility text sizes.
WARNING : don't forget to check your layout with these new images larger sizes.
For your record, an explanation of the Large Content Viewer is provided in this detailed WWDC video summary if need be ⟹ the UILargeContentViewerItem protocol is an iOS 13 new feature that shows the same HUD that's shown for standard bar items.
You need to go :
Settings > General > Accessibility > Larger Text(set on) > Move slider more then half to the right
Don't forget to set
tabBarItem.largeContentSizeImage = someKindOfImage
And Long press will does the trick.

Centering PickerIOS in React Native

I have been trying to center a PickerIOS, but I am probably missing the underlying logic behind a Picker, because I just want its width to be full screen.
I can manage to do that with iPhone 4s / 5s, but when I run it on the iPhone 6, the Picker seems to be on the left, with some space on the right side.
I have been trying to use alignItem:'center' with a wrapper around the picker, but that just makes it disappear. I have also tried alignSelf, but still doesn't work.
I thought that Picker, by default, had its width to full screen or does it adapt according to the length of the elements?
Do I have to place it in a Flexbox in order to get it centered with a full screen width?
mask1: {
height:120,
overflow:'hidden',
justifyContent:'space-around',
marginTop:50
}
I find out that the style of PickerIOSItem cannot change, and only works fine in NavigatorIOS. I review the example of UIExplorer and there is no more style binding to the Item. Maybe it's a bug.

Underscan issue with AirPlay mirroring

I'm having some issues with AirPlay. The thing is, I'm developing with the ATV3, and my TV set supports 1080p. But when I start screen mirroring and receive the new instance of UIScreen, the bounds and the applicationFrame are both giving me a 720p resolution.
But it gets weird when I actually moved the subviews to a negative value, and the whole screen gets covered. So, technically my iPhone is streaming at 1080p, but the bounds returned by the UIScreen are underscanned.
I've tried modifying the overscanCompensation before getting the bounds or the applicationFrame (tried both with all 3 overscanCompensation values available) but I'm still getting the same result.
Here is a picture of what I'm getting (sorry, it's the worst picture in the planet, I know, but I was using my phone to stream the image to the ATV :) )
Red view is the 720p reported by bounds.
It gets even weirder when I actually try this out in my ATV2 (it is supposedly limited to 720p even if it supports 1080p) and the result is exactly the same.
Anyway, if someone knows the method to get the real screen display to avoid putting a settings view in my app, I'll really appreciate it.
Thanks in advance :)
When you mentioned that you tried all 3 overscanCompensation modes, I presume you mean the 3 documented modes:
typedef enum {
UIScreenOverscanCompensationScale,
UIScreenOverscanCompensationInsetBounds,
UIScreenOverscanCompensationInsetApplicationFrame,
} UIScreenOverscanCompensation;
However, there is a fourth mode, which is not there, but should fix your problems: just set your overscanCompensation to 3.
Also, take a look at this SO question.
The answer of Ivan solved the same issue for me! But I also had the borders when using AirPlay Mirroring. I got rid of the borders without setting the overscanCompensation property by changing a setting on my Apple TV: try setting 'Settings > Audio & Video > Adjust For AirPlay Overscan' to Off (default On).
The setting that works best for most TVs is:
externalScreen.overscanCompensation = UIScreenOverscanCompensationInsetBounds | UIScreenOverscanCompensationInsetApplicationFrame; // this is the same as setting it to 3
Just setting it to UIScreenOverscanCompensationInsetApplicationFrame can cause misalignment of the UIWindow contents.
3 is a bitmask of UIScreenOverscanCompensationInsetBounds(1) and UIScreenOverscanCompensationInsetApplicationFrame(2) for those wondering where that number comes from and why it works.

D3D10 (DirectX10) fullscreen performance issue

I have a bit of a problem setting up my DirectX10 (Win32/c++) application for fullscreen mode. The problem is that I want to have my app running in fullscreen right from the start. This can be done by taking the DXGISwapChain::SetFullScreenState function. This works, but i get a small notice in my Visualc++ 2008 debugger which states:
"DXGI Warning: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH."
What this means is that DirectX will not take full ownership of the graphicscard and flip the images from front to backbuffer but instead blit them which is much slower.
Now, i do have the DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH enabled and i did try to resize my buffers but i have absolutely no idea what would be the best way to go into fullscreen mode. I have looked on MSDN but there they mostly assume you will only go into Fullscreen by pressing Alt+Enter which lest DXGI do all the work. If someone please could post a bit of code which takes DirectX10 into fullscreen mode and takes full advantage of the "flipping" it would be greatly appriciated!
For anybody interested in the code used on resize:
ReleaseCOM(m_pD3DRenderTargetView);
ReleaseCOM(m_pD3DDepthStencilView);
ReleaseCOM(m_pD3DDepthStencilBuffer);
DXGI_MODE_DESC* mod = new DXGI_MODE_DESC;
mod->Format = DXGI_FORMAT_R8G8B8A8_UNORM;
mod->Height = m_ScreenHeight;
mod->Width = m_ScreenWidth;
mod->RefreshRate.Denominator = 0;
mod->RefreshRate.Numerator = 0;
mod->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
mod->Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
delete mod; mod = 0;
m_pSwapChain->ResizeTarget(mod);
HR(m_pSwapChain->ResizeBuffers(1, m_ScreenWidth, m_ScreenHeight, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH))
throw(Exception(GET_BUFFER_FAIL, AT));
//problem area
m_pSwapChain->SetFullscreenState(TRUE, NULL);
ID3D10Texture2D* pBackBuffer;
HR( m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer))
throw(Exception(GET_BUFFER_FAIL, AT)); //continues as usual
Is there any reason you delete your mode desc?
Have you also tried putting your mode desc through "FindClosestMatchingMode"?
Check out http://msdn.microsoft.com/en-us/library/cc627095(VS.85).aspx The "Full-Screen issues" section contains a lot of useful information.
There are some prerequisites for enabling flipping in DXGI (which is the most efficient fullscreen presentation mode):
1) You should go into fullscreen state specifying a mode that exists in the system (you could do that either by using mode from IDXGIOutput::GetDisplayModeList or finding it using IDXGIOutput::FindClosestMatchingMode). Your code just specifies screen resolution, so most likely mode is set correctly.
2) After SetFullscreenState, you should call ResizeBuffers with the right buffer size matching mode, this is where DXGI would setup flipping mode.
Typically, it should happen naturally as reaction to WM_SIZE message send by SetFullscreenState transition, so if your app doesn't call ResizeBuffers on WM_SIZE, it probably should.
You can call ResizeBuffers manually after SetFullscreenState and that should work as well.
And yeah, MSDN has a good article about DXGI practices, including fullscreen transition:
http://msdn.microsoft.com/en-us/library/cc627095(VS.85).aspx#Full_Screen_Issues

Resources