Mir

Merge lp:~vanvugt/mir/double into lp:mir

Proposed by Daniel van Vugt
Status: Superseded
Proposed branch: lp:~vanvugt/mir/double
Merge into: lp:mir
Prerequisite: lp:~vanvugt/mir/unrestrict-bufferstream
Diff against target: 458 lines (+133/-72)
5 files modified
src/server/compositor/buffer_queue.cpp (+57/-14)
src/server/compositor/buffer_queue.h (+3/-0)
tests/integration-tests/compositor/test_buffer_stream.cpp (+57/-47)
tests/integration-tests/test_surface_first_frame_sync.cpp (+1/-1)
tests/unit-tests/compositor/test_buffer_queue.cpp (+15/-10)
To merge this branch: bzr merge lp:~vanvugt/mir/double
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Daniel van Vugt Needs Fixing
Mir development team Pending
Review via email: mp+221431@code.launchpad.net

Commit message

Scale BufferQueue length dynamically according to demand, up to a maximum
of nbuffers. Under normal synchronous rendering conditions clients will
now typically only get two unique buffers. So expect visible input lag to be
at least halved. And of course resource usage will be 33% less.

Description of the change

Notes:
  * Bug 1308843 is tricking the new algorithm into using 3 buffers when two would be safe. That will be solved separately, soon.
  * I would like to continue improving this, but may run out of time soon. So am proposing it slightly early.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

[ FAILED ] BufferQueueTest.slow_client_framerate_matches_compositor

Needs work. But I'm undecided as to whether BufferQueue should be fixed or the test case itself. Loosening the test case such that it can pass without re-introducing either of the bugs it is designed to protected against seems possible. But undesirable.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :
lp:~vanvugt/mir/double updated
1666. By Daniel van Vugt

Merge latest development-branch and fix conflicts (I think)

1667. By Daniel van Vugt

Start fixing failing/hanging tests since the merge

1668. By Daniel van Vugt

Disable hanging integration test

1669. By Daniel van Vugt

Remove FIXME for bugs now fixed.

1670. By Daniel van Vugt

Add debug output

1671. By Daniel van Vugt

More comments

1672. By Daniel van Vugt

Fix test case: framedropping_clients_get_max_2_buffers

1673. By Daniel van Vugt

Fix test case: compositor_acquires_resized_frames

1674. By Daniel van Vugt

Fix hanging test case: uncomposited_client_swaps_when_policy_triggered

1675. By Daniel van Vugt

Merge latest development-branch

1676. By Daniel van Vugt

Shrink the diff

1677. By Daniel van Vugt

Merge latest development-branch

1678. By Daniel van Vugt

Merge latest development-branch

1679. By Daniel van Vugt

Reenable debug output

1680. By Daniel van Vugt

Replace magic number 300 with a constant. I actually think this is less
readable defining constants so far away from the single location where
they're used. But it will generate less argument this way.

1681. By Daniel van Vugt

Tentatively drop bypass detection, and all associated logic. It seems bypass
doesn't need triple buffers any more.

1682. By Daniel van Vugt

Merge lp:~vanvugt/mir/unrestrict-bypass

1683. By Daniel van Vugt

Merge latest development branch via lp:~vanvugt/mir/unrestrict-bypass
to get fixes for spurious test failures.

1684. By Daniel van Vugt

Merge latest development-branch and fix a conflict.

1685. By Daniel van Vugt

Ultra-simplified the min_buffers decision.

1686. By Daniel van Vugt

Remove the excess/shrinkage delay algorithm. No delay is required at all any
more.

1687. By Daniel van Vugt

Remove debug output

1688. By Daniel van Vugt

Fix failing test: BufferQueueTest.clients_can_have_multiple_pending_completions

1689. By Daniel van Vugt

Fix failing test: BufferQueueTest.throws_on_out_of_order_client_release

1690. By Daniel van Vugt

Fix test case: BufferQueueTest.compositor_acquires_frames_in_order

1691. By Daniel van Vugt

Fix test case: BufferQueueTest.buffers_are_not_lost

1692. By Daniel van Vugt

Fix test case: BufferQueueTest.async_client_cycles_through_all_buffers

