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
hasEglPixelFormatFloat()33 bool 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
46 namespace android {
47
48 #define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE)
49
50 // retrieve wide-color setting from configstore
51 using namespace android::hardware::configstore;
52 using namespace android::hardware::configstore::V1_0;
53
54 static bool hasWideColorDisplay =
55 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
56
57 class EGLTest : public ::testing::Test {
58 protected:
59 EGLDisplay mEglDisplay;
60
61 protected:
EGLTest()62 EGLTest() :
63 mEglDisplay(EGL_NO_DISPLAY) {
64 }
65
SetUp()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
TearDown()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
TEST_F(EGLTest,DISABLED_EGLConfigEightBitFirst)86 TEST_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
TEST_F(EGLTest,EGLTerminateSucceedsWithRemainingObjects)119 TEST_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
TEST_F(EGLTest,EGLConfigRGBA8888First)156 TEST_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
TEST_F(EGLTest,EGLConfigFP16)197 TEST_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