primitives.cpp revision e09fd9e819c23dc90bca68375645e15544861330
17c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project/* libs/opengles/primitives.cpp
27c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project**
37c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** Copyright 2006, The Android Open Source Project
47c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project**
57c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
67c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** you may not use this file except in compliance with the License.
77c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** You may obtain a copy of the License at
87c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project**
97c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project**
117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** See the License for the specific language governing permissions and
157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project** limitations under the License.
167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project*/
177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include <stdio.h>
197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include <stdlib.h>
207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include <math.h>
217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "context.h"
237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "primitives.h"
247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "light.h"
257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "matrix.h"
267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "vertex.h"
277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "fp.h"
287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#include "TextureObjectManager.h"
297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectextern "C" void iterators0032(const void* that,
317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t* it, int32_t c0, int32_t c1, int32_t c2);
327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectnamespace android {
347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void primitive_point(ogles_context_t* c, vertex_t* v);
387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void primitive_clip_triangle(ogles_context_t* c,
407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void primitive_nop_point(ogles_context_t* c, vertex_t* v);
437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void primitive_nop_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void primitive_nop_triangle(ogles_context_t* c,
457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline bool cull_triangle(ogles_context_t* c,
487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lerp_triangle(ogles_context_t* c,
517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lerp_texcoords(ogles_context_t* c,
547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lerp_texcoords_w(ogles_context_t* c,
577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void triangle(ogles_context_t* c,
607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void clip_triangle(ogles_context_t* c,
637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2);
647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic unsigned int clip_line(ogles_context_t* c,
667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* s, vertex_t* p);
677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#if 0
707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark -
717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#endif
727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleDarkSmooth(ogles_context_t* c,
747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v0->flags & vertex_t::LIT)) {
777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        v0->flags |= vertex_t::LIT;
787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                v0->index & vertex_cache_t::INDEX_MASK);
807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->arrays.color.fetch(c, v0->color.v, cp);
817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v1->flags & vertex_t::LIT)) {
837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        v1->flags |= vertex_t::LIT;
847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                v1->index & vertex_cache_t::INDEX_MASK);
867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->arrays.color.fetch(c, v1->color.v, cp);
877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if(!(v2->flags & vertex_t::LIT)) {
897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        v2->flags |= vertex_t::LIT;
907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                v2->index & vertex_cache_t::INDEX_MASK);
927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->arrays.color.fetch(c, v2->color.v, cp);
937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleDarkFlat(ogles_context_t* c,
977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v2->flags & vertex_t::LIT)) {
1007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        v2->flags |= vertex_t::LIT;
1017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
1027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                v2->index & vertex_cache_t::INDEX_MASK);
1037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->arrays.color.fetch(c, v2->color.v, cp);
1047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
1057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // configure the rasterizer here, before we clip
1067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
1077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleSmooth(ogles_context_t* c,
1107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
1117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v0->flags & vertex_t::LIT))
1137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lighting.lightVertex(c, v0);
1147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v1->flags & vertex_t::LIT))
1157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lighting.lightVertex(c, v1);
1167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if(!(v2->flags & vertex_t::LIT))
1177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lighting.lightVertex(c, v2);
1187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleFlat(ogles_context_t* c,
1217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
1227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v2->flags & vertex_t::LIT))
1247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lighting.lightVertex(c, v2);
1257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // configure the rasterizer here, before we clip
1267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
1277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// The fog versions...
1307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
1327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid lightVertexDarkSmoothFog(ogles_context_t* c, vertex_t* v)
1337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v->flags & vertex_t::LIT)) {
1357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        v->flags |= vertex_t::LIT;
136e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        v->fog = c->fog.fog(c, v->eye.z);
1377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLvoid* cp = c->arrays.color.element(
1387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                v->index & vertex_cache_t::INDEX_MASK);
1397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->arrays.color.fetch(c, v->color.v, cp);
1407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
1417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
1437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid lightVertexDarkFlatFog(ogles_context_t* c, vertex_t* v)
1447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v->flags & vertex_t::LIT)) {
1467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        v->flags |= vertex_t::LIT;
147e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        v->fog = c->fog.fog(c, v->eye.z);
1487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
1497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
1517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid lightVertexSmoothFog(ogles_context_t* c, vertex_t* v)
1527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(v->flags & vertex_t::LIT)) {
154e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        v->fog = c->fog.fog(c, v->eye.z);
1557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lighting.lightVertex(c, v);
1567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
1577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleDarkSmoothFog(ogles_context_t* c,
1607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
1617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkSmoothFog(c, v0);
1637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkSmoothFog(c, v1);
1647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkSmoothFog(c, v2);
1657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleDarkFlatFog(ogles_context_t* c,
1687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
1697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkFlatFog(c, v0);
1717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkFlatFog(c, v1);
1727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkSmoothFog(c, v2);
1737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // configure the rasterizer here, before we clip
1747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
1757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleSmoothFog(ogles_context_t* c,
1787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
1797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexSmoothFog(c, v0);
1817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexSmoothFog(c, v1);
1827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexSmoothFog(c, v2);
1837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic void lightTriangleFlatFog(ogles_context_t* c,
1867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
1877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
1887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkFlatFog(c, v0);
1897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexDarkFlatFog(c, v1);
1907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightVertexSmoothFog(c, v2);
1917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // configure the rasterizer here, before we clip
1927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.color4xv(c, v2->color.v);
1937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
1947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
1977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projecttypedef void (*light_primitive_t)(ogles_context_t*,
1987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t*, vertex_t*, vertex_t*);
1997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// fog 0x4, light 0x2, smooth 0x1
2017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic const light_primitive_t lightPrimitive[8] = {
2027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleDarkFlat,          // no fog | dark  | flat
2037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleDarkSmooth,        // no fog | dark  | smooth
2047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleFlat,              // no fog | light | flat
2057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleSmooth,            // no fog | light | smooth
2067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleDarkFlatFog,       // fog    | dark  | flat
2077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleDarkSmoothFog,     // fog    | dark  | smooth
2087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleFlatFog,           // fog    | light | flat
2097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    lightTriangleSmoothFog          // fog    | light | smooth
2107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project};
2117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid ogles_validate_primitives(ogles_context_t* c)
2137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
2147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
2157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // set up the lighting/shading/smoothing/fogging function
2177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int index = enables & GGL_ENABLE_SMOOTH ? 0x1 : 0;
2187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    index |= c->lighting.enable ? 0x2 : 0;
2197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    index |= enables & GGL_ENABLE_FOG ? 0x4 : 0;
2207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->lighting.lightTriangle = lightPrimitive[index];
2217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // set up the primitive renderers
2237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_likely(c->arrays.vertex.enable)) {
2247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->prims.renderPoint    = primitive_point;
2257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->prims.renderLine     = primitive_line;
2267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->prims.renderTriangle = primitive_clip_triangle;
2277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    } else {
2287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->prims.renderPoint    = primitive_nop_point;
2297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->prims.renderLine     = primitive_nop_line;
2307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->prims.renderTriangle = primitive_nop_triangle;
2317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
2327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
2337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
2357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid compute_iterators_t::initTriangle(
2377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t const* v0, vertex_t const* v1, vertex_t const* v2)
2387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
2397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dx01 = v1->window.x - v0->window.x;
2407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dy10 = v0->window.y - v1->window.y;
2417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dx20 = v0->window.x - v2->window.x;
2427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dy02 = v2->window.y - v0->window.y;
2437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
2447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
2457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
246e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Projectvoid compute_iterators_t::initLine(
247e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        vertex_t const* v0, vertex_t const* v1)
248e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project{
249e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    m_dx01 = m_dy02 = v1->window.x - v0->window.x;
250e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    m_dy10 = m_dx20 = v0->window.y - v1->window.y;
251e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
252e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project}
253e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project
2547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid compute_iterators_t::initLerp(vertex_t const* v0, uint32_t enables)
2557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
2567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_x0 = v0->window.x;
2577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_y0 = v0->window.y;
2587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const GGLcoord area = (m_area + TRI_HALF) >> TRI_FRACTION_BITS;
259e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    const GGLcoord minArea = 2; // cannot be inverted
2607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // triangles with an area smaller than 1.0 are not smooth-shaded
2617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int q=0, s=0, d=0;
2637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (abs(area) >= minArea) {
2647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // Here we do some voodoo magic, to compute a suitable scale
2657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // factor for deltas/area:
2667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // First compute the 1/area with full 32-bits precision,
2687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // gglRecipQNormalized returns a number [-0.5, 0.5[ and an exponent.
2697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        d = gglRecipQNormalized(area, &q);
2707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // Then compute the minimum left-shift to not overflow the muls
2727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // below.
2737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        s = 32 - gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
2747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // We'll keep 16-bits of precision for deltas/area. So we need
2767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // to shift everything left an extra 15 bits.
2777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        s += 15;
2787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // make sure all final shifts are not > 32, because gglMulx
2807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // can't handle it.
2817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (s < q) s = q;
2827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (s > 32) {
2837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            d >>= 32-s;
2847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s = 32;
2857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
2867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
2877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dx01 = gglMulx(m_dx01, d, s);
2897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dy10 = gglMulx(m_dy10, d, s);
2907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dx20 = gglMulx(m_dx20, d, s);
2917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_dy02 = gglMulx(m_dy02, d, s);
2927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_area_scale = 32 + q - s;
2937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    m_scale = 0;
2947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
2957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_TMUS) {
2967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const int A = gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
2977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const int B = gglClz(abs(m_x0)|abs(m_y0));
2987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        m_scale = max(0, 32 - (A + 16)) +
2997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                  max(0, 32 - (B + TRI_FRACTION_BITS)) + 1;
3007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
3017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
3027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
3037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectint compute_iterators_t::iteratorsScale(GGLfixed* it,
3047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
3057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
3067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dc01 = c1 - c0;
3077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dc02 = c2 - c0;
3087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int A = gglClz(abs(c0));
3097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int B = gglClz(abs(dc01)|abs(dc02));
3107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int scale = min(A, B - m_scale) - 2;
3117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (scale >= 0) {
3127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c0   <<= scale;
3137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        dc01 <<= scale;
3147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        dc02 <<= scale;
3157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    } else {
3167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c0   >>= -scale;
3177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        dc01 >>= -scale;
3187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        dc02 >>= -scale;
3197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
3207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int s = m_area_scale;
3217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
3227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
3237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
3247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
3257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[0] = c;
3267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[1] = dcdx;
3277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[2] = dcdy;
3287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return scale;
3297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
3307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
3317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid compute_iterators_t::iterators1616(GGLfixed* it,
3327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        GGLfixed c0, GGLfixed c1, GGLfixed c2) const
3337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
3347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const GGLfixed dc01 = c1 - c0;
3357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const GGLfixed dc02 = c2 - c0;
3367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // 16.16 x 16.16 == 32.32 --> 16.16
3377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int s = m_area_scale;
3387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
3397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
3407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
3417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
3427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[0] = c;
3437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[1] = dcdx;
3447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[2] = dcdy;
3457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
3467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
347e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Projectvoid compute_iterators_t::iterators0032(int64_t* it,
3487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
3497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
3507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int s = m_area_scale - 16;
3517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dc01 = (c1 - c0)>>s;
3527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t dc02 = (c2 - c0)>>s;
3537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // 16.16 x 16.16 == 32.32
3547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int64_t dcdx = gglMulii(dc01, m_dy02) + gglMulii(dc02, m_dy10);
3557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int64_t dcdy = gglMulii(dc02, m_dx01) + gglMulii(dc01, m_dx20);
356e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    it[ 0] = (c0<<16) - ((dcdx*m_x0 + dcdy*m_y0)>>4);
3577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[ 1] = dcdx;
3587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    it[ 2] = dcdy;
3597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
360e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project
361e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project#if defined(__arm__) && !defined(__thumb__)
362e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Projectinline void compute_iterators_t::iterators0032(int32_t* it,
363e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
364e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project{
365e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    ::iterators0032(this, it, c0, c1, c2);
366e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project}
367e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project#else
368e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Projectvoid compute_iterators_t::iterators0032(int32_t* it,
369e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        int32_t c0, int32_t c1, int32_t c2) const
370e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project{
371e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    int64_t it64[3];
372e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    iterators0032(it, c0, c1, c2);
373e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    it[0] = it64[0];
374e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    it[1] = it64[1];
375e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    it[2] = it64[2];
376e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project}
3777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#endif
3787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
3797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
3807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
3817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline int32_t clampZ(GLfixed z) CONST;
3827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectint32_t clampZ(GLfixed z) {
3837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    z = (z & ~(z>>31));
3847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (z >= 0x10000)
3857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        z = 0xFFFF;
3867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return z;
3877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
3887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
3897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic __attribute__((noinline))
3907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid fetch_texcoord_impl(ogles_context_t* c,
3917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
3927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
3937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t* const vtx[3] = { v0, v1, v2 };
3947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    array_t const * const texcoordArray = c->arrays.texture;
3957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
3967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
3977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (!(c->rasterizer.state.texture[i].enable))
3987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            continue;
3997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        for (int j=0 ; j<3 ; j++) {
4017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            vertex_t* const v = vtx[j];
4027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (v->flags & vertex_t::TT)
4037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                continue;
4047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            // NOTE: here we could compute automatic texgen
4067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            // such as sphere/cube maps, instead of fetching them
4077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            // from the textcoord array.
4087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            vec4_t& coords = v->texture[i];
4107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GLubyte* tp = texcoordArray[i].element(
4117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    v->index & vertex_cache_t::INDEX_MASK);
4127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            texcoordArray[i].fetch(c, coords.v, tp);
4137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            // transform texture coordinates...
4157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            coords.Q = 0x10000;
4167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const transform_t& tr = c->transforms.texture[i].transform;
4177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (ggl_unlikely(tr.ops)) {
4187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                c->arrays.tex_transform[i](&tr, &coords, &coords);
4197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
4207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            // divide by Q
4227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GGLfixed q = coords.Q;
4237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (ggl_unlikely(q != 0x10000)) {
4247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const int32_t qinv = gglRecip28(q);
4257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                coords.S = gglMulx(coords.S, qinv, 28);
4267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                coords.T = gglMulx(coords.T, qinv, 28);
4277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
4287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
4297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
4307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    v0->flags |= vertex_t::TT;
4317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    v1->flags |= vertex_t::TT;
4327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    v2->flags |= vertex_t::TT;
4337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
4347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectinline void fetch_texcoord(ogles_context_t* c,
4367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
4377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
4387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
4397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (!(enables & GGL_ENABLE_TMUS))
4407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        return;
4417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // Fetch & transform texture coordinates...
4437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_likely(v0->flags & v1->flags & v2->flags & vertex_t::TT)) {
4447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // already done for all three vertices, bail...
4457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        return;
4467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
4477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    fetch_texcoord_impl(c, v0, v1, v2);
4487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
4497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
4517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#if 0
4527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark -
4537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark Point
4547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#endif
4557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid primitive_nop_point(ogles_context_t*, vertex_t*) {
4577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
4587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid primitive_point(ogles_context_t* c, vertex_t* v)
4607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
4617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // lighting & clamping...
4627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
4637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_unlikely(!(v->flags & vertex_t::LIT))) {
4657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (c->lighting.enable) {
4667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            c->lighting.lightVertex(c, v);
4677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        } else {
4687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            v->flags |= vertex_t::LIT;
4697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GLvoid* cp = c->arrays.color.element(
4707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    v->index & vertex_cache_t::INDEX_MASK);
4717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            c->arrays.color.fetch(c, v->color.v, cp);
4727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
4737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (enables & GGL_ENABLE_FOG) {
474e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project            v->fog = c->fog.fog(c, v->eye.z);
4757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
4767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
4777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // XXX: we don't need to do that each-time
4797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // if color array and lighting not enabled
4807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.color4xv(c, v->color.v);
4817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
4827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // XXX: look into ES point-sprite extension
4837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_TMUS) {
4847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        fetch_texcoord(c, v,v,v);
4857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
4867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (!c->rasterizer.state.texture[i].enable)
4877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                continue;
4887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            int32_t itt[8];
4897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            itt[1] = itt[2] = itt[4] = itt[5] = 0;
4907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            itt[6] = itt[7] = 16; // XXX: check that
4917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (c->rasterizer.state.texture[i].s_wrap == GGL_CLAMP) {
4927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                int width = c->textures.tmu[i].texture->surface.width;
4937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                itt[0] = v->texture[i].S * width;
4947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                itt[6] = 0;
4957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
4967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (c->rasterizer.state.texture[i].t_wrap == GGL_CLAMP) {
4977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                int height = c->textures.tmu[i].texture->surface.height;
4987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                itt[3] = v->texture[i].T * height;
4997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                itt[7] = 0;
5007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
5017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
5027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
5037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
5047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
5067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t itz[3];
5077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itz[0] = clampZ(v->window.z) * 0x00010001;
5087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itz[1] = itz[2] = 0;
5097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, itz);
5107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
5117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_FOG) {
5137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        GLfixed itf[3];
5147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itf[0] = v->fog;
5157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itf[1] = itf[2] = 0;
5167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, itf);
5177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
5187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // Render our point...
5207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.pointx(c, v->window.v, c->point.size);
5217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
5227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
5247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#if 0
5257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark -
5267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark Line
5277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#endif
5287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid primitive_nop_line(ogles_context_t*, vertex_t*, vertex_t*) {
5307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
5317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1)
5337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
5347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // get texture coordinates
5357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    fetch_texcoord(c, v0, v1, v1);
5367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // light/shade the vertices first (they're copied below)
5387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->lighting.lightTriangle(c, v0, v1, v1);
5397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // clip the line if needed
5417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_unlikely((v0->flags | v1->flags) & vertex_t::CLIP_ALL)) {
5427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        unsigned int count = clip_line(c, v0, v1);
5437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (ggl_unlikely(count == 0))
5447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            return;
5457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
5467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // compute iterators...
5487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
5497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t mask =   GGL_ENABLE_TMUS |
5507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_SMOOTH |
5517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_W |
5527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_FOG |
5537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_DEPTH_TEST;
5547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_unlikely(enables & mask)) {
556e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        c->lerp.initLine(v0, v1);
557e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        lerp_triangle(c, v0, v1, v0);
5587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
5597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // render our line
5617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.linex(c, v0->window.v, v1->window.v, c->line.width);
5627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
5637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// ----------------------------------------------------------------------------
5657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#if 0
5667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark -
5677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#pragma mark Triangle
5687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project#endif
5697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid primitive_nop_triangle(ogles_context_t* c,
5717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2) {
5727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
5737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid primitive_clip_triangle(ogles_context_t* c,
5757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
5767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
5777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    uint32_t cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
5787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_likely(!cc)) {
5797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // code below must be as optimized as possible, this is the
5807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // common code path.
5817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // This triangle is not clipped, test if it's culled
5837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // unclipped triangle...
5847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lerp.initTriangle(v0, v1, v2);
5857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (cull_triangle(c, v0, v1, v2))
5867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            return; // culled!
5877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // Fetch all texture coordinates if needed
5897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        fetch_texcoord(c, v0, v1, v2);
5907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // light (or shade) our triangle!
5927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lighting.lightTriangle(c, v0, v1, v2);
5937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        triangle(c, v0, v1, v2);
5957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        return;
5967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
5977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
5987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // The assumption here is that we're not going to clip very often,
5997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // and even more rarely will we clip a triangle that ends up
6007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // being culled out. So it's okay to light the vertices here, even though
6017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // in a few cases we won't render the triangle (if culled).
6027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // Fetch texture coordinates...
6047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    fetch_texcoord(c, v0, v1, v2);
6057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // light (or shade) our triangle!
6077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->lighting.lightTriangle(c, v0, v1, v2);
6087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    clip_triangle(c, v0, v1, v2);
6107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
6117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project// -----------------------------------------------------------------------
6137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid triangle(ogles_context_t* c,
6157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
6167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
6177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // compute iterators...
6187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
6197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t mask =   GGL_ENABLE_TMUS |
6207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_SMOOTH |
6217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_W |
6227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_FOG |
6237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            GGL_ENABLE_DEPTH_TEST;
6247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_likely(enables & mask))
6267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        lerp_triangle(c, v0, v1, v2);
6277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.trianglex(c, v0->window.v, v1->window.v, v2->window.v);
6297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
6307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid lerp_triangle(ogles_context_t* c,
6327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
6337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
6347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t enables = c->rasterizer.state.enables;
6357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->lerp.initLerp(v0, enables);
6367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // set up texture iterators
6387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_TMUS) {
6397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (enables & GGL_ENABLE_W) {
6407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            lerp_texcoords_w(c, v0, v1, v2);
6417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        } else {
6427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            lerp_texcoords(c, v0, v1, v2);
6437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
6447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
6457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // set up the color iterators
6477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
6487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_SMOOTH) {
6497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        GLfixed itc[12];
6507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        for (int i=0 ; i<4 ; i++) {
6517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GGLcolor c0 = v0->color.v[i] * 255;
6527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GGLcolor c1 = v1->color.v[i] * 255;
6537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GGLcolor c2 = v2->color.v[i] * 255;
6547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            lerp.iterators1616(&itc[i*3], c0, c1, c2);
6557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
6567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.colorGrad12xv(c, itc);
6577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
6587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (enables & GGL_ENABLE_DEPTH_TEST) {
6607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t itz[3];
6617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const int32_t v0z = clampZ(v0->window.z);
6627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const int32_t v1z = clampZ(v1->window.z);
6637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const int32_t v2z = clampZ(v2->window.z);
6647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (ggl_unlikely(c->polygonOffset.enable)) {
665e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project            const int32_t units = (c->polygonOffset.units << 16);
6667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const GLfixed factor = c->polygonOffset.factor;
667e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project            if (factor) {
668e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                int64_t itz64[3];
669e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                lerp.iterators0032(itz64, v0z, v1z, v2z);
670e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                int64_t maxDepthSlope = max(itz64[1], itz64[2]);
671e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                itz[0] = uint32_t(itz64[0])
672e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                        + uint32_t((maxDepthSlope*factor)>>16) + units;
673e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                itz[1] = uint32_t(itz64[1]);
674e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                itz[2] = uint32_t(itz64[2]);
675e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project            } else {
676e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                lerp.iterators0032(itz, v0z, v1z, v2z);
677e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                itz[0] += units;
678e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project            }
679e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project        } else {
680e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project            lerp.iterators0032(itz, v0z, v1z, v2z);
6817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
6827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.zGrad3xv(c, itz);
683e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project    }
6847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_unlikely(enables & GGL_ENABLE_FOG)) {
6867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        GLfixed itf[3];
6877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        lerp.iterators1616(itf, v0->fog, v1->fog, v2->fog);
6887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.fogGrad3xv(c, itf);
6897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
6907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
6917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
6937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
6947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectint compute_lod(ogles_context_t* c, int i,
6957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s0, int32_t t0, int32_t s1, int32_t t1, int32_t s2, int32_t t2)
6967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
6977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // Compute mipmap level / primitive
6987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // rho = sqrt( texelArea / area )
6997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // lod = log2( rho )
7007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // lod = log2( texelArea / area ) / 2
7017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // lod = (log2( texelArea ) - log2( area )) / 2
7027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
7037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const GGLcoord area = abs(lerp.area());
7047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int w = c->textures.tmu[i].texture->surface.width;
7057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int h = c->textures.tmu[i].texture->surface.height;
7067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int shift = 16 + (16 - TRI_FRACTION_BITS);
7077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t texelArea = abs( gglMulx(s1-s0, t2-t0, shift) -
7087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            gglMulx(s2-s0, t1-t0, shift) )*w*h;
7097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int log2TArea = (32-TRI_FRACTION_BITS  -1) - gglClz(texelArea);
7107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int log2Area  = (32-TRI_FRACTION_BITS*2-1) - gglClz(area);
7117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int lod = (log2TArea - log2Area + 1) >> 1;
7127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return lod;
7137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
7147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid lerp_texcoords(ogles_context_t* c,
7167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
7177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
7187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
7197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t itt[8] __attribute__((aligned(16)));
7207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
7217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const texture_t& tmu = c->rasterizer.state.texture[i];
7227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (!tmu.enable)
7237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            continue;
7247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // compute the jacobians using block floating-point
7267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s0 = v0->texture[i].S;
7277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t t0 = v0->texture[i].T;
7287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s1 = v1->texture[i].S;
7297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t t1 = v1->texture[i].T;
7307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s2 = v2->texture[i].S;
7317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t t2 = v2->texture[i].T;
7327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
7347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
7357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
7367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            c->rasterizer.procs.bindTextureLod(c, i,
7377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    &c->textures.tmu[i].texture->mip(lod));
7387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
7397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // premultiply (s,t) when clampling
7417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (tmu.s_wrap == GGL_CLAMP) {
7427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const int width = tmu.surface.width;
7437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s0 *= width;
7447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s1 *= width;
7457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s2 *= width;
7467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
7477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (tmu.t_wrap == GGL_CLAMP) {
7487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const int height = tmu.surface.height;
7497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            t0 *= height;
7507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            t1 *= height;
7517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            t2 *= height;
7527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
7537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itt[6] = -lerp.iteratorsScale(itt+0, s0, s1, s2);
7547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itt[7] = -lerp.iteratorsScale(itt+3, t0, t1, t2);
7557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
7567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
7577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
7587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid lerp_texcoords_w(ogles_context_t* c,
7607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
7617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
7627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const compute_iterators_t& lerp = c->lerp;
7637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t itt[8] __attribute__((aligned(16)));
7647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t itw[3];
7657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // compute W's scale to 2.30
7677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t w0 = v0->window.w;
7687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t w1 = v1->window.w;
7697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int32_t w2 = v2->window.w;
7707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int wscale = 32 - gglClz(w0|w1|w2);
7717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // compute the jacobian using block floating-point
7737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    int sc = lerp.iteratorsScale(itw, w0, w1, w2);
7747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    sc +=  wscale - 16;
7757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    c->rasterizer.procs.wGrad3xv(c, itw);
7767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
7787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const texture_t& tmu = c->rasterizer.state.texture[i];
7797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (!tmu.enable)
7807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            continue;
7817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // compute the jacobians using block floating-point
7837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s0 = v0->texture[i].S;
7847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t t0 = v0->texture[i].T;
7857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s1 = v1->texture[i].S;
7867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t t1 = v1->texture[i].T;
7877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t s2 = v2->texture[i].S;
7887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        int32_t t2 = v2->texture[i].T;
7897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
7917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
7927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
7937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            c->rasterizer.procs.bindTextureLod(c, i,
7947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    &c->textures.tmu[i].texture->mip(lod));
7957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
7967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
7977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        // premultiply (s,t) when clampling
7987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (tmu.s_wrap == GGL_CLAMP) {
7997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const int width = tmu.surface.width;
8007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s0 *= width;
8017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s1 *= width;
8027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            s2 *= width;
8037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
8047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (tmu.t_wrap == GGL_CLAMP) {
8057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            const int height = tmu.surface.height;
8067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            t0 *= height;
8077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            t1 *= height;
8087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            t2 *= height;
8097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
8107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        s0 = gglMulx(s0, w0, wscale);
8127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        t0 = gglMulx(t0, w0, wscale);
8137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        s1 = gglMulx(s1, w1, wscale);
8147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        t1 = gglMulx(t1, w1, wscale);
8157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        s2 = gglMulx(s2, w2, wscale);
8167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        t2 = gglMulx(t2, w2, wscale);
8177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itt[6] = sc - lerp.iteratorsScale(itt+0, s0, s1, s2);
8197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        itt[7] = sc - lerp.iteratorsScale(itt+3, t0, t1, t2);
8207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
8217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
8227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
8237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
8267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectbool cull_triangle(ogles_context_t* c, vertex_t* v0, vertex_t* v1, vertex_t* v2)
8277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
8287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_likely(c->cull.enable)) {
8297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLenum winding = (c->lerp.area() > 0) ? GL_CW : GL_CCW;
8307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        const GLenum face = (winding == c->cull.frontFace) ? GL_FRONT : GL_BACK;
8317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (face == c->cull.cullFace)
8327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            return true; // culled!
8337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
8347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return false;
8357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
8367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
8387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source ProjectGLfixed frustumPlaneDist(int plane, const vec4_t& s)
8397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
8407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const GLfixed d = s.v[ plane >> 1 ];
8417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return  ((plane & 1) ? (s.w - d) : (s.w + d));
8427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
8437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectstatic inline
8457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectint32_t clipDivide(GLfixed a, GLfixed b) {
8467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // returns a 4.28 fixed-point
8477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return gglMulDivi(1LU<<28, a, b);
8487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
8497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectvoid clip_triangle(ogles_context_t* c,
8517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        vertex_t* v0, vertex_t* v1, vertex_t* v2)
8527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
8537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    uint32_t all_cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
8547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t *p0, *p1, *p2;
8567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int MAX_CLIPPING_PLANES = 6 + OGLES_MAX_CLIP_PLANES;
8577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const int MAX_VERTICES = 3;
8587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // Temporary buffer to hold the new vertices. Each plane can add up to
8607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // two new vertices (because the polygon is convex).
8617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // We need one extra element, to handle an overflow case when
8627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // the polygon degenerates into something non convex.
8637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t buffer[MAX_CLIPPING_PLANES * 2 + 1];   // ~3KB
8647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t* buf = buffer;
8657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // original list of vertices (polygon to clip, in fact this
8677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // function works with an arbitrary polygon).
8687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t* in[3] = { v0, v1, v2 };
8697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // output lists (we need 2, which we use back and forth)
8717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // (maximum outpout list's size is MAX_CLIPPING_PLANES + MAX_VERTICES)
8727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // 2 more elements for overflow when non convex polygons.
8737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t* out[2][MAX_CLIPPING_PLANES + MAX_VERTICES + 2];
8747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    unsigned int outi = 0;
8757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // current input list
8777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    vertex_t** ivl = in;
8787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // 3 input vertices, 0 in the output list, first plane
8807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    unsigned int ic = 3;
8817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // User clip-planes first, the clipping is always done in eye-coordinate
8837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // this is basically the same algorithm than for the view-volume
8847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // clipping, except for the computation of the distance (vertex, plane)
8857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // and the fact that we need to compute the eye-coordinates of each
8867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // new vertex we create.
8877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
8887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
8897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    {
8907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        unsigned int plane = 0;
8917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
8927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        do {
8937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (cc & 1) {
8947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                // pointers to our output list (head and current)
8957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                vertex_t** const ovl = &out[outi][0];
8967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                vertex_t** output = ovl;
8977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                unsigned int oc = 0;
8987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                unsigned int sentinel = 0;
899e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                // previous vertex, compute distance to the plane
9007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                vertex_t* s = ivl[ic-1];
9017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
9027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                GLfixed sd = dot4(equation.v, s->eye.v);
903e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                // clip each vertex against this plane...
9047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                for (unsigned int i=0 ; i<ic ; i++) {
9057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    vertex_t* p = ivl[i];
9067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    const GLfixed pd = dot4(equation.v, p->eye.v);
9077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    if (sd >= 0) {
9087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        if (pd >= 0) {
9097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            // both inside
9107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            *output++ = p;
9117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            oc++;
9127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        } else {
9137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            // s inside, p outside (exiting)
9147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            const GLfixed t = clipDivide(sd, sd-pd);
9157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            c->arrays.clipEye(c, buf, t, p, s);
9167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            *output++ = buf++;
9177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            oc++;
9187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            if (++sentinel >= 3)
9197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                return; // non-convex polygon!
9207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        }
9217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    } else {
9227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        if (pd >= 0) {
9237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            // s outside (entering)
9247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            if (pd) {
9257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                const GLfixed t = clipDivide(pd, pd-sd);
9267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                c->arrays.clipEye(c, buf, t, s, p);
9277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                *output++ = buf++;
9287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                oc++;
9297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                if (++sentinel >= 3)
9307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                    return; // non-convex polygon!
9317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            }
9327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            *output++ = p;
9337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            oc++;
9347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        } else {
9357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                           // both outside
9367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        }
9377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    }
9387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    s = p;
9397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    sd = pd;
9407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                }
9417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                // output list become the new input list
9427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                if (oc<3)
9437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    return; // less than 3 vertices left? we're done!
9447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                ivl = ovl;
9457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                ic = oc;
9467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                outi = 1-outi;
9477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
9487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            cc >>= 1;
9497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            plane++;
9507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        } while (cc);
9517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
9527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
9537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // frustum clip-planes
9547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
9557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    {
9567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        unsigned int plane = 0;
9577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
9587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        do {
9597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (cc & 1) {
9607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                // pointers to our output list (head and current)
9617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                vertex_t** const ovl = &out[outi][0];
9627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                vertex_t** output = ovl;
9637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                unsigned int oc = 0;
9647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                unsigned int sentinel = 0;
965e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                // previous vertex, compute distance to the plane
9667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                vertex_t* s = ivl[ic-1];
9677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                GLfixed sd = frustumPlaneDist(plane, s->clip);
968e09fd9e819c23dc90bca68375645e15544861330The Android Open Source Project                // clip each vertex against this plane...
9697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                for (unsigned int i=0 ; i<ic ; i++) {
9707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    vertex_t* p = ivl[i];
9717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    const GLfixed pd = frustumPlaneDist(plane, p->clip);
9727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    if (sd >= 0) {
9737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        if (pd >= 0) {
9747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            // both inside
9757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            *output++ = p;
9767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            oc++;
9777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        } else {
9787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            // s inside, p outside (exiting)
9797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            const GLfixed t = clipDivide(sd, sd-pd);
9807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            c->arrays.clipVertex(c, buf, t, p, s);
9817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            *output++ = buf++;
9827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            oc++;
9837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            if (++sentinel >= 3)
9847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                return; // non-convex polygon!
9857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        }
9867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    } else {
9877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        if (pd >= 0) {
9887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            // s outside (entering)
9897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            if (pd) {
9907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                const GLfixed t = clipDivide(pd, pd-sd);
9917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                c->arrays.clipVertex(c, buf, t, s, p);
9927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                *output++ = buf++;
9937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                oc++;
9947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                if (++sentinel >= 3)
9957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                                    return; // non-convex polygon!
9967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            }
9977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            *output++ = p;
9987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            oc++;
9997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        } else {
10007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                           // both outside
10017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        }
10027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    }
10037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    s = p;
10047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    sd = pd;
10057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                }
10067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                // output list become the new input list
10077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                if (oc<3)
10087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    return; // less than 3 vertices left? we're done!
10097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                ivl = ovl;
10107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                ic = oc;
10117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                outi = 1-outi;
10127c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
10137c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            cc >>= 1;
10147c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            plane++;
10157c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        } while (cc);
10167c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
10177c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
10187c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // finally we can render our triangles...
10197c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    p0 = ivl[0];
10207c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    p1 = ivl[1];
10217c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    for (unsigned int i=2 ; i<ic ; i++) {
10227c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        p2 = ivl[i];
10237c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        c->lerp.initTriangle(p0, p1, p2);
10247c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        if (cull_triangle(c, p0, p1, p2)) {
10257c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            p1 = p2;
10267c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            continue; // culled!
10277c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        }
10287c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        triangle(c, p0, p1, p2);
10297c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        p1 = p2;
10307c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
10317c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
10327c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
10337c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Projectunsigned int clip_line(ogles_context_t* c, vertex_t* s, vertex_t* p)
10347c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project{
10357c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    const uint32_t all_cc = (s->flags | p->flags) & vertex_t::CLIP_ALL;
10367c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
10377c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
10387c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    {
10397c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        unsigned int plane = 0;
10407c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
10417c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        do {
10427c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (cc & 1) {
10437c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
10447c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const GLfixed sd = dot4(equation.v, s->eye.v);
10457c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const GLfixed pd = dot4(equation.v, p->eye.v);
10467c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                if (sd >= 0) {
10477c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    if (pd >= 0) {
10487c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        // both inside
10497c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    } else {
10507c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        // s inside, p outside (exiting)
10517c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        const GLfixed t = clipDivide(sd, sd-pd);
10527c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        c->arrays.clipEye(c, p, t, p, s);
10537c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    }
10547c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                } else {
10557c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    if (pd >= 0) {
10567c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        // s outside (entering)
10577c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        if (pd) {
10587c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            const GLfixed t = clipDivide(pd, pd-sd);
10597c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            c->arrays.clipEye(c, s, t, s, p);
10607c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        }
10617c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    } else {
10627c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                       // both outside
10637c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                       return 0;
10647c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    }
10657c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                }
10667c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
10677c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            cc >>= 1;
10687c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            plane++;
10697c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        } while (cc);
10707c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
10717c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
10727c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    // frustum clip-planes
10737c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
10747c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    {
10757c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        unsigned int plane = 0;
10767c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
10777c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        do {
10787c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            if (cc & 1) {
10797c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const GLfixed sd = frustumPlaneDist(plane, s->clip);
10807c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                const GLfixed pd = frustumPlaneDist(plane, p->clip);
10817c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                if (sd >= 0) {
10827c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    if (pd >= 0) {
10837c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        // both inside
10847c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    } else {
10857c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        // s inside, p outside (exiting)
10867c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        const GLfixed t = clipDivide(sd, sd-pd);
10877c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        c->arrays.clipVertex(c, p, t, p, s);
10887c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    }
10897c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                } else {
10907c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    if (pd >= 0) {
10917c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        // s outside (entering)
10927c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        if (pd) {
10937c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            const GLfixed t = clipDivide(pd, pd-sd);
10947c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                            c->arrays.clipVertex(c, s, t, s, p);
10957c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                        }
10967c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    } else {
10977c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                       // both outside
10987c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                       return 0;
10997c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                    }
11007c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project                }
11017c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            }
11027c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            cc >>= 1;
11037c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project            plane++;
11047c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project        } while (cc);
11057c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    }
11067c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
11077c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project    return 2;
11087c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}
11097c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
11107c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project
11117c1b96a165f970a09ed239bb4fb3f1b0d8f2a40The Android Open Source Project}; // namespace android
1112