Mir

Merge lp:~kdub/mir/n7-support into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1222
Proposed branch: lp:~kdub/mir/n7-support
Merge into: lp:mir
Diff against target: 1174 lines (+277/-420)
12 files modified
include/test/mir_test_doubles/mock_hwc_composer_device_1.h (+10/-2)
src/server/graphics/android/hwc10_device.cpp (+7/-9)
src/server/graphics/android/hwc10_device.h (+3/-0)
src/server/graphics/android/hwc11_device.cpp (+10/-9)
src/server/graphics/android/hwc11_device.h (+3/-5)
src/server/graphics/android/hwc_layerlist.cpp (+81/-102)
src/server/graphics/android/hwc_layerlist.h (+35/-59)
src/server/graphics/android/resource_factory.cpp (+1/-2)
tests/unit-tests/graphics/android/test_hwc10_device.cpp (+5/-8)
tests/unit-tests/graphics/android/test_hwc11_device.cpp (+14/-50)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+13/-40)
tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+95/-134)
To merge this branch: bzr merge lp:~kdub/mir/n7-support
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Alexandros Frantzis (community) Needs Fixing
Daniel van Vugt manual testing Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+194599@code.launchpad.net

Commit message

graphics: android: support 'old aka 2012' nexus 7 hwc (nvidia tegra3 SoC) better.

Description of the change

graphics: android: support 'old aka 2012' nexus 7 hwc (nvidia tegra3 SoC) better.

improve hwc1.0 support to avert segfaulting on mir startup with hwc1.0 on tegra 3.
Mir demo clients seem to work well. Unity8 is still affected by lp:1238695

improve HWCLayerList class a bit as well. Before it was just made one layer on construction, now you can use an initializer list to have multiple layers.

These are hwc1.0 changes primarily, so I gave a basic sanity test to:
Galaxy Nexus (hwc1.0)
Nexus 7 (hwc1.0)
Nexus 4 (hwc1.1)

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
Daniel van Vugt (vanvugt) wrote :

Seems to run fine on the N7. Although I don't see any change in performance compared to trunk. Should there be an improvement?

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

54 + layer_list({mga::CompositionLayer{true}}),

'true' is not very informative in this context. Perhaps use an enum?

491 + HWCLayer& operator=(HWCLayer const& layer)
492 + {
493 + memcpy(this, &layer, sizeof(HWCLayer));
494 + this->visibleRegionScreen = {1, &this->visible_rect};
495 + return *this;
496 + }
497 +
498 + HWCLayer(HWCLayer const& layer)
499 + {
500 + memcpy(this, &layer, sizeof(HWCLayer));
501 + this->visibleRegionScreen = {1, &this->visible_rect};
502 + }

Could (should) be in .cpp file.

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

> Seems to run fine on the N7. Although I don't see any change in performance
> compared to trunk. Should there be an improvement?

Stock images are missing hwcomposer.tegra3.so last I checked, so these changes won't really affect much until that library is returned to the build. I don't expect much performance change from this patch

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

> 'true' is not very informative in this context. Perhaps use an enum?
fair enough, used the existing enum from hwcomposer, HWC_SKIP_LAYER.

> Could (should) be in .cpp file.
moved to a cpp

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

> Stock images are missing hwcomposer.tegra3.so last I checked, so these changes
> won't really affect much until that library is returned to the build. I don't
> expect much performance change from this patch

Is there a bug for that?

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

> 'true' is not very informative in this context. Perhaps use an enum?
> fair enough, used the existing enum from hwcomposer, HWC_SKIP_LAYER.

54 + layer_list({mga::CompositionLayer{true}}),

It's still there :)

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

> > 'true' is not very informative in this context. Perhaps use an enum?
> > fair enough, used the existing enum from hwcomposer, HWC_SKIP_LAYER.
>
> 54 + layer_list({mga::CompositionLayer{true}}),
>
> It's still there :)

"true" an unusual synonym for 1.

(Is there any good reason this constructor takes an int rather than an enum class?)

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

> "true" an unusual synonym for 1.
yeah, an oversight when I was updating. will fix.

> (Is there any good reason this constructor takes an int rather than an enum
> class?)

we're using a header from android for this enum, which is unamed
http://bazaar.launchpad.net/~mir-team/mir/trusty/view/head:/3rd_party/android-deps/hardware/hwcomposer_defs.h#L74

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

> Is there a bug for that?

not that I know of, I'll file one once this lands (less disruption that way)

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

