• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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