EGL_test.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  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. #include <gtest/gtest.h>
  17. #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
  18. #include <configstore/Utils.h>
  19. #include <utils/String8.h>
  20. #include <EGL/egl.h>
  21. #include <gui/Surface.h>
  22. #include <gui/IConsumerListener.h>
  23. #include <gui/IProducerListener.h>
  24. #include <gui/IGraphicBufferConsumer.h>
  25. #include <gui/BufferQueue.h>
  26. bool hasEglExtension(EGLDisplay dpy, const char* extensionName) {
  27. const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
  28. size_t cropExtLen = strlen(extensionName);
  29. size_t extsLen = strlen(exts);
  30. bool equal = !strcmp(extensionName, exts);
  31. android::String8 extString(extensionName);
  32. android::String8 space(" ");
  33. bool atStart = !strncmp(extString + space, exts, cropExtLen + 1);
  34. bool atEnd = (cropExtLen + 1) < extsLen &&
  35. !strcmp(space + extString, exts + extsLen - (cropExtLen + 1));
  36. bool inMiddle = strstr(exts, space + extString + space);
  37. return equal || atStart || atEnd || inMiddle;
  38. }
  39. namespace android {
  40. #define EGL_UNSIGNED_TRUE static_cast<EGLBoolean>(EGL_TRUE)
  41. // retrieve wide-color setting from configstore
  42. using namespace android::hardware::configstore;
  43. using namespace android::hardware::configstore::V1_0;
  44. #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
  45. static bool hasWideColorDisplay =
  46. getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
  47. static bool hasHdrDisplay =
  48. getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
  49. class EGLTest : public ::testing::Test {
  50. public:
  51. void get8BitConfig(EGLConfig& config);
  52. void setSurfaceSmpteMetadata(EGLSurface surface);
  53. void checkSurfaceSmpteMetadata(EGLSurface eglSurface);
  54. protected:
  55. EGLDisplay mEglDisplay;
  56. protected:
  57. EGLTest() :
  58. mEglDisplay(EGL_NO_DISPLAY) {
  59. }
  60. virtual void SetUp() {
  61. mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  62. ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
  63. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  64. EGLint majorVersion;
  65. EGLint minorVersion;
  66. EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
  67. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  68. RecordProperty("EglVersionMajor", majorVersion);
  69. RecordProperty("EglVersionMajor", minorVersion);
  70. }
  71. virtual void TearDown() {
  72. EGLBoolean success = eglTerminate(mEglDisplay);
  73. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  74. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  75. }
  76. };
  77. TEST_F(EGLTest, DISABLED_EGLConfigEightBitFirst) {
  78. EGLint numConfigs;
  79. EGLConfig config;
  80. EGLBoolean success;
  81. EGLint attrs[] = {
  82. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  83. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  84. EGL_NONE
  85. };
  86. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  87. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  88. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  89. ASSERT_GE(numConfigs, 1);
  90. EGLint components[3];
  91. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  92. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  93. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  94. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  95. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  96. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  97. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  98. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  99. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  100. EXPECT_GE(components[0], 8);
  101. EXPECT_GE(components[1], 8);
  102. EXPECT_GE(components[2], 8);
  103. }
  104. TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) {
  105. EGLint numConfigs;
  106. EGLConfig config;
  107. EGLint attrs[] = {
  108. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  109. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  110. EGL_RED_SIZE, 8,
  111. EGL_GREEN_SIZE, 8,
  112. EGL_BLUE_SIZE, 8,
  113. EGL_ALPHA_SIZE, 8,
  114. EGL_NONE
  115. };
  116. EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
  117. struct DummyConsumer : public BnConsumerListener {
  118. void onFrameAvailable(const BufferItem& /* item */) override {}
  119. void onBuffersReleased() override {}
  120. void onSidebandStreamChanged() override {}
  121. };
  122. // Create a EGLSurface
  123. sp<IGraphicBufferProducer> producer;
  124. sp<IGraphicBufferConsumer> consumer;
  125. BufferQueue::createBufferQueue(&producer, &consumer);
  126. consumer->consumerConnect(new DummyConsumer, false);
  127. sp<Surface> mSTC = new Surface(producer);
  128. sp<ANativeWindow> mANW = mSTC;
  129. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config,
  130. mANW.get(), NULL);
  131. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  132. ASSERT_NE(EGL_NO_SURFACE, eglSurface) ;
  133. // do not destroy eglSurface
  134. // eglTerminate is called in the tear down and should destroy it for us
  135. }
  136. TEST_F(EGLTest, EGLConfigRGBA8888First) {
  137. EGLint numConfigs;
  138. EGLConfig config;
  139. EGLBoolean success;
  140. EGLint attrs[] = {
  141. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  142. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  143. EGL_RED_SIZE, 8,
  144. EGL_GREEN_SIZE, 8,
  145. EGL_BLUE_SIZE, 8,
  146. EGL_ALPHA_SIZE, 8,
  147. EGL_NONE
  148. };
  149. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  150. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  151. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  152. ASSERT_GE(numConfigs, 1);
  153. EGLint components[4];
  154. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  155. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  156. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  157. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  158. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  159. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  160. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  161. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  162. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  163. success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
  164. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  165. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  166. EXPECT_GE(components[0], 8);
  167. EXPECT_GE(components[1], 8);
  168. EXPECT_GE(components[2], 8);
  169. EXPECT_GE(components[3], 8);
  170. }
  171. TEST_F(EGLTest, EGLDisplayP3) {
  172. EGLint numConfigs;
  173. EGLConfig config;
  174. EGLBoolean success;
  175. if (!hasWideColorDisplay) {
  176. // skip this test if device does not have wide-color display
  177. std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
  178. return;
  179. }
  180. // Test that display-p3 extensions exist
  181. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
  182. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
  183. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
  184. // Use 8-bit to keep forcus on Display-P3 aspect
  185. EGLint attrs[] = {
  186. // clang-format off
  187. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  188. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  189. EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
  190. EGL_RED_SIZE, 8,
  191. EGL_GREEN_SIZE, 8,
  192. EGL_BLUE_SIZE, 8,
  193. EGL_ALPHA_SIZE, 8,
  194. EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
  195. EGL_NONE, EGL_NONE
  196. // clang-format on
  197. };
  198. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  199. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  200. ASSERT_EQ(1, numConfigs);
  201. EGLint components[4];
  202. EGLint value;
  203. eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
  204. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  205. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  206. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  207. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  208. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  209. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  210. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  211. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  212. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  213. success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
  214. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  215. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  216. EXPECT_EQ(components[0], 8);
  217. EXPECT_EQ(components[1], 8);
  218. EXPECT_EQ(components[2], 8);
  219. EXPECT_EQ(components[3], 8);
  220. struct DummyConsumer : public BnConsumerListener {
  221. void onFrameAvailable(const BufferItem& /* item */) override {}
  222. void onBuffersReleased() override {}
  223. void onSidebandStreamChanged() override {}
  224. };
  225. // Create a EGLSurface
  226. sp<IGraphicBufferProducer> producer;
  227. sp<IGraphicBufferConsumer> consumer;
  228. BufferQueue::createBufferQueue(&producer, &consumer);
  229. consumer->consumerConnect(new DummyConsumer, false);
  230. sp<Surface> mSTC = new Surface(producer);
  231. sp<ANativeWindow> mANW = mSTC;
  232. EGLint winAttrs[] = {
  233. // clang-format off
  234. EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
  235. EGL_NONE, EGL_NONE
  236. // clang-format on
  237. };
  238. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  239. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  240. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  241. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
  242. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  243. ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
  244. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  245. }
  246. TEST_F(EGLTest, EGLDisplayP3Passthrough) {
  247. EGLConfig config;
  248. EGLBoolean success;
  249. if (!hasWideColorDisplay) {
  250. // skip this test if device does not have wide-color display
  251. std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
  252. return;
  253. }
  254. // Test that display-p3 extensions exist
  255. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
  256. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
  257. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
  258. get8BitConfig(config);
  259. struct DummyConsumer : public BnConsumerListener {
  260. void onFrameAvailable(const BufferItem& /* item */) override {}
  261. void onBuffersReleased() override {}
  262. void onSidebandStreamChanged() override {}
  263. };
  264. // Create a EGLSurface
  265. sp<IGraphicBufferProducer> producer;
  266. sp<IGraphicBufferConsumer> consumer;
  267. BufferQueue::createBufferQueue(&producer, &consumer);
  268. consumer->consumerConnect(new DummyConsumer, false);
  269. sp<Surface> mSTC = new Surface(producer);
  270. sp<ANativeWindow> mANW = mSTC;
  271. EGLint winAttrs[] = {
  272. // clang-format off
  273. EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
  274. EGL_NONE, EGL_NONE
  275. // clang-format on
  276. };
  277. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  278. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  279. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  280. android_dataspace dataspace =
  281. static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
  282. ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
  283. EGLint value;
  284. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
  285. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  286. ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT, value);
  287. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  288. }
  289. TEST_F(EGLTest, EGLDisplayP31010102) {
  290. EGLint numConfigs;
  291. EGLConfig config;
  292. EGLBoolean success;
  293. if (!hasWideColorDisplay) {
  294. // skip this test if device does not have wide-color display
  295. std::cerr << "[ ] Device does not support wide-color, test skipped" << std::endl;
  296. return;
  297. }
  298. // Test that display-p3 extensions exist
  299. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3"));
  300. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"));
  301. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_display_p3_passthrough"));
  302. // Use 8-bit to keep forcus on Display-P3 aspect
  303. EGLint attrs[] = {
  304. // clang-format off
  305. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  306. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  307. EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
  308. EGL_RED_SIZE, 10,
  309. EGL_GREEN_SIZE, 10,
  310. EGL_BLUE_SIZE, 10,
  311. EGL_ALPHA_SIZE, 2,
  312. EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
  313. EGL_NONE, EGL_NONE
  314. // clang-format on
  315. };
  316. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  317. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  318. ASSERT_EQ(1, numConfigs);
  319. EGLint components[4];
  320. EGLint value;
  321. eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
  322. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  323. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  324. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  325. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  326. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  327. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  328. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  329. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  330. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  331. success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
  332. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  333. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  334. EXPECT_EQ(components[0], 10);
  335. EXPECT_EQ(components[1], 10);
  336. EXPECT_EQ(components[2], 10);
  337. EXPECT_EQ(components[3], 2);
  338. struct DummyConsumer : public BnConsumerListener {
  339. void onFrameAvailable(const BufferItem& /* item */) override {}
  340. void onBuffersReleased() override {}
  341. void onSidebandStreamChanged() override {}
  342. };
  343. // Create a EGLSurface
  344. sp<IGraphicBufferProducer> producer;
  345. sp<IGraphicBufferConsumer> consumer;
  346. BufferQueue::createBufferQueue(&producer, &consumer);
  347. consumer->consumerConnect(new DummyConsumer, false);
  348. sp<Surface> mSTC = new Surface(producer);
  349. sp<ANativeWindow> mANW = mSTC;
  350. EGLint winAttrs[] = {
  351. // clang-format off
  352. EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
  353. EGL_NONE, EGL_NONE
  354. // clang-format on
  355. };
  356. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  357. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  358. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  359. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
  360. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  361. ASSERT_EQ(EGL_GL_COLORSPACE_DISPLAY_P3_EXT, value);
  362. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  363. }
  364. void EGLTest::get8BitConfig(EGLConfig& config) {
  365. EGLint numConfigs;
  366. EGLBoolean success;
  367. // Use 8-bit to keep focus on colorspace aspect
  368. const EGLint attrs[] = {
  369. // clang-format off
  370. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  371. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  372. EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
  373. EGL_RED_SIZE, 8,
  374. EGL_GREEN_SIZE, 8,
  375. EGL_BLUE_SIZE, 8,
  376. EGL_ALPHA_SIZE, 8,
  377. EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
  378. EGL_NONE,
  379. // clang-format on
  380. };
  381. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  382. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  383. ASSERT_EQ(1, numConfigs);
  384. EGLint components[4];
  385. EGLint value;
  386. eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
  387. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  388. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  389. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  390. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  391. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  392. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  393. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  394. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  395. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  396. success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
  397. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  398. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  399. // Verify component sizes on config match what was asked for.
  400. EXPECT_EQ(components[0], 8);
  401. EXPECT_EQ(components[1], 8);
  402. EXPECT_EQ(components[2], 8);
  403. EXPECT_EQ(components[3], 8);
  404. }
  405. void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
  406. if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
  407. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
  408. METADATA_SCALE(0.640));
  409. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
  410. METADATA_SCALE(0.330));
  411. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
  412. METADATA_SCALE(0.290));
  413. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
  414. METADATA_SCALE(0.600));
  415. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
  416. METADATA_SCALE(0.150));
  417. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
  418. METADATA_SCALE(0.060));
  419. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
  420. METADATA_SCALE(0.3127));
  421. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
  422. METADATA_SCALE(0.3290));
  423. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
  424. METADATA_SCALE(300));
  425. eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
  426. METADATA_SCALE(0.7));
  427. }
  428. if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
  429. eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
  430. METADATA_SCALE(300));
  431. eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
  432. METADATA_SCALE(75));
  433. }
  434. }
  435. void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
  436. EGLBoolean success;
  437. EGLint value;
  438. if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
  439. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, &value);
  440. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  441. ASSERT_EQ(METADATA_SCALE(0.640), value);
  442. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, &value);
  443. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  444. ASSERT_EQ(METADATA_SCALE(0.330), value);
  445. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, &value);
  446. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  447. ASSERT_EQ(METADATA_SCALE(0.290), value);
  448. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, &value);
  449. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  450. ASSERT_EQ(METADATA_SCALE(0.600), value);
  451. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, &value);
  452. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  453. ASSERT_EQ(METADATA_SCALE(0.150), value);
  454. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, &value);
  455. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  456. ASSERT_EQ(METADATA_SCALE(0.060), value);
  457. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_X_EXT, &value);
  458. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  459. ASSERT_EQ(METADATA_SCALE(0.3127), value);
  460. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, &value);
  461. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  462. ASSERT_EQ(METADATA_SCALE(0.3290), value);
  463. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, &value);
  464. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  465. ASSERT_EQ(METADATA_SCALE(300.0), value);
  466. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, &value);
  467. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  468. ASSERT_EQ(METADATA_SCALE(0.7), value);
  469. }
  470. if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
  471. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, &value);
  472. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  473. ASSERT_EQ(METADATA_SCALE(300.0), value);
  474. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, &value);
  475. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  476. ASSERT_EQ(METADATA_SCALE(75.0), value);
  477. }
  478. }
  479. TEST_F(EGLTest, EGLBT2020Linear) {
  480. EGLConfig config;
  481. EGLBoolean success;
  482. if (!hasHdrDisplay) {
  483. // skip this test if device does not have HDR display
  484. RecordProperty("hasHdrDisplay", false);
  485. return;
  486. }
  487. // Test that bt2020 linear extension exists
  488. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_linear"))
  489. << "EGL_EXT_gl_colorspace_bt2020_linear extension not available";
  490. ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
  491. struct DummyConsumer : public BnConsumerListener {
  492. void onFrameAvailable(const BufferItem& /* item */) override {}
  493. void onBuffersReleased() override {}
  494. void onSidebandStreamChanged() override {}
  495. };
  496. // Create a EGLSurface
  497. sp<IGraphicBufferProducer> producer;
  498. sp<IGraphicBufferConsumer> consumer;
  499. BufferQueue::createBufferQueue(&producer, &consumer);
  500. consumer->consumerConnect(new DummyConsumer, false);
  501. sp<Surface> mSTC = new Surface(producer);
  502. sp<ANativeWindow> mANW = mSTC;
  503. std::vector<EGLint> winAttrs;
  504. winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
  505. winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
  506. winAttrs.push_back(EGL_NONE);
  507. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
  508. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  509. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  510. EGLint value;
  511. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
  512. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  513. ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
  514. ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
  515. ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
  516. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  517. }
  518. TEST_F(EGLTest, EGLBT2020PQ) {
  519. EGLConfig config;
  520. EGLBoolean success;
  521. if (!hasHdrDisplay) {
  522. // skip this test if device does not have HDR display
  523. RecordProperty("hasHdrDisplay", false);
  524. return;
  525. }
  526. // Test that bt2020-pq extension exists
  527. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_gl_colorspace_bt2020_pq"))
  528. << "EGL_EXT_gl_colorspace_bt2020_pq extension not available";
  529. ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
  530. struct DummyConsumer : public BnConsumerListener {
  531. void onFrameAvailable(const BufferItem& /* item */) override {}
  532. void onBuffersReleased() override {}
  533. void onSidebandStreamChanged() override {}
  534. };
  535. // Create a EGLSurface
  536. sp<IGraphicBufferProducer> producer;
  537. sp<IGraphicBufferConsumer> consumer;
  538. BufferQueue::createBufferQueue(&producer, &consumer);
  539. consumer->consumerConnect(new DummyConsumer, false);
  540. sp<Surface> mSTC = new Surface(producer);
  541. sp<ANativeWindow> mANW = mSTC;
  542. std::vector<EGLint> winAttrs;
  543. winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
  544. winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
  545. winAttrs.push_back(EGL_NONE);
  546. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
  547. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  548. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  549. EGLint value;
  550. success = eglQuerySurface(mEglDisplay, eglSurface, EGL_GL_COLORSPACE_KHR, &value);
  551. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  552. ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
  553. ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
  554. ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
  555. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  556. }
  557. TEST_F(EGLTest, EGLConfigFP16) {
  558. EGLint numConfigs;
  559. EGLConfig config;
  560. EGLBoolean success;
  561. if (!hasWideColorDisplay) {
  562. // skip this test if device does not have wide-color display
  563. RecordProperty("hasWideColorDisplay", false);
  564. return;
  565. }
  566. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float"));
  567. const EGLint attrs[] = {
  568. // clang-format off
  569. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  570. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  571. EGL_RED_SIZE, 16,
  572. EGL_GREEN_SIZE, 16,
  573. EGL_BLUE_SIZE, 16,
  574. EGL_ALPHA_SIZE, 16,
  575. EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
  576. EGL_NONE,
  577. // clang-format on
  578. };
  579. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  580. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  581. ASSERT_EQ(1, numConfigs);
  582. EGLint components[4];
  583. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  584. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  585. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  586. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  587. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  588. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  589. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  590. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  591. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  592. success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
  593. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  594. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  595. EXPECT_GE(components[0], 16);
  596. EXPECT_GE(components[1], 16);
  597. EXPECT_GE(components[2], 16);
  598. EXPECT_GE(components[3], 16);
  599. struct DummyConsumer : public BnConsumerListener {
  600. void onFrameAvailable(const BufferItem& /* item */) override {}
  601. void onBuffersReleased() override {}
  602. void onSidebandStreamChanged() override {}
  603. };
  604. sp<IGraphicBufferProducer> producer;
  605. sp<IGraphicBufferConsumer> consumer;
  606. BufferQueue::createBufferQueue(&producer, &consumer);
  607. consumer->consumerConnect(new DummyConsumer, false);
  608. sp<Surface> mSTC = new Surface(producer);
  609. sp<ANativeWindow> mANW = mSTC;
  610. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
  611. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  612. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  613. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  614. }
  615. TEST_F(EGLTest, EGLNoConfigContext) {
  616. if (!hasWideColorDisplay) {
  617. // skip this test if device does not have wide-color display
  618. RecordProperty("hasWideColorDisplay", false);
  619. return;
  620. }
  621. ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
  622. struct DummyConsumer : public BnConsumerListener {
  623. void onFrameAvailable(const BufferItem& /* item */) override {}
  624. void onBuffersReleased() override {}
  625. void onSidebandStreamChanged() override {}
  626. };
  627. std::vector<EGLint> contextAttributes;
  628. contextAttributes.reserve(4);
  629. contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
  630. contextAttributes.push_back(2);
  631. contextAttributes.push_back(EGL_NONE);
  632. contextAttributes.push_back(EGL_NONE);
  633. EGLContext eglContext = eglCreateContext(mEglDisplay, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT,
  634. contextAttributes.data());
  635. EXPECT_NE(EGL_NO_CONTEXT, eglContext);
  636. EXPECT_EQ(EGL_SUCCESS, eglGetError());
  637. if (eglContext != EGL_NO_CONTEXT) {
  638. eglDestroyContext(mEglDisplay, eglContext);
  639. }
  640. }
  641. // Emulate what a native application would do to create a
  642. // 10:10:10:2 surface.
  643. TEST_F(EGLTest, EGLConfig1010102) {
  644. EGLint numConfigs;
  645. EGLConfig config;
  646. EGLBoolean success;
  647. if (!hasWideColorDisplay) {
  648. // skip this test if device does not have wide-color display
  649. RecordProperty("hasWideColorDisplay", false);
  650. return;
  651. }
  652. const EGLint attrs[] = {
  653. // clang-format off
  654. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  655. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  656. EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
  657. EGL_RED_SIZE, 10,
  658. EGL_GREEN_SIZE, 10,
  659. EGL_BLUE_SIZE, 10,
  660. EGL_ALPHA_SIZE, 2,
  661. EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
  662. EGL_NONE, EGL_NONE
  663. // clang-format on
  664. };
  665. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  666. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  667. ASSERT_EQ(1, numConfigs);
  668. EGLint components[4];
  669. EGLint value;
  670. eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value);
  671. success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]);
  672. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  673. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  674. success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]);
  675. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  676. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  677. success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]);
  678. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  679. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  680. success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
  681. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  682. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  683. EXPECT_EQ(components[0], 10);
  684. EXPECT_EQ(components[1], 10);
  685. EXPECT_EQ(components[2], 10);
  686. EXPECT_EQ(components[3], 2);
  687. struct DummyConsumer : public BnConsumerListener {
  688. void onFrameAvailable(const BufferItem& /* item */) override {}
  689. void onBuffersReleased() override {}
  690. void onSidebandStreamChanged() override {}
  691. };
  692. // Create a EGLSurface
  693. sp<IGraphicBufferProducer> producer;
  694. sp<IGraphicBufferConsumer> consumer;
  695. BufferQueue::createBufferQueue(&producer, &consumer);
  696. consumer->consumerConnect(new DummyConsumer, false);
  697. sp<Surface> mSTC = new Surface(producer);
  698. sp<ANativeWindow> mANW = mSTC;
  699. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
  700. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  701. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  702. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  703. }
  704. TEST_F(EGLTest, EGLInvalidColorspaceAttribute) {
  705. EGLConfig config;
  706. ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
  707. struct DummyConsumer : public BnConsumerListener {
  708. void onFrameAvailable(const BufferItem& /* item */) override {}
  709. void onBuffersReleased() override {}
  710. void onSidebandStreamChanged() override {}
  711. };
  712. // Create a EGLSurface
  713. sp<IGraphicBufferProducer> producer;
  714. sp<IGraphicBufferConsumer> consumer;
  715. BufferQueue::createBufferQueue(&producer, &consumer);
  716. consumer->consumerConnect(new DummyConsumer, false);
  717. sp<Surface> mSTC = new Surface(producer);
  718. sp<ANativeWindow> mANW = mSTC;
  719. EGLint winAttrs[] = {
  720. // clang-format off
  721. EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
  722. EGL_NONE,
  723. // clang-format on
  724. };
  725. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  726. ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
  727. ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
  728. }
  729. TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) {
  730. EGLint numConfigs;
  731. EGLConfig config;
  732. EGLBoolean success;
  733. const EGLint attrs[] = {
  734. // clang-format off
  735. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  736. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  737. EGL_RED_SIZE, 16,
  738. EGL_GREEN_SIZE, 16,
  739. EGL_BLUE_SIZE, 16,
  740. EGL_ALPHA_SIZE, 16,
  741. EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
  742. EGL_NONE,
  743. // clang-format on
  744. };
  745. success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs);
  746. ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
  747. ASSERT_EQ(1, numConfigs);
  748. struct DummyConsumer : public BnConsumerListener {
  749. void onFrameAvailable(const BufferItem& /* item */) override {}
  750. void onBuffersReleased() override {}
  751. void onSidebandStreamChanged() override {}
  752. };
  753. // Create a EGLSurface
  754. sp<IGraphicBufferProducer> producer;
  755. sp<IGraphicBufferConsumer> consumer;
  756. BufferQueue::createBufferQueue(&producer, &consumer);
  757. consumer->consumerConnect(new DummyConsumer, false);
  758. sp<Surface> mSTC = new Surface(producer);
  759. sp<ANativeWindow> mANW = mSTC;
  760. const EGLint winAttrs[] = {
  761. // clang-format off
  762. EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
  763. EGL_NONE,
  764. // clang-format on
  765. };
  766. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  767. ASSERT_EQ(EGL_BAD_MATCH, eglGetError());
  768. ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
  769. }
  770. TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) {
  771. EGLConfig config;
  772. ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
  773. struct DummyConsumer : public BnConsumerListener {
  774. void onFrameAvailable(const BufferItem& /* item */) override {}
  775. void onBuffersReleased() override {}
  776. void onSidebandStreamChanged() override {}
  777. };
  778. // Create a EGLSurface
  779. sp<IGraphicBufferProducer> producer;
  780. sp<IGraphicBufferConsumer> consumer;
  781. BufferQueue::createBufferQueue(&producer, &consumer);
  782. consumer->consumerConnect(new DummyConsumer, false);
  783. sp<Surface> mSTC = new Surface(producer);
  784. sp<ANativeWindow> mANW = mSTC;
  785. EGLint winAttrs[] = {
  786. // clang-format off
  787. EGL_GL_COLORSPACE_KHR, EGL_BACK_BUFFER,
  788. EGL_NONE,
  789. // clang-format on
  790. };
  791. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  792. ASSERT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
  793. ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
  794. // Now recreate surface with a valid colorspace. Ensure proper cleanup is done
  795. // in the first failed attempt (e.g. native_window_api_disconnect).
  796. winAttrs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
  797. eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  798. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  799. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  800. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  801. }
  802. TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) {
  803. EGLConfig config;
  804. ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
  805. struct DummyConsumer : public BnConsumerListener {
  806. void onFrameAvailable(const BufferItem& /* item */) override {}
  807. void onBuffersReleased() override {}
  808. void onSidebandStreamChanged() override {}
  809. };
  810. // Create a EGLSurface
  811. sp<IGraphicBufferProducer> producer;
  812. sp<IGraphicBufferConsumer> consumer;
  813. BufferQueue::createBufferQueue(&producer, &consumer);
  814. consumer->consumerConnect(new DummyConsumer, false);
  815. sp<Surface> mSTC = new Surface(producer);
  816. sp<ANativeWindow> mANW = mSTC;
  817. const EGLint winAttrs[] = {
  818. // clang-format off
  819. EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_EXT,
  820. EGL_NONE,
  821. // clang-format on
  822. };
  823. EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs);
  824. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  825. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  826. android_dataspace dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
  827. ASSERT_EQ(dataspace, HAL_DATASPACE_DISPLAY_P3);
  828. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  829. // Now create with default attribute (EGL_GL_COLORSPACE_LINEAR_KHR)
  830. eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL);
  831. ASSERT_EQ(EGL_SUCCESS, eglGetError());
  832. ASSERT_NE(EGL_NO_SURFACE, eglSurface);
  833. dataspace = static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(mANW.get()));
  834. // Make sure the dataspace has been reset to UNKNOWN
  835. ASSERT_NE(dataspace, HAL_DATASPACE_DISPLAY_P3);
  836. EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
  837. }
  838. }