Merge lp:~gerboland/qtubuntu/surface-visible-hidden-side-channel into lp:qtubuntu

Proposed by kevin gunn
Status: Merged
Merged at revision: 219
Proposed branch: lp:~gerboland/qtubuntu/surface-visible-hidden-side-channel
Merge into: lp:qtubuntu
Diff against target: 135 lines (+54/-5)
3 files modified
src/platforms/ubuntu/ubuntucommon/integration.cc (+10/-1)
src/platforms/ubuntu/ubuntucommon/window.cc (+40/-4)
src/platforms/ubuntu/ubuntucommon/window.h (+4/-0)
To merge this branch: bzr merge lp:~gerboland/qtubuntu/surface-visible-hidden-side-channel
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Ubuntu Phablet Team Pending
Review via email: mp+215884@code.launchpad.net

Commit message

Lifecycle events emit expose events to safely stop & resume the renderer threads.

We don't use hide/show directly as hide causes Qt to stop the renderer, but then release the GL context and its resources. Expose events just stop & resume the renderer without altering the context.

Description of the change

The Qt5.2 blocking at eglSwapBuffers fix is to never block, but to stop clients rendering continually, we use a side-channel to notify clients that their surfaces are hidden and they can stop rendering, and when they can resume.

 * Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
Y
 * Did you build your software in a clean sbuild/pbuilder chroot or ppa?
Y
 * Did you build your software in a clean sbuild/pbuilder armhf chroot or ppa?
Y
 * Has a 5 minute exploratory testing run been executed on N4?
Y
 * If you changed the packaging (debian), did you subscribe a core-dev to this MP?
N/A
 * What components might get impacted by your changes?
Any app that renders
 * Have you requested review by the teams of these owning components?
No, this is very low level component shared with all Qt apps on touch, so if one is broken, all would be.

To post a comment you must log in.
Revision history for this message
Gerry Boland (gerboland) wrote :

To test, fetch this file and save on the device:
http://people.canonical.com/~gerboland/dateTime.qml
Run it with this command (with shell unlocked):

QSG_RENDER_TIMING=1 qmlscene dateTime.qml
--desktop_file_hint=/usr/share/applications/address-book-app.desktop

You should see the time printed on screen, and being printed on your
console once per second. You'll also see rendering statistics once per frame.