1693. By Daniel van Vugt

Fixed test case:
BufferQueueTest.partially_composited_client_swaps_when_policy_triggered

1694. By Daniel van Vugt

Merge latest development-branch

1695. By Daniel van Vugt

Merge latest development-branch

1696. By Daniel van Vugt

Merge latest development-branch

1697. By Daniel van Vugt

Re-enable the remaining failing test

1698. By Daniel van Vugt

Fix failing test: BufferStreamTest.blocked_client_is_released_on_timeout

1699. By Daniel van Vugt

Shrink the diff

1700. By Daniel van Vugt

Shrink the diff

1701. By Daniel van Vugt

Restore test case BufferQueueTest.framedropping_clients_get_all_buffers
properly. Also shrink the diff.

1702. By Daniel van Vugt

Shrink the diff

1703. By Daniel van Vugt

Clean up comments

1704. By Daniel van Vugt

Rename nbuffers to max_buffers to avoid confusion.

1705. By Daniel van Vugt

Add new test: BufferQueueTest.queue_size_scales_on_demand

1706. By Daniel van Vugt

Merge latest development-branch

1707. By Daniel van Vugt

Shrink the buffers vector from any location, not just the back.

1708. By Daniel van Vugt

Shrink the buffer queue immediately when framedropping is toggled. This
provides much better determinism for tests.

1709. By Daniel van Vugt

BufferQueueTest.slow_client_framerate_matches_compositor: Loosen thresholds
so it's less likely to fail spuriously under the strain of valgrind-on-armhf.

1710. By Daniel van Vugt

Merge latest development-branch

1711. By Daniel van Vugt

Merge latest development-branch

1712. By Daniel van Vugt

Merge latest development-branch

1713. By Daniel van Vugt

Rename min_buffers to ideal_buffers

1714. By Daniel van Vugt

Add a "min_buffers" constant in preparation for future configurability.

1715. By Daniel van Vugt

Fix failing tests (bad initalizer of min_buffers)

1716. By Daniel van Vugt

Revert evil fudges to TEST_F(BufferQueueTest, slow_client_framerate_matches_compositor)

Let's see if we can make it pass again properly.

1717. By Daniel van Vugt

Add detection of missed frame deadlines and auto-expand the buffer queue when
it happens too much.

1718. By Daniel van Vugt

Remember to reset extra_buffers when frame dropping

1719. By Daniel van Vugt

Tidy up

1720. By Daniel van Vugt

Make the resize delay configurable so slow_client_framerate_matches_compositor
can pass again reliably without cheating.

1721. By Daniel van Vugt

Fix test: BufferQueueTest.synchronous_clients_only_get_two_real_buffers

1722. By Daniel van Vugt

Fix unreliable test: queue_size_scales_instantly_on_framedropping

1723. By Daniel van Vugt

More rigorous auto-expansion testing

1724. By Daniel van Vugt

Avoid ping-pong queue resizing. If a slow client needs more buffers, giving
it an extra one will make it look fast. But that doesn't make it a fast client.
So avoid shrinking the buffer queue based on performance observations alone.

1725. By Daniel van Vugt

More intelligent hysteresis. Ensure missed_frames can come down if we're
mostly keeping up.

1726. By Daniel van Vugt

Merge latest development-branch

1727. By Daniel van Vugt

Merge latest development-branch

1728. By Daniel van Vugt

Merge latest development-branch

1729. By Daniel van Vugt

Merge latest development-branch and fix conflicts.

1730. By Daniel van Vugt

Merge latest development-branch

1731. By Daniel van Vugt

Fix failing test case, merged from devel:
gives_compositor_the_newest_buffer_after_dropping_old_buffers

1732. By Daniel van Vugt

Make tests which require 3 buffers more consistent

1733. By Daniel van Vugt

Fix failing test: TEST_F(StaleFrames, are_dropped_when_restarting_compositor)
It was designed to assume three unique buffers available by default. Remove
that assumption.

1734. By Daniel van Vugt

Lower the resize delay to 100 frames so slow clients only take ~1.5s to
be detected as slow and change to triple buffers.

1735. By Daniel van Vugt

