=== modified file 'benchmarks/CMakeLists.txt'
--- benchmarks/CMakeLists.txt	2013-10-15 10:10:05 +0000
+++ benchmarks/CMakeLists.txt	2014-01-02 07:37:29 +0000
@@ -2,7 +2,9 @@
   benchmarks
 )
 
-add_subdirectory(android-input)
+if (MIR_ENABLE_TESTS)
+  add_subdirectory(android-input)
+endif ()
 add_subdirectory(cpu)
 add_subdirectory(memory)
 

=== modified file 'doc/building_source_for_android.md'
--- doc/building_source_for_android.md	2013-12-17 18:24:51 +0000
+++ doc/building_source_for_android.md	2014-01-02 07:37:29 +0000
@@ -51,35 +51,24 @@
 ubuntu package) to produce armhf code. This is typically the quickest way to
 compile and run code, and is well suited for a development workflow.
 
--  Be sure that the cross compiler that you are using matches the target
-   environment. (eg, make sure you're using the trusty toolchain if you're
-   targeting a trusty phablet image) You can specify the toolchain version
-   thusly:
-
-        $ apt-get install g++-arm-linux-gnueabihf/trusty
-
--  Get access to armhf packages via apt-get. On an amd64/ia32 system, you can
-   do this by adding a file like the one below to /etc/apt/sources.list.d/
-
-        #example sources.list with armhf dependencies
-        deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe multiverse
-    
-    Then you should run:
-
-        $ apt-get update
-
-    To test, try downloading a package like this:
-
-        $ apt-get download my-package:armhf
-
--  Once you're able to download armhf packages from the repository, the 
-   cross-compile-chroot.sh script provides an example of how to download
-   a partial chroot with the mir dependencies, and compile the source for
-   android targets.
-
-   The script sets up a partial chroot via tools/setup-partial-armhf-chroot.sh
-   and then runs build commands similar to this:
-
-        $ mkdir mir/build; cd mir/build
-        $ MIR_NDK_PATH=/path/to/depenendcies/chroot cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/LinuxCrossCompile.cmake -DBoost_COMPILER=-gcc -DMIR_PLATFORM=android ..
-        $ make
+Initial setup of a desktop machine for cross-compiling to armhf is simple:
+
+    $ sudo apt-get install g++-arm-linux-gnueabihf/trusty debootstrap
+    $ sudo sh -c 'echo "deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe multiverse" > /etc/apt/sources.list.d/armhf-xcompile.list'
+    $ sudo apt-get update
+
+Now to test that everything is working you can try downloading a package like
+this:
+
+    $ apt-get download gcc:armhf
+
+Once you're able to download armhf packages from the repository, the 
+cross-compile-chroot.sh script provides an example of how to build Mir for
+armhf:
+
+    $ ./cross-compile-chroot.sh
+    $ ls -l build-android-arm/*  # binaries to copy to your device
+
+To speed up the process for future branches you may wish to cache the files
+downloaded by setting environment variable MIR_NDK_PATH to point to a directory
+that cross-compile-chroot.sh should reuse each time.

=== added file 'include/platform/mir/graphics/pixel_format_utils.h'
--- include/platform/mir/graphics/pixel_format_utils.h	1970-01-01 00:00:00 +0000
+++ include/platform/mir/graphics/pixel_format_utils.h	2014-01-02 07:37:29 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
+ */
+
+#include "mir_toolkit/common.h"
+
+namespace mir
+{
+namespace graphics
+{
+
+/*!
+ * \name MirPixelFormat utility functions
+ *
+ * A set of functions to query details of MirPixelFormat
+ * TODO improve this through https://bugs.launchpad.net/mir/+bug/1236254
+ * \{
+ */
+bool contains_alpha(MirPixelFormat format);
+int red_channel_depth(MirPixelFormat format);
+int blue_channel_depth(MirPixelFormat format);
+int green_channel_depth(MirPixelFormat format);
+int alpha_channel_depth(MirPixelFormat format);
+bool valid_format(MirPixelFormat format);
+/*!
+ * \}
+ */
+
+
+}
+}

