Hwc2TestBuffer.cpp revision dde19448624ca514e0598f0343029c1ca4960c05
12fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers/* 22fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * Copyright (C) 2016 The Android Open Source Project 32fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * 42fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 52fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * you may not use this file except in compliance with the License. 62fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * You may obtain a copy of the License at 72fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * 82fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 92fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * 102fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * Unless required by applicable law or agreed to in writing, software 112fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 122fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * See the License for the specific language governing permissions and 142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * limitations under the License. 152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers */ 162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 178ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz#include <mutex> 18b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include <array> 19d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include <sstream> 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <algorithm> 21b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 22b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include <gui/Surface.h> 232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#include <gui/BufferItemConsumer.h> 242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#include <gui/GraphicBufferAlloc.h> 252fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 2664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#include <ui/GraphicBuffer.h> 27ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include <math/vec4.h> 285d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 2964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers#include <GLES3/gl3.h> 3064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 31a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers#include "Hwc2TestBuffer.h" 32a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers#include "Hwc2TestLayers.h" 33a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers 34a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogersusing namespace android; 35a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers 36b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier/* Returns a fence from egl */ 37a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogerstypedef void (*FenceCallback)(int32_t fence, void* callbackArgs); 38a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers 39f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi/* Returns fence to fence generator */ 40f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchistatic void setFence(int32_t fence, void* fenceGenerator); 41a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers 4264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 4364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers/* Used to receive the surfaces and fences from egl. The egl buffers are thrown 447a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers * away. The fences are sent to the requester via a callback */ 4564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersclass Hwc2TestSurfaceManager { 4664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogerspublic: 4764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers /* Listens for a new frame, detaches the buffer and returns the fence 485d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao * through saved callback. */ 495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao class BufferListener : public ConsumerBase::FrameAvailableListener { 505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao public: 5164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers BufferListener(sp<IGraphicBufferConsumer> consumer, 52f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier FenceCallback callback, void* callbackArgs) 53f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier : mConsumer(consumer), 5464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mCallback(callback), 555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mCallbackArgs(callbackArgs) { } 5664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao void onFrameAvailable(const BufferItem& /*item*/) 5864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao BufferItem item; 605d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 615d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao if (mConsumer->acquireBuffer(&item, 0)) 6264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return; 6364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (mConsumer->detachBuffer(item.mSlot)) 6464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return; 6505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 6664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mCallback(item.mFence->dup(), mCallbackArgs); 675d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 6864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 6964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers private: 7064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers sp<IGraphicBufferConsumer> mConsumer; 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers FenceCallback mCallback; 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers void* mCallbackArgs; 735d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao }; 7464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 75eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier /* Creates a buffer listener that waits on a new frame from the buffer 76eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier * queue. */ 77eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier void initialize(const Area& bufferArea, android_pixel_format_t format, 78eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier FenceCallback callback, void* callbackArgs) 7964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 8064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers sp<IGraphicBufferProducer> producer; 815d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers sp<IGraphicBufferConsumer> consumer; 825d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers BufferQueue::createBufferQueue(&producer, &consumer); 835d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers 845d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers consumer->setDefaultBufferSize(bufferArea.width, bufferArea.height); 855d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers consumer->setDefaultBufferFormat(format); 86f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz 87f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz mBufferItemConsumer = new BufferItemConsumer(consumer, 0); 88f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz 8964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mListener = new BufferListener(consumer, callback, callbackArgs); 90f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz mBufferItemConsumer->setFrameAvailableListener(mListener); 9164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 925d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mSurface = new Surface(producer, true); 935d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 945d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 955d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao /* Used by Egl manager. The surface is never displayed. */ 965d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers sp<Surface> getSurface() const 975d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers { 98d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return mSurface; 99d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 1005d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers 101d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmprivate: 102d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm sp<BufferItemConsumer> mBufferItemConsumer; 1035d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers sp<BufferListener> mListener; 104f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz /* Used by Egl manager. The surface is never displayed */ 10564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers sp<Surface> mSurface; 1065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao}; 107f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz 1085d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 1095d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers/* Used to generate valid fences. It is not possible to create a dummy sync 1105d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers * fence for testing. Egl can generate buffers along with a valid fence. 1115d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers * The buffer cannot be guaranteed to be the same format across all devices so 1125d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers * a CPU filled buffer is used instead. The Egl fence is used along with the 1135d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers * CPU filled buffer. */ 1144d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchiclass Hwc2TestEglManager { 1154d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchipublic: 1164d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi Hwc2TestEglManager() 1174d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi : mEglDisplay(EGL_NO_DISPLAY), 1184d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi mEglSurface(EGL_NO_SURFACE), 1194d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi mEglContext(EGL_NO_CONTEXT) { } 1204d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi 1214d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi ~Hwc2TestEglManager() 1225d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers { 123b2c7ead6bb5c98282cdfbc89db8984a004bea030Mathieu Chartier cleanup(); 124b2c7ead6bb5c98282cdfbc89db8984a004bea030Mathieu Chartier } 1255d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers 1265d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers int initialize(sp<Surface> surface) 1275d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers { 1285d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers mSurface = surface; 12964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 13064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 13164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (mEglDisplay == EGL_NO_DISPLAY) return false; 132fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogers 1335d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao EGLint major; 13464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGLint minor; 13564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!eglInitialize(mEglDisplay, &major, &minor)) { 13664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ALOGW("Could not initialize EGL"); 13764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return false; 13864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 13964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 140460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer /* We're going to use a 1x1 pbuffer surface later on 141460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer * The configuration distance doesn't really matter for what we're 14264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers * trying to do */ 14364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGLint configAttrs[] = { 144556d637764b71563030c479bc35364a75188d559Ian Rogers EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 145556d637764b71563030c479bc35364a75188d559Ian Rogers EGL_RED_SIZE, 8, 146556d637764b71563030c479bc35364a75188d559Ian Rogers EGL_GREEN_SIZE, 8, 147556d637764b71563030c479bc35364a75188d559Ian Rogers EGL_BLUE_SIZE, 8, 148556d637764b71563030c479bc35364a75188d559Ian Rogers EGL_ALPHA_SIZE, 0, 149556d637764b71563030c479bc35364a75188d559Ian Rogers EGL_DEPTH_SIZE, 24, 15064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGL_STENCIL_SIZE, 0, 151460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer EGL_NONE 152460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer }; 15364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 15464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGLConfig configs[1]; 15564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGLint configCnt; 15664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!eglChooseConfig(mEglDisplay, configAttrs, configs, 1, 15764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers &configCnt)) { 158460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer ALOGW("Could not select EGL configuration"); 159460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer eglReleaseThread(); 16064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers eglTerminate(mEglDisplay); 16164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return false; 16264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 16364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 16464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (configCnt <= 0) { 165460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer ALOGW("Could not find EGL configuration"); 166460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer eglReleaseThread(); 16764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers eglTerminate(mEglDisplay); 16864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return false; 16964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 1705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 17164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers /* These objects are initialized below but the default "null" values are 172460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer * used to cleanup properly at any point in the initialization sequence */ 173460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 17464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mEglContext = eglCreateContext(mEglDisplay, configs[0], EGL_NO_CONTEXT, 17564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers attrs); 17664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (mEglContext == EGL_NO_CONTEXT) { 1775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao ALOGW("Could not create EGL context"); 17864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers cleanup(); 179460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer return false; 180460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer } 18164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 18264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGLint surfaceAttrs[] = { EGL_NONE }; 18364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mEglSurface = eglCreateWindowSurface(mEglDisplay, configs[0], 1845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mSurface.get(), surfaceAttrs); 185556d637764b71563030c479bc35364a75188d559Ian Rogers if (mEglSurface == EGL_NO_SURFACE) { 186556d637764b71563030c479bc35364a75188d559Ian Rogers ALOGW("Could not create EGL surface"); 187556d637764b71563030c479bc35364a75188d559Ian Rogers cleanup(); 188556d637764b71563030c479bc35364a75188d559Ian Rogers return false; 189556d637764b71563030c479bc35364a75188d559Ian Rogers } 190556d637764b71563030c479bc35364a75188d559Ian Rogers 19164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 192460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer ALOGW("Could not change current EGL context"); 193460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer cleanup(); 19464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return false; 19564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 19664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 1975d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao return true; 19864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 199460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer 200460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer void makeCurrent() const 20164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 20264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); 20364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 2045d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 20564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers void present() const 2065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao { 20764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers eglSwapBuffers(mEglDisplay, mEglSurface); 208460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer } 209460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer 21064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogersprivate: 21164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers void cleanup() 21264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 2135d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao if (mEglDisplay == EGL_NO_DISPLAY) 21464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers return; 215460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer if (mEglSurface != EGL_NO_SURFACE) 216460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer eglDestroySurface(mEglDisplay, mEglSurface); 21764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (mEglContext != EGL_NO_CONTEXT) 21864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers eglDestroyContext(mEglDisplay, mEglContext); 21964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 22164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGL_NO_CONTEXT); 222460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer eglReleaseThread(); 223460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer eglTerminate(mEglDisplay); 22464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 22664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers sp<Surface> mSurface; 2275d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao EGLDisplay mEglDisplay; 22864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers EGLSurface mEglSurface; 2295d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao EGLContext mEglContext; 23064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers}; 23164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 23264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 233460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzerstatic const std::array<vec2, 4> triangles = {{ 234460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer { 1.0f, 1.0f }, 23564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { -1.0f, 1.0f }, 23664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 1.0f, -1.0f }, 23764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { -1.0f, -1.0f }, 2385d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao}}; 23964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2405d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Haoclass Hwc2TestFenceGenerator { 24164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogerspublic: 2425d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 24364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers Hwc2TestFenceGenerator() 244460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer { 245460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer mSurfaceManager.initialize({1, 1}, HAL_PIXEL_FORMAT_RGBA_8888, 24664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers setFence, this); 24764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 24864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!mEglManager.initialize(mSurfaceManager.getSurface())) 2495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao return; 25064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mEglManager.makeCurrent(); 25264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 253460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer glClearColor(0.0, 0.0, 0.0, 1.0); 254460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer glEnableVertexAttribArray(0); 25564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 25664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 25764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ~Hwc2TestFenceGenerator() 2585d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao { 25964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (mFence >= 0) 2605d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao close(mFence); 26164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mFence = -1; 2625d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 26364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mEglManager.makeCurrent(); 26464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 26564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 26664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers /* It is not possible to simply generate a fence. The easiest way is to 26764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers * generate a buffer using egl and use the associated fence. The buffer 26864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers * cannot be guaranteed to be a certain format across all devices using this 269460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer * method. Instead the buffer is generated using the CPU */ 270460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer int32_t get() 27164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 27264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (mFence >= 0) { 273556d637764b71563030c479bc35364a75188d559Ian Rogers return dup(mFence); 274556d637764b71563030c479bc35364a75188d559Ian Rogers } 275556d637764b71563030c479bc35364a75188d559Ian Rogers 276556d637764b71563030c479bc35364a75188d559Ian Rogers std::unique_lock<std::mutex> lock(mMutex); 277556d637764b71563030c479bc35364a75188d559Ian Rogers 278556d637764b71563030c479bc35364a75188d559Ian Rogers /* If the pending is still set to false and times out, we cannot recover. 2793dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao * Set an error and return */ 280460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer while (mPending != false) { 281460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer if (mCv.wait_for(lock, std::chrono::seconds(2)) == std::cv_status::timeout) 2823dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao return -ETIME; 2833dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } 2843dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao 2853dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao /* Generate a fence. The fence will be returned through the setFence 28664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers * callback */ 287460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer mEglManager.makeCurrent(); 288460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer 28964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, triangles.data()); 29064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers glClear(GL_COLOR_BUFFER_BIT); 29164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2925d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mEglManager.present(); 293556d637764b71563030c479bc35364a75188d559Ian Rogers 294556d637764b71563030c479bc35364a75188d559Ian Rogers /* Wait for the setFence callback */ 295556d637764b71563030c479bc35364a75188d559Ian Rogers while (mPending != true) { 296556d637764b71563030c479bc35364a75188d559Ian Rogers if (mCv.wait_for(lock, std::chrono::seconds(2)) == std::cv_status::timeout) 297556d637764b71563030c479bc35364a75188d559Ian Rogers return -ETIME; 298556d637764b71563030c479bc35364a75188d559Ian Rogers } 29964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 30064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mPending = false; 301460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer 302460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer return dup(mFence); 30364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 30464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 30564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers /* Callback that sets the fence */ 3065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao void set(int32_t fence) 30764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers { 30864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mFence = fence; 30964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mPending = true; 31064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 31164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mCv.notify_all(); 31264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 31364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 3148ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzprivate: 315b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers 316b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers Hwc2TestSurfaceManager mSurfaceManager; 3178ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz Hwc2TestEglManager mEglManager; 318277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe 3196a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers std::mutex mMutex; 3206a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers std::condition_variable mCv; 3216a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers 322fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers int32_t mFence = -1; 323fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz bool mPending = false; 324b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers}; 325fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz 326fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz 327fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertzstatic void setFence(int32_t fence, void* fenceGenerator) 328fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz{ 3296a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers static_cast<Hwc2TestFenceGenerator*>(fenceGenerator)->set(fence); 330fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz} 3312c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers 332fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz 333fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz/* Sets the pixel of a buffer given the location, format, stride and color. 334fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz * Currently only supports RGBA_8888 */ 335fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertzstatic void setColor(int32_t x, int32_t y, 336fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz android_pixel_format_t format, uint32_t stride, uint8_t* img, uint8_t r, 337fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz uint8_t g, uint8_t b, uint8_t a) 338fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz{ 339fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz switch (format) { 340fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz case HAL_PIXEL_FORMAT_RGBA_8888: 341fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz img[(y * stride + x) * 4 + 0] = r; 342fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz img[(y * stride + x) * 4 + 1] = g; 343fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz img[(y * stride + x) * 4 + 2] = b; 344fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz img[(y * stride + x) * 4 + 3] = a; 345fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz break; 346fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz default: 347fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz break; 348fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz } 349fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz} 350fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz 3512fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan RogersHwc2TestBuffer::Hwc2TestBuffer() 352233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz : mFenceGenerator(new Hwc2TestFenceGenerator()) { } 353233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 354233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien HertzHwc2TestBuffer::~Hwc2TestBuffer() = default; 355233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 356233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz/* When the buffer changes sizes, save the new size and invalidate the current 357233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz * buffer */ 358848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogersvoid Hwc2TestBuffer::updateBufferArea(const Area& bufferArea) 359848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers{ 360848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers if (mBufferArea.width == bufferArea.width 361848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers && mBufferArea.height == bufferArea.height) 3624e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz return; 3638ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 364d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mBufferArea.width = bufferArea.width; 3658ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz mBufferArea.height = bufferArea.height; 366233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 3678ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz mValidBuffer = false; 368d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 369d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 370d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz/* Returns a valid buffer handle and fence. The handle is filled using the CPU 371d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * to ensure the correct format across all devices. The fence is created using 372d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * egl. */ 3738ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzint Hwc2TestBuffer::get(buffer_handle_t* outHandle, int32_t* outFence) 3748ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz{ 375d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (mBufferArea.width == -1 || mBufferArea.height == -1) 376d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return -EINVAL; 377d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 378d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz /* If the current buffer is valid, the previous buffer can be reused. 379d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * Otherwise, create new buffer */ 3808ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (!mValidBuffer) { 381233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz int ret = generateBuffer(); 382233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz if (ret) 3838ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz return ret; 384d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 385d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 386d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz *outFence = mFenceGenerator->get(); 387d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz *outHandle = mHandle; 388d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3898ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz mValidBuffer = true; 3908ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 391d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return 0; 392d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 393d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 394d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz/* CPU fills a buffer to guarantee the correct buffer format across all 395d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * devices */ 3968ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzint Hwc2TestBuffer::generateBuffer() 397233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz{ 398233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz int ret; 399233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 400ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom /* Create new graphic buffer with correct dimensions */ 4016474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao mGraphicBuffer = mGraphicBufferAlloc.createGraphicBuffer( 40264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers mBufferArea.width, mBufferArea.height, mFormat, 403535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER, 404535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray "hwc2_test_buffer", &ret); 405d752132c73072084a3def9257cca4fcee76047b6jeffhao if (ret) 406d752132c73072084a3def9257cca4fcee76047b6jeffhao return ret; 407d752132c73072084a3def9257cca4fcee76047b6jeffhao 408d752132c73072084a3def9257cca4fcee76047b6jeffhao /* Locks the buffer for writing */ 409e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier uint8_t* img; 410bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier mGraphicBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 4112fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4122fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint32_t stride = mGraphicBuffer->getStride(); 4132fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers /* Iterate from the top row of the buffer to the bottom row */ 4152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers for (int32_t y = 0; y < mBufferArea.height; y++) { 4160a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao 417e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier /* Will be used as R, G and B values for pixel colors */ 41856adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz uint8_t max = 255; 4190a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao uint8_t min = 0; 4202fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers /* Divide the rows into 3 sections. The first section will contain 422bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier * the lighest colors. The last section will contain the darkest 4232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * colors. */ 4242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (y < mBufferArea.height * 1.0 / 3.0) { 4252fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers min = 255 / 2; 4262fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else if (y >= mBufferArea.height * 2.0 / 3.0) { 4272fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers max = 255 / 2; 4282fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4292fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4306613519990bdb5616f2858c146f162ef760f03d2Jeff Hao /* Divide the columns into 3 sections. The first section is red, 4316613519990bdb5616f2858c146f162ef760f03d2Jeff Hao * the second is green and the third is blue */ 4326613519990bdb5616f2858c146f162ef760f03d2Jeff Hao int32_t x = 0; 433e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier for (; x < mBufferArea.width / 3; x++) { 4342fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers setColor(x, y, mFormat, stride, img, max, min, min, 255); 4352fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4362fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 437ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa for (; x < mBufferArea.width * 2 / 3; x++) { 4382fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers setColor(x, y, mFormat, stride, img, min, max, min, 255); 4392fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 440bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 441bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier for (; x < mBufferArea.width; x++) { 4425d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao setColor(x, y, mFormat, stride, img, min, min, max, 255); 443bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 4445d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 4452fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 446ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers /* Unlock the buffer for reading */ 447ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa mGraphicBuffer->unlock(); 4482fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4492fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers mHandle = mGraphicBuffer->handle; 4505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 4515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao return 0; 4525d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao} 4532fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4545d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 4552fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan RogersHwc2TestClientTargetBuffer::Hwc2TestClientTargetBuffer() 4565d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao : mFenceGenerator(new Hwc2TestFenceGenerator()) { } 4572fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4585d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoHwc2TestClientTargetBuffer::~Hwc2TestClientTargetBuffer() { } 4592fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4602fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers/* Generates a client target buffer using the layers assigned for client 4612fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * composition. Takes into account the individual layer properties such as 46292246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier * transform, blend mode, source crop, etc. */ 46392246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartierint Hwc2TestClientTargetBuffer::get(buffer_handle_t* outHandle, 4646c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers int32_t* outFence, const Area& bufferArea, 46592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier const Hwc2TestLayers* testLayers, 466eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier const std::set<hwc2_layer_t>* clientLayers, 467eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier const std::set<hwc2_layer_t>* clearLayers) 4687b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers{ 46992246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier int err; 47092246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier 47192246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier /* Create new graphic buffer with updated size */ 47292246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier mGraphicBuffer = mGraphicBufferAlloc.createGraphicBuffer(bufferArea.width, 47392246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier bufferArea.height, mFormat, 47464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER, 475bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier "hwc2_test_buffer", &err); 476bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier if (err) 4776613519990bdb5616f2858c146f162ef760f03d2Jeff Hao return err; 4786474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao 4796474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao uint8_t* img; 4802fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers mGraphicBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 4812fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 48264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers uint32_t stride = mGraphicBuffer->getStride(); 48364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 48492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier float bWDiv3 = bufferArea.width / 3; 48592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier float bW2Div3 = bufferArea.width * 2 / 3; 48692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier float bHDiv3 = bufferArea.height / 3; 48764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers float bH2Div3 = bufferArea.height * 2 / 3; 4886474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao 4892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers /* Cycle through every pixel in the buffer and determine what color it 4906474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * should be. */ 4912fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers for (int32_t y = 0; y < bufferArea.height; y++) { 4922fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers for (int32_t x = 0; x < bufferArea.width; x++) { 4932fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 4942fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint8_t r = 0, g = 0, b = 0; 4952fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers float a = 0.0f; 49662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 49711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao /* Cycle through each client layer from back to front and 49811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao * update the pixel color. */ 49962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers for (auto layer = clientLayers->rbegin(); 50011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao layer != clientLayers->rend(); ++layer) { 50162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 502bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const hwc_rect_t df = testLayers->getDisplayFrame(*layer); 503bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 504bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier float dfL = df.left; 50511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao float dfT = df.top; 50611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao float dfR = df.right; 50711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao float dfB = df.bottom; 50811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 50911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao /* If the pixel location falls outside of the layer display 51011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao * frame, skip the layer. */ 51111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao if (x < dfL || x >= dfR || y < dfT || y >= dfB) 51211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao continue; 5136f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers 5146f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers /* If the device has requested the layer be clear, clear 5156f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers * the pixel and continue. */ 516f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers if (clearLayers->count(*layer) != 0) { 517535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray r = 0; 518535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray g = 0; 519f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers b = 0; 520f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers a = 0.0f; 521f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers continue; 522f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 5236f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers 5247db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers float planeAlpha = testLayers->getPlaneAlpha(*layer); 5257db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 5266f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers /* If the layer is a solid color, fill the color and 527848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers * continue. */ 528848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers if (testLayers->getComposition(*layer) 529535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray == HWC2_COMPOSITION_SOLID_COLOR) { 530535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray const auto color = testLayers->getColor(*layer); 531167436311a08a65dea28dda079a137893821c9c7Jeff Hao r = color.r; 5326951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao g = color.g; 533167436311a08a65dea28dda079a137893821c9c7Jeff Hao b = color.b; 534167436311a08a65dea28dda079a137893821c9c7Jeff Hao a = color.a * planeAlpha; 535e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier continue; 5366f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers } 537c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz 5386f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers float xPos = x; 5396f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers float yPos = y; 5406c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers 5410cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier hwc_transform_t transform = testLayers->getTransform(*layer); 5420cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier 5430cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier float dfW = dfR - dfL; 5447b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers float dfH = dfB - dfT; 5450cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier 546e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier /* If a layer has a transform, find which location on the 547c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz * layer will end up in the current pixel location. We 548c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz * can calculate the color of the current pixel using that 5490cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier * location. */ 550167436311a08a65dea28dda079a137893821c9c7Jeff Hao if (transform > 0) { 551167436311a08a65dea28dda079a137893821c9c7Jeff Hao /* Change origin to be the center of the layer. */ 552167436311a08a65dea28dda079a137893821c9c7Jeff Hao xPos = xPos - dfL - dfW / 2.0; 5536f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers yPos = yPos - dfT - dfH / 2.0; 5546f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers 555167436311a08a65dea28dda079a137893821c9c7Jeff Hao /* Flip Horizontal by reflecting across the y axis. */ 556167436311a08a65dea28dda079a137893821c9c7Jeff Hao if (transform & HWC_TRANSFORM_FLIP_H) 557167436311a08a65dea28dda079a137893821c9c7Jeff Hao xPos = -xPos; 558167436311a08a65dea28dda079a137893821c9c7Jeff Hao 5596f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers /* Flip vertical by reflecting across the x axis. */ 5606f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers if (transform & HWC_TRANSFORM_FLIP_V) 5616f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers yPos = -yPos; 562167436311a08a65dea28dda079a137893821c9c7Jeff Hao 563167436311a08a65dea28dda079a137893821c9c7Jeff Hao /* Rotate 90 by using a basic linear algebra rotation 564167436311a08a65dea28dda079a137893821c9c7Jeff Hao * and scaling the result so the display frame remains 565167436311a08a65dea28dda079a137893821c9c7Jeff Hao * the same. For example, a buffer of size 100x50 should 566167436311a08a65dea28dda079a137893821c9c7Jeff Hao * rotate 90 degress but remain the same dimension 5672fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * (100x50) at the end of the transformation. */ 5682fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (transform & HWC_TRANSFORM_ROT_90) { 569 float tmp = xPos; 570 xPos = -yPos * dfW / dfH; 571 yPos = tmp * dfH / dfW; 572 } 573 574 /* Change origin back to the top left corner of the 575 * layer. */ 576 xPos = xPos + dfL + dfW / 2.0; 577 yPos = yPos + dfT + dfH / 2.0; 578 } 579 580 hwc_frect_t sc = testLayers->getSourceCrop(*layer); 581 float scL = sc.left, scT = sc.top; 582 583 float dfWDivScW = dfW / (sc.right - scL); 584 float dfHDivScH = dfH / (sc.bottom - scT); 585 586 float max = 255, min = 0; 587 588 /* Choose the pixel color. Similar to generateBuffer, 589 * each layer will be divided into 3x3 colors. Because 590 * both the source crop and display frame must be taken into 591 * account, the formulas are more complicated. 592 * 593 * If the source crop and display frame were not taken into 594 * account, we would simply divide the buffer into three 595 * sections by height. Each section would get one color. 596 * For example the formula for the first section would be: 597 * 598 * if (yPos < bufferArea.height / 3) 599 * //Select first section color 600 * 601 * However the pixel color is chosen based on the source 602 * crop and displayed based on the display frame. 603 * 604 * If the display frame top was 0 and the source crop height 605 * and display frame height were the same. The only factor 606 * would be the source crop top. To calculate the new 607 * section boundary, the section boundary would be moved up 608 * by the height of the source crop top. The formula would 609 * be: 610 * if (yPos < (bufferArea.height / 3 - sourceCrop.top) 611 * //Select first section color 612 * 613 * If the display frame top could also vary but source crop 614 * and display frame heights were the same, the formula 615 * would be: 616 * if (yPos < (bufferArea.height / 3 - sourceCrop.top 617 * + displayFrameTop) 618 * //Select first section color 619 * 620 * If the heights were not the same, the conversion between 621 * the source crop and display frame dimensions must be 622 * taken into account. The formula would be: 623 * if (yPos < ((bufferArea.height / 3) - sourceCrop.top) 624 * * displayFrameHeight / sourceCropHeight 625 * + displayFrameTop) 626 * //Select first section color 627 */ 628 if (yPos < ((bHDiv3) - scT) * dfHDivScH + dfT) { 629 min = 255 / 2; 630 } else if (yPos >= ((bH2Div3) - scT) * dfHDivScH + dfT) { 631 max = 255 / 2; 632 } 633 634 uint8_t rCur = min, gCur = min, bCur = min; 635 float aCur = 1.0f; 636 637 /* This further divides the color sections from 3 to 3x3. 638 * The math behind it follows the same logic as the previous 639 * comment */ 640 if (xPos < ((bWDiv3) - scL) * (dfWDivScW) + dfL) { 641 rCur = max; 642 } else if (xPos < ((bW2Div3) - scL) * (dfWDivScW) + dfL) { 643 gCur = max; 644 } else { 645 bCur = max; 646 } 647 648 649 /* Blend the pixel color with the previous layers' pixel 650 * colors using the plane alpha and blend mode. The final 651 * pixel color is chosen using the plane alpha and blend 652 * mode formulas found in hwcomposer2.h */ 653 hwc2_blend_mode_t blendMode = testLayers->getBlendMode(*layer); 654 655 if (blendMode == HWC2_BLEND_MODE_PREMULTIPLIED) { 656 rCur *= planeAlpha; 657 gCur *= planeAlpha; 658 bCur *= planeAlpha; 659 } 660 661 aCur *= planeAlpha; 662 663 if (blendMode == HWC2_BLEND_MODE_PREMULTIPLIED) { 664 r = rCur + r * (1.0 - aCur); 665 g = gCur + g * (1.0 - aCur); 666 b = bCur + b * (1.0 - aCur); 667 a = aCur + a * (1.0 - aCur); 668 } else if (blendMode == HWC2_BLEND_MODE_COVERAGE) { 669 r = rCur * aCur + r * (1.0 - aCur); 670 g = gCur * aCur + g * (1.0 - aCur); 671 b = bCur * aCur + b * (1.0 - aCur); 672 a = aCur * aCur + a * (1.0 - aCur); 673 } else { 674 r = rCur; 675 g = gCur; 676 b = bCur; 677 a = aCur; 678 } 679 } 680 681 /* Set the pixel color */ 682 setColor(x, y, mFormat, stride, img, r, g, b, a * 255); 683 } 684 } 685 686 mGraphicBuffer->unlock(); 687 688 *outFence = mFenceGenerator->get(); 689 *outHandle = mGraphicBuffer->handle; 690 691 return 0; 692} 693