Merge latest development-branch

1736. By Daniel van Vugt

Merge latest development-branch

1737. By Daniel van Vugt

Add unit test: BufferQueueTest.switch_to_triple_buffers_is_permanent

This verifies we don't accidentally ping-pong between 2 and 3 buffers.

1738. By Daniel van Vugt

Merge latest development-branch

1739. By Daniel van Vugt

Add a regression test for the idle-vs-slow client problem Alexandros
described. Presently failing.

1740. By Daniel van Vugt

Move the "missed frames" decision to a point where it won't be skewed by
multiple compositors (multi-monitor).

1741. By Daniel van Vugt

Prototype a detection of "idle" clients. Other questionable tests still
failing.

1742. By Daniel van Vugt

Simplify

1743. By Daniel van Vugt

More readable.

1744. By Daniel van Vugt

Fix failing test: BufferQueueTest.queue_size_scales_for_slow_clients
It needed some enhancement to not be detected as an "idle" client by the
new logic.

1745. By Daniel van Vugt

Fix test case: BufferQueueTest.switch_to_triple_buffers_is_permanent
The new idle detection logic was not seeing any client activity and so
deemed it not trying to keep up. So added some "slow client" activity.

1746. By Daniel van Vugt

Simplified idle detection

1747. By Daniel van Vugt

Fix comment typo

1748. By Daniel van Vugt

Add another regression test which shows premature expansion for really
slow clients.

1749. By Daniel van Vugt

Fixed: Mis-detection of a really slow client (low self-determined frame rate)
as failing to keep up. Regression test now passes.

1750. By Daniel van Vugt

Remove debug code

1751. By Daniel van Vugt

Merge latest development-branch

1752. By Daniel van Vugt

Merge latest development-branch

1753. By Daniel van Vugt

Slightly simpler and more straight forward detection of slow vs idle clients.

1754. By Daniel van Vugt

Shrink the diff

1755. By Daniel van Vugt

More comments

1756. By Daniel van Vugt

Add a regression test for the slow-ticking-client-mostly-idle-desktop case.

1757. By Daniel van Vugt

test_buffer_queue.cpp: De-duplicate buffer counting logic

1758. By Daniel van Vugt

Fix indentation in new tests

1759. By Daniel van Vugt

test_buffer_queue.cpp: Major simplification - reuse a common function to
measure unique buffers.

1760. By Daniel van Vugt

Tidy up tests

1761. By Daniel van Vugt

Remove unnecessary sleeps from new tests

1762. By Daniel van Vugt

Go back to the old algorithm, keep the new tests.

1763. By Daniel van Vugt

A slightly more elegant measure of client_lag

1764. By Daniel van Vugt

Merge latest development-branch

1765. By Daniel van Vugt

Merge latest development-branch

1766. By Daniel van Vugt

Merge latest development-branch

1767. By Daniel van Vugt

Merge latest development-branch

1768. By Daniel van Vugt

Merge latest development-branch

1769. By Daniel van Vugt

Merge latest development-branch

1770. By Daniel van Vugt

Merge latest development-branch

1771. By Daniel van Vugt

Merge latest development-branch and fix conflicts.

1772. By Daniel van Vugt

Merge latest development-branch

1773. By Daniel van Vugt

Merge latest development-branch

1774. By Daniel van Vugt

Merge latest development-branch

1775. By Daniel van Vugt

Merge latest development-branch

1776. By Daniel van Vugt

Merge latest development-branch

1777. By Daniel van Vugt

Merge latest development-branch

1778. By Daniel van Vugt

Merge (rebase on) 'double-integration-tests' to shrink the diff of
this branch to its new parent.

1779. By Daniel van Vugt

Merge latest development-branch

1780. By Daniel van Vugt

Merge latest development-branch and fix conflicts.

1781. By Daniel van Vugt

Merge latest development-branch

1782. By Daniel van Vugt

Merge latest development-branch

1783. By Daniel van Vugt

Merge latest development-branch

1784. By Daniel van Vugt

Merge latest development-branch

1785. By Daniel van Vugt

Merge latest development-branch and fix a conflict.

1786. By Daniel van Vugt

