Mir

Merge lp:~raof/mir/client-side-buffer-age into lp:~mir-team/mir/trunk

Proposed by Chris Halse Rogers
Status: Merged
Approved by: Chris Halse Rogers
Approved revision: no longer in the source branch.
Merged at revision: 532
Proposed branch: lp:~raof/mir/client-side-buffer-age
Merge into: lp:~mir-team/mir/trunk
Diff against target: 2342 lines (+1074/-555)
41 files modified
include/shared/mir_toolkit/c_types.h (+3/-0)
src/client/CMakeLists.txt (+4/-2)
src/client/aging_buffer.cpp (+42/-0)
src/client/aging_buffer.h (+45/-0)
src/client/android/android_client_buffer.cpp (+3/-3)
src/client/android/android_client_buffer.h (+3/-3)
src/client/android/android_client_buffer_depository.cpp (+0/-51)
src/client/android/android_client_buffer_depository.h (+0/-55)
src/client/android/android_client_buffer_factory.cpp (+35/-0)
src/client/android/android_client_buffer_factory.h (+55/-0)
src/client/android/android_client_platform.cpp (+5/-5)
src/client/android/android_client_platform.h (+1/-1)
src/client/client_buffer.h (+3/-0)
src/client/client_buffer_depository.cpp (+77/-0)
src/client/client_buffer_depository.h (+29/-7)
src/client/client_buffer_factory.h (+44/-0)
src/client/client_platform.h (+2/-2)
src/client/gbm/gbm_client_buffer.cpp (+3/-2)
src/client/gbm/gbm_client_buffer.h (+3/-4)
src/client/gbm/gbm_client_buffer_depository.cpp (+0/-44)
src/client/gbm/gbm_client_buffer_depository.h (+0/-55)
src/client/gbm/gbm_client_buffer_factory.cpp (+35/-0)
src/client/gbm/gbm_client_buffer_factory.h (+51/-0)
src/client/gbm/gbm_client_platform.cpp (+4/-3)
src/client/gbm/gbm_client_platform.h (+1/-1)
src/client/mir_connection.cpp (+3/-3)
src/client/mir_surface.cpp (+6/-8)
src/client/mir_surface.h (+1/-3)
tests/unit-tests/client/CMakeLists.txt (+2/-0)
tests/unit-tests/client/android/CMakeLists.txt (+0/-1)
tests/unit-tests/client/android/test_android_client_depository.cpp (+0/-169)
tests/unit-tests/client/android/test_client_surface_interpreter.cpp (+4/-0)
tests/unit-tests/client/gbm/CMakeLists.txt (+0/-1)
tests/unit-tests/client/gbm/test_gbm_client_buffer.cpp (+5/-4)
tests/unit-tests/client/gbm/test_gbm_client_depository.cpp (+0/-79)
tests/unit-tests/client/test_aging_buffer.cpp (+114/-0)
tests/unit-tests/client/test_android_client_buffer_factory.cpp (+74/-0)
tests/unit-tests/client/test_client_buffer_depository.cpp (+364/-0)
tests/unit-tests/client/test_client_mir_surface.cpp (+49/-45)
tests/unit-tests/client/test_client_platform.cpp (+3/-3)
tests/unit-tests/client/test_mir_connection.cpp (+1/-1)
To merge this branch: bzr merge lp:~raof/mir/client-side-buffer-age
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Abstain
Alan Griffiths Approve
Alexandros Frantzis (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Needs Fixing
Review via email: mp+151869@code.launchpad.net

Commit message

Add an “age” field to MirBufferPackage

This is the number of frames submitted by the client since the buffer
has been rendered to; 0 indicates that the client has not rendered to it before.

This allows clients which have only small changes between frames to do
significantly less rendering, by only rendering the difference.

See also: http://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_buffer_age.txt

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

On a quick scan the only thing I'd argue with is "set_age()" (because I hate set_xxx() member functions).

Rather than set_age(1)/set_age(age()+1) I'd prefer to see reset_age(), increment_age()

(Just commenting pending a closer review.)

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Some notes on the loop starting at line 193:

The mir coding convention is to put curly braces on their on own line, and also, if one clause of an if statement uses braces, then so should all the others.

193 + for (auto buffer_pair :buffers) {

Is there a reason to copy the buffer_pair instead of taking a reference (auto&)?
A space is missing after ':'.

199 + buffers.erase(buffer_pair.first);

I am not sure if it is safe to delete an element while iterating with a range-based for loop. Unless we have a guarantee from the standard that this works, we should do something different (e.g. use iterators manually, save the keys to a vector for deletion after the loop)

204 + if (!buffers.empty())
205 + buffers[current_buffer]->set_age(1);

Is this needed? The loop should have reset the current buffer's age.

206 + auto find_it = buffers.find(id);
207 + if (find_it == buffers.end())

Since we don't need find_it later, we might as well use the more compact if (buffers.find(id) == buffers.end()).
(this is really minor, not a blocker).

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
Download full text (4.3 KiB)

[ RUN ] MirGBMBufferDepositoryTest.depository_forgets_old_buffers
==21586== Invalid read of size 4
==21586== at 0x4365E04: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17)
==21586== by 0x4058FBA: mir::client::gbm::GBMClientBufferDepository::deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage>&&, int, mir::geometry::Size, mir::geometry::PixelFormat) (stl_tree.h:188)
==21586== by 0x8276E2D: MirGBMBufferDepositoryTest_depository_forgets_old_buffers_Test::TestBody() (test_gbm_client_depository.cpp:226)
==21586== by 0x850407B: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2090)
==21586== by 0x84FB651: testing::Test::Run() (gtest.cc:2162)
==21586== by 0x84FB737: testing::TestInfo::Run() (gtest.cc:2338)
==21586== by 0x84FB886: testing::TestCase::Run() (gtest.cc:2445)
==21586== by 0x84FBB84: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4243)
==21586== by 0x8503C5B: bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (gtest.cc:2090)
==21586== by 0x84FABFB: testing::UnitTest::Run() (gtest.cc:3880)
==21586== by 0x4467934: (below main) (libc-start.c:260)
==21586== Address 0x49a209c is 12 bytes inside a block of size 28 free'd
==21586== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21586== by 0x405999F: std::_Rb_tree<unsigned int, std::pair<unsigned int const, std::shared_ptr<mir::client::gbm::GBMClientBuffer> >, std::_Select1st<std::pair<unsigned int const, std::shared_ptr<mir::client::gbm::GBMClientBuffer> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::shared_ptr<mir::client::gbm::GBMClientBuffer> > > >::_M_erase_aux(std::_Rb_tree_const_iterator<std::pair<unsigned int const, std::shared_ptr<mir::client::gbm::GBMClientBuffer> > >, std::_Rb_tree_const_iterator<std::pair<unsigned int const, std::shared_ptr<mir::client::gbm::GBMClientBuffer> > >) (new_allocator.h:98)
==21586==
==21586== Invalid read of size 4
==21586== at 0x4365E1B: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17)
==21586== by 0x4058FBA: mir::client::gbm::GBMClientBufferDepository::deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage>&&, int, mir::geometry::Size, mir::geometry::PixelFormat) (stl_tree.h:188)
==21586== by 0x8276E2D: MirGBMBufferDepositoryTest_depository_forgets_old_buffers_Test::TestBody() (test_gbm_client_depository.cpp:226)
==21586== by 0x850407B: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2090)
==21586== by 0x84FB651: testing::Test::Run() (gtest.cc:2162)
==21586== by 0x84FB737: testing::TestInfo::Run() (gtest.cc:2338)
==21586== by 0x84FB886: testing::TestCase::Run() (gtest.cc:2445)
==21586== by 0x84FBB84: testing::internal::UnitTestImpl::RunAllTests() (gtest....

Read more...

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:463
http://jenkins.qa.ubuntu.com/job/mir-ci/5/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-quantal-amd64-ci/5//console

Click here to trigger a rebuild:
http://jenkins.qa.ubuntu.com/job/mir-ci/5//rebuild/?

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

PASSED: Continuous integration, rev:464
http://jenkins.qa.ubuntu.com/job/mir-ci/6/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-quantal-amd64-ci/6//console

Click here to trigger a rebuild:
http://jenkins.qa.ubuntu.com/job/mir-ci/6//rebuild/?

review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

It isn't obvious locally why:

200 + auto buffer_it = buffers.begin();
201 + while (buffer_it != buffers.end())
202 + {
203 + auto tmp_it = buffer_it;
204 + ++buffer_it;

isn't written as

    for (auto tmp_it : buffers)
    {

only when you read to:

213 + // C++ guarantees that buffers.erase() will only invalidate the iterator
214 + // we erase.
215 + buffers.erase(tmp_it);

Does it become apparent.

If we can't think of a way to write the code more clearly I think the comment should move to before

204 + ++buffer_it;

And I think "tmp_it" could be better named - e.g. "current"

~~~~

72 + std::shared_ptr<ClientBuffer> access_current_buffer(void);
144 +void mclg::GBMClientBuffer::increment_age(void)
150 +void mclg::GBMClientBuffer::mark_as_submitted(void)
169 + void increment_age(void);
170 + void mark_as_submitted(void);
...

s/void//

~~~~
591 +TEST_F(MirGBMBufferDepositoryTest, depository_forgets_old_buffers)
...
604 + // We've submitted 4 buffers now; we should have forgotten the first one.

This is just a naming issue, but I don't think the test proves anything about old buffers being "forgotten". (I think we'd need to take a weak pointer to the "old buffer" and test that it becomes null to prove "forgets".)

What it checks is that buffers that were seen four generations ago have age 0. (Which I accept is implemented by "forgetting" - but forgetting isn't the behaviour tested for.)

~~~~

246 void deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> && package, int, geometry::Size size, geometry::PixelFormat pf);

I guess this MP didn't create this (so I wouldn't block on it). But WHY a rvalue-reference to a shared pointer?! A const ref would be idiomatic and work better. It would be nice to clean this up while changing this code.

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

246 void deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> && package, int, geometry::Size size, geometry::PixelFormat pf);

I guess this MP didn't create this (so I wouldn't block on it). But WHY a rvalue-reference to a shared pointer?! A const ref would be idiomatic and work better. It would be nice to clean this up while changing this code.
~~~~~~

Every time I look at that code I'm tempted to make deposit_package take a mir::protobuf::Buffer. The MirSurface does nothing with the m::p::Buffer but copy the values to a MirBufferPackage which it promptly hands off to the depository and forgets.

That's probably more controversial, though.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:467
http://jenkins.qa.ubuntu.com/job/mir-ci/19/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-quantal-amd64-ci/19//console

Click here to trigger a rebuild:
http://jenkins.qa.ubuntu.com/job/mir-ci/19//rebuild/?

review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

116 + virtual std::shared_ptr<ClientBuffer> access_current_buffer() = 0;

This could might as well be named 'current_buffer()'.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

593 +TEST_F(MirGBMBufferDepositoryTest, depository_forgets_old_buffers)
etc.

Hmm, I guess I shouldn't have mentioned this trick for probing the implementation. :(

Tests must check the required behaviour not the implementation. The previous version did test the right thing (it just had a bad name).

~~~~

PS I agree with Alexandros about s/access_current_buffer/current_buffer/ (the member variable can have another name).

PPS I had a go at writing a cleaner version of GBMClientBufferDepository::deposit_package - you can see if you like it here:

    https://code.launchpad.net/~alan-griffiths/mir/client-side-buffer-age/+merge/152392

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

593 +TEST_F(MirGBMBufferDepositoryTest, depository_forgets_old_buffers)

This now tests exactly what I wanted it to test in the first place - that the depository does not keep old buffers around, and destroys them.

GBMClientBuffer is about to grow a non-trivial destructor, and I need to test that we're cleaning up old buffers - the GBM platform could easily send thousands of unique buffers to a client, each of which will have an associated fd, so without destroying old buffers we'll rapidly exhaust the client's fd space.

Although it's not API behaviour, “doesn't consume resources without limit” seems like testable behaviour to me - perhaps the test should be renamed to depository_destroys_old_buffers?

You've got more TTD experience than me; where do you believe this test should reside?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:468
http://jenkins.qa.ubuntu.com/job/mir-ci/32/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-quantal-amd64-ci/32//console

Click here to trigger a rebuild:
http://jenkins.qa.ubuntu.com/job/mir-ci/32//rebuild/?

review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> 593 +TEST_F(MirGBMBufferDepositoryTest, depository_forgets_old_buffers)
>
> This now tests exactly what I wanted it to test in the first place - that the
> depository does not keep old buffers around, and destroys them.
>
> GBMClientBuffer is about to grow a non-trivial destructor, and I need to test
> that we're cleaning up old buffers - the GBM platform could easily send
> thousands of unique buffers to a client, each of which will have an associated
> fd, so without destroying old buffers we'll rapidly exhaust the client's fd
> space.
>
> Although it's not API behaviour, “doesn't consume resources without limit”
> seems like testable behaviour to me - perhaps the test should be renamed to
> depository_destroys_old_buffers?
>
> You've got more TTD experience than me; where do you believe this test should
> reside?

OK, I understand that concern.

I'm not sure of the "right answer" here so I'll dump some stream of consciousness (this is where conversation would have saved days of reviews)...

TDD orthodoxy says that if you can't test what you want through the API then you can (and should) improve the design to make that requirement explicit.

I guess the problem arises because GBMClientBufferDepository creates the GBMClientBuffer objects directly - so there's no "seam" here to inject a mock with an instrumented destructor. Supplying the constructor with a GBMClientBufferFactory (that could be a std::function<>) is one option that adds a seam for this - another is to template GBMClientBufferDepository on the buffer type.

I don't know GBM or Android well enough to be sure, but, having thought through the above, I've a feeling that ClientBufferDepository *ought* to be pretty similar between GBM and Android (and just the buffer creation depend on the platform) - so maybe that is the right answer.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Re performance comments in the other MP:

My experience suggests that we'd get a bigger performance improvement by using an array (and liner search) instead of a std::map rather than by avoiding multiple loops. But measurement is the only true way to tell.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Ok. This is untested on Android, as the build fails outside my changes for me.

I suspect that the age()/increment_age()/mark_as_submitted() might want to head up to the ClientBuffer, but haven't done that for this round.

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

> Ok. This is untested on Android, as the build fails outside my changes for
> me.
>
> I suspect that the age()/increment_age()/mark_as_submitted() might want to
> head up to the ClientBuffer, but haven't done that for this round.

