2
* Copyright © 2012 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Kevin DuBois <kevin.dubois@canonical.com>
19
#include "mir_toolkit/mir_client_library.h"
20
#include "src/client/mesa/client_buffer.h"
21
#include "src/client/mesa/client_buffer_factory.h"
22
#include "src/client/mesa/buffer_file_ops.h"
25
#include <gmock/gmock.h>
26
#include <gtest/gtest.h>
30
namespace geom=mir::geometry;
31
namespace mclg=mir::client::mesa;
36
class MockBufferFileOps : public mclg::BufferFileOps
39
MOCK_CONST_METHOD1(close, int(int fd));
40
MOCK_CONST_METHOD3(map, void*(int fd, off_t offset, size_t size));
41
MOCK_CONST_METHOD2(unmap, void(void* addr, size_t size));
44
struct MesaClientBufferTest : public testing::Test
48
width = geom::Width(12);
49
height =geom::Height(14);
50
stride = geom::Stride(66);
51
pf = mir_pixel_format_abgr_8888;
52
size = geom::Size{width, height};
53
buffer_file_ops = std::make_shared<testing::NiceMock<MockBufferFileOps>>();
55
package = std::make_shared<MirBufferPackage>();
57
package->fd_items = 1;
58
package->stride = stride.as_uint32_t();
59
package->width = width.as_int();
60
package->height = height.as_int();
62
package_copy = std::make_shared<MirBufferPackage>(*package.get());
70
std::shared_ptr<testing::NiceMock<MockBufferFileOps>> buffer_file_ops;
71
std::shared_ptr<MirBufferPackage> package;
72
std::shared_ptr<MirBufferPackage> package_copy;
78
TEST_F(MesaClientBufferTest, width_and_height)
80
using namespace testing;
82
mclg::ClientBuffer buffer(buffer_file_ops, package, size, pf);
84
EXPECT_EQ(buffer.size().height, height);
85
EXPECT_EQ(buffer.size().width, width);
86
EXPECT_EQ(buffer.pixel_format(), pf);
89
TEST_F(MesaClientBufferTest, buffer_returns_correct_stride)
91
using namespace testing;
93
mclg::ClientBuffer buffer(buffer_file_ops, package, size, pf);
95
EXPECT_EQ(buffer.stride(), stride);
98
TEST_F(MesaClientBufferTest, buffer_returns_set_package)
100
using namespace testing;
102
mclg::ClientBuffer buffer(buffer_file_ops, package, size, pf);
104
auto package_return = buffer.native_buffer_handle();
105
EXPECT_EQ(package_return->data_items, package_copy->data_items);
106
EXPECT_EQ(package_return->fd_items, package_copy->fd_items);
107
EXPECT_EQ(package_return->stride, package_copy->stride);
108
for (auto i=0; i<mir_buffer_package_max; i++)
109
EXPECT_EQ(package_return->data[i], package_copy->data[i]);
110
for (auto i=0; i<mir_buffer_package_max; i++)
111
EXPECT_EQ(package_return->fd[i], package_copy->fd[i]);
114
TEST_F(MesaClientBufferTest, secure_for_cpu_write_maps_buffer_fd)
116
using namespace testing;
117
void *map_addr{reinterpret_cast<void*>(0xabcdef)};
119
EXPECT_CALL(*buffer_file_ops, map(package->fd[0],_,_))
120
.WillOnce(Return(map_addr));
121
EXPECT_CALL(*buffer_file_ops, unmap(map_addr,_))
123
EXPECT_CALL(*buffer_file_ops, close(package->fd[0]))
126
mclg::ClientBuffer buffer(buffer_file_ops, package, size, pf);
128
auto mem_region = buffer.secure_for_cpu_write();
129
ASSERT_EQ(map_addr, mem_region->vaddr.get());
130
ASSERT_EQ(width, mem_region->width);
131
ASSERT_EQ(height, mem_region->height);
132
ASSERT_EQ(stride, mem_region->stride);
133
ASSERT_EQ(pf, mem_region->format);
136
TEST_F(MesaClientBufferTest, secure_for_cpu_write_throws_on_map_failure)
138
using namespace testing;
140
EXPECT_CALL(*buffer_file_ops, map(package->fd[0],_,_))
141
.WillOnce(Return(MAP_FAILED));
142
EXPECT_CALL(*buffer_file_ops, unmap(_,_))
144
EXPECT_CALL(*buffer_file_ops, close(package->fd[0]))
147
mclg::ClientBuffer buffer(buffer_file_ops, package, size, pf);
150
auto mem_region = buffer.secure_for_cpu_write();
151
}, std::runtime_error);
154
TEST_F(MesaClientBufferTest, buffer_fd_closed_on_buffer_destruction)
156
using namespace testing;
158
EXPECT_CALL(*buffer_file_ops, close(package->fd[0]))
161
mclg::ClientBuffer buffer(buffer_file_ops, package, size, pf);
164
TEST_F(MesaClientBufferTest, factory_gets_size_from_package)
166
using namespace testing;
168
mclg::ClientBufferFactory factory(buffer_file_ops);
170
geom::Size unused_size{0, 0};
171
auto buffer = factory.create_buffer(package, unused_size, pf);
173
auto const& buf_size = buffer->size();
174
EXPECT_EQ(package->width, buf_size.width.as_int());
175
EXPECT_EQ(package->height, buf_size.height.as_int());
177
EXPECT_NE(unused_size, buf_size);