pixelflinger.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. /* libs/pixelflinger/pixelflinger.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. #include <stdlib.h>
  18. #include <string.h>
  19. #include <assert.h>
  20. #include <sys/time.h>
  21. #include <pixelflinger/pixelflinger.h>
  22. #include <private/pixelflinger/ggl_context.h>
  23. #include "buffer.h"
  24. #include "clear.h"
  25. #include "picker.h"
  26. #include "raster.h"
  27. #include "scanline.h"
  28. #include "trap.h"
  29. #include "codeflinger/GGLAssembler.h"
  30. #include "codeflinger/CodeCache.h"
  31. #include <stdio.h>
  32. namespace android {
  33. // ----------------------------------------------------------------------------
  34. // 8x8 Bayer dither matrix
  35. static const uint8_t gDitherMatrix[GGL_DITHER_SIZE] = {
  36. 0, 32, 8, 40, 2, 34, 10, 42,
  37. 48, 16, 56, 24, 50, 18, 58, 26,
  38. 12, 44, 4, 36, 14, 46, 6, 38,
  39. 60, 28, 52, 20, 62, 30, 54, 22,
  40. 3, 35, 11, 43, 1, 33, 9, 41,
  41. 51, 19, 59, 27, 49, 17, 57, 25,
  42. 15, 47, 7, 39, 13, 45, 5, 37,
  43. 63, 31, 55, 23, 61, 29, 53, 21
  44. };
  45. static void ggl_init_procs(context_t* c);
  46. static void ggl_set_scissor(context_t* c);
  47. static void ggl_enable_blending(context_t* c, int enable);
  48. static void ggl_enable_scissor_test(context_t* c, int enable);
  49. static void ggl_enable_alpha_test(context_t* c, int enable);
  50. static void ggl_enable_logic_op(context_t* c, int enable);
  51. static void ggl_enable_dither(context_t* c, int enable);
  52. static void ggl_enable_stencil_test(context_t* c, int enable);
  53. static void ggl_enable_depth_test(context_t* c, int enable);
  54. static void ggl_enable_aa(context_t* c, int enable);
  55. static void ggl_enable_point_aa_nice(context_t* c, int enable);
  56. static void ggl_enable_texture2d(context_t* c, int enable);
  57. static void ggl_enable_w_lerp(context_t* c, int enable);
  58. static void ggl_enable_fog(context_t* c, int enable);
  59. static inline int min(int a, int b) CONST;
  60. static inline int min(int a, int b) {
  61. return a < b ? a : b;
  62. }
  63. static inline int max(int a, int b) CONST;
  64. static inline int max(int a, int b) {
  65. return a < b ? b : a;
  66. }
  67. // ----------------------------------------------------------------------------
  68. void ggl_error(context_t* c, GGLenum error)
  69. {
  70. if (c->error == GGL_NO_ERROR)
  71. c->error = error;
  72. }
  73. // ----------------------------------------------------------------------------
  74. static void ggl_bindTexture(void* con, const GGLSurface* surface)
  75. {
  76. GGL_CONTEXT(c, con);
  77. if (surface->format != c->activeTMU->surface.format)
  78. ggl_state_changed(c, GGL_TMU_STATE);
  79. ggl_set_surface(c, &(c->activeTMU->surface), surface);
  80. }
  81. static void ggl_bindTextureLod(void* con, GGLuint tmu,const GGLSurface* surface)
  82. {
  83. GGL_CONTEXT(c, con);
  84. // All LODs must have the same format
  85. ggl_set_surface(c, &c->state.texture[tmu].surface, surface);
  86. }
  87. static void ggl_colorBuffer(void* con, const GGLSurface* surface)
  88. {
  89. GGL_CONTEXT(c, con);
  90. if (surface->format != c->state.buffers.color.format)
  91. ggl_state_changed(c, GGL_CB_STATE);
  92. if (surface->width > c->state.buffers.coverageBufferSize) {
  93. // allocate the coverage factor buffer
  94. free(c->state.buffers.coverage);
  95. c->state.buffers.coverage = (int16_t*)malloc(surface->width * 2);
  96. c->state.buffers.coverageBufferSize =
  97. c->state.buffers.coverage ? surface->width : 0;
  98. }
  99. ggl_set_surface(c, &(c->state.buffers.color), surface);
  100. if (c->state.buffers.read.format == 0) {
  101. ggl_set_surface(c, &(c->state.buffers.read), surface);
  102. }
  103. ggl_set_scissor(c);
  104. }
  105. static void ggl_readBuffer(void* con, const GGLSurface* surface)
  106. {
  107. GGL_CONTEXT(c, con);
  108. ggl_set_surface(c, &(c->state.buffers.read), surface);
  109. }
  110. static void ggl_depthBuffer(void* con, const GGLSurface* surface)
  111. {
  112. GGL_CONTEXT(c, con);
  113. if (surface->format == GGL_PIXEL_FORMAT_Z_16) {
  114. ggl_set_surface(c, &(c->state.buffers.depth), surface);
  115. } else {
  116. c->state.buffers.depth.format = GGL_PIXEL_FORMAT_NONE;
  117. ggl_enable_depth_test(c, 0);
  118. }
  119. }
  120. static void ggl_scissor(void* con, GGLint x, GGLint y,
  121. GGLsizei width, GGLsizei height)
  122. {
  123. GGL_CONTEXT(c, con);
  124. c->state.scissor.user_left = x;
  125. c->state.scissor.user_top = y;
  126. c->state.scissor.user_right = x + width;
  127. c->state.scissor.user_bottom = y + height;
  128. ggl_set_scissor(c);
  129. }
  130. // ----------------------------------------------------------------------------
  131. static void enable_disable(context_t* c, GGLenum name, int en)
  132. {
  133. switch (name) {
  134. case GGL_BLEND: ggl_enable_blending(c, en); break;
  135. case GGL_SCISSOR_TEST: ggl_enable_scissor_test(c, en); break;
  136. case GGL_ALPHA_TEST: ggl_enable_alpha_test(c, en); break;
  137. case GGL_COLOR_LOGIC_OP: ggl_enable_logic_op(c, en); break;
  138. case GGL_DITHER: ggl_enable_dither(c, en); break;
  139. case GGL_STENCIL_TEST: ggl_enable_stencil_test(c, en); break;
  140. case GGL_DEPTH_TEST: ggl_enable_depth_test(c, en); break;
  141. case GGL_AA: ggl_enable_aa(c, en); break;
  142. case GGL_TEXTURE_2D: ggl_enable_texture2d(c, en); break;
  143. case GGL_W_LERP: ggl_enable_w_lerp(c, en); break;
  144. case GGL_FOG: ggl_enable_fog(c, en); break;
  145. case GGL_POINT_SMOOTH_NICE: ggl_enable_point_aa_nice(c, en); break;
  146. }
  147. }
  148. static void ggl_enable(void* con, GGLenum name)
  149. {
  150. GGL_CONTEXT(c, con);
  151. enable_disable(c, name, 1);
  152. }
  153. static void ggl_disable(void* con, GGLenum name)
  154. {
  155. GGL_CONTEXT(c, con);
  156. enable_disable(c, name, 0);
  157. }
  158. static void ggl_enableDisable(void* con, GGLenum name, GGLboolean en)
  159. {
  160. GGL_CONTEXT(c, con);
  161. enable_disable(c, name, en ? 1 : 0);
  162. }
  163. // ----------------------------------------------------------------------------
  164. static void ggl_shadeModel(void* con, GGLenum mode)
  165. {
  166. GGL_CONTEXT(c, con);
  167. switch (mode) {
  168. case GGL_FLAT:
  169. if (c->state.enables & GGL_ENABLE_SMOOTH) {
  170. c->state.enables &= ~GGL_ENABLE_SMOOTH;
  171. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  172. }
  173. break;
  174. case GGL_SMOOTH:
  175. if (!(c->state.enables & GGL_ENABLE_SMOOTH)) {
  176. c->state.enables |= GGL_ENABLE_SMOOTH;
  177. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  178. }
  179. break;
  180. default:
  181. ggl_error(c, GGL_INVALID_ENUM);
  182. }
  183. }
  184. static void ggl_color4xv(void* con, const GGLclampx* color)
  185. {
  186. GGL_CONTEXT(c, con);
  187. c->shade.r0 = gglFixedToIteratedColor(color[0]);
  188. c->shade.g0 = gglFixedToIteratedColor(color[1]);
  189. c->shade.b0 = gglFixedToIteratedColor(color[2]);
  190. c->shade.a0 = gglFixedToIteratedColor(color[3]);
  191. }
  192. static void ggl_colorGrad12xv(void* con, const GGLcolor* grad)
  193. {
  194. GGL_CONTEXT(c, con);
  195. // it is very important to round the iterated value here because
  196. // the rasterizer doesn't clamp them, therefore the iterated value
  197. //must absolutely be correct.
  198. // GGLColor is encoded as 8.16 value
  199. const int32_t round = 0x8000;
  200. c->shade.r0 = grad[ 0] + round;
  201. c->shade.drdx = grad[ 1];
  202. c->shade.drdy = grad[ 2];
  203. c->shade.g0 = grad[ 3] + round;
  204. c->shade.dgdx = grad[ 4];
  205. c->shade.dgdy = grad[ 5];
  206. c->shade.b0 = grad[ 6] + round;
  207. c->shade.dbdx = grad[ 7];
  208. c->shade.dbdy = grad[ 8];
  209. c->shade.a0 = grad[ 9] + round;
  210. c->shade.dadx = grad[10];
  211. c->shade.dady = grad[11];
  212. }
  213. static void ggl_zGrad3xv(void* con, const GGLfixed32* grad)
  214. {
  215. GGL_CONTEXT(c, con);
  216. // z iterators are encoded as 0.32 fixed point and the z-buffer
  217. // holds 16 bits, the rounding value is 0x8000.
  218. const uint32_t round = 0x8000;
  219. c->shade.z0 = grad[0] + round;
  220. c->shade.dzdx = grad[1];
  221. c->shade.dzdy = grad[2];
  222. }
  223. static void ggl_wGrad3xv(void* con, const GGLfixed* grad)
  224. {
  225. GGL_CONTEXT(c, con);
  226. c->shade.w0 = grad[0];
  227. c->shade.dwdx = grad[1];
  228. c->shade.dwdy = grad[2];
  229. }
  230. // ----------------------------------------------------------------------------
  231. static void ggl_fogGrad3xv(void* con, const GGLfixed* grad)
  232. {
  233. GGL_CONTEXT(c, con);
  234. c->shade.f0 = grad[0];
  235. c->shade.dfdx = grad[1];
  236. c->shade.dfdy = grad[2];
  237. }
  238. static void ggl_fogColor3xv(void* con, const GGLclampx* color)
  239. {
  240. GGL_CONTEXT(c, con);
  241. const int32_t r = gglClampx(color[0]);
  242. const int32_t g = gglClampx(color[1]);
  243. const int32_t b = gglClampx(color[2]);
  244. c->state.fog.color[GGLFormat::ALPHA]= 0xFF; // unused
  245. c->state.fog.color[GGLFormat::RED] = (r - (r>>8))>>8;
  246. c->state.fog.color[GGLFormat::GREEN]= (g - (g>>8))>>8;
  247. c->state.fog.color[GGLFormat::BLUE] = (b - (b>>8))>>8;
  248. }
  249. static void ggl_enable_fog(context_t* c, int enable)
  250. {
  251. const int e = (c->state.enables & GGL_ENABLE_FOG)?1:0;
  252. if (e != enable) {
  253. if (enable) c->state.enables |= GGL_ENABLE_FOG;
  254. else c->state.enables &= ~GGL_ENABLE_FOG;
  255. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  256. }
  257. }
  258. // ----------------------------------------------------------------------------
  259. static void ggl_blendFunc(void* con, GGLenum src, GGLenum dst)
  260. {
  261. GGL_CONTEXT(c, con);
  262. c->state.blend.src = src;
  263. c->state.blend.src_alpha = src;
  264. c->state.blend.dst = dst;
  265. c->state.blend.dst_alpha = dst;
  266. c->state.blend.alpha_separate = 0;
  267. if (c->state.enables & GGL_ENABLE_BLENDING) {
  268. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  269. }
  270. }
  271. static void ggl_blendFuncSeparate(void* con,
  272. GGLenum src, GGLenum dst,
  273. GGLenum srcAlpha, GGLenum dstAplha)
  274. {
  275. GGL_CONTEXT(c, con);
  276. c->state.blend.src = src;
  277. c->state.blend.src_alpha = srcAlpha;
  278. c->state.blend.dst = dst;
  279. c->state.blend.dst_alpha = dstAplha;
  280. c->state.blend.alpha_separate = 1;
  281. if (c->state.enables & GGL_ENABLE_BLENDING) {
  282. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  283. }
  284. }
  285. // ----------------------------------------------------------------------------
  286. static void ggl_texEnvi(void* con, GGLenum target,
  287. GGLenum pname,
  288. GGLint param)
  289. {
  290. GGL_CONTEXT(c, con);
  291. if (target != GGL_TEXTURE_ENV || pname != GGL_TEXTURE_ENV_MODE) {
  292. ggl_error(c, GGL_INVALID_ENUM);
  293. return;
  294. }
  295. switch (param) {
  296. case GGL_REPLACE:
  297. case GGL_MODULATE:
  298. case GGL_DECAL:
  299. case GGL_BLEND:
  300. case GGL_ADD:
  301. if (c->activeTMU->env != param) {
  302. c->activeTMU->env = param;
  303. ggl_state_changed(c, GGL_TMU_STATE);
  304. }
  305. break;
  306. default:
  307. ggl_error(c, GGL_INVALID_ENUM);
  308. }
  309. }
  310. static void ggl_texEnvxv(void* con, GGLenum target,
  311. GGLenum pname, const GGLfixed* params)
  312. {
  313. GGL_CONTEXT(c, con);
  314. if (target != GGL_TEXTURE_ENV) {
  315. ggl_error(c, GGL_INVALID_ENUM);
  316. return;
  317. }
  318. switch (pname) {
  319. case GGL_TEXTURE_ENV_MODE:
  320. ggl_texEnvi(con, target, pname, params[0]);
  321. break;
  322. case GGL_TEXTURE_ENV_COLOR: {
  323. uint8_t* const color = c->activeTMU->env_color;
  324. const GGLclampx r = gglClampx(params[0]);
  325. const GGLclampx g = gglClampx(params[1]);
  326. const GGLclampx b = gglClampx(params[2]);
  327. const GGLclampx a = gglClampx(params[3]);
  328. color[0] = (a-(a>>8))>>8;
  329. color[1] = (r-(r>>8))>>8;
  330. color[2] = (g-(g>>8))>>8;
  331. color[3] = (b-(b>>8))>>8;
  332. break;
  333. }
  334. default:
  335. ggl_error(c, GGL_INVALID_ENUM);
  336. return;
  337. }
  338. }
  339. static void ggl_texParameteri(void* con,
  340. GGLenum target,
  341. GGLenum pname,
  342. GGLint param)
  343. {
  344. GGL_CONTEXT(c, con);
  345. if (target != GGL_TEXTURE_2D) {
  346. ggl_error(c, GGL_INVALID_ENUM);
  347. return;
  348. }
  349. if (param == GGL_CLAMP_TO_EDGE)
  350. param = GGL_CLAMP;
  351. uint16_t* what = 0;
  352. switch (pname) {
  353. case GGL_TEXTURE_WRAP_S:
  354. if ((param == GGL_CLAMP) ||
  355. (param == GGL_REPEAT)) {
  356. what = &c->activeTMU->s_wrap;
  357. }
  358. break;
  359. case GGL_TEXTURE_WRAP_T:
  360. if ((param == GGL_CLAMP) ||
  361. (param == GGL_REPEAT)) {
  362. what = &c->activeTMU->t_wrap;
  363. }
  364. break;
  365. case GGL_TEXTURE_MIN_FILTER:
  366. if ((param == GGL_NEAREST) ||
  367. (param == GGL_NEAREST_MIPMAP_NEAREST) ||
  368. (param == GGL_NEAREST_MIPMAP_LINEAR)) {
  369. what = &c->activeTMU->min_filter;
  370. param = GGL_NEAREST;
  371. }
  372. if ((param == GGL_LINEAR) ||
  373. (param == GGL_LINEAR_MIPMAP_NEAREST) ||
  374. (param == GGL_LINEAR_MIPMAP_LINEAR)) {
  375. what = &c->activeTMU->min_filter;
  376. param = GGL_LINEAR;
  377. }
  378. break;
  379. case GGL_TEXTURE_MAG_FILTER:
  380. if ((param == GGL_NEAREST) ||
  381. (param == GGL_LINEAR)) {
  382. what = &c->activeTMU->mag_filter;
  383. }
  384. break;
  385. }
  386. if (!what) {
  387. ggl_error(c, GGL_INVALID_ENUM);
  388. return;
  389. }
  390. if (*what != param) {
  391. *what = param;
  392. ggl_state_changed(c, GGL_TMU_STATE);
  393. }
  394. }
  395. static void ggl_texCoordGradScale8xv(void* con, GGLint tmu, const int32_t* grad)
  396. {
  397. GGL_CONTEXT(c, con);
  398. texture_t& u = c->state.texture[tmu];
  399. u.shade.is0 = grad[0];
  400. u.shade.idsdx = grad[1];
  401. u.shade.idsdy = grad[2];
  402. u.shade.it0 = grad[3];
  403. u.shade.idtdx = grad[4];
  404. u.shade.idtdy = grad[5];
  405. u.shade.sscale= grad[6];
  406. u.shade.tscale= grad[7];
  407. }
  408. static void ggl_texCoord2x(void* con, GGLfixed s, GGLfixed t)
  409. {
  410. GGL_CONTEXT(c, con);
  411. c->activeTMU->shade.is0 = s;
  412. c->activeTMU->shade.it0 = t;
  413. c->activeTMU->shade.sscale= 0;
  414. c->activeTMU->shade.tscale= 0;
  415. }
  416. static void ggl_texCoord2i(void* con, GGLint s, GGLint t)
  417. {
  418. ggl_texCoord2x(con, s<<16, t<<16);
  419. }
  420. static void ggl_texGeni(void* con, GGLenum coord, GGLenum pname, GGLint param)
  421. {
  422. GGL_CONTEXT(c, con);
  423. if (pname != GGL_TEXTURE_GEN_MODE) {
  424. ggl_error(c, GGL_INVALID_ENUM);
  425. return;
  426. }
  427. uint32_t* coord_ptr = 0;
  428. if (coord == GGL_S) coord_ptr = &(c->activeTMU->s_coord);
  429. else if (coord == GGL_T) coord_ptr = &(c->activeTMU->t_coord);
  430. if (coord_ptr) {
  431. if (*coord_ptr != uint32_t(param)) {
  432. *coord_ptr = uint32_t(param);
  433. ggl_state_changed(c, GGL_TMU_STATE);
  434. }
  435. } else {
  436. ggl_error(c, GGL_INVALID_ENUM);
  437. }
  438. }
  439. static void ggl_activeTexture(void* con, GGLuint tmu)
  440. {
  441. GGL_CONTEXT(c, con);
  442. if (tmu >= GGLuint(GGL_TEXTURE_UNIT_COUNT)) {
  443. ggl_error(c, GGL_INVALID_ENUM);
  444. return;
  445. }
  446. c->activeTMUIndex = tmu;
  447. c->activeTMU = &(c->state.texture[tmu]);
  448. }
  449. // ----------------------------------------------------------------------------
  450. static void ggl_colorMask(void* con, GGLboolean r,
  451. GGLboolean g,
  452. GGLboolean b,
  453. GGLboolean a)
  454. {
  455. GGL_CONTEXT(c, con);
  456. int mask = 0;
  457. if (a) mask |= 1 << GGLFormat::ALPHA;
  458. if (r) mask |= 1 << GGLFormat::RED;
  459. if (g) mask |= 1 << GGLFormat::GREEN;
  460. if (b) mask |= 1 << GGLFormat::BLUE;
  461. if (c->state.mask.color != mask) {
  462. c->state.mask.color = mask;
  463. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  464. }
  465. }
  466. static void ggl_depthMask(void* con, GGLboolean flag)
  467. {
  468. GGL_CONTEXT(c, con);
  469. if (c->state.mask.depth != flag?1:0) {
  470. c->state.mask.depth = flag?1:0;
  471. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  472. }
  473. }
  474. static void ggl_stencilMask(void* con, GGLuint mask)
  475. {
  476. GGL_CONTEXT(c, con);
  477. if (c->state.mask.stencil != mask) {
  478. c->state.mask.stencil = mask;
  479. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  480. }
  481. }
  482. // ----------------------------------------------------------------------------
  483. static void ggl_alphaFuncx(void* con, GGLenum func, GGLclampx ref)
  484. {
  485. GGL_CONTEXT(c, con);
  486. if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) {
  487. ggl_error(c, GGL_INVALID_ENUM);
  488. return;
  489. }
  490. c->state.alpha_test.ref = gglFixedToIteratedColor(gglClampx(ref));
  491. if (c->state.alpha_test.func != func) {
  492. c->state.alpha_test.func = func;
  493. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  494. }
  495. }
  496. // ----------------------------------------------------------------------------
  497. static void ggl_depthFunc(void* con, GGLenum func)
  498. {
  499. GGL_CONTEXT(c, con);
  500. if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) {
  501. ggl_error(c, GGL_INVALID_ENUM);
  502. return;
  503. }
  504. if (c->state.depth_test.func != func) {
  505. c->state.depth_test.func = func;
  506. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  507. }
  508. }
  509. // ----------------------------------------------------------------------------
  510. static void ggl_logicOp(void* con, GGLenum opcode)
  511. {
  512. GGL_CONTEXT(c, con);
  513. if ((opcode < GGL_CLEAR) || (opcode > GGL_SET)) {
  514. ggl_error(c, GGL_INVALID_ENUM);
  515. return;
  516. }
  517. if (c->state.logic_op.opcode != opcode) {
  518. c->state.logic_op.opcode = opcode;
  519. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  520. }
  521. }
  522. // ----------------------------------------------------------------------------
  523. void ggl_set_scissor(context_t* c)
  524. {
  525. if (c->state.enables & GGL_ENABLE_SCISSOR_TEST) {
  526. const int32_t l = c->state.scissor.user_left;
  527. const int32_t t = c->state.scissor.user_top;
  528. const int32_t r = c->state.scissor.user_right;
  529. const int32_t b = c->state.scissor.user_bottom;
  530. c->state.scissor.left = max(0, l);
  531. c->state.scissor.right = min(c->state.buffers.color.width, r);
  532. c->state.scissor.top = max(0, t);
  533. c->state.scissor.bottom = min(c->state.buffers.color.height, b);
  534. } else {
  535. c->state.scissor.left = 0;
  536. c->state.scissor.top = 0;
  537. c->state.scissor.right = c->state.buffers.color.width;
  538. c->state.scissor.bottom = c->state.buffers.color.height;
  539. }
  540. }
  541. void ggl_enable_blending(context_t* c, int enable)
  542. {
  543. const int e = (c->state.enables & GGL_ENABLE_BLENDING)?1:0;
  544. if (e != enable) {
  545. if (enable) c->state.enables |= GGL_ENABLE_BLENDING;
  546. else c->state.enables &= ~GGL_ENABLE_BLENDING;
  547. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  548. }
  549. }
  550. void ggl_enable_scissor_test(context_t* c, int enable)
  551. {
  552. const int e = (c->state.enables & GGL_ENABLE_SCISSOR_TEST)?1:0;
  553. if (e != enable) {
  554. if (enable) c->state.enables |= GGL_ENABLE_SCISSOR_TEST;
  555. else c->state.enables &= ~GGL_ENABLE_SCISSOR_TEST;
  556. ggl_set_scissor(c);
  557. }
  558. }
  559. void ggl_enable_alpha_test(context_t* c, int enable)
  560. {
  561. const int e = (c->state.enables & GGL_ENABLE_ALPHA_TEST)?1:0;
  562. if (e != enable) {
  563. if (enable) c->state.enables |= GGL_ENABLE_ALPHA_TEST;
  564. else c->state.enables &= ~GGL_ENABLE_ALPHA_TEST;
  565. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  566. }
  567. }
  568. void ggl_enable_logic_op(context_t* c, int enable)
  569. {
  570. const int e = (c->state.enables & GGL_ENABLE_LOGIC_OP)?1:0;
  571. if (e != enable) {
  572. if (enable) c->state.enables |= GGL_ENABLE_LOGIC_OP;
  573. else c->state.enables &= ~GGL_ENABLE_LOGIC_OP;
  574. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  575. }
  576. }
  577. void ggl_enable_dither(context_t* c, int enable)
  578. {
  579. const int e = (c->state.enables & GGL_ENABLE_DITHER)?1:0;
  580. if (e != enable) {
  581. if (enable) c->state.enables |= GGL_ENABLE_DITHER;
  582. else c->state.enables &= ~GGL_ENABLE_DITHER;
  583. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  584. }
  585. }
  586. void ggl_enable_stencil_test(context_t* /*c*/, int /*enable*/)
  587. {
  588. }
  589. void ggl_enable_depth_test(context_t* c, int enable)
  590. {
  591. if (c->state.buffers.depth.format == 0)
  592. enable = 0;
  593. const int e = (c->state.enables & GGL_ENABLE_DEPTH_TEST)?1:0;
  594. if (e != enable) {
  595. if (enable) c->state.enables |= GGL_ENABLE_DEPTH_TEST;
  596. else c->state.enables &= ~GGL_ENABLE_DEPTH_TEST;
  597. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  598. }
  599. }
  600. void ggl_enable_aa(context_t* c, int enable)
  601. {
  602. const int e = (c->state.enables & GGL_ENABLE_AA)?1:0;
  603. if (e != enable) {
  604. if (enable) c->state.enables |= GGL_ENABLE_AA;
  605. else c->state.enables &= ~GGL_ENABLE_AA;
  606. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  607. }
  608. }
  609. void ggl_enable_point_aa_nice(context_t* c, int enable)
  610. {
  611. const int e = (c->state.enables & GGL_ENABLE_POINT_AA_NICE)?1:0;
  612. if (e != enable) {
  613. if (enable) c->state.enables |= GGL_ENABLE_POINT_AA_NICE;
  614. else c->state.enables &= ~GGL_ENABLE_POINT_AA_NICE;
  615. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  616. }
  617. }
  618. void ggl_enable_w_lerp(context_t* c, int enable)
  619. {
  620. const int e = (c->state.enables & GGL_ENABLE_W)?1:0;
  621. if (e != enable) {
  622. if (enable) c->state.enables |= GGL_ENABLE_W;
  623. else c->state.enables &= ~GGL_ENABLE_W;
  624. ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE);
  625. }
  626. }
  627. void ggl_enable_texture2d(context_t* c, int enable)
  628. {
  629. if (c->activeTMU->enable != enable) {
  630. const uint32_t tmu = c->activeTMUIndex;
  631. c->activeTMU->enable = enable;
  632. const uint32_t mask = 1UL << tmu;
  633. if (enable) c->state.enabled_tmu |= mask;
  634. else c->state.enabled_tmu &= ~mask;
  635. if (c->state.enabled_tmu) c->state.enables |= GGL_ENABLE_TMUS;
  636. else c->state.enables &= ~GGL_ENABLE_TMUS;
  637. ggl_state_changed(c, GGL_TMU_STATE);
  638. }
  639. }
  640. // ----------------------------------------------------------------------------
  641. int64_t ggl_system_time()
  642. {
  643. struct timespec t;
  644. t.tv_sec = t.tv_nsec = 0;
  645. clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t);
  646. return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec;
  647. }
  648. // ----------------------------------------------------------------------------
  649. void ggl_init_procs(context_t* c)
  650. {
  651. GGLContext& procs = *(GGLContext*)c;
  652. GGL_INIT_PROC(procs, scissor);
  653. GGL_INIT_PROC(procs, activeTexture);
  654. GGL_INIT_PROC(procs, bindTexture);
  655. GGL_INIT_PROC(procs, bindTextureLod);
  656. GGL_INIT_PROC(procs, colorBuffer);
  657. GGL_INIT_PROC(procs, readBuffer);
  658. GGL_INIT_PROC(procs, depthBuffer);
  659. GGL_INIT_PROC(procs, enable);
  660. GGL_INIT_PROC(procs, disable);
  661. GGL_INIT_PROC(procs, enableDisable);
  662. GGL_INIT_PROC(procs, shadeModel);
  663. GGL_INIT_PROC(procs, color4xv);
  664. GGL_INIT_PROC(procs, colorGrad12xv);
  665. GGL_INIT_PROC(procs, zGrad3xv);
  666. GGL_INIT_PROC(procs, wGrad3xv);
  667. GGL_INIT_PROC(procs, fogGrad3xv);
  668. GGL_INIT_PROC(procs, fogColor3xv);
  669. GGL_INIT_PROC(procs, blendFunc);
  670. GGL_INIT_PROC(procs, blendFuncSeparate);
  671. GGL_INIT_PROC(procs, texEnvi);
  672. GGL_INIT_PROC(procs, texEnvxv);
  673. GGL_INIT_PROC(procs, texParameteri);
  674. GGL_INIT_PROC(procs, texCoord2i);
  675. GGL_INIT_PROC(procs, texCoord2x);
  676. GGL_INIT_PROC(procs, texCoordGradScale8xv);
  677. GGL_INIT_PROC(procs, texGeni);
  678. GGL_INIT_PROC(procs, colorMask);
  679. GGL_INIT_PROC(procs, depthMask);
  680. GGL_INIT_PROC(procs, stencilMask);
  681. GGL_INIT_PROC(procs, alphaFuncx);
  682. GGL_INIT_PROC(procs, depthFunc);
  683. GGL_INIT_PROC(procs, logicOp);
  684. ggl_init_clear(c);
  685. }
  686. void ggl_init_context(context_t* c)
  687. {
  688. memset(c, 0, sizeof(context_t));
  689. ggl_init_procs(c);
  690. ggl_init_trap(c);
  691. ggl_init_scanline(c);
  692. ggl_init_texture(c);
  693. ggl_init_picker(c);
  694. ggl_init_raster(c);
  695. c->formats = gglGetPixelFormatTable();
  696. c->state.blend.src = GGL_ONE;
  697. c->state.blend.dst = GGL_ZERO;
  698. c->state.blend.src_alpha = GGL_ONE;
  699. c->state.blend.dst_alpha = GGL_ZERO;
  700. c->state.mask.color = 0xF;
  701. c->state.mask.depth = 0;
  702. c->state.mask.stencil = 0xFFFFFFFF;
  703. c->state.logic_op.opcode = GGL_COPY;
  704. c->state.alpha_test.func = GGL_ALWAYS;
  705. c->state.depth_test.func = GGL_LESS;
  706. c->state.depth_test.clearValue = FIXED_ONE;
  707. c->shade.w0 = FIXED_ONE;
  708. memcpy(c->ditherMatrix, gDitherMatrix, sizeof(gDitherMatrix));
  709. }
  710. void ggl_uninit_context(context_t* c)
  711. {
  712. ggl_uninit_scanline(c);
  713. }
  714. // ----------------------------------------------------------------------------
  715. }; // namespace android
  716. // ----------------------------------------------------------------------------
  717. using namespace android;
  718. ssize_t gglInit(GGLContext** context)
  719. {
  720. void* const base = malloc(sizeof(context_t) + 32);
  721. if (base) {
  722. // always align the context on cache lines
  723. context_t *c = (context_t *)((ptrdiff_t(base)+31) & ~0x1FL);
  724. ggl_init_context(c);
  725. c->base = base;
  726. *context = (GGLContext*)c;
  727. } else {
  728. return -1;
  729. }
  730. return 0;
  731. }
  732. ssize_t gglUninit(GGLContext* con)
  733. {
  734. GGL_CONTEXT(c, (void*)con);
  735. ggl_uninit_context(c);
  736. free(c->base);
  737. return 0;
  738. }