Merge lp:~aacid/qtmir/create_observer_sooner into lp:qtmir

Proposed by Albert Astals Cid on 2014-12-12
Status: Merged
Approved by: Michał Sawicz on 2015-01-14
Approved revision: 300
Merged at revision: 305
Proposed branch: lp:~aacid/qtmir/create_observer_sooner
Merge into: lp:qtmir
Diff against target: 337 lines (+122/-48)
10 files modified
src/modules/Unity/Application/mirsurfaceitem.cpp (+9/-16)
src/modules/Unity/Application/mirsurfaceitem.h (+4/-26)
src/modules/Unity/Application/mirsurfacemanager.cpp (+3/-2)
src/modules/Unity/Application/mirsurfacemanager.h (+1/-1)
src/platforms/mirserver/CMakeLists.txt (+1/-0)
src/platforms/mirserver/sessionlistener.cpp (+7/-1)
src/platforms/mirserver/sessionlistener.h (+3/-1)
src/platforms/mirserver/surfaceobserver.cpp (+39/-0)
src/platforms/mirserver/surfaceobserver.h (+54/-0)
tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp (+1/-1)
To merge this branch: bzr merge lp:~aacid/qtmir/create_observer_sooner
Reviewer Review Type Date Requested Status
Michał Sawicz Abstain on 2015-01-14
Gerry Boland 2014-12-12 Approve on 2015-01-07
PS Jenkins bot continuous-integration Approve on 2014-12-16
Review via email: mp+244622@code.launchpad.net

Commit Message

Move the creation of the surface observer to SessionListener::surface_created

Otherwise we may lose some frame_posted calls if we delay it (it was run in a different thread), meaning that if the app doesn't paint anything else qtmir will think that nothing was yet drawn showing the splash screen forever.

Description of the Change

* Are there any related MPs required for this MP to build/function as expected? No

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

To post a comment you must log in.
Gerry Boland (gerboland) wrote :

You approach should work nicely, but I'd prefer SurfaceObserver to emit framesPosted signals and MirSurfaceItem to connect to them, instead of using QMetaObject::invokeMethod (to get compile time checks, have Qt decide if queued connection needed or not, and is slightly faster).

To be absolutely correct, we shouldn't be ignoring the count parameter passed to frame_posted, but that can be a later fix.

review: Needs Fixing
Gerry Boland (gerboland) wrote :

+ SurfaceObserver *so = dynamic_cast<SurfaceObserver *>(observer.get());
makes me think you'd be better just having MirSurfaceManager::onSessionCreatedSurface explicitly pass the QObject derived SurfaceObserver, instead of just referring to its interface and having to cast. i.e.

 void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession,
- const std::shared_ptr<mir::scene::Surface> &surface)
+ const std::shared_ptr<mir::scene::Surface> &surface,
+ const std::shared_ptr<SurfaceObserver> &observer)

Am also doubting if it needs to be a shared_ptr at all. Since SurfaceObserver is a QObject, and we use connect() to listen for its signals, if it is deleted everything should still be ok. I think raw pointer would do just fine. So

 void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession,
- const std::shared_ptr<mir::scene::Surface> &surface)
+ const std::shared_ptr<mir::scene::Surface> &surface,
+ const SurfaceObserver *observer)

review: Needs Fixing
Gerry Boland (gerboland) wrote :

Code wise, looks great. Need to test on all our devices

review: Approve (code)
Gerry Boland (gerboland) wrote :

Ok tested on N7, kryllin and my laptop. LGTM

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Y
 * Did CI run pass? If not, please explain why.
Y

review: Approve
Michał Sawicz (saviq) wrote :

Text conflict in src/modules/Unity/Application/mirsurfaceitem.h
1 conflicts encountered.

review: Needs Fixing
300. By Albert Astals Cid on 2015-01-14

Merge

Albert Astals Cid (aacid) wrote :

Merged

