1 /**
2 **
3 ** Copyright 2010, 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
18 #include <stdlib.h>
19 #include <math.h>
20 #include <string.h>
21 #include <stdio.h>
22
23 #include "pixelflinger2.h"
24 #include "src/mesa/main/mtypes.h"
25 #include "src/mesa/program/prog_parameter.h"
26 #include "src/mesa/program/prog_uniform.h"
27 #include "src/glsl/glsl_types.h"
28
29 //#undef LOGD
30 //#define LOGD(...)
31
32 static inline void LerpVector4(const Vector4 * a, const Vector4 * b,
33 const VectorComp_t x, Vector4 * d) __attribute__((always_inline));
LerpVector4(const Vector4 * a,const Vector4 * b,const VectorComp_t x,Vector4 * d)34 static inline void LerpVector4(const Vector4 * a, const Vector4 * b,
35 const VectorComp_t x, Vector4 * d)
36 {
37 assert(a != d && b != d);
38 //d = (b - a) * x + a;
39 (*d) = (*b);
40 (*d) -= (*a);
41 (*d) *= x;
42 (*d) += (*a);
43 }
44
InterpolateVertex(const VertexOutput * a,const VertexOutput * b,const VectorComp_t x,VertexOutput * v,const unsigned varyingCount)45 static inline void InterpolateVertex(const VertexOutput * a, const VertexOutput * b, const VectorComp_t x,
46 VertexOutput * v, const unsigned varyingCount)
47 {
48 LerpVector4(&a->position, &b->position, x, &v->position);
49 for (unsigned i = 0; i < varyingCount; i++)
50 LerpVector4(a->varyings + i, b->varyings + i, x, v->varyings + i);
51 LerpVector4(&a->frontFacingPointCoord, &b->frontFacingPointCoord,
52 x, &v->frontFacingPointCoord); // gl_PointCoord
53 v->frontFacingPointCoord.y = a->frontFacingPointCoord.y; // gl_FrontFacing not interpolated
54
55 }
56
GGLProcessVertex(const gl_shader_program * program,const VertexInput * input,VertexOutput * output,const float (* constants)[4])57 void GGLProcessVertex(const gl_shader_program * program, const VertexInput * input,
58 VertexOutput * output, const float (*constants)[4])
59 {
60 ShaderFunction_t function = (ShaderFunction_t)program->_LinkedShaders[MESA_SHADER_VERTEX]->function;
61 function(input, output, constants);
62 }
63
ProcessVertex(const GGLInterface * iface,const VertexInput * input,VertexOutput * output)64 static void ProcessVertex(const GGLInterface * iface, const VertexInput * input,
65 VertexOutput * output)
66 {
67 GGL_GET_CONST_CONTEXT(ctx, iface);
68
69 //#if !USE_LLVM_TEXTURE_SAMPLER
70 // extern const GGLContext * textureGGLContext;
71 // textureGGLContext = ctx;
72 //#endif
73 //
74
75 // memcpy(ctx->glCtx->CurrentProgram->ValuesVertexInput, input, sizeof(*input));
76 // ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_VERTEX]->function();
77 // memcpy(output, ctx->glCtx->CurrentProgram->ValuesVertexOutput, sizeof(*output));
78
79 GGLProcessVertex(ctx->CurrentProgram, input, output, ctx->CurrentProgram->ValuesUniform);
80 // const Vector4 * constants = (Vector4 *)
81 // ctx->glCtx->Shader.CurrentProgram->VertexProgram->Parameters->ParameterValues;
82 // ctx->glCtx->Shader.CurrentProgram->GLVMVP->function(input, output, constants);
83 //
84 //#if !USE_LLVM_TEXTURE_SAMPLER
85 // textureGGLContext = NULL;
86 //#endif
87 }
88
89 #if USE_DUAL_THREAD
RasterTrapezoidWorker(void * threadArgs)90 static void * RasterTrapezoidWorker(void * threadArgs)
91 {
92 GGLContext::Worker * args = (GGLContext::Worker *)threadArgs;
93 VertexOutput clip0, clip1, * left, * right;
94
95 pthread_mutex_lock(&args->finishLock);
96 pthread_mutex_lock(&args->assignLock);
97 pthread_cond_signal(&args->finishCond);
98 pthread_mutex_unlock(&args->finishLock);
99
100 while (true) {
101 pthread_cond_wait(&args->assignCond, &args->assignLock);
102 if (args->quit)
103 {
104 pthread_mutex_unlock(&args->assignLock);
105 break;
106 }
107 else
108 assert(args->assignedWork);
109
110 for (unsigned y = args->startY; y <= args->endY; y += 2) {
111 do {
112 if (args->bV.position.x < 0) {
113 if (args->cV.position.x < 0)
114 break;
115 InterpolateVertex(&args->bV, &args->cV, -args->bV.position.x /
116 (args->cV.position.x - args->bV.position.x),
117 &clip0, args->varyingCount);
118 left = &clip0;
119 } else
120 left = &args->bV;
121 if ((int)args->cV.position.x >= (int)args->width) {
122 if (args->bV.position.x >= (int)args->width)
123 break;
124 InterpolateVertex(&args->bV, &args->cV, (args->width - 1 - args->bV.position.x) /
125 (args->cV.position.x - args->bV.position.x),
126 &clip1, args->varyingCount);
127 right = &clip1;
128 } else
129 right = &args->cV;
130 args->iface->ScanLine(args->iface, left, right);
131 } while (false);
132 for (unsigned i = 0; i < args->varyingCount; i++) {
133 args->bV.varyings[i] += args->bDx.varyings[i];
134 args->cV.varyings[i] += args->cDx.varyings[i];
135 }
136 args->bV.position += args->bDx.position;
137 args->cV.position += args->cDx.position;
138 args->bV.frontFacingPointCoord += args->bDx.frontFacingPointCoord;
139 args->cV.frontFacingPointCoord += args->cDx.frontFacingPointCoord;
140 }
141
142 pthread_mutex_lock(&args->finishLock);
143 pthread_cond_signal(&args->finishCond);
144 pthread_mutex_unlock(&args->finishLock);
145 }
146 pthread_exit(NULL);
147 return NULL;
148 }
149 #endif
150
RasterTrapezoid(const GGLInterface * iface,const VertexOutput * tl,const VertexOutput * tr,const VertexOutput * bl,const VertexOutput * br)151 static void RasterTrapezoid(const GGLInterface * iface, const VertexOutput * tl,
152 const VertexOutput * tr, const VertexOutput * bl,
153 const VertexOutput * br)
154 {
155 GGL_GET_CONST_CONTEXT(ctx, iface);
156
157 assert(tl->position.x <= tr->position.x && bl->position.x <= br->position.x);
158 assert(tl->position.y <= bl->position.y && tr->position.y <= br->position.y);
159 assert(fabs(tl->position.y - tr->position.y) < 1 && fabs(bl->position.y - br->position.y) < 1);
160
161 const unsigned width = ctx->frameSurface.width, height = ctx->frameSurface.height;
162 const unsigned varyingCount = ctx->CurrentProgram->VaryingSlots;
163
164
165 // tlv-trv and blv-brv are parallel and horizontal
166 VertexOutput tlv(*tl), trv(*tr), blv(*bl), brv(*br);
167 VertexOutput tmp;
168
169 // vertically clip
170
171 if ((int)tlv.position.y < 0) {
172 InterpolateVertex(&tlv, &blv, (0 - tlv.position.y) / (blv.position.y - tlv.position.y),
173 &tmp, varyingCount);
174 tlv = tmp;
175 }
176 if ((int)trv.position.y < 0) {
177 InterpolateVertex(&trv, &brv, (0 - trv.position.y) / (brv.position.y - trv.position.y),
178 &tmp, varyingCount);
179 trv = tmp;
180 }
181 if ((int)blv.position.y >= (int)height) {
182 InterpolateVertex(&tlv, &blv, (height - 1 - tlv.position.y) / (blv.position.y - tlv.position.y),
183 &tmp, varyingCount);
184 blv = tmp;
185 }
186 if ((int)brv.position.y >= (int)height) {
187 InterpolateVertex(&trv, &brv, (height - 1 - trv.position.y) / (brv.position.y - trv.position.y),
188 &tmp, varyingCount);
189 brv = tmp;
190 }
191
192 // // horizontally clip
193 // if ((int)tlv.position.x < 0) {
194 // InterpolateVertex(&tlv, &trv, (0 - tlv.position.x) / (trv.position.x - tlv.position.x),
195 // &tmp, varyingCount);
196 // tlv = tmp;
197 // }
198 // if ((int)blv.position.x < 0) {
199 // InterpolateVertex(&blv, &brv, (0 - blv.position.x) / (brv.position.x - blv.position.x),
200 // &tmp, varyingCount);
201 // blv = tmp;
202 // }
203 // if ((int)trv.position.x >= (int)width) {
204 // InterpolateVertex(&tlv, &trv, (width - 1 - tlv.position.x) / (trv.position.x - tlv.position.x),
205 // &tmp, varyingCount);
206 // trv = tmp;
207 // }
208 // if ((int)brv.position.x >= (int)width) {
209 // InterpolateVertex(&blv, &brv, (width - 1 - blv.position.x) / (brv.position.x - blv.position.x),
210 // &tmp, varyingCount);
211 // brv = tmp;
212 // }
213
214 const unsigned int startY = tlv.position.y;
215 const unsigned int endY = blv.position.y;
216
217 if (endY < startY)
218 return;
219
220 const VectorComp_t yDistInv = VectorComp_t_CTR(1.0f / (endY - startY));
221
222 // bV and cV are left and right vertices on a horizontal line in quad
223 // bDx and cDx are iterators from tlv to blv, trv to brv for bV and cV
224
225 VertexOutput bV(tlv), cV(trv);
226 VertexOutput bDx(blv), cDx(brv);
227
228 for (unsigned i = 0; i < varyingCount; i++) {
229 bDx.varyings[i] -= tlv.varyings[i];
230 bDx.varyings[i] *= yDistInv;
231
232 cDx.varyings[i] -= trv.varyings[i];
233 cDx.varyings[i] *= yDistInv;
234 }
235
236 bDx.position -= tlv.position;
237 bDx.position *= yDistInv;
238
239 cDx.position -= trv.position;
240 cDx.position *= yDistInv;
241
242 bDx.frontFacingPointCoord -= tlv.frontFacingPointCoord; // gl_PointCoord
243 bDx.frontFacingPointCoord *= yDistInv;
244 bDx.frontFacingPointCoord.y = VectorComp_t_Zero; // gl_FrontFacing not interpolated
245 cDx.frontFacingPointCoord -= trv.frontFacingPointCoord; // gl_PointCoord
246 cDx.frontFacingPointCoord *= yDistInv;
247 cDx.frontFacingPointCoord.y = VectorComp_t_Zero; // gl_FrontFacing not interpolated
248
249 #if USE_DUAL_THREAD
250 GGLContext::Worker & args = ctx->worker;
251 if (!ctx->worker.thread) {
252 pthread_attr_t attr;
253 pthread_attr_init(&attr);
254 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
255 int rc = pthread_create(&ctx->worker.thread, &attr, RasterTrapezoidWorker, &args);
256 assert(!rc);
257 // wait for worker to start
258 pthread_cond_wait(&args.finishCond, &args.finishLock);
259 }
260 args.startY = startY + 1;
261 args.endY = endY;
262 if (args.startY <= args.endY) {
263 pthread_mutex_lock(&args.assignLock);
264
265 args.bV = bV;
266 args.cV = cV;
267 for (unsigned i = 0; i < varyingCount; i++) {
268 args.bV.varyings[i] += bDx.varyings[i];
269 bDx.varyings[i] += bDx.varyings[i];
270 args.cV.varyings[i] += cDx.varyings[i];
271 cDx.varyings[i] += cDx.varyings[i];
272 }
273 args.bV.position += bDx.position;
274 bDx.position += bDx.position;
275 args.cV.position += cDx.position;
276 cDx.position += cDx.position;
277 args.bV.frontFacingPointCoord += bDx.frontFacingPointCoord;
278 bDx.frontFacingPointCoord += bDx.frontFacingPointCoord;
279 args.cV.frontFacingPointCoord += cDx.frontFacingPointCoord;
280 cDx.frontFacingPointCoord += cDx.frontFacingPointCoord;
281 args.iface = iface;
282 args.bDx = bDx;
283 args.cDx = cDx;
284 args.varyingCount = varyingCount;
285 args.width = width;
286 args.height = height;
287 args.assignedWork = true;
288
289 pthread_cond_signal(&args.assignCond);
290 pthread_mutex_unlock(&args.assignLock);
291 }
292 #endif
293
294 VertexOutput * left, * right;
295 VertexOutput clip0, clip1;
296
297 for (unsigned y = startY; y <= endY; y += 1 + USE_DUAL_THREAD) {
298 do {
299 if (bV.position.x < 0) {
300 if (cV.position.x < 0)
301 break;
302 InterpolateVertex(&bV, &cV, -bV.position.x / (cV.position.x - bV.position.x),
303 &clip0, varyingCount);
304 left = &clip0;
305 } else
306 left = &bV;
307 if ((int)cV.position.x >= (int)width) {
308 if (bV.position.x >= (int)width)
309 break;
310 InterpolateVertex(&bV, &cV, (width - 1 - bV.position.x) / (cV.position.x - bV.position.x),
311 &clip1, varyingCount);
312 right = &clip1;
313 } else
314 right = &cV;
315 iface->ScanLine(iface, left, right);
316 } while (false);
317 for (unsigned i = 0; i < varyingCount; i++) {
318 bV.varyings[i] += bDx.varyings[i];
319 cV.varyings[i] += cDx.varyings[i];
320 }
321 bV.position += bDx.position;
322 cV.position += cDx.position;
323 bV.frontFacingPointCoord += bDx.frontFacingPointCoord;
324 cV.frontFacingPointCoord += cDx.frontFacingPointCoord;
325 }
326
327 #if USE_DUAL_THREAD
328 if (args.assignedWork)
329 {
330 pthread_cond_wait(&args.finishCond, &args.finishLock);
331 args.assignedWork = false;
332 }
333 #endif
334 }
335
RasterTriangle(const GGLInterface * iface,const VertexOutput * v1,const VertexOutput * v2,const VertexOutput * v3)336 static void RasterTriangle(const GGLInterface * iface, const VertexOutput * v1,
337 const VertexOutput * v2, const VertexOutput * v3)
338 {
339 GGL_GET_CONST_CONTEXT(ctx, iface);
340 const unsigned varyingCount = ctx->CurrentProgram->VaryingSlots;
341 const unsigned height = ctx->frameSurface.height;
342 const VertexOutput * a = v1, * b = v2, * d = v3;
343 //abc is a triangle, bcd is another triangle, they share bc as horizontal edge
344 //c is between a and d, xy is screen coord
345
346 //first sort 3 vertices by MIN y first
347 if (v2->position.y < v1->position.y) {
348 a = v2;
349 b = v1;
350 }
351 if (v3->position.y < a->position.y) {
352 d = b;
353 b = a;
354 a = v3;
355 } else if (v3->position.y < b->position.y) {
356 d = b;
357 b = v3;
358 }
359
360 assert(a->position.y <= b->position.y && b->position.y <= d->position.y);
361
362 VertexOutput cVertex;
363 const VertexOutput* c = &cVertex;
364
365 const VectorComp_t cLerp = (b->position.y - a->position.y) /
366 MAX2(VectorComp_t_One, (d->position.y - a->position.y));
367 // create 4th vertex, same y as b to form two triangles/trapezoids sharing horizontal edge
368 InterpolateVertex(a, d, cLerp, &cVertex, varyingCount);
369
370 if (c->position.x < b->position.x) {
371 const VertexOutput * tmp = c;
372 c = b;
373 b = tmp;
374 }
375
376 if ((int)a->position.y < (int)height && (int)b->position.y >= 0)
377 RasterTrapezoid(iface, a, a, b, c);
378 //b->position.y += VectorComp_t_One;
379 //c->position.y += VectorComp_t_One;
380 if ((int)b->position.y < (int)height && (int)d->position.y >= 0)
381 RasterTrapezoid(iface, b, c, d, d);
382 }
383
DrawTriangle(const GGLInterface * iface,const VertexInput * vin1,const VertexInput * vin2,const VertexInput * vin3)384 static void DrawTriangle(const GGLInterface * iface, const VertexInput * vin1,
385 const VertexInput * vin2, const VertexInput * vin3)
386 {
387 GGL_GET_CONST_CONTEXT(ctx, iface);
388
389 VertexOutput vouts[3];
390 memset(vouts, 0, sizeof(vouts));
391 VertexOutput * v1 = vouts + 0, * v2 = vouts + 1, * v3 = vouts + 2;
392
393 // LOGD("pf2: DrawTriangle");
394
395 // if (!strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source,
396 // "gl_FragColor = color * texture2D(sampler, outTexCoords).a;"))
397 // return;
398
399 // for (unsigned i = 0; i < program->NumShaders; i++)
400 // if (program->Shaders[i]->Source)
401 // LOGD("%s", program->Shaders[i]->Source);
402
403 // if (!strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, ").a;"))
404 // return;
405
406 // LOGD("%s", program->Shaders[MESA_SHADER_VERTEX]->Source);
407 // LOGD("%s", program->Shaders[MESA_SHADER_FRAGMENT]->Source);
408
409 // for (unsigned i = 0; i < program->Attributes->NumParameters; i++) {
410 // const gl_program_parameter & attribute = program->Attributes->Parameters[i];
411 // LOGD("attribute '%s': location=%d slots=%d \n", attribute.Name, attribute.Location, attribute.Slots);
412 // }
413 // for (unsigned i = 0; i < program->Varying->NumParameters; i++) {
414 // const gl_program_parameter & varying = program->Varying->Parameters[i];
415 // LOGD("varying '%s': vs_location=%d fs_location=%d \n", varying.Name, varying.BindLocation, varying.Location);
416 // }
417 // for (unsigned i = 0; i < program->Uniforms->NumUniforms; i++) {
418 // const gl_uniform & uniform = program->Uniforms->Uniforms[i];
419 // LOGD("uniform '%s': location=%d type=%s \n", uniform.Name, uniform.Pos, uniform.Type->name);
420 // }
421
422 // __attribute__ ((aligned (16)))
423 // static const float matrix[16] = {
424 // 1,0,0,0,
425 // 0,1,0,0,
426 // 0,0,1,0,
427 // 0,0,0,1
428 // };
429 //
430 // iface->ShaderUniformMatrix((gl_shader_program *)program, 4, 4, 0, 1, GL_FALSE, matrix);
431
432 iface->ProcessVertex(iface, vin1, v1);
433 iface->ProcessVertex(iface, vin2, v2);
434 iface->ProcessVertex(iface, vin3, v3);
435
436 // __attribute__ ((aligned (16)))
437 // static const float matrix[16] = {
438 // 2,0,0,0,
439 // 0,-2,0,0,
440 // 0,0,-1,0,
441 // -1,1,0,1
442 // };
443
444
445 // float * matrix = program->ValuesUniform[0];
446 // for (unsigned i = 0; i < 4; i++)
447 // LOGD("pf2: DrawTriangle %.2f \t %.2f \t %.2f \t %.2f \n", matrix[i * 4 + 0],
448 // matrix[i * 4 + 1], matrix[i * 4 + 2], matrix[i * 4 + 3]);
449 //// LOGD("color %.02f %.02f %.02f %.02f", program->ValuesUniform[4][0], program->ValuesUniform[4][1],
450 //// program->ValuesUniform[4][2], program->ValuesUniform[4][3]);
451 // LOGD("vin1 position %.02f %.02f %.02f %.02f", vin1->attributes[1].x, vin1->attributes[1].y,
452 // vin1->attributes[1].z, vin1->attributes[1].w);
453 // LOGD("vin2 position %.02f %.02f %.02f %.02f", vin2->attributes[1].x, vin2->attributes[1].y,
454 // vin2->attributes[1].z, vin2->attributes[1].w);
455 // LOGD("vin3 position %.02f %.02f %.02f %.02f", vin3->attributes[1].x, vin3->attributes[1].y,
456 // vin3->attributes[1].z, vin3->attributes[1].w);
457
458 // GGLProcessVertex(program, vin1, v1, (const float (*)[4])matrix);
459 // GGLProcessVertex(program, vin2, v2, (const float (*)[4])matrix);
460 // GGLProcessVertex(program, vin3, v3, (const float (*)[4])matrix);
461
462 // LOGD("pf2: DrawTriangle processed %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f",
463 // v1->position.x, v1->position.y, v1->position.z, v1->position.w,
464 // v2->position.x, v2->position.y, v2->position.z, v2->position.w,
465 // v3->position.x, v3->position.y, v3->position.z, v3->position.w);
466
467 v1->position /= v1->position.w;
468 v2->position /= v2->position.w;
469 v3->position /= v3->position.w;
470
471 // LOGD("pf2: DrawTriangle divided %.02f,%.02f \t %.02f,%.02f \t %.02f,%.02f", v1->position.x, v1->position.y,
472 // v2->position.x, v2->position.y, v3->position.x, v3->position.y);
473
474 iface->ViewportTransform(iface, &v1->position);
475 iface->ViewportTransform(iface, &v2->position);
476 iface->ViewportTransform(iface, &v3->position);
477
478 // if (strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source,
479 // "gl_FragColor = color * texture2D(sampler, outTexCoords).a;")) {
480 //// LOGD("%s", program->Shaders[MESA_SHADER_FRAGMENT]->Source);
481 // v1->position = vin1->attributes[0];
482 // v2->position = vin2->attributes[0];
483 // v3->position = vin3->attributes[0];
484 //
485 // v1->varyings[0] = vin1->attributes[1];
486 // v2->varyings[0] = vin2->attributes[1];
487 // v3->varyings[0] = vin3->attributes[1];
488 // }
489
490 // LOGD("pf2: DrawTriangle transformed %.0f,%.0f \t %.0f,%.0f \t %.0f,%.0f", v1->position.x, v1->position.y,
491 // v2->position.x, v2->position.y, v3->position.x, v3->position.y);
492
493 // LOGD("pf2: DrawTriangle varying %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f",
494 // v1->varyings[0].x, v1->varyings[0].y, v1->varyings[0].z, v1->varyings[0].w,
495 // v2->varyings[0].x, v2->varyings[0].y, v2->varyings[0].z, v2->varyings[0].w,
496 // v3->varyings[0].x, v3->varyings[0].y, v3->varyings[0].z, v3->varyings[0].w);
497
498 VectorComp_t area;
499 area = v1->position.x * v2->position.y - v2->position.x * v1->position.y;
500 area += v2->position.x * v3->position.y - v3->position.x * v2->position.y;
501 area += v3->position.x * v1->position.y - v1->position.x * v3->position.y;
502 area *= 0.5f;
503
504 if (GL_CCW == ctx->cullState.frontFace + GL_CW)
505 (unsigned &)area ^= 0x80000000;
506
507 if (false && ctx->cullState.enable) { // TODO: turn off for now
508 switch (ctx->cullState.cullFace + GL_FRONT) {
509 case GL_FRONT:
510 if (!((unsigned &)area & 0x80000000)) // +ve, front facing
511 return;
512 break;
513 case GL_BACK:
514 if ((unsigned &)area & 0x80000000) // -ve, back facing
515 return;
516 break;
517 case GL_FRONT_AND_BACK:
518 return;
519 default:
520 assert(0);
521 }
522 }
523
524 v1->frontFacingPointCoord.y = v2->frontFacingPointCoord.y =
525 v3->frontFacingPointCoord.y = !((unsigned &)area & 0x80000000) ?
526 VectorComp_t_One : VectorComp_t_Zero;
527
528 iface->StencilSelect(iface, ((unsigned &)area & 0x80000000) ? GL_BACK : GL_FRONT);
529
530 // if (0)
531 // {
532 // GGLContext * ctx =(GGLContext *)iface;
533 // for (unsigned sampler = 0; sampler < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; sampler++)
534 // {
535 // if (!((1 << sampler) & ctx->glCtx->Shader.CurrentProgram->FragmentProgram->SamplersUsed))
536 // continue;
537 // const GGLTexture * texture = ctx->textureState.textures + sampler;
538 // int level = texture->width * texture->height / (area * 2) - 4;
539 // assert(texture->levels);
540 // ctx->textureState.textureData[sampler] = texture->levels[0];
541 // ctx->textureState.textureDimensions[sampler * 2] = texture->width;
542 // ctx->textureState.textureDimensions[sampler * 2 + 1] = texture->height;
543 // for (unsigned i = 1; i < texture->levelCount && i <= level; i++)
544 // {
545 // ctx->textureState.textureData[sampler] = texture->levels[i];
546 // ctx->textureState.textureDimensions[sampler * 2] += 1;
547 // ctx->textureState.textureDimensions[sampler * 2] /= 2;
548 // ctx->textureState.textureDimensions[sampler * 2 + 1] += 1;
549 // ctx->textureState.textureDimensions[sampler * 2 + 1] /= 2;
550 // }
551 // }
552 // }
553
554 // TODO DXL view frustum clipping
555 iface->RasterTriangle(iface, v1, v2, v3);
556
557 // LOGD("pf2: DrawTriangle end");
558
559 }
560
PickRaster(GGLInterface * iface)561 static void PickRaster(GGLInterface * iface)
562 {
563 iface->ProcessVertex = ProcessVertex;
564 iface->DrawTriangle = DrawTriangle;
565 iface->RasterTriangle = RasterTriangle;
566 iface->RasterTrapezoid = RasterTrapezoid;
567 }
568
ViewportTransform(const GGLInterface * iface,Vector4 * v)569 static void ViewportTransform(const GGLInterface * iface, Vector4 * v)
570 {
571 GGL_GET_CONST_CONTEXT(ctx, iface);
572 v->x = v->x * ctx->viewport.w + ctx->viewport.x;
573 v->y *= -1;
574 v->y = v->y * ctx->viewport.h + ctx->viewport.y;
575 v->z = v->z * ctx->viewport.f + ctx->viewport.n;
576 }
577
578
InitializeRasterFunctions(GGLInterface * iface)579 void InitializeRasterFunctions(GGLInterface * iface)
580 {
581 GGL_GET_CONTEXT(ctx, iface);
582 ctx->PickRaster = PickRaster;
583 iface->ViewportTransform = ViewportTransform;
584 }
585