OK I don't see anything I object too.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/test/mir_test_doubles/mock_hwc_composer_device_1.h'
--- include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2013-04-24 05:22:20 +0000
+++ include/test/mir_test_doubles/mock_hwc_composer_device_1.h 2013-11-12 23:50:30 +0000
@@ -21,6 +21,8 @@
2121
22#include <hardware/hwcomposer.h>22#include <hardware/hwcomposer.h>
23#include <gmock/gmock.h>23#include <gmock/gmock.h>
24#include <vector>
25#include <memory>
2426
25namespace mir27namespace mir
26{28{
@@ -59,10 +61,9 @@
5961
60 hwc_display_contents_1_t* primary_display = *in;62 hwc_display_contents_1_t* primary_display = *in;
61 memcpy(out, primary_display, sizeof(hwc_display_contents_1_t));63 memcpy(out, primary_display, sizeof(hwc_display_contents_1_t));
62
63 return 0;64 return 0;
65 }
6466
65 }
66 int save_last_prepare_arguments(struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays)67 int save_last_prepare_arguments(struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays)
67 {68 {
68 return save_args(&display0_prepare_content, displays);69 return save_args(&display0_prepare_content, displays);
@@ -70,6 +71,12 @@
7071
71 int save_last_set_arguments(struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays)72 int save_last_set_arguments(struct hwc_composer_device_1 *, size_t, hwc_display_contents_1_t** displays)
72 {73 {
74 hwc_display_contents_1_t* display = *displays;
75 for(auto i = 0u; i < display->numHwLayers; i++)
76 {
77 set_layerlist.push_back(display->hwLayers[i]);
78 set_layerlist.back().visibleRegionScreen = {0, nullptr};
79 }
73 return save_args(&display0_set_content, displays);80 return save_args(&display0_set_content, displays);
74 }81 }
7582
@@ -120,6 +127,7 @@
120 MOCK_METHOD5(getDisplayAttributes_interface, int(struct hwc_composer_device_1*, int, uint32_t, const uint32_t*, int32_t*));127 MOCK_METHOD5(getDisplayAttributes_interface, int(struct hwc_composer_device_1*, int, uint32_t, const uint32_t*, int32_t*));
121128
122 hwc_display_contents_1_t display0_set_content;129 hwc_display_contents_1_t display0_set_content;
130 std::vector<hwc_layer_1> set_layerlist;
123 hwc_display_contents_1_t display0_prepare_content;131 hwc_display_contents_1_t display0_prepare_content;
124};132};
125133
126134
=== modified file 'src/server/graphics/android/hwc10_device.cpp'
--- src/server/graphics/android/hwc10_device.cpp 2013-10-25 16:39:50 +0000
+++ src/server/graphics/android/hwc10_device.cpp 2013-11-12 23:50:30 +0000
@@ -30,6 +30,7 @@
30 std::shared_ptr<DisplayDevice> const& fbdev,30 std::shared_ptr<DisplayDevice> const& fbdev,
31 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)31 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)
32 : HWCCommonDevice(hwc_device, coordinator),32 : HWCCommonDevice(hwc_device, coordinator),
33 layer_list({mga::CompositionLayer{HWC_SKIP_LAYER}}),
33 fb_device(fbdev),34 fb_device(fbdev),
34 wait_for_vsync(true)35 wait_for_vsync(true)
35{36{
@@ -63,20 +64,17 @@
63{64{
64 auto lg = lock_unblanked();65 auto lg = lock_unblanked();
6566
66 hwc_display_contents_1 display_contents;67 auto display_list = layer_list.native_list();
67 display_contents.dpy = dpy;68 display_list->dpy = dpy;
68 display_contents.sur = sur;69 display_list->sur = sur;
69 display_contents.retireFenceFd = -1;
70 display_contents.flags = 0;
71 display_contents.numHwLayers = 0;
72 hwc_display_contents_1* contents = &display_contents;
7370
74 auto rc = hwc_device->prepare(hwc_device.get(), 1, &contents);71 auto rc = hwc_device->prepare(hwc_device.get(), 1, &display_list);
75 if (rc != 0)72 if (rc != 0)
76 {73 {
77 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc prepare()"));74 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc prepare()"));
78 }75 }
79 rc = hwc_device->set(hwc_device.get(), 1, &contents);76
77 rc = hwc_device->set(hwc_device.get(), 1, &display_list);
80 if (rc != 0)78 if (rc != 0)
81 {79 {
82 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));80 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));
8381
=== modified file 'src/server/graphics/android/hwc10_device.h'
--- src/server/graphics/android/hwc10_device.h 2013-10-25 16:39:50 +0000
+++ src/server/graphics/android/hwc10_device.h 2013-11-12 23:50:30 +0000
@@ -19,6 +19,7 @@
19#ifndef MIR_GRAPHICS_ANDROID_HWC10_DEVICE_H_19#ifndef MIR_GRAPHICS_ANDROID_HWC10_DEVICE_H_
20#define MIR_GRAPHICS_ANDROID_HWC10_DEVICE_H_20#define MIR_GRAPHICS_ANDROID_HWC10_DEVICE_H_
21#include "hwc_common_device.h"21#include "hwc_common_device.h"
22#include "hwc_layerlist.h"
2223
23namespace mir24namespace mir
24{25{
@@ -44,6 +45,8 @@
44 void commit_frame(EGLDisplay dpy, EGLSurface sur);45 void commit_frame(EGLDisplay dpy, EGLSurface sur);
4546
46private:47private:
48 LayerList layer_list;
49
47 std::shared_ptr<DisplayDevice> const fb_device;50 std::shared_ptr<DisplayDevice> const fb_device;
48 bool wait_for_vsync;51 bool wait_for_vsync;
49};52};
5053
=== modified file 'src/server/graphics/android/hwc11_device.cpp'
--- src/server/graphics/android/hwc11_device.cpp 2013-10-31 16:37:35 +0000
+++ src/server/graphics/android/hwc11_device.cpp 2013-11-12 23:50:30 +0000
@@ -22,6 +22,8 @@
22#include "hwc_vsync_coordinator.h"22#include "hwc_vsync_coordinator.h"
23#include "android_format_conversion-inl.h"23#include "android_format_conversion-inl.h"
24#include "mir/graphics/android/sync_fence.h"24#include "mir/graphics/android/sync_fence.h"
25#include "mir/graphics/android/native_buffer.h"
26#include "mir/graphics/buffer.h"
2527
26#include <EGL/eglext.h>28#include <EGL/eglext.h>
27#include <boost/throw_exception.hpp>29#include <boost/throw_exception.hpp>
@@ -70,12 +72,9 @@
70}72}
7173
72mga::HWC11Device::HWC11Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device,74mga::HWC11Device::HWC11Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
73 std::shared_ptr<HWCLayerList> const& layer_list,
74 std::shared_ptr<DisplayDevice> const& fbdev,
75 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)75 std::shared_ptr<HWCVsyncCoordinator> const& coordinator)
76 : HWCCommonDevice(hwc_device, coordinator),76 : HWCCommonDevice(hwc_device, coordinator),
77 layer_list(layer_list),77 layer_list({mga::FramebufferLayer{}}),
78 fb_device(fbdev),
79 sync_ops(std::make_shared<mga::RealSyncFileOps>()),78 sync_ops(std::make_shared<mga::RealSyncFileOps>()),
80 fb_format(determine_fb_format())79 fb_format(determine_fb_format())
81{80{
@@ -118,16 +117,19 @@
118117
119void mga::HWC11Device::set_next_frontbuffer(std::shared_ptr<mg::Buffer> const& buffer)118void mga::HWC11Device::set_next_frontbuffer(std::shared_ptr<mg::Buffer> const& buffer)
120{119{
121 layer_list->set_fb_target(buffer);120 layer_list.set_fb_target(buffer->native_buffer_handle());
121 //TODO: wait for framebuffer render to complete here. Eventually, we want to pass the fence right
122 // into hwc_device->set() and let that wait for the render to complete.
123 buffer->native_buffer_handle()->wait_for_content();
122}124}
123125
124void mga::HWC11Device::commit_frame(EGLDisplay dpy, EGLSurface sur)126void mga::HWC11Device::commit_frame(EGLDisplay dpy, EGLSurface sur)
125{127{
126 auto lg = lock_unblanked();128 auto lg = lock_unblanked();
127129
128 //note, although we only have a primary display right now,130 //note, although we only have a primary display right now,
129 // set the second display to nullptr, as exynos hwc always derefs displays[1]131 // set the second display to nullptr, as exynos hwc always derefs displays[1]
130 hwc_display_contents_1_t* displays[HWC_NUM_DISPLAY_TYPES] {layer_list->native_list(), nullptr};132 hwc_display_contents_1_t* displays[HWC_NUM_DISPLAY_TYPES] {layer_list.native_list(), nullptr};
131133
132 if (hwc_device->prepare(hwc_device.get(), 1, displays))134 if (hwc_device->prepare(hwc_device.get(), 1, displays))
133 {135 {
@@ -135,7 +137,7 @@
135 }137 }
136138
137 /* note, swapbuffers will go around through the driver and call139 /* note, swapbuffers will go around through the driver and call
138 set_next_frontbuffer, updating the fb target before committing */140 set_next_frontbuffer, updating the fb in layerlist before committing */
139 if (eglSwapBuffers(dpy, sur) == EGL_FALSE)141 if (eglSwapBuffers(dpy, sur) == EGL_FALSE)
140 {142 {
141 BOOST_THROW_EXCEPTION(std::runtime_error("error during eglSwapBuffers"));143 BOOST_THROW_EXCEPTION(std::runtime_error("error during eglSwapBuffers"));
@@ -145,7 +147,6 @@
145 {147 {
146 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));148 BOOST_THROW_EXCEPTION(std::runtime_error("error during hwc set()"));
147 }149 }
148
149 mga::SyncFence fence(sync_ops, displays[HWC_DISPLAY_PRIMARY]->retireFenceFd);150 mga::SyncFence fence(sync_ops, displays[HWC_DISPLAY_PRIMARY]->retireFenceFd);
150 fence.wait();151 fence.wait();
151}152}
152153
=== modified file 'src/server/graphics/android/hwc11_device.h'
--- src/server/graphics/android/hwc11_device.h 2013-10-31 16:27:43 +0000
+++ src/server/graphics/android/hwc11_device.h 2013-11-12 23:50:30 +0000
@@ -19,6 +19,7 @@
19#ifndef MIR_GRAPHICS_ANDROID_HWC11_DEVICE_H_19#ifndef MIR_GRAPHICS_ANDROID_HWC11_DEVICE_H_
20#define MIR_GRAPHICS_ANDROID_HWC11_DEVICE_H_20#define MIR_GRAPHICS_ANDROID_HWC11_DEVICE_H_
21#include "hwc_common_device.h"21#include "hwc_common_device.h"
22#include "hwc_layerlist.h"
22#include <memory>23#include <memory>
2324
24namespace mir25namespace mir
@@ -29,7 +30,6 @@
2930
30namespace android31namespace android
31{32{
32class HWCLayerList;
33class HWCVsyncCoordinator;33class HWCVsyncCoordinator;
34class SyncFileOps;34class SyncFileOps;
3535
@@ -37,8 +37,6 @@
37{37{
38public:38public:
39 HWC11Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device,39 HWC11Device(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
40 std::shared_ptr<HWCLayerList> const& layer_list,
41 std::shared_ptr<DisplayDevice> const& fbdev,
42 std::shared_ptr<HWCVsyncCoordinator> const& coordinator);40 std::shared_ptr<HWCVsyncCoordinator> const& coordinator);
43 ~HWC11Device() noexcept;41 ~HWC11Device() noexcept;
4442
@@ -51,8 +49,8 @@
51 void commit_frame(EGLDisplay dpy, EGLSurface sur);49 void commit_frame(EGLDisplay dpy, EGLSurface sur);
5250
53private:51private:
54 std::shared_ptr<HWCLayerList> const layer_list;52 LayerList layer_list;
55 std::shared_ptr<DisplayDevice> const fb_device;53
56 std::shared_ptr<SyncFileOps> const sync_ops;54 std::shared_ptr<SyncFileOps> const sync_ops;
57 unsigned int primary_display_config;55 unsigned int primary_display_config;
58 geometry::PixelFormat fb_format;56 geometry::PixelFormat fb_format;
5957
=== modified file 'src/server/graphics/android/hwc_layerlist.cpp'
--- src/server/graphics/android/hwc_layerlist.cpp 2013-10-16 03:27:36 +0000
+++ src/server/graphics/android/hwc_layerlist.cpp 2013-11-12 23:50:30 +0000
@@ -19,7 +19,6 @@
19#include "mir/graphics/android/sync_fence.h"19#include "mir/graphics/android/sync_fence.h"
20#include "mir/graphics/android/native_buffer.h"20#include "mir/graphics/android/native_buffer.h"
21#include "hwc_layerlist.h"21#include "hwc_layerlist.h"
22#include "buffer.h"
2322
24#include <cstring>23#include <cstring>
2524
@@ -27,112 +26,92 @@
27namespace mga=mir::graphics::android;26namespace mga=mir::graphics::android;
28namespace geom=mir::geometry;27namespace geom=mir::geometry;
2928
30mga::HWCRect::HWCRect()29mga::HWCLayer& mga::HWCLayer::operator=(HWCLayer const& layer)
31 : self{0,0,0,0}30{
32{31 memcpy(this, &layer, sizeof(HWCLayer));
33}32 this->visibleRegionScreen = {1, &this->visible_rect};
3433 return *this;
35mga::HWCRect::HWCRect(geom::Rectangle& rect)34}
36{35
37 self.top = rect.top_left.y.as_uint32_t();36mga::HWCLayer::HWCLayer(HWCLayer const& layer)
38 self.left = rect.top_left.x.as_uint32_t();37{
39 self.bottom= rect.size.height.as_uint32_t();38 memcpy(this, &layer, sizeof(HWCLayer));
40 self.right = rect.size.width.as_uint32_t();39 this->visibleRegionScreen = {1, &this->visible_rect};
41}40}
4241
43mga::HWCDefaultLayer::HWCDefaultLayer(std::initializer_list<mga::HWCRect> list)42mga::HWCLayer::HWCLayer(int type, buffer_handle_t buffer_handle, int width, int height, int layer_flags)
44{43{
45 /* default values.*/44 compositionType = type;
46 self.compositionType = HWC_FRAMEBUFFER_TARGET;45 hints = 0;
47 self.hints = 0;46 flags = layer_flags;
48 self.flags = 0;47 transform = 0;
49 self.transform = 0;48 blending = HWC_BLENDING_NONE;
50 self.blending = HWC_BLENDING_NONE;49 //TODO: acquireFenceFd should be buffer.fence()
51 self.acquireFenceFd = -1;50 acquireFenceFd = -1;
52 self.releaseFenceFd = -1;51 releaseFenceFd = -1;
5352
54 HWCRect emptyrect;53 visible_rect.top = 0;
55 self.sourceCrop = emptyrect;54 visible_rect.left = 0;
56 self.displayFrame = emptyrect;55 visible_rect.bottom = height;
57 self.visibleRegionScreen.numRects=list.size();56 visible_rect.right = width;
58 self.visibleRegionScreen.rects=nullptr;57 sourceCrop = visible_rect;
59 if (list.size() != 0)58 displayFrame = visible_rect;
60 {59 visibleRegionScreen.numRects=1;
61 auto rect_array = new hwc_rect_t[list.size()];60 visibleRegionScreen.rects= &visible_rect;
62 auto i = 0u;61 handle = buffer_handle;
63 for( auto& rect : list )62}
64 {63
65 rect_array[i++] = rect; 64mga::FramebufferLayer::FramebufferLayer()
66 }65 : HWCLayer(HWC_FRAMEBUFFER_TARGET, nullptr, 0, 0, 0)
67 self.visibleRegionScreen.rects = rect_array;66{
68 }67}
69}68
7069mga::FramebufferLayer::FramebufferLayer(mg::NativeBuffer const& buffer)
71mga::HWCDefaultLayer::~HWCDefaultLayer()70 : HWCLayer(HWC_FRAMEBUFFER_TARGET, buffer.handle(),
72{71 buffer.anwb()->width, buffer.anwb()->height, 0)
73 if (self.visibleRegionScreen.rects)72{
74 {73}
75 delete[] self.visibleRegionScreen.rects;74
76 }75mga::CompositionLayer::CompositionLayer(int layer_flags)
77}76 : HWCLayer(HWC_FRAMEBUFFER, nullptr, 0, 0, layer_flags)
7877{
79mga::HWCFBLayer::HWCFBLayer(78}
80 buffer_handle_t native_handle,79
81 HWCRect display_frame_rect)80mga::CompositionLayer::CompositionLayer(mg::NativeBuffer const& buffer, int layer_flags)
82 : HWCDefaultLayer{display_frame_rect}81 : HWCLayer(HWC_FRAMEBUFFER, buffer.handle(),
83{82 buffer.anwb()->width, buffer.anwb()->height, layer_flags)
84 self.compositionType = HWC_FRAMEBUFFER_TARGET;83{
8584}
86 self.handle = native_handle;85
87 self.sourceCrop = display_frame_rect;86mga::LayerList::LayerList(std::initializer_list<HWCLayer> const& layer_list)
88 self.displayFrame = display_frame_rect;87{
89}88 auto struct_size = sizeof(hwc_display_contents_1_t) + sizeof(hwc_layer_1_t)*(layer_list.size());
9089 hwc_representation = std::shared_ptr<hwc_display_contents_1_t>(
91mga::HWCFBLayer::HWCFBLayer()90 static_cast<hwc_display_contents_1_t*>( ::operator new(struct_size)));
92 : HWCFBLayer{nullptr, mga::HWCRect{}}
93{
94}
95
96mga::LayerList::LayerList()
97 : layer_list{std::make_shared<HWCFBLayer>()},
98 hwc_representation{std::make_shared<hwc_display_contents_1_t>()}
99{
100 memset(hwc_representation.get(), 0, sizeof(hwc_display_contents_1_t));
101 update_list();
102}
103
104void mga::LayerList::set_fb_target(std::shared_ptr<mg::Buffer> const& buffer)
105{
106 auto native_buffer = buffer->native_buffer_handle();
107 native_buffer->wait_for_content();
108
109 geom::Point pt{0, 0};
110 geom::Rectangle rect{pt, buffer->size()};
111 HWCRect display_rect(rect);
112
113 auto fb_layer = std::make_shared<HWCFBLayer>(native_buffer->handle(), display_rect);
114 layer_list[fb_position] = fb_layer;
115
116 update_list();
117}
118
119void mga::LayerList::update_list()
120{
121 if (layer_list.size() != hwc_representation->numHwLayers)
122 {
123 auto struct_size = sizeof(hwc_display_contents_1_t) + sizeof(hwc_layer_1_t)*(layer_list.size());
124 hwc_representation = std::shared_ptr<hwc_display_contents_1_t>(
125 static_cast<hwc_display_contents_1_t*>( ::operator new(struct_size)));
126
127 hwc_representation->numHwLayers = layer_list.size();
128 }
12991
130 auto i = 0u;92 auto i = 0u;
131 for( auto& layer : layer_list)93 for(auto& layer : layer_list)
132 {94 {
133 hwc_representation->hwLayers[i++] = *layer;95 hwc_representation->hwLayers[i++] = layer;
134 }96 }
97 hwc_representation->numHwLayers = layer_list.size();
135 hwc_representation->retireFenceFd = -1;98 hwc_representation->retireFenceFd = -1;
99 hwc_representation->flags = HWC_GEOMETRY_CHANGED;
100
101 //aosp exynos hwc in particular, checks that these fields are non-null in hwc1.1, although
102 //these fields are deprecated in hwc1.1 and later.
103 hwc_representation->dpy = reinterpret_cast<void*>(0xDECAF);
104 hwc_representation->sur = reinterpret_cast<void*>(0xC0FFEE);
105
106}
107
108void mga::LayerList::set_fb_target(std::shared_ptr<NativeBuffer> const& native_buffer)
109{
110 auto fb_position = hwc_representation->numHwLayers - 1;
111 if (hwc_representation->hwLayers[fb_position].compositionType == HWC_FRAMEBUFFER_TARGET)
112 {
113 hwc_representation->hwLayers[fb_position] = mga::FramebufferLayer(*native_buffer);
114 }
136}115}
137116
138hwc_display_contents_1_t* mga::LayerList::native_list() const117hwc_display_contents_1_t* mga::LayerList::native_list() const
139118
=== modified file 'src/server/graphics/android/hwc_layerlist.h'
--- src/server/graphics/android/hwc_layerlist.h 2013-09-11 00:50:04 +0000
+++ src/server/graphics/android/hwc_layerlist.h 2013-11-12 23:50:30 +0000
@@ -24,76 +24,52 @@
24#include <memory>24#include <memory>
25#include <vector>25#include <vector>
26#include <initializer_list>26#include <initializer_list>
27
27namespace mir28namespace mir
28{29{
29namespace graphics30namespace graphics
30{31{
32
33class NativeBuffer;
31class Buffer;34class Buffer;
3235
33namespace android36namespace android
34{37{
35 38
36struct HWCRect39struct HWCLayer : public hwc_layer_1
37{40{
38 HWCRect(); 41 virtual ~HWCLayer() = default;
39 HWCRect(geometry::Rectangle& rect);42
4043 HWCLayer& operator=(HWCLayer const& layer);
41 operator hwc_rect_t const& () const { return self; }44 HWCLayer(HWCLayer const& layer);
42 operator hwc_rect_t& () { return self; }45
43private:46protected:
44 hwc_rect_t self;47 HWCLayer(int type, buffer_handle_t handle, int width, int height, int layer_flags);
45};48
4649 hwc_rect_t visible_rect;
47struct HWCDefaultLayer50};
48{51
49 HWCDefaultLayer(std::initializer_list<HWCRect> list);52struct CompositionLayer : public HWCLayer
50 ~HWCDefaultLayer();53{
5154 CompositionLayer(int layer_flags);
52 operator hwc_layer_1 const& () const { return self; }55 CompositionLayer(NativeBuffer const&, int layer_flags);
53 operator hwc_layer_1& () { return self; }56};
5457
55protected:58struct FramebufferLayer : public HWCLayer
56 HWCDefaultLayer& operator=(HWCDefaultLayer const&) = delete;59{
57 HWCDefaultLayer(HWCDefaultLayer const&) = delete;60 FramebufferLayer();
5861 FramebufferLayer(NativeBuffer const&);
59 hwc_layer_1 self;62};
60};63
6164class LayerList
62struct HWCFBLayer : public HWCDefaultLayer65{
63{66public:
64 HWCFBLayer();67 LayerList(std::initializer_list<HWCLayer> const& layers);
65 HWCFBLayer(buffer_handle_t native_buf,68
66 HWCRect display_frame_rect);
67};
68
69class HWCLayerList
70{
71public:
72 virtual ~HWCLayerList() = default;
73
74 virtual hwc_display_contents_1_t* native_list() const = 0;
75 virtual void set_fb_target(std::shared_ptr<Buffer> const&) = 0;
76
77protected:
78 HWCLayerList() = default;
79 HWCLayerList& operator=(HWCLayerList const&) = delete;
80 HWCLayerList(HWCLayerList const&) = delete;
81
82};
83
84class LayerList : public HWCLayerList
85{
86public:
87 LayerList();
88
89 void set_fb_target(std::shared_ptr<Buffer> const&);
90 hwc_display_contents_1_t* native_list() const;69 hwc_display_contents_1_t* native_list() const;
70 void set_fb_target(std::shared_ptr<NativeBuffer> const&);
9171
92private:72private:
93 std::vector<std::shared_ptr<HWCDefaultLayer>> layer_list;
94 void update_list();
95
96 static size_t const fb_position = 0u;
97 std::shared_ptr<hwc_display_contents_1_t> hwc_representation;73 std::shared_ptr<hwc_display_contents_1_t> hwc_representation;
98};74};
9975
10076
=== modified file 'src/server/graphics/android/resource_factory.cpp'
--- src/server/graphics/android/resource_factory.cpp 2013-10-28 22:17:13 +0000
+++ src/server/graphics/android/resource_factory.cpp 2013-11-12 23:50:30 +0000
@@ -106,9 +106,8 @@
106std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc11_device(106std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc11_device(
107 std::shared_ptr<hwc_composer_device_1> const& hwc_native_device) const107 std::shared_ptr<hwc_composer_device_1> const& hwc_native_device) const
108{108{
109 auto layer_list = std::make_shared<mga::LayerList>();
110 auto syncer = std::make_shared<mga::HWCVsync>();109 auto syncer = std::make_shared<mga::HWCVsync>();
111 return std::make_shared<mga::HWC11Device>(hwc_native_device, layer_list, nullptr, syncer);110 return std::make_shared<mga::HWC11Device>(hwc_native_device, syncer);
112}111}
113112
114std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc10_device(113std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc10_device(
115114
=== modified file 'tests/unit-tests/graphics/android/test_hwc10_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc10_device.cpp 2013-10-25 16:39:50 +0000
+++ tests/unit-tests/graphics/android/test_hwc10_device.cpp 2013-11-12 23:50:30 +0000
@@ -86,14 +86,11 @@
86 EXPECT_EQ(dpy, mock_device->display0_set_content.dpy);86 EXPECT_EQ(dpy, mock_device->display0_set_content.dpy);
87 EXPECT_EQ(sur, mock_device->display0_set_content.sur);87 EXPECT_EQ(sur, mock_device->display0_set_content.sur);
88 EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd);88 EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd);
89 EXPECT_EQ(0u, mock_device->display0_set_content.flags);89 EXPECT_EQ(HWC_GEOMETRY_CHANGED, mock_device->display0_set_content.flags);
90 EXPECT_EQ(0u, mock_device->display0_set_content.numHwLayers);90 EXPECT_EQ(1u, mock_device->display0_set_content.numHwLayers);
9191 ASSERT_NE(nullptr, mock_device->display0_set_content.hwLayers);
92 EXPECT_EQ(dpy, mock_device->display0_prepare_content.dpy);92 EXPECT_EQ(HWC_FRAMEBUFFER, mock_device->set_layerlist[0].compositionType);
93 EXPECT_EQ(sur, mock_device->display0_prepare_content.sur);93 EXPECT_EQ(HWC_SKIP_LAYER, mock_device->set_layerlist[0].flags);
94 EXPECT_EQ(-1, mock_device->display0_prepare_content.retireFenceFd);
95 EXPECT_EQ(0u, mock_device->display0_prepare_content.flags);
96 EXPECT_EQ(0u, mock_device->display0_prepare_content.numHwLayers);
97}94}
9895
99TEST_F(HWC10Device, hwc10_commit_frame_async)96TEST_F(HWC10Device, hwc10_commit_frame_async)
10097
=== modified file 'tests/unit-tests/graphics/android/test_hwc11_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc11_device.cpp 2013-10-31 00:11:29 +0000
+++ tests/unit-tests/graphics/android/test_hwc11_device.cpp 2013-11-12 23:50:30 +0000
@@ -18,9 +18,7 @@
1818
19#include "src/server/graphics/android/hwc11_device.h"19#include "src/server/graphics/android/hwc11_device.h"
20#include "src/server/graphics/android/hwc_layerlist.h"20#include "src/server/graphics/android/hwc_layerlist.h"
21#include "mir_test_doubles/mock_display_device.h"
22#include "mir_test_doubles/mock_hwc_composer_device_1.h"21#include "mir_test_doubles/mock_hwc_composer_device_1.h"
23#include "mir_test_doubles/mock_hwc_layerlist.h"
24#include "mir_test_doubles/mock_buffer.h"22#include "mir_test_doubles/mock_buffer.h"
25#include "mir_test_doubles/mock_hwc_vsync_coordinator.h"23#include "mir_test_doubles/mock_hwc_vsync_coordinator.h"
26#include "mir_test_doubles/mock_egl.h"24#include "mir_test_doubles/mock_egl.h"
@@ -38,49 +36,27 @@
38 virtual void SetUp()36 virtual void SetUp()
39 {37 {
40 mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>();38 mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>();
41 mock_display_device = std::make_shared<testing::NiceMock<mtd::MockDisplayDevice>>();
42 mock_hwc_layers = std::make_shared<testing::NiceMock<mtd::MockHWCLayerList>>();
43 mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>();39 mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>();
44 mock_egl.silence_uninteresting();
45
46 empty_list.numHwLayers = 0;
47 empty_list.retireFenceFd = -1;
48 ON_CALL(*mock_hwc_layers, native_list())
49 .WillByDefault(testing::Return(&empty_list));
50 }40 }
5141
52 std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync;42 std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync;
53 std::shared_ptr<mtd::MockHWCLayerList> mock_hwc_layers;
54 std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device;43 std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device;
55 std::shared_ptr<mtd::MockDisplayDevice> mock_display_device;
56 EGLDisplay dpy;44 EGLDisplay dpy;
57 EGLSurface surf;45 EGLSurface surf;
58 testing::NiceMock<mtd::MockEGL> mock_egl;46 testing::NiceMock<mtd::MockEGL> mock_egl;
59 hwc_display_contents_1_t empty_list;47};
60};
61
62namespace
63{
64struct HWCDummyLayer : public mga::HWCDefaultLayer
65{
66 HWCDummyLayer()
67 : HWCDefaultLayer({})
68 {
69 }
70};
71}
7248
73TEST_F(HWC11Device, test_hwc_gles_set_empty_layerlist)49TEST_F(HWC11Device, test_hwc_gles_set_empty_layerlist)
74{50{
75 using namespace testing;51 using namespace testing;
7652
77 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);53 mga::HWC11Device device(mock_device, mock_vsync);
7854
79 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _))55 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _))
80 .Times(1);56 .Times(1);
81 device.commit_frame(dpy, surf);57 device.commit_frame(dpy, surf);
8258
83 EXPECT_EQ(empty_list.numHwLayers, mock_device->display0_set_content.numHwLayers);59 EXPECT_EQ(1, mock_device->display0_set_content.numHwLayers);
84 EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd);60 EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd);
85}61}
8662
@@ -88,7 +64,7 @@
88{64{
89 using namespace testing;65 using namespace testing;
9066
91 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);67 mga::HWC11Device device(mock_device, mock_vsync);
9268
93 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _))69 EXPECT_CALL(*mock_device, set_interface(mock_device.get(), 1, _))
94 .Times(1)70 .Times(1)
@@ -106,7 +82,7 @@
106 .Times(1)82 .Times(1)
107 .WillOnce(Return(EGL_FALSE));83 .WillOnce(Return(EGL_FALSE));
10884
109 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);85 mga::HWC11Device device(mock_device, mock_vsync);
11086
111 EXPECT_THROW({87 EXPECT_THROW({
112 device.commit_frame(dpy, surf);88 device.commit_frame(dpy, surf);
@@ -117,13 +93,11 @@
117{93{
118 using namespace testing;94 using namespace testing;
11995
120 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);96 mga::HWC11Device device(mock_device, mock_vsync);
12197
122 //the order here is very important. eglSwapBuffers will alter the layerlist,98 //the order here is very important. eglSwapBuffers will alter the layerlist,
123 //so it must come before assembling the data for set99 //so it must come before assembling the data for set
124 InSequence seq;100 InSequence seq;
125 EXPECT_CALL(*mock_hwc_layers, native_list())
126 .Times(1);
127 EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _))101 EXPECT_CALL(*mock_device, prepare_interface(mock_device.get(), 1, _))
128 .Times(1);102 .Times(1);
129 EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf))103 EXPECT_CALL(mock_egl, eglSwapBuffers(dpy,surf))
@@ -133,22 +107,12 @@
133107
134 device.commit_frame(dpy, surf);108 device.commit_frame(dpy, surf);
135109
136 EXPECT_EQ(empty_list.numHwLayers, mock_device->display0_prepare_content.numHwLayers);110 EXPECT_EQ(1, mock_device->display0_prepare_content.numHwLayers);
137 EXPECT_EQ(-1, mock_device->display0_prepare_content.retireFenceFd);111 EXPECT_EQ(-1, mock_device->display0_prepare_content.retireFenceFd);
138 EXPECT_EQ(empty_list.numHwLayers, mock_device->display0_set_content.numHwLayers);112 EXPECT_EQ(1, mock_device->display0_set_content.numHwLayers);
139 EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd);113 EXPECT_EQ(-1, mock_device->display0_set_content.retireFenceFd);
140}114}
141115
142TEST_F(HWC11Device, hwc_device_set_next_frontbuffer_adds_to_layerlist)
143{
144 std::shared_ptr<mg::Buffer> mock_buffer = std::make_shared<mtd::MockBuffer>();
145 EXPECT_CALL(*this->mock_hwc_layers, set_fb_target(mock_buffer))
146 .Times(1);
147
148 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);
149 device.set_next_frontbuffer(mock_buffer);
150}
151
152TEST_F(HWC11Device, test_hwc_device_display_config)116TEST_F(HWC11Device, test_hwc_device_display_config)
153{117{
154 using namespace testing;118 using namespace testing;
@@ -158,7 +122,7 @@
158 .Times(1)122 .Times(1)
159 .WillOnce(DoAll(SetArgPointee<2>(hwc_configs), Return(0)));123 .WillOnce(DoAll(SetArgPointee<2>(hwc_configs), Return(0)));
160124
161 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);125 mga::HWC11Device device(mock_device, mock_vsync);
162}126}
163127
164128
@@ -172,7 +136,7 @@
172 .WillOnce(Return(-1));136 .WillOnce(Return(-1));
173137
174 EXPECT_THROW({138 EXPECT_THROW({
175 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);139 mga::HWC11Device device(mock_device, mock_vsync);
176 }, std::runtime_error);140 }, std::runtime_error);
177}141}
178142
@@ -206,7 +170,7 @@
206 .Times(1)170 .Times(1)
207 .WillOnce(Invoke(display_attribute_handler));171 .WillOnce(Invoke(display_attribute_handler));
208172
209 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);173 mga::HWC11Device device(mock_device, mock_vsync);
210 174
211 auto size = device.display_size();175 auto size = device.display_size();
212 EXPECT_EQ(size.width.as_uint32_t(), static_cast<unsigned int>(display_width));176 EXPECT_EQ(size.width.as_uint32_t(), static_cast<unsigned int>(display_width));
@@ -215,7 +179,7 @@
215179
216TEST_F(HWC11Device, hwc_device_reports_2_fbs_available_by_default)180TEST_F(HWC11Device, hwc_device_reports_2_fbs_available_by_default)
217{181{
218 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);182 mga::HWC11Device device(mock_device, mock_vsync);
219 EXPECT_EQ(2u, device.number_of_framebuffers_available());183 EXPECT_EQ(2u, device.number_of_framebuffers_available());
220}184}
221185
@@ -249,7 +213,7 @@
249 EXPECT_CALL(mock_egl, eglTerminate(fake_display))213 EXPECT_CALL(mock_egl, eglTerminate(fake_display))
250 .InSequence(seq);214 .InSequence(seq);
251 215
252 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);216 mga::HWC11Device device(mock_device, mock_vsync);
253 EXPECT_EQ(geom::PixelFormat::argb_8888, device.display_format());217 EXPECT_EQ(geom::PixelFormat::argb_8888, device.display_format());
254}218}
255219
@@ -272,6 +236,6 @@
272 EXPECT_CALL(mock_egl, eglTerminate(fake_display))236 EXPECT_CALL(mock_egl, eglTerminate(fake_display))
273 .InSequence(seq);237 .InSequence(seq);
274 238
275 mga::HWC11Device device(mock_device, mock_hwc_layers, mock_display_device, mock_vsync);239 mga::HWC11Device device(mock_device, mock_vsync);
276 EXPECT_EQ(geom::PixelFormat::abgr_8888, device.display_format());240 EXPECT_EQ(geom::PixelFormat::abgr_8888, device.display_format());
277}241}
278242
=== modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc_device.cpp 2013-10-31 17:03:59 +0000
+++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2013-11-12 23:50:30 +0000
@@ -21,7 +21,6 @@
21#include "src/server/graphics/android/hwc_layerlist.h"21#include "src/server/graphics/android/hwc_layerlist.h"
22#include "src/server/graphics/android/hwc_vsync_coordinator.h"22#include "src/server/graphics/android/hwc_vsync_coordinator.h"
23#include "mir_test_doubles/mock_hwc_composer_device_1.h"23#include "mir_test_doubles/mock_hwc_composer_device_1.h"
24#include "mir_test_doubles/mock_hwc_layerlist.h"
25#include "mir_test_doubles/mock_hwc_vsync_coordinator.h"24#include "mir_test_doubles/mock_hwc_vsync_coordinator.h"
26#include "mir_test_doubles/mock_buffer.h"25#include "mir_test_doubles/mock_buffer.h"
27#include "mir_test_doubles/mock_egl.h"26#include "mir_test_doubles/mock_egl.h"
@@ -39,14 +38,12 @@
3938
40template<class T>39template<class T>
41std::shared_ptr<mga::HWCCommonDevice> make_hwc_device(std::shared_ptr<hwc_composer_device_1> const& hwc_device,40std::shared_ptr<mga::HWCCommonDevice> make_hwc_device(std::shared_ptr<hwc_composer_device_1> const& hwc_device,
42 std::shared_ptr<mga::HWCLayerList> const& layer_list,
43 std::shared_ptr<mga::DisplayDevice> const& fbdev,41 std::shared_ptr<mga::DisplayDevice> const& fbdev,
44 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator);42 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator);
4543
46template <>44template <>
47std::shared_ptr<mga::HWCCommonDevice> make_hwc_device<mga::HWC10Device>(45std::shared_ptr<mga::HWCCommonDevice> make_hwc_device<mga::HWC10Device>(
48 std::shared_ptr<hwc_composer_device_1> const& hwc_device,46 std::shared_ptr<hwc_composer_device_1> const& hwc_device,
49 std::shared_ptr<mga::HWCLayerList> const&,
50 std::shared_ptr<mga::DisplayDevice> const& fbdev,47 std::shared_ptr<mga::DisplayDevice> const& fbdev,
51 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)48 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)
52{49{
@@ -56,23 +53,10 @@
56template <>53template <>
57std::shared_ptr<mga::HWCCommonDevice> make_hwc_device<mga::HWC11Device>(54std::shared_ptr<mga::HWCCommonDevice> make_hwc_device<mga::HWC11Device>(
58 std::shared_ptr<hwc_composer_device_1> const& hwc_device,55 std::shared_ptr<hwc_composer_device_1> const& hwc_device,
59 std::shared_ptr<mga::HWCLayerList> const& layer_list,56 std::shared_ptr<mga::DisplayDevice> const&,
60 std::shared_ptr<mga::DisplayDevice> const& fbdev,
61 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)57 std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator)
62{58{
63 return std::make_shared<mga::HWC11Device>(hwc_device, layer_list, fbdev, coordinator);59 return std::make_shared<mga::HWC11Device>(hwc_device, coordinator);
64}
65
66namespace
67{
68struct HWCDummyLayer : public mga::HWCDefaultLayer
69{
70 HWCDummyLayer()
71 : HWCDefaultLayer({})
72 {
73 }
74};
75
76}60}
7761
78template<typename T>62template<typename T>
@@ -84,14 +68,12 @@
84 using namespace testing;68 using namespace testing;
8569
86 mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>();70 mock_device = std::make_shared<testing::NiceMock<mtd::MockHWCComposerDevice1>>();
87 mock_layer_list = std::make_shared<testing::NiceMock<mtd::MockHWCLayerList>>();
88 mock_fbdev = std::make_shared<testing::NiceMock<mtd::MockDisplayDevice>>();71 mock_fbdev = std::make_shared<testing::NiceMock<mtd::MockDisplayDevice>>();
89 mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>();72 mock_vsync = std::make_shared<testing::NiceMock<mtd::MockVsyncCoordinator>>();
90 }73 }
9174
92 testing::NiceMock<mtd::MockEGL> mock_egl;75 testing::NiceMock<mtd::MockEGL> mock_egl;
93 std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync;76 std::shared_ptr<mtd::MockVsyncCoordinator> mock_vsync;
94 std::shared_ptr<mtd::MockHWCLayerList> mock_layer_list;
95 std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device;77 std::shared_ptr<mtd::MockHWCComposerDevice1> mock_device;
96 std::shared_ptr<mtd::MockDisplayDevice> mock_fbdev;78 std::shared_ptr<mtd::MockDisplayDevice> mock_fbdev;
97};79};
@@ -108,8 +90,7 @@
108 .Times(1)90 .Times(1)
109 .WillOnce(SaveArg<1>(&procs));91 .WillOnce(SaveArg<1>(&procs));
11092
111 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,93 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
112 this->mock_fbdev, this->mock_vsync);
11394
114 EXPECT_NE(nullptr, procs->invalidate);95 EXPECT_NE(nullptr, procs->invalidate);
115 EXPECT_NE(nullptr, procs->vsync);96 EXPECT_NE(nullptr, procs->vsync);
@@ -127,8 +108,7 @@
127 .Times(1)108 .Times(1)
128 .WillOnce(Return(0));109 .WillOnce(Return(0));
129110
130 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,111 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
131 this->mock_fbdev, this->mock_vsync);
132 testing::Mock::VerifyAndClearExpectations(this->mock_device.get());112 testing::Mock::VerifyAndClearExpectations(this->mock_device.get());
133}113}
134114
@@ -140,9 +120,9 @@
140 .WillRepeatedly(Return(-EINVAL));120 .WillRepeatedly(Return(-EINVAL));
141121
142122
143 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,123 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
144 this->mock_fbdev, this->mock_vsync);
145 EXPECT_THROW({124 EXPECT_THROW({
125 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
146 device->mode(mir_power_mode_off);126 device->mode(mir_power_mode_off);
147 }, std::runtime_error);127 }, std::runtime_error);
148}128}
@@ -156,8 +136,7 @@
156 EXPECT_CALL(*this->mock_device, blank_interface(this->mock_device.get(), HWC_DISPLAY_PRIMARY, 0))136 EXPECT_CALL(*this->mock_device, blank_interface(this->mock_device.get(), HWC_DISPLAY_PRIMARY, 0))
157 .Times(1);137 .Times(1);
158138
159 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,139 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
160 this->mock_fbdev, this->mock_vsync);
161 testing::Mock::VerifyAndClearExpectations(this->mock_device.get());140 testing::Mock::VerifyAndClearExpectations(this->mock_device.get());
162}141}
163142
@@ -174,8 +153,7 @@
174 .WillOnce(Return(-1))153 .WillOnce(Return(-1))
175 .WillOnce(Return(0));154 .WillOnce(Return(0));
176155
177 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,156 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
178 this->mock_fbdev, this->mock_vsync);
179 EXPECT_THROW({157 EXPECT_THROW({
180 device->mode(mir_power_mode_off);158 device->mode(mir_power_mode_off);
181 }, std::runtime_error);159 }, std::runtime_error);
@@ -192,8 +170,7 @@
192 .Times(3)170 .Times(3)
193 .WillRepeatedly(Return(0));171 .WillRepeatedly(Return(0));
194172
195 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,173 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
196 this->mock_fbdev, this->mock_vsync);
197 device->mode(mir_power_mode_off);174 device->mode(mir_power_mode_off);
198 device->mode(mir_power_mode_on);175 device->mode(mir_power_mode_on);
199 device->mode(mir_power_mode_suspend);176 device->mode(mir_power_mode_suspend);
@@ -218,8 +195,7 @@
218 .Times(1)195 .Times(1)
219 .WillOnce(Return(0));196 .WillOnce(Return(0));
220197
221 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,198 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
222 this->mock_fbdev, this->mock_vsync);
223 device->mode(mir_power_mode_off);199 device->mode(mir_power_mode_off);
224}200}
225201
@@ -239,15 +215,13 @@
239 .Times(1)215 .Times(1)
240 .WillOnce(Return(0));216 .WillOnce(Return(0));
241217
242 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,218 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
243 this->mock_fbdev, this->mock_vsync);
244 device->mode(mir_power_mode_on);219 device->mode(mir_power_mode_on);
245}220}
246221
247TYPED_TEST(HWCCommon, test_hwc_display_is_deactivated_on_destroy)222TYPED_TEST(HWCCommon, test_hwc_display_is_deactivated_on_destroy)
248{223{
249 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,224 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
250 this->mock_fbdev, this->mock_vsync);
251225
252 EXPECT_CALL(*this->mock_device, blank_interface(this->mock_device.get(), HWC_DISPLAY_PRIMARY, 1))226 EXPECT_CALL(*this->mock_device, blank_interface(this->mock_device.get(), HWC_DISPLAY_PRIMARY, 1))
253 .Times(1);227 .Times(1);
@@ -265,8 +239,7 @@
265 .Times(1)239 .Times(1)
266 .WillOnce(SaveArg<1>(&procs));240 .WillOnce(SaveArg<1>(&procs));
267241
268 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_layer_list,242 auto device = make_hwc_device<TypeParam>(this->mock_device, this->mock_fbdev, this->mock_vsync);
269 this->mock_fbdev, this->mock_vsync);
270243
271 EXPECT_CALL(*this->mock_vsync, notify_vsync())244 EXPECT_CALL(*this->mock_vsync, notify_vsync())
272 .Times(1);245 .Times(1);
273246
=== modified file 'tests/unit-tests/graphics/android/test_hwc_layerlist.cpp'
--- tests/unit-tests/graphics/android/test_hwc_layerlist.cpp 2013-10-15 08:53:10 +0000
+++ tests/unit-tests/graphics/android/test_hwc_layerlist.cpp 2013-11-12 23:50:30 +0000
@@ -36,140 +36,24 @@
3636
37 width = 432; 37 width = 432;
38 height = 876; 38 height = 876;
39 default_size = geom::Size{width, height};
40
41 native_handle_1 = std::make_shared<mtd::StubAndroidNativeBuffer>();39 native_handle_1 = std::make_shared<mtd::StubAndroidNativeBuffer>();
40 native_handle_1->anwb()->width = width;
41 native_handle_1->anwb()->height = height;
42 native_handle_2 = std::make_shared<mtd::StubAndroidNativeBuffer>();42 native_handle_2 = std::make_shared<mtd::StubAndroidNativeBuffer>();
43
44 mock_buffer = std::make_shared<NiceMock<mtd::MockBuffer>>();
45 ON_CALL(*mock_buffer, native_buffer_handle())
46 .WillByDefault(Return(native_handle_1));
47 ON_CALL(*mock_buffer, size())
48 .WillByDefault(Return(default_size));
49 }43 }
5044
51 int width; 45 int width;
52 int height; 46 int height;
53 geom::Size default_size;
54
55 std::shared_ptr<mg::NativeBuffer> native_handle_1;47 std::shared_ptr<mg::NativeBuffer> native_handle_1;
56 std::shared_ptr<mg::NativeBuffer> native_handle_2;48 std::shared_ptr<mg::NativeBuffer> native_handle_2;
57 std::shared_ptr<mtd::MockBuffer> mock_buffer;
58};49};
5950
60TEST(HWCLayerDeepCopy, hwc_layer)51TEST_F(HWCLayerListTest, fb_target_layer)
61{52{
62 mga::HWCDefaultLayer original({});53 mga::FramebufferLayer target_layer(*native_handle_1);
63 hwc_layer_1 layer = original;54
64 EXPECT_EQ(0u, layer.visibleRegionScreen.numRects); 55 hwc_rect_t region = {0,0,width, height};
65 EXPECT_EQ(nullptr, layer.visibleRegionScreen.rects);56 hwc_region_t visible_region {1, &region};
66
67 geom::Rectangle r0{geom::Point{geom::X{0},geom::Y{1}},
68 geom::Size{2, 3}};
69 geom::Rectangle r1{geom::Point{geom::X{0},geom::Y{1}},
70 geom::Size{3, 3}};
71 geom::Rectangle r2{geom::Point{geom::X{1},geom::Y{1}},
72 geom::Size{2, 3}};
73 mga::HWCRect a(r0), b(r1), c(r2);
74 mga::HWCDefaultLayer original2({a, b, c});
75 layer = original2;
76
77 ASSERT_EQ(3u, layer.visibleRegionScreen.numRects);
78 ASSERT_NE(nullptr, layer.visibleRegionScreen.rects);
79 EXPECT_THAT(a, HWCRectMatchesRect(layer.visibleRegionScreen.rects[0],""));
80 EXPECT_THAT(b, HWCRectMatchesRect(layer.visibleRegionScreen.rects[1],""));
81 EXPECT_THAT(c, HWCRectMatchesRect(layer.visibleRegionScreen.rects[2],""));
82}
83
84TEST_F(HWCLayerListTest, hwc_list_creation_loads_latest_fb_target)
85{
86 using namespace testing;
87
88 hwc_rect_t expected_sc, expected_df, expected_visible;
89 expected_sc = {0, 0, width, height};
90 expected_df = expected_visible = expected_sc;
91 EXPECT_CALL(*mock_buffer, size())
92 .Times(1)
93 .WillOnce(Return(default_size));
94
95 mga::LayerList layerlist;
96 layerlist.set_fb_target(mock_buffer);
97
98 auto list = layerlist.native_list();
99 ASSERT_EQ(1u, list->numHwLayers);
100 hwc_layer_1 target_layer = list->hwLayers[0];
101 EXPECT_THAT(target_layer.sourceCrop, MatchesRect( expected_sc, "sourceCrop"));
102 EXPECT_THAT(target_layer.displayFrame, MatchesRect( expected_df, "displayFrame"));
103
104 ASSERT_EQ(1u, target_layer.visibleRegionScreen.numRects);
105 ASSERT_NE(nullptr, target_layer.visibleRegionScreen.rects);
106 EXPECT_THAT(target_layer.visibleRegionScreen.rects[0], MatchesRect( expected_visible, "visible"));
107}
108
109TEST_F(HWCLayerListTest, fb_target)
110{
111 using namespace testing;
112
113 mga::LayerList layerlist;
114
115 auto list = layerlist.native_list();
116 ASSERT_EQ(1u, list->numHwLayers);
117 hwc_layer_1 target_layer = list->hwLayers[0];
118 EXPECT_EQ(nullptr, target_layer.handle);
119}
120
121TEST_F(HWCLayerListTest, set_fb_target_gets_fb_handle)
122{
123 using namespace testing;
124
125 mga::LayerList layerlist;
126
127 EXPECT_CALL(*mock_buffer, native_buffer_handle())
128 .Times(1)
129 .WillOnce(Return(native_handle_1));
130
131 layerlist.set_fb_target(mock_buffer);
132 auto list = layerlist.native_list();
133 ASSERT_EQ(1u, list->numHwLayers);
134 hwc_layer_1 target_layer = list->hwLayers[0];
135 EXPECT_EQ(native_handle_1->handle(), target_layer.handle);
136}
137
138TEST_F(HWCLayerListTest, set_fb_target_2x)
139{
140 using namespace testing;
141
142 mga::LayerList layerlist;
143
144 EXPECT_CALL(*mock_buffer, native_buffer_handle())
145 .Times(2)
146 .WillOnce(Return(native_handle_1))
147 .WillOnce(Return(native_handle_2));
148
149 layerlist.set_fb_target(mock_buffer);
150 auto list = layerlist.native_list();
151 ASSERT_EQ(1u, list->numHwLayers);
152 hwc_layer_1 target_layer = list->hwLayers[0];
153 EXPECT_EQ(native_handle_1->handle(), target_layer.handle);
154
155 layerlist.set_fb_target(mock_buffer);
156 auto list_second = layerlist.native_list();
157 ASSERT_EQ(1u, list_second->numHwLayers);
158 target_layer = list_second->hwLayers[0];
159 EXPECT_EQ(native_handle_2->handle(), target_layer.handle);
160}
161
162TEST_F(HWCLayerListTest, set_fb_target_programs_other_struct_members_correctly)
163{
164 using namespace testing;
165
166 mga::LayerList layerlist;
167 layerlist.set_fb_target(mock_buffer);
168
169 hwc_rect_t source_region = {0,0,width, height};
170 hwc_rect_t target_region = source_region;
171 hwc_region_t region {1, nullptr};
172
173 hwc_layer_1 expected_layer;57 hwc_layer_1 expected_layer;
174 expected_layer.compositionType = HWC_FRAMEBUFFER_TARGET;58 expected_layer.compositionType = HWC_FRAMEBUFFER_TARGET;
175 expected_layer.hints = 0;59 expected_layer.hints = 0;
@@ -177,14 +61,91 @@
177 expected_layer.handle = native_handle_1->handle();61 expected_layer.handle = native_handle_1->handle();
178 expected_layer.transform = 0;62 expected_layer.transform = 0;
179 expected_layer.blending = HWC_BLENDING_NONE;63 expected_layer.blending = HWC_BLENDING_NONE;
180 expected_layer.sourceCrop = source_region;64 expected_layer.sourceCrop = region;
181 expected_layer.displayFrame = target_region; 65 expected_layer.displayFrame = region;
182 expected_layer.visibleRegionScreen = region; 66 expected_layer.visibleRegionScreen = visible_region;
183 expected_layer.acquireFenceFd = -1;67 expected_layer.acquireFenceFd = -1;
184 expected_layer.releaseFenceFd = -1;68 expected_layer.releaseFenceFd = -1;
18569
186 auto list = layerlist.native_list(); 70 EXPECT_THAT(target_layer, MatchesLayer(expected_layer));
187 ASSERT_EQ(1u, list->numHwLayers);71}
188 hwc_layer_1 target_layer = list->hwLayers[0]; 72
189 EXPECT_THAT(target_layer, MatchesLayer( expected_layer ));73TEST_F(HWCLayerListTest, gl_target_layer_with_force_gl)
74{
75 mga::CompositionLayer target_layer(*native_handle_1, HWC_SKIP_LAYER);
76
77 hwc_rect_t region = {0,0,width, height};
78 hwc_region_t visible_region {1, &region};
79 hwc_layer_1 expected_layer;
80 expected_layer.compositionType = HWC_FRAMEBUFFER;
81 expected_layer.hints = 0;
82 expected_layer.flags = HWC_SKIP_LAYER;
83 expected_layer.handle = native_handle_1->handle();
84 expected_layer.transform = 0;
85 expected_layer.blending = HWC_BLENDING_NONE;
86 expected_layer.sourceCrop = region;
87 expected_layer.displayFrame = region;
88 expected_layer.visibleRegionScreen = visible_region;
89 expected_layer.acquireFenceFd = -1;
90 expected_layer.releaseFenceFd = -1;
91
92 EXPECT_THAT(target_layer, MatchesLayer(expected_layer));
93}
94
95TEST_F(HWCLayerListTest, gl_target_layer_without_skip)
96{
97 mga::CompositionLayer target_layer(*native_handle_1, 0);
98
99 hwc_rect_t region = {0,0,width, height};
100 hwc_region_t visible_region {1, &region};
101 hwc_layer_1 expected_layer;
102 expected_layer.compositionType = HWC_FRAMEBUFFER;
103 expected_layer.hints = 0;
104 expected_layer.flags = 0;
105 expected_layer.handle = native_handle_1->handle();
106 expected_layer.transform = 0;
107 expected_layer.blending = HWC_BLENDING_NONE;
108 expected_layer.sourceCrop = region;
109 expected_layer.displayFrame = region;
110 expected_layer.visibleRegionScreen = visible_region;
111 expected_layer.acquireFenceFd = -1;
112 expected_layer.releaseFenceFd = -1;
113
114 EXPECT_THAT(target_layer, MatchesLayer(expected_layer));
115}
116
117TEST_F(HWCLayerListTest, hwc_list_creation)
118{
119 using namespace testing;
120
121 mga::CompositionLayer surface_layer(*native_handle_1, 0);
122 mga::FramebufferLayer target_layer(*native_handle_1);
123 mga::LayerList layerlist({
124 surface_layer,
125 target_layer});
126
127 auto list = layerlist.native_list();
128 EXPECT_EQ(-1, list->retireFenceFd);
129 EXPECT_EQ(HWC_GEOMETRY_CHANGED, list->flags);
130 /* note, mali hwc1.1 actually falsely returns if these are not set to something. set to garbage */
131 EXPECT_NE(nullptr, list->dpy);
132 EXPECT_NE(nullptr, list->sur);
133
134 ASSERT_EQ(2u, list->numHwLayers);
135 EXPECT_THAT(surface_layer, MatchesLayer(list->hwLayers[0]));
136 EXPECT_THAT(target_layer, MatchesLayer(list->hwLayers[1]));
137}
138
139TEST_F(HWCLayerListTest, hwc_list_update)
140{
141 using namespace testing;
142 mga::LayerList layerlist({
143 mga::CompositionLayer(*native_handle_1, 0),
144 mga::FramebufferLayer(*native_handle_1)});
145 layerlist.set_fb_target(native_handle_2);
146
147 auto list = layerlist.native_list();
148 ASSERT_EQ(2u, list->numHwLayers);
149 EXPECT_EQ(list->hwLayers[0].handle, native_handle_1->handle());
150 EXPECT_EQ(list->hwLayers[1].handle, native_handle_2->handle());
190}151}

Subscribers

People subscribed via source and target branches