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/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> 20 21#include <configstore/Utils.h> 22#include <utils/String8.h> 23 24#include <EGL/egl.h> 25#include <gui/Surface.h> 26#include <gui/IConsumerListener.h> 27#include <gui/IProducerListener.h> 28#include <gui/IGraphicBufferConsumer.h> 29#include <gui/BufferQueue.h> 30 31#define PIXEL_FORMAT_FLOAT "EGL_EXT_pixel_format_float" 32 33bool hasEglPixelFormatFloat() { 34 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 35 const char* exts = eglQueryString(dpy, EGL_EXTENSIONS); 36 size_t cropExtLen = strlen(PIXEL_FORMAT_FLOAT); 37 size_t extsLen = strlen(exts); 38 bool equal = !strcmp(PIXEL_FORMAT_FLOAT, exts); 39 bool atStart = !strncmp(PIXEL_FORMAT_FLOAT " ", exts, cropExtLen + 1); 40 bool atEnd = (cropExtLen + 1) < extsLen && 41 !strcmp(" " PIXEL_FORMAT_FLOAT, exts + extsLen - (cropExtLen + 1)); 42 bool inMiddle = strstr(exts, " " PIXEL_FORMAT_FLOAT " "); 43 return equal || atStart || atEnd || inMiddle; 44} 45 46namespace android { 47 48#define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE) 49 50// retrieve wide-color setting from configstore 51using namespace android::hardware::configstore; 52using namespace android::hardware::configstore::V1_0; 53 54static bool hasWideColorDisplay = 55 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false); 56 57class EGLTest : public ::testing::Test { 58protected: 59 EGLDisplay mEglDisplay; 60 61protected: 62 EGLTest() : 63 mEglDisplay(EGL_NO_DISPLAY) { 64 } 65 66 virtual void SetUp() { 67 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 68 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); 69 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 70 71 EGLint majorVersion; 72 EGLint minorVersion; 73 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); 74 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 75 RecordProperty("EglVersionMajor", majorVersion); 76 RecordProperty("EglVersionMajor", minorVersion); 77 } 78 79 virtual void TearDown() { 80 EGLBoolean success = eglTerminate(mEglDisplay); 81 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 82 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 83 } 84}; 85 86TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) { 87 88 EGLint numConfigs; 89 EGLConfig config; 90 EGLBoolean success; 91 EGLint attrs[] = { 92 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 93 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 94 EGL_NONE 95 }; 96 97 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); 98 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 99 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 100 ASSERT_GE(numConfigs, 1); 101 102 EGLint components[3]; 103 104 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); 105 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 106 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 107 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); 108 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 109 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 110 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); 111 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 112 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 113 114 EXPECT_GE(components[0], 8); 115 EXPECT_GE(components[1], 8); 116 EXPECT_GE(components[2], 8); 117} 118 119TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { 120 EGLint numConfigs; 121 EGLConfig config; 122 EGLint attrs[] = { 123 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 124 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 125 EGL_RED_SIZE, 8, 126 EGL_GREEN_SIZE, 8, 127 EGL_BLUE_SIZE, 8, 128 EGL_ALPHA_SIZE, 8, 129 EGL_NONE 130 }; 131 EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs)); 132 133 struct DummyConsumer : public BnConsumerListener { 134 void onFrameAvailable(const BufferItem& /* item */) override {} 135 void onBuffersReleased() override {} 136 void onSidebandStreamChanged() override {} 137 }; 138 139 // Create a EGLSurface 140 sp<IGraphicBufferProducer> producer; 141 sp<IGraphicBufferConsumer> consumer; 142 BufferQueue::createBufferQueue(&producer, &consumer); 143 consumer->consumerConnect(new DummyConsumer, false); 144 sp<Surface> mSTC = new Surface(producer); 145 sp<ANativeWindow> mANW = mSTC; 146 147 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, 148 mANW.get(), NULL); 149 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 150 ASSERT_NE(EGL_NO_SURFACE, eglSurface) ; 151 152 // do not destroy eglSurface 153 // eglTerminate is called in the tear down and should destroy it for us 154} 155 156TEST_F(EGLTest, EGLConfigRGBA8888First) { 157 158 EGLint numConfigs; 159 EGLConfig config; 160 EGLBoolean success; 161 EGLint attrs[] = { 162 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 163 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 164 EGL_RED_SIZE, 8, 165 EGL_GREEN_SIZE, 8, 166 EGL_BLUE_SIZE, 8, 167 EGL_ALPHA_SIZE, 8, 168 EGL_NONE 169 }; 170 171 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); 172 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 173 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 174 ASSERT_GE(numConfigs, 1); 175 176 EGLint components[4]; 177 178 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); 179 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 180 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 181 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); 182 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 183 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 184 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); 185 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 186 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 187 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]); 188 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 189 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 190 191 EXPECT_GE(components[0], 8); 192 EXPECT_GE(components[1], 8); 193 EXPECT_GE(components[2], 8); 194 EXPECT_GE(components[3], 8); 195} 196 197TEST_F(EGLTest, EGLConfigFP16) { 198 EGLint numConfigs; 199 EGLConfig config; 200 EGLBoolean success; 201 202 if (!hasWideColorDisplay) { 203 // skip this test if device does not have wide-color display 204 return; 205 } 206 207 ASSERT_TRUE(hasEglPixelFormatFloat()); 208 209 EGLint attrs[] = {EGL_SURFACE_TYPE, 210 EGL_WINDOW_BIT, 211 EGL_RENDERABLE_TYPE, 212 EGL_OPENGL_ES2_BIT, 213 EGL_RED_SIZE, 214 16, 215 EGL_GREEN_SIZE, 216 16, 217 EGL_BLUE_SIZE, 218 16, 219 EGL_ALPHA_SIZE, 220 16, 221 EGL_COLOR_COMPONENT_TYPE_EXT, 222 EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, 223 EGL_NONE}; 224 success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); 225 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 226 ASSERT_EQ(1, numConfigs); 227 228 EGLint components[4]; 229 230 success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); 231 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 232 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 233 success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); 234 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 235 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 236 success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); 237 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 238 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 239 success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]); 240 ASSERT_EQ(EGL_UNSIGNED_TRUE, success); 241 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 242 243 EXPECT_GE(components[0], 16); 244 EXPECT_GE(components[1], 16); 245 EXPECT_GE(components[2], 16); 246 EXPECT_GE(components[3], 16); 247 248 struct DummyConsumer : public BnConsumerListener { 249 void onFrameAvailable(const BufferItem& /* item */) override {} 250 void onBuffersReleased() override {} 251 void onSidebandStreamChanged() override {} 252 }; 253 254 // Create a EGLSurface 255 sp<IGraphicBufferProducer> producer; 256 sp<IGraphicBufferConsumer> consumer; 257 BufferQueue::createBufferQueue(&producer, &consumer); 258 consumer->consumerConnect(new DummyConsumer, false); 259 sp<Surface> mSTC = new Surface(producer); 260 sp<ANativeWindow> mANW = mSTC; 261 262 EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL); 263 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 264 ASSERT_NE(EGL_NO_SURFACE, eglSurface); 265 266 EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface)); 267} 268} 269