Michał Sawicz (saviq) :
review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
2--- src/modules/Unity/Application/mirsurfaceitem.cpp 2014-11-05 14:57:19 +0000
3+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2015-01-14 08:24:48 +0000
4@@ -26,6 +26,9 @@
5 #include "logging.h"
6 #include "ubuntukeyboardinfo.h"
7
8+// mirserver
9+#include "surfaceobserver.h"
10+
11 // common
12 #include <debughelpers.h>
13
14@@ -231,21 +234,9 @@
15 }
16 };
17
18-MirSurfaceObserver::MirSurfaceObserver()
19- : m_listener(nullptr) {
20-}
21-
22-void MirSurfaceObserver::setListener(QObject *listener) {
23- m_listener = listener;
24-}
25-
26-void MirSurfaceObserver::frame_posted(int frames_available) {
27- Q_UNUSED(frames_available);
28- QMetaObject::invokeMethod(m_listener, "surfaceDamaged");
29-}
30-
31 MirSurfaceItem::MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface,
32 SessionInterface* session,
33+ std::shared_ptr<SurfaceObserver> observer,
34 QQuickItem *parent)
35 : QQuickItem(parent)
36 , m_surface(surface)
37@@ -258,9 +249,11 @@
38 {
39 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::MirSurfaceItem";
40
41- m_surfaceObserver = std::make_shared<MirSurfaceObserver>();
42- m_surfaceObserver->setListener(this);
43- m_surface->add_observer(m_surfaceObserver);
44+ m_surfaceObserver = observer;
45+ if (observer) {
46+ connect(observer.get(), &SurfaceObserver::framesPosted, this, &MirSurfaceItem::surfaceDamaged);
47+ observer->setListener(this);
48+ }
49
50 setSmooth(true);
51 setFlag(QQuickItem::ItemHasContents, true); //so scene graph will render this item
52
53=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
54--- src/modules/Unity/Application/mirsurfaceitem.h 2015-01-06 17:28:52 +0000
55+++ src/modules/Unity/Application/mirsurfaceitem.h 2015-01-14 08:24:48 +0000
56@@ -29,11 +29,12 @@
57
58 // mir
59 #include <mir/scene/surface.h>
60-#include <mir/scene/surface_observer.h>
61 #include <mir_toolkit/common.h>
62
63 #include "session_interface.h"
64
65+class SurfaceObserver;
66+
67 namespace qtmir {
68
69 class MirSurfaceManager;
70@@ -41,30 +42,6 @@
71 class QMirSurfaceTextureProvider;
72 class Application;
73
74-class MirSurfaceObserver : public mir::scene::SurfaceObserver {
75-public:
76- MirSurfaceObserver();
77-
78- void setListener(QObject *listener);
79-
80- void attrib_changed(MirSurfaceAttrib, int) override {}
81- void resized_to(mir::geometry::Size const&) override {}
82- void moved_to(mir::geometry::Point const&) override {}
83- void hidden_set_to(bool) override {}
84-
85- // Get new frame notifications from Mir, called from a Mir thread.
86- void frame_posted(int frames_available) override;
87-
88- void alpha_set_to(float) override {}
89- void transformation_set_to(glm::mat4 const&) override {}
90- void reception_mode_set_to(mir::input::InputReceptionMode) override {}
91- void cursor_image_set_to(mir::graphics::CursorImage const&) override {}
92- void orientation_set_to(MirOrientation) override {}
93- void client_surface_close_requested() override {}
94-private:
95- QObject *m_listener;
96-};
97-
98 class MirSurfaceItem : public QQuickItem
99 {
100 Q_OBJECT
101@@ -80,6 +57,7 @@
102 public:
103 explicit MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface,
104 SessionInterface* session,
105+ std::shared_ptr<SurfaceObserver> observer,
106 QQuickItem *parent = 0);
107 ~MirSurfaceItem();
108
109@@ -199,7 +177,7 @@
110
111 QMirSurfaceTextureProvider *m_textureProvider;
112
113- std::shared_ptr<MirSurfaceObserver> m_surfaceObserver;
114+ std::shared_ptr<SurfaceObserver> m_surfaceObserver;
115
116 QTimer m_frameDropperTimer;
117
118
119=== modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
120--- src/modules/Unity/Application/mirsurfacemanager.cpp 2014-12-01 11:05:01 +0000
121+++ src/modules/Unity/Application/mirsurfacemanager.cpp 2015-01-14 08:24:48 +0000
122@@ -100,13 +100,14 @@
123 }
124
125 void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession,
126- const std::shared_ptr<mir::scene::Surface> &surface)
127+ const std::shared_ptr<mir::scene::Surface> &surface,
128+ const std::shared_ptr<SurfaceObserver> &observer)
129 {
130 qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - mirSession=" << mirSession
131 << "surface=" << surface.get() << "surface.name=" << surface->name().c_str();
132
133 SessionInterface* session = m_sessionManager->findSession(mirSession);
134- auto qmlSurface = new MirSurfaceItem(surface, session);
135+ auto qmlSurface = new MirSurfaceItem(surface, session, observer);
136 {
137 QMutexLocker lock(&m_mutex);
138 m_mirSurfaceToItemHash.insert(surface.get(), qmlSurface);
139
140=== modified file 'src/modules/Unity/Application/mirsurfacemanager.h'
141--- src/modules/Unity/Application/mirsurfacemanager.h 2014-12-01 11:05:01 +0000
142+++ src/modules/Unity/Application/mirsurfacemanager.h 2015-01-14 08:24:48 +0000
143@@ -68,7 +68,7 @@
144 // void fullscreenSurfaceChanged();
145
146 public Q_SLOTS:
147- void onSessionCreatedSurface(const mir::scene::Session *, const std::shared_ptr<mir::scene::Surface> &);
148+ void onSessionCreatedSurface(const mir::scene::Session *, const std::shared_ptr<mir::scene::Surface> &, std::shared_ptr<SurfaceObserver> const&);
149 void onSessionDestroyingSurface(const mir::scene::Session *, const std::shared_ptr<mir::scene::Surface> &);
150
151 void onSurfaceAttributeChanged(const mir::scene::Surface *, MirSurfaceAttrib, int);
152
153=== modified file 'src/platforms/mirserver/CMakeLists.txt'
154--- src/platforms/mirserver/CMakeLists.txt 2014-12-11 15:27:02 +0000
155+++ src/platforms/mirserver/CMakeLists.txt 2015-01-14 08:24:48 +0000
156@@ -45,6 +45,7 @@
157 sessionauthorizer.cpp
158 sessionlistener.cpp
159 surfaceconfigurator.cpp
160+ surfaceobserver.cpp
161 promptsessionlistener.cpp
162 mirplacementstrategy.cpp
163 mirserver.cpp
164
165=== modified file 'src/platforms/mirserver/sessionlistener.cpp'
166--- src/platforms/mirserver/sessionlistener.cpp 2014-09-26 17:38:05 +0000
167+++ src/platforms/mirserver/sessionlistener.cpp 2015-01-14 08:24:48 +0000
168@@ -15,9 +15,12 @@
169 */
170
171 #include "sessionlistener.h"
172+#include "surfaceobserver.h"
173 #include "logging.h"
174 #include "tracepoints.h" // generated from tracepoints.tp
175
176+#include <mir/scene/surface.h>
177+
178 namespace ms = mir::scene;
179
180 Q_DECLARE_METATYPE(std::shared_ptr<ms::Session>)
181@@ -30,6 +33,7 @@
182 // need to register type to send over threads with signal/slot
183 qRegisterMetaType<std::shared_ptr<ms::Session>>("std::shared_ptr<mir::scene::Session>");
184 qRegisterMetaType<std::shared_ptr<ms::Surface>>("std::shared_ptr<mir::scene::Surface>");
185+ qRegisterMetaType<std::shared_ptr<SurfaceObserver>>("std::shared_ptr<SurfaceObserver>");
186 }
187
188 SessionListener::~SessionListener()
189@@ -68,7 +72,9 @@
190 tracepoint(qtmirserver, surfaceCreated);
191 qCDebug(QTMIR_MIR_MESSAGES) << "SessionListener::surface_created - this=" << this << "session=" << &session
192 << "surface=" << surface.get();
193- Q_EMIT sessionCreatedSurface(&session, surface);
194+ std::shared_ptr<SurfaceObserver> surfaceObserver = std::make_shared<SurfaceObserver>();
195+ surface->add_observer(surfaceObserver);
196+ Q_EMIT sessionCreatedSurface(&session, surface, surfaceObserver);
197 }
198
199 void SessionListener::destroying_surface(ms::Session& session, std::shared_ptr<ms::Surface> const& surface)
200
201=== modified file 'src/platforms/mirserver/sessionlistener.h'
202--- src/platforms/mirserver/sessionlistener.h 2014-04-17 22:25:39 +0000
203+++ src/platforms/mirserver/sessionlistener.h 2015-01-14 08:24:48 +0000
204@@ -22,6 +22,8 @@
205 #include "mir/scene/session_listener.h"
206 #include "mir/scene/session.h"
207
208+class SurfaceObserver;
209+
210 class SessionListener : public QObject, public mir::scene::SessionListener
211 {
212 Q_OBJECT
213@@ -43,7 +45,7 @@
214 void sessionFocused(std::shared_ptr<mir::scene::Session> const& session);
215 void sessionUnfocused();
216
217- void sessionCreatedSurface(mir::scene::Session const*, std::shared_ptr<mir::scene::Surface> const&);
218+ void sessionCreatedSurface(mir::scene::Session const*, std::shared_ptr<mir::scene::Surface> const&, std::shared_ptr<SurfaceObserver> const&);
219 void sessionDestroyingSurface(mir::scene::Session const*, std::shared_ptr<mir::scene::Surface> const&);
220 };
221
222
223=== added file 'src/platforms/mirserver/surfaceobserver.cpp'
224--- src/platforms/mirserver/surfaceobserver.cpp 1970-01-01 00:00:00 +0000
225+++ src/platforms/mirserver/surfaceobserver.cpp 2015-01-14 08:24:48 +0000
226@@ -0,0 +1,39 @@
227+/*
228+ * Copyright (C) 2014 Canonical, Ltd.
229+ *
230+ * This program is free software: you can redistribute it and/or modify it under
231+ * the terms of the GNU Lesser General Public License version 3, as published by
232+ * the Free Software Foundation.
233+ *
234+ * This program is distributed in the hope that it will be useful, but WITHOUT
235+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
236+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
237+ * Lesser General Public License for more details.
238+ *
239+ * You should have received a copy of the GNU Lesser General Public License
240+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
241+ */
242+
243+#include "surfaceobserver.h"
244+
245+#include <QMetaObject>
246+
247+SurfaceObserver::SurfaceObserver()
248+ : m_listener(nullptr)
249+ , m_framesPosted(false)
250+{
251+}
252+
253+void SurfaceObserver::setListener(QObject *listener) {
254+ m_listener = listener;
255+ if (m_framesPosted) {
256+ Q_EMIT framesPosted();
257+ }
258+}
259+
260+void SurfaceObserver::frame_posted(int /*frames_available*/) {
261+ m_framesPosted = true;
262+ if (m_listener) {
263+ Q_EMIT framesPosted();
264+ }
265+}
266
267=== added file 'src/platforms/mirserver/surfaceobserver.h'
268--- src/platforms/mirserver/surfaceobserver.h 1970-01-01 00:00:00 +0000
269+++ src/platforms/mirserver/surfaceobserver.h 2015-01-14 08:24:48 +0000
270@@ -0,0 +1,54 @@
271+/*
272+ * Copyright (C) 2014 Canonical, Ltd.
273+ *
274+ * This program is free software: you can redistribute it and/or modify it under
275+ * the terms of the GNU Lesser General Public License version 3, as published by
276+ * the Free Software Foundation.
277+ *
278+ * This program is distributed in the hope that it will be useful, but WITHOUT
279+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
280+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
281+ * Lesser General Public License for more details.
282+ *
283+ * You should have received a copy of the GNU Lesser General Public License
284+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
285+ */
286+
287+#ifndef SESSIONOBSERVER_H
288+#define SESSIONOBSERVER_H
289+
290+#include <QObject>
291+#include <mir/scene/surface_observer.h>
292+
293+class SurfaceObserver : public QObject, public mir::scene::SurfaceObserver {
294+ Q_OBJECT
295+
296+public:
297+ SurfaceObserver();
298+
299+ void setListener(QObject *listener);
300+
301+ void attrib_changed(MirSurfaceAttrib, int) override {}
302+ void resized_to(mir::geometry::Size const&) override {}
303+ void moved_to(mir::geometry::Point const&) override {}
304+ void hidden_set_to(bool) override {}
305+
306+ // Get new frame notifications from Mir, called from a Mir thread.
307+ void frame_posted(int frames_available) override;
308+
309+ void alpha_set_to(float) override {}
310+ void transformation_set_to(glm::mat4 const&) override {}
311+ void reception_mode_set_to(mir::input::InputReceptionMode) override {}
312+ void cursor_image_set_to(mir::graphics::CursorImage const&) override {}
313+ void orientation_set_to(MirOrientation) override {}
314+ void client_surface_close_requested() override {}
315+
316+Q_SIGNALS:
317+ void framesPosted();
318+
319+private:
320+ QObject *m_listener;
321+ bool m_framesPosted;
322+};
323+
324+#endif
325
326=== modified file 'tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp'
327--- tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp 2014-09-11 20:21:47 +0000
328+++ tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp 2015-01-14 08:24:48 +0000
329@@ -86,7 +86,7 @@
330 }));
331
332
333- MirSurfaceItem *surfaceItem = new MirSurfaceItem(mockSurface, mockSession);
334+ MirSurfaceItem *surfaceItem = new MirSurfaceItem(mockSurface, mockSession, nullptr);
335
336 ulong timestamp = 1234;
337 QList<QTouchEvent::TouchPoint> touchPoints;

Subscribers

People subscribed via source and target branches