vg_lite_dump.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353
  1. /****************************************************************************
  2. *
  3. * Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California.
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * 'Software'), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject
  12. * to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial
  16. * portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21. * IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
  22. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. *****************************************************************************/
  27. #include <stdio.h>
  28. #include <stdint.h>
  29. #include <assert.h>
  30. #include <stdarg.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "vg_lite_context.h"
  34. #ifdef _WIN32
  35. #include <windows.h>
  36. #elif defined(__ZEPHYR__)
  37. #include <zephyr.h>
  38. #include <fs/fs.h>
  39. #else
  40. #include <stdbool.h>
  41. #include <pthread.h>
  42. #include <unistd.h>
  43. #include "png.h"
  44. #endif
  45. #if DUMP_CAPTURE || DUMP_LAST_CAPTURE
  46. static int DumpFlag = 0;
  47. static void * dump_mutex = NULL;
  48. #if defined(__ZEPHYR__)
  49. typedef struct _vglitesDUMP_FILE_INFO
  50. {
  51. void * _debugFile;
  52. uint32_t _threadID;
  53. }vglitesDUMP_FILE_INFO;
  54. #else
  55. typedef struct _vglitesDUMP_FILE_INFO
  56. {
  57. FILE * _debugFile;
  58. uint32_t _threadID;
  59. }vglitesDUMP_FILE_INFO;
  60. #endif
  61. typedef struct _vglitesBUFFERED_OUTPUT * vglitesBUFFERED_OUTPUT_PTR;
  62. typedef struct _vglitesBUFFERED_OUTPUT
  63. {
  64. int indent;
  65. vglitesBUFFERED_OUTPUT_PTR prev;
  66. vglitesBUFFERED_OUTPUT_PTR next;
  67. }
  68. vglitesBUFFERED_OUTPUT;
  69. static vglitesBUFFERED_OUTPUT _outputBuffer[1];
  70. static vglitesBUFFERED_OUTPUT_PTR _outputBufferHead = NULL;
  71. static vglitesBUFFERED_OUTPUT_PTR _outputBufferTail = NULL;
  72. #ifdef __linux__
  73. static pthread_mutex_t _printMutex = PTHREAD_MUTEX_INITIALIZER;
  74. static pthread_mutex_t _dumpFileMutex = PTHREAD_MUTEX_INITIALIZER;
  75. #elif defined(__ZEPHYR__)
  76. static K_MUTEX_DEFINE(_printMutex);
  77. static K_MUTEX_DEFINE(_dumpFileMutex);
  78. #endif
  79. /* Alignment with a power of two value. */
  80. #define vglitemALIGN(n, align) \
  81. ( \
  82. ((n) + ((align) - 1)) & ~((align) - 1) \
  83. )
  84. #if defined(__ZEPHYR__)
  85. static void *_SetDumpFile(
  86. void *File, int CloseOldFile
  87. );
  88. #else
  89. static FILE *_SetDumpFile(
  90. FILE *File, int CloseOldFile
  91. );
  92. #endif
  93. vg_lite_error_t vg_lite_CreateMutex(void **Mutex)
  94. {
  95. #ifdef _WIN32
  96. void *handle;
  97. assert(Mutex!=NULL);
  98. handle = CreateMutex(NULL, 0, NULL);
  99. if (handle == NULL)
  100. {
  101. return VG_LITE_OUT_OF_RESOURCES;
  102. }
  103. *Mutex = handle;
  104. #elif defined(__ZEPHYR__)
  105. struct k_mutex *mutex = NULL;
  106. /* Validate the arguments. */
  107. assert(Mutex != NULL);
  108. mutex = vg_lite_os_malloc(sizeof(*mutex));
  109. if (mutex)
  110. {
  111. k_mutex_init(mutex);
  112. *Mutex = (void *) mutex;
  113. }
  114. else
  115. {
  116. return VG_LITE_OUT_OF_RESOURCES;
  117. }
  118. #else
  119. pthread_mutex_t* mutex = NULL;
  120. pthread_mutexattr_t mta;
  121. /* Validate the arguments. */
  122. assert(Mutex != NULL);
  123. /* Allocate memory for the mutex. */
  124. mutex = malloc(sizeof(pthread_mutex_t));
  125. pthread_mutexattr_init(&mta);
  126. pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
  127. /* Initialize the mutex. */
  128. pthread_mutex_init(mutex, &mta);
  129. /* Destroy mta.*/
  130. pthread_mutexattr_destroy(&mta);
  131. /* Return mutex to caller. */
  132. *Mutex = (void *) mutex;
  133. #endif
  134. return VG_LITE_SUCCESS;
  135. }
  136. vg_lite_error_t
  137. vg_lite_AcquireMutex(void *Mutex, unsigned int Timeout)
  138. {
  139. vg_lite_error_t status = VG_LITE_SUCCESS;
  140. #ifdef _WIN32
  141. unsigned long milliSeconds;
  142. /* Validate the arguments. */
  143. assert(Mutex != NULL);
  144. milliSeconds = (Timeout == ((unsigned int) ~0U))
  145. ? INFINITE
  146. : Timeout;
  147. if (WaitForSingleObject((HANDLE) Mutex,
  148. milliSeconds) == WAIT_TIMEOUT)
  149. {
  150. /* Timeout. */
  151. return VG_LITE_TIMEOUT;
  152. }
  153. #elif defined(__ZEPHYR__)
  154. k_timeout_t z_timeout;
  155. /* Validate the arguments. */
  156. assert(Mutex != NULL);
  157. z_timeout = (Timeout == ((unsigned int) ~0U)) ? K_FOREVER : K_MSEC(Timeout);
  158. if (k_mutex_lock(Mutex, z_timeout))
  159. {
  160. /* Timeout. */
  161. return VG_LITE_TIMEOUT;
  162. }
  163. #else
  164. pthread_mutex_t *mutex;
  165. /* Validate the arguments. */
  166. assert(Mutex != NULL);
  167. /* Cast the pointer. */
  168. mutex = (pthread_mutex_t *) Mutex;
  169. /* Test for infinite. */
  170. if (Timeout == ((uint32_t) ~0U))
  171. {
  172. /* Lock the mutex. */
  173. if (pthread_mutex_lock(mutex))
  174. {
  175. /* Some error. */
  176. status = VG_LITE_GENERIC_IO;
  177. }
  178. else
  179. {
  180. /* Success. */
  181. status = VG_LITE_SUCCESS;
  182. }
  183. }
  184. else
  185. {
  186. /* Try locking the mutex. */
  187. if (pthread_mutex_trylock(mutex))
  188. {
  189. /* Assume timeout. */
  190. status = VG_LITE_TIMEOUT;
  191. /* Loop while not timeout. */
  192. while (Timeout-- > 0)
  193. {
  194. /* Try locking the mutex. */
  195. if (pthread_mutex_trylock(mutex) == 0)
  196. {
  197. /* Success. */
  198. status = VG_LITE_SUCCESS;
  199. break;
  200. }
  201. /* Sleep 1 millisecond. */
  202. usleep(1000);
  203. }
  204. }
  205. else
  206. {
  207. /* Success. */
  208. status = VG_LITE_SUCCESS;
  209. }
  210. }
  211. #endif
  212. return status;
  213. }
  214. vg_lite_error_t
  215. vg_lite_ReleaseMutex(void *Mutex)
  216. {
  217. #ifdef _WIN32
  218. /* Validate the arguments. */
  219. assert(Mutex != NULL);
  220. /* Release the fast mutex. */
  221. if (!ReleaseMutex((void *) Mutex))
  222. {
  223. return VG_LITE_NOT_SUPPORT;
  224. }
  225. #elif defined(__ZEPHYR__)
  226. /* Validate the arguments. */
  227. assert(Mutex != NULL);
  228. k_mutex_unlock(Mutex);
  229. #else
  230. pthread_mutex_t *mutex;
  231. /* Validate the arguments. */
  232. assert(Mutex != NULL);
  233. /* Cast the pointer. */
  234. mutex = (pthread_mutex_t *) Mutex;
  235. /* Release the mutex. */
  236. pthread_mutex_unlock(mutex);
  237. #endif
  238. return VG_LITE_SUCCESS;
  239. }
  240. #define vglitemLOCKDUMP() \
  241. { \
  242. if (dump_mutex == NULL) \
  243. { \
  244. assert(vg_lite_CreateMutex(&dump_mutex) == VG_LITE_SUCCESS); \
  245. } \
  246. assert(vg_lite_AcquireMutex(dump_mutex, ((unsigned int) ~0U)) == VG_LITE_SUCCESS); \
  247. }
  248. #define vglitemUNLOCKDUMP() \
  249. assert(vg_lite_ReleaseMutex(dump_mutex) == VG_LITE_SUCCESS);
  250. #define STACK_THREAD_NUMBER 1
  251. static uint32_t _usedFileSlot = 0;
  252. static uint32_t _currentPos = 0;
  253. static vglitesDUMP_FILE_INFO _FileArray[STACK_THREAD_NUMBER];
  254. #define vglitemOPT_VALUE(ptr) (((ptr) == NULL) ? 0 : *(ptr))
  255. vg_lite_error_t vg_lite_PrintStrVSafe(
  256. char * String,
  257. size_t StringSize,
  258. unsigned int * Offset,
  259. const char * Format,
  260. va_list Arguments
  261. )
  262. {
  263. unsigned int offset = vglitemOPT_VALUE(Offset);
  264. vg_lite_error_t status = VG_LITE_SUCCESS;
  265. /* Verify the arguments. */
  266. assert(String != NULL);
  267. assert(StringSize > 0);
  268. assert(Format != NULL);
  269. if (offset < StringSize - 1)
  270. {
  271. /* Print into the string. */
  272. int n = vsnprintf(String + offset,
  273. StringSize - offset,
  274. Format,
  275. Arguments);
  276. if (n < 0 || n >= (int)(StringSize - offset))
  277. {
  278. status = VG_LITE_GENERIC_IO;
  279. }
  280. else if (Offset)
  281. {
  282. *Offset = offset + n;
  283. }
  284. }
  285. else
  286. {
  287. status = VG_LITE_OUT_OF_RESOURCES;
  288. }
  289. /* Success. */
  290. return status;
  291. }
  292. vg_lite_error_t vg_lite_PrintStrSafe(
  293. char * String,
  294. size_t StringSize,
  295. unsigned int * Offset,
  296. const char* Format,
  297. ...
  298. )
  299. {
  300. va_list arguments;
  301. vg_lite_error_t status = VG_LITE_SUCCESS;
  302. /* Verify the arguments. */
  303. assert(String != NULL);
  304. assert(StringSize > 0);
  305. assert(Format != NULL);
  306. /* Route through vgliteoOS_PrintStrVSafe. */
  307. va_start(arguments, Format);
  308. status = vg_lite_PrintStrVSafe(String, StringSize,
  309. Offset,
  310. Format, arguments);
  311. va_end(arguments);
  312. return status;
  313. }
  314. #if defined(__ZEPHYR__)
  315. void
  316. vg_lite_SetDebugFile(
  317. const char* FileName
  318. )
  319. {
  320. void *debugFile;
  321. if (FileName != NULL)
  322. {
  323. /* Don't change it to 'w' !!!*/
  324. debugFile = vg_lite_os_fopen(FileName, "a");
  325. if (debugFile)
  326. {
  327. _SetDumpFile(debugFile, 1);
  328. }
  329. }
  330. }
  331. #else
  332. void
  333. vg_lite_SetDebugFile(
  334. const char* FileName
  335. )
  336. {
  337. FILE *debugFile;
  338. if (FileName != NULL)
  339. {
  340. /* Don't change it to 'w' !!!*/
  341. debugFile = fopen(FileName, "a");
  342. if (debugFile)
  343. {
  344. _SetDumpFile(debugFile, 1);
  345. }
  346. }
  347. }
  348. #endif
  349. /******************************************************************************\
  350. ****************************** OS-dependent Macros *****************************
  351. \******************************************************************************/
  352. #ifdef __linux__
  353. # define vglitemGETTHREADID() \
  354. (uint32_t) pthread_self()
  355. # define vglitemGETPROCESSID() \
  356. getpid()
  357. #elif defined (__ZEPHYR__)
  358. # define vglitemGETTHREADID() \
  359. (uint32_t) k_current_get()
  360. # define vglitemGETPROCESSID() \
  361. (uint32_t) k_current_get()
  362. #else
  363. # define vglitemLOCKSECTION() \
  364. static HANDLE __lockHandle__; \
  365. \
  366. if (__lockHandle__ == NULL) \
  367. { \
  368. __lockHandle__ = CreateMutex(NULL, 0, NULL); \
  369. } \
  370. \
  371. WaitForSingleObject(__lockHandle__, INFINITE)
  372. # define vglitemUNLOCKSECTION() \
  373. ReleaseMutex(__lockHandle__)
  374. # define vglitemGETPROCESSID() \
  375. GetCurrentProcessId()
  376. # define vglitemGETTHREADID() \
  377. GetCurrentThreadId()
  378. #endif
  379. #if defined(__linux__) || defined (__ZEPHYR__)
  380. #ifdef __STRICT_ANSI__ /* ANSI C does not have snprintf, vsnprintf functions */
  381. # define vglitemSPRINTF(Destination, Size, Message, Value) \
  382. sprintf(Destination, Message, Value)
  383. # define vglitemVSPRINTF(Destination, Size, Message, Arguments) \
  384. vsprintf(Destination, Message, Arguments)
  385. #else
  386. # define vglitemSPRINTF(Destination, Size, Message, Value) \
  387. snprintf(Destination, Size, Message, Value)
  388. # define vglitemVSPRINTF(Destination, Size, Message, Arguments) \
  389. vsnprintf(Destination, Size, Message, Arguments)
  390. #endif
  391. # define vglitemSTRCAT(Destination, Size, String) \
  392. strncat(Destination, String, Size)
  393. #else
  394. # define vglitemSPRINTF(Destination, Size, Message, Value) \
  395. sprintf_s(Destination, Size, Message, Value)
  396. # define vglitemVSPRINTF(Destination, Size, Message, Arguments) \
  397. vsnprintf_s(Destination, Size, Size, Message, Arguments)
  398. # define vglitemSTRCAT(Destination, Size, String) \
  399. strcat_s(Destination, Size, String)
  400. #endif
  401. vg_lite_error_t vgliteoDUMP_SetDumpFlag(int DumpState)
  402. {
  403. DumpFlag = DumpState;
  404. return VG_LITE_SUCCESS;
  405. }
  406. #if defined(__ZEPHYR__)
  407. static void *_SetDumpFile(void *File, int CloseOldFile)
  408. {
  409. void *oldFile = NULL;
  410. uint32_t selfThreadID = vglitemGETTHREADID();
  411. uint32_t pos;
  412. uint32_t tmpCurPos;
  413. k_mutex_lock(&_dumpFileMutex, K_FOREVER);
  414. tmpCurPos = _currentPos;
  415. /* Find if this thread has already been recorded */
  416. for (pos = 0; pos < _usedFileSlot; pos++)
  417. {
  418. if (selfThreadID == _FileArray[pos]._threadID)
  419. {
  420. if (_FileArray[pos]._debugFile != NULL &&
  421. _FileArray[pos]._debugFile != File &&
  422. CloseOldFile)
  423. {
  424. /* Close the earliest existing file handle. */
  425. vg_lite_os_fclose(_FileArray[pos]._debugFile);
  426. _FileArray[pos]._debugFile = NULL;
  427. }
  428. oldFile = _FileArray[pos]._debugFile;
  429. /* Replace old file by new file */
  430. _FileArray[pos]._debugFile = File;
  431. goto exit;
  432. }
  433. }
  434. /* Test if we have exhausted our thread buffers. One thread one buffer. */
  435. if (tmpCurPos == STACK_THREAD_NUMBER)
  436. {
  437. goto error;
  438. }
  439. /* Record this new thread */
  440. _FileArray[tmpCurPos]._debugFile = File;
  441. _FileArray[tmpCurPos]._threadID = selfThreadID;
  442. _currentPos = ++tmpCurPos;
  443. if (_usedFileSlot < STACK_THREAD_NUMBER)
  444. {
  445. _usedFileSlot++;
  446. }
  447. exit:
  448. k_mutex_unlock(&_dumpFileMutex);
  449. return oldFile;
  450. error:
  451. k_mutex_unlock(&_dumpFileMutex);
  452. printf("ERROR: Not enough dump file buffers. Buffer num = %d", STACK_THREAD_NUMBER);
  453. return oldFile;
  454. }
  455. #else
  456. static FILE *_SetDumpFile(FILE *File, int CloseOldFile)
  457. {
  458. FILE *oldFile = NULL;
  459. uint32_t selfThreadID = vglitemGETTHREADID();
  460. uint32_t pos;
  461. uint32_t tmpCurPos;
  462. #ifdef _WIN32
  463. vglitemLOCKSECTION();
  464. #else
  465. pthread_mutex_lock(&_dumpFileMutex);
  466. #endif
  467. tmpCurPos = _currentPos;
  468. /* Find if this thread has already been recorded */
  469. for (pos = 0; pos < _usedFileSlot; pos++)
  470. {
  471. if (selfThreadID == _FileArray[pos]._threadID)
  472. {
  473. if (_FileArray[pos]._debugFile != NULL &&
  474. _FileArray[pos]._debugFile != File &&
  475. CloseOldFile)
  476. {
  477. /* Close the earliest existing file handle. */
  478. fclose(_FileArray[pos]._debugFile);
  479. _FileArray[pos]._debugFile = NULL;
  480. }
  481. oldFile = _FileArray[pos]._debugFile;
  482. /* Replace old file by new file */
  483. _FileArray[pos]._debugFile = File;
  484. goto exit;
  485. }
  486. }
  487. /* Test if we have exhausted our thread buffers. One thread one buffer. */
  488. if (tmpCurPos == STACK_THREAD_NUMBER)
  489. {
  490. goto error;
  491. }
  492. /* Record this new thread */
  493. _FileArray[tmpCurPos]._debugFile = File;
  494. _FileArray[tmpCurPos]._threadID = selfThreadID;
  495. _currentPos = ++tmpCurPos;
  496. if (_usedFileSlot < STACK_THREAD_NUMBER)
  497. {
  498. _usedFileSlot++;
  499. }
  500. #ifdef __linux__
  501. exit:
  502. pthread_mutex_unlock(&_dumpFileMutex);
  503. return oldFile;
  504. error:
  505. pthread_mutex_unlock(&_dumpFileMutex);
  506. printf("ERROR: Not enough dump file buffers. Buffer num = %d", STACK_THREAD_NUMBER);
  507. #else
  508. exit:
  509. vglitemUNLOCKSECTION();
  510. return oldFile;
  511. error:
  512. vglitemUNLOCKSECTION();
  513. printf("ERROR: Not enough dump file buffers. Buffer num = %d", STACK_THREAD_NUMBER);
  514. #endif
  515. return oldFile;
  516. }
  517. #endif
  518. #if defined(__ZEPHYR__)
  519. void * _GetDumpFile()
  520. {
  521. uint32_t selfThreadID;
  522. uint32_t pos = 0;
  523. void* retFile = NULL;
  524. k_mutex_lock(&_dumpFileMutex, K_FOREVER);
  525. if (_usedFileSlot == 0)
  526. {
  527. goto exit;
  528. }
  529. selfThreadID = vglitemGETTHREADID();
  530. for (; pos < _usedFileSlot; pos++)
  531. {
  532. if (selfThreadID == _FileArray[pos]._threadID)
  533. {
  534. retFile = _FileArray[pos]._debugFile;
  535. goto exit;
  536. }
  537. }
  538. exit:
  539. k_mutex_unlock(&_dumpFileMutex);
  540. return retFile;
  541. }
  542. #else
  543. FILE * _GetDumpFile()
  544. {
  545. uint32_t selfThreadID;
  546. uint32_t pos = 0;
  547. FILE* retFile = NULL;
  548. #ifdef __linux__
  549. pthread_mutex_lock(&_dumpFileMutex);
  550. #else
  551. vglitemLOCKSECTION();
  552. #endif
  553. if (_usedFileSlot == 0)
  554. {
  555. goto exit;
  556. }
  557. selfThreadID = vglitemGETTHREADID();
  558. for (; pos < _usedFileSlot; pos++)
  559. {
  560. if (selfThreadID == _FileArray[pos]._threadID)
  561. {
  562. retFile = _FileArray[pos]._debugFile;
  563. goto exit;
  564. }
  565. }
  566. exit:
  567. #ifdef __linux__
  568. pthread_mutex_unlock(&_dumpFileMutex);
  569. #else
  570. vglitemUNLOCKSECTION();
  571. #endif
  572. return retFile;
  573. }
  574. #endif
  575. #ifdef __linux__
  576. #define vglitemOUTPUT_STRING(File, String) \
  577. fprintf(((File == NULL) ? stderr : File), "%s", String);
  578. #elif defined (__ZEPHYR__)
  579. #define vglitemOUTPUT_STRING(File, String) \
  580. { \
  581. printk("%s", String); \
  582. }
  583. #else
  584. #define vglitemOUTPUT_STRING(File, String) \
  585. if (File != NULL) { \
  586. fprintf(File, "%s", String); \
  587. } else { \
  588. OutputDebugString(String); \
  589. }
  590. #endif
  591. static void OutputString(FILE *File, const char *String)
  592. {
  593. if (String != NULL) {
  594. vglitemOUTPUT_STRING(File, String);
  595. }
  596. }
  597. static void _Print(FILE *File, const char *Message, va_list Arguments)
  598. {
  599. /* Output to file or debugger. */
  600. int i, j, n, indent;
  601. static char buffer[4096];
  602. vglitesBUFFERED_OUTPUT_PTR outputBuffer = NULL;
  603. #ifdef _WIN32
  604. static uint32_t prevThreadID;
  605. uint32_t threadID;
  606. vglitemLOCKSECTION();
  607. /* Get the current thread ID. */
  608. threadID = vglitemGETTHREADID();
  609. #elif defined(__ZEPHYR__)
  610. k_mutex_lock(&_printMutex, K_FOREVER);
  611. #else
  612. pthread_mutex_lock(&_printMutex);
  613. #endif
  614. /* Initialize output buffer list. */
  615. if (_outputBufferHead == NULL)
  616. {
  617. for (i = 0; i < 1; i += 1)
  618. {
  619. if (_outputBufferTail == NULL)
  620. {
  621. _outputBufferHead = &_outputBuffer[i];
  622. }
  623. else
  624. {
  625. _outputBufferTail->next = &_outputBuffer[i];
  626. }
  627. _outputBuffer[i].prev = _outputBufferTail;
  628. _outputBuffer[i].next = NULL;
  629. _outputBufferTail = &_outputBuffer[i];
  630. }
  631. }
  632. outputBuffer = _outputBufferHead;
  633. #ifdef _Win32
  634. /* Update the previous thread value. */
  635. prevThreadID = threadID;
  636. #endif
  637. if (strcmp(Message, "$$FLUSH$$") == 0)
  638. {
  639. OutputString(File, NULL);
  640. #ifdef _WIN32
  641. vglitemUNLOCKSECTION();
  642. #elif defined(__ZEPHYR__)
  643. k_mutex_unlock(&_printMutex);
  644. #else
  645. pthread_mutex_unlock(&_printMutex);
  646. #endif
  647. return;
  648. }
  649. i = 0;
  650. if (strncmp(Message, "--", 2) == 0)
  651. {
  652. if (outputBuffer->indent == 0)
  653. {
  654. OutputString(File,"ERROR: indent=0\n");
  655. }
  656. outputBuffer->indent -= 2;
  657. }
  658. indent = outputBuffer->indent % 40;
  659. for (j = 0; j < indent; ++j)
  660. {
  661. buffer[i++] = ' ';
  662. }
  663. if (indent != outputBuffer->indent)
  664. {
  665. i += vglitemSPRINTF(
  666. buffer + i, sizeof(buffer) - i, " <%d> ", outputBuffer->indent
  667. );
  668. buffer[sizeof(buffer) - 1] = '\0';
  669. }
  670. /* Print message to buffer. */
  671. n = vglitemVSPRINTF(buffer + i, sizeof(buffer) - i, Message, Arguments);
  672. buffer[sizeof(buffer) - 1] = '\0';
  673. if ((n <= 0) || (buffer[i + n - 1] != '\n'))
  674. {
  675. /* Append new-line. */
  676. vglitemSTRCAT(buffer, sizeof(buffer) - strlen(buffer) - 1, "\n");
  677. buffer[sizeof(buffer) - 1] = '\0';
  678. }
  679. /* Output to debugger. */
  680. OutputString(File, buffer);
  681. if (strncmp(Message, "++", 2) == 0)
  682. {
  683. outputBuffer->indent += 2;
  684. }
  685. #ifdef __linux__
  686. pthread_mutex_unlock(&_printMutex);
  687. #elif defined(__ZEPHYR__)
  688. k_mutex_unlock(&_printMutex);
  689. #else
  690. vglitemUNLOCKSECTION();
  691. #endif
  692. }
  693. #define vglitemDEBUGPRINT(FileHandle, Message) \
  694. { \
  695. va_list arguments; \
  696. va_start(arguments, Message); \
  697. _Print(FileHandle, Message, arguments); \
  698. va_end(arguments); \
  699. }
  700. void vgliteoOS_Print(const char * Message, ...)
  701. {
  702. vglitemDEBUGPRINT(_GetDumpFile(), Message);
  703. }
  704. void _SetDumpFileInfo()
  705. {
  706. #define DUMP_FILE_PREFIX "hal"
  707. char dump_file[128];
  708. unsigned int offset = 0;
  709. /* Customize filename as needed. */
  710. vg_lite_PrintStrSafe(dump_file,
  711. sizeof(dump_file),
  712. &offset,
  713. "%s%s_dump_pid-%d_tid-%d_%s.log",
  714. vgliteDUMP_PATH,
  715. DUMP_FILE_PREFIX,
  716. #ifdef _WIN32
  717. (void *)(uintptr_t)(GetCurrentProcessId()),
  718. (void *)(uintptr_t)GetCurrentThreadId(),
  719. #elif defined(__ZEPHYR__)
  720. (void *)(uintptr_t)k_current_get(),
  721. (void *)(uintptr_t)k_current_get(),
  722. #else
  723. (void *)(uintptr_t)getpid(),
  724. (void *)pthread_self(),
  725. #endif
  726. vgliteDUMP_KEY);
  727. vg_lite_SetDebugFile(dump_file);
  728. vgliteoDUMP_SetDumpFlag(1);
  729. }
  730. vg_lite_error_t vglitefDump(char * Message, ...)
  731. {
  732. vg_lite_error_t status = VG_LITE_SUCCESS;
  733. unsigned offset = 0;
  734. va_list args;
  735. char buffer[180];
  736. if (!DumpFlag)
  737. {
  738. return status;
  739. }
  740. va_start(args, Message);
  741. status = vg_lite_PrintStrVSafe(buffer, sizeof(buffer),
  742. &offset,
  743. Message, args);
  744. assert(status == VG_LITE_SUCCESS);
  745. va_end(args);
  746. vgliteoOS_Print("%s", buffer);;
  747. return status;
  748. }
  749. vg_lite_error_t vglitefDumpBuffer(char *Tag, size_t Physical, void * Logical, size_t Offset, size_t Bytes)
  750. {
  751. unsigned int * ptr = (unsigned int *) Logical + (Offset >> 2);
  752. size_t bytes = vglitemALIGN(Bytes + (Offset & 3), 4);
  753. if (!DumpFlag)
  754. {
  755. return VG_LITE_SUCCESS;
  756. }
  757. vglitemLOCKDUMP();
  758. #if !DUMP_COMMAND_CAPTURE
  759. vglitemDUMP("@[%s 0x%08X 0x%08X", Tag, Physical + (Offset & ~3), bytes);
  760. #endif
  761. while (bytes >= 16)
  762. {
  763. #if !DUMP_COMMAND_CAPTURE
  764. vglitemDUMP(" 0x%08X 0x%08X 0x%08X 0x%08X",
  765. ptr[0], ptr[1], ptr[2], ptr[3]);
  766. #else
  767. vglitemDUMP(" 0x%08X", ptr[0]);
  768. vglitemDUMP(" 0x%08X", ptr[1]);
  769. if (bytes == 16 && (ptr[2] == 0) && (ptr[3] == 0))
  770. {
  771. printf("This two commands is 0x00000000\n");
  772. }
  773. else {
  774. vglitemDUMP(" 0x%08X", ptr[2]);
  775. vglitemDUMP(" 0x%08X", ptr[3]);
  776. }
  777. #endif
  778. ptr += 4;
  779. bytes -= 16;
  780. }
  781. switch (bytes)
  782. {
  783. case 12:
  784. #if !DUMP_COMMAND_CAPTURE
  785. vglitemDUMP(" 0x%08X 0x%08X 0x%08X", ptr[0], ptr[1], ptr[2]);
  786. #else
  787. vglitemDUMP(" 0x%08X", ptr[0]);
  788. if ((ptr[1] == 0) && (ptr[2] == 0))
  789. {
  790. printf("This two commands is 0x00000000\n");
  791. }
  792. else
  793. {
  794. vglitemDUMP(" 0x%08X", ptr[1]);
  795. vglitemDUMP(" 0x%08X", ptr[2]);
  796. }
  797. #endif
  798. break;
  799. case 8:
  800. #if !DUMP_COMMAND_CAPTURE
  801. vglitemDUMP(" 0x%08X 0x%08X", ptr[0], ptr[1]);
  802. #else
  803. if ((ptr[0] == 0) && (ptr[1] == 0))
  804. {
  805. printf("This two commands is 0x00000000\n");
  806. }
  807. else
  808. {
  809. vglitemDUMP(" 0x%08X", ptr[0]);
  810. vglitemDUMP(" 0x%08X", ptr[1]);
  811. }
  812. #endif
  813. break;
  814. case 4:
  815. vglitemDUMP(" 0x%08X", ptr[0]);
  816. break;
  817. }
  818. #if !DUMP_COMMAND_CAPTURE
  819. vglitemDUMP("] -- %s", Tag);
  820. #else
  821. vglitemDUMP("---This command end----");
  822. #endif
  823. vglitemUNLOCKDUMP();
  824. return VG_LITE_SUCCESS;
  825. }
  826. #endif /* DUMP_CAPTURE */
  827. #if DUMP_LAST_CAPTURE
  828. vg_lite_error_t vglitefDumpBuffer_single(char* Tag, size_t Physical, void* Logical, size_t Offset, size_t Bytes)
  829. {
  830. unsigned int* ptr = (unsigned int*)Logical + (Offset >> 2);
  831. size_t bytes = vglitemALIGN(Bytes + (Offset & 3), 4);
  832. if (!DumpFlag)
  833. {
  834. return VG_LITE_SUCCESS;
  835. }
  836. vglitemLOCKDUMP();
  837. #if !DUMP_COMMAND_CAPTURE
  838. vglitemDUMP_single("@[%s 0x%08X 0x%08X", Tag, Physical + (Offset & ~3), bytes);
  839. #endif
  840. while (bytes >= 16)
  841. {
  842. #if !DUMP_COMMAND_CAPTURE
  843. vglitemDUMP_single(" 0x%08X 0x%08X 0x%08X 0x%08X",
  844. ptr[0], ptr[1], ptr[2], ptr[3]);
  845. #else
  846. vglitemDUMP(" 0x%08X", ptr[0]);
  847. vglitemDUMP(" 0x%08X", ptr[1]);
  848. if (bytes == 16 && (ptr[2] == 0) && (ptr[3] == 0))
  849. {
  850. printf("This two commands is 0x00000000\n");
  851. }
  852. else {
  853. vglitemDUMP(" 0x%08X", ptr[2]);
  854. vglitemDUMP(" 0x%08X", ptr[3]);
  855. }
  856. #endif
  857. ptr += 4;
  858. bytes -= 16;
  859. }
  860. switch (bytes)
  861. {
  862. case 12:
  863. #if !DUMP_COMMAND_CAPTURE
  864. vglitemDUMP_single(" 0x%08X 0x%08X 0x%08X", ptr[0], ptr[1], ptr[2]);
  865. #else
  866. vglitemDUMP(" 0x%08X", ptr[0]);
  867. if ((ptr[1] == 0) && (ptr[2] == 0))
  868. {
  869. printf("This two commands is 0x00000000\n");
  870. }
  871. else
  872. {
  873. vglitemDUMP(" 0x%08X", ptr[1]);
  874. vglitemDUMP(" 0x%08X", ptr[2]);
  875. }
  876. #endif
  877. break;
  878. case 8:
  879. #if !DUMP_COMMAND_CAPTURE
  880. vglitemDUMP_single(" 0x%08X 0x%08X", ptr[0], ptr[1]);
  881. #else
  882. if ((ptr[0] == 0) && (ptr[1] == 0))
  883. {
  884. printf("This two commands is 0x00000000\n");
  885. }
  886. else
  887. {
  888. vglitemDUMP(" 0x%08X", ptr[0]);
  889. vglitemDUMP(" 0x%08X", ptr[1]);
  890. }
  891. #endif
  892. break;
  893. case 4:
  894. vglitemDUMP_single(" 0x%08X", ptr[0]);
  895. break;
  896. }
  897. #if !DUMP_COMMAND_CAPTURE
  898. vglitemDUMP_single("] -- %s", Tag);
  899. #else
  900. vglitemDUMP("---This command end----");
  901. #endif
  902. vglitemUNLOCKDUMP();
  903. return VG_LITE_SUCCESS;
  904. }
  905. #endif
  906. vg_lite_error_t vg_lite_dump_png(const char *name, vg_lite_buffer_t *buffer)
  907. {
  908. vg_lite_error_t status = VG_LITE_SUCCESS;
  909. #ifdef __linux__
  910. uint8_t *memory, *p, *q;
  911. int x, y;
  912. png_image image;
  913. uint16_t color;
  914. if (buffer->format == VG_LITE_L8) {
  915. /* Construct the PNG image structure. */
  916. png_image image;
  917. memset(&image, 0, (sizeof image));
  918. image.version = PNG_IMAGE_VERSION;
  919. image.width = buffer->width;
  920. image.height = buffer->height;
  921. image.format = PNG_FORMAT_GRAY;
  922. /* Write the PNG image. */
  923. return png_image_write_to_file(&image, name, 0, buffer->memory, buffer->stride, NULL);
  924. }
  925. /* Allocate RGB memory buffer. */
  926. memory = malloc(buffer->width * buffer->height * 3);
  927. if (memory == NULL) {
  928. return VG_LITE_OUT_OF_RESOURCES;
  929. }
  930. for (y = 0; y < buffer->height; y++) {
  931. p = (uint8_t*) buffer->memory + y * buffer->stride;
  932. q = memory + y * buffer->width * 3;
  933. for (x = 0; x < buffer->width; x++, q += 3) {
  934. switch (buffer->format) {
  935. case VG_LITE_RGBA5658_PLANAR:
  936. case VG_LITE_ARGB8565_PLANAR:
  937. case VG_LITE_RGB565:
  938. color = *(uint16_t *)p;
  939. p += 2;
  940. q[0] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  941. q[1] = ((color & 0x07E0) >> 3) | ((color & 0x0600) >> 9);
  942. q[2] = ((color & 0xF800) >> 8) | ((color & 0xE000) >> 13);
  943. break;
  944. case VG_LITE_ABGR8565_PLANAR:
  945. case VG_LITE_BGRA5658_PLANAR:
  946. case VG_LITE_BGR565:
  947. case OPENVG_sRGB_565:
  948. case OPENVG_sRGB_565_PRE:
  949. case OPENVG_lRGB_565:
  950. case OPENVG_lRGB_565_PRE:
  951. color = *(uint16_t *)p;
  952. p += 2;
  953. q[0] = ((color & 0xF800) >> 8) | ((color & 0xE000) >> 13);
  954. q[1] = ((color & 0x07E0) >> 3) | ((color & 0x0600) >> 9);
  955. q[2] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  956. break;
  957. case VG_LITE_ABGR8565:
  958. p += 1;
  959. color = *(uint8_t *)p | *(uint8_t *)(p + 1) << 8;
  960. p += 2;
  961. q[0] = ((color & 0xF800) >> 8) | ((color & 0xE000) >> 13);
  962. q[1] = ((color & 0x07E0) >> 3) | ((color & 0x0600) >> 9);
  963. q[2] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  964. break;
  965. case VG_LITE_BGRA5658:
  966. color = *(uint8_t *)p | *(uint8_t *)(p + 1) << 8;
  967. p += 3;
  968. q[0] = ((color & 0xF800) >> 8) | ((color & 0xE000) >> 13);
  969. q[1] = ((color & 0x07E0) >> 3) | ((color & 0x0600) >> 9);
  970. q[2] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  971. break;
  972. case VG_LITE_ARGB8565:
  973. p += 1;
  974. color = *(uint8_t *)p | *(uint8_t *)(p + 1) << 8;
  975. p += 2;
  976. q[0] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  977. q[1] = ((color & 0x07E0) >> 3) | ((color & 0x0600) >> 9);
  978. q[2] = ((color & 0xF800) >> 8) | ((color & 0xE000) >> 13);
  979. break;
  980. case VG_LITE_RGBA5658:
  981. color = *(uint8_t *)p | *(uint8_t *)(p + 1) << 8;
  982. p += 3;
  983. q[0] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  984. q[1] = ((color & 0x07E0) >> 3) | ((color & 0x0600) >> 9);
  985. q[2] = ((color & 0xF800) >> 8) | ((color & 0xE000) >> 13);
  986. break;
  987. case VG_LITE_RGB888:
  988. q[0] = p[0];
  989. q[1] = p[1];
  990. q[2] = p[2];
  991. p += 3;
  992. break;
  993. case VG_LITE_BGR888:
  994. q[0] = p[2];
  995. q[1] = p[1];
  996. q[2] = p[0];
  997. p += 3;
  998. break;
  999. case VG_LITE_RGBA8888:
  1000. case VG_LITE_RGBX8888:
  1001. case OPENVG_sABGR_8888:
  1002. case OPENVG_sXBGR_8888:
  1003. q[0] = p[0];
  1004. q[1] = p[1];
  1005. q[2] = p[2];
  1006. p += 4;
  1007. break;
  1008. case VG_LITE_ARGB8888:
  1009. case VG_LITE_XRGB8888:
  1010. case OPENVG_sBGRA_8888:
  1011. case OPENVG_sBGRX_8888:
  1012. q[0] = p[1];
  1013. q[1] = p[2];
  1014. q[2] = p[3];
  1015. p += 4;
  1016. break;
  1017. case VG_LITE_BGRA8888:
  1018. case VG_LITE_BGRX8888:
  1019. case OPENVG_sARGB_8888:
  1020. case OPENVG_sXRGB_8888:
  1021. q[0] = p[2];
  1022. q[1] = p[1];
  1023. q[2] = p[0];
  1024. p += 4;
  1025. break;
  1026. case VG_LITE_ABGR8888:
  1027. case VG_LITE_XBGR8888:
  1028. case OPENVG_sRGBA_8888:
  1029. case OPENVG_sRGBX_8888:
  1030. q[0] = p[3];
  1031. q[1] = p[2];
  1032. q[2] = p[1];
  1033. p += 4;
  1034. break;
  1035. case VG_LITE_RGBA4444:
  1036. case OPENVG_sABGR_4444:
  1037. color = *(uint16_t*)p;
  1038. p += 2;
  1039. q[0] = (color & 0x000F) << 4;
  1040. q[1] = (color & 0x00F0);
  1041. q[2] = (color & 0x0F00) >> 4;
  1042. break;
  1043. case VG_LITE_BGRA4444:
  1044. case OPENVG_sARGB_4444:
  1045. color = *(uint16_t*)p;
  1046. p += 2;
  1047. q[2] = (color & 0x000F) << 4;
  1048. q[1] = (color & 0x00F0);
  1049. q[0] = (color & 0x0F00) >> 4;
  1050. break;
  1051. case VG_LITE_ABGR4444:
  1052. case OPENVG_sRGBA_4444:
  1053. color = *(uint16_t*)p;
  1054. color = (color >> 4);
  1055. p += 2;
  1056. q[2] = (color & 0x000F) << 4;
  1057. q[1] = (color & 0x00F0);
  1058. q[0] = (color & 0x0F00) >> 4;
  1059. break;
  1060. case VG_LITE_ARGB4444:
  1061. case OPENVG_sBGRA_4444:
  1062. color = *(uint16_t*)p;
  1063. color = (color >> 4);
  1064. p += 2;
  1065. q[0] = (color & 0x000F) << 4;
  1066. q[1] = (color & 0x00F0);
  1067. q[2] = (color & 0x0F00) >> 4;
  1068. break;
  1069. case VG_LITE_BGRA5551:
  1070. case OPENVG_sARGB_1555:
  1071. color = *(uint16_t*)p;
  1072. p += 2;
  1073. q[0] = ((color & 0x7C00) >> 7) | ((color & 0x7000) >> 12);
  1074. q[1] = ((color & 0x03E0) >> 2) | ((color & 0x0380) >> 7);
  1075. q[2] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  1076. break;
  1077. case VG_LITE_ABGR1555:
  1078. case OPENVG_sRGBA_5551:
  1079. color = *(uint16_t*)p;
  1080. color = (color >> 1);
  1081. p += 2;
  1082. q[0] = ((color & 0x7C00) >> 7) | ((color & 0x7000) >> 12);
  1083. q[1] = ((color & 0x03E0) >> 2) | ((color & 0x0380) >> 7);
  1084. q[2] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  1085. break;
  1086. case VG_LITE_RGBA5551:
  1087. case OPENVG_sABGR_1555:
  1088. color = *(uint16_t*)p;
  1089. p += 2;
  1090. q[2] = ((color & 0x7C00) >> 7) | ((color & 0x7000) >> 12);
  1091. q[1] = ((color & 0x03E0) >> 2) | ((color & 0x0380) >> 7);
  1092. q[0] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  1093. break;
  1094. case VG_LITE_ARGB1555:
  1095. case OPENVG_sBGRA_5551:
  1096. color = *(uint16_t*)p;
  1097. color = (color >> 1);
  1098. p += 2;
  1099. q[2] = ((color & 0x7C00) >> 7) | ((color & 0x7000) >> 12);
  1100. q[1] = ((color & 0x03E0) >> 2) | ((color & 0x0380) >> 7);
  1101. q[0] = ((color & 0x001F) << 3) | ((color & 0x001C) >> 2);
  1102. break;
  1103. case VG_LITE_RGBA2222:
  1104. color = *(uint8_t*)p;
  1105. p += 1;
  1106. q[0] = (color & 0x03) << 2 | (color & 0x03) << 4 | (color & 0x03) << 6 |(color & 0x03);
  1107. q[1] = (color & 0x0C) << 2 | (color & 0x0C) << 4 | (color & 0x0C) << 6 |(color & 0x0C);
  1108. q[2] = (color & 0x30) << 2 | (color & 0x30) << 4 | (color & 0x30) << 6 |(color & 0x30);
  1109. break;
  1110. case VG_LITE_BGRA2222:
  1111. color = *(uint8_t*)p;
  1112. p += 1;
  1113. q[2] = (color & 0x03) << 2 | (color & 0x03) << 4 | (color & 0x03) << 6 |(color & 0x03);
  1114. q[1] = (color & 0x0C) << 2 | (color & 0x0C) << 4 | (color & 0x0C) << 6 |(color & 0x0C);
  1115. q[0] = (color & 0x30) << 2 | (color & 0x30) << 4 | (color & 0x30) << 6 |(color & 0x30);
  1116. break;
  1117. case VG_LITE_ARGB2222:
  1118. color = *(uint8_t*)p;
  1119. p += 1;
  1120. q[0] = (color & 0x0C) << 2 | (color & 0x0C) << 4 | (color & 0x0C) << 6 |(color & 0x0C);
  1121. q[1] = (color & 0x30) << 2 | (color & 0x30) << 4 | (color & 0x30) << 6 |(color & 0x30);
  1122. q[2] = (color & 0xC0) << 2 | (color & 0xC0) << 4 | (color & 0xC0) << 6 |(color & 0xC0);
  1123. break;
  1124. case VG_LITE_ABGR2222:
  1125. color = *(uint8_t*)p;
  1126. p += 1;
  1127. q[2] = (color & 0x0C) << 2 | (color & 0x0C) << 4 | (color & 0x0C) << 6 |(color & 0x0C);
  1128. q[1] = (color & 0x30) << 2 | (color & 0x30) << 4 | (color & 0x30) << 6 |(color & 0x30);
  1129. q[0] = (color & 0xC0) << 2 | (color & 0xC0) << 4 | (color & 0xC0) << 6 |(color & 0xC0);
  1130. break;
  1131. case VG_LITE_A8:
  1132. case VG_LITE_L8:
  1133. q[0] = q[1] = q[2] = p[0];
  1134. p++;
  1135. break;
  1136. case VG_LITE_YUYV:
  1137. /* YUYV not supported yet. */
  1138. default:
  1139. break;
  1140. }
  1141. }
  1142. }
  1143. /* Construct the PNG image structure. */
  1144. memset(&image, 0, (sizeof image));
  1145. image.version = PNG_IMAGE_VERSION;
  1146. image.width = buffer->width;
  1147. image.height = buffer->height;
  1148. image.format = PNG_FORMAT_RGB;
  1149. /* Write the PNG image. */
  1150. status = png_image_write_to_file(&image, name, 0, memory, buffer->width * 3, NULL);
  1151. /* Free the RGB memory buffer.*/
  1152. free(memory);
  1153. #endif /* __linux__ */
  1154. /* Success. */
  1155. return status;
  1156. }