⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trap.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* libs/pixelflinger/trap.cpp**** Copyright 2006, The Android Open Source Project**** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ****     http://www.apache.org/licenses/LICENSE-2.0 **** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License.*/#include <assert.h>#include <stdio.h>#include <stdlib.h>#include "trap.h"#include "picker.h"#include <cutils/log.h>#include <cutils/memory.h>namespace android {// ----------------------------------------------------------------------------// enable to see triangles edges#define DEBUG_TRANGLES  0// ----------------------------------------------------------------------------static void pointx_validate(void *con, const GGLcoord* c, GGLcoord r);static void pointx(void *con, const GGLcoord* c, GGLcoord r);static void aa_pointx(void *con, const GGLcoord* c, GGLcoord r);static void aa_nice_pointx(void *con, const GGLcoord* c, GGLcoord r);static void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);static void recti_validate(void* c, GGLint l, GGLint t, GGLint r, GGLint b); static void recti(void* c, GGLint l, GGLint t, GGLint r, GGLint b); static void trianglex_validate(void*,        const GGLcoord*, const GGLcoord*, const GGLcoord*);static void trianglex_small(void*,        const GGLcoord*, const GGLcoord*, const GGLcoord*);static void trianglex_big(void*,        const GGLcoord*, const GGLcoord*, const GGLcoord*);static void aa_trianglex(void*,        const GGLcoord*, const GGLcoord*, const GGLcoord*);static void trianglex_debug(void* con,        const GGLcoord*, const GGLcoord*, const GGLcoord*);static void aapolyx(void* con,        const GGLcoord* pts, int count);static inline int min(int a, int b) CONST;static inline int max(int a, int b) CONST;static inline int min(int a, int b, int c) CONST;static inline int max(int a, int b, int c) CONST;// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Tools#endifinline int min(int a, int b) {    return a<b ? a : b;}inline int max(int a, int b) {    return a<b ? b : a;}inline int min(int a, int b, int c) {    return min(a,min(b,c));}inline int max(int a, int b, int c) {    return max(a,max(b,c));}template <typename T>static inline void swap(T& a, T& b) {    T t(a);    a = b;    b = t;}static voidtriangle_dump_points( const GGLcoord*  v0,                      const GGLcoord*  v1,				 	  const GGLcoord*  v2 ){    float tri = 1.0f / TRI_ONE;  LOGD(     "  P0=(%.3f, %.3f)  [%08x, %08x]\n"            "  P1=(%.3f, %.3f)  [%08x, %08x]\n"            "  P2=(%.3f, %.3f)  [%08x, %08x]\n",		v0[0]*tri, v0[1]*tri, v0[0], v0[1],		v1[0]*tri, v1[1]*tri, v1[0], v1[1],		v2[0]*tri, v2[1]*tri, v2[0], v2[1] );}// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Misc#endifvoid ggl_init_trap(context_t* c){    ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE|GGL_TMU_STATE|GGL_CB_STATE);}void ggl_state_changed(context_t* c, int flags){    if (ggl_likely(!c->dirty)) {        c->procs.pointx     = pointx_validate;        c->procs.linex      = linex_validate;        c->procs.recti      = recti_validate;        c->procs.trianglex  = trianglex_validate;    }    c->dirty |= uint32_t(flags);}// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Point#endifvoid pointx_validate(void *con, const GGLcoord* v, GGLcoord rad){    GGL_CONTEXT(c, con);    ggl_pick(c);    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {        if (c->state.enables & GGL_ENABLE_POINT_AA_NICE) {            c->procs.pointx = aa_nice_pointx;        } else {            c->procs.pointx = aa_pointx;        }    } else {        c->procs.pointx = pointx;    }    c->procs.pointx(con, v, rad);}void pointx(void *con, const GGLcoord* v, GGLcoord rad){    GGL_CONTEXT(c, con);    GGLcoord halfSize = TRI_ROUND(rad) >> 1;    if (halfSize == 0)        halfSize = TRI_HALF;    GGLcoord xc = v[0];     GGLcoord yc = v[1];    if (halfSize & TRI_HALF) { // size odd        xc = TRI_FLOOR(xc) + TRI_HALF;        yc = TRI_FLOOR(yc) + TRI_HALF;    } else { // size even        xc = TRI_ROUND(xc);        yc = TRI_ROUND(yc);    }    GGLint l = (xc - halfSize) >> TRI_FRACTION_BITS;    GGLint t = (yc - halfSize) >> TRI_FRACTION_BITS;    GGLint r = (xc + halfSize) >> TRI_FRACTION_BITS;    GGLint b = (yc + halfSize) >> TRI_FRACTION_BITS;    recti(c, l, t, r, b);}// This way of computing the coverage factor, is more accurate and gives// better results for small circles, but it is also a lot slower.// Here we use super-sampling.static int32_t coverageNice(GGLcoord x, GGLcoord y,         GGLcoord rmin, GGLcoord rmax, GGLcoord rr){    const GGLcoord d2 = x*x + y*y;    if (d2 >= rmax) return 0;    if (d2 < rmin)  return 0x7FFF;    const int kSamples              =  4;    const int kInc                  =  4;    // 1/4 = 0.25    const int kCoverageUnit         =  1;    // 1/(4^2) = 0.0625    const GGLcoord kCoordOffset     = -6;    // -0.375    int hits = 0;    int x_sample = x + kCoordOffset;    for (int i=0 ; i<kSamples ; i++, x_sample += kInc) {        const int xval = rr - (x_sample * x_sample);        int y_sample = y + kCoordOffset;        for (int j=0 ; j<kSamples ; j++, y_sample += kInc) {            if (xval - (y_sample * y_sample) > 0)                hits += kCoverageUnit;        }    }    return min(0x7FFF, hits << (15 - kSamples));}void aa_nice_pointx(void *con, const GGLcoord* v, GGLcoord size){    GGL_CONTEXT(c, con);    GGLcoord rad = ((size + 1)>>1);    GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS;    GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS;    GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;    GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;    GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF;     GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF;     // scissor...    if (l < GGLint(c->state.scissor.left)) {        xstart += TRI_FROM_INT(c->state.scissor.left-l);        l = GGLint(c->state.scissor.left);    }    if (t < GGLint(c->state.scissor.top)) {        ystart += TRI_FROM_INT(c->state.scissor.top-t);        t = GGLint(c->state.scissor.top);    }    if (r > GGLint(c->state.scissor.right)) {        r = GGLint(c->state.scissor.right);    }    if (b > GGLint(c->state.scissor.bottom)) {        b = GGLint(c->state.scissor.bottom);    }    int xc = r - l;    int yc = b - t;    if (xc>0 && yc>0) {        int16_t* covPtr = c->state.buffers.coverage;        const int32_t sqr2Over2 = 0xC; // rounded up        GGLcoord rr = rad*rad;        GGLcoord rmin = (rad - sqr2Over2)*(rad - sqr2Over2);        GGLcoord rmax = (rad + sqr2Over2)*(rad + sqr2Over2);        GGLcoord y = ystart;        c->iterators.xl = l;        c->iterators.xr = r;        c->init_y(c, t);        do {            // compute coverage factors for each pixel            GGLcoord x = xstart;            for (int i=l ; i<r ; i++) {                covPtr[i] = coverageNice(x, y, rmin, rmax, rr);                x += TRI_ONE;            }            y += TRI_ONE;            c->scanline(c);            c->step_y(c);        } while (--yc);    }}// This is a cheap way of computing the coverage factor for a circle.// We just lerp between the circles of radii r-sqrt(2)/2 and r+sqrt(2)/2static inline int32_t coverageFast(GGLcoord x, GGLcoord y,        GGLcoord rmin, GGLcoord rmax, GGLcoord scale){    const GGLcoord d2 = x*x + y*y;    if (d2 >= rmax) return 0;    if (d2 < rmin)  return 0x7FFF;    return 0x7FFF - (d2-rmin)*scale;}void aa_pointx(void *con, const GGLcoord* v, GGLcoord size){    GGL_CONTEXT(c, con);    GGLcoord rad = ((size + 1)>>1);    GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS;    GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS;    GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;    GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;    GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF;     GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF;     // scissor...    if (l < GGLint(c->state.scissor.left)) {        xstart += TRI_FROM_INT(c->state.scissor.left-l);        l = GGLint(c->state.scissor.left);    }    if (t < GGLint(c->state.scissor.top)) {        ystart += TRI_FROM_INT(c->state.scissor.top-t);        t = GGLint(c->state.scissor.top);    }    if (r > GGLint(c->state.scissor.right)) {        r = GGLint(c->state.scissor.right);    }    if (b > GGLint(c->state.scissor.bottom)) {        b = GGLint(c->state.scissor.bottom);    }    int xc = r - l;    int yc = b - t;    if (xc>0 && yc>0) {        int16_t* covPtr = c->state.buffers.coverage;        rad <<= 4;        const int32_t sqr2Over2 = 0xB5;    // fixed-point 24.8        GGLcoord rmin = rad - sqr2Over2;        GGLcoord rmax = rad + sqr2Over2;        GGLcoord scale;        rmin *= rmin;        rmax *= rmax;        scale = 0x800000 / (rmax - rmin);        rmin >>= 8;        rmax >>= 8;        GGLcoord y = ystart;        c->iterators.xl = l;        c->iterators.xr = r;        c->init_y(c, t);        do {            // compute coverage factors for each pixel            GGLcoord x = xstart;            for (int i=l ; i<r ; i++) {                covPtr[i] = coverageFast(x, y, rmin, rmax, scale);                x += TRI_ONE;            }            y += TRI_ONE;            c->scanline(c);            c->step_y(c);        } while (--yc);    }}// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Line#endifvoid linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w){    GGL_CONTEXT(c, con);    ggl_pick(c);    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {        c->procs.linex = aa_linex;    } else {        c->procs.linex = linex;    }    c->procs.linex(con, v0, v1, w);}static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width){    GGL_CONTEXT(c, con);    GGLcoord v[4][2];    v[0][0] = v0[0];    v[0][1] = v0[1];    v[1][0] = v1[0];    v[1][1] = v1[1];    v0 = v[0];    v1 = v[1];    const GGLcoord dx = abs(v0[0] - v1[0]);    const GGLcoord dy = abs(v0[1] - v1[1]);    GGLcoord nx, ny;    nx = ny = 0;    GGLcoord halfWidth = TRI_ROUND(width) >> 1;    if (halfWidth == 0)        halfWidth = TRI_HALF;    ((dx > dy) ? ny : nx) = halfWidth;    v[2][0] = v1[0];    v[2][1] = v1[1];    v[3][0] = v0[0];    v[3][1] = v0[1];    v[0][0] += nx;      v[0][1] += ny;    v[1][0] += nx;      v[1][1] += ny;    v[2][0] -= nx;      v[2][1] -= ny;    v[3][0] -= nx;      v[3][1] -= ny;    trianglex_big(con, v[0], v[1], v[2]);    trianglex_big(con, v[0], v[2], v[3]);}static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width){    GGL_CONTEXT(c, con);    GGLcoord v[4][2];    v[0][0] = v0[0];    v[0][1] = v0[1];    v[1][0] = v1[0];    v[1][1] = v1[1];    v0 = v[0];    v1 = v[1];        const GGLcoord dx = v0[0] - v1[0];    const GGLcoord dy = v0[1] - v1[1];    GGLcoord nx = -dy;    GGLcoord ny =  dx;    // generally, this will be well below 1.0    const GGLfixed norm = gglMulx(width, gglSqrtRecipx(nx*nx+ny*ny), 4);    nx = gglMulx(nx, norm, 21);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -