blob: ee4ad4e43459eea4c11cf01641886590dd259674 [file] [log] [blame]
Jamie Gennis23c2c5d2011-10-11 19:22:19 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
Michael Lentine5a16a622015-05-21 13:48:24 -070019#include <android/native_window.h>
20
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070021#include <binder/IMemory.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080022
23#include <gui/ISurfaceComposer.h>
24#include <gui/Surface.h>
25#include <gui/SurfaceComposerClient.h>
26#include <private/gui/ComposerService.h>
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -070027#include <private/gui/LayerState.h>
Mathias Agopian90ac7992012-02-25 18:48:35 -080028
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070029#include <utils/String8.h>
Mathias Agopianc666cae2012-07-25 18:56:13 -070030#include <ui/DisplayInfo.h>
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070031
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -070032#include <math.h>
33
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070034namespace android {
35
36// Fill an RGBA_8888 formatted surface with a single color.
37static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc,
38 uint8_t r, uint8_t g, uint8_t b) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -080039 ANativeWindow_Buffer outBuffer;
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070040 sp<Surface> s = sc->getSurface();
41 ASSERT_TRUE(s != NULL);
Mathias Agopiane3c697f2013-02-14 17:11:02 -080042 ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, NULL));
43 uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -070044 for (int y = 0; y < outBuffer.height; y++) {
45 for (int x = 0; x < outBuffer.width; x++) {
Mathias Agopiane3c697f2013-02-14 17:11:02 -080046 uint8_t* pixel = img + (4 * (y*outBuffer.stride + x));
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070047 pixel[0] = r;
48 pixel[1] = g;
49 pixel[2] = b;
50 pixel[3] = 255;
51 }
52 }
53 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
54}
55
56// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check
57// individual pixel values for testing purposes.
58class ScreenCapture : public RefBase {
59public:
60 static void captureScreen(sp<ScreenCapture>* sc) {
Michael Lentine5a16a622015-05-21 13:48:24 -070061 sp<IGraphicBufferProducer> producer;
62 sp<IGraphicBufferConsumer> consumer;
63 BufferQueue::createBufferQueue(&producer, &consumer);
64 IGraphicBufferProducer::QueueBufferOutput bufferOutput;
65 sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070066 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
Michael Lentine5a16a622015-05-21 13:48:24 -070067 sp<IBinder> display(sf->getBuiltInDisplay(
68 ISurfaceComposer::eDisplayIdMain));
69 ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 0, 0,
70 0, INT_MAX, false));
71 *sc = new ScreenCapture(cpuConsumer);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070072 }
73
74 void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) {
Michael Lentine5a16a622015-05-21 13:48:24 -070075 ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mBuf.format);
76 const uint8_t* img = static_cast<const uint8_t*>(mBuf.data);
77 const uint8_t* pixel = img + (4 * (y * mBuf.stride + x));
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070078 if (r != pixel[0] || g != pixel[1] || b != pixel[2]) {
79 String8 err(String8::format("pixel @ (%3d, %3d): "
80 "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]",
81 x, y, r, g, b, pixel[0], pixel[1], pixel[2]));
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -070082 EXPECT_EQ(String8(), err) << err.string();
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070083 }
84 }
85
86private:
Michael Lentine5a16a622015-05-21 13:48:24 -070087 ScreenCapture(const sp<CpuConsumer>& cc) :
88 mCC(cc) {
89 EXPECT_EQ(NO_ERROR, mCC->lockNextBuffer(&mBuf));
90 }
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070091
Michael Lentine5a16a622015-05-21 13:48:24 -070092 ~ScreenCapture() {
93 mCC->unlockBuffer(mBuf);
94 }
95
96 sp<CpuConsumer> mCC;
97 CpuConsumer::LockedBuffer mBuf;
Jamie Gennis23c2c5d2011-10-11 19:22:19 -070098};
99
100class LayerUpdateTest : public ::testing::Test {
101protected:
102 virtual void SetUp() {
103 mComposerClient = new SurfaceComposerClient;
104 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
105
Jeff Brown9d4e3d22012-08-24 20:00:51 -0700106 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
107 ISurfaceComposer::eDisplayIdMain));
Mathias Agopianc666cae2012-07-25 18:56:13 -0700108 DisplayInfo info;
Jeff Brown9d4e3d22012-08-24 20:00:51 -0700109 SurfaceComposerClient::getDisplayInfo(display, &info);
Mathias Agopianc666cae2012-07-25 18:56:13 -0700110
111 ssize_t displayWidth = info.w;
112 ssize_t displayHeight = info.h;
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700113
114 // Background surface
115 mBGSurfaceControl = mComposerClient->createSurface(
Jeff Brown9d4e3d22012-08-24 20:00:51 -0700116 String8("BG Test Surface"), displayWidth, displayHeight,
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700117 PIXEL_FORMAT_RGBA_8888, 0);
118 ASSERT_TRUE(mBGSurfaceControl != NULL);
119 ASSERT_TRUE(mBGSurfaceControl->isValid());
120 fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
121
122 // Foreground surface
123 mFGSurfaceControl = mComposerClient->createSurface(
Jeff Brown9d4e3d22012-08-24 20:00:51 -0700124 String8("FG Test Surface"), 64, 64, PIXEL_FORMAT_RGBA_8888, 0);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700125 ASSERT_TRUE(mFGSurfaceControl != NULL);
126 ASSERT_TRUE(mFGSurfaceControl->isValid());
127
128 fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
129
130 // Synchronization surface
131 mSyncSurfaceControl = mComposerClient->createSurface(
Jeff Brown9d4e3d22012-08-24 20:00:51 -0700132 String8("Sync Test Surface"), 1, 1, PIXEL_FORMAT_RGBA_8888, 0);
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700133 ASSERT_TRUE(mSyncSurfaceControl != NULL);
134 ASSERT_TRUE(mSyncSurfaceControl->isValid());
135
136 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
137
138 SurfaceComposerClient::openGlobalTransaction();
139
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -0700140 mComposerClient->setDisplayLayerStack(display, 0);
141
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700142 ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT_MAX-2));
143 ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show());
144
145 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX-1));
146 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64));
147 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show());
148
149 ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setLayer(INT_MAX-1));
150 ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setPosition(displayWidth-2,
151 displayHeight-2));
152 ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->show());
153
154 SurfaceComposerClient::closeGlobalTransaction(true);
155 }
156
157 virtual void TearDown() {
158 mComposerClient->dispose();
159 mBGSurfaceControl = 0;
160 mFGSurfaceControl = 0;
161 mSyncSurfaceControl = 0;
162 mComposerClient = 0;
163 }
164
165 void waitForPostedBuffers() {
166 // Since the sync surface is in synchronous mode (i.e. double buffered)
167 // posting three buffers to it should ensure that at least two
168 // SurfaceFlinger::handlePageFlip calls have been made, which should
169 // guaranteed that a buffer posted to another Surface has been retired.
170 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
171 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
172 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
173 }
174
175 sp<SurfaceComposerClient> mComposerClient;
176 sp<SurfaceControl> mBGSurfaceControl;
177 sp<SurfaceControl> mFGSurfaceControl;
178
179 // This surface is used to ensure that the buffers posted to
180 // mFGSurfaceControl have been picked up by SurfaceFlinger.
181 sp<SurfaceControl> mSyncSurfaceControl;
182};
183
184TEST_F(LayerUpdateTest, LayerMoveWorks) {
185 sp<ScreenCapture> sc;
186 {
187 SCOPED_TRACE("before move");
188 ScreenCapture::captureScreen(&sc);
189 sc->checkPixel( 0, 12, 63, 63, 195);
190 sc->checkPixel( 75, 75, 195, 63, 63);
191 sc->checkPixel(145, 145, 63, 63, 195);
192 }
193
194 SurfaceComposerClient::openGlobalTransaction();
195 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128));
196 SurfaceComposerClient::closeGlobalTransaction(true);
197 {
198 // This should reflect the new position, but not the new color.
199 SCOPED_TRACE("after move, before redraw");
200 ScreenCapture::captureScreen(&sc);
201 sc->checkPixel( 24, 24, 63, 63, 195);
202 sc->checkPixel( 75, 75, 63, 63, 195);
203 sc->checkPixel(145, 145, 195, 63, 63);
204 }
205
206 fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
207 waitForPostedBuffers();
208 {
209 // This should reflect the new position and the new color.
210 SCOPED_TRACE("after redraw");
211 ScreenCapture::captureScreen(&sc);
212 sc->checkPixel( 24, 24, 63, 63, 195);
213 sc->checkPixel( 75, 75, 63, 63, 195);
214 sc->checkPixel(145, 145, 63, 195, 63);
215 }
216}
217
218TEST_F(LayerUpdateTest, LayerResizeWorks) {
219 sp<ScreenCapture> sc;
220 {
221 SCOPED_TRACE("before resize");
222 ScreenCapture::captureScreen(&sc);
223 sc->checkPixel( 0, 12, 63, 63, 195);
224 sc->checkPixel( 75, 75, 195, 63, 63);
225 sc->checkPixel(145, 145, 63, 63, 195);
226 }
227
Steve Block9d453682011-12-20 16:23:08 +0000228 ALOGD("resizing");
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700229 SurfaceComposerClient::openGlobalTransaction();
230 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128));
231 SurfaceComposerClient::closeGlobalTransaction(true);
Steve Block9d453682011-12-20 16:23:08 +0000232 ALOGD("resized");
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700233 {
234 // This should not reflect the new size or color because SurfaceFlinger
235 // has not yet received a buffer of the correct size.
236 SCOPED_TRACE("after resize, before redraw");
237 ScreenCapture::captureScreen(&sc);
238 sc->checkPixel( 0, 12, 63, 63, 195);
239 sc->checkPixel( 75, 75, 195, 63, 63);
240 sc->checkPixel(145, 145, 63, 63, 195);
241 }
242
Steve Block9d453682011-12-20 16:23:08 +0000243 ALOGD("drawing");
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700244 fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
245 waitForPostedBuffers();
Steve Block9d453682011-12-20 16:23:08 +0000246 ALOGD("drawn");
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700247 {
248 // This should reflect the new size and the new color.
249 SCOPED_TRACE("after redraw");
250 ScreenCapture::captureScreen(&sc);
251 sc->checkPixel( 24, 24, 63, 63, 195);
252 sc->checkPixel( 75, 75, 63, 195, 63);
253 sc->checkPixel(145, 145, 63, 195, 63);
254 }
255}
256
Haixia Shid5750962015-07-27 16:50:49 -0700257TEST_F(LayerUpdateTest, LayerCropWorks) {
258 sp<ScreenCapture> sc;
259 {
260 SCOPED_TRACE("before crop");
261 ScreenCapture::captureScreen(&sc);
262 sc->checkPixel( 24, 24, 63, 63, 195);
263 sc->checkPixel( 75, 75, 195, 63, 63);
264 sc->checkPixel(145, 145, 63, 63, 195);
265 }
266
267 SurfaceComposerClient::openGlobalTransaction();
268 Rect cropRect(16, 16, 32, 32);
269 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setCrop(cropRect));
270 SurfaceComposerClient::closeGlobalTransaction(true);
271 {
272 // This should crop the foreground surface.
273 SCOPED_TRACE("after crop");
274 ScreenCapture::captureScreen(&sc);
275 sc->checkPixel( 24, 24, 63, 63, 195);
276 sc->checkPixel( 75, 75, 63, 63, 195);
277 sc->checkPixel( 95, 80, 195, 63, 63);
278 sc->checkPixel( 80, 95, 195, 63, 63);
279 sc->checkPixel( 96, 96, 63, 63, 195);
280 }
281}
282
283TEST_F(LayerUpdateTest, LayerSetLayerWorks) {
284 sp<ScreenCapture> sc;
285 {
286 SCOPED_TRACE("before setLayer");
287 ScreenCapture::captureScreen(&sc);
288 sc->checkPixel( 24, 24, 63, 63, 195);
289 sc->checkPixel( 75, 75, 195, 63, 63);
290 sc->checkPixel(145, 145, 63, 63, 195);
291 }
292
293 SurfaceComposerClient::openGlobalTransaction();
294 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX - 3));
295 SurfaceComposerClient::closeGlobalTransaction(true);
296 {
297 // This should hide the foreground surface beneath the background.
298 SCOPED_TRACE("after setLayer");
299 ScreenCapture::captureScreen(&sc);
300 sc->checkPixel( 24, 24, 63, 63, 195);
301 sc->checkPixel( 75, 75, 63, 63, 195);
302 sc->checkPixel(145, 145, 63, 63, 195);
303 }
304}
305
306TEST_F(LayerUpdateTest, LayerShowHideWorks) {
307 sp<ScreenCapture> sc;
308 {
309 SCOPED_TRACE("before hide");
310 ScreenCapture::captureScreen(&sc);
311 sc->checkPixel( 24, 24, 63, 63, 195);
312 sc->checkPixel( 75, 75, 195, 63, 63);
313 sc->checkPixel(145, 145, 63, 63, 195);
314 }
315
316 SurfaceComposerClient::openGlobalTransaction();
317 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide());
318 SurfaceComposerClient::closeGlobalTransaction(true);
319 {
320 // This should hide the foreground surface.
321 SCOPED_TRACE("after hide, before show");
322 ScreenCapture::captureScreen(&sc);
323 sc->checkPixel( 24, 24, 63, 63, 195);
324 sc->checkPixel( 75, 75, 63, 63, 195);
325 sc->checkPixel(145, 145, 63, 63, 195);
326 }
327
328 SurfaceComposerClient::openGlobalTransaction();
329 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show());
330 SurfaceComposerClient::closeGlobalTransaction(true);
331 {
332 // This should show the foreground surface.
333 SCOPED_TRACE("after show");
334 ScreenCapture::captureScreen(&sc);
335 sc->checkPixel( 24, 24, 63, 63, 195);
336 sc->checkPixel( 75, 75, 195, 63, 63);
337 sc->checkPixel(145, 145, 63, 63, 195);
338 }
339}
340
341TEST_F(LayerUpdateTest, LayerSetAlphaWorks) {
342 sp<ScreenCapture> sc;
343 {
344 SCOPED_TRACE("before setAlpha");
345 ScreenCapture::captureScreen(&sc);
346 sc->checkPixel( 24, 24, 63, 63, 195);
347 sc->checkPixel( 75, 75, 195, 63, 63);
348 sc->checkPixel(145, 145, 63, 63, 195);
349 }
350
351 SurfaceComposerClient::openGlobalTransaction();
352 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75f));
353 SurfaceComposerClient::closeGlobalTransaction(true);
354 {
355 // This should set foreground to be 75% opaque.
356 SCOPED_TRACE("after setAlpha");
357 ScreenCapture::captureScreen(&sc);
358 sc->checkPixel( 24, 24, 63, 63, 195);
359 sc->checkPixel( 75, 75, 162, 63, 96);
360 sc->checkPixel(145, 145, 63, 63, 195);
361 }
362}
363
Pablo Ceballos5e4fcbe2015-09-02 09:53:16 -0700364TEST_F(LayerUpdateTest, LayerSetLayerStackWorks) {
365 sp<ScreenCapture> sc;
366 {
367 SCOPED_TRACE("before setLayerStack");
368 ScreenCapture::captureScreen(&sc);
369 sc->checkPixel( 24, 24, 63, 63, 195);
370 sc->checkPixel( 75, 75, 195, 63, 63);
371 sc->checkPixel(145, 145, 63, 63, 195);
372 }
373
374 SurfaceComposerClient::openGlobalTransaction();
375 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayerStack(1));
376 SurfaceComposerClient::closeGlobalTransaction(true);
377 {
378 // This should hide the foreground surface since it goes to a different
379 // layer stack.
380 SCOPED_TRACE("after setLayerStack");
381 ScreenCapture::captureScreen(&sc);
382 sc->checkPixel( 24, 24, 63, 63, 195);
383 sc->checkPixel( 75, 75, 63, 63, 195);
384 sc->checkPixel(145, 145, 63, 63, 195);
385 }
386}
387
388TEST_F(LayerUpdateTest, LayerSetFlagsWorks) {
389 sp<ScreenCapture> sc;
390 {
391 SCOPED_TRACE("before setFlags");
392 ScreenCapture::captureScreen(&sc);
393 sc->checkPixel( 24, 24, 63, 63, 195);
394 sc->checkPixel( 75, 75, 195, 63, 63);
395 sc->checkPixel(145, 145, 63, 63, 195);
396 }
397
398 SurfaceComposerClient::openGlobalTransaction();
399 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFlags(
400 layer_state_t::eLayerHidden, layer_state_t::eLayerHidden));
401 SurfaceComposerClient::closeGlobalTransaction(true);
402 {
403 // This should hide the foreground surface
404 SCOPED_TRACE("after setFlags");
405 ScreenCapture::captureScreen(&sc);
406 sc->checkPixel( 24, 24, 63, 63, 195);
407 sc->checkPixel( 75, 75, 63, 63, 195);
408 sc->checkPixel(145, 145, 63, 63, 195);
409 }
410}
411
412TEST_F(LayerUpdateTest, LayerSetMatrixWorks) {
413 sp<ScreenCapture> sc;
414 {
415 SCOPED_TRACE("before setMatrix");
416 ScreenCapture::captureScreen(&sc);
417 sc->checkPixel( 24, 24, 63, 63, 195);
418 sc->checkPixel( 91, 96, 195, 63, 63);
419 sc->checkPixel( 96, 101, 195, 63, 63);
420 sc->checkPixel(145, 145, 63, 63, 195);
421 }
422
423 SurfaceComposerClient::openGlobalTransaction();
424 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setMatrix(M_SQRT1_2, M_SQRT1_2,
425 -M_SQRT1_2, M_SQRT1_2));
426 SurfaceComposerClient::closeGlobalTransaction(true);
427 {
428 SCOPED_TRACE("after setMatrix");
429 ScreenCapture::captureScreen(&sc);
430 sc->checkPixel( 24, 24, 63, 63, 195);
431 sc->checkPixel( 91, 96, 195, 63, 63);
432 sc->checkPixel( 96, 91, 63, 63, 195);
433 sc->checkPixel(145, 145, 63, 63, 195);
434 }
435}
436
Jamie Gennis23c2c5d2011-10-11 19:22:19 -0700437}