=== added file 'include/shared/mir/logging/input_timestamp.h'
--- include/shared/mir/logging/input_timestamp.h	1970-01-01 00:00:00 +0000
+++ include/shared/mir/logging/input_timestamp.h	2014-01-02 07:37:29 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
+ */
+
+#ifndef MIR_LOGGING_INPUT_TIMESTAMP_H_
+#define MIR_LOGGING_INPUT_TIMESTAMP_H_
+
+#include "mir_toolkit/event.h"
+#include <string>
+
+namespace mir
+{
+namespace logging
+{
+
+std::string input_timestamp(nsecs_t when);
+
+}
+}
+
+#endif // MIR_LOGGING_INPUT_TIMESTAMP_H_

=== modified file 'include/test/mir_test_doubles/mock_surface_renderer.h'
--- include/test/mir_test_doubles/mock_surface_renderer.h	2013-12-17 18:24:51 +0000
+++ include/test/mir_test_doubles/mock_surface_renderer.h	2014-01-02 07:37:29 +0000
@@ -31,8 +31,9 @@
 
 struct MockSurfaceRenderer : public compositor::Renderer
 {
+    MOCK_CONST_METHOD0(begin, void());
     MOCK_CONST_METHOD2(render, void(compositor::CompositingCriteria const&, graphics::Buffer&));
-    MOCK_CONST_METHOD0(clear, void());
+    MOCK_CONST_METHOD0(end, void());
 
     ~MockSurfaceRenderer() noexcept {}
 };

=== modified file 'src/client/logging/input_receiver_report.cpp'
--- src/client/logging/input_receiver_report.cpp	2013-12-17 18:24:51 +0000
+++ src/client/logging/input_receiver_report.cpp	2014-01-02 07:37:29 +0000
@@ -19,6 +19,7 @@
 #include "input_receiver_report.h"
 
 #include "mir/logging/logger.h"
+#include "mir/logging/input_timestamp.h"
 
 #include <boost/throw_exception.hpp>
 
@@ -53,7 +54,7 @@
     ss << "  scan_code: " << ev.scan_code << std::endl;
     ss << "  repeat_count: " << ev.repeat_count << std::endl;
     ss << "  down_time: " << ev.down_time << std::endl;
-    ss << "  event_time: " << ev.event_time << std::endl;
+    ss << "  event_time: " << ml::input_timestamp(ev.event_time) << std::endl;
     ss << "  is_system_key: " << ev.is_system_key << std::endl;
     ss << "}";
 }
@@ -73,7 +74,7 @@
     ss << "  x_precision: " << ev.x_precision << std::endl;
     ss << "  y_precision: " << ev.y_precision << std::endl;
     ss << "  down_time: " << ev.down_time << std::endl;
-    ss << "  event_time: " << ev.event_time << std::endl;
+    ss << "  event_time: " << ml::input_timestamp(ev.event_time) << std::endl;
     ss << "  pointer_count: " << ev.pointer_count << std::endl;
     for (unsigned int i = 0; i < ev.pointer_count; i++)
     {

=== modified file 'src/platform/graphics/CMakeLists.txt'
--- src/platform/graphics/CMakeLists.txt	2013-12-17 18:24:51 +0000
+++ src/platform/graphics/CMakeLists.txt	2014-01-02 07:37:29 +0000
@@ -10,6 +10,7 @@
   display_configuration.cpp
   null_display_report.cpp
   buffer_basic.cpp
+  pixel_format_utils.cpp
 )
 
 add_library(

=== added file 'src/platform/graphics/pixel_format_utils.cpp'
--- src/platform/graphics/pixel_format_utils.cpp	1970-01-01 00:00:00 +0000
+++ src/platform/graphics/pixel_format_utils.cpp	2014-01-02 07:37:29 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
+ */
+
+#include "mir/graphics/pixel_format_utils.h"
+
+namespace mir
+{
+namespace graphics
+{
+
+bool contains_alpha(MirPixelFormat format)
+{
+    return (format == mir_pixel_format_abgr_8888 ||
+            format == mir_pixel_format_argb_8888);
+}
+
+int red_channel_depth(MirPixelFormat format)
+{
+    if (mir_pixel_format_invalid < format &&
+        format < mir_pixel_formats)
+        return 8;
+    return 0;
+}
+
+int blue_channel_depth(MirPixelFormat format)
+{
+    if (mir_pixel_format_invalid < format &&
+        format < mir_pixel_formats)
+        return 8;
+    return 0;
+}
+
+int green_channel_depth(MirPixelFormat format)
+{
+    if (mir_pixel_format_invalid < format &&
+        format < mir_pixel_formats)
+        return 8;
+    return 0;
+}
+
+int alpha_channel_depth(MirPixelFormat format)
+{
+    if (format == mir_pixel_format_abgr_8888 ||
+        format == mir_pixel_format_argb_8888)
+        return 8;
+    return 0;
+}
+
+bool valid_format(MirPixelFormat format)
+{
+    return (format > mir_pixel_format_invalid &&
+            format < mir_pixel_formats);
+}
+
+}
+}

=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
--- src/server/compositor/default_display_buffer_compositor.cpp	2013-12-17 18:24:51 +0000
+++ src/server/compositor/default_display_buffer_compositor.cpp	2014-01-02 07:37:29 +0000
@@ -135,10 +135,11 @@
         mc::OcclusionMatch occlusion_match;
         scene->reverse_for_each_if(occlusion_search, occlusion_match);
 
-        renderer->clear();
+        renderer->begin();
         mc::RenderingOperator applicator(*renderer, save_resource, local_frameno);
         FilterForVisibleSceneInRegion selector(view_area, occlusion_match);
         scene->for_each_if(selector, applicator);
+        renderer->end();
 
         display_buffer.post_update();
     }