yes, looks like the android compile for this branch needs some dusting up. lp:mir (515) looks ok to me. I'm still trying to make the android cross compile easier to use with better scripts (lp:~mir-team/mir/consolidate-crossbuild-scripts), I can help set up your system (although i have limited bandwidth)

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Overall the implementation appears to be semantically correct. However android build is definitely broken, at the least it looks like there is truncation at l236

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

What is going on around line 1347? Why the usage of this "_rv" function rather than mock create buffer directly?

review: Needs Information
Revision history for this message
Robert Carr (robertcarr) wrote :

Why the separate implementations of buffer age for android and GBM? Notably GBM refuses to increment the age if age == 0 while android happily increments?

review: Needs Information
Revision history for this message
Robert Carr (robertcarr) wrote :

Numerous whitespace errors
l284, l38, l1685, l1799, l1815 (examples). Might be good to use make style_check and grep for files modified in diff.

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Some random musings:

* The tests around 1464 feel really verbose but I am not sure of a more concise set of tests. Perhaps it is best!

* BufferDepository seems to make sense for the interface the receiver (or rather the surface) uses to deposit buffers, but doesn't tell you much that it have this age tracking role. Perhaps the implementation should be renamed, BufferCollection, BufferBundle?

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

Enough nits to add up to a "Needs Fixing"

398 + std::shared_ptr<ClientBufferFactory> create_buffer_factory ();

Nit: s/y /y/

~~~~

859 +#include <stdexcept>
860 +#include <memory>

Not needed. (One not used, the other has to be included by header for signatures there.)

~~~~

905 +#include <stdexcept>
906 +#include <map>

Not needed.

~~~~

993 + for (auto it = release_wait_handles.begin(); it != release_wait_handles.end(); it++)
994 delete *it;

for (auto handle : release_wait_handles) delete handle;

~~~~

1651 + MockBuffer *first_buffer = reinterpret_cast<MockBuffer *>(depository.current_buffer().get());

Doesn't need "reinterpret_cast" (which should only be used as a last, non-portable, resort). Use static_cast - or, probably better, access the MockBuffer via MockClientBufferFactory member.

~~~~

2055 +#include <stdexcept>
2056 +

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Re: <RAOF> What do you think of pulling the age() related bits into ClientBuffer; the implementation shouldn't be different between AndroidClientBuffer and GBMClientBuffer.

I think ClientBuffer should remain an interface (it is easier to mock).

But there is no reason that the age related bits couldn't have a common implementation inherited by AndroidClientBuffer and GBMClientBuffer.

There are several options, the simplest is:

class AgingClientBuffer : public ClientBuffer { ...age stuff... };
class AndroidClientBuffer : public AgingClientBuffer { ...non-age stuff... };
class GBMClientBuffer : public AgingClientBuffer { ...non-age stuff... };

But it is also possible to split out an AgingBuffer interface.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Now that ClientBufferDepository is a concrete class, injecting it into MirSurface is much less useful. I'd rather we injected the BufferFactory directly, and make the ClientBufferDepository an implementation detail. This direction is also supported by the MirSurface tests, where we currently need to mock an indirect dependency of the class under test. This approach presumes that we don't need to share depositories between surfaces, which seems to be the case currently.

Concerning making ClientBufferDepository concrete in the first place, I think it's a valid option as long as we are still able to perform the tests we want. The MirSurface unit-tests need some more tests (e.g. MirSurface.get_buffer_returns_last_received_buffer), so perhaps we are not yet at a position to answer this.

Revision history for this message
Chris Halse Rogers (raof) wrote :

I think this addresses all the review concerns. Perhaps we can defer further refactoring to a later MP? :)

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

628 + std::shared_ptr<ClientBufferFactory> factory;
          std::shared_ptr<ClientBufferFactory> const factory;

(dependencies should be const)

~~~~

AgingBuffer - the implicit constructor default initializes buffer_age - which for a POD is an unspecified value. There should be a constructor that initializes buffer_age to 0.

~~~~

struct MockAgingBuffer : public mcl::AgingBuffer

This doesn't mock AgingBuffer.

~~~~

1209 + auto mock_buffer = std::make_shared<NiceMock<MockAgingBuffer>>();
1210 +
1211 + EXPECT_EQ(0u, mock_buffer->age());

This reads really strangely because it appears you're testing the mock age() function (c.f. previous comment).

Rewriting the test as:

TEST(MirClientAgingBufferTest, buffer_age_starts_at_zero)
{
    using namespace testing;

    struct MyAgingBuffer : mcl::AgingBuffer
    {
        std::shared_ptr<mcl::MemoryRegion> secure_for_cpu_write() { exit(1); }
        geom::Size size() const { exit(1); }
        geom::Stride stride() const { exit(1); }
        geom::PixelFormat pixel_format() const { exit(1); }
        std::shared_ptr<mir_toolkit::MirBufferPackage> get_buffer_package() const { exit(1); }
        MirNativeBuffer get_native_handle() { exit(1); }
    } test_buffer;

    EXPECT_EQ(0u, test_buffer.age());
}

is less misleading and also exposes the failure to initialize buffer_age (unfortunately make_shared seems to hide it).

PS it almost seems worth either defining an "AgingBuffer interface" (or providing stub implementations in AgingBuffer) to avoid the need to stub the unimplemented methods in the tests.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Style nitpick: there are a lot of instances of "const &" instead of our preferred "const&". I don't want to block the branch for this (unless something else comes up, too), but we should fix these in style cleanup branch.

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Note that I still stand by my previous comment "Now that ClientBufferDepository is a concrete class, injecting it into MirSurface is much less useful", but let's discuss further and amend in a future MP if needed.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Note that I still stand by my previous comment "Now that
> ClientBufferDepository is a concrete class, injecting it into MirSurface is
> much less useful", but let's discuss further and amend in a future MP if
> needed.

Agreed.

Another nit:

1016 + std::shared_ptr<ClientBufferFactory> create_buffer_factory ()

s/y /y/

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

android clients work... algorithm seems good to me from the android perspective. overall, seems good

src/client/client_buffer_factory.h
virtual destructor, probably can disallow copy/assign

1205 (MyAgingBuffer)
although this code is not hit, exit(-1) will exit the test executable, we should assert in the test so we can continue the rest of the tests

also see some "//" for multiline, we've been preferring

Anyways, I think that this is good enough to go in, so I'll switch to 'abstain' so as to unblock this for the Australian monday work day

review: Abstain
Revision history for this message
Chris Halse Rogers (raof) wrote :

Marking as approved as per comments.

