Преглед изворни кода

Delay showing render windows until the first framebuffer swap in order to avoid the black screen

Marko Pintera пре 10 година
родитељ
комит
2ebccea148

+ 2 - 1
BansheeCore/Include/BsRenderWindow.h

@@ -27,7 +27,7 @@ namespace BansheeEngine
 		: vsync(false), vsyncInterval(1), fullscreen(false), hidden(false), depthBuffer(true)
 			, multisampleCount(0), multisampleHint(""), gamma(false), left(-1), top(-1)
 			, title(""), border(WindowBorder::Normal), outerDimensions(false), enableDoubleClick(true)
-			, toolWindow(false), modal(false)
+			, toolWindow(false), modal(false), hideUntilSwap(false)
 		{ }
 
 		VideoMode videoMode; /**< A set of frame buffer options. */
@@ -47,6 +47,7 @@ namespace BansheeEngine
 		bool enableDoubleClick; /**< Does window accept double-clicks. */
 		bool toolWindow; /**< Tool windows have a different style than normal windows and can be created with no border or title bar. */
 		bool modal; /**< When a modal window is open all other windows will be locked until modal window is closed. */
+		bool hideUntilSwap; /** < Window will be created as hidden and only be shown when the first framebuffer swap happens. */
 
 		NameValuePairList platformSpecific; /**< Platform-specific creation options. */
 	};

+ 1 - 0
BansheeD3D11RenderSystem/Include/BsD3D11RenderWindow.h

@@ -171,6 +171,7 @@ namespace BansheeEngine
 		bool mIsExternal;
 		bool mSizing;
 		bool mIsChild;
+		bool mShowOnSwap;
 
 		DXGI_SAMPLE_DESC mMultisampleType;
 		UINT32 mRefreshRateNumerator;

+ 14 - 2
BansheeD3D11RenderSystem/Source/BsD3D11RenderWindow.cpp

@@ -23,7 +23,7 @@ namespace BansheeEngine
 	D3D11RenderWindowCore::D3D11RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, D3D11Device& device, IDXGIFactory* DXGIFactory)
 		: RenderWindowCore(desc, windowId), mProperties(desc), mSyncedProperties(desc), mDevice(device), mDXGIFactory(DXGIFactory), mIsExternal(false), 
 		mSizing(false), mRenderTargetView(nullptr), mBackBuffer(nullptr), mSwapChain(nullptr), mDepthStencilView(nullptr), mIsChild(false), 
-		 mRefreshRateNumerator(0), mRefreshRateDenominator(0), mHWnd(0)
+		mRefreshRateNumerator(0), mRefreshRateDenominator(0), mHWnd(0), mShowOnSwap(false)
 	{ }
 
 	D3D11RenderWindowCore::~D3D11RenderWindowCore()
