Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Side by Side Diff: mojo/services/gfx/images/cpp/image_pipe_apptest.cc

Issue 1595773002: Added ImagePipe (Closed) Base URL: https://github.com/domokit/mojo.git@submit-2
Patch Set: rebased Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/public/cpp/application/application_impl.h"
6 #include "mojo/public/cpp/application/application_test_base.h"
7 #include "mojo/public/cpp/environment/logging.h"
8 #include "mojo/public/cpp/system/macros.h"
9 #include "mojo/public/cpp/utility/run_loop.h"
10 #include "mojo/services/gfx/images/cpp/image_pipe_consumer_endpoint.h"
11 #include "mojo/services/gfx/images/cpp/image_pipe_producer_endpoint.h"
12
13 namespace mojo {
14 namespace {
15
16 class ImagePipeApplicationTest : public test::ApplicationTestBase {
17 public:
18 ImagePipeApplicationTest() : ApplicationTestBase() {}
19 ~ImagePipeApplicationTest() override {}
20
21 private:
22 MOJO_DISALLOW_COPY_AND_ASSIGN(ImagePipeApplicationTest);
23 };
24
25 class TestImagePipe : image_pipe::ImagePipeConsumerDelegate {
26 public:
27 TestImagePipe(bool producer_checked, bool consumer_checked);
28 ~TestImagePipe() override;
29 mojo::gfx::ImagePtr CreateTestImage();
30
31 bool HasExperiencedError() { return has_error_; }
32
33 image_pipe::ImagePipeProducerEndpoint* ProducerEndpoint() {
34 return producer_endpoint_.get();
35 }
36 image_pipe::ImagePipeConsumerEndpoint* ConsumerEndpoint() {
37 return consumer_endpoint_.get();
38 }
39
40 void OverrideAddImage(
41 std::function<void(mojo::gfx::ImagePtr image, uint32_t id)> add_func) {
42 add_image_override_ = add_func;
43 }
44 void OverrideRemoveImage(std::function<void(uint32_t id)> remove_func) {
45 remove_image_override_ = remove_func;
46 }
47 void OverridePresentImage(std::function<void(uint32_t id)> present_func) {
48 present_image_override_ = present_func;
49 }
50
51 private:
52 // Inherited from ImagePipeConsumerDelegate
53 void AddImage(mojo::gfx::ImagePtr image, uint32_t id) override;
54 void RemoveImage(uint32_t id) override;
55 void PresentImage(uint32_t id) override;
56 void HandleEndpointClosed() override {
57 has_error_ = true;
58 mojo::RunLoop::current()->Quit();
59 }
60
61 std::unique_ptr<image_pipe::ImagePipeProducerEndpoint> producer_endpoint_;
62 std::unique_ptr<image_pipe::ImagePipeConsumerEndpoint> consumer_endpoint_;
63 mojo::gfx::SupportedImagePropertiesPtr supported_properties_;
64
65 std::function<void(mojo::gfx::ImagePtr image, uint32_t id)>
66 add_image_override_;
67 std::function<void(uint32_t id)> remove_image_override_;
68 std::function<void(uint32_t id)> present_image_override_;
69
70 bool has_error_;
71 };
72
73 void TestImagePipe::AddImage(mojo::gfx::ImagePtr image, uint32_t id) {
74 if (add_image_override_)
75 add_image_override_(image.Pass(), id);
76 }
77 void TestImagePipe::RemoveImage(uint32_t id) {
78 if (remove_image_override_)
79 remove_image_override_(id);
80 }
81 void TestImagePipe::PresentImage(uint32_t id) {
82 if (present_image_override_)
83 present_image_override_(id);
84 }
85
86 TestImagePipe::TestImagePipe(bool producer_checked, bool consumer_checked) {
87 has_error_ = false;
88 supported_properties_ = mojo::gfx::SupportedImageProperties::New();
89 supported_properties_->size = mojo::Size::New();
90 supported_properties_->size->width = 256;
91 supported_properties_->size->height = 256;
92
93 supported_properties_->formats =
94 mojo::Array<mojo::gfx::ColorFormatPtr>::New(0);
95 mojo::gfx::ColorFormatPtr format = mojo::gfx::ColorFormat::New();
96 format->layout = mojo::gfx::PixelLayout::BGRA_8888;
97 format->color_space = mojo::gfx::ColorSpace::SRGB;
98 supported_properties_->formats.push_back(format.Pass());
99
100 mojo::gfx::ImagePipePtr image_pipe_ptr;
101 consumer_endpoint_.reset(new image_pipe::ImagePipeConsumerEndpoint(
102 GetProxy(&image_pipe_ptr), this));
103 if (!consumer_checked) {
104 consumer_endpoint_->DisableFatalErrorsForTesting();
105 }
106
107 producer_endpoint_.reset(
108 new image_pipe::ImagePipeProducerEndpoint(image_pipe_ptr.Pass(), [this] {
109 has_error_ = true;
110 mojo::RunLoop::current()->Quit();
111 }));
112 if (!producer_checked) {
113 producer_endpoint_->DisableFatalErrorsForTesting();
114 }
115 }
116
117 TestImagePipe::~TestImagePipe() {}
118
119 mojo::gfx::ImagePtr TestImagePipe::CreateTestImage() {
120 mojo::MessagePipe pipe;
121
122 uint32_t bytes_per_pixel = 32;
123
124 mojo::gfx::ImageBufferPtr image_buffer = mojo::gfx::ImageBuffer::New();
125 image_buffer->size = supported_properties_->size->width *
126 supported_properties_->size->width * bytes_per_pixel;
127 image_buffer->data = mojo::ScopedHandle(pipe.handle0.Pass());
128
129 mojo::gfx::ImagePtr image = mojo::gfx::Image::New();
130 image->buffer = image_buffer.Pass();
131 image->format = supported_properties_->formats[0].Clone();
132 image->size = supported_properties_->size.Clone();
133 image->pitch = supported_properties_->size->width;
134 image->stride = image->pitch * bytes_per_pixel;
135
136 return image;
137 }
138
139 // Tests that the usual flow for creating, adding, presenting, and removing
140 // an image doesnt crash/break/cause-errors etc
141 TEST_F(ImagePipeApplicationTest, NormalImageLifeCycle) {
142 TestImagePipe image_pipe(true, true);
143
144 image_pipe.OverridePresentImage([&image_pipe](uint32_t id) {
145 uint32_t acquired_id;
146 MOJO_CHECK(image_pipe.ConsumerEndpoint()->AcquireNextImage(&acquired_id));
147 MOJO_CHECK(acquired_id == id);
148 image_pipe.ConsumerEndpoint()->ReleaseImage(
149 id, mojo::gfx::PresentationStatus::PRESENTED);
150 });
151
152 uint32_t id = 0, acquired_id = UINT32_MAX;
153 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
154 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
155 MOJO_CHECK(acquired_id == id);
156 image_pipe.ProducerEndpoint()->PresentImage(
157 id, [&image_pipe](mojo::gfx::PresentationStatus status) {
158 EXPECT_EQ(mojo::gfx::PresentationStatus::PRESENTED, status);
159 mojo::RunLoop::current()->Quit();
160 });
161
162 mojo::RunLoop::current()->Run();
163 acquired_id = UINT32_MAX;
164 EXPECT_TRUE(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
165 MOJO_CHECK(acquired_id == id);
166 image_pipe.ProducerEndpoint()->RemoveImage(acquired_id);
167
168 EXPECT_FALSE(image_pipe.HasExperiencedError());
169 }
170
171 // Tests that flushing returns images to the producer with NOT_PRESENTED_FLUSHED
172 TEST_F(ImagePipeApplicationTest, FlushImages) {
173 TestImagePipe image_pipe(true, true);
174
175 uint32_t id = 0, acquired_id = UINT32_MAX;
176 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
177 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
178 MOJO_CHECK(acquired_id == id);
179 image_pipe.ProducerEndpoint()->PresentImage(
180 id, [](mojo::gfx::PresentationStatus status) {
181 EXPECT_EQ(mojo::gfx::PresentationStatus::NOT_PRESENTED_FLUSHED, status);
182 mojo::RunLoop::current()->Quit();
183 });
184 image_pipe.ProducerEndpoint()->FlushImages();
185
186 mojo::RunLoop::current()->Run();
187 acquired_id = UINT32_MAX;
188 EXPECT_TRUE(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
189 EXPECT_TRUE(acquired_id == id);
190
191 EXPECT_FALSE(image_pipe.HasExperiencedError());
192 }
193
194 // Tests that you can safely try to acquire an image when none are available,
195 // and that you will safely fail
196 TEST_F(ImagePipeApplicationTest, AcquireImageFromEmptyPool) {
197 TestImagePipe image_pipe(true, true);
198
199 uint32_t id = 0xDEADBEEF, acquired_id = id;
200 EXPECT_FALSE(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
201 EXPECT_TRUE(acquired_id == id);
202 EXPECT_FALSE(image_pipe.HasExperiencedError());
203 }
204
205 // Tests that adding an image with an existing ID causes the pipe to error
206 TEST_F(ImagePipeApplicationTest, ProducerError_AddImageWithReusedID) {
207 TestImagePipe image_pipe(false, true);
208
209 uint32_t id = 0;
210 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
211 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
212
213 mojo::RunLoop::current()->Run();
214 EXPECT_TRUE(image_pipe.HasExperiencedError());
215 }
216
217 // Tests that removing an image that hasnt been added causes the pipe to error
218 TEST_F(ImagePipeApplicationTest, ProducerError_RemoveImageBeforeAdded) {
219 TestImagePipe image_pipe(false, true);
220
221 uint32_t id = 0;
222 image_pipe.ProducerEndpoint()->RemoveImage(id);
223
224 mojo::RunLoop::current()->Run();
225 EXPECT_TRUE(image_pipe.HasExperiencedError());
226 }
227
228 // Tests that removing an image that has already been removed causes the pipe to
229 // error (essentially that removing and image takes it out of the pool)
230 TEST_F(ImagePipeApplicationTest, ProducerError_AddImageThenRemoveTwice) {
231 TestImagePipe image_pipe(false, true);
232
233 uint32_t id = 0;
234 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
235 image_pipe.ProducerEndpoint()->RemoveImage(id);
236 image_pipe.ProducerEndpoint()->RemoveImage(id);
237
238 mojo::RunLoop::current()->Run();
239 EXPECT_TRUE(image_pipe.HasExperiencedError());
240 }
241
242 // Tests that removing an image owned by the consumer causes the pipe to error
243 TEST_F(ImagePipeApplicationTest, ProducerError_RemoveImageOwnedByConsumer) {
244 TestImagePipe image_pipe(false, true);
245
246 uint32_t id = 0, acquired_id = UINT32_MAX;
247 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
248 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
249 MOJO_CHECK(acquired_id == id);
250 image_pipe.ProducerEndpoint()->PresentImage(
251 id, [](mojo::gfx::PresentationStatus) {});
252 image_pipe.ProducerEndpoint()->RemoveImage(id);
253
254 mojo::RunLoop::current()->Run();
255 EXPECT_TRUE(image_pipe.HasExperiencedError());
256 }
257
258 // Tests that presenting an image that hasnt been added causes the pipe to error
259 TEST_F(ImagePipeApplicationTest, ProducerError_PresentImageNotAdded) {
260 TestImagePipe image_pipe(false, true);
261
262 uint32_t id = 0;
263 image_pipe.ProducerEndpoint()->PresentImage(
264 id, [](mojo::gfx::PresentationStatus) {});
265
266 mojo::RunLoop::current()->Run();
267 EXPECT_TRUE(image_pipe.HasExperiencedError());
268 }
269
270 // Tests that presenting an image that has already been presented causes the
271 // pipe to error
272 TEST_F(ImagePipeApplicationTest, ProducerError_PresentImageTwice) {
273 TestImagePipe image_pipe(false, true);
274
275 uint32_t id = 0, acquired_id = UINT32_MAX;
276 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
277 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
278 MOJO_CHECK(acquired_id == id);
279 image_pipe.ProducerEndpoint()->PresentImage(
280 id, [](mojo::gfx::PresentationStatus) {});
281 image_pipe.ProducerEndpoint()->PresentImage(
282 id, [](mojo::gfx::PresentationStatus) {});
283
284 mojo::RunLoop::current()->Run();
285 EXPECT_TRUE(image_pipe.HasExperiencedError());
286 }
287
288 // Tests that releasing an image that hasnt been added causes the pipe to error
289 TEST_F(ImagePipeApplicationTest, ConsumerError_ReleaseImageNotInPool) {
290 TestImagePipe image_pipe(true, false);
291
292 image_pipe.OverridePresentImage([&image_pipe](uint32_t id) {
293 image_pipe.ConsumerEndpoint()->ReleaseImage(
294 id + 1, mojo::gfx::PresentationStatus::PRESENTED);
295 });
296
297 uint32_t id = 0, acquired_id = UINT32_MAX;
298 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
299 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
300 MOJO_CHECK(acquired_id == id);
301 image_pipe.ProducerEndpoint()->PresentImage(
302 id, [](mojo::gfx::PresentationStatus) {});
303
304 mojo::RunLoop::current()->Run();
305 EXPECT_TRUE(image_pipe.HasExperiencedError());
306 }
307
308 // Tests that releasing an image before acquiring it causes the pipe to error
309 TEST_F(ImagePipeApplicationTest, ConsumerError_ReleaseBeforeAcquire) {
310 TestImagePipe image_pipe(true, false);
311
312 image_pipe.OverridePresentImage([&image_pipe](uint32_t id) {
313 image_pipe.ConsumerEndpoint()->ReleaseImage(
314 id, mojo::gfx::PresentationStatus::PRESENTED);
315 });
316
317 uint32_t id = 0, acquired_id = UINT32_MAX;
318 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
319 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
320 MOJO_CHECK(acquired_id == id);
321 image_pipe.ProducerEndpoint()->PresentImage(
322 id, [](mojo::gfx::PresentationStatus) {});
323
324 mojo::RunLoop::current()->Run();
325 EXPECT_TRUE(image_pipe.HasExperiencedError());
326 }
327
328 // Tests that releasing an image before its presented causes the pipe to error
329 TEST_F(ImagePipeApplicationTest, ConsumerError_ReleaseImageNotPresented) {
330 TestImagePipe image_pipe(true, false);
331
332 image_pipe.OverridePresentImage([&image_pipe](uint32_t id) {
333 uint32_t acquired_id;
334 MOJO_CHECK(image_pipe.ConsumerEndpoint()->AcquireNextImage(&acquired_id));
335 MOJO_CHECK(acquired_id == id);
336 image_pipe.ConsumerEndpoint()->ReleaseImage(
337 id + 1, mojo::gfx::PresentationStatus::PRESENTED);
338 });
339
340 uint32_t id = 0, acquired_id = UINT32_MAX;
341 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id);
342 image_pipe.ProducerEndpoint()->AddImage(image_pipe.CreateTestImage(), id + 1);
343 MOJO_CHECK(image_pipe.ProducerEndpoint()->AcquireImage(&acquired_id));
344 MOJO_CHECK(acquired_id == id);
345 image_pipe.ProducerEndpoint()->PresentImage(
346 id, [](mojo::gfx::PresentationStatus) {});
347
348 mojo::RunLoop::current()->Run();
349 EXPECT_TRUE(image_pipe.HasExperiencedError());
350 }
351
352 } // namespace
353 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/gfx/images/cpp/BUILD.gn ('k') | mojo/services/gfx/images/cpp/image_pipe_consumer_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698