Merge latest development-branch

1787. By Daniel van Vugt

Merge latest development-branch

1788. By Daniel van Vugt

Merge latest development-branch

1789. By Daniel van Vugt

Merge latest trunk

1790. By Daniel van Vugt

Merge latest trunk

1791. By Daniel van Vugt

Merge latest trunk

1792. By Daniel van Vugt

Merge latest trunk

1793. By Daniel van Vugt

Merge latest trunk

1794. By Daniel van Vugt

Merge latest trunk

1795. By Daniel van Vugt

Merge latest trunk

1796. By Daniel van Vugt

Merge latest trunk

1797. By Daniel van Vugt

Prototype fix for the crashing integration test

1798. By Daniel van Vugt

A simpler fix for the crashing test -- don't try to release the same
old_buffer multiple times.

1799. By Daniel van Vugt

Even simpler

Unmerged revisions

1799. By Daniel van Vugt

Even simpler

1798. By Daniel van Vugt

A simpler fix for the crashing test -- don't try to release the same
old_buffer multiple times.

1797. By Daniel van Vugt

Prototype fix for the crashing integration test

1796. By Daniel van Vugt

Merge latest trunk

1795. By Daniel van Vugt

Merge latest trunk

1794. By Daniel van Vugt

Merge latest trunk

1793. By Daniel van Vugt

Merge latest trunk

1792. By Daniel van Vugt

Merge latest trunk

1791. By Daniel van Vugt

Merge latest trunk

1790. By Daniel van Vugt