=== modified file 'src/server/compositor/gl_renderer.cpp'
--- src/server/compositor/gl_renderer.cpp	2013-12-17 18:24:51 +0000
+++ src/server/compositor/gl_renderer.cpp	2014-01-02 07:37:29 +0000
@@ -117,7 +117,7 @@
 
 }
 
-mc::GLRenderer::Resources::Resources() :
+mc::GLRenderer::GLRenderer(geom::Rectangle const& display_area) :
     vertex_shader(0),
     fragment_shader(0),
     program(0),
@@ -128,24 +128,6 @@
     vertex_attribs_vbo(0),
     texture(0)
 {
-}
-
-mc::GLRenderer::Resources::~Resources()
-{
-    if (vertex_shader)
-        glDeleteShader(vertex_shader);
-    if (fragment_shader)
-        glDeleteShader(fragment_shader);
-    if (program)
-        glDeleteProgram(program);
-    if (vertex_attribs_vbo)
-        glDeleteBuffers(1, &vertex_attribs_vbo);
-    if (texture)
-        glDeleteTextures(1, &texture);
-}
-
-void mc::GLRenderer::Resources::setup(geometry::Rectangle const& display_area)
-{
     GLint param = 0;
 
     /* Create shaders and program */
@@ -235,14 +217,23 @@
     glUseProgram(0);
 }
 
