trap.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. /* libs/pixelflinger/trap.cpp
  2. **
  3. ** Copyright 2006, The Android Open Source Project
  4. **
  5. ** Licensed under the Apache License, Version 2.0 (the "License");
  6. ** you may not use this file except in compliance with the License.
  7. ** You may obtain a copy of the License at
  8. **
  9. ** http://www.apache.org/licenses/LICENSE-2.0
  10. **
  11. ** Unless required by applicable law or agreed to in writing, software
  12. ** distributed under the License is distributed on an "AS IS" BASIS,
  13. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ** See the License for the specific language governing permissions and
  15. ** limitations under the License.
  16. */
  17. #define LOG_TAG "pixelflinger-trap"
  18. #include <assert.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <cutils/memory.h>
  22. #include <log/log.h>
  23. #include "trap.h"
  24. #include "picker.h"
  25. namespace android {
  26. // ----------------------------------------------------------------------------
  27. // enable to see triangles edges
  28. #define DEBUG_TRANGLES 0
  29. // ----------------------------------------------------------------------------
  30. static void pointx_validate(void *con, const GGLcoord* c, GGLcoord r);
  31. static void pointx(void *con, const GGLcoord* c, GGLcoord r);
  32. static void aa_pointx(void *con, const GGLcoord* c, GGLcoord r);
  33. static void aa_nice_pointx(void *con, const GGLcoord* c, GGLcoord r);
  34. static void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);
  35. static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);
  36. static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);
  37. static void recti_validate(void* c, GGLint l, GGLint t, GGLint r, GGLint b);
  38. static void recti(void* c, GGLint l, GGLint t, GGLint r, GGLint b);
  39. static void trianglex_validate(void*,
  40. const GGLcoord*, const GGLcoord*, const GGLcoord*);
  41. static void trianglex_small(void*,
  42. const GGLcoord*, const GGLcoord*, const GGLcoord*);
  43. static void trianglex_big(void*,
  44. const GGLcoord*, const GGLcoord*, const GGLcoord*);
  45. static void aa_trianglex(void*,
  46. const GGLcoord*, const GGLcoord*, const GGLcoord*);
  47. static void trianglex_debug(void* con,
  48. const GGLcoord*, const GGLcoord*, const GGLcoord*);
  49. static void aapolyx(void* con,
  50. const GGLcoord* pts, int count);
  51. static inline int min(int a, int b) CONST;
  52. static inline int max(int a, int b) CONST;
  53. static inline int min(int a, int b, int c) CONST;
  54. static inline int max(int a, int b, int c) CONST;
  55. // ----------------------------------------------------------------------------
  56. #if 0
  57. #pragma mark -
  58. #pragma mark Tools
  59. #endif
  60. inline int min(int a, int b) {
  61. return a<b ? a : b;
  62. }
  63. inline int max(int a, int b) {
  64. return a<b ? b : a;
  65. }
  66. inline int min(int a, int b, int c) {
  67. return min(a,min(b,c));
  68. }
  69. inline int max(int a, int b, int c) {
  70. return max(a,max(b,c));
  71. }
  72. template <typename T>
  73. static inline void swap(T& a, T& b) {
  74. T t(a);
  75. a = b;
  76. b = t;
  77. }
  78. static void
  79. triangle_dump_points( const GGLcoord* v0,
  80. const GGLcoord* v1,
  81. const GGLcoord* v2 )
  82. {
  83. float tri = 1.0f / TRI_ONE;
  84. ALOGD(" P0=(%.3f, %.3f) [%08x, %08x]\n"
  85. " P1=(%.3f, %.3f) [%08x, %08x]\n"
  86. " P2=(%.3f, %.3f) [%08x, %08x]\n",
  87. v0[0]*tri, v0[1]*tri, v0[0], v0[1],
  88. v1[0]*tri, v1[1]*tri, v1[0], v1[1],
  89. v2[0]*tri, v2[1]*tri, v2[0], v2[1] );
  90. }
  91. // ----------------------------------------------------------------------------
  92. #if 0
  93. #pragma mark -
  94. #pragma mark Misc
  95. #endif
  96. void ggl_init_trap(context_t* c)
  97. {
  98. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE|GGL_TMU_STATE|GGL_CB_STATE);
  99. }
  100. void ggl_state_changed(context_t* c, int flags)
  101. {
  102. if (ggl_likely(!c->dirty)) {
  103. c->procs.pointx = pointx_validate;
  104. c->procs.linex = linex_validate;
  105. c->procs.recti = recti_validate;
  106. c->procs.trianglex = trianglex_validate;
  107. }
  108. c->dirty |= uint32_t(flags);
  109. }
  110. // ----------------------------------------------------------------------------
  111. #if 0
  112. #pragma mark -
  113. #pragma mark Point
  114. #endif
  115. void pointx_validate(void *con, const GGLcoord* v, GGLcoord rad)
  116. {
  117. GGL_CONTEXT(c, con);
  118. ggl_pick(c);
  119. if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
  120. if (c->state.enables & GGL_ENABLE_POINT_AA_NICE) {
  121. c->procs.pointx = aa_nice_pointx;
  122. } else {
  123. c->procs.pointx = aa_pointx;
  124. }
  125. } else {
  126. c->procs.pointx = pointx;
  127. }
  128. c->procs.pointx(con, v, rad);
  129. }
  130. void pointx(void *con, const GGLcoord* v, GGLcoord rad)
  131. {
  132. GGL_CONTEXT(c, con);
  133. GGLcoord halfSize = TRI_ROUND(rad) >> 1;
  134. if (halfSize == 0)
  135. halfSize = TRI_HALF;
  136. GGLcoord xc = v[0];
  137. GGLcoord yc = v[1];
  138. if (halfSize & TRI_HALF) { // size odd
  139. xc = TRI_FLOOR(xc) + TRI_HALF;
  140. yc = TRI_FLOOR(yc) + TRI_HALF;
  141. } else { // size even
  142. xc = TRI_ROUND(xc);
  143. yc = TRI_ROUND(yc);
  144. }
  145. GGLint l = (xc - halfSize) >> TRI_FRACTION_BITS;
  146. GGLint t = (yc - halfSize) >> TRI_FRACTION_BITS;
  147. GGLint r = (xc + halfSize) >> TRI_FRACTION_BITS;
  148. GGLint b = (yc + halfSize) >> TRI_FRACTION_BITS;
  149. recti(c, l, t, r, b);
  150. }
  151. // This way of computing the coverage factor, is more accurate and gives
  152. // better results for small circles, but it is also a lot slower.
  153. // Here we use super-sampling.
  154. static int32_t coverageNice(GGLcoord x, GGLcoord y,
  155. GGLcoord rmin, GGLcoord rmax, GGLcoord rr)
  156. {
  157. const GGLcoord d2 = x*x + y*y;
  158. if (d2 >= rmax) return 0;
  159. if (d2 < rmin) return 0x7FFF;
  160. const int kSamples = 4;
  161. const int kInc = 4; // 1/4 = 0.25
  162. const int kCoverageUnit = 1; // 1/(4^2) = 0.0625
  163. const GGLcoord kCoordOffset = -6; // -0.375
  164. int hits = 0;
  165. int x_sample = x + kCoordOffset;
  166. for (int i=0 ; i<kSamples ; i++, x_sample += kInc) {
  167. const int xval = rr - (x_sample * x_sample);
  168. int y_sample = y + kCoordOffset;
  169. for (int j=0 ; j<kSamples ; j++, y_sample += kInc) {
  170. if (xval - (y_sample * y_sample) > 0)
  171. hits += kCoverageUnit;
  172. }
  173. }
  174. return min(0x7FFF, hits << (15 - kSamples));
  175. }
  176. void aa_nice_pointx(void *con, const GGLcoord* v, GGLcoord size)
  177. {
  178. GGL_CONTEXT(c, con);
  179. GGLcoord rad = ((size + 1)>>1);
  180. GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS;
  181. GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS;
  182. GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
  183. GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
  184. GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF;
  185. GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF;
  186. // scissor...
  187. if (l < GGLint(c->state.scissor.left)) {
  188. xstart += TRI_FROM_INT(c->state.scissor.left-l);
  189. l = GGLint(c->state.scissor.left);
  190. }
  191. if (t < GGLint(c->state.scissor.top)) {
  192. ystart += TRI_FROM_INT(c->state.scissor.top-t);
  193. t = GGLint(c->state.scissor.top);
  194. }
  195. if (r > GGLint(c->state.scissor.right)) {
  196. r = GGLint(c->state.scissor.right);
  197. }
  198. if (b > GGLint(c->state.scissor.bottom)) {
  199. b = GGLint(c->state.scissor.bottom);
  200. }
  201. int xc = r - l;
  202. int yc = b - t;
  203. if (xc>0 && yc>0) {
  204. int16_t* covPtr = c->state.buffers.coverage;
  205. const int32_t sqr2Over2 = 0xC; // rounded up
  206. GGLcoord rr = rad*rad;
  207. GGLcoord rmin = (rad - sqr2Over2)*(rad - sqr2Over2);
  208. GGLcoord rmax = (rad + sqr2Over2)*(rad + sqr2Over2);
  209. GGLcoord y = ystart;
  210. c->iterators.xl = l;
  211. c->iterators.xr = r;
  212. c->init_y(c, t);
  213. do {
  214. // compute coverage factors for each pixel
  215. GGLcoord x = xstart;
  216. for (int i=l ; i<r ; i++) {
  217. covPtr[i] = coverageNice(x, y, rmin, rmax, rr);
  218. x += TRI_ONE;
  219. }
  220. y += TRI_ONE;
  221. c->scanline(c);
  222. c->step_y(c);
  223. } while (--yc);
  224. }
  225. }
  226. // This is a cheap way of computing the coverage factor for a circle.
  227. // We just lerp between the circles of radii r-sqrt(2)/2 and r+sqrt(2)/2
  228. static inline int32_t coverageFast(GGLcoord x, GGLcoord y,
  229. GGLcoord rmin, GGLcoord rmax, GGLcoord scale)
  230. {
  231. const GGLcoord d2 = x*x + y*y;
  232. if (d2 >= rmax) return 0;
  233. if (d2 < rmin) return 0x7FFF;
  234. return 0x7FFF - (d2-rmin)*scale;
  235. }
  236. void aa_pointx(void *con, const GGLcoord* v, GGLcoord size)
  237. {
  238. GGL_CONTEXT(c, con);
  239. GGLcoord rad = ((size + 1)>>1);
  240. GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS;
  241. GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS;
  242. GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
  243. GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
  244. GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF;
  245. GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF;
  246. // scissor...
  247. if (l < GGLint(c->state.scissor.left)) {
  248. xstart += TRI_FROM_INT(c->state.scissor.left-l);
  249. l = GGLint(c->state.scissor.left);
  250. }
  251. if (t < GGLint(c->state.scissor.top)) {
  252. ystart += TRI_FROM_INT(c->state.scissor.top-t);
  253. t = GGLint(c->state.scissor.top);
  254. }
  255. if (r > GGLint(c->state.scissor.right)) {
  256. r = GGLint(c->state.scissor.right);
  257. }
  258. if (b > GGLint(c->state.scissor.bottom)) {
  259. b = GGLint(c->state.scissor.bottom);
  260. }
  261. int xc = r - l;
  262. int yc = b - t;
  263. if (xc>0 && yc>0) {
  264. int16_t* covPtr = c->state.buffers.coverage;
  265. rad <<= 4;
  266. const int32_t sqr2Over2 = 0xB5; // fixed-point 24.8
  267. GGLcoord rmin = rad - sqr2Over2;
  268. GGLcoord rmax = rad + sqr2Over2;
  269. GGLcoord scale;
  270. rmin *= rmin;
  271. rmax *= rmax;
  272. scale = 0x800000 / (rmax - rmin);
  273. rmin >>= 8;
  274. rmax >>= 8;
  275. GGLcoord y = ystart;
  276. c->iterators.xl = l;
  277. c->iterators.xr = r;
  278. c->init_y(c, t);
  279. do {
  280. // compute coverage factors for each pixel
  281. GGLcoord x = xstart;
  282. for (int i=l ; i<r ; i++) {
  283. covPtr[i] = coverageFast(x, y, rmin, rmax, scale);
  284. x += TRI_ONE;
  285. }
  286. y += TRI_ONE;
  287. c->scanline(c);
  288. c->step_y(c);
  289. } while (--yc);
  290. }
  291. }
  292. // ----------------------------------------------------------------------------
  293. #if 0
  294. #pragma mark -
  295. #pragma mark Line
  296. #endif
  297. void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w)
  298. {
  299. GGL_CONTEXT(c, con);
  300. ggl_pick(c);
  301. if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
  302. c->procs.linex = aa_linex;
  303. } else {
  304. c->procs.linex = linex;
  305. }
  306. c->procs.linex(con, v0, v1, w);
  307. }
  308. static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width)
  309. {
  310. GGLcoord v[4][2];
  311. v[0][0] = v0[0]; v[0][1] = v0[1];
  312. v[1][0] = v1[0]; v[1][1] = v1[1];
  313. v0 = v[0];
  314. v1 = v[1];
  315. const GGLcoord dx = abs(v0[0] - v1[0]);
  316. const GGLcoord dy = abs(v0[1] - v1[1]);
  317. GGLcoord nx, ny;
  318. nx = ny = 0;
  319. GGLcoord halfWidth = TRI_ROUND(width) >> 1;
  320. if (halfWidth == 0)
  321. halfWidth = TRI_HALF;
  322. ((dx > dy) ? ny : nx) = halfWidth;
  323. v[2][0] = v1[0]; v[2][1] = v1[1];
  324. v[3][0] = v0[0]; v[3][1] = v0[1];
  325. v[0][0] += nx; v[0][1] += ny;
  326. v[1][0] += nx; v[1][1] += ny;
  327. v[2][0] -= nx; v[2][1] -= ny;
  328. v[3][0] -= nx; v[3][1] -= ny;
  329. trianglex_big(con, v[0], v[1], v[2]);
  330. trianglex_big(con, v[0], v[2], v[3]);
  331. }
  332. static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width)
  333. {
  334. GGLcoord v[4][2];
  335. v[0][0] = v0[0]; v[0][1] = v0[1];
  336. v[1][0] = v1[0]; v[1][1] = v1[1];
  337. v0 = v[0];
  338. v1 = v[1];
  339. const GGLcoord dx = v0[0] - v1[0];
  340. const GGLcoord dy = v0[1] - v1[1];
  341. GGLcoord nx = -dy;
  342. GGLcoord ny = dx;
  343. // generally, this will be well below 1.0
  344. const GGLfixed norm = gglMulx(width, gglSqrtRecipx(nx*nx+ny*ny), 4);
  345. nx = gglMulx(nx, norm, 21);
  346. ny = gglMulx(ny, norm, 21);
  347. v[2][0] = v1[0]; v[2][1] = v1[1];
  348. v[3][0] = v0[0]; v[3][1] = v0[1];
  349. v[0][0] += nx; v[0][1] += ny;
  350. v[1][0] += nx; v[1][1] += ny;
  351. v[2][0] -= nx; v[2][1] -= ny;
  352. v[3][0] -= nx; v[3][1] -= ny;
  353. aapolyx(con, v[0], 4);
  354. }
  355. // ----------------------------------------------------------------------------
  356. #if 0
  357. #pragma mark -
  358. #pragma mark Rect
  359. #endif
  360. void recti_validate(void *con, GGLint l, GGLint t, GGLint r, GGLint b)
  361. {
  362. GGL_CONTEXT(c, con);
  363. ggl_pick(c);
  364. c->procs.recti = recti;
  365. c->procs.recti(con, l, t, r, b);
  366. }
  367. void recti(void* con, GGLint l, GGLint t, GGLint r, GGLint b)
  368. {
  369. GGL_CONTEXT(c, con);
  370. // scissor...
  371. if (l < GGLint(c->state.scissor.left))
  372. l = GGLint(c->state.scissor.left);
  373. if (t < GGLint(c->state.scissor.top))
  374. t = GGLint(c->state.scissor.top);
  375. if (r > GGLint(c->state.scissor.right))
  376. r = GGLint(c->state.scissor.right);
  377. if (b > GGLint(c->state.scissor.bottom))
  378. b = GGLint(c->state.scissor.bottom);
  379. int xc = r - l;
  380. int yc = b - t;
  381. if (xc>0 && yc>0) {
  382. c->iterators.xl = l;
  383. c->iterators.xr = r;
  384. c->init_y(c, t);
  385. c->rect(c, yc);
  386. }
  387. }
  388. // ----------------------------------------------------------------------------
  389. #if 0
  390. #pragma mark -
  391. #pragma mark Triangle / Debugging
  392. #endif
  393. static void scanline_set(context_t* c)
  394. {
  395. int32_t x = c->iterators.xl;
  396. size_t ct = c->iterators.xr - x;
  397. int32_t y = c->iterators.y;
  398. surface_t* cb = &(c->state.buffers.color);
  399. const GGLFormat* fp = &(c->formats[cb->format]);
  400. uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) +
  401. (x + (cb->stride * y)) * fp->size;
  402. const size_t size = ct * fp->size;
  403. memset(dst, 0xFF, size);
  404. }
  405. static void trianglex_debug(void* con,
  406. const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
  407. {
  408. GGL_CONTEXT(c, con);
  409. if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
  410. aa_trianglex(con,v0,v1,v2);
  411. } else {
  412. trianglex_big(con,v0,v1,v2);
  413. }
  414. void (*save_scanline)(context_t*) = c->scanline;
  415. c->scanline = scanline_set;
  416. linex(con, v0, v1, TRI_ONE);
  417. linex(con, v1, v2, TRI_ONE);
  418. linex(con, v2, v0, TRI_ONE);
  419. c->scanline = save_scanline;
  420. }
  421. static void trianglex_xor(void* con,
  422. const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
  423. {
  424. trianglex_big(con,v0,v1,v2);
  425. trianglex_small(con,v0,v1,v2);
  426. }
  427. // ----------------------------------------------------------------------------
  428. #if 0
  429. #pragma mark -
  430. #pragma mark Triangle
  431. #endif
  432. void trianglex_validate(void *con,
  433. const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
  434. {
  435. GGL_CONTEXT(c, con);
  436. ggl_pick(c);
  437. if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
  438. c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : aa_trianglex;
  439. } else {
  440. c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : trianglex_big;
  441. }
  442. c->procs.trianglex(con, v0, v1, v2);
  443. }
  444. // ----------------------------------------------------------------------------
  445. void trianglex_small(void* con,
  446. const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
  447. {
  448. GGL_CONTEXT(c, con);
  449. // vertices are in 28.4 fixed point, which allows
  450. // us to use 32 bits multiplies below.
  451. int32_t x0 = v0[0];
  452. int32_t y0 = v0[1];
  453. int32_t x1 = v1[0];
  454. int32_t y1 = v1[1];
  455. int32_t x2 = v2[0];
  456. int32_t y2 = v2[1];
  457. int32_t dx01 = x0 - x1;
  458. int32_t dy20 = y2 - y0;
  459. int32_t dy01 = y0 - y1;
  460. int32_t dx20 = x2 - x0;
  461. // The code below works only with CCW triangles
  462. // so if we get a CW triangle, we need to swap two of its vertices
  463. if (dx01*dy20 < dy01*dx20) {
  464. swap(x0, x1);
  465. swap(y0, y1);
  466. dx01 = x0 - x1;
  467. dy01 = y0 - y1;
  468. dx20 = x2 - x0;
  469. dy20 = y2 - y0;
  470. }
  471. int32_t dx12 = x1 - x2;
  472. int32_t dy12 = y1 - y2;
  473. // bounding box & scissor
  474. const int32_t bminx = TRI_FLOOR(min(x0, x1, x2)) >> TRI_FRACTION_BITS;
  475. const int32_t bminy = TRI_FLOOR(min(y0, y1, y2)) >> TRI_FRACTION_BITS;
  476. const int32_t bmaxx = TRI_CEIL( max(x0, x1, x2)) >> TRI_FRACTION_BITS;
  477. const int32_t bmaxy = TRI_CEIL( max(y0, y1, y2)) >> TRI_FRACTION_BITS;
  478. const int32_t minx = max(bminx, c->state.scissor.left);
  479. const int32_t miny = max(bminy, c->state.scissor.top);
  480. const int32_t maxx = min(bmaxx, c->state.scissor.right);
  481. const int32_t maxy = min(bmaxy, c->state.scissor.bottom);
  482. if ((minx >= maxx) || (miny >= maxy))
  483. return; // too small or clipped out...
  484. // step equations to the bounding box and snap to pixel center
  485. const int32_t my = (miny << TRI_FRACTION_BITS) + TRI_HALF;
  486. const int32_t mx = (minx << TRI_FRACTION_BITS) + TRI_HALF;
  487. int32_t ey0 = dy01 * (x0 - mx) - dx01 * (y0 - my);
  488. int32_t ey1 = dy12 * (x1 - mx) - dx12 * (y1 - my);
  489. int32_t ey2 = dy20 * (x2 - mx) - dx20 * (y2 - my);
  490. // right-exclusive fill rule, to avoid rare cases
  491. // of over drawing
  492. if (dy01<0 || (dy01 == 0 && dx01>0)) ey0++;
  493. if (dy12<0 || (dy12 == 0 && dx12>0)) ey1++;
  494. if (dy20<0 || (dy20 == 0 && dx20>0)) ey2++;
  495. c->init_y(c, miny);
  496. for (int32_t y = miny; y < maxy; y++) {
  497. int32_t ex0 = ey0;
  498. int32_t ex1 = ey1;
  499. int32_t ex2 = ey2;
  500. int32_t xl, xr;
  501. for (xl=minx ; xl<maxx ; xl++) {
  502. if (ex0>0 && ex1>0 && ex2>0)
  503. break; // all strictly positive
  504. ex0 -= dy01 << TRI_FRACTION_BITS;
  505. ex1 -= dy12 << TRI_FRACTION_BITS;
  506. ex2 -= dy20 << TRI_FRACTION_BITS;
  507. }
  508. xr = xl;
  509. for ( ; xr<maxx ; xr++) {
  510. if (!(ex0>0 && ex1>0 && ex2>0))
  511. break; // not all strictly positive
  512. ex0 -= dy01 << TRI_FRACTION_BITS;
  513. ex1 -= dy12 << TRI_FRACTION_BITS;
  514. ex2 -= dy20 << TRI_FRACTION_BITS;
  515. }
  516. if (xl < xr) {
  517. c->iterators.xl = xl;
  518. c->iterators.xr = xr;
  519. c->scanline(c);
  520. }
  521. c->step_y(c);
  522. ey0 += dx01 << TRI_FRACTION_BITS;
  523. ey1 += dx12 << TRI_FRACTION_BITS;
  524. ey2 += dx20 << TRI_FRACTION_BITS;
  525. }
  526. }
  527. // ----------------------------------------------------------------------------
  528. #if 0
  529. #pragma mark -
  530. #endif
  531. // the following routine fills a triangle via edge stepping, which
  532. // unfortunately requires divisions in the setup phase to get right,
  533. // it should probably only be used for relatively large trianges
  534. // x = y*DX/DY (ou DX and DY are constants, DY > 0, et y >= 0)
  535. //
  536. // for an equation of the type:
  537. // x' = y*K/2^p (with K and p constants "carefully chosen")
  538. //
  539. // We can now do a DDA without precision loss. We define 'e' by:
  540. // x' - x = y*(DX/DY - K/2^p) = y*e
  541. //
  542. // If we choose K = round(DX*2^p/DY) then,
  543. // abs(e) <= 1/2^(p+1) by construction
  544. //
  545. // therefore abs(x'-x) = y*abs(e) <= y/2^(p+1) <= DY/2^(p+1) <= DMAX/2^(p+1)
  546. //
  547. // which means that if DMAX <= 2^p, therefore abs(x-x') <= 1/2, including
  548. // at the last line. In fact, it's even a strict inequality except in one
  549. // extrem case (DY == DMAX et e = +/- 1/2)
  550. //
  551. // Applying that to our coordinates, we need 2^p >= 4096*16 = 65536
  552. // so p = 16 is enough, we're so lucky!
  553. const int TRI_ITERATORS_BITS = 16;
  554. struct Edge
  555. {
  556. int32_t x; // edge position in 16.16 coordinates
  557. int32_t x_incr; // on each step, increment x by that amount
  558. int32_t y_top; // starting scanline, 16.4 format
  559. int32_t y_bot;
  560. };
  561. static void
  562. edge_dump( Edge* edge )
  563. {
  564. ALOGI( " top=%d (%.3f) bot=%d (%.3f) x=%d (%.3f) ix=%d (%.3f)",
  565. edge->y_top, edge->y_top/float(TRI_ONE),
  566. edge->y_bot, edge->y_bot/float(TRI_ONE),
  567. edge->x, edge->x/float(FIXED_ONE),
  568. edge->x_incr, edge->x_incr/float(FIXED_ONE) );
  569. }
  570. static void
  571. triangle_dump_edges( Edge* edges,
  572. int count )
  573. {
  574. ALOGI( "%d edge%s:\n", count, count == 1 ? "" : "s" );
  575. for ( ; count > 0; count--, edges++ )
  576. edge_dump( edges );
  577. }
  578. // the following function sets up an edge, it assumes
  579. // that ymin and ymax are in already in the 'reduced'
  580. // format
  581. static __attribute__((noinline))
  582. void edge_setup(
  583. Edge* edges,
  584. int* pcount,
  585. const GGLcoord* p1,
  586. const GGLcoord* p2,
  587. int32_t ymin,
  588. int32_t ymax )
  589. {
  590. const GGLfixed* top = p1;
  591. const GGLfixed* bot = p2;
  592. Edge* edge = edges + *pcount;
  593. if (top[1] > bot[1]) {
  594. swap(top, bot);
  595. }
  596. int y1 = top[1] | 1;
  597. int y2 = bot[1] | 1;
  598. int dy = y2 - y1;
  599. if ( dy == 0 || y1 > ymax || y2 < ymin )
  600. return;
  601. if ( y1 > ymin )
  602. ymin = TRI_SNAP_NEXT_HALF(y1);
  603. if ( y2 < ymax )
  604. ymax = TRI_SNAP_PREV_HALF(y2);
  605. if ( ymin > ymax ) // when the edge doesn't cross any scanline
  606. return;
  607. const int x1 = top[0];
  608. const int dx = bot[0] - x1;
  609. const int shift = TRI_ITERATORS_BITS - TRI_FRACTION_BITS;
  610. // setup edge fields
  611. // We add 0.5 to edge->x here because it simplifies the rounding
  612. // in triangle_sweep_edges() -- this doesn't change the ordering of 'x'
  613. edge->x = (x1 << shift) + (1LU << (TRI_ITERATORS_BITS-1));
  614. edge->x_incr = 0;
  615. edge->y_top = ymin;
  616. edge->y_bot = ymax;
  617. if (ggl_likely(ymin <= ymax && dx)) {
  618. edge->x_incr = gglDivQ16(dx, dy);
  619. }
  620. if (ggl_likely(y1 < ymin)) {
  621. int32_t xadjust = (edge->x_incr * (ymin-y1)) >> TRI_FRACTION_BITS;
  622. edge->x += xadjust;
  623. }
  624. ++*pcount;
  625. }
  626. static void
  627. triangle_sweep_edges( Edge* left,
  628. Edge* right,
  629. int ytop,
  630. int ybot,
  631. context_t* c )
  632. {
  633. int count = ((ybot - ytop)>>TRI_FRACTION_BITS) + 1;
  634. if (count<=0) return;
  635. // sort the edges horizontally
  636. if ((left->x > right->x) ||
  637. ((left->x == right->x) && (left->x_incr > right->x_incr))) {
  638. swap(left, right);
  639. }
  640. int left_x = left->x;
  641. int right_x = right->x;
  642. const int left_xi = left->x_incr;
  643. const int right_xi = right->x_incr;
  644. left->x += left_xi * count;
  645. right->x += right_xi * count;
  646. const int xmin = c->state.scissor.left;
  647. const int xmax = c->state.scissor.right;
  648. do {
  649. // horizontal scissoring
  650. const int32_t xl = max(left_x >> TRI_ITERATORS_BITS, xmin);
  651. const int32_t xr = min(right_x >> TRI_ITERATORS_BITS, xmax);
  652. left_x += left_xi;
  653. right_x += right_xi;
  654. // invoke the scanline rasterizer
  655. if (ggl_likely(xl < xr)) {
  656. c->iterators.xl = xl;
  657. c->iterators.xr = xr;
  658. c->scanline(c);
  659. }
  660. c->step_y(c);
  661. } while (--count);
  662. }
  663. void trianglex_big(void* con,
  664. const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
  665. {
  666. GGL_CONTEXT(c, con);
  667. Edge edges[3];
  668. int num_edges = 0;
  669. int32_t ymin = TRI_FROM_INT(c->state.scissor.top) + TRI_HALF;
  670. int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom) - TRI_HALF;
  671. edge_setup( edges, &num_edges, v0, v1, ymin, ymax );
  672. edge_setup( edges, &num_edges, v0, v2, ymin, ymax );
  673. edge_setup( edges, &num_edges, v1, v2, ymin, ymax );
  674. if (ggl_unlikely(num_edges<2)) // for really tiny triangles that don't
  675. return; // cross any scanline centers
  676. Edge* left = &edges[0];
  677. Edge* right = &edges[1];
  678. Edge* other = &edges[2];
  679. int32_t y_top = min(left->y_top, right->y_top);
  680. int32_t y_bot = max(left->y_bot, right->y_bot);
  681. if (ggl_likely(num_edges==3)) {
  682. y_top = min(y_top, edges[2].y_top);
  683. y_bot = max(y_bot, edges[2].y_bot);
  684. if (edges[0].y_top > y_top) {
  685. other = &edges[0];
  686. left = &edges[2];
  687. } else if (edges[1].y_top > y_top) {
  688. other = &edges[1];
  689. right = &edges[2];
  690. }
  691. }
  692. c->init_y(c, y_top >> TRI_FRACTION_BITS);
  693. int32_t y_mid = min(left->y_bot, right->y_bot);
  694. triangle_sweep_edges( left, right, y_top, y_mid, c );
  695. // second scanline sweep loop, if necessary
  696. y_mid += TRI_ONE;
  697. if (y_mid <= y_bot) {
  698. ((left->y_bot == y_bot) ? right : left) = other;
  699. if (other->y_top < y_mid) {
  700. other->x += other->x_incr;
  701. }
  702. triangle_sweep_edges( left, right, y_mid, y_bot, c );
  703. }
  704. }
  705. void aa_trianglex(void* con,
  706. const GGLcoord* a, const GGLcoord* b, const GGLcoord* c)
  707. {
  708. GGLcoord pts[6] = { a[0], a[1], b[0], b[1], c[0], c[1] };
  709. aapolyx(con, pts, 3);
  710. }
  711. // ----------------------------------------------------------------------------
  712. #if 0
  713. #pragma mark -
  714. #endif
  715. struct AAEdge
  716. {
  717. GGLfixed x; // edge position in 12.16 coordinates
  718. GGLfixed x_incr; // on each y step, increment x by that amount
  719. GGLfixed y_incr; // on each x step, increment y by that amount
  720. int16_t y_top; // starting scanline, 12.4 format
  721. int16_t y_bot; // starting scanline, 12.4 format
  722. void dump();
  723. };
  724. void AAEdge::dump()
  725. {
  726. float tri = 1.0f / TRI_ONE;
  727. float iter = 1.0f / (1<<TRI_ITERATORS_BITS);
  728. float fix = 1.0f / FIXED_ONE;
  729. ALOGD( "x=%08x (%.3f), "
  730. "x_incr=%08x (%.3f), y_incr=%08x (%.3f), "
  731. "y_top=%08x (%.3f), y_bot=%08x (%.3f) ",
  732. x, x*fix,
  733. x_incr, x_incr*iter,
  734. y_incr, y_incr*iter,
  735. y_top, y_top*tri,
  736. y_bot, y_bot*tri );
  737. }
  738. // the following function sets up an edge, it assumes
  739. // that ymin and ymax are in already in the 'reduced'
  740. // format
  741. static __attribute__((noinline))
  742. void aa_edge_setup(
  743. AAEdge* edges,
  744. int* pcount,
  745. const GGLcoord* p1,
  746. const GGLcoord* p2,
  747. int32_t ymin,
  748. int32_t ymax )
  749. {
  750. const GGLfixed* top = p1;
  751. const GGLfixed* bot = p2;
  752. AAEdge* edge = edges + *pcount;
  753. if (top[1] > bot[1])
  754. swap(top, bot);
  755. int y1 = top[1];
  756. int y2 = bot[1];
  757. int dy = y2 - y1;
  758. if (dy==0 || y1>ymax || y2<ymin)
  759. return;
  760. if (y1 > ymin)
  761. ymin = y1;
  762. if (y2 < ymax)
  763. ymax = y2;
  764. const int x1 = top[0];
  765. const int dx = bot[0] - x1;
  766. const int shift = FIXED_BITS - TRI_FRACTION_BITS;
  767. // setup edge fields
  768. edge->x = x1 << shift;
  769. edge->x_incr = 0;
  770. edge->y_top = ymin;
  771. edge->y_bot = ymax;
  772. edge->y_incr = 0x7FFFFFFF;
  773. if (ggl_likely(ymin <= ymax && dx)) {
  774. edge->x_incr = gglDivQ16(dx, dy);
  775. if (dx != 0) {
  776. edge->y_incr = abs(gglDivQ16(dy, dx));
  777. }
  778. }
  779. if (ggl_likely(y1 < ymin)) {
  780. int32_t xadjust = (edge->x_incr * (ymin-y1))
  781. >> (TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS);
  782. edge->x += xadjust;
  783. }
  784. ++*pcount;
  785. }
  786. typedef int (*compar_t)(const void*, const void*);
  787. static int compare_edges(const AAEdge *e0, const AAEdge *e1) {
  788. if (e0->y_top > e1->y_top) return 1;
  789. if (e0->y_top < e1->y_top) return -1;
  790. if (e0->x > e1->x) return 1;
  791. if (e0->x < e1->x) return -1;
  792. if (e0->x_incr > e1->x_incr) return 1;
  793. if (e0->x_incr < e1->x_incr) return -1;
  794. return 0; // same edges, should never happen
  795. }
  796. static inline
  797. void SET_COVERAGE(int16_t*& p, int32_t value, ssize_t n)
  798. {
  799. android_memset16((uint16_t*)p, value, n*2);
  800. p += n;
  801. }
  802. static inline
  803. void ADD_COVERAGE(int16_t*& p, int32_t value)
  804. {
  805. value = *p + value;
  806. if (value >= 0x8000)
  807. value = 0x7FFF;
  808. *p++ = value;
  809. }
  810. static inline
  811. void SUB_COVERAGE(int16_t*& p, int32_t value)
  812. {
  813. value = *p - value;
  814. value &= ~(value>>31);
  815. *p++ = value;
  816. }
  817. void aapolyx(void* con,
  818. const GGLcoord* pts, int count)
  819. {
  820. /*
  821. * NOTE: This routine assumes that the polygon has been clipped to the
  822. * viewport already, that is, no vertex lies outside of the framebuffer.
  823. * If this happens, the code below won't corrupt memory but the
  824. * coverage values may not be correct.
  825. */
  826. GGL_CONTEXT(c, con);
  827. // we do only quads for now (it's used for thick lines)
  828. if ((count>4) || (count<2)) return;
  829. // take scissor into account
  830. const int xmin = c->state.scissor.left;
  831. const int xmax = c->state.scissor.right;
  832. if (xmin >= xmax) return;
  833. // generate edges from the vertices
  834. int32_t ymin = TRI_FROM_INT(c->state.scissor.top);
  835. int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom);
  836. if (ymin >= ymax) return;
  837. AAEdge edges[4];
  838. int num_edges = 0;
  839. GGLcoord const * p = pts;
  840. for (int i=0 ; i<count-1 ; i++, p+=2) {
  841. aa_edge_setup(edges, &num_edges, p, p+2, ymin, ymax);
  842. }
  843. aa_edge_setup(edges, &num_edges, p, pts, ymin, ymax );
  844. if (ggl_unlikely(num_edges<2))
  845. return;
  846. // sort the edge list top to bottom, left to right.
  847. qsort(edges, num_edges, sizeof(AAEdge), (compar_t)compare_edges);
  848. int16_t* const covPtr = c->state.buffers.coverage;
  849. memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr));
  850. // now, sweep all edges in order
  851. // start with the 2 first edges. We know that they share their top
  852. // vertex, by construction.
  853. int i = 2;
  854. AAEdge* left = &edges[0];
  855. AAEdge* right = &edges[1];
  856. int32_t yt = left->y_top;
  857. GGLfixed l = left->x;
  858. GGLfixed r = right->x;
  859. int retire = 0;
  860. int16_t* coverage;
  861. // at this point we can initialize the rasterizer
  862. c->init_y(c, yt>>TRI_FRACTION_BITS);
  863. c->iterators.xl = xmax;
  864. c->iterators.xr = xmin;
  865. do {
  866. int32_t y = min(min(left->y_bot, right->y_bot), TRI_FLOOR(yt + TRI_ONE));
  867. const int32_t shift = TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS;
  868. const int cf_shift = (1 + TRI_FRACTION_BITS*2 + TRI_ITERATORS_BITS - 15);
  869. // compute xmin and xmax for the left edge
  870. GGLfixed l_min = gglMulAddx(left->x_incr, y - left->y_top, left->x, shift);
  871. GGLfixed l_max = l;
  872. l = l_min;
  873. if (l_min > l_max)
  874. swap(l_min, l_max);
  875. // compute xmin and xmax for the right edge
  876. GGLfixed r_min = gglMulAddx(right->x_incr, y - right->y_top, right->x, shift);
  877. GGLfixed r_max = r;
  878. r = r_min;
  879. if (r_min > r_max)
  880. swap(r_min, r_max);
  881. // make sure we're not touching coverage values outside of the
  882. // framebuffer
  883. l_min &= ~(l_min>>31);
  884. r_min &= ~(r_min>>31);
  885. l_max &= ~(l_max>>31);
  886. r_max &= ~(r_max>>31);
  887. if (gglFixedToIntFloor(l_min) >= xmax) l_min = gglIntToFixed(xmax)-1;
  888. if (gglFixedToIntFloor(r_min) >= xmax) r_min = gglIntToFixed(xmax)-1;
  889. if (gglFixedToIntCeil(l_max) >= xmax) l_max = gglIntToFixed(xmax)-1;
  890. if (gglFixedToIntCeil(r_max) >= xmax) r_max = gglIntToFixed(xmax)-1;
  891. // compute the integer versions of the above
  892. const GGLfixed l_min_i = gglFloorx(l_min);
  893. const GGLfixed l_max_i = gglCeilx (l_max);
  894. const GGLfixed r_min_i = gglFloorx(r_min);
  895. const GGLfixed r_max_i = gglCeilx (r_max);
  896. // clip horizontally using the scissor
  897. const int xml = max(xmin, gglFixedToIntFloor(l_min_i));
  898. const int xmr = min(xmax, gglFixedToIntFloor(r_max_i));
  899. // if we just stepped to a new scanline, render the previous one.
  900. // and clear the coverage buffer
  901. if (retire) {
  902. if (c->iterators.xl < c->iterators.xr)
  903. c->scanline(c);
  904. c->step_y(c);
  905. memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr));
  906. c->iterators.xl = xml;
  907. c->iterators.xr = xmr;
  908. } else {
  909. // update the horizontal range of this scanline
  910. c->iterators.xl = min(c->iterators.xl, xml);
  911. c->iterators.xr = max(c->iterators.xr, xmr);
  912. }
  913. coverage = covPtr + gglFixedToIntFloor(l_min_i);
  914. if (l_min_i == gglFloorx(l_max)) {
  915. /*
  916. * fully traverse this pixel vertically
  917. * l_max
  918. * +-----/--+ yt
  919. * | / |
  920. * | / |
  921. * | / |
  922. * +-/------+ y
  923. * l_min (l_min_i + TRI_ONE)
  924. */
  925. GGLfixed dx = l_max - l_min;
  926. int32_t dy = y - yt;
  927. int cf = gglMulx((dx >> 1) + (l_min_i + FIXED_ONE - l_max), dy,
  928. FIXED_BITS + TRI_FRACTION_BITS - 15);
  929. ADD_COVERAGE(coverage, cf);
  930. // all pixels on the right have cf = 1.0
  931. } else {
  932. /*
  933. * spans several pixels in one scanline
  934. * l_max
  935. * +--------+--/-----+ yt
  936. * | |/ |
  937. * | /| |
  938. * | / | |
  939. * +---/----+--------+ y
  940. * l_min (l_min_i + TRI_ONE)
  941. */
  942. // handle the first pixel separately...
  943. const int32_t y_incr = left->y_incr;
  944. int32_t dx = TRI_FROM_FIXED(l_min_i - l_min) + TRI_ONE;
  945. int32_t cf = (dx * dx * y_incr) >> cf_shift;
  946. ADD_COVERAGE(coverage, cf);
  947. // following pixels get covered by y_incr, but we need
  948. // to fix-up the cf to account for previous partial pixel
  949. dx = TRI_FROM_FIXED(l_min - l_min_i);
  950. cf -= (dx * dx * y_incr) >> cf_shift;
  951. for (int x = l_min_i+FIXED_ONE ; x < l_max_i-FIXED_ONE ; x += FIXED_ONE) {
  952. cf += y_incr >> (TRI_ITERATORS_BITS-15);
  953. ADD_COVERAGE(coverage, cf);
  954. }
  955. // and the last pixel
  956. dx = TRI_FROM_FIXED(l_max - l_max_i) - TRI_ONE;
  957. cf += (dx * dx * y_incr) >> cf_shift;
  958. ADD_COVERAGE(coverage, cf);
  959. }
  960. // now, fill up all fully covered pixels
  961. coverage = covPtr + gglFixedToIntFloor(l_max_i);
  962. int cf = ((y - yt) << (15 - TRI_FRACTION_BITS));
  963. if (ggl_likely(cf >= 0x8000)) {
  964. SET_COVERAGE(coverage, 0x7FFF, ((r_max - l_max_i)>>FIXED_BITS)+1);
  965. } else {
  966. for (int x=l_max_i ; x<r_max ; x+=FIXED_ONE) {
  967. ADD_COVERAGE(coverage, cf);
  968. }
  969. }
  970. // subtract the coverage of the right edge
  971. coverage = covPtr + gglFixedToIntFloor(r_min_i);
  972. if (r_min_i == gglFloorx(r_max)) {
  973. GGLfixed dx = r_max - r_min;
  974. int32_t dy = y - yt;
  975. int cf = gglMulx((dx >> 1) + (r_min_i + FIXED_ONE - r_max), dy,
  976. FIXED_BITS + TRI_FRACTION_BITS - 15);
  977. SUB_COVERAGE(coverage, cf);
  978. // all pixels on the right have cf = 1.0
  979. } else {
  980. // handle the first pixel separately...
  981. const int32_t y_incr = right->y_incr;
  982. int32_t dx = TRI_FROM_FIXED(r_min_i - r_min) + TRI_ONE;
  983. int32_t cf = (dx * dx * y_incr) >> cf_shift;
  984. SUB_COVERAGE(coverage, cf);
  985. // following pixels get covered by y_incr, but we need
  986. // to fix-up the cf to account for previous partial pixel
  987. dx = TRI_FROM_FIXED(r_min - r_min_i);
  988. cf -= (dx * dx * y_incr) >> cf_shift;
  989. for (int x = r_min_i+FIXED_ONE ; x < r_max_i-FIXED_ONE ; x += FIXED_ONE) {
  990. cf += y_incr >> (TRI_ITERATORS_BITS-15);
  991. SUB_COVERAGE(coverage, cf);
  992. }
  993. // and the last pixel
  994. dx = TRI_FROM_FIXED(r_max - r_max_i) - TRI_ONE;
  995. cf += (dx * dx * y_incr) >> cf_shift;
  996. SUB_COVERAGE(coverage, cf);
  997. }
  998. // did we reach the end of an edge? if so, get a new one.
  999. if (y == left->y_bot || y == right->y_bot) {
  1000. // bail out if we're done
  1001. if (i>=num_edges)
  1002. break;
  1003. if (y == left->y_bot)
  1004. left = &edges[i++];
  1005. if (y == right->y_bot)
  1006. right = &edges[i++];
  1007. }
  1008. // next scanline
  1009. yt = y;
  1010. // did we just finish a scanline?
  1011. retire = (y << (32-TRI_FRACTION_BITS)) == 0;
  1012. } while (true);
  1013. // render the last scanline
  1014. if (c->iterators.xl < c->iterators.xr)
  1015. c->scanline(c);
  1016. }
  1017. }; // namespace android