vg_lite_path.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright 2012 - 2020 Vivante Corporation, Santa Clara, California.
  6. * All Rights Reserved.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining
  9. * a copy of this software and associated documentation files (the
  10. * 'Software'), to deal in the Software without restriction, including
  11. * without limitation the rights to use, copy, modify, merge, publish,
  12. * distribute, sub license, and/or sell copies of the Software, and to
  13. * permit persons to whom the Software is furnished to do so, subject
  14. * to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice (including the
  17. * next paragraph) shall be included in all copies or substantial
  18. * portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  21. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  23. * IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
  24. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. *
  28. *****************************************************************************/
  29. #include <stddef.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include "vg_lite.h"
  34. vg_lite_error_t vg_lite_upload_path(vg_lite_path_t * path)
  35. {
  36. uint32_t bytes;
  37. vg_lite_buffer_t Buf, *buffer;
  38. buffer = &Buf;
  39. /* Compute the number of bytes required for path + command buffer prefix/postfix. */
  40. bytes = (8 + path->path_length + 7 + 8) & ~7;
  41. /* Allocate GPU memory. */
  42. buffer->width = bytes;
  43. buffer->height = 1;
  44. buffer->stride = 0;
  45. buffer->format = VG_LITE_A8;
  46. if (vg_lite_allocate(buffer) != VG_LITE_SUCCESS) {
  47. return VG_LITE_OUT_OF_MEMORY;
  48. }
  49. /* Initialize command buffer prefix. */
  50. ((uint32_t *) buffer->memory)[0] = 0x40000000 | ((path->path_length + 7) / 8);
  51. ((uint32_t *) buffer->memory)[1] = 0;
  52. /* Copy the path data. */
  53. memcpy((uint32_t *) buffer->memory + 2, path->path, path->path_length);
  54. /* Initialize command buffer postfix. */
  55. ((uint32_t *) buffer->memory)[bytes / 4 - 2] = 0x70000000;
  56. ((uint32_t *) buffer->memory)[bytes / 4 - 1] = 0;
  57. /* Mark path as uploaded. */
  58. path->uploaded.handle = buffer->handle;
  59. path->uploaded.address = buffer->address;
  60. path->uploaded.memory = buffer->memory;
  61. path->uploaded.bytes = bytes;
  62. path->path_changed = 0;
  63. VLM_PATH_ENABLE_UPLOAD(*path); /* Implicitly enable path uploading. */
  64. /* Return pointer to vg_lite_buffer structure. */
  65. return VG_LITE_SUCCESS;
  66. }
  67. /* Path data operations. */
  68. #define CDALIGN(value, by) (((value) + (by) - 1) & ~((by) - 1))
  69. #define CDMIN(x, y) ((x) > (y) ? (y) : (x))
  70. #define CDMAX(x, y) ((x) > (y) ? (x) : (y))
  71. static int32_t get_data_count(uint8_t cmd)
  72. {
  73. static int32_t count[] = {
  74. 0,
  75. 0,
  76. 2,
  77. 2,
  78. 2,
  79. 2,
  80. 4,
  81. 4,
  82. 6,
  83. 6,
  84. 5,
  85. 5,
  86. 5,
  87. 5,
  88. 5,
  89. 5,
  90. 5,
  91. 5
  92. };
  93. if (cmd > VLC_OP_LCWARC_REL) {
  94. return -1;
  95. }
  96. else {
  97. return count[cmd];
  98. }
  99. }
  100. static void compute_pathbounds(float *xmin, float *ymin, float *xmax, float *ymax, float x, float y)
  101. {
  102. if (xmin != NULL)
  103. {
  104. *xmin = *xmin < x ? *xmin : x;
  105. }
  106. if (xmax != NULL)
  107. {
  108. *xmax = *xmax > x ? *xmax : x;
  109. }
  110. if (ymin != NULL)
  111. {
  112. *ymin = *ymin < y ? *ymin : y;
  113. }
  114. if (ymax != NULL)
  115. {
  116. *ymax = *ymax > y ? *ymax : y;
  117. }
  118. }
  119. static int32_t get_data_size(vg_lite_format_t format)
  120. {
  121. int32_t data_size = 0;
  122. switch (format) {
  123. case VG_LITE_S8:
  124. data_size = sizeof(int8_t);
  125. break;
  126. case VG_LITE_S16:
  127. data_size = sizeof(int16_t);
  128. break;
  129. case VG_LITE_S32:
  130. data_size = sizeof(int32_t);
  131. break;
  132. default:
  133. data_size = sizeof(vg_lite_float_t);
  134. break;
  135. }
  136. return data_size;
  137. }
  138. int32_t vg_lite_path_calc_length(uint8_t *cmd, uint32_t count, vg_lite_format_t format)
  139. {
  140. int32_t size = 0;
  141. int32_t dCount = 0;
  142. uint32_t i = 0;
  143. int32_t data_size = 0;
  144. data_size = get_data_size(format);
  145. for (i = 0; i < count; i++) {
  146. size++; /* OP CODE. */
  147. dCount = get_data_count(cmd[i]);
  148. if (dCount > 0) {
  149. size = CDALIGN(size, data_size);
  150. size += dCount * data_size;
  151. }
  152. }
  153. return size;
  154. }
  155. vg_lite_error_t vg_lite_path_append(vg_lite_path_t *path,
  156. uint8_t *cmd,
  157. void *data,
  158. uint32_t seg_count)
  159. {
  160. vg_lite_error_t error = VG_LITE_SUCCESS;
  161. uint32_t i;
  162. int32_t j;
  163. int32_t offset = 0;
  164. int32_t dataCount = 0;
  165. float *dataf = (float*) data;
  166. float *pathf = NULL;
  167. int32_t *data_s32 = (int32_t*) data;
  168. int32_t *path_s32 = NULL;
  169. int16_t *data_s16 = (int16_t*) data;
  170. int16_t *path_s16 = NULL;
  171. int8_t *data_s8 = (int8_t*) data;
  172. int8_t *path_s8 = NULL;
  173. uint8_t *pathc = NULL;
  174. int32_t data_size;
  175. uint8_t arc_path = 0;
  176. float px = 0.0f, py = 0.0f, cx = 0.0f, cy = 0.0f;
  177. int rel = 0;
  178. if(cmd == NULL || data == NULL || path == NULL || path->path == NULL)
  179. return VG_LITE_INVALID_ARGUMENT;
  180. for(i = 0; i < seg_count; i++) {
  181. if(cmd[i] > VLC_OP_LCWARC_REL)
  182. return VG_LITE_INVALID_ARGUMENT;
  183. }
  184. data_size = get_data_size(path->format);
  185. path->path_changed= 1;
  186. pathf = (float *)path->path;
  187. path_s32 = (int32_t *)path->path;
  188. path_s16 = (int16_t *)path->path;
  189. path_s8 = (int8_t *)path->path;
  190. pathc = (uint8_t *)path->path;
  191. /* Loop to fill path data. */
  192. for (i = 0; i < seg_count; i++) {
  193. *(pathc + offset) = cmd[i];
  194. offset++;
  195. dataCount = get_data_count(cmd[i]);
  196. if (dataCount > 0) {
  197. offset = CDALIGN(offset, data_size);
  198. if ((cmd[i] > VLC_OP_CLOSE) &&
  199. ((cmd[i] & 0x01) == 1)){
  200. rel = 1;
  201. }
  202. else {
  203. rel = 0;
  204. }
  205. if(cmd[i] < VLC_OP_SCCWARC) {
  206. for (j = 0; j < dataCount / 2; j++) {
  207. switch (path->format) {
  208. case VG_LITE_S8:
  209. path_s8 = (int8_t *)(pathc + offset);
  210. path_s8[j * 2] = *data_s8++;
  211. path_s8[j * 2 + 1] = *data_s8++;
  212. if (rel) {
  213. cx = px + path_s8[j * 2];
  214. cy = py + path_s8[j * 2 + 1];
  215. }
  216. else {
  217. cx = path_s8[j * 2];
  218. cy = path_s8[j * 2 + 1];
  219. }
  220. break;
  221. case VG_LITE_S16:
  222. path_s16 = (int16_t *)(pathc + offset);
  223. path_s16[j * 2] = *data_s16++;
  224. path_s16[j * 2 + 1] = *data_s16++;
  225. if (rel) {
  226. cx = px + path_s16[j * 2];
  227. cy = py + path_s16[j * 2 + 1];
  228. }
  229. else {
  230. cx = path_s16[j * 2];
  231. cy = path_s16[j * 2 + 1];
  232. }
  233. break;
  234. case VG_LITE_S32:
  235. path_s32 = (int32_t *)(pathc + offset);
  236. path_s32[j * 2] = *data_s32++;
  237. path_s32[j * 2 + 1] = *data_s32++;
  238. if (rel) {
  239. cx = px + path_s32[j * 2];
  240. cy = py + path_s32[j * 2 + 1];
  241. }
  242. else {
  243. cx = path_s32[j * 2];
  244. cy = path_s32[j * 2 + 1];
  245. }
  246. break;
  247. case VG_LITE_FP32:
  248. pathf = (float *)(pathc + offset);
  249. pathf[j * 2] = *dataf++;
  250. pathf[j * 2 + 1] = *dataf++;
  251. if (rel) {
  252. cx = px + pathf[j * 2];
  253. cy = py + pathf[j * 2 + 1];
  254. }
  255. else {
  256. cx = pathf[j * 2];
  257. cy = pathf[j * 2 + 1];
  258. }
  259. break;
  260. default:
  261. return VG_LITE_INVALID_ARGUMENT;
  262. }
  263. /* Update path bounds. */
  264. path->bounding_box[0] = CDMIN(path->bounding_box[0], cx);
  265. path->bounding_box[2] = CDMAX(path->bounding_box[2], cx);
  266. path->bounding_box[1] = CDMIN(path->bounding_box[1], cy);
  267. path->bounding_box[3] = CDMAX(path->bounding_box[3], cy);
  268. }
  269. }
  270. else {
  271. arc_path = 1;
  272. pathf = (float *)(pathc + offset);
  273. pathf[0] = *dataf++;
  274. pathf[1] = *dataf++;
  275. pathf[2] = *dataf++;
  276. pathf[3] = *dataf++;
  277. pathf[4] = *dataf++;
  278. if (rel) {
  279. cx = px + pathf[3];
  280. cy = py + pathf[4];
  281. }
  282. else {
  283. cx = pathf[3];
  284. cy = pathf[4];
  285. }
  286. /* Update path bounds. */
  287. compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx + 2 * pathf[0],cy + 2 * pathf[1]);
  288. compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px + 2 * pathf[1],py + 2 * pathf[1]);
  289. compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx - 2 * pathf[0],cy - 2 * pathf[1]);
  290. compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px - 2 * pathf[1],py - 2 * pathf[1]);
  291. }
  292. px = cx;
  293. py = cy;
  294. offset += dataCount * data_size;
  295. }
  296. }
  297. path->path_length = offset;
  298. if(arc_path) {
  299. error = vg_lite_init_arc_path(path,
  300. VG_LITE_FP32,
  301. path->quality,
  302. path->path_length,
  303. path->path,
  304. path->bounding_box[0], path->bounding_box[1],
  305. path->bounding_box[2], path->bounding_box[3]);
  306. }
  307. return error;
  308. }