hwcTestLib.cpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  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. /*
  18. * Hardware Composer Test Library
  19. * Utility library functions for use by the Hardware Composer test cases
  20. */
  21. #include <arpa/inet.h> // For ntohl() and htonl()
  22. #include <cmath>
  23. #include <sstream>
  24. #include <string>
  25. #include "hwcTestLib.h"
  26. #include "EGLUtils.h"
  27. // Defines
  28. #define NUMA(a) (sizeof(a) / sizeof((a)[0]))
  29. // Function Prototypes
  30. static void printGLString(const char *name, GLenum s);
  31. static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
  32. static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config);
  33. using namespace std;
  34. using namespace android;
  35. #define BITSPERBYTE 8 // TODO: Obtain from <values.h>, once
  36. // it has been added
  37. // Initialize Display
  38. void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface,
  39. EGLint *width, EGLint *height)
  40. {
  41. static EGLContext context;
  42. EGLBoolean returnValue;
  43. EGLConfig myConfig = {0};
  44. EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
  45. EGLint sConfigAttribs[] = {
  46. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  47. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  48. EGL_NONE };
  49. EGLint majorVersion, minorVersion;
  50. checkEglError("<init>");
  51. *dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  52. checkEglError("eglGetDisplay");
  53. if (*dpy == EGL_NO_DISPLAY) {
  54. testPrintE("eglGetDisplay returned EGL_NO_DISPLAY");
  55. exit(70);
  56. }
  57. returnValue = eglInitialize(*dpy, &majorVersion, &minorVersion);
  58. checkEglError("eglInitialize", returnValue);
  59. if (verbose) {
  60. testPrintI("EGL version %d.%d", majorVersion, minorVersion);
  61. }
  62. if (returnValue != EGL_TRUE) {
  63. testPrintE("eglInitialize failed");
  64. exit(71);
  65. }
  66. // The tests want to stop the framework and play with the hardware
  67. // composer, which means it doesn't make sense to use WindowSurface
  68. // here. android_createDisplaySurface() is going away, so just
  69. // politely fail here.
  70. EGLNativeWindowType window = NULL; //android_createDisplaySurface();
  71. if (window == NULL) {
  72. testPrintE("android_createDisplaySurface failed");
  73. exit(72);
  74. }
  75. returnValue = EGLUtils::selectConfigForNativeWindow(*dpy,
  76. sConfigAttribs, window, &myConfig);
  77. if (returnValue) {
  78. testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d",
  79. returnValue);
  80. exit(73);
  81. }
  82. checkEglError("EGLUtils::selectConfigForNativeWindow");
  83. if (verbose) {
  84. testPrintI("Chose this configuration:");
  85. printEGLConfiguration(*dpy, myConfig);
  86. }
  87. *surface = eglCreateWindowSurface(*dpy, myConfig, window, NULL);
  88. checkEglError("eglCreateWindowSurface");
  89. if (*surface == EGL_NO_SURFACE) {
  90. testPrintE("gelCreateWindowSurface failed.");
  91. exit(74);
  92. }
  93. context = eglCreateContext(*dpy, myConfig, EGL_NO_CONTEXT, contextAttribs);
  94. checkEglError("eglCreateContext");
  95. if (context == EGL_NO_CONTEXT) {
  96. testPrintE("eglCreateContext failed");
  97. exit(75);
  98. }
  99. returnValue = eglMakeCurrent(*dpy, *surface, *surface, context);
  100. checkEglError("eglMakeCurrent", returnValue);
  101. if (returnValue != EGL_TRUE) {
  102. testPrintE("eglMakeCurrent failed");
  103. exit(76);
  104. }
  105. eglQuerySurface(*dpy, *surface, EGL_WIDTH, width);
  106. checkEglError("eglQuerySurface");
  107. eglQuerySurface(*dpy, *surface, EGL_HEIGHT, height);
  108. checkEglError("eglQuerySurface");
  109. if (verbose) {
  110. testPrintI("Window dimensions: %d x %d", *width, *height);
  111. printGLString("Version", GL_VERSION);
  112. printGLString("Vendor", GL_VENDOR);
  113. printGLString("Renderer", GL_RENDERER);
  114. printGLString("Extensions", GL_EXTENSIONS);
  115. }
  116. }
  117. // Open Hardware Composer Device
  118. void hwcTestOpenHwc(hwc_composer_device_1_t **hwcDevicePtr)
  119. {
  120. int rv;
  121. hw_module_t const *hwcModule;
  122. if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) {
  123. testPrintE("hw_get_module failed, rv: %i", rv);
  124. errno = -rv;
  125. perror(NULL);
  126. exit(77);
  127. }
  128. if ((rv = hwc_open_1(hwcModule, hwcDevicePtr)) != 0) {
  129. testPrintE("hwc_open failed, rv: %i", rv);
  130. errno = -rv;
  131. perror(NULL);
  132. exit(78);
  133. }
  134. }
  135. // Color fraction class to string conversion
  136. ColorFract::operator string()
  137. {
  138. ostringstream out;
  139. out << '[' << this->c1() << ", "
  140. << this->c2() << ", "
  141. << this->c3() << ']';
  142. return out.str();
  143. }
  144. // Dimension class to string conversion
  145. HwcTestDim::operator string()
  146. {
  147. ostringstream out;
  148. out << '[' << this->width() << ", "
  149. << this->height() << ']';
  150. return out.str();
  151. }
  152. // Dimension class to hwc_rect conversion
  153. HwcTestDim::operator hwc_rect() const
  154. {
  155. hwc_rect rect;
  156. rect.left = rect.top = 0;
  157. rect.right = this->_w;
  158. rect.bottom = this->_h;
  159. return rect;
  160. }
  161. // Hardware Composer rectangle to string conversion
  162. string hwcTestRect2str(const struct hwc_rect& rect)
  163. {
  164. ostringstream out;
  165. out << '[';
  166. out << rect.left << ", ";
  167. out << rect.top << ", ";
  168. out << rect.right << ", ";
  169. out << rect.bottom;
  170. out << ']';
  171. return out.str();
  172. }
  173. // Parse HWC rectangle description of form [left, top, right, bottom]
  174. struct hwc_rect hwcTestParseHwcRect(istringstream& in, bool& error)
  175. {
  176. struct hwc_rect rect;
  177. char chStart, ch;
  178. // Defensively specify that an error occurred. Will clear
  179. // error flag if all of parsing succeeds.
  180. error = true;
  181. // First character should be a [ or <
  182. in >> chStart;
  183. if (!in || ((chStart != '<') && (chStart != '['))) { return rect; }
  184. // Left
  185. in >> rect.left;
  186. if (!in) { return rect; }
  187. in >> ch;
  188. if (!in || (ch != ',')) { return rect; }
  189. // Top
  190. in >> rect.top;
  191. if (!in) { return rect; }
  192. in >> ch;
  193. if (!in || (ch != ',')) { return rect; }
  194. // Right
  195. in >> rect.right;
  196. if (!in) { return rect; }
  197. in >> ch;
  198. if (!in || (ch != ',')) { return rect; }
  199. // Bottom
  200. in >> rect.bottom;
  201. if (!in) { return rect; }
  202. // Closing > or ]
  203. in >> ch;
  204. if (!in) { return rect; }
  205. if (((chStart == '<') && (ch != '>'))
  206. || ((chStart == '[') && (ch != ']'))) { return rect; }
  207. // Validate right and bottom are greater than left and top
  208. if ((rect.right <= rect.left) || (rect.bottom <= rect.top)) { return rect; }
  209. // Made It, clear error indicator
  210. error = false;
  211. return rect;
  212. }
  213. // Parse dimension of form [width, height]
  214. HwcTestDim hwcTestParseDim(istringstream& in, bool& error)
  215. {
  216. HwcTestDim dim;
  217. char chStart, ch;
  218. uint32_t val;
  219. // Defensively specify that an error occurred. Will clear
  220. // error flag if all of parsing succeeds.
  221. error = true;
  222. // First character should be a [ or <
  223. in >> chStart;
  224. if (!in || ((chStart != '<') && (chStart != '['))) { return dim; }
  225. // Width
  226. in >> val;
  227. if (!in) { return dim; }
  228. dim.setWidth(val);
  229. in >> ch;
  230. if (!in || (ch != ',')) { return dim; }
  231. // Height
  232. in >> val;
  233. if (!in) { return dim; }
  234. dim.setHeight(val);
  235. // Closing > or ]
  236. in >> ch;
  237. if (!in) { return dim; }
  238. if (((chStart == '<') && (ch != '>'))
  239. || ((chStart == '[') && (ch != ']'))) { return dim; }
  240. // Validate width and height greater than 0
  241. if ((dim.width() <= 0) || (dim.height() <= 0)) { return dim; }
  242. // Made It, clear error indicator
  243. error = false;
  244. return dim;
  245. }
  246. // Parse fractional color of form [0.##, 0.##, 0.##]
  247. // Fractional values can be from 0.0 to 1.0 inclusive. Note, integer
  248. // values of 0.0 and 1.0, which are non-fractional, are considered valid.
  249. // They are an exception, all other valid inputs are fractions.
  250. ColorFract hwcTestParseColor(istringstream& in, bool& error)
  251. {
  252. ColorFract color;
  253. char chStart, ch;
  254. float c1, c2, c3;
  255. // Defensively specify that an error occurred. Will clear
  256. // error flag if all of parsing succeeds.
  257. error = true;
  258. // First character should be a [ or <
  259. in >> chStart;
  260. if (!in || ((chStart != '<') && (chStart != '['))) { return color; }
  261. // 1st Component
  262. in >> c1;
  263. if (!in) { return color; }
  264. if ((c1 < 0.0) || (c1 > 1.0)) { return color; }
  265. in >> ch;
  266. if (!in || (ch != ',')) { return color; }
  267. // 2nd Component
  268. in >> c2;
  269. if (!in) { return color; }
  270. if ((c2 < 0.0) || (c2 > 1.0)) { return color; }
  271. in >> ch;
  272. if (!in || (ch != ',')) { return color; }
  273. // 3rd Component
  274. in >> c3;
  275. if (!in) { return color; }
  276. if ((c3 < 0.0) || (c3 > 1.0)) { return color; }
  277. // Closing > or ]
  278. in >> ch;
  279. if (!in) { return color; }
  280. if (((chStart == '<') && (ch != '>'))
  281. || ((chStart == '[') && (ch != ']'))) { return color; }
  282. // Are all the components fractional
  283. if ((c1 < 0.0) || (c1 > 1.0)
  284. || (c2 < 0.0) || (c2 > 1.0)
  285. || (c3 < 0.0) || (c3 > 1.0)) { return color; }
  286. // Made It, clear error indicator
  287. error = false;
  288. return ColorFract(c1, c2, c3);
  289. }
  290. // Look up and return pointer to structure with the characteristics
  291. // of the graphic format named by the desc parameter. Search failure
  292. // indicated by the return of NULL.
  293. const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc)
  294. {
  295. for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
  296. if (string(desc) == string(hwcTestGraphicFormat[n1].desc)) {
  297. return &hwcTestGraphicFormat[n1];
  298. }
  299. }
  300. return NULL;
  301. }
  302. // Look up and return pointer to structure with the characteristics
  303. // of the graphic format specified by the id parameter. Search failure
  304. // indicated by the return of NULL.
  305. const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id)
  306. {
  307. for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
  308. if (id == hwcTestGraphicFormat[n1].format) {
  309. return &hwcTestGraphicFormat[n1];
  310. }
  311. }
  312. return NULL;
  313. }
  314. // Given the integer ID of a graphic format, return a pointer to
  315. // a string that describes the format.
  316. const char *hwcTestGraphicFormat2str(uint32_t format)
  317. {
  318. const static char *unknown = "unknown";
  319. for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
  320. if (format == hwcTestGraphicFormat[n1].format) {
  321. return hwcTestGraphicFormat[n1].desc;
  322. }
  323. }
  324. return unknown;
  325. }
  326. /*
  327. * hwcTestCreateLayerList
  328. * Dynamically creates layer list with numLayers worth
  329. * of hwLayers entries.
  330. */
  331. hwc_display_contents_1_t *hwcTestCreateLayerList(size_t numLayers)
  332. {
  333. hwc_display_contents_1_t *list;
  334. size_t size = sizeof(hwc_display_contents_1_t) + numLayers * sizeof(hwc_layer_1_t);
  335. if ((list = (hwc_display_contents_1_t *) calloc(1, size)) == NULL) {
  336. return NULL;
  337. }
  338. list->flags = HWC_GEOMETRY_CHANGED;
  339. list->numHwLayers = numLayers;
  340. return list;
  341. }
  342. /*
  343. * hwcTestFreeLayerList
  344. * Frees memory previous allocated via hwcTestCreateLayerList().
  345. */
  346. void hwcTestFreeLayerList(hwc_display_contents_1_t *list)
  347. {
  348. free(list);
  349. }
  350. // Display the settings of the layer list pointed to by list
  351. void hwcTestDisplayList(hwc_display_contents_1_t *list)
  352. {
  353. testPrintI(" flags: %#x%s", list->flags,
  354. (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : "");
  355. testPrintI(" numHwLayers: %u", list->numHwLayers);
  356. for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
  357. testPrintI(" layer %u compositionType: %#x%s%s", layer,
  358. list->hwLayers[layer].compositionType,
  359. (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
  360. ? " FRAMEBUFFER" : "",
  361. (list->hwLayers[layer].compositionType == HWC_OVERLAY)
  362. ? " OVERLAY" : "");
  363. testPrintI(" hints: %#x",
  364. list->hwLayers[layer].hints,
  365. (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
  366. ? " TRIPLE_BUFFER" : "",
  367. (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
  368. ? " CLEAR_FB" : "");
  369. testPrintI(" flags: %#x%s",
  370. list->hwLayers[layer].flags,
  371. (list->hwLayers[layer].flags & HWC_SKIP_LAYER)
  372. ? " SKIP_LAYER" : "");
  373. testPrintI(" handle: %p",
  374. list->hwLayers[layer].handle);
  375. // Intentionally skipped display of ROT_180 & ROT_270,
  376. // which are formed from combinations of the other flags.
  377. testPrintI(" transform: %#x%s%s%s",
  378. list->hwLayers[layer].transform,
  379. (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H)
  380. ? " FLIP_H" : "",
  381. (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V)
  382. ? " FLIP_V" : "",
  383. (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90)
  384. ? " ROT_90" : "");
  385. testPrintI(" blending: %#x%s%s%s",
  386. list->hwLayers[layer].blending,
  387. (list->hwLayers[layer].blending == HWC_BLENDING_NONE)
  388. ? " NONE" : "",
  389. (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT)
  390. ? " PREMULT" : "",
  391. (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE)
  392. ? " COVERAGE" : "");
  393. testPrintI(" sourceCrop: %s",
  394. hwcTestRect2str(list->hwLayers[layer].sourceCrop).c_str());
  395. testPrintI(" displayFrame: %s",
  396. hwcTestRect2str(list->hwLayers[layer].displayFrame).c_str());
  397. testPrintI(" scaleFactor: [%f, %f]",
  398. (float) (list->hwLayers[layer].sourceCrop.right
  399. - list->hwLayers[layer].sourceCrop.left)
  400. / (float) (list->hwLayers[layer].displayFrame.right
  401. - list->hwLayers[layer].displayFrame.left),
  402. (float) (list->hwLayers[layer].sourceCrop.bottom
  403. - list->hwLayers[layer].sourceCrop.top)
  404. / (float) (list->hwLayers[layer].displayFrame.bottom
  405. - list->hwLayers[layer].displayFrame.top));
  406. }
  407. }
  408. /*
  409. * Display List Prepare Modifiable
  410. *
  411. * Displays the portions of a list that are meant to be modified by
  412. * a prepare call.
  413. */
  414. void hwcTestDisplayListPrepareModifiable(hwc_display_contents_1_t *list)
  415. {
  416. uint32_t numOverlays = 0;
  417. for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
  418. if (list->hwLayers[layer].compositionType == HWC_OVERLAY) {
  419. numOverlays++;
  420. }
  421. testPrintI(" layer %u compositionType: %#x%s%s", layer,
  422. list->hwLayers[layer].compositionType,
  423. (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
  424. ? " FRAMEBUFFER" : "",
  425. (list->hwLayers[layer].compositionType == HWC_OVERLAY)
  426. ? " OVERLAY" : "");
  427. testPrintI(" hints: %#x%s%s",
  428. list->hwLayers[layer].hints,
  429. (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
  430. ? " TRIPLE_BUFFER" : "",
  431. (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
  432. ? " CLEAR_FB" : "");
  433. }
  434. testPrintI(" numOverlays: %u", numOverlays);
  435. }
  436. /*
  437. * Display List Handles
  438. *
  439. * Displays the handles of all the graphic buffers in the list.
  440. */
  441. void hwcTestDisplayListHandles(hwc_display_contents_1_t *list)
  442. {
  443. const unsigned int maxLayersPerLine = 6;
  444. ostringstream str(" layers:");
  445. for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
  446. str << ' ' << list->hwLayers[layer].handle;
  447. if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1))
  448. && (layer != list->numHwLayers - 1)) {
  449. testPrintI("%s", str.str().c_str());
  450. str.str(" ");
  451. }
  452. }
  453. testPrintI("%s", str.str().c_str());
  454. }
  455. // Returns a uint32_t that contains a format specific representation of a
  456. // single pixel of the given color and alpha values.
  457. uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha)
  458. {
  459. const struct attrib {
  460. uint32_t format;
  461. bool hostByteOrder;
  462. size_t bytes;
  463. size_t c1Offset;
  464. size_t c1Size;
  465. size_t c2Offset;
  466. size_t c2Size;
  467. size_t c3Offset;
  468. size_t c3Size;
  469. size_t aOffset;
  470. size_t aSize;
  471. } attributes[] = {
  472. {HAL_PIXEL_FORMAT_RGBA_8888, false, 4, 0, 8, 8, 8, 16, 8, 24, 8},
  473. {HAL_PIXEL_FORMAT_RGBX_8888, false, 4, 0, 8, 8, 8, 16, 8, 0, 0},
  474. {HAL_PIXEL_FORMAT_RGB_888, false, 3, 0, 8, 8, 8, 16, 8, 0, 0},
  475. {HAL_PIXEL_FORMAT_RGB_565, true, 2, 0, 5, 5, 6, 11, 5, 0, 0},
  476. {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8, 8, 8, 0, 8, 24, 8},
  477. {HAL_PIXEL_FORMAT_YV12, true, 3, 16, 8, 8, 8, 0, 8, 0, 0},
  478. };
  479. const struct attrib *attrib;
  480. for (attrib = attributes; attrib < attributes + NUMA(attributes);
  481. attrib++) {
  482. if (attrib->format == format) { break; }
  483. }
  484. if (attrib >= attributes + NUMA(attributes)) {
  485. testPrintE("colorFract2Pixel unsupported format of: %u", format);
  486. exit(80);
  487. }
  488. uint32_t pixel;
  489. pixel = htonl((uint32_t) round((((1 << attrib->c1Size) - 1) * color.c1()))
  490. << ((sizeof(pixel) * BITSPERBYTE)
  491. - (attrib->c1Offset + attrib->c1Size)));
  492. pixel |= htonl((uint32_t) round((((1 << attrib->c2Size) - 1) * color.c2()))
  493. << ((sizeof(pixel) * BITSPERBYTE)
  494. - (attrib->c2Offset + attrib->c2Size)));
  495. pixel |= htonl((uint32_t) round((((1 << attrib->c3Size) - 1) * color.c3()))
  496. << ((sizeof(pixel) * BITSPERBYTE)
  497. - (attrib->c3Offset + attrib->c3Size)));
  498. if (attrib->aSize) {
  499. pixel |= htonl((uint32_t) round((((1 << attrib->aSize) - 1) * alpha))
  500. << ((sizeof(pixel) * BITSPERBYTE)
  501. - (attrib->aOffset + attrib->aSize)));
  502. }
  503. if (attrib->hostByteOrder) {
  504. pixel = ntohl(pixel);
  505. pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE;
  506. }
  507. return pixel;
  508. }
  509. // Sets the pixel at the given x and y coordinates to the color and alpha
  510. // value given by pixel. The contents of pixel is format specific. It's
  511. // value should come from a call to hwcTestColor2Pixel().
  512. void hwcTestSetPixel(GraphicBuffer *gBuf, unsigned char *buf,
  513. uint32_t x, uint32_t y, uint32_t pixel)
  514. {
  515. const struct attrib {
  516. int format;
  517. size_t bytes;
  518. } attributes[] = {
  519. {HAL_PIXEL_FORMAT_RGBA_8888, 4},
  520. {HAL_PIXEL_FORMAT_RGBX_8888, 4},
  521. {HAL_PIXEL_FORMAT_RGB_888, 3},
  522. {HAL_PIXEL_FORMAT_RGB_565, 2},
  523. {HAL_PIXEL_FORMAT_BGRA_8888, 4},
  524. };
  525. if (gBuf->getPixelFormat() == HAL_PIXEL_FORMAT_YV12) {
  526. uint32_t yPlaneOffset, uPlaneOffset, vPlaneOffset;
  527. uint32_t yPlaneStride = gBuf->getStride();
  528. uint32_t uPlaneStride = ((gBuf->getStride() / 2) + 0xf) & ~0xf;
  529. uint32_t vPlaneStride = uPlaneStride;
  530. yPlaneOffset = 0;
  531. vPlaneOffset = yPlaneOffset + yPlaneStride * gBuf->getHeight();
  532. uPlaneOffset = vPlaneOffset
  533. + vPlaneStride * (gBuf->getHeight() / 2);
  534. *(buf + yPlaneOffset + y * yPlaneStride + x) = pixel & 0xff;
  535. *(buf + uPlaneOffset + (y / 2) * uPlaneStride + (x / 2))
  536. = (pixel & 0xff00) >> 8;
  537. *(buf + vPlaneOffset + (y / 2) * vPlaneStride + (x / 2))
  538. = (pixel & 0xff0000) >> 16;
  539. return;
  540. }
  541. const struct attrib *attrib;
  542. for (attrib = attributes; attrib < attributes + NUMA(attributes);
  543. attrib++) {
  544. if (attrib->format == gBuf->getPixelFormat()) { break; }
  545. }
  546. if (attrib >= attributes + NUMA(attributes)) {
  547. testPrintE("setPixel unsupported format of: %u",
  548. gBuf->getPixelFormat());
  549. exit(90);
  550. }
  551. memmove(buf + ((gBuf->getStride() * attrib->bytes) * y)
  552. + (attrib->bytes * x), &pixel, attrib->bytes);
  553. }
  554. // Fill a given graphic buffer with a uniform color and alpha
  555. void hwcTestFillColor(GraphicBuffer *gBuf, ColorFract color, float alpha)
  556. {
  557. unsigned char* buf = NULL;
  558. status_t err;
  559. uint32_t pixel;
  560. pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, alpha);
  561. err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
  562. if (err != 0) {
  563. testPrintE("hwcTestFillColor lock failed: %d", err);
  564. exit(100);
  565. }
  566. for (unsigned int x = 0; x < gBuf->getStride(); x++) {
  567. for (unsigned int y = 0; y < gBuf->getHeight(); y++) {
  568. hwcTestSetPixel(gBuf, buf, x, y, (x < gBuf->getWidth())
  569. ? pixel : testRand());
  570. }
  571. }
  572. err = gBuf->unlock();
  573. if (err != 0) {
  574. testPrintE("hwcTestFillColor unlock failed: %d", err);
  575. exit(101);
  576. }
  577. }
  578. // Fill the given buffer with a horizontal blend of colors, with the left
  579. // side color given by startColor and the right side color given by
  580. // endColor. The startColor and endColor values are specified in the format
  581. // given by colorFormat, which might be different from the format of the
  582. // graphic buffer. When different, a color conversion is done when possible
  583. // to the graphic format of the graphic buffer. A color of black is
  584. // produced for cases where the conversion is impossible (e.g. out of gamut
  585. // values).
  586. void hwcTestFillColorHBlend(GraphicBuffer *gBuf, uint32_t colorFormat,
  587. ColorFract startColor, ColorFract endColor)
  588. {
  589. status_t err;
  590. unsigned char* buf = NULL;
  591. const uint32_t width = gBuf->getWidth();
  592. const uint32_t height = gBuf->getHeight();
  593. const uint32_t stride = gBuf->getStride();
  594. err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
  595. if (err != 0) {
  596. testPrintE("hwcTestFillColorHBlend lock failed: %d", err);
  597. exit(110);
  598. }
  599. for (unsigned int x = 0; x < stride; x++) {
  600. uint32_t pixel;
  601. if (x < width) {
  602. ColorFract color(startColor.c1() + (endColor.c1() - startColor.c1())
  603. * ((float) x / (float) (width - 1)),
  604. startColor.c2() + (endColor.c2() - startColor.c2())
  605. * ((float) x / (float) (width - 1)),
  606. startColor.c3() + (endColor.c3() - startColor.c3())
  607. * ((float) x / (float) (width - 1)));
  608. // When formats differ, convert colors.
  609. // Important to not convert when formats are the same, since
  610. // out of gamut colors are always converted to black.
  611. if (colorFormat != (uint32_t) gBuf->getPixelFormat()) {
  612. hwcTestColorConvert(colorFormat, gBuf->getPixelFormat(), color);
  613. }
  614. pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, 1.0);
  615. } else {
  616. // Fill pad with random values
  617. pixel = testRand();
  618. }
  619. for (unsigned int y = 0; y < height; y++) {
  620. hwcTestSetPixel(gBuf, buf, x, y, pixel);
  621. }
  622. }
  623. err = gBuf->unlock();
  624. if (err != 0) {
  625. testPrintE("hwcTestFillColorHBlend unlock failed: %d", err);
  626. exit(111);
  627. }
  628. }
  629. /*
  630. * When possible, converts color specified as a full range value in
  631. * the fromFormat, into an equivalent full range color in the toFormat.
  632. * When conversion is impossible (e.g. out of gamut color) a color
  633. * or black in the full range output format is produced. The input
  634. * color is given as a fractional color in the parameter named color.
  635. * The produced color is written over the same parameter used to
  636. * provide the input color.
  637. *
  638. * Each graphic format has 3 color components and each of these
  639. * components has both a full and in gamut range. This function uses
  640. * a table that provides the full and in gamut ranges of each of the
  641. * supported graphic formats. The full range is given by members named
  642. * c[123]Min to c[123]Max, while the in gamut range is given by members
  643. * named c[123]Low to c[123]High. In most cases the full and in gamut
  644. * ranges are equivalent. This occurs when the c[123]Min == c[123]Low and
  645. * c[123]High == c[123]Max.
  646. *
  647. * The input and produced colors are both specified as a fractional amount
  648. * of the full range. The diagram below provides an overview of the
  649. * conversion process. The main steps are:
  650. *
  651. * 1. Produce black if the input color is out of gamut.
  652. *
  653. * 2. Convert the in gamut color into the fraction of the fromFromat
  654. * in gamut range.
  655. *
  656. * 3. Convert from the fraction of the in gamut from format range to
  657. * the fraction of the in gamut to format range. Produce black
  658. * if an equivalent color does not exists.
  659. *
  660. * 4. Covert from the fraction of the in gamut to format to the
  661. * fraction of the full range to format.
  662. *
  663. * From Format To Format
  664. * max high high max
  665. * ----+ +-----------+
  666. * high \ / \ high
  667. * ------\-------------+ +-------->
  668. * \
  669. * \ +--- black --+
  670. * \ / \
  671. * \ / +-->
  672. * low \ / low
  673. * -------- ---+-- black --+
  674. * min low low min
  675. * ^ ^ ^ ^ ^
  676. * | | | | |
  677. * | | | | +-- fraction of full range
  678. * | | | +-- fraction of valid range
  679. * | | +-- fromFormat to toFormat color conversion
  680. * | +-- fraction of valid range
  681. * +-- fraction of full range
  682. */
  683. void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat,
  684. ColorFract& color)
  685. {
  686. const struct attrib {
  687. uint32_t format;
  688. bool rgb;
  689. bool yuv;
  690. int c1Min, c1Low, c1High, c1Max;
  691. int c2Min, c2Low, c2High, c2Max;
  692. int c3Min, c3Low, c3High, c3Max;
  693. } attributes[] = {
  694. {HAL_PIXEL_FORMAT_RGBA_8888, true, false,
  695. 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
  696. {HAL_PIXEL_FORMAT_RGBX_8888, true, false,
  697. 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
  698. {HAL_PIXEL_FORMAT_RGB_888, true, false,
  699. 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
  700. {HAL_PIXEL_FORMAT_RGB_565, true, false,
  701. 0, 0, 31, 31, 0, 0, 63, 63, 0, 0, 31, 31},
  702. {HAL_PIXEL_FORMAT_BGRA_8888, true, false,
  703. 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
  704. {HAL_PIXEL_FORMAT_YV12, false, true,
  705. 0, 16, 235, 255, 0, 16, 240, 255, 0, 16, 240, 255},
  706. };
  707. const struct attrib *fromAttrib;
  708. for (fromAttrib = attributes; fromAttrib < attributes + NUMA(attributes);
  709. fromAttrib++) {
  710. if (fromAttrib->format == fromFormat) { break; }
  711. }
  712. if (fromAttrib >= attributes + NUMA(attributes)) {
  713. testPrintE("hwcTestColorConvert unsupported from format of: %u",
  714. fromFormat);
  715. exit(120);
  716. }
  717. const struct attrib *toAttrib;
  718. for (toAttrib = attributes; toAttrib < attributes + NUMA(attributes);
  719. toAttrib++) {
  720. if (toAttrib->format == toFormat) { break; }
  721. }
  722. if (toAttrib >= attributes + NUMA(attributes)) {
  723. testPrintE("hwcTestColorConvert unsupported to format of: %u",
  724. toFormat);
  725. exit(121);
  726. }
  727. // Produce black if any of the from components are outside the
  728. // valid color range
  729. float c1Val = fromAttrib->c1Min
  730. + ((float) (fromAttrib->c1Max - fromAttrib->c1Min) * color.c1());
  731. float c2Val = fromAttrib->c2Min
  732. + ((float) (fromAttrib->c2Max - fromAttrib->c2Min) * color.c2());
  733. float c3Val = fromAttrib->c3Min
  734. + ((float) (fromAttrib->c3Max - fromAttrib->c3Min) * color.c3());
  735. if ((c1Val < fromAttrib->c1Low) || (c1Val > fromAttrib->c1High)
  736. || (c2Val < fromAttrib->c2Low) || (c2Val > fromAttrib->c2High)
  737. || (c3Val < fromAttrib->c3Low) || (c3Val > fromAttrib->c3High)) {
  738. // Return black
  739. // Will use representation of black from RGBA8888 graphic format
  740. // and recursively convert it to the requested graphic format.
  741. color = ColorFract(0.0, 0.0, 0.0);
  742. hwcTestColorConvert(HAL_PIXEL_FORMAT_RGBA_8888, toFormat, color);
  743. return;
  744. }
  745. // Within from format, convert from fraction of full range
  746. // to fraction of valid range
  747. color = ColorFract((c1Val - fromAttrib->c1Low)
  748. / (fromAttrib->c1High - fromAttrib->c1Low),
  749. (c2Val - fromAttrib->c2Low)
  750. / (fromAttrib->c2High - fromAttrib->c2Low),
  751. (c3Val - fromAttrib->c3Low)
  752. / (fromAttrib->c3High - fromAttrib->c3Low));
  753. // If needed perform RGB to YUV conversion
  754. float wr = 0.2126, wg = 0.7152, wb = 0.0722; // ITU709 recommended constants
  755. if (fromAttrib->rgb && toAttrib->yuv) {
  756. float r = color.c1(), g = color.c2(), b = color.c3();
  757. float y = wr * r + wg * g + wb * b;
  758. float u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5;
  759. float v = 0.5 * ((r - y) / (1.0 - wr)) + 0.5;
  760. // Produce black if color is outside the YUV gamut
  761. if ((y < 0.0) || (y > 1.0)
  762. || (u < 0.0) || (u > 1.0)
  763. || (v < 0.0) || (v > 1.0)) {
  764. y = 0.0;
  765. u = v = 0.5;
  766. }
  767. color = ColorFract(y, u, v);
  768. }
  769. // If needed perform YUV to RGB conversion
  770. // Equations determined from the ITU709 equations for RGB to YUV
  771. // conversion, plus the following algebra:
  772. //
  773. // u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5
  774. // 0.5 * ((b - y) / (1.0 - wb)) = u - 0.5
  775. // (b - y) / (1.0 - wb) = 2 * (u - 0.5)
  776. // b - y = 2 * (u - 0.5) * (1.0 - wb)
  777. // b = 2 * (u - 0.5) * (1.0 - wb) + y
  778. //
  779. // v = 0.5 * ((r -y) / (1.0 - wr)) + 0.5
  780. // 0.5 * ((r - y) / (1.0 - wr)) = v - 0.5
  781. // (r - y) / (1.0 - wr) = 2 * (v - 0.5)
  782. // r - y = 2 * (v - 0.5) * (1.0 - wr)
  783. // r = 2 * (v - 0.5) * (1.0 - wr) + y
  784. //
  785. // y = wr * r + wg * g + wb * b
  786. // wr * r + wg * g + wb * b = y
  787. // wg * g = y - wr * r - wb * b
  788. // g = (y - wr * r - wb * b) / wg
  789. if (fromAttrib->yuv && toAttrib->rgb) {
  790. float y = color.c1(), u = color.c2(), v = color.c3();
  791. float r = 2.0 * (v - 0.5) * (1.0 - wr) + y;
  792. float b = 2.0 * (u - 0.5) * (1.0 - wb) + y;
  793. float g = (y - wr * r - wb * b) / wg;
  794. // Produce black if color is outside the RGB gamut
  795. if ((r < 0.0) || (r > 1.0)
  796. || (g < 0.0) || (g > 1.0)
  797. || (b < 0.0) || (b > 1.0)) {
  798. r = g = b = 0.0;
  799. }
  800. color = ColorFract(r, g, b);
  801. }
  802. // Within to format, convert from fraction of valid range
  803. // to fraction of full range
  804. c1Val = (toAttrib->c1Low
  805. + (float) (toAttrib->c1High - toAttrib->c1Low) * color.c1());
  806. c2Val = (toAttrib->c1Low
  807. + (float) (toAttrib->c2High - toAttrib->c2Low) * color.c2());
  808. c3Val = (toAttrib->c1Low
  809. + (float) (toAttrib->c3High - toAttrib->c3Low) * color.c3());
  810. color = ColorFract((float) (c1Val - toAttrib->c1Min)
  811. / (float) (toAttrib->c1Max - toAttrib->c1Min),
  812. (float) (c2Val - toAttrib->c2Min)
  813. / (float) (toAttrib->c2Max - toAttrib->c2Min),
  814. (float) (c3Val - toAttrib->c3Min)
  815. / (float) (toAttrib->c3Max - toAttrib->c3Min));
  816. }
  817. // TODO: Use PrintGLString, CechckGlError, and PrintEGLConfiguration
  818. // from libglTest
  819. static void printGLString(const char *name, GLenum s)
  820. {
  821. const char *v = (const char *) glGetString(s);
  822. if (v == NULL) {
  823. testPrintI("GL %s unknown", name);
  824. } else {
  825. testPrintI("GL %s = %s", name, v);
  826. }
  827. }
  828. static void checkEglError(const char* op, EGLBoolean returnVal)
  829. {
  830. if (returnVal != EGL_TRUE) {
  831. testPrintE("%s() returned %d", op, returnVal);
  832. }
  833. for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
  834. = eglGetError()) {
  835. testPrintE("after %s() eglError %s (0x%x)",
  836. op, EGLUtils::strerror(error), error);
  837. }
  838. }
  839. static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config)
  840. {
  841. #define X(VAL) {VAL, #VAL}
  842. struct {EGLint attribute; const char* name;} names[] = {
  843. X(EGL_BUFFER_SIZE),
  844. X(EGL_ALPHA_SIZE),
  845. X(EGL_BLUE_SIZE),
  846. X(EGL_GREEN_SIZE),
  847. X(EGL_RED_SIZE),
  848. X(EGL_DEPTH_SIZE),
  849. X(EGL_STENCIL_SIZE),
  850. X(EGL_CONFIG_CAVEAT),
  851. X(EGL_CONFIG_ID),
  852. X(EGL_LEVEL),
  853. X(EGL_MAX_PBUFFER_HEIGHT),
  854. X(EGL_MAX_PBUFFER_PIXELS),
  855. X(EGL_MAX_PBUFFER_WIDTH),
  856. X(EGL_NATIVE_RENDERABLE),
  857. X(EGL_NATIVE_VISUAL_ID),
  858. X(EGL_NATIVE_VISUAL_TYPE),
  859. X(EGL_SAMPLES),
  860. X(EGL_SAMPLE_BUFFERS),
  861. X(EGL_SURFACE_TYPE),
  862. X(EGL_TRANSPARENT_TYPE),
  863. X(EGL_TRANSPARENT_RED_VALUE),
  864. X(EGL_TRANSPARENT_GREEN_VALUE),
  865. X(EGL_TRANSPARENT_BLUE_VALUE),
  866. X(EGL_BIND_TO_TEXTURE_RGB),
  867. X(EGL_BIND_TO_TEXTURE_RGBA),
  868. X(EGL_MIN_SWAP_INTERVAL),
  869. X(EGL_MAX_SWAP_INTERVAL),
  870. X(EGL_LUMINANCE_SIZE),
  871. X(EGL_ALPHA_MASK_SIZE),
  872. X(EGL_COLOR_BUFFER_TYPE),
  873. X(EGL_RENDERABLE_TYPE),
  874. X(EGL_CONFORMANT),
  875. };
  876. #undef X
  877. for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
  878. EGLint value = -1;
  879. EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute,
  880. &value);
  881. EGLint error = eglGetError();
  882. if (returnVal && error == EGL_SUCCESS) {
  883. testPrintI(" %s: %d (%#x)", names[j].name, value, value);
  884. }
  885. }
  886. testPrintI("");
  887. }