Merge latest trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/compositor/buffer_queue.cpp'
2--- src/server/compositor/buffer_queue.cpp 2014-05-29 15:51:54 +0000
3+++ src/server/compositor/buffer_queue.cpp 2014-05-30 13:43:29 +0000
4@@ -95,6 +95,8 @@
5 std::shared_ptr<graphics::GraphicBufferAllocator> const& gralloc,
6 graphics::BufferProperties const& props)
7 : nbuffers{nbuffers},
8+ excess{0},
9+ overlapping_compositors{false},
10 frame_dropping_enabled{false},
11 the_properties{props},
12 gralloc{gralloc}
13@@ -143,12 +145,8 @@
14 return;
15 }
16
17- /* No empty buffers, attempt allocating more
18- * TODO: need a good heuristic to switch
19- * between double-buffering to n-buffering
20- */
21 int const allocated_buffers = buffers.size();
22- if (allocated_buffers < nbuffers)
23+ if (allocated_buffers < min_buffers())
24 {
25 auto const& buffer = gralloc->alloc_buffer(the_properties);
26 buffers.push_back(buffer);
27@@ -213,9 +211,18 @@
28 current_buffer_users.push_back(user_id);
29 current_compositor_buffer = pop(ready_to_composite_queue);
30 }
31+ else if (current_buffer_users.empty())
32+ { // current_buffer_users and ready_to_composite_queue both empty
33+ current_buffer_users.push_back(user_id);
34+ }
35
36 buffers_sent_to_compositor.push_back(current_compositor_buffer);
37
38+ // Detect bypassing compositors (those that need to hold multiple different
39+ // buffers simultaneously).
40+ overlapping_compositors =
41+ buffers_sent_to_compositor.size() > current_buffer_users.size();
42+
43 std::shared_ptr<mg::Buffer> const acquired_buffer =
44 buffer_for(current_compositor_buffer, buffers);
45
46@@ -337,14 +344,7 @@
47 int mc::BufferQueue::buffers_free_for_client() const
48 {
49 std::lock_guard<decltype(guard)> lock(guard);
50- int ret = 1;
51- if (nbuffers > 1)
52- {
53- int nfree = free_buffers.size();
54- int future_growth = nbuffers - buffers.size();
55- ret = nfree + future_growth;
56- }
57- return ret;
58+ return nbuffers > 1 ? free_buffers.size() : 1;
59 }
60
61 void mc::BufferQueue::give_buffer_to_client(
62@@ -400,8 +400,51 @@
63 mg::Buffer* buffer,
64 std::unique_lock<std::mutex> lock)
65 {
66- if (!pending_client_notifications.empty())
67+ int used_buffers = buffers.size() - free_buffers.size();
68+
69+ // To avoid reallocating buffers too often (which may be slow), only drop
70+ // a buffer after it's continually been in excess for a long time...
71+
72+ if (used_buffers > min_buffers())
73+ ++excess;
74+ else
75+ excess = 0;
76+
77+ // If too many frames have had excess buffers then start dropping them now
78+ if (excess > 300 && buffers.back().get() == buffer && nbuffers > 1)
79+ {
80+ buffers.pop_back();
81+ excess = 0;
82+ }
83+ else if (!pending_client_notifications.empty())
84 give_buffer_to_client(buffer, std::move(lock));
85 else
86 free_buffers.push_back(buffer);
87 }
88+
89+/**
90+ * Measure the actual number of buffers we presently need concurrently
91+ * to avoid starving any compositors of fresh frames or starving clients of
92+ * any buffers at all. Typically in a multi-buffer client min_buffers will
93+ * be 2. However when DRM bypass is active or frame dropping enabled, the
94+ * result of min_buffers could be 3. If you had bypass and frame dropping
95+ * enabled simultaneously then required_buffers could reach 4 (LP: #1317403)
96+ */
97+int mc::BufferQueue::min_buffers() const
98+{
99+ if (nbuffers <= 1)
100+ return nbuffers;
101+
102+ // else for multi-buffering with exclusivity guarantees:
103+ int client_demand = buffers_owned_by_client.size() +
104+ pending_client_notifications.size();
105+ // FIXME: LP: #1308844 / LP: #1308843 is inflating compositor_demand
106+ int compositor_demand = overlapping_compositors ? 2 : 1;
107+ int min_compositors = std::max(1, compositor_demand);
108+ int min_clients = std::max(1, client_demand);
109+ int min_free = frame_dropping_enabled ? 1 : 0;
110+ int required_buffers = min_compositors + min_clients + min_free;
111+
112+ // FIXME: Sometimes required_buffers > nbuffers (LP: #1317403)
113+ return std::min(nbuffers, required_buffers);
114+}
115
116=== modified file 'src/server/compositor/buffer_queue.h'
117--- src/server/compositor/buffer_queue.h 2014-05-29 15:51:54 +0000
118+++ src/server/compositor/buffer_queue.h 2014-05-30 13:43:29 +0000
119@@ -65,6 +65,7 @@
120 bool is_a_current_buffer_user(void const* user_id) const;
121 void release(graphics::Buffer* buffer,
122 std::unique_lock<std::mutex> lock);
123+ int min_buffers() const;
124
125 mutable std::mutex guard;
126
127@@ -81,6 +82,8 @@
128 std::deque<Callback> pending_client_notifications;
129
130 int nbuffers;
131+ int excess;
132+ bool overlapping_compositors;
133 bool frame_dropping_enabled;
134 graphics::BufferProperties the_properties;
135
136
137=== modified file 'tests/integration-tests/compositor/test_buffer_stream.cpp'
138--- tests/integration-tests/compositor/test_buffer_stream.cpp 2014-05-30 13:43:28 +0000
139+++ tests/integration-tests/compositor/test_buffer_stream.cpp 2014-05-30 13:43:29 +0000
140@@ -45,15 +45,13 @@
141 {
142 using mc::BufferStreamSurfaces::BufferStreamSurfaces;
143
144- // Convenient function to allow tests to be written in linear style
145- void swap_client_buffers_blocking(mg::Buffer*& buffer)
146+ // Convenient functions to allow tests to be written in linear style
147+ mg::Buffer* acquire_client_buffer_blocking()
148 {
149 std::mutex mutex;
150 std::condition_variable cv;
151 bool done = false;
152-
153- if (buffer)
154- release_client_buffer(buffer);
155+ mg::Buffer* buffer = nullptr;
156
157 acquire_client_buffer(
158 [&](mg::Buffer* new_buffer)
159@@ -67,6 +65,16 @@
160 std::unique_lock<decltype(mutex)> lock(mutex);
161
162 cv.wait(lock, [&]{ return done; });
163+
164+ return buffer;
165+ }
166+
167+ void swap_client_buffers_blocking(mg::Buffer*& buffer)
168+ {
169+ if (buffer)
170+ release_client_buffer(buffer);
171+
172+ buffer = acquire_client_buffer_blocking();
173 }
174 };
175
176@@ -106,12 +114,9 @@
177
178 TEST_F(BufferStreamTest, gives_same_back_buffer_until_more_available)
179 {
180- ASSERT_THAT(buffers_free_for_client(), Ge(2)); // else we will hang
181-
182- mg::Buffer* client1{nullptr};
183- buffer_stream.swap_client_buffers_blocking(client1);
184+ mg::Buffer* client1 = buffer_stream.acquire_client_buffer_blocking();
185 auto client1_id = client1->id();
186- buffer_stream.swap_client_buffers_blocking(client1);
187+ buffer_stream.release_client_buffer(client1);
188
189 auto comp1 = buffer_stream.lock_compositor_buffer(nullptr);
190 auto comp2 = buffer_stream.lock_compositor_buffer(nullptr);
191@@ -121,10 +126,14 @@
192
193 comp1.reset();
194
195- buffer_stream.swap_client_buffers_blocking(client1);
196+ mg::Buffer* client2 = buffer_stream.acquire_client_buffer_blocking();
197+ auto client2_id = client2->id();
198+ buffer_stream.release_client_buffer(client2);
199+
200 auto comp3 = buffer_stream.lock_compositor_buffer(nullptr);
201
202 EXPECT_NE(client1_id, comp3->id());
203+ EXPECT_EQ(client2_id, comp3->id());
204
205 comp2.reset();
206 auto comp3_id = comp3->id();
207@@ -155,16 +164,10 @@
208
209 TEST_F(BufferStreamTest, gives_different_back_buffer_asap)
210 {
211- ASSERT_THAT(buffers_free_for_client(), Ge(2)); // else we will hang
212-
213- mg::Buffer* client_buffer{nullptr};
214- buffer_stream.swap_client_buffers_blocking(client_buffer);
215-
216- ASSERT_THAT(nbuffers, Gt(1));
217- buffer_stream.swap_client_buffers_blocking(client_buffer);
218+ buffer_stream.release_client_buffer(buffer_stream.acquire_client_buffer_blocking());
219 auto comp1 = buffer_stream.lock_compositor_buffer(nullptr);
220
221- buffer_stream.swap_client_buffers_blocking(client_buffer);
222+ buffer_stream.release_client_buffer(buffer_stream.acquire_client_buffer_blocking());
223 auto comp2 = buffer_stream.lock_compositor_buffer(nullptr);
224
225 EXPECT_NE(comp1->id(), comp2->id());
226@@ -175,13 +178,13 @@
227
228 TEST_F(BufferStreamTest, resize_affects_client_buffers_immediately)
229 {
230- ASSERT_THAT(buffers_free_for_client(), Ge(2)); // else we will hang
231-
232 auto old_size = buffer_stream.stream_size();
233
234- mg::Buffer* client{nullptr};
235- buffer_stream.swap_client_buffers_blocking(client);
236+ mg::Buffer* client = buffer_stream.acquire_client_buffer_blocking();
237 EXPECT_EQ(old_size, client->size());
238+ buffer_stream.release_client_buffer(client);
239+
240+ buffer_stream.lock_compositor_buffer(this);
241
242 geom::Size const new_size
243 {
244@@ -191,28 +194,28 @@
245 buffer_stream.resize(new_size);
246 EXPECT_EQ(new_size, buffer_stream.stream_size());
247
248- buffer_stream.swap_client_buffers_blocking(client);
249+ client = buffer_stream.acquire_client_buffer_blocking();
250 EXPECT_EQ(new_size, client->size());
251+ buffer_stream.release_client_buffer(client);
252+
253+ buffer_stream.lock_compositor_buffer(this);
254
255 buffer_stream.resize(old_size);
256 EXPECT_EQ(old_size, buffer_stream.stream_size());
257
258- /* Release a buffer so client can acquire another */
259- auto comp = buffer_stream.lock_compositor_buffer(nullptr);
260- comp.reset();
261+ buffer_stream.lock_compositor_buffer(this);
262
263- buffer_stream.swap_client_buffers_blocking(client);
264+ client = buffer_stream.acquire_client_buffer_blocking();
265 EXPECT_EQ(old_size, client->size());
266+ buffer_stream.release_client_buffer(client);
267 }
268
269 TEST_F(BufferStreamTest, compositor_gets_resized_buffers)
270 {
271- ASSERT_THAT(buffers_free_for_client(), Ge(2)); // else we will hang
272-
273 auto old_size = buffer_stream.stream_size();
274
275- mg::Buffer* client{nullptr};
276- buffer_stream.swap_client_buffers_blocking(client);
277+ mg::Buffer* client = buffer_stream.acquire_client_buffer_blocking();
278+ buffer_stream.release_client_buffer(client);
279
280 geom::Size const new_size
281 {
282@@ -222,47 +225,54 @@
283 buffer_stream.resize(new_size);
284 EXPECT_EQ(new_size, buffer_stream.stream_size());
285
286- buffer_stream.swap_client_buffers_blocking(client);
287-
288 auto comp1 = buffer_stream.lock_compositor_buffer(nullptr);
289+
290+ client = buffer_stream.acquire_client_buffer_blocking();
291+ buffer_stream.release_client_buffer(client);
292+
293 EXPECT_EQ(old_size, comp1->size());
294 comp1.reset();
295
296- buffer_stream.swap_client_buffers_blocking(client);
297-
298 auto comp2 = buffer_stream.lock_compositor_buffer(nullptr);
299+
300+ client = buffer_stream.acquire_client_buffer_blocking();
301+ buffer_stream.release_client_buffer(client);
302+
303 EXPECT_EQ(new_size, comp2->size());
304 comp2.reset();
305
306- buffer_stream.swap_client_buffers_blocking(client);
307-
308 auto comp3 = buffer_stream.lock_compositor_buffer(nullptr);
309+
310+ client = buffer_stream.acquire_client_buffer_blocking();
311+ buffer_stream.release_client_buffer(client);
312+
313 EXPECT_EQ(new_size, comp3->size());
314 comp3.reset();
315
316 buffer_stream.resize(old_size);
317 EXPECT_EQ(old_size, buffer_stream.stream_size());
318
319+ auto comp4 = buffer_stream.lock_compositor_buffer(nullptr);
320+
321 // No client frames "drawn" since resize(old_size), so compositor gets new_size
322- buffer_stream.swap_client_buffers_blocking(client);
323- auto comp4 = buffer_stream.lock_compositor_buffer(nullptr);
324+ client = buffer_stream.acquire_client_buffer_blocking();
325+ buffer_stream.release_client_buffer(client);
326 EXPECT_EQ(new_size, comp4->size());
327 comp4.reset();
328
329+ auto comp5 = buffer_stream.lock_compositor_buffer(nullptr);
330+
331 // Generate a new frame, which should be back to old_size now
332- buffer_stream.swap_client_buffers_blocking(client);
333- auto comp5 = buffer_stream.lock_compositor_buffer(nullptr);
334+ client = buffer_stream.acquire_client_buffer_blocking();
335+ buffer_stream.release_client_buffer(client);
336 EXPECT_EQ(old_size, comp5->size());
337 comp5.reset();
338 }
339
340 TEST_F(BufferStreamTest, can_get_partly_released_back_buffer)
341 {
342- ASSERT_THAT(buffers_free_for_client(), Ge(2)); // else we will hang
343-
344- mg::Buffer* client{nullptr};
345- buffer_stream.swap_client_buffers_blocking(client);
346- buffer_stream.swap_client_buffers_blocking(client);
347+ mg::Buffer* client = buffer_stream.acquire_client_buffer_blocking();
348+ buffer_stream.release_client_buffer(client);
349
350 int a, b, c;
351 auto comp1 = buffer_stream.lock_compositor_buffer(&a);
352
353=== modified file 'tests/integration-tests/test_surface_first_frame_sync.cpp'
354--- tests/integration-tests/test_surface_first_frame_sync.cpp 2014-05-29 15:51:54 +0000
355+++ tests/integration-tests/test_surface_first_frame_sync.cpp 2014-05-30 13:43:29 +0000
356@@ -114,7 +114,7 @@
357 {
358 for (auto const& r : renderables)
359 {
360- (void)r;
361+ r->buffer(); // We need to consume a buffer to unblock client tests
362 while (write(render_operations_fd, "a", 1) != 1) continue;
363 }
364 }
365
366=== modified file 'tests/unit-tests/compositor/test_buffer_queue.cpp'
367--- tests/unit-tests/compositor/test_buffer_queue.cpp 2014-05-29 15:51:54 +0000
368+++ tests/unit-tests/compositor/test_buffer_queue.cpp 2014-05-30 13:43:29 +0000
369@@ -305,10 +305,7 @@
370 }
371
372 auto handle1 = client_acquire_async(q);
373- ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));
374-
375 auto handle2 = client_acquire_async(q);
376- ASSERT_THAT(handle1->has_acquired_buffer(), Eq(false));
377
378 for (int i = 0; i < nbuffers + 1; ++i)
379 q.compositor_release(q.compositor_acquire(this));
380@@ -377,7 +374,6 @@
381 handle->release_buffer();
382
383 handle = client_acquire_async(q);
384- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
385 handle->release_buffer();
386
387 auto comp_buffer = q.compositor_acquire(this);
388@@ -623,13 +619,13 @@
389 handle->release_buffer();
390
391 handle = client_acquire_async(q);
392- ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
393
394 // in the original bug, compositor would be given the wrong buffer here
395 auto compositor_buffer = q.compositor_acquire(this);
396
397 EXPECT_THAT(compositor_buffer->id(), Eq(first_ready_buffer_id));
398
399+ ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
400 handle->release_buffer();
401 q.compositor_release(compositor_buffer);
402 }
403@@ -800,7 +796,7 @@
404 }
405 }
406
407-TEST_F(BufferQueueTest, framedropping_clients_get_all_buffers)
408+TEST_F(BufferQueueTest, framedropping_clients_get_multiple_buffers)
409 {
410 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
411 {
412@@ -808,7 +804,9 @@
413 q.allow_framedropping(true);
414
415 int const nframes = 100;
416- int max_ownable_buffers = nbuffers - 1;
417+ // Dynamic queue scaling sensibly limits the framedropping client to
418+ // two non-overlapping buffers, before overwriting old ones.
419+ int max_ownable_buffers = nbuffers <= 2 ? 1 : 2;
420 std::unordered_set<uint32_t> ids_acquired;
421 for (int i = 0; i < nframes; ++i)
422 {
423@@ -995,6 +993,7 @@
424 {
425 mc::BufferQueue q(nbuffers, allocator, basic_properties);
426 mg::BufferID history[5];
427+ std::shared_ptr<AcquireWaitHandle> producing[5];
428
429 const int width0 = 123;
430 const int height0 = 456;
431@@ -1015,9 +1014,16 @@
432 auto handle = client_acquire_async(q);
433 ASSERT_THAT(handle->has_acquired_buffer(), Eq(true));
434 history[produce] = handle->id();
435+ producing[produce] = handle;
436 auto buffer = handle->buffer();
437 ASSERT_THAT(buffer->size(), Eq(new_size));
438- handle->release_buffer();
439+ }
440+
441+ // Overlap all the client_acquires asyncronously. It's the only way
442+ // the new dynamic queue scaling will let a client hold that many...
443+ for (int complete = 0; complete < nbuffers_to_use; ++complete)
444+ {
445+ producing[complete]->release_buffer();
446 }
447
448 width = width0;
449@@ -1328,8 +1334,7 @@
450 }
451 }
452
453-/* FIXME (enabling this optimization breaks timing tests) */
454-TEST_F(BufferQueueTest, DISABLED_synchronous_clients_only_get_two_real_buffers)
455+TEST_F(BufferQueueTest, synchronous_clients_only_get_two_real_buffers)
456 {
457 for (int nbuffers = 2; nbuffers <= max_nbuffers_to_test; ++nbuffers)
458 {

Subscribers

People subscribed via source and target branches