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