-mc::GLRenderer::GLRenderer(geom::Rectangle const& display_area)
+mc::GLRenderer::~GLRenderer() noexcept
 {
-    resources.setup(display_area);
+    if (vertex_shader)
+        glDeleteShader(vertex_shader);
+    if (fragment_shader)
+        glDeleteShader(fragment_shader);
+    if (program)
+        glDeleteProgram(program);
+    if (vertex_attribs_vbo)
+        glDeleteBuffers(1, &vertex_attribs_vbo);
+    if (texture)
+        glDeleteTextures(1, &texture);
 }
 
 void mc::GLRenderer::render(CompositingCriteria const& criteria, mg::Buffer& buffer) const
 {
-    glUseProgram(resources.program);
+    glUseProgram(program);
 
     if (criteria.shaped() || criteria.alpha() < 1.0f)
     {
@@ -255,32 +246,36 @@
     }
     glActiveTexture(GL_TEXTURE0);
 
-    glUniformMatrix4fv(resources.transform_uniform_loc, 1, GL_FALSE,
+    glUniformMatrix4fv(transform_uniform_loc, 1, GL_FALSE,
                        glm::value_ptr(criteria.transformation()));
-    glUniform1f(resources.alpha_uniform_loc, criteria.alpha());
+    glUniform1f(alpha_uniform_loc, criteria.alpha());
 
     /* Set up vertex attribute data */
-    glBindBuffer(GL_ARRAY_BUFFER, resources.vertex_attribs_vbo);
-    glVertexAttribPointer(resources.position_attr_loc, 3, GL_FLOAT,
+    glBindBuffer(GL_ARRAY_BUFFER, vertex_attribs_vbo);
+    glVertexAttribPointer(position_attr_loc, 3, GL_FLOAT,
                           GL_FALSE, sizeof(VertexAttributes), 0);
-    glVertexAttribPointer(resources.texcoord_attr_loc, 2, GL_FLOAT,
+    glVertexAttribPointer(texcoord_attr_loc, 2, GL_FLOAT,
                           GL_FALSE, sizeof(VertexAttributes),
                           reinterpret_cast<void*>(sizeof(glm::vec3)));
 
     /* Use the renderable's texture */
-    glBindTexture(GL_TEXTURE_2D, resources.texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
 
     buffer.bind_to_texture();
 
     /* Draw */
-    glEnableVertexAttribArray(resources.position_attr_loc);
-    glEnableVertexAttribArray(resources.texcoord_attr_loc);
+    glEnableVertexAttribArray(position_attr_loc);
+    glEnableVertexAttribArray(texcoord_attr_loc);
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    glDisableVertexAttribArray(resources.texcoord_attr_loc);
-    glDisableVertexAttribArray(resources.position_attr_loc);
+    glDisableVertexAttribArray(texcoord_attr_loc);
+    glDisableVertexAttribArray(position_attr_loc);
 }
 
-void mc::GLRenderer::clear() const
+void mc::GLRenderer::begin() const
 {
     glClear(GL_COLOR_BUFFER_BIT);
 }
+
+void mc::GLRenderer::end() const
+{
+}

=== modified file 'src/server/compositor/gl_renderer.h'
--- src/server/compositor/gl_renderer.h	2013-12-17 18:24:51 +0000
+++ src/server/compositor/gl_renderer.h	2014-01-02 07:37:29 +0000
@@ -32,32 +32,22 @@
 {
 public:
     GLRenderer(geometry::Rectangle const& display_area);
+    virtual ~GLRenderer() noexcept;
 
+    void begin() const override;
     void render(CompositingCriteria const& info, graphics::Buffer& buffer) const override;
-    void clear() const override;
-
-    ~GLRenderer() noexcept {}
+    void end() const override;
 
 private:
-    class Resources
-    {
-    public:
-        Resources();
-        ~Resources();
-        void setup(geometry::Rectangle const& display_area);
-
-        GLuint vertex_shader;
-        GLuint fragment_shader;
-        GLuint program;
-        GLuint position_attr_loc;
-        GLuint texcoord_attr_loc;
-        GLuint transform_uniform_loc;
-        GLuint alpha_uniform_loc;
-        GLuint vertex_attribs_vbo;
-        GLuint texture;
-    };
-
-    Resources resources;
+    GLuint vertex_shader;
+    GLuint fragment_shader;
+    GLuint program;
+    GLuint position_attr_loc;
+    GLuint texcoord_attr_loc;
+    GLuint transform_uniform_loc;
+    GLuint alpha_uniform_loc;
+    GLuint vertex_attribs_vbo;
+    GLuint texture;
 };
 
 }

=== modified file 'src/server/compositor/renderer.h'
--- src/server/compositor/renderer.h	2013-12-17 18:24:51 +0000
+++ src/server/compositor/renderer.h	2014-01-02 07:37:29 +0000
@@ -34,8 +34,9 @@
 public:
     virtual ~Renderer() = default;
 
-    virtual void clear() const = 0;
+    virtual void begin() const = 0;
     virtual void render(CompositingCriteria const& info, graphics::Buffer& buffer) const = 0;
+    virtual void end() const = 0;
 
 protected:
     Renderer() = default;

=== modified file 'src/server/logging/input_report.cpp'
--- src/server/logging/input_report.cpp	2013-12-19 16:33:56 +0000
+++ src/server/logging/input_report.cpp	2014-01-02 07:37:29 +0000
@@ -18,6 +18,7 @@
 
 #include "mir/logging/input_report.h"
 #include "mir/logging/logger.h"
+#include "mir/logging/input_timestamp.h"
 
 #include "std/MirLog.h"
 #include <std/Log.h>
@@ -108,7 +109,7 @@
     std::stringstream ss;
 
     ss << "Received event"
-       << " time=" << when
+       << " time=" << ml::input_timestamp(when)
        << " type=" << type
        << " code=" << code
        << " value=" << value;
@@ -122,7 +123,7 @@
 
     ss << "Published key event"
        << " seq_id=" << seq_id
-       << " time=" << event_time
+       << " time=" << ml::input_timestamp(event_time)
        << " dest_fd=" << dest_fd;
 
     logger->log(Logger::informational, ss.str(), component());
@@ -134,7 +135,7 @@
 
     ss << "Published motion event"
        << " seq_id=" << seq_id
-       << " time=" << event_time
+       << " time=" << ml::input_timestamp(event_time)
        << " dest_fd=" << dest_fd;
 
     logger->log(Logger::informational, ss.str(), component());

=== modified file 'src/shared/logging/CMakeLists.txt'
--- src/shared/logging/CMakeLists.txt	2013-12-12 07:51:12 +0000
+++ src/shared/logging/CMakeLists.txt	2014-01-02 07:37:29 +0000
@@ -16,4 +16,5 @@
 
 add_library(mirsharedlogging STATIC
   dumb_console_logger.cpp
+  input_timestamp.cpp
 )

=== added file 'src/shared/logging/input_timestamp.cpp'
--- src/shared/logging/input_timestamp.cpp	1970-01-01 00:00:00 +0000
+++ src/shared/logging/input_timestamp.cpp	2014-01-02 07:37:29 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
+ */
+
+#include "mir/logging/input_timestamp.h"
+#include <ctime>
+#include <cstdio>
+#include <string>
+
+std::string mir::logging::input_timestamp(nsecs_t when)
+{
+    // Input events use CLOCK_REALTIME, and so we must...
+    struct timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+
+    nsecs_t now = ts.tv_sec * 1000000000LL + ts.tv_nsec;
+    nsecs_t age = now - when;
+
+    char str[64];
+    snprintf(str, sizeof str, "%lld (%ld.%06ld ms ago)",
+             static_cast<long long>(when),
+             static_cast<long>(age / 1000000LL),
+             static_cast<long>(age % 1000000LL));
+
+    return std::string(str);
+}
+

=== modified file 'tests/acceptance-tests/test_server_shutdown.cpp'
--- tests/acceptance-tests/test_server_shutdown.cpp	2013-12-17 18:24:51 +0000
+++ tests/acceptance-tests/test_server_shutdown.cpp	2014-01-02 07:37:29 +0000
@@ -48,6 +48,10 @@
 class NullRenderer : public mc::Renderer
 {
 public:
+    void begin() const override
+    {
+    }
+
     void render(mc::CompositingCriteria const&, mg::Buffer&) const override
     {
         /*
@@ -58,7 +62,7 @@
         std::this_thread::yield();
     }
 
-    void clear() const override
+    void end() const override
     {
     }
 };

=== modified file 'tests/integration-tests/test_session.cpp'
--- tests/integration-tests/test_session.cpp	2013-12-17 18:24:51 +0000
+++ tests/integration-tests/test_session.cpp	2014-01-02 07:37:29 +0000
@@ -87,12 +87,15 @@
     {
         struct StubRenderer : public mc::Renderer
         {
-            void clear() const override
+            void begin() const override
             {
             }
             void render(mc::CompositingCriteria const&, mg::Buffer&) const override
             {
             }
+            void end() const override
+            {
+            }
         };
 
         struct StubRendererFactory : public mc::RendererFactory

=== modified file 'tests/integration-tests/test_surface_first_frame_sync.cpp'
--- tests/integration-tests/test_surface_first_frame_sync.cpp	2013-12-17 18:24:51 +0000
+++ tests/integration-tests/test_surface_first_frame_sync.cpp	2014-01-02 07:37:29 +0000
@@ -96,7 +96,7 @@
     {
     }
 
-    void clear() const override
+    void begin() const override
     {
     }
 
@@ -105,6 +105,10 @@
         while (write(render_operations_fd, "a", 1) != 1) continue;
     }
 
+    void end() const override
+    {
+    }
+
 private:
     int render_operations_fd;
 };

=== modified file 'tests/mir_test_framework/stubbed_server_configuration.cpp'
--- tests/mir_test_framework/stubbed_server_configuration.cpp	2013-12-19 16:34:53 +0000
+++ tests/mir_test_framework/stubbed_server_configuration.cpp	2014-01-02 07:37:29 +0000
@@ -201,11 +201,15 @@
 class StubRenderer : public mc::Renderer
 {
 public:
+    void begin() const override
+    {
+    }
+
     void render(mc::CompositingCriteria const&, mg::Buffer&) const override
     {
     }
 
-    void clear() const override
+    void end() const override
     {
     }
 };

=== modified file 'tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp'
--- tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp	2013-12-17 18:24:51 +0000
+++ tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp	2014-01-02 07:37:29 +0000
@@ -106,9 +106,9 @@
     {
     }
 
-    void clear() const override
+    void begin() const override
     {
-        renderer->clear();
+        renderer->begin();
     }
 
     void render(mc::CompositingCriteria const& criteria, mg::Buffer& buffer) const override
@@ -116,6 +116,11 @@
         renderer->render(criteria, buffer);
     }
 
+    void end() const override
+    {
+        renderer->end();
+    }
+
     mc::Renderer* const renderer;
 };
 
@@ -241,10 +246,14 @@
     renderable_vec.push_back(&small);
     renderable_vec.push_back(&fullscreen);
 
+    EXPECT_CALL(renderer_factory.mock_renderer, begin())
+        .Times(0);
     EXPECT_CALL(renderer_factory.mock_renderer, render(Ref(small),_))
         .Times(0);
     EXPECT_CALL(renderer_factory.mock_renderer, render(Ref(fullscreen),_))
         .Times(0);
+    EXPECT_CALL(renderer_factory.mock_renderer, end())
+        .Times(0);
 
     FakeScene scene(renderable_vec);
 
@@ -263,6 +272,58 @@
     comp->composite();
 }
 
+TEST(DefaultDisplayBufferCompositor, calls_renderer_in_sequence)
+{
+    using namespace testing;
+
+    StubRendererFactory renderer_factory;
+
+    geom::Rectangle screen{{0, 0}, {1366, 768}};
+
+    mtd::MockDisplayBuffer display_buffer;
+
+    EXPECT_CALL(display_buffer, view_area())
+        .WillRepeatedly(Return(screen));
+    EXPECT_CALL(display_buffer, can_bypass())
+        .WillRepeatedly(Return(false));
+
+    mtd::StubCompositingCriteria big(5, 10, 100, 200);
+    mtd::StubCompositingCriteria small(10, 20, 30, 40);
+
+    std::vector<mc::CompositingCriteria*> renderable_vec;
+    renderable_vec.push_back(&big);
+    renderable_vec.push_back(&small);
+
+    Sequence render_seq;
+
+    EXPECT_CALL(display_buffer, make_current())
+        .InSequence(render_seq);
+    EXPECT_CALL(renderer_factory.mock_renderer, begin())
+        .InSequence(render_seq);
+    EXPECT_CALL(renderer_factory.mock_renderer, render(Ref(big),_))
+        .InSequence(render_seq);
+    EXPECT_CALL(renderer_factory.mock_renderer, render(Ref(small),_))
+        .InSequence(render_seq);
+    EXPECT_CALL(renderer_factory.mock_renderer, end())
+        .InSequence(render_seq);
+    EXPECT_CALL(display_buffer, post_update())
+        .InSequence(render_seq);
+
+    FakeScene scene(renderable_vec);
+
+    auto compositor_buffer = std::make_shared<mtd::MockBuffer>();
+    EXPECT_CALL(*compositor_buffer, can_bypass())
+        .Times(0);
+
+    mc::DefaultDisplayBufferCompositorFactory factory(
+        mt::fake_shared(scene),
+        mt::fake_shared(renderer_factory));
+
+    auto comp = factory.create_compositor_for(display_buffer);
+
+    comp->composite();
+}
+
 TEST(DefaultDisplayBufferCompositor, obscured_fullscreen_does_not_bypass)
 {
     using namespace testing;

=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
--- tests/unit-tests/graphics/CMakeLists.txt	2013-12-19 19:05:57 +0000
+++ tests/unit-tests/graphics/CMakeLists.txt	2014-01-02 07:37:29 +0000
@@ -6,6 +6,7 @@
     ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/test_pixel_format_utils.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test_surfaceless_egl_context.cpp
 )
 

=== added file 'tests/unit-tests/graphics/test_pixel_format_utils.cpp'
--- tests/unit-tests/graphics/test_pixel_format_utils.cpp	1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/test_pixel_format_utils.cpp	2014-01-02 07:37:29 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
+ */
+
+#include "mir_toolkit/common.h"
+#include "mir/graphics/pixel_format_utils.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace mir::graphics;
+TEST(MirPixelformat, contains_alpha)
+{
+    EXPECT_FALSE(contains_alpha(mir_pixel_format_xbgr_8888));
+    EXPECT_FALSE(contains_alpha(mir_pixel_format_bgr_888));
+    EXPECT_FALSE(contains_alpha(mir_pixel_format_xrgb_8888));
+    EXPECT_FALSE(contains_alpha(mir_pixel_format_xbgr_8888));
+    EXPECT_TRUE(contains_alpha(mir_pixel_format_argb_8888));
+    EXPECT_TRUE(contains_alpha(mir_pixel_format_abgr_8888));
+    EXPECT_FALSE(contains_alpha(mir_pixel_format_invalid));
+} 
+
+TEST(MirPixelformat, red_channel_depths)
+{
+    EXPECT_EQ(8, red_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, red_channel_depth(mir_pixel_format_bgr_888));
+    EXPECT_EQ(8, red_channel_depth(mir_pixel_format_xrgb_8888));
+    EXPECT_EQ(8, red_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, red_channel_depth(mir_pixel_format_argb_8888));
+    EXPECT_EQ(8, red_channel_depth(mir_pixel_format_abgr_8888));
+    EXPECT_EQ(0, red_channel_depth(mir_pixel_format_invalid));
+}
+
+TEST(MirPixelformat, blue_channel_depths)
+{
+    EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_bgr_888));
+    EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_xrgb_8888));
+    EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_argb_8888));
+    EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_abgr_8888));
+    EXPECT_EQ(0, blue_channel_depth(mir_pixel_format_invalid));
+}
+
+TEST(MirPixelformat, green_channel_depths)
+{
+    EXPECT_EQ(8, green_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, green_channel_depth(mir_pixel_format_bgr_888));
+    EXPECT_EQ(8, green_channel_depth(mir_pixel_format_xrgb_8888));
+    EXPECT_EQ(8, green_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, green_channel_depth(mir_pixel_format_argb_8888));
+    EXPECT_EQ(8, green_channel_depth(mir_pixel_format_abgr_8888));
+    EXPECT_EQ(0, green_channel_depth(mir_pixel_format_invalid));
+}
+
+
+TEST(MirPixelformat, alpha_channel_depths)
+{
+    EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_bgr_888));
+    EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_xrgb_8888));
+    EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_xbgr_8888));
+    EXPECT_EQ(8, alpha_channel_depth(mir_pixel_format_argb_8888));
+    EXPECT_EQ(8, alpha_channel_depth(mir_pixel_format_abgr_8888));
+    EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_invalid));
+}
+
+TEST(MirPixelformat, valid_format)
+{
+    EXPECT_TRUE(valid_format(mir_pixel_format_xbgr_8888));
+    EXPECT_TRUE(valid_format(mir_pixel_format_bgr_888));
+    EXPECT_TRUE(valid_format(mir_pixel_format_xrgb_8888));
+    EXPECT_TRUE(valid_format(mir_pixel_format_xbgr_8888));
+    EXPECT_TRUE(valid_format(mir_pixel_format_argb_8888));
+    EXPECT_TRUE(valid_format(mir_pixel_format_abgr_8888));
+    EXPECT_FALSE(valid_format(mir_pixel_format_invalid));
+}

