Hwc2TestBuffer.cpp revision 5a240aaf0e3a1dd52be6a8d0811ec727369a210d
15a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/*
25a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * Copyright (C) 2016 The Android Open Source Project
35a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall *
45a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * Licensed under the Apache License, Version 2.0 (the "License");
55a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * you may not use this file except in compliance with the License.
65a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * You may obtain a copy of the License at
75a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall *
85a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall *      http://www.apache.org/licenses/LICENSE-2.0
95a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall *
105a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * Unless required by applicable law or agreed to in writing, software
115a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * distributed under the License is distributed on an "AS IS" BASIS,
125a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * See the License for the specific language governing permissions and
145a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * limitations under the License.
155a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall */
165a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
175a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <mutex>
185a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <array>
195a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <sstream>
205a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <algorithm>
215a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
225a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <gui/Surface.h>
235a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <gui/BufferItemConsumer.h>
245a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <gui/GraphicBufferAlloc.h>
255a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
265a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <ui/GraphicBuffer.h>
275a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <ui/vec4.h>
285a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
295a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include <GLES3/gl3.h>
305a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
315a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include "Hwc2TestBuffer.h"
325a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall#include "Hwc2TestLayers.h"
335a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
345a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallusing namespace android;
355a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
365a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* Returns a fence from egl */
375a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Walltypedef void (*FenceCallback)(int32_t fence, void* callbackArgs);
385a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
395a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* Returns fence to fence generator */
405a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallstatic void setFence(int32_t fence, void* fenceGenerator);
415a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
425a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
435a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* Used to receive the surfaces and fences from egl. The egl buffers are thrown
445a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * away. The fences are sent to the requester via a callback */
455a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallclass Hwc2TestSurfaceManager {
465a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallpublic:
475a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Listens for a new frame, detaches the buffer and returns the fence
485a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall     * through saved callback. */
495a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    class BufferListener : public ConsumerBase::FrameAvailableListener {
505a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    public:
515a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        BufferListener(sp<IGraphicBufferConsumer> consumer,
525a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                FenceCallback callback, void* callbackArgs)
535a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            : mConsumer(consumer),
545a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall              mCallback(callback),
555a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall              mCallbackArgs(callbackArgs) { }
565a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
575a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        void onFrameAvailable(const BufferItem& /*item*/)
585a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        {
595a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            BufferItem item;
605a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
615a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            if (mConsumer->acquireBuffer(&item, 0))
625a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                return;
635a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            if (mConsumer->detachBuffer(item.mSlot))
645a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                return;
655a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
665a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            mCallback(item.mFence->dup(), mCallbackArgs);
675a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
685a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
695a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    private:
705a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        sp<IGraphicBufferConsumer> mConsumer;
715a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        FenceCallback mCallback;
725a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        void* mCallbackArgs;
735a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    };
745a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
755a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Creates a buffer listener that waits on a new frame from the buffer
765a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall     * queue. */
775a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    void initialize(const Area& bufferArea, android_pixel_format_t format,
785a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            FenceCallback callback, void* callbackArgs)
795a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
805a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        sp<IGraphicBufferProducer> producer;
815a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        sp<IGraphicBufferConsumer> consumer;
825a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        BufferQueue::createBufferQueue(&producer, &consumer);
835a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
845a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        consumer->setDefaultBufferSize(bufferArea.width, bufferArea.height);
855a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        consumer->setDefaultBufferFormat(format);
865a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
875a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mBufferItemConsumer = new BufferItemConsumer(consumer, 0);
885a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
895a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mListener = new BufferListener(consumer, callback, callbackArgs);
905a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mBufferItemConsumer->setFrameAvailableListener(mListener);
915a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
925a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mSurface = new Surface(producer, true);
935a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
945a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
955a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Used by Egl manager. The surface is never displayed. */
965a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    sp<Surface> getSurface() const
975a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
985a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        return mSurface;
995a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
1005a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1015a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallprivate:
1025a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    sp<BufferItemConsumer> mBufferItemConsumer;
1035a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    sp<BufferListener> mListener;
1045a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Used by Egl manager. The surface is never displayed */
1055a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    sp<Surface> mSurface;
1065a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall};
1075a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1085a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1095a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* Used to generate valid fences. It is not possible to create a dummy sync
1105a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * fence for testing. Egl can generate buffers along with a valid fence.
1115a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * The buffer cannot be guaranteed to be the same format across all devices so
1125a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * a CPU filled buffer is used instead. The Egl fence is used along with the
1135a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * CPU filled buffer. */
1145a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallclass Hwc2TestEglManager {
1155a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallpublic:
1165a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    Hwc2TestEglManager()
1175a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        : mEglDisplay(EGL_NO_DISPLAY),
1185a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall          mEglSurface(EGL_NO_SURFACE),
1195a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall          mEglContext(EGL_NO_CONTEXT) { }
1205a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1215a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    ~Hwc2TestEglManager()
1225a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
1235a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        cleanup();
1245a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
1255a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1265a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    int initialize(sp<Surface> surface)
1275a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
1285a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mSurface = surface;
1295a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1305a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1315a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mEglDisplay == EGL_NO_DISPLAY) return false;
1325a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1335a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLint major;
1345a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLint minor;
1355a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (!eglInitialize(mEglDisplay, &major, &minor)) {
1365a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            ALOGW("Could not initialize EGL");
1375a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return false;
1385a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
1395a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1405a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* We're going to use a 1x1 pbuffer surface later on
1415a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * The configuration distance doesn't really matter for what we're
1425a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * trying to do */
1435a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLint configAttrs[] = {
1445a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
1455a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_RED_SIZE, 8,
1465a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_GREEN_SIZE, 8,
1475a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_BLUE_SIZE, 8,
1485a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_ALPHA_SIZE, 0,
1495a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_DEPTH_SIZE, 24,
1505a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_STENCIL_SIZE, 0,
1515a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_NONE
1525a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        };
1535a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1545a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLConfig configs[1];
1555a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLint configCnt;
1565a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (!eglChooseConfig(mEglDisplay, configAttrs, configs, 1,
1575a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                &configCnt)) {
1585a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            ALOGW("Could not select EGL configuration");
1595a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            eglReleaseThread();
1605a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            eglTerminate(mEglDisplay);
1615a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return false;
1625a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
1635a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1645a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (configCnt <= 0) {
1655a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            ALOGW("Could not find EGL configuration");
1665a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            eglReleaseThread();
1675a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            eglTerminate(mEglDisplay);
1685a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return false;
1695a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
1705a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1715a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* These objects are initialized below but the default "null" values are
1725a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * used to cleanup properly at any point in the initialization sequence */
1735a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
1745a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglContext = eglCreateContext(mEglDisplay, configs[0], EGL_NO_CONTEXT,
1755a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                attrs);
1765a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mEglContext == EGL_NO_CONTEXT) {
1775a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            ALOGW("Could not create EGL context");
1785a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            cleanup();
1795a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return false;
1805a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
1815a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1825a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        EGLint surfaceAttrs[] = { EGL_NONE };
1835a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglSurface = eglCreateWindowSurface(mEglDisplay, configs[0],
1845a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                mSurface.get(), surfaceAttrs);
1855a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mEglSurface == EGL_NO_SURFACE) {
1865a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            ALOGW("Could not create EGL surface");
1875a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            cleanup();
1885a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return false;
1895a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
1905a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1915a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
1925a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            ALOGW("Could not change current EGL context");
1935a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            cleanup();
1945a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return false;
1955a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
1965a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
1975a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        return true;
1985a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
1995a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2005a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    void makeCurrent() const
2015a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
2025a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
2035a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
2045a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2055a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    void present() const
2065a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
2075a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        eglSwapBuffers(mEglDisplay, mEglSurface);
2085a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
2095a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2105a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallprivate:
2115a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    void cleanup()
2125a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
2135a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mEglDisplay == EGL_NO_DISPLAY)
2145a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return;
2155a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mEglSurface != EGL_NO_SURFACE)
2165a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            eglDestroySurface(mEglDisplay, mEglSurface);
2175a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mEglContext != EGL_NO_CONTEXT)
2185a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            eglDestroyContext(mEglDisplay, mEglContext);
2195a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2205a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
2215a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                EGL_NO_CONTEXT);
2225a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        eglReleaseThread();
2235a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        eglTerminate(mEglDisplay);
2245a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
2255a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2265a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    sp<Surface> mSurface;
2275a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    EGLDisplay mEglDisplay;
2285a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    EGLSurface mEglSurface;
2295a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    EGLContext mEglContext;
2305a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall};
2315a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2325a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2335a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallstatic const std::array<vec2, 4> triangles = {{
2345a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {  1.0f,  1.0f },
2355a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    { -1.0f,  1.0f },
2365a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {  1.0f, -1.0f },
2375a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    { -1.0f, -1.0f },
2385a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall}};
2395a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2405a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallclass Hwc2TestFenceGenerator {
2415a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallpublic:
2425a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2435a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    Hwc2TestFenceGenerator()
2445a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
2455a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mSurfaceManager.initialize({1, 1}, HAL_PIXEL_FORMAT_RGBA_8888,
2465a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                setFence, this);
2475a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2485a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (!mEglManager.initialize(mSurfaceManager.getSurface()))
2495a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return;
2505a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2515a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglManager.makeCurrent();
2525a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2535a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        glClearColor(0.0, 0.0, 0.0, 1.0);
2545a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        glEnableVertexAttribArray(0);
2555a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
2565a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2575a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    ~Hwc2TestFenceGenerator()
2585a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
2595a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mFence >= 0)
2605a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            close(mFence);
2615a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mFence = -1;
2625a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2635a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglManager.makeCurrent();
2645a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
2655a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2665a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* It is not possible to simply generate a fence. The easiest way is to
2675a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall     * generate a buffer using egl and use the associated fence. The buffer
2685a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall     * cannot be guaranteed to be a certain format across all devices using this
2695a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall     * method. Instead the buffer is generated using the CPU */
2705a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    int32_t get()
2715a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
2725a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (mFence >= 0) {
2735a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return dup(mFence);
2745a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
2755a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2765a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        std::unique_lock<std::mutex> lock(mMutex);
2775a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2785a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* If the pending is still set to false and times out, we cannot recover.
2795a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * Set an error and return */
2805a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        while (mPending != false) {
2815a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            if (mCv.wait_for(lock, std::chrono::seconds(2)) == std::cv_status::timeout)
2825a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                return -ETIME;
2835a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
2845a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2855a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* Generate a fence. The fence will be returned through the setFence
2865a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * callback */
2875a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglManager.makeCurrent();
2885a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2895a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, triangles.data());
2905a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        glClear(GL_COLOR_BUFFER_BIT);
2915a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2925a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mEglManager.present();
2935a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
2945a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* Wait for the setFence callback */
2955a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        while (mPending != true) {
2965a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            if (mCv.wait_for(lock, std::chrono::seconds(2)) == std::cv_status::timeout)
2975a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall                return -ETIME;
2985a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
2995a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3005a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mPending = false;
3015a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3025a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        return dup(mFence);
3035a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
3045a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3055a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Callback that sets the fence */
3065a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    void set(int32_t fence)
3075a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    {
3085a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mFence = fence;
3095a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mPending = true;
3105a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3115a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        mCv.notify_all();
3125a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
3135a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3145a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallprivate:
3155a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3165a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    Hwc2TestSurfaceManager mSurfaceManager;
3175a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    Hwc2TestEglManager mEglManager;
3185a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3195a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    std::mutex mMutex;
3205a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    std::condition_variable mCv;
3215a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3225a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    int32_t mFence = -1;
3235a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    bool mPending = false;
3245a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall};
3255a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3265a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3275a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallstatic void setFence(int32_t fence, void* fenceGenerator)
3285a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall{
3295a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    static_cast<Hwc2TestFenceGenerator*>(fenceGenerator)->set(fence);
3305a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall}
3315a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3325a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3335a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa WallHwc2TestBuffer::Hwc2TestBuffer()
3345a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    : mFenceGenerator(new Hwc2TestFenceGenerator()) { }
3355a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3365a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa WallHwc2TestBuffer::~Hwc2TestBuffer() = default;
3375a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3385a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* When the buffer changes sizes, save the new size and invalidate the current
3395a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * buffer */
3405a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallvoid Hwc2TestBuffer::updateBufferArea(const Area& bufferArea)
3415a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall{
3425a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    if (mBufferArea.width == bufferArea.width
3435a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            && mBufferArea.height == bufferArea.height)
3445a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        return;
3455a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3465a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mBufferArea.width = bufferArea.width;
3475a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mBufferArea.height = bufferArea.height;
3485a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3495a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mValidBuffer = false;
3505a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall}
3515a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3525a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* Returns a valid buffer handle and fence. The handle is filled using the CPU
3535a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * to ensure the correct format across all devices. The fence is created using
3545a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * egl. */
3555a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallint Hwc2TestBuffer::get(buffer_handle_t* outHandle, int32_t* outFence)
3565a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall{
3575a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    if (mBufferArea.width == -1 || mBufferArea.height == -1)
3585a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        return -EINVAL;
3595a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3605a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* If the current buffer is valid, the previous buffer can be reused.
3615a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall     * Otherwise, create new buffer */
3625a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    if (!mValidBuffer) {
3635a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        int ret = generateBuffer();
3645a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (ret)
3655a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            return ret;
3665a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
3675a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3685a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    *outFence = mFenceGenerator->get();
3695a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    *outHandle = mHandle;
3705a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3715a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mValidBuffer = true;
3725a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3735a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    return 0;
3745a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall}
3755a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3765a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* CPU fills a buffer to guarantee the correct buffer format across all
3775a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * devices */
3785a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallint Hwc2TestBuffer::generateBuffer()
3795a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall{
3805a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    int ret;
3815a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3825a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Create new graphic buffer with correct dimensions */
3835a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mGraphicBuffer = mGraphicBufferAlloc.createGraphicBuffer(
3845a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            mBufferArea.width, mBufferArea.height, mFormat,
3855a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER,
3865a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            "hwc2_test_buffer", &ret);
3875a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    if (ret)
3885a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        return ret;
3895a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3905a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Locks the buffer for writing */
3915a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    uint8_t* img;
3925a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mGraphicBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3935a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3945a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    uint32_t stride = mGraphicBuffer->getStride();
3955a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3965a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Iterate from the top row of the buffer to the bottom row */
3975a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    for (int32_t y = 0; y < mBufferArea.height; y++) {
3985a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
3995a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* Will be used as R, G and B values for pixel colors */
4005a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        uint8_t max = 255;
4015a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        uint8_t min = 0;
4025a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4035a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* Divide the rows into 3 sections. The first section will contain
4045a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * the lighest colors. The last section will contain the darkest
4055a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * colors. */
4065a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        if (y < mBufferArea.height * 1.0 / 3.0) {
4075a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            min = 255 / 2;
4085a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        } else if (y >= mBufferArea.height * 2.0 / 3.0) {
4095a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            max = 255 / 2;
4105a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
4115a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4125a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        /* Divide the columns into 3 sections. The first section is red,
4135a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall         * the second is green and the third is blue */
4145a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        int32_t x = 0;
4155a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        for (; x < mBufferArea.width / 3; x++) {
4165a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            setColor(x, y, mFormat, stride, img, max, min, min, 255);
4175a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
4185a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4195a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        for (; x < mBufferArea.width * 2 / 3; x++) {
4205a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            setColor(x, y, mFormat, stride, img, min, max, min, 255);
4215a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
4225a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4235a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        for (; x < mBufferArea.width; x++) {
4245a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall            setColor(x, y, mFormat, stride, img, min, min, max, 255);
4255a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        }
4265a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    }
4275a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4285a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    /* Unlock the buffer for reading */
4295a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mGraphicBuffer->unlock();
4305a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4315a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    mHandle = mGraphicBuffer->handle;
4325a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4335a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall    return 0;
4345a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall}
4355a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall
4365a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall/* Sets the pixel of a buffer given the location, format, stride and color.
4375a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall * Currently only supports RGBA_8888 */
4385a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wallvoid Hwc2TestBuffer::setColor(int32_t x, int32_t y,
4395a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        android_pixel_format_t format, uint32_t stride, uint8_t* img, uint8_t r,
4405a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall        uint8_t g, uint8_t b, uint8_t a)
4415a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall{
4425a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall       switch (format) {
4435a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall       case HAL_PIXEL_FORMAT_RGBA_8888:
4445a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall           img[(y * stride + x) * 4 + 0] = r;
4455a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall           img[(y * stride + x) * 4 + 1] = g;
4465a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall           img[(y * stride + x) * 4 + 2] = b;
4475a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall           img[(y * stride + x) * 4 + 3] = a;
4485a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall           break;
4495a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall       default:
4505a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall           break;
4515a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall       }
4525a240aaf0e3a1dd52be6a8d0811ec727369a210dMarissa Wall}
453