I'll post a follow-up merge proposal addressing the remaining niggles.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/shared/mir_toolkit/c_types.h'
2--- include/shared/mir_toolkit/c_types.h 2013-03-21 17:00:06 +0000
3+++ include/shared/mir_toolkit/c_types.h 2013-03-24 23:57:21 +0000
4@@ -123,6 +123,9 @@
5 int fd[mir_buffer_package_max];
6
7 int stride;
8+ int age; /**< Number of frames submitted by the client since the client has rendered to this buffer. */
9+ /**< This has the same semantics as the EGL_EXT_buffer_age extension */
10+ /**< \see http://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_buffer_age.txt */
11 } MirBufferPackage;
12
13 /**
14
15=== modified file 'src/client/CMakeLists.txt'
16--- src/client/CMakeLists.txt 2013-03-22 10:34:16 +0000
17+++ src/client/CMakeLists.txt 2013-03-24 23:57:21 +0000
18@@ -27,6 +27,8 @@
19 set(
20 CLIENT_SOURCES
21
22+ aging_buffer.cpp
23+ client_buffer_depository.cpp
24 mir_client_library.cpp
25 mir_connection.cpp
26 mir_wait_handle.cpp
27@@ -54,7 +56,7 @@
28 CLIENT_SOURCES
29
30 android/android_client_buffer.cpp
31- android/android_client_buffer_depository.cpp
32+ android/android_client_buffer_factory.cpp
33 android/android_registrar.cpp
34 android/android_client_platform.cpp
35 android/mir_native_window.cpp
36@@ -70,7 +72,7 @@
37 CLIENT_SOURCES
38
39 gbm/gbm_client_platform.cpp
40- gbm/gbm_client_buffer_depository.cpp
41+ gbm/gbm_client_buffer_factory.cpp
42 gbm/gbm_client_buffer.cpp
43 gbm/mesa_native_display_container.cpp
44 ${CLIENT_SOURCES}
45
46=== added file 'src/client/aging_buffer.cpp'
47--- src/client/aging_buffer.cpp 1970-01-01 00:00:00 +0000
48+++ src/client/aging_buffer.cpp 2013-03-24 23:57:21 +0000
49@@ -0,0 +1,42 @@
50+/*
51+ * Copyright © 2013 Canonical Ltd.
52+ *
53+ * This program is free software: you can redistribute it and/or modify
54+ * it under the terms of the GNU Lesser General Public License version 3 as
55+ * published by the Free Software Foundation.
56+ *
57+ * This program is distributed in the hope that it will be useful,
58+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
59+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60+ * GNU General Public License for more details.
61+ *
62+ * You should have received a copy of the GNU Lesser General Public License
63+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
64+ *
65+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
66+ */
67+
68+#include "aging_buffer.h"
69+
70+namespace mcl = mir::client;
71+
72+mcl::AgingBuffer::AgingBuffer()
73+ : buffer_age(0)
74+{
75+}
76+
77+uint32_t mcl::AgingBuffer::age() const
78+{
79+ return buffer_age;
80+}
81+
82+void mcl::AgingBuffer::increment_age()
83+{
84+ if (buffer_age != 0)
85+ ++buffer_age;
86+}
87+
88+void mcl::AgingBuffer::mark_as_submitted()
89+{
90+ buffer_age = 1;
91+}
92
93=== added file 'src/client/aging_buffer.h'
94--- src/client/aging_buffer.h 1970-01-01 00:00:00 +0000
95+++ src/client/aging_buffer.h 2013-03-24 23:57:21 +0000
96@@ -0,0 +1,45 @@
97+/*
98+ * Copyright © 2013 Canonical Ltd.
99+ *
100+ * This program is free software: you can redistribute it and/or modify
101+ * it under the terms of the GNU Lesser General Public License version 3 as
102+ * published by the Free Software Foundation.
103+ *
104+ * This program is distributed in the hope that it will be useful,
105+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
106+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107+ * GNU General Public License for more details.
108+ *
109+ * You should have received a copy of the GNU Lesser General Public License
110+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
111+ *
112+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
113+ */
114+
115+#ifndef MIR_CLIENT_AGING_BUFFER_H_
116+#define MIR_CLIENT_AGING_BUFFER_H_
117+
118+#include "client_buffer.h"
119+
120+namespace mir
121+{
122+namespace client
123+{
124+
125+class AgingBuffer : public ClientBuffer
126+{
127+public:
128+ AgingBuffer();
129+ virtual uint32_t age() const;
130+ virtual void increment_age();
131+ virtual void mark_as_submitted();
132+
133+private:
134+ uint32_t buffer_age;
135+};
136+
137+}
138+}
139+
140+#endif /* MIR_CLIENT_AGING_BUFFER_H_ */
141+
142
143=== modified file 'src/client/android/android_client_buffer.cpp'
144--- src/client/android/android_client_buffer.cpp 2013-03-22 10:34:16 +0000
145+++ src/client/android/android_client_buffer.cpp 2013-03-24 23:57:21 +0000
146@@ -64,19 +64,19 @@
147 {
148 int native_handle_header_size = sizeof(native_handle_t);
149 int total = package->fd_items + package->data_items + native_handle_header_size;
150- native_handle_t* handle = (native_handle_t*) malloc(sizeof(int) * total );
151+ native_handle_t* handle = (native_handle_t*) malloc(sizeof(int) * total);
152
153 handle->version = native_handle_header_size;
154 handle->numFds = package->fd_items;
155 handle->numInts = package->data_items;
156
157- for(auto i=0; i< handle->numFds; i++)
158+ for (auto i=0; i< handle->numFds; i++)
159 {
160 handle->data[i] = package->fd[i];
161 }
162
163 int offset_i = handle->numFds;
164- for(auto i=0; i< handle->numInts; i++)
165+ for (auto i=0; i< handle->numInts; i++)
166 {
167 handle->data[offset_i+i] = package->data[i];
168 }
169
170=== modified file 'src/client/android/android_client_buffer.h'
171--- src/client/android/android_client_buffer.h 2013-03-22 10:34:16 +0000
172+++ src/client/android/android_client_buffer.h 2013-03-24 23:57:21 +0000
173@@ -21,7 +21,7 @@
174 #define MIR_CLIENT_ANDROID_ANDROID_CLIENT_BUFFER_H_
175
176 #include "mir_toolkit/mir_client_library.h"
177-#include "../client_buffer.h"
178+#include "../aging_buffer.h"
179 #include "android_registrar.h"
180
181 #include <system/window.h>
182@@ -34,12 +34,12 @@
183 namespace android
184 {
185
186-class AndroidClientBuffer : public ClientBuffer
187+class AndroidClientBuffer : public AgingBuffer
188 {
189 public:
190 AndroidClientBuffer(std::shared_ptr<AndroidRegistrar> const&,
191 std::shared_ptr<MirBufferPackage> const&,
192- geometry::Size size, geometry::PixelFormat pf );
193+ geometry::Size size, geometry::PixelFormat pf);
194 ~AndroidClientBuffer();
195
196 std::shared_ptr<MemoryRegion> secure_for_cpu_write();
197
198=== removed file 'src/client/android/android_client_buffer_depository.cpp'
199--- src/client/android/android_client_buffer_depository.cpp 2013-03-13 04:54:15 +0000
200+++ src/client/android/android_client_buffer_depository.cpp 1970-01-01 00:00:00 +0000
201@@ -1,51 +0,0 @@
202-/*
203- * Copyright © 2012 Canonical Ltd.
204- *
205- * This program is free software: you can redistribute it and/or modify it
206- * under the terms of the GNU Lesser General Public License version 3,
207- * as published by the Free Software Foundation.
208- *
209- * This program is distributed in the hope that it will be useful,
210- * but WITHOUT ANY WARRANTY; without even the implied warranty of
211- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
212- * GNU General Public License for more details.
213- *
214- * You should have received a copy of the GNU Lesser General Public License
215- * along with this program. If not, see <http://www.gnu.org/licenses/>.
216- *
217- * Authored by:
218- * Kevin DuBois <kevin.dubois@canonical.com>
219- */
220-
221-#include "android_client_buffer_depository.h"
222-#include "android_client_buffer.h"
223-
224-#include <boost/throw_exception.hpp>
225-
226-namespace mcl=mir::client;
227-namespace mcla=mir::client::android;
228-namespace geom=mir::geometry;
229-
230-mcla::AndroidClientBufferDepository::AndroidClientBufferDepository(const std::shared_ptr<AndroidRegistrar>& buffer_registrar)
231- : registrar(buffer_registrar)
232-{
233-}
234-
235-void mcla::AndroidClientBufferDepository::deposit_package(std::shared_ptr<MirBufferPackage>&& package, int id, geom::Size size, geom::PixelFormat pf)
236-{
237- auto find_it = buffer_depository.find(id);
238- if (find_it == buffer_depository.end())
239- {
240- auto buffer = std::make_shared<mcla::AndroidClientBuffer>(registrar, std::move(package), size, pf);
241- buffer_depository[id] = buffer;
242- }
243-}
244-
245-std::shared_ptr<mcl::ClientBuffer> mcla::AndroidClientBufferDepository::access_buffer(int id)
246-{
247- auto find_it = buffer_depository.find(id);
248- if (find_it == buffer_depository.end())
249- BOOST_THROW_EXCEPTION(std::runtime_error("server told client to use buffer before"));
250-
251- return buffer_depository[id];
252-}
253
254=== removed file 'src/client/android/android_client_buffer_depository.h'
255--- src/client/android/android_client_buffer_depository.h 2013-03-13 04:54:15 +0000
256+++ src/client/android/android_client_buffer_depository.h 1970-01-01 00:00:00 +0000
257@@ -1,55 +0,0 @@
258-/*
259- * Copyright © 2012 Canonical Ltd.
260- *
261- * This program is free software: you can redistribute it and/or modify it
262- * under the terms of the GNU Lesser General Public License version 3,
263- * as published by the Free Software Foundation.
264- *
265- * This program is distributed in the hope that it will be useful,
266- * but WITHOUT ANY WARRANTY; without even the implied warranty of
267- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
268- * GNU General Public License for more details.
269- *
270- * You should have received a copy of the GNU Lesser General Public License
271- * along with this program. If not, see <http://www.gnu.org/licenses/>.
272- *
273- * Authored by:
274- * Kevin DuBois <kevin.dubois@canonical.com>
275- */
276-
277-#ifndef MIR_CLIENT_ANDROID_ANDROID_CLIENT_BUFFER_DEPOSITORY_H_
278-#define MIR_CLIENT_ANDROID_ANDROID_CLIENT_BUFFER_DEPOSITORY_H_
279-
280-#include "../client_buffer_depository.h"
281-
282-#include <stdexcept>
283-#include <map>
284-
285-namespace mir
286-{
287-namespace client
288-{
289-class ClientBuffer;
290-
291-namespace android
292-{
293-class AndroidRegistrar;
294-
295-class AndroidClientBufferDepository : public ClientBufferDepository
296-{
297-public:
298- AndroidClientBufferDepository(const std::shared_ptr<AndroidRegistrar>&);
299-
300- void deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> && package, int, geometry::Size sz, geometry::PixelFormat pf);
301-
302- std::shared_ptr<ClientBuffer> access_buffer(int id);
303-private:
304- std::shared_ptr<AndroidRegistrar> registrar;
305-
306- std::map<int, std::shared_ptr<mir::client::ClientBuffer>> buffer_depository;
307-};
308-
309-}
310-}
311-}
312-#endif /* MIR_CLIENT_ANDROID_ANDROID_CLIENT_BUFFER_DEPOSITORY_H_ */
313
314=== added file 'src/client/android/android_client_buffer_factory.cpp'
315--- src/client/android/android_client_buffer_factory.cpp 1970-01-01 00:00:00 +0000
316+++ src/client/android/android_client_buffer_factory.cpp 2013-03-24 23:57:21 +0000
317@@ -0,0 +1,35 @@
318+/*
319+ * Copyright © 2013 Canonical Ltd.
320+ *
321+ * This program is free software: you can redistribute it and/or modify
322+ * it under the terms of the GNU Lesser General Public License version 3 as
323+ * published by the Free Software Foundation.
324+ *
325+ * This program is distributed in the hope that it will be useful,
326+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
327+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
328+ * GNU General Public License for more details.
329+ *
330+ * You should have received a copy of the GNU Lesser General Public License
331+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
332+ *
333+ * Authored by:
334+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
335+ */
336+
337+#include "android_client_buffer_factory.h"
338+#include "android_client_buffer.h"
339+
340+namespace mcl=mir::client;
341+namespace mcla=mir::client::android;
342+namespace geom=mir::geometry;
343+
344+mcla::AndroidClientBufferFactory::AndroidClientBufferFactory(std::shared_ptr<AndroidRegistrar> const &buffer_registrar)
345+ : registrar(buffer_registrar)
346+{
347+}
348+
349+std::shared_ptr<mcl::ClientBuffer> mcla::AndroidClientBufferFactory::create_buffer(std::shared_ptr<mir_toolkit::MirBufferPackage> const & package, geom::Size size, geom::PixelFormat pf)
350+{
351+ return std::make_shared<mcla::AndroidClientBuffer>(registrar, package, size, pf);
352+}
353
354=== added file 'src/client/android/android_client_buffer_factory.h'
355--- src/client/android/android_client_buffer_factory.h 1970-01-01 00:00:00 +0000
356+++ src/client/android/android_client_buffer_factory.h 2013-03-24 23:57:21 +0000
357@@ -0,0 +1,55 @@
358+/*
359+ * Copyright © 2013 Canonical Ltd.
360+ *
361+ * This program is free software: you can redistribute it and/or modify
362+ * it under the terms of the GNU Lesser General Public License version 3 as
363+ * published by the Free Software Foundation.
364+ *
365+ * This program is distributed in the hope that it will be useful,
366+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
367+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
368+ * GNU General Public License for more details.
369+ *
370+ * You should have received a copy of the GNU Lesser General Public License
371+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
372+ *
373+ * Authored by:
374+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
375+ */
376+
377+#ifndef MIR_CLIENT_ANDROID_ANDROID_BUFFER_FACTORY_H_
378+#define MIR_CLIENT_ANDROID_ANDROID_BUFFER_FACTORY_H_
379+
380+#include <memory>
381+
382+#include "mir_toolkit/mir_client_library.h"
383+#include "mir/geometry/pixel_format.h"
384+#include "mir/geometry/size.h"
385+
386+#include "../client_buffer_factory.h"
387+
388+namespace mir
389+{
390+namespace client
391+{
392+class ClientBuffer;
393+
394+namespace android
395+{
396+class AndroidRegistrar;
397+
398+class AndroidClientBufferFactory : public ClientBufferFactory
399+{
400+public:
401+ explicit AndroidClientBufferFactory(std::shared_ptr<AndroidRegistrar> const &);
402+
403+ virtual std::shared_ptr<ClientBuffer> create_buffer(std::shared_ptr<mir_toolkit::MirBufferPackage> const & package,
404+ geometry::Size size, geometry::PixelFormat pf);
405+private:
406+ std::shared_ptr<AndroidRegistrar> registrar;
407+};
408+
409+}
410+}
411+}
412+#endif /* MIR_CLIENT_ANDROID_ANDROID_BUFFER_FACTORY_H_ */
413
414=== modified file 'src/client/android/android_client_platform.cpp'
415--- src/client/android/android_client_platform.cpp 2013-03-13 04:54:15 +0000
416+++ src/client/android/android_client_platform.cpp 2013-03-24 23:57:21 +0000
417@@ -19,7 +19,7 @@
418 #include "mir_native_window.h"
419 #include "android_client_platform.h"
420 #include "android_registrar_gralloc.h"
421-#include "android_client_buffer_depository.h"
422+#include "android_client_buffer_factory.h"
423 #include "client_surface_interpreter.h"
424 #include "../mir_connection.h"
425 #include "../native_client_platform_factory.h"
426@@ -36,7 +36,7 @@
427
428 struct EmptyDeleter
429 {
430- void operator()(void* )
431+ void operator()(void*)
432 {
433 }
434 };
435@@ -49,7 +49,7 @@
436 return std::make_shared<mcla::AndroidClientPlatform>();
437 }
438
439-std::shared_ptr<mcl::ClientBufferDepository> mcla::AndroidClientPlatform::create_platform_depository()
440+std::shared_ptr<mcl::ClientBufferFactory> mcla::AndroidClientPlatform::create_buffer_factory()
441 {
442 const hw_module_t *hw_module;
443 int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module);
444@@ -63,7 +63,7 @@
445 EmptyDeleter empty_del;
446 auto gralloc_dev = std::shared_ptr<gralloc_module_t>(gr_dev, empty_del);
447 auto registrar = std::make_shared<mcla::AndroidRegistrarGralloc>(gralloc_dev);
448- return std::make_shared<mcla::AndroidClientBufferDepository>(registrar);
449+ return std::make_shared<mcla::AndroidClientBufferFactory>(registrar);
450 }
451
452 namespace
453@@ -73,7 +73,7 @@
454 MirNativeWindowDeleter(mcla::MirNativeWindow* window)
455 : window(window) {}
456
457- void operator()(EGLNativeWindowType* type )
458+ void operator()(EGLNativeWindowType* type)
459 {
460 delete type;
461 delete window;
462
463=== modified file 'src/client/android/android_client_platform.h'
464--- src/client/android/android_client_platform.h 2013-03-13 04:54:15 +0000
465+++ src/client/android/android_client_platform.h 2013-03-24 23:57:21 +0000
466@@ -32,7 +32,7 @@
467 class AndroidClientPlatform : public ClientPlatform
468 {
469 public:
470- std::shared_ptr<ClientBufferDepository> create_platform_depository ();
471+ std::shared_ptr<ClientBufferFactory> create_buffer_factory();
472 std::shared_ptr<EGLNativeWindowType> create_egl_native_window(ClientSurface *surface);
473 std::shared_ptr<EGLNativeDisplayType> create_egl_native_display();
474 };
475
476=== modified file 'src/client/client_buffer.h'
477--- src/client/client_buffer.h 2013-03-21 03:32:59 +0000
478+++ src/client/client_buffer.h 2013-03-24 23:57:21 +0000
479@@ -53,6 +53,9 @@
480 virtual geometry::Size size() const = 0;
481 virtual geometry::Stride stride() const = 0;
482 virtual geometry::PixelFormat pixel_format() const = 0;
483+ virtual uint32_t age() const = 0;
484+ virtual void increment_age() = 0;
485+ virtual void mark_as_submitted() = 0;
486
487 virtual MirNativeBuffer get_native_handle() = 0;
488 virtual std::shared_ptr<mir_toolkit::MirBufferPackage> get_buffer_package() const = 0;
489
490=== added file 'src/client/client_buffer_depository.cpp'
491--- src/client/client_buffer_depository.cpp 1970-01-01 00:00:00 +0000
492+++ src/client/client_buffer_depository.cpp 2013-03-24 23:57:21 +0000
493@@ -0,0 +1,77 @@
494+/*
495+ * Copyright © 2013 Canonical Ltd.
496+ *
497+ * This program is free software: you can redistribute it and/or modify
498+ * it under the terms of the GNU Lesser General Public License version 3 as
499+ * published by the Free Software Foundation.
500+ *
501+ * This program is distributed in the hope that it will be useful,
502+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
503+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
504+ * GNU General Public License for more details.
505+ *
506+ * You should have received a copy of the GNU Lesser General Public License
507+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
508+ *
509+ * Authored by:
510+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
511+ */
512+
513+#include "client_buffer.h"
514+#include "client_buffer_factory.h"
515+#include "client_buffer_depository.h"
516+
517+#include <stdexcept>
518+#include <memory>
519+#include <map>
520+
521+namespace mcl=mir::client;
522+
523+mcl::ClientBufferDepository::ClientBufferDepository(std::shared_ptr<ClientBufferFactory> const &factory, int max_buffers)
524+ : factory(factory),
525+ current_buffer_iter(buffers.end()),
526+ max_age(max_buffers - 1)
527+{
528+}
529+
530+void mcl::ClientBufferDepository::deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> const & package, int id, geometry::Size size, geometry::PixelFormat pf)
531+{
532+ for (auto next = buffers.begin(); next != buffers.end();)
533+ {
534+ // C++ guarantees that buffers.erase() will only invalidate the iterator we
535+ // erase. Move to the next buffer before we potentially invalidate our iterator.
536+ auto current = next;
537+ next++;
538+
539+ if (current != current_buffer_iter &&
540+ current->first != id &&
541+ current->second->age() >= max_age)
542+ {
543+ buffers.erase(current);
544+ }
545+ }
546+
547+ for (auto& current : buffers)
548+ {
549+ current.second->increment_age();
550+ }
551+
552+ if (current_buffer_iter != buffers.end())
553+ {
554+ current_buffer_iter->second->mark_as_submitted();
555+ }
556+
557+ current_buffer_iter = buffers.find(id);
558+
559+ if (current_buffer_iter == buffers.end())
560+ {
561+ auto new_buffer = factory->create_buffer(package, size, pf);
562+
563+ current_buffer_iter = buffers.insert(current_buffer_iter, std::make_pair(id, new_buffer));
564+ }
565+}
566+
567+std::shared_ptr<mcl::ClientBuffer> mcl::ClientBufferDepository::current_buffer()
568+{
569+ return current_buffer_iter->second;
570+}
571
572=== modified file 'src/client/client_buffer_depository.h'
573--- src/client/client_buffer_depository.h 2013-03-21 03:32:59 +0000
574+++ src/client/client_buffer_depository.h 2013-03-24 23:57:21 +0000
575@@ -1,9 +1,9 @@
576 /*
577 * Copyright © 2012 Canonical Ltd.
578 *
579- * This program is free software: you can redistribute it and/or modify it
580- * under the terms of the GNU Lesser General Public License version 3,
581- * as published by the Free Software Foundation.
582+ * This program is free software: you can redistribute it and/or modify
583+ * it under the terms of the GNU Lesser General Public License version 3 as
584+ * published by the Free Software Foundation.
585 *
586 * This program is distributed in the hope that it will be useful,
587 * but WITHOUT ANY WARRANTY; without even the implied warranty of
588@@ -20,7 +20,9 @@
589 #ifndef MIR_CLIENT_PRIVATE_MIR_CLIENT_BUFFER_DEPOSITORY_H_
590 #define MIR_CLIENT_PRIVATE_MIR_CLIENT_BUFFER_DEPOSITORY_H_
591
592+#include <map>
593 #include <memory>
594+
595 #include "mir/geometry/pixel_format.h"
596 #include "mir/geometry/size.h"
597
598@@ -28,19 +30,39 @@
599 {
600 struct MirBufferPackage;
601 }
602+
603 namespace mir
604 {
605
606 namespace client
607 {
608 class ClientBuffer;
609-
610+class ClientBufferFactory;
611+
612+/// Responsible for taking the buffer data sent from the server and wrapping it in a ClientBuffer
613+
614+/// The ClientBufferDepository is responsible for taking the IPC buffer data and converting it into
615+/// the more digestible form of a ClientBuffer. It maintains the client-side state necessary to
616+/// construct a ClientBuffer.
617 class ClientBufferDepository
618 {
619 public:
620- virtual void deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> &&, int id,
621- geometry::Size, geometry::PixelFormat) = 0;
622- virtual std::shared_ptr<ClientBuffer> access_buffer(int id) = 0;
623+ ClientBufferDepository(std::shared_ptr<ClientBufferFactory> const &factory, int max_buffers);
624+
625+ /// Construct a ClientBuffer from the IPC data, and use it as the current buffer.
626+
627+ /// This also marks the previous current buffer (if any) as being submitted to the server.
628+ /// \post current_buffer() will return a ClientBuffer constructed from this IPC data.
629+ void deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> const &, int id,
630+ geometry::Size, geometry::PixelFormat);
631+ std::shared_ptr<ClientBuffer> current_buffer();
632+
633+private:
634+ std::shared_ptr<ClientBufferFactory> const factory;
635+ typedef std::map<int, std::shared_ptr<ClientBuffer>> BufferMap;
636+ BufferMap buffers;
637+ BufferMap::iterator current_buffer_iter;
638+ const unsigned max_age;
639 };
640 }
641 }
642
643=== added file 'src/client/client_buffer_factory.h'
644--- src/client/client_buffer_factory.h 1970-01-01 00:00:00 +0000
645+++ src/client/client_buffer_factory.h 2013-03-24 23:57:21 +0000
646@@ -0,0 +1,44 @@
647+/*
648+ * Copyright © 2013 Canonical Ltd.
649+ *
650+ * This program is free software: you can redistribute it and/or modify
651+ * it under the terms of the GNU Lesser General Public License version 3 as
652+ * published by the Free Software Foundation.
653+ *
654+ * This program is distributed in the hope that it will be useful,
655+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
656+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
657+ * GNU General Public License for more details.
658+ *
659+ * You should have received a copy of the GNU Lesser General Public License
660+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
661+ *
662+ * Authored by:
663+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
664+ */
665+
666+#ifndef MIR_CLIENT_CLIENT_BUFFER_FACTORY_H_
667+#define MIR_CLIENT_CLIENT_BUFFER_FACTORY_H_
668+
669+#include <memory>
670+
671+#include "mir_toolkit/mir_client_library.h"
672+#include "mir/geometry/pixel_format.h"
673+#include "mir/geometry/size.h"
674+
675+namespace mir
676+{
677+namespace client
678+{
679+class ClientBuffer;
680+
681+class ClientBufferFactory
682+{
683+public:
684+ virtual std::shared_ptr<ClientBuffer> create_buffer(std::shared_ptr<mir_toolkit::MirBufferPackage> const & package,
685+ geometry::Size size, geometry::PixelFormat pf) = 0;
686+};
687+
688+}
689+}
690+#endif /* MIR_CLIENT_CLIENT_BUFFER_FACTORY_H_ */
691
692=== modified file 'src/client/client_platform.h'
693--- src/client/client_platform.h 2013-03-13 04:54:15 +0000
694+++ src/client/client_platform.h 2013-03-24 23:57:21 +0000
695@@ -25,7 +25,7 @@
696 {
697 namespace client
698 {
699-class ClientBufferDepository;
700+class ClientBufferFactory;
701 class ClientSurface;
702 class ClientContext;
703
704@@ -36,7 +36,7 @@
705 ClientPlatform(const ClientPlatform& p) = delete;
706 ClientPlatform& operator=(const ClientPlatform& p) = delete;
707
708- virtual std::shared_ptr<ClientBufferDepository> create_platform_depository () = 0;
709+ virtual std::shared_ptr<ClientBufferFactory> create_buffer_factory () = 0;
710 virtual std::shared_ptr<EGLNativeWindowType> create_egl_native_window(ClientSurface *surface) = 0;
711 virtual std::shared_ptr<EGLNativeDisplayType> create_egl_native_display() = 0;
712 };
713
714=== modified file 'src/client/gbm/gbm_client_buffer.cpp'
715--- src/client/gbm/gbm_client_buffer.cpp 2013-03-22 10:34:16 +0000
716+++ src/client/gbm/gbm_client_buffer.cpp 2013-03-24 23:57:21 +0000
717@@ -128,11 +128,11 @@
718
719 mclg::GBMClientBuffer::GBMClientBuffer(
720 std::shared_ptr<mclg::DRMFDHandler> const& drm_fd_handler,
721- std::shared_ptr<mir_toolkit::MirBufferPackage> && package,
722+ std::shared_ptr<mir_toolkit::MirBufferPackage> const& package,
723 geom::Size size, geom::PixelFormat pf)
724 : drm_fd_handler{drm_fd_handler},
725 creation_package(std::move(package)),
726- rect({{geom::X(0),geom::Y(0)}, size}),
727+ rect({{geom::X(0), geom::Y(0)}, size}),
728 buffer_pf{pf}
729 {
730 }
731@@ -165,6 +165,7 @@
732
733 std::shared_ptr<mir_toolkit::MirBufferPackage> mclg::GBMClientBuffer::get_buffer_package() const
734 {
735+ creation_package->age = age();
736 return creation_package;
737 }
738
739
740=== modified file 'src/client/gbm/gbm_client_buffer.h'
741--- src/client/gbm/gbm_client_buffer.h 2013-03-22 10:34:16 +0000
742+++ src/client/gbm/gbm_client_buffer.h 2013-03-24 23:57:21 +0000
743@@ -20,7 +20,7 @@
744 #ifndef MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_H_
745 #define MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_H_
746
747-#include "../client_buffer.h"
748+#include "../aging_buffer.h"
749 #include "mir_toolkit/mir_client_library.h"
750 #include "mir/geometry/rectangle.h"
751
752@@ -35,11 +35,11 @@
753
754 class DRMFDHandler;
755
756-class GBMClientBuffer : public ClientBuffer
757+class GBMClientBuffer : public AgingBuffer
758 {
759 public:
760 GBMClientBuffer(std::shared_ptr<DRMFDHandler> const& drm_fd_handler,
761- std::shared_ptr<mir_toolkit::MirBufferPackage>&& buffer_package,
762+ std::shared_ptr<mir_toolkit::MirBufferPackage> const& buffer_package,
763 geometry::Size size,
764 geometry::PixelFormat pf);
765
766@@ -52,7 +52,6 @@
767
768 GBMClientBuffer(const GBMClientBuffer&) = delete;
769 GBMClientBuffer& operator=(const GBMClientBuffer&) = delete;
770-
771 private:
772 const std::shared_ptr<DRMFDHandler> drm_fd_handler;
773 const std::shared_ptr<mir_toolkit::MirBufferPackage> creation_package;
774
775=== removed file 'src/client/gbm/gbm_client_buffer_depository.cpp'
776--- src/client/gbm/gbm_client_buffer_depository.cpp 2013-03-13 04:54:15 +0000
777+++ src/client/gbm/gbm_client_buffer_depository.cpp 1970-01-01 00:00:00 +0000
778@@ -1,44 +0,0 @@
779-/*
780- * Copyright © 2012 Canonical Ltd.
781- *
782- * This program is free software: you can redistribute it and/or modify it
783- * under the terms of the GNU Lesser General Public License version 3,
784- * as published by the Free Software Foundation.
785- *
786- * This program is distributed in the hope that it will be useful,
787- * but WITHOUT ANY WARRANTY; without even the implied warranty of
788- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
789- * GNU General Public License for more details.
790- *
791- * You should have received a copy of the GNU Lesser General Public License
792- * along with this program. If not, see <http://www.gnu.org/licenses/>.
793- *
794- * Authored by:
795- * Kevin DuBois <kevin.dubois@canonical.com>
796- */
797-
798-#include "gbm_client_buffer_depository.h"
799-#include "gbm_client_buffer.h"
800-
801-#include <stdexcept>
802-#include <map>
803-
804-namespace mcl=mir::client;
805-namespace mclg=mir::client::gbm;
806-
807-mclg::GBMClientBufferDepository::GBMClientBufferDepository(
808- std::shared_ptr<DRMFDHandler> const& drm_fd_handler)
809- : drm_fd_handler{drm_fd_handler}
810-{
811-}
812-
813-void mclg::GBMClientBufferDepository::deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage>&& package, int, geometry::Size size, geometry::PixelFormat pf)
814-{
815- buffer = std::make_shared<mclg::GBMClientBuffer>(drm_fd_handler, std::move(package), size, pf);
816-}
817-
818-std::shared_ptr<mcl::ClientBuffer> mclg::GBMClientBufferDepository::access_buffer(int)
819-{
820- return buffer;
821-}
822-
823
824=== removed file 'src/client/gbm/gbm_client_buffer_depository.h'
825--- src/client/gbm/gbm_client_buffer_depository.h 2013-03-13 04:54:15 +0000
826+++ src/client/gbm/gbm_client_buffer_depository.h 1970-01-01 00:00:00 +0000
827@@ -1,55 +0,0 @@
828-/*
829- * Copyright © 2012 Canonical Ltd.
830- *
831- * This program is free software: you can redistribute it and/or modify it
832- * under the terms of the GNU Lesser General Public License version 3,
833- * as published by the Free Software Foundation.
834- *
835- * This program is distributed in the hope that it will be useful,
836- * but WITHOUT ANY WARRANTY; without even the implied warranty of
837- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
838- * GNU General Public License for more details.
839- *
840- * You should have received a copy of the GNU Lesser General Public License
841- * along with this program. If not, see <http://www.gnu.org/licenses/>.
842- *
843- * Authored by:
844- * Kevin DuBois <kevin.dubois@canonical.com>
845- */
846-
847-#ifndef MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_DEPOSITORY_H_
848-#define MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_DEPOSITORY_H_
849-
850-#include "../client_buffer_depository.h"
851-
852-#include <stdexcept>
853-#include <map>
854-
855-namespace mir
856-{
857-namespace client
858-{
859-class ClientBuffer;
860-
861-namespace gbm
862-{
863-
864-class DRMFDHandler;
865-
866-class GBMClientBufferDepository : public ClientBufferDepository
867-{
868-public:
869- GBMClientBufferDepository(std::shared_ptr<DRMFDHandler> const& drm_fd_handler);
870-
871- void deposit_package(std::shared_ptr<mir_toolkit::MirBufferPackage> && package, int, geometry::Size size, geometry::PixelFormat pf);
872-
873- std::shared_ptr<ClientBuffer> access_buffer(int id);
874-private:
875- std::shared_ptr<ClientBuffer> buffer;
876- std::shared_ptr<DRMFDHandler> drm_fd_handler;
877-};
878-
879-}
880-}
881-}
882-#endif /* MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_DEPOSITORY_H_ */
883
884=== added file 'src/client/gbm/gbm_client_buffer_factory.cpp'
885--- src/client/gbm/gbm_client_buffer_factory.cpp 1970-01-01 00:00:00 +0000
886+++ src/client/gbm/gbm_client_buffer_factory.cpp 2013-03-24 23:57:21 +0000
887@@ -0,0 +1,35 @@
888+/*
889+ * Copyright © 2013 Canonical Ltd.
890+ *
891+ * This program is free software: you can redistribute it and/or modify
892+ * it under the terms of the GNU Lesser General Public License version 3 as
893+ * published by the Free Software Foundation.
894+ *
895+ * This program is distributed in the hope that it will be useful,
896+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
897+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
898+ * GNU General Public License for more details.
899+ *
900+ * You should have received a copy of the GNU Lesser General Public License
901+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
902+ *
903+ * Authored by:
904+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
905+ */
906+
907+#include "gbm_client_buffer_factory.h"
908+#include "gbm_client_buffer.h"
909+
910+namespace mcl=mir::client;
911+namespace mclg=mir::client::gbm;
912+
913+mclg::GBMClientBufferFactory::GBMClientBufferFactory(
914+ std::shared_ptr<DRMFDHandler> const& drm_fd_handler)
915+ : drm_fd_handler{drm_fd_handler}
916+{
917+}
918+
919+std::shared_ptr<mcl::ClientBuffer> mclg::GBMClientBufferFactory::create_buffer(std::shared_ptr<mir_toolkit::MirBufferPackage> const & package, geometry::Size size, geometry::PixelFormat pf)
920+{
921+ return std::make_shared<mclg::GBMClientBuffer>(drm_fd_handler, package, size, pf);
922+}
923
924=== added file 'src/client/gbm/gbm_client_buffer_factory.h'
925--- src/client/gbm/gbm_client_buffer_factory.h 1970-01-01 00:00:00 +0000
926+++ src/client/gbm/gbm_client_buffer_factory.h 2013-03-24 23:57:21 +0000
927@@ -0,0 +1,51 @@
928+/*
929+ * Copyright © 2013 Canonical Ltd.
930+ *
931+ * This program is free software: you can redistribute it and/or modify
932+ * it under the terms of the GNU Lesser General Public License version 3 as
933+ * published by the Free Software Foundation.
934+ *
935+ * This program is distributed in the hope that it will be useful,
936+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
937+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
938+ * GNU General Public License for more details.
939+ *
940+ * You should have received a copy of the GNU Lesser General Public License
941+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
942+ *
943+ * Authored by:
944+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
945+ */
946+
947+#ifndef MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_FACTORY_H_
948+#define MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_FACTORY_H_
949+
950+#include "../client_buffer_factory.h"
951+#include "gbm_client_buffer.h"
952+
953+namespace mir
954+{
955+namespace client
956+{
957+class ClientBuffer;
958+
959+namespace gbm
960+{
961+
962+class DRMFDHandler;
963+
964+class GBMClientBufferFactory : public ClientBufferFactory
965+{
966+public:
967+ explicit GBMClientBufferFactory(std::shared_ptr<DRMFDHandler> const& drm_fd_handler);
968+
969+ std::shared_ptr<ClientBuffer> create_buffer(std::shared_ptr<mir_toolkit::MirBufferPackage> const & package,
970+ geometry::Size size, geometry::PixelFormat pf);
971+private:
972+ std::shared_ptr<DRMFDHandler> drm_fd_handler;
973+};
974+
975+}
976+}
977+}
978+#endif /* MIR_CLIENT_GBM_GBM_CLIENT_BUFFER_FACTORY_H_ */
979
980=== modified file 'src/client/gbm/gbm_client_platform.cpp'
981--- src/client/gbm/gbm_client_platform.cpp 2013-03-22 10:34:16 +0000
982+++ src/client/gbm/gbm_client_platform.cpp 2013-03-24 23:57:21 +0000
983@@ -18,10 +18,11 @@
984
985 #include "mir_toolkit/mir_client_library.h"
986 #include "gbm_client_platform.h"
987-#include "gbm_client_buffer_depository.h"
988+#include "gbm_client_buffer_factory.h"
989 #include "mesa_native_display_container.h"
990 #include "drm_fd_handler.h"
991 #include "../mir_connection.h"
992+#include "../client_buffer_factory.h"
993 #include "../native_client_platform_factory.h"
994
995 #include <xf86drm.h>
996@@ -106,9 +107,9 @@
997 {
998 }
999
1000-std::shared_ptr<mcl::ClientBufferDepository> mclg::GBMClientPlatform::create_platform_depository()
1001+std::shared_ptr<mcl::ClientBufferFactory> mclg::GBMClientPlatform::create_buffer_factory()
1002 {
1003- return std::make_shared<mclg::GBMClientBufferDepository>(drm_fd_handler);
1004+ return std::make_shared<mclg::GBMClientBufferFactory>(drm_fd_handler);
1005 }
1006
1007 std::shared_ptr<EGLNativeWindowType> mclg::GBMClientPlatform::create_egl_native_window(ClientSurface* client_surface)
1008
1009=== modified file 'src/client/gbm/gbm_client_platform.h'
1010--- src/client/gbm/gbm_client_platform.h 2013-03-22 10:34:16 +0000
1011+++ src/client/gbm/gbm_client_platform.h 2013-03-24 23:57:21 +0000
1012@@ -39,7 +39,7 @@
1013 std::shared_ptr<DRMFDHandler> const& drm_fd_handler,
1014 EGLNativeDisplayContainer& display_container);
1015
1016- std::shared_ptr<ClientBufferDepository> create_platform_depository ();
1017+ std::shared_ptr<ClientBufferFactory> create_buffer_factory ();
1018 std::shared_ptr<EGLNativeWindowType> create_egl_native_window(ClientSurface *surface);
1019 std::shared_ptr<EGLNativeDisplayType> create_egl_native_display();
1020
1021
1022=== modified file 'src/client/mir_connection.cpp'
1023--- src/client/mir_connection.cpp 2013-03-13 04:54:15 +0000
1024+++ src/client/mir_connection.cpp 2013-03-24 23:57:21 +0000
1025@@ -66,7 +66,7 @@
1026 mir_surface_lifecycle_callback callback,
1027 void * context)
1028 {
1029- auto depository = platform->create_platform_depository();
1030+ auto depository = std::make_shared<mir::client::ClientBufferDepository>(platform->create_buffer_factory(), 3);
1031 auto null_log = std::make_shared<mir::client::NullLogger>();
1032 auto surface = new MirSurface(this, server, null_log, depository, params, callback, context);
1033 return surface->get_create_wait_handle();
1034@@ -187,8 +187,8 @@
1035 is a kludge until we have a better story about the lifetime of MirWaitHandles */
1036 {
1037 std::lock_guard<std::mutex> lock(release_wait_handle_guard);
1038- for(auto it = release_wait_handles.begin(); it != release_wait_handles.end(); it++)
1039- delete *it;
1040+ for (auto handle : release_wait_handles)
1041+ delete handle;
1042 }
1043
1044 disconnect_wait_handle.result_received();
1045
1046=== modified file 'src/client/mir_surface.cpp'
1047--- src/client/mir_surface.cpp 2013-03-22 10:34:16 +0000
1048+++ src/client/mir_surface.cpp 2013-03-24 23:57:21 +0000
1049@@ -38,7 +38,6 @@
1050 mir_surface_lifecycle_callback callback, void * context)
1051 : server(server),
1052 connection(allocating_connection),
1053- last_buffer_id(-1),
1054 buffer_depository(depository),
1055 logger(logger)
1056 {
1057@@ -92,7 +91,7 @@
1058
1059 void mir_toolkit::MirSurface::get_cpu_region(MirGraphicsRegion& region_out)
1060 {
1061- auto buffer = buffer_depository->access_buffer(last_buffer_id);
1062+ auto buffer = buffer_depository->current_buffer();
1063
1064 secured_region = buffer->secure_for_cpu_write();
1065 region_out.width = secured_region->width.as_uint32_t();
1066@@ -129,9 +128,9 @@
1067
1068 /* todo: all these conversion functions are a bit of a kludge, probably
1069 better to have a more developed geometry::PixelFormat that can handle this */
1070-geom::PixelFormat mir_toolkit::MirSurface::convert_ipc_pf_to_geometry(gp::int32 pf )
1071+geom::PixelFormat mir_toolkit::MirSurface::convert_ipc_pf_to_geometry(gp::int32 pf)
1072 {
1073- if ( pf == mir_pixel_format_abgr_8888 )
1074+ if (pf == mir_pixel_format_abgr_8888)
1075 return geom::PixelFormat::abgr_8888;
1076 return geom::PixelFormat::invalid;
1077 }
1078@@ -139,7 +138,6 @@
1079 void mir_toolkit::MirSurface::process_incoming_buffer()
1080 {
1081 auto const& buffer = surface.buffer();
1082- last_buffer_id = buffer.buffer_id();
1083
1084 auto surface_width = geom::Width(surface.width());
1085 auto surface_height = geom::Height(surface.height());
1086@@ -152,7 +150,7 @@
1087 try
1088 {
1089 buffer_depository->deposit_package(std::move(ipc_package),
1090- last_buffer_id,
1091+ buffer.buffer_id(),
1092 surface_size, surface_pf);
1093 } catch (const std::runtime_error& err)
1094 {
1095@@ -188,13 +186,13 @@
1096
1097 std::shared_ptr<mir_toolkit::MirBufferPackage> mir_toolkit::MirSurface::get_current_buffer_package()
1098 {
1099- auto buffer = buffer_depository->access_buffer(last_buffer_id);
1100+ auto buffer = buffer_depository->current_buffer();
1101 return buffer->get_buffer_package();
1102 }
1103
1104 std::shared_ptr<mcl::ClientBuffer> mir_toolkit::MirSurface::get_current_buffer()
1105 {
1106- return buffer_depository->access_buffer(last_buffer_id);
1107+ return buffer_depository->current_buffer();
1108 }
1109
1110 void mir_toolkit::MirSurface::populate(MirBufferPackage& buffer_package)
1111
1112=== modified file 'src/client/mir_surface.h'
1113--- src/client/mir_surface.h 2013-03-22 10:34:16 +0000
1114+++ src/client/mir_surface.h 2013-03-24 23:57:21 +0000
1115@@ -82,7 +82,7 @@
1116 void populate(MirBufferPackage& buffer_package);
1117 void created(mir_surface_lifecycle_callback callback, void * context);
1118 void new_buffer(mir_surface_lifecycle_callback callback, void * context);
1119- mir::geometry::PixelFormat convert_ipc_pf_to_geometry(google::protobuf::int32 pf );
1120+ mir::geometry::PixelFormat convert_ipc_pf_to_geometry(google::protobuf::int32 pf);
1121
1122 /* todo: race condition. protobuf does not guarantee that callbacks will be synchronized. potential
1123 race in surface, last_buffer_id */
1124@@ -95,8 +95,6 @@
1125 MirWaitHandle next_buffer_wait_handle;
1126 MirWaitHandle configure_wait_handle;
1127
1128- int last_buffer_id;
1129-
1130 std::shared_ptr<mir::client::MemoryRegion> secured_region;
1131 std::shared_ptr<mir::client::ClientBufferDepository> buffer_depository;
1132
1133
1134=== modified file 'tests/unit-tests/client/CMakeLists.txt'
1135--- tests/unit-tests/client/CMakeLists.txt 2013-03-22 10:34:16 +0000
1136+++ tests/unit-tests/client/CMakeLists.txt 2013-03-24 23:57:21 +0000
1137@@ -1,5 +1,7 @@
1138 list(APPEND UNIT_TEST_SOURCES
1139+ ${CMAKE_CURRENT_SOURCE_DIR}/test_aging_buffer.cpp
1140 ${CMAKE_CURRENT_SOURCE_DIR}/test_client.cpp
1141+ ${CMAKE_CURRENT_SOURCE_DIR}/test_client_buffer_depository.cpp
1142 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_platform.cpp
1143 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_mir_surface.cpp
1144 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_connection.cpp
1145
1146=== modified file 'tests/unit-tests/client/android/CMakeLists.txt'
1147--- tests/unit-tests/client/android/CMakeLists.txt 2013-03-14 18:35:31 +0000
1148+++ tests/unit-tests/client/android/CMakeLists.txt 2013-03-24 23:57:21 +0000
1149@@ -19,7 +19,6 @@
1150 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_android_buffer.cpp
1151 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_android_registrar.cpp
1152 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_native_window.cpp
1153- ${CMAKE_CURRENT_SOURCE_DIR}/test_android_client_depository.cpp
1154 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_client_platform.cpp
1155 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_surface_interpreter.cpp
1156 ${CMAKE_CURRENT_SOURCE_DIR}/test_android_syncfence.cpp
1157
1158=== removed file 'tests/unit-tests/client/android/test_android_client_depository.cpp'
1159--- tests/unit-tests/client/android/test_android_client_depository.cpp 2013-03-22 10:34:16 +0000
1160+++ tests/unit-tests/client/android/test_android_client_depository.cpp 1970-01-01 00:00:00 +0000
1161@@ -1,169 +0,0 @@
1162-/*
1163- * Copyright © 2012 Canonical Ltd.
1164- *
1165- * This program is free software: you can redistribute it and/or modify
1166- * it under the terms of the GNU General Public License version 3 as
1167- * published by the Free Software Foundation.
1168- *
1169- * This program is distributed in the hope that it will be useful,
1170- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1171- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1172- * GNU General Public License for more details.
1173- *
1174- * You should have received a copy of the GNU General Public License
1175- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1176- *
1177- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1178- */
1179-
1180-#include "mir_toolkit/mir_client_library.h"
1181-#include "src/client/android/android_client_buffer_depository.h"
1182-#include "src/client/android/android_client_buffer.h"
1183-#include "mir_test_doubles/mock_android_registrar.h"
1184-
1185-#include <gtest/gtest.h>
1186-
1187-namespace geom = mir::geometry;
1188-namespace mcla = mir::client::android;
1189-namespace mt = mir::test;
1190-namespace mtd = mir::test::doubles;
1191-
1192-
1193-struct MirBufferDepositoryTest : public testing::Test
1194-{
1195- void SetUp()
1196- {
1197- width = geom::Width(12);
1198- height =geom::Height(14);
1199- size = geom::Size{width, height};
1200- pf = geom::PixelFormat::abgr_8888;
1201-
1202- mock_registrar = std::make_shared<mtd::MockAndroidRegistrar>();
1203- package1 = std::make_shared<MirBufferPackage>();
1204- package2 = std::make_shared<MirBufferPackage>();
1205-
1206- }
1207- geom::Width width;
1208- geom::Height height;
1209- geom::PixelFormat pf;
1210- geom::Size size;
1211-
1212- std::shared_ptr<mtd::MockAndroidRegistrar> mock_registrar;
1213-
1214- std::shared_ptr<MirBufferPackage> package1;
1215- std::shared_ptr<MirBufferPackage> package2;
1216-
1217-};
1218-
1219-TEST_F(MirBufferDepositoryTest, depository_sets_width_and_height)
1220-{
1221- using namespace testing;
1222-
1223- mcla::AndroidClientBufferDepository depository(mock_registrar);
1224-
1225- EXPECT_CALL(*mock_registrar, register_buffer(_))
1226- .Times(1);
1227- EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1228- .Times(1);
1229-
1230- depository.deposit_package(std::move(package1), 8, size, pf);
1231- auto buffer = depository.access_buffer(8);
1232-
1233- EXPECT_EQ(buffer->size().height, height);
1234- EXPECT_EQ(buffer->size().width, width);
1235- EXPECT_EQ(buffer->pixel_format(), pf);
1236-}
1237-
1238-TEST_F(MirBufferDepositoryTest, depository_does_not_create_a_buffer_its_seen_before )
1239-{
1240- using namespace testing;
1241-
1242- mcla::AndroidClientBufferDepository depository(mock_registrar);
1243-
1244- EXPECT_CALL(*mock_registrar, register_buffer(_))
1245- .Times(1);
1246- EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1247- .Times(1);
1248-
1249- /* repeated id */
1250- depository.deposit_package(std::move(package1), 8, size, pf);
1251- depository.deposit_package(std::move(package2), 8, size, pf);
1252-}
1253-
1254-TEST_F(MirBufferDepositoryTest, depository_creates_two_buffers_with_distinct_id )
1255-{
1256- using namespace testing;
1257-
1258- mcla::AndroidClientBufferDepository depository(mock_registrar);
1259-
1260- EXPECT_CALL(*mock_registrar, register_buffer(_))
1261- .Times(2);
1262- EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1263- .Times(2);
1264-
1265- /* repeated id */
1266- depository.deposit_package(std::move(package1), 8, size, pf);
1267- depository.deposit_package(std::move(package2), 9, size, pf);
1268-}
1269-
1270-TEST_F(MirBufferDepositoryTest, depository_returns_same_accessed_buffer_for_same_id )
1271-{
1272- using namespace testing;
1273-
1274- mcla::AndroidClientBufferDepository depository(mock_registrar);
1275-
1276- EXPECT_CALL(*mock_registrar, register_buffer(_))
1277- .Times(2);
1278- EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1279- .Times(2);
1280-
1281- /* repeated id */
1282- depository.deposit_package(std::move(package1), 8, size, pf);
1283- depository.deposit_package(std::move(package2), 9, size, pf);
1284-
1285- auto buffer1 = depository.access_buffer(8);
1286- auto buffer2 = depository.access_buffer(8);
1287-
1288- EXPECT_EQ(buffer1, buffer2);
1289-}
1290-
1291-TEST_F(MirBufferDepositoryTest, depository_returns_different_accessed_buffer_for_unique_id )
1292-{
1293- using namespace testing;
1294-
1295- mcla::AndroidClientBufferDepository depository(mock_registrar);
1296-
1297- EXPECT_CALL(*mock_registrar, register_buffer(_))
1298- .Times(2);
1299- EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1300- .Times(2);
1301-
1302- /* repeated id */
1303- depository.deposit_package(std::move(package1), 8, size, pf);
1304- depository.deposit_package(std::move(package2), 9, size, pf);
1305-
1306- auto buffer1 = depository.access_buffer(8);
1307- auto buffer2 = depository.access_buffer(9);
1308-
1309- EXPECT_NE(buffer1, buffer2);
1310-}
1311-
1312-TEST_F(MirBufferDepositoryTest, depository_throws_for_uncreated_id )
1313-{
1314- using namespace testing;
1315-
1316- mcla::AndroidClientBufferDepository depository(mock_registrar);
1317-
1318- EXPECT_CALL(*mock_registrar, register_buffer(_))
1319- .Times(1);
1320- EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1321- .Times(1);
1322-
1323- /* repeated id */
1324- depository.deposit_package(std::move(package1), 8, size, pf);
1325-
1326- EXPECT_THROW({
1327- auto buffer2 = depository.access_buffer(9);
1328- }, std::runtime_error);
1329-
1330-}
1331
1332=== modified file 'tests/unit-tests/client/android/test_client_surface_interpreter.cpp'
1333--- tests/unit-tests/client/android/test_client_surface_interpreter.cpp 2013-03-22 10:34:16 +0000
1334+++ tests/unit-tests/client/android/test_client_surface_interpreter.cpp 2013-03-24 23:57:21 +0000
1335@@ -42,6 +42,10 @@
1336 MOCK_CONST_METHOD0(stride, geom::Stride());
1337 MOCK_CONST_METHOD0(pixel_format, geom::PixelFormat());
1338
1339+ MOCK_CONST_METHOD0(age, uint32_t());
1340+ MOCK_METHOD0(mark_as_submitted, void());
1341+ MOCK_METHOD0(increment_age, void());
1342+
1343 MOCK_CONST_METHOD0(get_buffer_package, std::shared_ptr<MirBufferPackage>());
1344 MOCK_METHOD0(get_native_handle, ANativeWindowBuffer*());
1345
1346
1347=== modified file 'tests/unit-tests/client/gbm/CMakeLists.txt'
1348--- tests/unit-tests/client/gbm/CMakeLists.txt 2013-03-13 01:01:01 +0000
1349+++ tests/unit-tests/client/gbm/CMakeLists.txt 2013-03-24 23:57:21 +0000
1350@@ -16,7 +16,6 @@
1351 # Alan Griffiths <alan@octopull.co.uk>
1352
1353 list(APPEND UNIT_TEST_SOURCES
1354- ${CMAKE_CURRENT_SOURCE_DIR}/test_gbm_client_depository.cpp
1355 ${CMAKE_CURRENT_SOURCE_DIR}/test_gbm_client_buffer.cpp
1356 ${CMAKE_CURRENT_SOURCE_DIR}/test_gbm_client_platform.cpp
1357 ${CMAKE_CURRENT_SOURCE_DIR}/test_mesa_native_display_container.cpp
1358
1359=== modified file 'tests/unit-tests/client/gbm/test_gbm_client_buffer.cpp'
1360--- tests/unit-tests/client/gbm/test_gbm_client_buffer.cpp 2013-03-22 10:34:16 +0000
1361+++ tests/unit-tests/client/gbm/test_gbm_client_buffer.cpp 2013-03-24 23:57:21 +0000
1362@@ -17,7 +17,6 @@
1363 */
1364
1365 #include "mir_toolkit/mir_client_library.h"
1366-#include "src/client/gbm/gbm_client_buffer_depository.h"
1367 #include "src/client/gbm/gbm_client_buffer.h"
1368 #include "mock_drm_fd_handler.h"
1369
1370@@ -25,6 +24,8 @@
1371 #include <sys/mman.h>
1372 #include <gtest/gtest.h>
1373
1374+#include <stdexcept>
1375+
1376 namespace geom=mir::geometry;
1377 namespace mclg=mir::client::gbm;
1378
1379@@ -85,9 +86,9 @@
1380 EXPECT_EQ(package_return->data_items, package_copy->data_items);
1381 EXPECT_EQ(package_return->fd_items, package_copy->fd_items);
1382 EXPECT_EQ(package_return->stride, package_copy->stride);
1383- for(auto i=0; i<mir_buffer_package_max; i++)
1384+ for (auto i=0; i<mir_buffer_package_max; i++)
1385 EXPECT_EQ(package_return->data[i], package_copy->data[i]);
1386- for(auto i=0; i<mir_buffer_package_max; i++)
1387+ for (auto i=0; i<mir_buffer_package_max; i++)
1388 EXPECT_EQ(package_return->fd[i], package_copy->fd[i]);
1389 }
1390
1391@@ -135,7 +136,7 @@
1392 mclg::GBMClientBuffer buffer(drm_fd_handler, std::move(package), size, pf);
1393
1394 EXPECT_THROW({
1395- auto mem_region = buffer.secure_for_cpu_write();
1396+ buffer.secure_for_cpu_write();
1397 }, std::runtime_error);
1398 }
1399
1400
1401=== removed file 'tests/unit-tests/client/gbm/test_gbm_client_depository.cpp'
1402--- tests/unit-tests/client/gbm/test_gbm_client_depository.cpp 2013-03-22 10:34:16 +0000
1403+++ tests/unit-tests/client/gbm/test_gbm_client_depository.cpp 1970-01-01 00:00:00 +0000
1404@@ -1,79 +0,0 @@
1405-/*
1406- * Copyright © 2012 Canonical Ltd.
1407- *
1408- * This program is free software: you can redistribute it and/or modify
1409- * it under the terms of the GNU General Public License version 3 as
1410- * published by the Free Software Foundation.
1411- *
1412- * This program is distributed in the hope that it will be useful,
1413- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1414- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1415- * GNU General Public License for more details.
1416- *
1417- * You should have received a copy of the GNU General Public License
1418- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1419- *
1420- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1421- */
1422-
1423-#include "mir_toolkit/mir_client_library.h"
1424-#include "src/client/gbm/gbm_client_buffer_depository.h"
1425-#include "src/client/gbm/gbm_client_buffer.h"
1426-#include "mock_drm_fd_handler.h"
1427-
1428-#include <gtest/gtest.h>
1429-
1430-namespace geom=mir::geometry;
1431-namespace mclg=mir::client::gbm;
1432-
1433-struct MirGBMBufferDepositoryTest : public testing::Test
1434-{
1435- void SetUp()
1436- {
1437- width = geom::Width(12);
1438- height =geom::Height(14);
1439- pf = geom::PixelFormat::abgr_8888;
1440- size = geom::Size{width, height};
1441-
1442- drm_fd_handler = std::make_shared<testing::NiceMock<mclg::MockDRMFDHandler>>();
1443- package = std::make_shared<MirBufferPackage>();
1444- }
1445- geom::Width width;
1446- geom::Height height;
1447- geom::PixelFormat pf;
1448- geom::Size size;
1449-
1450- std::shared_ptr<testing::NiceMock<mclg::MockDRMFDHandler>> drm_fd_handler;
1451- std::shared_ptr<MirBufferPackage> package;
1452-
1453-};
1454-
1455-TEST_F(MirGBMBufferDepositoryTest, depository_sets_width_and_height)
1456-{
1457- using namespace testing;
1458-
1459- mclg::GBMClientBufferDepository depository{drm_fd_handler};
1460-
1461- depository.deposit_package(std::move(package), 8, size, pf);
1462- auto buffer = depository.access_buffer(8);
1463-
1464- EXPECT_EQ(buffer->size().height, height);
1465- EXPECT_EQ(buffer->size().width, width);
1466- EXPECT_EQ(buffer->pixel_format(), pf);
1467-}
1468-
1469-TEST_F(MirGBMBufferDepositoryTest, depository_new_deposit_changes_buffer )
1470-{
1471- using namespace testing;
1472-
1473- mclg::GBMClientBufferDepository depository{drm_fd_handler};
1474-
1475- depository.deposit_package(std::move(package), 8, size, pf);
1476- auto buffer1 = depository.access_buffer(8);
1477-
1478- depository.deposit_package(std::move(package), 8, size, pf);
1479- auto buffer2 = depository.access_buffer(8);
1480-
1481- EXPECT_NE(buffer1, buffer2);
1482-}
1483-
1484
1485=== added file 'tests/unit-tests/client/test_aging_buffer.cpp'
1486--- tests/unit-tests/client/test_aging_buffer.cpp 1970-01-01 00:00:00 +0000
1487+++ tests/unit-tests/client/test_aging_buffer.cpp 2013-03-24 23:57:21 +0000
1488@@ -0,0 +1,114 @@
1489+/*
1490+ * Copyright © 2013 Canonical Ltd.
1491+ *
1492+ * This program is free software: you can redistribute it and/or modify
1493+ * it under the terms of the GNU Lesser General Public License version 3 as
1494+ * published by the Free Software Foundation.
1495+ *
1496+ * This program is distributed in the hope that it will be useful,
1497+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1498+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1499+ * GNU General Public License for more details.
1500+ *
1501+ * You should have received a copy of the GNU Lesser General Public License
1502+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1503+ *
1504+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
1505+ */
1506+
1507+#include "src/client/aging_buffer.h"
1508+
1509+#include <gtest/gtest.h>
1510+#include <gmock/gmock.h>
1511+
1512+namespace mcl = mir::client;
1513+namespace geom = mir::geometry;
1514+
1515+namespace mir_toolkit
1516+{
1517+ struct MirBufferPackage;
1518+}
1519+
1520+namespace mir
1521+{
1522+namespace test
1523+{
1524+
1525+struct MyAgingBuffer : public mcl::AgingBuffer
1526+{
1527+ std::shared_ptr<mcl::MemoryRegion> secure_for_cpu_write()
1528+ {
1529+ exit(1);
1530+ }
1531+
1532+ geom::Size size() const
1533+ {
1534+ exit(1);
1535+ }
1536+
1537+ geom::Stride stride() const
1538+ {
1539+ exit(1);
1540+ }
1541+
1542+ geom::PixelFormat pixel_format() const
1543+ {
1544+ exit(1);
1545+ }
1546+
1547+ std::shared_ptr<mir_toolkit::MirBufferPackage> get_buffer_package() const
1548+ {
1549+ exit(1);
1550+ }
1551+
1552+ MirNativeBuffer get_native_handle()
1553+ {
1554+ exit(1);
1555+ }
1556+};
1557+
1558+TEST(MirClientAgingBufferTest, buffer_age_starts_at_zero)
1559+{
1560+ using namespace testing;
1561+
1562+ MyAgingBuffer buffer;
1563+
1564+ EXPECT_EQ(0u, buffer.age());
1565+}
1566+
1567+TEST(MirClientAgingBufferTest, buffer_age_set_to_one_on_submit)
1568+{
1569+ using namespace testing;
1570+
1571+ MyAgingBuffer buffer;
1572+ buffer.mark_as_submitted();
1573+
1574+ EXPECT_EQ(1u, buffer.age());
1575+}
1576+
1577+TEST(MirClientAgingBufferTest, buffer_age_increases_on_increment)
1578+{
1579+ using namespace testing;
1580+
1581+ MyAgingBuffer buffer;
1582+ buffer.mark_as_submitted();
1583+
1584+ for (uint32_t age = 2; age < 10; ++age)
1585+ {
1586+ buffer.increment_age();
1587+ EXPECT_EQ(age, buffer.age());
1588+ }
1589+}
1590+
1591+TEST(MirClientAgingBufferTest, incrementing_age_has_no_effect_for_unsubmitted_buffer)
1592+{
1593+ using namespace testing;
1594+
1595+ MyAgingBuffer buffer;
1596+ buffer.increment_age();
1597+
1598+ EXPECT_EQ(0u, buffer.age());
1599+}
1600+
1601+}
1602+}
1603
1604=== added file 'tests/unit-tests/client/test_android_client_buffer_factory.cpp'
1605--- tests/unit-tests/client/test_android_client_buffer_factory.cpp 1970-01-01 00:00:00 +0000
1606+++ tests/unit-tests/client/test_android_client_buffer_factory.cpp 2013-03-24 23:57:21 +0000
1607@@ -0,0 +1,74 @@
1608+/*
1609+ * Copyright © 2012 Canonical Ltd.
1610+ *
1611+ * This program is free software: you can redistribute it and/or modify
1612+ * it under the terms of the GNU Lesser General Public License version 3 as
1613+ * published by the Free Software Foundation.
1614+ *
1615+ * This program is distributed in the hope that it will be useful,
1616+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1617+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1618+ * GNU General Public License for more details.
1619+ *
1620+ * You should have received a copy of the GNU Lesser General Public License
1621+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1622+ *
1623+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1624+ */
1625+
1626+#include "mir_toolkit/mir_client_library.h"
1627+#include "src/client/android/android_client_buffer_factory.h"
1628+#include "src/client/android/android_client_buffer.h"
1629+#include "mir_test_doubles/mock_android_registrar.h"
1630+
1631+#include <gtest/gtest.h>
1632+
1633+namespace geom = mir::geometry;
1634+namespace mcla = mir::client::android;
1635+namespace mt = mir::test;
1636+namespace mtd = mir::test::doubles;
1637+
1638+
1639+struct MirBufferFactoryTest : public testing::Test
1640+{
1641+ void SetUp()
1642+ {
1643+ width = geom::Width(12);
1644+ height =geom::Height(14);
1645+ size = geom::Size{width, height};
1646+ pf = geom::PixelFormat::abgr_8888;
1647+
1648+ mock_registrar = std::make_shared<mtd::MockAndroidRegistrar>();
1649+ package1 = std::make_shared<MirBufferPackage>();
1650+ package2 = std::make_shared<MirBufferPackage>();
1651+
1652+ }
1653+ geom::Width width;
1654+ geom::Height height;
1655+ geom::PixelFormat pf;
1656+ geom::Size size;
1657+
1658+ std::shared_ptr<mtd::MockAndroidRegistrar> mock_registrar;
1659+
1660+ std::shared_ptr<MirBufferPackage> package1;
1661+ std::shared_ptr<MirBufferPackage> package2;
1662+
1663+};
1664+
1665+TEST_F(MirBufferFactoryTest, factory_sets_width_and_height)
1666+{
1667+ using namespace testing;
1668+
1669+ mcla::AndroidClientBufferFactory buffer_factory(mock_registrar);
1670+
1671+ EXPECT_CALL(*mock_registrar, register_buffer(_))
1672+ .Times(1);
1673+ EXPECT_CALL(*mock_registrar, unregister_buffer(_))
1674+ .Times(1);
1675+
1676+ auto buffer = buffer_factory.create_buffer(package1, size, pf);
1677+
1678+ EXPECT_EQ(buffer->size().height, height);
1679+ EXPECT_EQ(buffer->size().width, width);
1680+ EXPECT_EQ(buffer->pixel_format(), pf);
1681+}
1682
1683=== added file 'tests/unit-tests/client/test_client_buffer_depository.cpp'
1684--- tests/unit-tests/client/test_client_buffer_depository.cpp 1970-01-01 00:00:00 +0000
1685+++ tests/unit-tests/client/test_client_buffer_depository.cpp 2013-03-24 23:57:21 +0000
1686@@ -0,0 +1,364 @@
1687+/*
1688+ * Copyright © 2013 Canonical Ltd.
1689+ *
1690+ * This program is free software: you can redistribute it and/or modify
1691+ * it under the terms of the GNU Lesser General Public License version 3 as
1692+ * published by the Free Software Foundation.
1693+ *
1694+ * This program is distributed in the hope that it will be useful,
1695+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1696+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1697+ * GNU General Public License for more details.
1698+ *
1699+ * You should have received a copy of the GNU Lesser General Public License
1700+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1701+ *
1702+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1703+ */
1704+
1705+#include "mir_toolkit/mir_client_library.h"
1706+#include "src/client/client_buffer_depository.h"
1707+#include "src/client/client_buffer_factory.h"
1708+#include "src/client/aging_buffer.h"
1709+#include "mir/geometry/pixel_format.h"
1710+#include "mir/geometry/size.h"
1711+
1712+#include <gtest/gtest.h>
1713+#include <gmock/gmock.h>
1714+
1715+namespace geom=mir::geometry;
1716+namespace mcl=mir::client;
1717+
1718+struct MockBuffer : public mcl::AgingBuffer
1719+{
1720+ MockBuffer()
1721+ {
1722+ using namespace testing;
1723+ ON_CALL(*this, mark_as_submitted())
1724+ .WillByDefault(Invoke([this](){this->AgingBuffer::mark_as_submitted();}));
1725+ }
1726+
1727+ MOCK_METHOD0(Destroy, void());
1728+ virtual ~MockBuffer()
1729+ {
1730+ Destroy();
1731+ }
1732+
1733+ MOCK_METHOD0(mark_as_submitted, void());
1734+ MOCK_METHOD0(secure_for_cpu_write, std::shared_ptr<mcl::MemoryRegion>());
1735+ MOCK_CONST_METHOD0(size, geom::Size());
1736+ MOCK_CONST_METHOD0(stride, geom::Stride());
1737+ MOCK_CONST_METHOD0(pixel_format, geom::PixelFormat());
1738+ MOCK_CONST_METHOD0(get_buffer_package, std::shared_ptr<MirBufferPackage>());
1739+ MOCK_METHOD0(get_native_handle, MirNativeBuffer());
1740+};
1741+
1742+struct MockClientBufferFactory : public mcl::ClientBufferFactory
1743+{
1744+ MockClientBufferFactory()
1745+ {
1746+ using namespace testing;
1747+
1748+ // Some tests, quite reasonably, rely on create_buffer returning a different buffer each time
1749+ // Handle this by first updating our "buffer" temporary, then returning-by-pointee.
1750+ ON_CALL(*this, create_buffer(_,_,_))
1751+ .WillByDefault(DoAll(InvokeWithoutArgs([this]() {this->buffer = std::make_shared<NiceMock<MockBuffer>>();}),
1752+ ReturnPointee(&buffer)));
1753+ }
1754+
1755+ MOCK_METHOD3(create_buffer,
1756+ std::shared_ptr<mcl::ClientBuffer>(std::shared_ptr<MirBufferPackage> const &,
1757+ geom::Size, geom::PixelFormat));
1758+
1759+ std::shared_ptr<mcl::ClientBuffer> buffer;
1760+};
1761+
1762+struct MirBufferDepositoryTest : public testing::Test
1763+{
1764+ void SetUp()
1765+ {
1766+ width = geom::Width(12);
1767+ height =geom::Height(14);
1768+ pf = geom::PixelFormat::abgr_8888;
1769+ size = geom::Size{width, height};
1770+
1771+ package = std::make_shared<MirBufferPackage>();
1772+ mock_factory = std::make_shared<testing::NiceMock<MockClientBufferFactory>>();
1773+ }
1774+ geom::Width width;
1775+ geom::Height height;
1776+ geom::PixelFormat pf;
1777+ geom::Size size;
1778+
1779+ std::shared_ptr<MirBufferPackage> package;
1780+ std::shared_ptr<MockClientBufferFactory> mock_factory;
1781+};
1782+
1783+MATCHER_P(SizeMatches, value, "")
1784+{
1785+ return value == arg;
1786+}
1787+
1788+TEST_F(MirBufferDepositoryTest, depository_sets_width_and_height)
1789+{
1790+ using namespace testing;
1791+
1792+ mcl::ClientBufferDepository depository{mock_factory, 3};
1793+
1794+ EXPECT_CALL(*mock_factory, create_buffer(_,size,pf))
1795+ .Times(1);
1796+ depository.deposit_package(package, 8, size, pf);
1797+}
1798+
1799+TEST_F(MirBufferDepositoryTest, depository_new_deposit_changes_current_buffer)
1800+{
1801+ using namespace testing;
1802+
1803+ auto package2 = std::make_shared<MirBufferPackage>();
1804+ mcl::ClientBufferDepository depository{mock_factory, 3};
1805+
1806+ depository.deposit_package(package, 8, size, pf);
1807+ auto buffer1 = depository.current_buffer();
1808+
1809+ depository.deposit_package(package2, 9, size, pf);
1810+ auto buffer2 = depository.current_buffer();
1811+
1812+ EXPECT_NE(buffer1, buffer2);
1813+}
1814+
1815+TEST_F(MirBufferDepositoryTest, depository_sets_buffer_age_to_zero_for_new_buffer)
1816+{
1817+ using namespace testing;
1818+
1819+ mcl::ClientBufferDepository depository{mock_factory, 3};
1820+
1821+ depository.deposit_package(package, 1, size, pf);
1822+ auto buffer1 = depository.current_buffer();
1823+
1824+ EXPECT_EQ(0u, buffer1->age());
1825+}
1826+
1827+TEST_F(MirBufferDepositoryTest, just_sumbitted_buffer_has_age_1)
1828+{
1829+ using namespace testing;
1830+
1831+ mcl::ClientBufferDepository depository{mock_factory, 3};
1832+ auto package2 = std::make_shared<MirBufferPackage>();
1833+
1834+ depository.deposit_package(package, 1, size, pf);
1835+ auto buffer1 = depository.current_buffer();
1836+
1837+ ASSERT_EQ(0u, buffer1->age());
1838+
1839+ // Deposit new package, implicitly marking previous buffer as submitted
1840+ depository.deposit_package(package2, 2, size, pf);
1841+
1842+ EXPECT_EQ(1u, buffer1->age());
1843+}
1844+
1845+TEST_F(MirBufferDepositoryTest, submitting_buffer_ages_other_buffers)
1846+{
1847+ using namespace testing;
1848+
1849+ mcl::ClientBufferDepository depository{mock_factory, 3};
1850+
1851+ depository.deposit_package(package, 1, size, pf);
1852+ auto buffer1 = depository.current_buffer();
1853+
1854+ EXPECT_EQ(0u, buffer1->age());
1855+
1856+ auto package2 = std::make_shared<MirBufferPackage>();
1857+ depository.deposit_package(package2, 2, size, pf);
1858+ auto buffer2 = depository.current_buffer();
1859+
1860+ EXPECT_EQ(1u, buffer1->age());
1861+ EXPECT_EQ(0u, buffer2->age());
1862+
1863+ auto package3 = std::make_shared<MirBufferPackage>();
1864+ depository.deposit_package(package3, 3, size, pf);
1865+ auto buffer3 = depository.current_buffer();
1866+
1867+ EXPECT_EQ(2u, buffer1->age());
1868+ EXPECT_EQ(1u, buffer2->age());
1869+ EXPECT_EQ(0u, buffer3->age());
1870+}
1871+
1872+TEST_F(MirBufferDepositoryTest, double_buffering_reaches_steady_state_age)
1873+{
1874+ using namespace testing;
1875+
1876+ mcl::ClientBufferDepository depository{mock_factory, 3};
1877+
1878+ depository.deposit_package(package, 1, size, pf);
1879+ auto buffer1 = depository.current_buffer();
1880+
1881+ EXPECT_EQ(0u, buffer1->age());
1882+
1883+ auto package2 = std::make_shared<MirBufferPackage>();
1884+ depository.deposit_package(package2, 2, size, pf);
1885+ auto buffer2 = depository.current_buffer();
1886+
1887+ EXPECT_EQ(1u, buffer1->age());
1888+ EXPECT_EQ(0u, buffer2->age());
1889+
1890+ depository.deposit_package(package, 1, size, pf);
1891+
1892+ EXPECT_EQ(2u, buffer1->age());
1893+ EXPECT_EQ(1u, buffer2->age());
1894+
1895+ depository.deposit_package(package2, 2, size, pf);
1896+
1897+ EXPECT_EQ(1u, buffer1->age());
1898+ EXPECT_EQ(2u, buffer2->age());
1899+}
1900+
1901+TEST_F(MirBufferDepositoryTest, triple_buffering_reaches_steady_state_age)
1902+{
1903+ using namespace testing;
1904+
1905+ mcl::ClientBufferDepository depository{mock_factory, 3};
1906+
1907+ depository.deposit_package(package, 1, size, pf);
1908+ auto buffer1 = depository.current_buffer();
1909+
1910+ auto package2 = std::make_shared<MirBufferPackage>();
1911+ depository.deposit_package(package2, 2, size, pf);
1912+ auto buffer2 = depository.current_buffer();
1913+
1914+ auto package3 = std::make_shared<MirBufferPackage>();
1915+ depository.deposit_package(package3, 3, size, pf);
1916+ auto buffer3 = depository.current_buffer();
1917+
1918+ EXPECT_EQ(2u, buffer1->age());
1919+ EXPECT_EQ(1u, buffer2->age());
1920+ EXPECT_EQ(0u, buffer3->age());
1921+
1922+ depository.deposit_package(package, 1, size, pf);
1923+
1924+ EXPECT_EQ(3u, buffer1->age());
1925+ EXPECT_EQ(2u, buffer2->age());
1926+ EXPECT_EQ(1u, buffer3->age());
1927+
1928+ depository.deposit_package(package2, 2, size, pf);
1929+
1930+ EXPECT_EQ(1u, buffer1->age());
1931+ EXPECT_EQ(3u, buffer2->age());
1932+ EXPECT_EQ(2u, buffer3->age());
1933+
1934+ depository.deposit_package(package3, 3, size, pf);
1935+
1936+ EXPECT_EQ(2u, buffer1->age());
1937+ EXPECT_EQ(1u, buffer2->age());
1938+ EXPECT_EQ(3u, buffer3->age());
1939+}
1940+
1941+TEST_F(MirBufferDepositoryTest, depository_destroys_old_buffers)
1942+{
1943+ using namespace testing;
1944+ const int num_buffers = 3;
1945+
1946+ mcl::ClientBufferDepository depository{mock_factory, num_buffers};
1947+
1948+ const int num_packages = 4;
1949+ std::shared_ptr<MirBufferPackage> packages[num_packages];
1950+
1951+ depository.deposit_package(packages[0], 1, size, pf);
1952+ // Raw pointer so we don't influence the buffer's life-cycle
1953+ MockBuffer *first_buffer = static_cast<MockBuffer *>(depository.current_buffer().get());
1954+
1955+ depository.deposit_package(packages[1], 2, size, pf);
1956+ depository.deposit_package(packages[2], 3, size, pf);
1957+
1958+ // We've deposited three different buffers now; the fourth should trigger the destruction
1959+ // of the first buffer.
1960+ EXPECT_CALL(*first_buffer, Destroy());
1961+
1962+ depository.deposit_package(packages[3], 4, size, pf);
1963+
1964+ // Explicitly verify that the buffer has been destroyed here, before the depository goes out of scope
1965+ // and its destructor cleans everything up.
1966+ Mock::VerifyAndClearExpectations(first_buffer);
1967+}
1968+
1969+TEST_F(MirBufferDepositoryTest, depositing_packages_implicitly_submits_current_buffer)
1970+{
1971+ using namespace testing;
1972+ const int num_buffers = 3;
1973+
1974+ mcl::ClientBufferDepository depository{mock_factory, num_buffers};
1975+
1976+ auto package1 = std::make_shared<MirBufferPackage>();
1977+ auto package2 = std::make_shared<MirBufferPackage>();
1978+
1979+ depository.deposit_package(package1, 1, size, pf);
1980+ EXPECT_CALL(*static_cast<MockBuffer *>(depository.current_buffer().get()), mark_as_submitted());
1981+ depository.deposit_package(package2, 2, size, pf);
1982+}
1983+
1984+TEST_F(MirBufferDepositoryTest, depository_respects_max_buffer_parameter)
1985+{
1986+ using namespace testing;
1987+ std::shared_ptr<mcl::ClientBufferDepository> depository;
1988+ std::shared_ptr<MirBufferPackage> packages[10];
1989+ MockBuffer *buffers[10];
1990+
1991+ for (int num_buffers = 2; num_buffers < 10; ++num_buffers)
1992+ {
1993+ depository = std::make_shared<mcl::ClientBufferDepository>(mock_factory, num_buffers);
1994+
1995+ depository->deposit_package(packages[0], 1, size, pf);
1996+ // Raw pointer so we don't influence the buffer's life-cycle
1997+ MockBuffer* first_buffer = static_cast<MockBuffer *>(depository->current_buffer().get());
1998+
1999+ int i;
2000+ for (i = 1; i < num_buffers ; ++i)
2001+ {
2002+ depository->deposit_package(packages[i], i + 1, size, pf);
2003+ buffers[i] = static_cast<MockBuffer *>(depository->current_buffer().get());
2004+ // None of these buffers should be destroyed
2005+ EXPECT_CALL(*buffers[i], Destroy()).Times(0);
2006+ }
2007+
2008+ // Next deposit should destroy first buffer
2009+ EXPECT_CALL(*first_buffer, Destroy()).Times(1);
2010+ depository->deposit_package(packages[i], i+1, size, pf);
2011+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(first_buffer));
2012+
2013+ // Verify none of the other buffers have been destroyed
2014+ for (i = 1; i < num_buffers; ++i)
2015+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(buffers[i]));
2016+ }
2017+}
2018+
2019+TEST_F(MirBufferDepositoryTest, depository_caches_recently_seen_buffer)
2020+{
2021+ using namespace testing;
2022+
2023+ mcl::ClientBufferDepository depository{mock_factory, 3};
2024+
2025+ auto package1 = std::make_shared<MirBufferPackage>();
2026+ auto package2 = std::make_shared<MirBufferPackage>();
2027+
2028+ EXPECT_CALL(*mock_factory, create_buffer(_,_,_))
2029+ .Times(1);
2030+
2031+ depository.deposit_package(package1, 8, size, pf);
2032+ depository.deposit_package(package1, 8, size, pf);
2033+ depository.deposit_package(package1, 8, size, pf);
2034+}
2035+
2036+TEST_F(MirBufferDepositoryTest, depository_creates_new_buffer_for_different_id)
2037+{
2038+ using namespace testing;
2039+
2040+ mcl::ClientBufferDepository depository{mock_factory, 3};
2041+
2042+ auto package1 = std::make_shared<MirBufferPackage>();
2043+ auto package2 = std::make_shared<MirBufferPackage>();
2044+
2045+ EXPECT_CALL(*mock_factory, create_buffer(_,_,_))
2046+ .Times(2);
2047+
2048+ depository.deposit_package(package1, 8, size, pf);
2049+ depository.deposit_package(package2, 9, size, pf);
2050+}
2051
2052=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
2053--- tests/unit-tests/client/test_client_mir_surface.cpp 2013-03-22 10:34:16 +0000
2054+++ tests/unit-tests/client/test_client_mir_surface.cpp 2013-03-24 23:57:21 +0000
2055@@ -21,6 +21,7 @@
2056 #include "src/client/mir_logger.h"
2057 #include "src/client/client_buffer.h"
2058 #include "src/client/client_buffer_depository.h"
2059+#include "src/client/client_buffer_factory.h"
2060 #include "src/client/client_platform.h"
2061 #include "src/client/client_platform_factory.h"
2062 #include "src/client/mir_surface.h"
2063@@ -55,12 +56,12 @@
2064 pf_sent = mir_pixel_format_abgr_8888;
2065 }
2066
2067- void create_surface(google::protobuf::RpcController* ,
2068+ void create_surface(google::protobuf::RpcController*,
2069 const mir::protobuf::SurfaceParameters* request,
2070 mir::protobuf::Surface* response,
2071 google::protobuf::Closure* done)
2072 {
2073- create_surface_response( response );
2074+ create_surface_response(response);
2075 surface_name = request->surface_name();
2076 done->Run();
2077 }
2078@@ -71,7 +72,7 @@
2079 ::mir::protobuf::Buffer* response,
2080 ::google::protobuf::Closure* done)
2081 {
2082- create_buffer_response( response );
2083+ create_buffer_response(response);
2084 done->Run();
2085 }
2086
2087@@ -117,6 +118,8 @@
2088 }
2089
2090 response->set_stride(server_package.stride);
2091+
2092+ generate_unique_buffer();
2093 }
2094
2095 void create_surface_response(mir::protobuf::Surface* response)
2096@@ -140,31 +143,27 @@
2097 MOCK_CONST_METHOD0(size, geom::Size());
2098 MOCK_CONST_METHOD0(stride, geom::Stride());
2099 MOCK_CONST_METHOD0(pixel_format, geom::PixelFormat());
2100+ MOCK_CONST_METHOD0(age, uint32_t());
2101+ MOCK_METHOD0(increment_age, void());
2102+ MOCK_METHOD0(mark_as_submitted, void());
2103 MOCK_CONST_METHOD0(get_buffer_package, std::shared_ptr<MirBufferPackage>());
2104 MOCK_METHOD0(get_native_handle, MirNativeBuffer());
2105 };
2106
2107-struct MockClientDepository : public mcl::ClientBufferDepository
2108+struct MockClientBufferFactory : public mcl::ClientBufferFactory
2109 {
2110- MockClientDepository()
2111+ MockClientBufferFactory()
2112 {
2113 using namespace testing;
2114
2115- emptybuffer=std::make_shared<MockBuffer>();
2116- ON_CALL(*this, access_buffer(_))
2117+ emptybuffer=std::make_shared<NiceMock<MockBuffer>>();
2118+ ON_CALL(*this, create_buffer(_,_,_))
2119 .WillByDefault(Return(emptybuffer));
2120 }
2121
2122- void deposit_package(std::shared_ptr<MirBufferPackage> && p, int id,
2123- geometry::Size size, geometry::PixelFormat pf)
2124- {
2125- deposit_package_rv( p, id, size, pf);
2126- }
2127-
2128- MOCK_METHOD4(deposit_package_rv,
2129- void(std::shared_ptr<MirBufferPackage>, int,
2130- geom::Size, geom::PixelFormat));
2131- MOCK_METHOD1(access_buffer, std::shared_ptr<mcl::ClientBuffer>(int));
2132+ MOCK_METHOD3(create_buffer,
2133+ std::shared_ptr<mcl::ClientBuffer>(std::shared_ptr<MirBufferPackage> const &,
2134+ geom::Size, geom::PixelFormat));
2135
2136 std::shared_ptr<mcl::ClientBuffer> emptybuffer;
2137 };
2138@@ -172,9 +171,9 @@
2139
2140 struct StubClientPlatform : public mcl::ClientPlatform
2141 {
2142- std::shared_ptr<mcl::ClientBufferDepository> create_platform_depository()
2143+ std::shared_ptr<mcl::ClientBufferFactory> create_buffer_factory()
2144 {
2145- return std::shared_ptr<mcl::ClientBufferDepository>();
2146+ return std::shared_ptr<MockClientBufferFactory>();
2147 }
2148
2149 std::shared_ptr<EGLNativeWindowType> create_egl_native_window(mcl::ClientSurface* /*surface*/)
2150@@ -219,7 +218,8 @@
2151
2152 test_server->comm->start();
2153
2154- mock_depository = std::make_shared<mt::MockClientDepository>();
2155+ mock_buffer_factory = std::make_shared<mt::MockClientBufferFactory>();
2156+ depository = std::make_shared<mcl::ClientBufferDepository>(mock_buffer_factory, 3);
2157
2158 params = MirSurfaceParameters{"test", 33, 45, mir_pixel_format_abgr_8888,
2159 mir_buffer_usage_hardware};
2160@@ -249,7 +249,8 @@
2161 std::shared_ptr<MirConnection> connection;
2162
2163 MirSurfaceParameters params;
2164- std::shared_ptr<mt::MockClientDepository> mock_depository;
2165+ std::shared_ptr<mt::MockClientBufferFactory> mock_buffer_factory;
2166+ std::shared_ptr<mcl::ClientBufferDepository> depository;
2167
2168 mir::protobuf::Connection response;
2169 mir::protobuf::ConnectParameters connect_parameters;
2170@@ -264,14 +265,14 @@
2171 };
2172
2173 void empty_callback(MirSurface*, void*) { }
2174-TEST_F(MirClientSurfaceTest, client_buffer_created_on_surface_creation )
2175+TEST_F(MirClientSurfaceTest, client_buffer_created_on_surface_creation)
2176 {
2177 using namespace testing;
2178
2179- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2180+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2181 .Times(1);
2182
2183- auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, mock_depository, params, &empty_callback, (void*) NULL);
2184+ auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, depository, params, &empty_callback, (void*) NULL);
2185
2186 auto wait_handle = surface->get_create_wait_handle();
2187 wait_handle->wait_for_result();
2188@@ -282,35 +283,35 @@
2189 void empty_surface_callback(MirSurface*, void*) {}
2190 }
2191
2192-TEST_F(MirClientSurfaceTest, client_buffer_created_on_next_buffer )
2193+TEST_F(MirClientSurfaceTest, client_buffer_created_on_next_buffer)
2194 {
2195 using namespace testing;
2196
2197- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2198+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2199 .Times(1);
2200
2201- auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, mock_depository, params, &empty_callback, (void*) NULL);
2202+ auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, depository, params, &empty_callback, (void*) NULL);
2203
2204 auto wait_handle = surface->get_create_wait_handle();
2205 wait_handle->wait_for_result();
2206
2207- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2208+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2209 .Times(1);
2210 auto buffer_wait_handle = surface->next_buffer(&empty_surface_callback, (void*) NULL);
2211 buffer_wait_handle->wait_for_result();
2212 }
2213
2214-TEST_F(MirClientSurfaceTest, client_buffer_uses_ipc_message_from_server_on_create )
2215+TEST_F(MirClientSurfaceTest, client_buffer_uses_ipc_message_from_server_on_create)
2216 {
2217 using namespace testing;
2218
2219 std::shared_ptr<MirBufferPackage> submitted_package;
2220- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2221+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2222 .Times(1)
2223- .WillOnce(
2224- SaveArg<0>(&submitted_package));
2225+ .WillOnce(DoAll(SaveArg<0>(&submitted_package),
2226+ Return(mock_buffer_factory->emptybuffer)));
2227
2228- auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, mock_depository, params, &empty_callback, (void*) NULL);
2229+ auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, depository, params, &empty_callback, (void*) NULL);
2230 auto wait_handle = surface->get_create_wait_handle();
2231 wait_handle->wait_for_result();
2232
2233@@ -318,7 +319,7 @@
2234 ASSERT_EQ(submitted_package->data_items, mock_server_tool->server_package.data_items);
2235 ASSERT_EQ(submitted_package->fd_items, mock_server_tool->server_package.fd_items);
2236 ASSERT_EQ(submitted_package->stride, mock_server_tool->server_package.stride);
2237- for(auto i=0; i< submitted_package->data_items; i++)
2238+ for (auto i=0; i< submitted_package->data_items; i++)
2239 EXPECT_EQ(submitted_package->data[i], mock_server_tool->server_package.data[i]);
2240 }
2241
2242@@ -329,11 +330,12 @@
2243 geom::Size sz;
2244 std::shared_ptr<MirBufferPackage> submitted_package;
2245
2246- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2247+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2248 .Times(1)
2249- .WillOnce(SaveArg<2>(&sz));
2250+ .WillOnce(DoAll(SaveArg<1>(&sz),
2251+ Return(mock_buffer_factory->emptybuffer)));
2252
2253- auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, mock_depository, params, &empty_callback, (void*) NULL);
2254+ auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, depository, params, &empty_callback, (void*) NULL);
2255 auto wait_handle = surface->get_create_wait_handle();
2256 wait_handle->wait_for_result();
2257
2258@@ -347,11 +349,12 @@
2259 geom::Size sz;
2260 std::shared_ptr<MirBufferPackage> submitted_package;
2261
2262- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2263+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2264 .Times(1)
2265- .WillOnce(SaveArg<2>(&sz));
2266+ .WillOnce(DoAll(SaveArg<1>(&sz),
2267+ Return(mock_buffer_factory->emptybuffer)));
2268
2269- auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, mock_depository, params, &empty_callback, (void*) NULL);
2270+ auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, depository, params, &empty_callback, (void*) NULL);
2271 auto wait_handle = surface->get_create_wait_handle();
2272 wait_handle->wait_for_result();
2273
2274@@ -365,11 +368,12 @@
2275 geom::PixelFormat pf;
2276 std::shared_ptr<MirBufferPackage> submitted_package;
2277
2278- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2279+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2280 .Times(1)
2281- .WillOnce(SaveArg<3>(&pf));
2282+ .WillOnce(DoAll(SaveArg<2>(&pf),
2283+ Return(mock_buffer_factory->emptybuffer)));
2284
2285- auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, mock_depository, params, &empty_callback, (void*) NULL);
2286+ auto surface = std::make_shared<MirSurface> (connection.get(), *client_comm_channel, logger, depository, params, &empty_callback, (void*) NULL);
2287 auto wait_handle = surface->get_create_wait_handle();
2288 wait_handle->wait_for_result();
2289
2290@@ -381,13 +385,13 @@
2291 using namespace testing;
2292 using namespace mir::protobuf;
2293
2294- EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_))
2295+ EXPECT_CALL(*mock_buffer_factory, create_buffer(_,_,_))
2296 .Times(1);
2297
2298 auto surface = std::make_shared<MirSurface> (connection.get(),
2299 *client_comm_channel,
2300 logger,
2301- mock_depository,
2302+ depository,
2303 params,
2304 &empty_callback,
2305 (void*) NULL);
2306
2307=== modified file 'tests/unit-tests/client/test_client_platform.cpp'
2308--- tests/unit-tests/client/test_client_platform.cpp 2013-03-18 22:18:23 +0000
2309+++ tests/unit-tests/client/test_client_platform.cpp 2013-03-24 23:57:21 +0000
2310@@ -45,8 +45,8 @@
2311 mtd::MockClientContext context;
2312 mcl::NativeClientPlatformFactory factory;
2313 auto platform = factory.create_client_platform(&context);
2314- auto depository = platform->create_platform_depository();
2315- EXPECT_NE( depository.get(), (mcl::ClientBufferDepository*) NULL);
2316+ auto buffer_factory = platform->create_buffer_factory();
2317+ EXPECT_NE(buffer_factory.get(), (mcl::ClientBufferFactory*) NULL);
2318 }
2319
2320 TEST_F(ClientPlatformTest, platform_creates_native_window)
2321@@ -56,7 +56,7 @@
2322 auto platform = factory.create_client_platform(&context);
2323 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
2324 auto native_window = platform->create_egl_native_window(mock_client_surface.get());
2325- EXPECT_NE( *native_window, (EGLNativeWindowType) NULL);
2326+ EXPECT_NE(*native_window, (EGLNativeWindowType) NULL);
2327 }
2328
2329 TEST_F(ClientPlatformTest, platform_creates_egl_native_display)
2330
2331=== modified file 'tests/unit-tests/client/test_mir_connection.cpp'
2332--- tests/unit-tests/client/test_mir_connection.cpp 2013-01-02 15:57:13 +0000
2333+++ tests/unit-tests/client/test_mir_connection.cpp 2013-03-24 23:57:21 +0000
2334@@ -78,7 +78,7 @@
2335 .WillByDefault(Return(native_display));
2336 }
2337
2338- MOCK_METHOD0(create_platform_depository, std::shared_ptr<mcl::ClientBufferDepository>());
2339+ MOCK_METHOD0(create_buffer_factory, std::shared_ptr<mcl::ClientBufferFactory>());
2340 MOCK_METHOD1(create_egl_native_window, std::shared_ptr<EGLNativeWindowType>(mcl::ClientSurface*));
2341 MOCK_METHOD0(create_egl_native_display, std::shared_ptr<EGLNativeDisplayType>());
2342 };

Subscribers

People subscribed via source and target branches