winrt: Resize window on Windows Phone using EGL

To avoid duplicating code in ANGLE, we can resize the framebuffer in QPA.
This potentially allows us to synchronize rendering to avoid displaying
a frame which is rendered for the new geometry but is displayed with the
old geometry.

Change-Id: I5f3a0634628d9ea4ca73349a02e646eb043bd757
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
This commit is contained in:
Andrew Knight 2014-11-14 11:51:49 +02:00 committed by Jani Heikkinen
parent 08afe17731
commit 47c2d76dba

View File

@ -473,6 +473,7 @@ QWinRTScreen::QWinRTScreen()
Q_D(QWinRTScreen);
d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR;
d->eglDisplay = EGL_NO_DISPLAY;
// Obtain the WinRT Application, view, and window
HRESULT hr;
@ -531,8 +532,10 @@ QWinRTScreen::QWinRTScreen()
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
Q_ASSERT_SUCCEEDED(hr);
#ifndef Q_OS_WINPHONE
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
Q_ASSERT_SUCCEEDED(hr);
#endif
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
@ -610,7 +613,14 @@ QWinRTScreen::QWinRTScreen()
d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat);
d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat);
d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL);
const QRect bounds = geometry();
EGLint windowAttributes[] = {
EGL_FIXED_SIZE_ANGLE, EGL_TRUE,
EGL_WIDTH, bounds.width(),
EGL_HEIGHT, bounds.height(),
EGL_NONE
};
d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), windowAttributes);
if (d->eglSurface == EGL_NO_SURFACE)
qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
}
@ -1051,26 +1061,33 @@ HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationPr
return S_OK;
}
HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *)
{
Q_D(QWinRTScreen);
Size size;
HRESULT hr = args->get_Size(&size);
RETURN_OK_IF_FAILED("Failed to get window size.");
Rect size;
HRESULT hr;
hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds");
QSizeF logicalSize = QSizeF(size.Width, size.Height);
#ifndef Q_OS_WINPHONE // This handler is called from orientation changed, in which case we should always update the size
if (d->logicalSize == logicalSize)
return S_OK;
#endif
// Regardless of state, all top-level windows are viewport-sized - this might change if
// a more advanced compositor is written.
d->logicalSize = logicalSize;
if (d->eglDisplay) {
const QRect newGeometry = geometry();
#ifdef Q_OS_WINPHONE // Resize the EGL window
const int width = newGeometry.width() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::LandscapeOrientation ? -1 : 1);
const int height = newGeometry.height() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::InvertedLandscapeOrientation ? -1 : 1);
eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_WIDTH, width);
eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_HEIGHT, height);
#endif
QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
}
return S_OK;
}
@ -1140,6 +1157,9 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
}
#ifdef Q_OS_WINPHONE // The size changed handler is ignored in favor of this callback
onSizeChanged(Q_NULLPTR, Q_NULLPTR);
#endif
return S_OK;
}