1/*
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
19#include <android/native_window.h>
20
21#include <binder/IMemory.h>
22
23#include <gui/ISurfaceComposer.h>
24#include <gui/Surface.h>
25#include <gui/SurfaceComposerClient.h>
26#include <private/gui/ComposerService.h>
27#include <private/gui/LayerState.h>
28
29#include <utils/String8.h>
30#include <ui/DisplayInfo.h>
31
32#include <math.h>
33
34namespace 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) {
39    ANativeWindow_Buffer outBuffer;
40    sp<Surface> s = sc->getSurface();
41    ASSERT_TRUE(s != NULL);
42    ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, NULL));
43    uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
44    for (int y = 0; y < outBuffer.height; y++) {
45        for (int x = 0; x < outBuffer.width; x++) {
46            uint8_t* pixel = img + (4 * (y*outBuffer.stride + x));
47            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) {
61        sp<IGraphicBufferProducer> producer;
62        sp<IGraphicBufferConsumer> consumer;
63        BufferQueue::createBufferQueue(&producer, &consumer);
64        IGraphicBufferProducer::QueueBufferOutput bufferOutput;
65        sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
66        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
67        sp<IBinder> display(sf->getBuiltInDisplay(
68                ISurfaceComposer::eDisplayIdMain));
69        SurfaceComposerClient::openGlobalTransaction();
70        SurfaceComposerClient::closeGlobalTransaction(true);
71        ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 0, 0,
72                0, INT_MAX, false));
73        *sc = new ScreenCapture(cpuConsumer);
74    }
75
76    void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) {
77        ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mBuf.format);
78        const uint8_t* img = static_cast<const uint8_t*>(mBuf.data);
79        const uint8_t* pixel = img + (4 * (y * mBuf.stride + x));
80        if (r != pixel[0] || g != pixel[1] || b != pixel[2]) {
81            String8 err(String8::format("pixel @ (%3d, %3d): "
82                    "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]",
83                    x, y, r, g, b, pixel[0], pixel[1], pixel[2]));
84            EXPECT_EQ(String8(), err) << err.string();
85        }
86    }
87
88private:
89    ScreenCapture(const sp<CpuConsumer>& cc) :
90        mCC(cc) {
91        EXPECT_EQ(NO_ERROR, mCC->lockNextBuffer(&mBuf));
92    }
93
94    ~ScreenCapture() {
95        mCC->unlockBuffer(mBuf);
96    }
97
98    sp<CpuConsumer> mCC;
99    CpuConsumer::LockedBuffer mBuf;
100};
101
102class LayerUpdateTest : public ::testing::Test {
103protected:
104    virtual void SetUp() {
105        mComposerClient = new SurfaceComposerClient;
106        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
107
108        sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
109                ISurfaceComposer::eDisplayIdMain));
110        DisplayInfo info;
111        SurfaceComposerClient::getDisplayInfo(display, &info);
112
113        ssize_t displayWidth = info.w;
114        ssize_t displayHeight = info.h;
115
116        // Background surface
117        mBGSurfaceControl = mComposerClient->createSurface(
118                String8("BG Test Surface"), displayWidth, displayHeight,
119                PIXEL_FORMAT_RGBA_8888, 0);
120        ASSERT_TRUE(mBGSurfaceControl != NULL);
121        ASSERT_TRUE(mBGSurfaceControl->isValid());
122        fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
123
124        // Foreground surface
125        mFGSurfaceControl = mComposerClient->createSurface(
126                String8("FG Test Surface"), 64, 64, PIXEL_FORMAT_RGBA_8888, 0);
127        ASSERT_TRUE(mFGSurfaceControl != NULL);
128        ASSERT_TRUE(mFGSurfaceControl->isValid());
129
130        fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
131
132        // Synchronization surface
133        mSyncSurfaceControl = mComposerClient->createSurface(
134                String8("Sync Test Surface"), 1, 1, PIXEL_FORMAT_RGBA_8888, 0);
135        ASSERT_TRUE(mSyncSurfaceControl != NULL);
136        ASSERT_TRUE(mSyncSurfaceControl->isValid());
137
138        fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
139
140        SurfaceComposerClient::openGlobalTransaction();
141
142        mComposerClient->setDisplayLayerStack(display, 0);
143
144        ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT_MAX-2));
145        ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show());
146
147        ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX-1));
148        ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64));
149        ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show());
150
151        ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setLayer(INT_MAX-1));
152        ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setPosition(displayWidth-2,
153                displayHeight-2));
154        ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->show());
155
156        SurfaceComposerClient::closeGlobalTransaction(true);
157    }
158
159    virtual void TearDown() {
160        mComposerClient->dispose();
161        mBGSurfaceControl = 0;
162        mFGSurfaceControl = 0;
163        mSyncSurfaceControl = 0;
164        mComposerClient = 0;
165    }
166
167    void waitForPostedBuffers() {
168        // Since the sync surface is in synchronous mode (i.e. double buffered)
169        // posting three buffers to it should ensure that at least two
170        // SurfaceFlinger::handlePageFlip calls have been made, which should
171        // guaranteed that a buffer posted to another Surface has been retired.
172        fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
173        fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
174        fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
175    }
176
177    sp<SurfaceComposerClient> mComposerClient;
178    sp<SurfaceControl> mBGSurfaceControl;
179    sp<SurfaceControl> mFGSurfaceControl;
180
181    // This surface is used to ensure that the buffers posted to
182    // mFGSurfaceControl have been picked up by SurfaceFlinger.
183    sp<SurfaceControl> mSyncSurfaceControl;
184};
185
186TEST_F(LayerUpdateTest, LayerMoveWorks) {
187    sp<ScreenCapture> sc;
188    {
189        SCOPED_TRACE("before move");
190        ScreenCapture::captureScreen(&sc);
191        sc->checkPixel(  0,  12,  63,  63, 195);
192        sc->checkPixel( 75,  75, 195,  63,  63);
193        sc->checkPixel(145, 145,  63,  63, 195);
194    }
195
196    SurfaceComposerClient::openGlobalTransaction();
197    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128));
198    SurfaceComposerClient::closeGlobalTransaction(true);
199    {
200        // This should reflect the new position, but not the new color.
201        SCOPED_TRACE("after move, before redraw");
202        ScreenCapture::captureScreen(&sc);
203        sc->checkPixel( 24,  24,  63,  63, 195);
204        sc->checkPixel( 75,  75,  63,  63, 195);
205        sc->checkPixel(145, 145, 195,  63,  63);
206    }
207
208    fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
209    waitForPostedBuffers();
210    {
211        // This should reflect the new position and the new color.
212        SCOPED_TRACE("after redraw");
213        ScreenCapture::captureScreen(&sc);
214        sc->checkPixel( 24,  24,  63,  63, 195);
215        sc->checkPixel( 75,  75,  63,  63, 195);
216        sc->checkPixel(145, 145,  63, 195,  63);
217    }
218}
219
220TEST_F(LayerUpdateTest, LayerResizeWorks) {
221    sp<ScreenCapture> sc;
222    {
223        SCOPED_TRACE("before resize");
224        ScreenCapture::captureScreen(&sc);
225        sc->checkPixel(  0,  12,  63,  63, 195);
226        sc->checkPixel( 75,  75, 195,  63,  63);
227        sc->checkPixel(145, 145,  63,  63, 195);
228    }
229
230    ALOGD("resizing");
231    SurfaceComposerClient::openGlobalTransaction();
232    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128));
233    SurfaceComposerClient::closeGlobalTransaction(true);
234    ALOGD("resized");
235    {
236        // This should not reflect the new size or color because SurfaceFlinger
237        // has not yet received a buffer of the correct size.
238        SCOPED_TRACE("after resize, before redraw");
239        ScreenCapture::captureScreen(&sc);
240        sc->checkPixel(  0,  12,  63,  63, 195);
241        sc->checkPixel( 75,  75, 195,  63,  63);
242        sc->checkPixel(145, 145,  63,  63, 195);
243    }
244
245    ALOGD("drawing");
246    fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
247    waitForPostedBuffers();
248    ALOGD("drawn");
249    {
250        // This should reflect the new size and the new color.
251        SCOPED_TRACE("after redraw");
252        ScreenCapture::captureScreen(&sc);
253        sc->checkPixel( 24,  24,  63,  63, 195);
254        sc->checkPixel( 75,  75,  63, 195,  63);
255        sc->checkPixel(145, 145,  63, 195,  63);
256    }
257}
258
259TEST_F(LayerUpdateTest, LayerCropWorks) {
260    sp<ScreenCapture> sc;
261    {
262        SCOPED_TRACE("before crop");
263        ScreenCapture::captureScreen(&sc);
264        sc->checkPixel( 24,  24,  63,  63, 195);
265        sc->checkPixel( 75,  75, 195,  63,  63);
266        sc->checkPixel(145, 145,  63,  63, 195);
267    }
268
269    SurfaceComposerClient::openGlobalTransaction();
270    Rect cropRect(16, 16, 32, 32);
271    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setCrop(cropRect));
272    SurfaceComposerClient::closeGlobalTransaction(true);
273    {
274        // This should crop the foreground surface.
275        SCOPED_TRACE("after crop");
276        ScreenCapture::captureScreen(&sc);
277        sc->checkPixel( 24,  24,  63,  63, 195);
278        sc->checkPixel( 75,  75,  63,  63, 195);
279        sc->checkPixel( 95,  80, 195,  63,  63);
280        sc->checkPixel( 80,  95, 195,  63,  63);
281        sc->checkPixel( 96,  96,  63,  63, 195);
282    }
283}
284
285TEST_F(LayerUpdateTest, LayerFinalCropWorks) {
286    sp<ScreenCapture> sc;
287    {
288        SCOPED_TRACE("before crop");
289        ScreenCapture::captureScreen(&sc);
290        sc->checkPixel( 24,  24,  63,  63, 195);
291        sc->checkPixel( 75,  75, 195,  63,  63);
292        sc->checkPixel(145, 145,  63,  63, 195);
293    }
294    SurfaceComposerClient::openGlobalTransaction();
295    Rect cropRect(16, 16, 32, 32);
296    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFinalCrop(cropRect));
297    SurfaceComposerClient::closeGlobalTransaction(true);
298    {
299        // This should crop the foreground surface.
300        SCOPED_TRACE("after crop");
301        ScreenCapture::captureScreen(&sc);
302        sc->checkPixel( 24,  24,  63,  63, 195);
303        sc->checkPixel( 75,  75,  63,  63, 195);
304        sc->checkPixel( 95,  80,  63,  63, 195);
305        sc->checkPixel( 80,  95,  63,  63, 195);
306        sc->checkPixel( 96,  96,  63,  63, 195);
307    }
308}
309
310TEST_F(LayerUpdateTest, LayerSetLayerWorks) {
311    sp<ScreenCapture> sc;
312    {
313        SCOPED_TRACE("before setLayer");
314        ScreenCapture::captureScreen(&sc);
315        sc->checkPixel( 24,  24,  63,  63, 195);
316        sc->checkPixel( 75,  75, 195,  63,  63);
317        sc->checkPixel(145, 145,  63,  63, 195);
318    }
319
320    SurfaceComposerClient::openGlobalTransaction();
321    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX - 3));
322    SurfaceComposerClient::closeGlobalTransaction(true);
323    {
324        // This should hide the foreground surface beneath the background.
325        SCOPED_TRACE("after setLayer");
326        ScreenCapture::captureScreen(&sc);
327        sc->checkPixel( 24,  24,  63,  63, 195);
328        sc->checkPixel( 75,  75,  63,  63, 195);
329        sc->checkPixel(145, 145,  63,  63, 195);
330    }
331}
332
333TEST_F(LayerUpdateTest, LayerShowHideWorks) {
334    sp<ScreenCapture> sc;
335    {
336        SCOPED_TRACE("before hide");
337        ScreenCapture::captureScreen(&sc);
338        sc->checkPixel( 24,  24,  63,  63, 195);
339        sc->checkPixel( 75,  75, 195,  63,  63);
340        sc->checkPixel(145, 145,  63,  63, 195);
341    }
342
343    SurfaceComposerClient::openGlobalTransaction();
344    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide());
345    SurfaceComposerClient::closeGlobalTransaction(true);
346    {
347        // This should hide the foreground surface.
348        SCOPED_TRACE("after hide, before show");
349        ScreenCapture::captureScreen(&sc);
350        sc->checkPixel( 24,  24,  63,  63, 195);
351        sc->checkPixel( 75,  75,  63,  63, 195);
352        sc->checkPixel(145, 145,  63,  63, 195);
353    }
354
355    SurfaceComposerClient::openGlobalTransaction();
356    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show());
357    SurfaceComposerClient::closeGlobalTransaction(true);
358    {
359        // This should show the foreground surface.
360        SCOPED_TRACE("after show");
361        ScreenCapture::captureScreen(&sc);
362        sc->checkPixel( 24,  24,  63,  63, 195);
363        sc->checkPixel( 75,  75, 195,  63,  63);
364        sc->checkPixel(145, 145,  63,  63, 195);
365    }
366}
367
368TEST_F(LayerUpdateTest, LayerSetAlphaWorks) {
369    sp<ScreenCapture> sc;
370    {
371        SCOPED_TRACE("before setAlpha");
372        ScreenCapture::captureScreen(&sc);
373        sc->checkPixel( 24,  24,  63,  63, 195);
374        sc->checkPixel( 75,  75, 195,  63,  63);
375        sc->checkPixel(145, 145,  63,  63, 195);
376    }
377
378    SurfaceComposerClient::openGlobalTransaction();
379    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75f));
380    SurfaceComposerClient::closeGlobalTransaction(true);
381    {
382        // This should set foreground to be 75% opaque.
383        SCOPED_TRACE("after setAlpha");
384        ScreenCapture::captureScreen(&sc);
385        sc->checkPixel( 24,  24,  63,  63, 195);
386        sc->checkPixel( 75,  75, 162,  63,  96);
387        sc->checkPixel(145, 145,  63,  63, 195);
388    }
389}
390
391TEST_F(LayerUpdateTest, LayerSetLayerStackWorks) {
392    sp<ScreenCapture> sc;
393    {
394        SCOPED_TRACE("before setLayerStack");
395        ScreenCapture::captureScreen(&sc);
396        sc->checkPixel( 24,  24,  63,  63, 195);
397        sc->checkPixel( 75,  75, 195,  63,  63);
398        sc->checkPixel(145, 145,  63,  63, 195);
399    }
400
401    SurfaceComposerClient::openGlobalTransaction();
402    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayerStack(1));
403    SurfaceComposerClient::closeGlobalTransaction(true);
404    {
405        // This should hide the foreground surface since it goes to a different
406        // layer stack.
407        SCOPED_TRACE("after setLayerStack");
408        ScreenCapture::captureScreen(&sc);
409        sc->checkPixel( 24,  24,  63,  63, 195);
410        sc->checkPixel( 75,  75,  63,  63, 195);
411        sc->checkPixel(145, 145,  63,  63, 195);
412    }
413}
414
415TEST_F(LayerUpdateTest, LayerSetFlagsWorks) {
416    sp<ScreenCapture> sc;
417    {
418        SCOPED_TRACE("before setFlags");
419        ScreenCapture::captureScreen(&sc);
420        sc->checkPixel( 24,  24,  63,  63, 195);
421        sc->checkPixel( 75,  75, 195,  63,  63);
422        sc->checkPixel(145, 145,  63,  63, 195);
423    }
424
425    SurfaceComposerClient::openGlobalTransaction();
426    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFlags(
427            layer_state_t::eLayerHidden, layer_state_t::eLayerHidden));
428    SurfaceComposerClient::closeGlobalTransaction(true);
429    {
430        // This should hide the foreground surface
431        SCOPED_TRACE("after setFlags");
432        ScreenCapture::captureScreen(&sc);
433        sc->checkPixel( 24,  24,  63,  63, 195);
434        sc->checkPixel( 75,  75,  63,  63, 195);
435        sc->checkPixel(145, 145,  63,  63, 195);
436    }
437}
438
439TEST_F(LayerUpdateTest, LayerSetMatrixWorks) {
440    sp<ScreenCapture> sc;
441    {
442        SCOPED_TRACE("before setMatrix");
443        ScreenCapture::captureScreen(&sc);
444        sc->checkPixel( 24,  24,  63,  63, 195);
445        sc->checkPixel( 91,  96, 195,  63,  63);
446        sc->checkPixel( 96, 101, 195,  63,  63);
447        sc->checkPixel(145, 145,  63,  63, 195);
448    }
449
450    SurfaceComposerClient::openGlobalTransaction();
451    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setMatrix(M_SQRT1_2, M_SQRT1_2,
452            -M_SQRT1_2, M_SQRT1_2));
453    SurfaceComposerClient::closeGlobalTransaction(true);
454    {
455        SCOPED_TRACE("after setMatrix");
456        ScreenCapture::captureScreen(&sc);
457        sc->checkPixel( 24,  24,  63,  63, 195);
458        sc->checkPixel( 91,  96, 195,  63,  63);
459        sc->checkPixel( 96,  91,  63,  63, 195);
460        sc->checkPixel(145, 145,  63,  63, 195);
461    }
462}
463
464TEST_F(LayerUpdateTest, DeferredTransactionTest) {
465    sp<ScreenCapture> sc;
466    {
467        SCOPED_TRACE("before anything");
468        ScreenCapture::captureScreen(&sc);
469        sc->checkPixel( 32,  32,  63,  63, 195);
470        sc->checkPixel( 96,  96, 195,  63,  63);
471        sc->checkPixel(160, 160,  63,  63, 195);
472    }
473
474    // set up two deferred transactions on different frames
475    SurfaceComposerClient::openGlobalTransaction();
476    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75));
477    mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(),
478            mSyncSurfaceControl->getSurface()->getNextFrameNumber());
479    SurfaceComposerClient::closeGlobalTransaction(true);
480
481    SurfaceComposerClient::openGlobalTransaction();
482    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128,128));
483    mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(),
484            mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
485    SurfaceComposerClient::closeGlobalTransaction(true);
486
487    {
488        SCOPED_TRACE("before any trigger");
489        ScreenCapture::captureScreen(&sc);
490        sc->checkPixel( 32,  32,  63,  63, 195);
491        sc->checkPixel( 96,  96, 195,  63,  63);
492        sc->checkPixel(160, 160,  63,  63, 195);
493    }
494
495    // should trigger the first deferred transaction, but not the second one
496    fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
497    {
498        SCOPED_TRACE("after first trigger");
499        ScreenCapture::captureScreen(&sc);
500        sc->checkPixel( 32,  32,  63,  63, 195);
501        sc->checkPixel( 96,  96, 162,  63,  96);
502        sc->checkPixel(160, 160,  63,  63, 195);
503    }
504
505    // should show up immediately since it's not deferred
506    SurfaceComposerClient::openGlobalTransaction();
507    ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(1.0));
508    SurfaceComposerClient::closeGlobalTransaction(true);
509
510    // trigger the second deferred transaction
511    fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
512    {
513        SCOPED_TRACE("after second trigger");
514        ScreenCapture::captureScreen(&sc);
515        sc->checkPixel( 32,  32,  63,  63, 195);
516        sc->checkPixel( 96,  96,  63,  63, 195);
517        sc->checkPixel(160, 160, 195,  63,  63);
518    }
519}
520
521}
522