@@ -109,7 +109,14 @@ namespace BansheeEngine
 
 		if (!externalHandle)
 		{
-			DWORD dwStyle = (props.isHidden() ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
+			DWORD dwStyle = WS_CLIPCHILDREN;
+
+			mShowOnSwap = mDesc.hideUntilSwap;
+			props.mHidden = mDesc.hideUntilSwap;
+
+			if (!mShowOnSwap)
+				dwStyle |= WS_VISIBLE;
+
 			DWORD dwStyleEx = 0;
 			RECT rc;
 			MONITORINFO monitorInfo;
@@ -281,6 +288,9 @@ namespace BansheeEngine
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
+		if (mShowOnSwap)
+			setHidden(false);
+
 		if(mDevice.getD3D11Device() != nullptr)
 		{
 			HRESULT hr = mSwapChain->Present(getProperties().getVSync() ? getProperties().getVSyncInterval() : 0, 0);
@@ -371,6 +381,8 @@ namespace BansheeEngine
 		D3D11RenderWindowProperties& props = mProperties;
 
 		props.mHidden = hidden;
+		mShowOnSwap = false;
+
 		if (!mIsExternal)
 		{
 			if (hidden)

+ 1 - 0
BansheeD3D9RenderSystem/Include/BsD3D9RenderWindow.h

@@ -187,6 +187,7 @@ namespace BansheeEngine
 		bool mIsDepthBuffered;
 		bool mIsChild;
 		HWND mHWnd;
+		bool mShowOnSwap;
 
 		D3D9RenderWindowProperties mProperties;
 		D3D9RenderWindowProperties mSyncedProperties;

+ 14 - 3
BansheeD3D9RenderSystem/Source/BsD3D9RenderWindow.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 
 	D3D9RenderWindowCore::D3D9RenderWindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, HINSTANCE instance)
 		: RenderWindowCore(desc, windowId), mInstance(instance), mProperties(desc), mSyncedProperties(desc), mIsDepthBuffered(true), mIsChild(false), mHWnd(0),
-		mStyle(0), mWindowedStyle(0), mWindowedStyleEx(0), mDevice(nullptr), mIsExternal(false), mDisplayFrequency(0), mDeviceValid(false)
+		mStyle(0), mWindowedStyle(0), mWindowedStyleEx(0), mDevice(nullptr), mIsExternal(false), mDisplayFrequency(0), mDeviceValid(false), mShowOnSwap(false)
 	{ }
 
 	D3D9RenderWindowCore::~D3D9RenderWindowCore()
@@ -46,6 +46,7 @@ namespace BansheeEngine
 		RenderWindowCore::initialize();
 
 		HINSTANCE hInst = mInstance;
+		D3D9RenderWindowProperties& props = mProperties;
 
 		mMultisampleType = D3DMULTISAMPLE_NONE;
 		mMultisampleQuality = 0;
@@ -65,7 +66,13 @@ namespace BansheeEngine
 
 		mIsChild = parentHWnd != 0;
 
-		mWindowedStyle = WS_VISIBLE | WS_CLIPCHILDREN;
+		mWindowedStyle = WS_CLIPCHILDREN;
+		mShowOnSwap = mDesc.hideUntilSwap;
+		props.mHidden = mDesc.hideUntilSwap;
+
+		if (!mShowOnSwap)
+			mWindowedStyle |= WS_VISIBLE;
+
 		mWindowedStyleEx = 0;
 
 		if (!mDesc.fullscreen || mIsChild)
@@ -90,7 +97,6 @@ namespace BansheeEngine
 			}
 		}
 
-		D3D9RenderWindowProperties& props = mProperties;
 		if (!externalHandle)
 		{
 			MONITORINFO monitorInfo;
@@ -363,6 +369,8 @@ namespace BansheeEngine
 		D3D9RenderWindowProperties& props = mProperties;
 
 		props.mHidden = hidden;
+		mShowOnSwap = false;
+
 		if (!mIsExternal)
 		{
 			if (hidden)
@@ -497,6 +505,9 @@ namespace BansheeEngine
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
+		if (mShowOnSwap)
+			setHidden(false);
+
 		if (mDeviceValid)
 			mDevice->present(this);		
 	}

+ 1 - 0
BansheeEditor/Source/BsEditorApplication.cpp

@@ -57,6 +57,7 @@ namespace BansheeEngine
 		renderWindowDesc.title = "BansheeEditor";
 		renderWindowDesc.fullscreen = false;
 		renderWindowDesc.border = WindowBorder::None;
+		renderWindowDesc.hideUntilSwap = true;
 
 		return renderWindowDesc;
 	}

+ 1 - 0
BansheeEditor/Source/BsEditorWindowBase.cpp

@@ -21,6 +21,7 @@ namespace BansheeEngine
 		renderWindowDesc.border = WindowBorder::None;
 		renderWindowDesc.toolWindow = true;
 		renderWindowDesc.modal = isModal;
+		renderWindowDesc.hideUntilSwap = true;
 
 		mRenderWindow = RenderWindow::create(renderWindowDesc, gCoreApplication().getPrimaryWindow());
 

+ 1 - 0
BansheeGLRenderSystem/Include/BsWin32Window.h

@@ -152,6 +152,7 @@ namespace BansheeEngine
 		char* mDeviceName;
 		bool mIsExternalGLControl;
 		int mDisplayFrequency;
+		bool mShowOnSwap;
 		HWND mHWnd;
 		SPtr<Win32Context> mContext;
 		Win32RenderWindowProperties mProperties;

+ 14 - 2
BansheeGLRenderSystem/Source/BsWin32Window.cpp

@@ -26,7 +26,8 @@ namespace BansheeEngine
 
 	Win32WindowCore::Win32WindowCore(const RENDER_WINDOW_DESC& desc, UINT32 windowId, Win32GLSupport& glsupport)
 		: RenderWindowCore(desc, windowId), mProperties(desc), mSyncedProperties(desc), mGLSupport(glsupport), mContext(0), 
-		mWindowedStyle(0), mWindowedStyleEx(0), mIsExternal(false), mIsExternalGLControl(false), mDisplayFrequency(0), mDeviceName(nullptr), mHWnd(0)
+		mWindowedStyle(0), mWindowedStyleEx(0), mIsExternal(false), mIsExternalGLControl(false), mDisplayFrequency(0), 
+		mDeviceName(nullptr), mHWnd(0), mShowOnSwap(false)
 	{ }
 
 	Win32WindowCore::~Win32WindowCore()
@@ -123,7 +124,13 @@ namespace BansheeEngine
 				props.mColorDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
 		}
 
-		mWindowedStyle = WS_VISIBLE | WS_CLIPCHILDREN;
+		mWindowedStyle = WS_CLIPCHILDREN;
+		mShowOnSwap = mDesc.hideUntilSwap;
+		props.mHidden = mDesc.hideUntilSwap;
+
+		if (!mShowOnSwap)
+			mWindowedStyle |= WS_VISIBLE;
+
 		mWindowedStyleEx = 0;
 
 		if (!props.mIsFullScreen)
@@ -557,6 +564,9 @@ namespace BansheeEngine
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
+		if (mShowOnSwap)
+			setHidden(false);
+
 		if (!mIsExternalGLControl) {
 			SwapBuffers(mHDC);
 		}
@@ -691,6 +701,8 @@ namespace BansheeEngine
 
 		Win32RenderWindowProperties& props = mProperties;
 		props.mHidden = hidden;
+		mShowOnSwap = false;
+
 		if (!mIsExternal)
 		{
 			if (hidden)