Now hit your power key. You should see that the render statistics stop,
yet you still get the time printed on your console. (note lifecycle
doesn't apply to manually started apps).

Hit the power key again, and unlock the greeter. Rendering should resume
immediately.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
221. By Gerry Boland

Using the hide/show events at all is dangerous, rely solely on expose

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/platforms/ubuntu/ubuntucommon/integration.cc'
--- src/platforms/ubuntu/ubuntucommon/integration.cc 2013-10-14 09:55:36 +0000
+++ src/platforms/ubuntu/ubuntucommon/integration.cc 2014-04-16 16:30:46 +0000
@@ -19,7 +19,7 @@
19#include "clipboard.h"19#include "clipboard.h"
20#include "input_adaptor_factory.h"20#include "input_adaptor_factory.h"
21#include "base/logging.h"21#include "base/logging.h"
22#include <QtCore/QCoreApplication>22#include <QGuiApplication>
23#include <qpa/qplatformnativeinterface.h>23#include <qpa/qplatformnativeinterface.h>
24#include <qpa/qplatforminputcontextfactory_p.h>24#include <qpa/qplatforminputcontextfactory_p.h>
25#include <qpa/qplatforminputcontext.h>25#include <qpa/qplatforminputcontext.h>
@@ -35,6 +35,10 @@
35 QUbuntuIntegration* integration = static_cast<QUbuntuIntegration*>(context);35 QUbuntuIntegration* integration = static_cast<QUbuntuIntegration*>(context);
36 integration->screen()->toggleSensors(true);36 integration->screen()->toggleSensors(true);
37 QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::ApplicationActivate));37 QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::ApplicationActivate));
38
39 Q_FOREACH(QWindow *window, QGuiApplication::allWindows()) {
40 QGuiApplication::postEvent(window, new QExposeEvent( window->geometry() ));
41 }
38}42}
3943
40static void aboutToStopCallback(UApplicationArchive *archive, void* context) {44static void aboutToStopCallback(UApplicationArchive *archive, void* context) {
@@ -43,6 +47,11 @@
43 QUbuntuIntegration* integration = static_cast<QUbuntuIntegration*>(context);47 QUbuntuIntegration* integration = static_cast<QUbuntuIntegration*>(context);
44 integration->screen()->toggleSensors(false);48 integration->screen()->toggleSensors(false);
45 integration->inputContext()->hideInputPanel();49 integration->inputContext()->hideInputPanel();
50
51 Q_FOREACH(QWindow *window, QGuiApplication::allWindows()) {
52 QGuiApplication::postEvent(window, new QExposeEvent( QRegion() ));
53 }
54
46 QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::ApplicationDeactivate));55 QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::ApplicationDeactivate));
47}56}
4857
4958
=== modified file 'src/platforms/ubuntu/ubuntucommon/window.cc'
--- src/platforms/ubuntu/ubuntucommon/window.cc 2013-12-11 04:32:09 +0000
+++ src/platforms/ubuntu/ubuntucommon/window.cc 2014-04-16 16:30:46 +0000
@@ -24,6 +24,7 @@
24#include "base/logging.h"24#include "base/logging.h"
25#include <qpa/qwindowsysteminterface.h>25#include <qpa/qwindowsysteminterface.h>
26#include <ubuntu/application/ui/window.h>26#include <ubuntu/application/ui/window.h>
27#include <QRegion>
2728
28static void eventCallback(void* context, const Event* event) {29static void eventCallback(void* context, const Event* event) {
29 DLOG("eventCallback (context=%p, event=%p)", context, event);30 DLOG("eventCallback (context=%p, event=%p)", context, event);
@@ -41,7 +42,9 @@
41 , systemSession_(systemSession)42 , systemSession_(systemSession)
42 , uainstance_(instance)43 , uainstance_(instance)
43 , screen_(screen)44 , screen_(screen)
44 , isShell_(isShell) {45 , isShell_(isShell)
46 , exposed_(false)
47{
45 if (!systemSession) {48 if (!systemSession) {
46 // Non-system sessions can't resize the window geometry.49 // Non-system sessions can't resize the window geometry.
47 geometry_ = screen->availableGeometry();50 geometry_ = screen->availableGeometry();
@@ -183,12 +186,45 @@
183void QUbuntuWindow::setVisible(bool visible) {186void QUbuntuWindow::setVisible(bool visible) {
184 DLOG("QUbuntuWindow::setVisible (this=%p, visible=%s)", this, visible ? "true" : "false");187 DLOG("QUbuntuWindow::setVisible (this=%p, visible=%s)", this, visible ? "true" : "false");
185 if (isShell_ == false)188 if (isShell_ == false)
186 screen_->toggleSensors(visible);189 screen_->toggleSensors(visible);
190
191 setExposed(visible);
187192
188 if (visible) {193 if (visible) {
189 ua_ui_window_show(window_);194 ua_ui_window_show(window_);
195 } else {
196 ua_ui_window_hide(window_);
197 }
198}
199
200bool QUbuntuWindow::isExposed() const {
201 return exposed_;
202}
203
204void QUbuntuWindow::setExposed(const bool exposed) {
205 DLOG("QUbuntuWindow::setExposed (this=%p, exposed=%s)", this, exposed ? "true" : "false");
206
207 if (exposed_ == exposed)
208 return;
209
210 exposed_ = exposed;
211 if (exposed_) {
212 QWindowSystemInterface::handleExposeEvent(window(), geometry());
213 } else {
190 QWindowSystemInterface::handleExposeEvent(window(), QRect());214 QWindowSystemInterface::handleExposeEvent(window(), QRect());
191 } else {215 }
192 ua_ui_window_hide(window_);216}
217
218void QUbuntuWindow::windowEvent(QEvent *event) {
219 if (event->type() == QEvent::Expose) {
220 QRegion region = static_cast<QExposeEvent *>(event)->region();
221
222 if (region.isEmpty()) {
223 // hiding window causes Qt to release the GL context and its resources, which is a bit severe
224 // Instead can use the exposure system to stop the rendering loop, but hold onto the resources
225 setExposed(false);
226 } else {
227 setExposed(true);
228 }
193 }229 }
194}230}
195231
=== modified file 'src/platforms/ubuntu/ubuntucommon/window.h'
--- src/platforms/ubuntu/ubuntucommon/window.h 2013-08-02 21:32:00 +0000
+++ src/platforms/ubuntu/ubuntucommon/window.h 2014-04-16 16:30:46 +0000
@@ -34,12 +34,15 @@
34 void setGeometry(const QRect&);34 void setGeometry(const QRect&);
35 void setWindowState(Qt::WindowState state);35 void setWindowState(Qt::WindowState state);
36 void setVisible(bool visible);36 void setVisible(bool visible);
37 bool isExposed() const;
38 void windowEvent(QEvent *event);
3739
38 QUbuntuInput* input_;40 QUbuntuInput* input_;
3941
40 private:42 private:
41 void createWindow();43 void createWindow();
42 void moveResize(const QRect& rect);44 void moveResize(const QRect& rect);
45 void setExposed(const bool exposed);
4346
44 UAUiWindow* window_;47 UAUiWindow* window_;
45 Qt::WindowState state_;48 Qt::WindowState state_;
@@ -49,6 +52,7 @@
49 UAUiWindowProperties* wprops_;52 UAUiWindowProperties* wprops_;
50 QUbuntuScreen* screen_;53 QUbuntuScreen* screen_;
51 bool isShell_;54 bool isShell_;
55 bool exposed_;
52};56};
5357
54#endif // QUBUNTUWINDOW_H58#endif // QUBUNTUWINDOW_H

Subscribers

People subscribed via source and target branches