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

📄 texturing.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* libs/pixelflinger/codeflinger/texturing.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 <stdint.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <cutils/log.h>#include "codeflinger/GGLAssembler.h"namespace android {// ---------------------------------------------------------------------------// iterators are initialized like this:// (intToFixedCenter(x) * dx)>>16 + x0// ((x<<16 + 0x8000) * dx)>>16 + x0// ((x<<16)*dx + (0x8000*dx))>>16 + x0// ( (x*dx) + dx>>1 ) + x0// (x*dx) + (dx>>1 + x0)void GGLAssembler::init_iterated_color(fragment_parts_t& parts, const reg_t& x){    context_t const* c = mBuilderContext.c;    const needs_t& needs = mBuilderContext.needs;    if (mSmooth) {        // NOTE: we could take this case in the mDithering + !mSmooth case,        // but this would use up to 4 more registers for the color components        // for only a little added quality.        // Currently, this causes the system to run out of registers in        // some case (see issue #719496)        comment("compute initial iterated color (smooth and/or dither case)");        parts.iterated_packed = 0;        parts.packed = 0;        // 0x1: color component        // 0x2: iterators        const int optReload = mOptLevel >> 1;        if (optReload >= 3)         parts.reload = 0; // reload nothing        else if (optReload == 2)    parts.reload = 2; // reload iterators        else if (optReload == 1)    parts.reload = 1; // reload colors        else if (optReload <= 0)    parts.reload = 3; // reload both        if (!mSmooth) {            // we're not smoothing (just dithering), we never have to             // reload the iterators            parts.reload &= ~2;        }        Scratch scratches(registerFile());        const int t0 = (parts.reload & 1) ? scratches.obtain() : 0;        const int t1 = (parts.reload & 2) ? scratches.obtain() : 0;        for (int i=0 ; i<4 ; i++) {            if (!mInfo[i].iterated)                continue;                                    // this component exists in the destination and is not replaced            // by a texture unit.            const int c = (parts.reload & 1) ? t0 : obtainReg();                          if (i==0) CONTEXT_LOAD(c, iterators.ydady);            if (i==1) CONTEXT_LOAD(c, iterators.ydrdy);            if (i==2) CONTEXT_LOAD(c, iterators.ydgdy);            if (i==3) CONTEXT_LOAD(c, iterators.ydbdy);            parts.argb[i].reg = c;            if (mInfo[i].smooth) {                parts.argb_dx[i].reg = (parts.reload & 2) ? t1 : obtainReg();                const int dvdx = parts.argb_dx[i].reg;                CONTEXT_LOAD(dvdx, generated_vars.argb[i].dx);                MLA(AL, 0, c, x.reg, dvdx, c);                                // adjust the color iterator to make sure it won't overflow                if (!mAA) {                    // this is not needed when we're using anti-aliasing                    // because we will (have to) clamp the components                    // anyway.                    int end = scratches.obtain();                    MOV(AL, 0, end, reg_imm(parts.count.reg, LSR, 16));                    MLA(AL, 1, end, dvdx, end, c);                    SUB(MI, 0, c, c, end);                    BIC(AL, 0, c, c, reg_imm(c, ASR, 31));                     scratches.recycle(end);                }            }                        if (parts.reload & 1) {                CONTEXT_STORE(c, generated_vars.argb[i].c);            }        }    } else {        // We're not smoothed, so we can         // just use a packed version of the color and extract the        // components as needed (or not at all if we don't blend)        // figure out if we need the iterated color        int load = 0;        for (int i=0 ; i<4 ; i++) {            component_info_t& info = mInfo[i];            if ((info.inDest || info.needed) && !info.replaced)                load |= 1;        }                parts.iterated_packed = 1;        parts.packed = (!mTextureMachine.mask && !mBlending                && !mFog && !mDithering);        parts.reload = 0;        if (load || parts.packed) {            if (mBlending || mDithering || mInfo[GGLFormat::ALPHA].needed) {                comment("load initial iterated color (8888 packed)");                parts.iterated.setTo(obtainReg(),                        &(c->formats[GGL_PIXEL_FORMAT_RGBA_8888]));                CONTEXT_LOAD(parts.iterated.reg, packed8888);            } else {                comment("load initial iterated color (dest format packed)");                parts.iterated.setTo(obtainReg(), &mCbFormat);                // pre-mask the iterated color                const int bits = parts.iterated.size();                const uint32_t size = ((bits>=32) ? 0 : (1LU << bits)) - 1;                uint32_t mask = 0;                if (mMasking) {                    for (int i=0 ; i<4 ; i++) {                        const int component_mask = 1<<i;                        const int h = parts.iterated.format.c[i].h;                        const int l = parts.iterated.format.c[i].l;                        if (h && (!(mMasking & component_mask))) {                            mask |= ((1<<(h-l))-1) << l;                        }                    }                }                if (mMasking && ((mask & size)==0)) {                    // none of the components are present in the mask                } else {                    CONTEXT_LOAD(parts.iterated.reg, packed);                    if (mCbFormat.size == 1) {                        AND(AL, 0, parts.iterated.reg,                                parts.iterated.reg, imm(0xFF));                    } else if (mCbFormat.size == 2) {                        MOV(AL, 0, parts.iterated.reg,                                reg_imm(parts.iterated.reg, LSR, 16));                    }                }                // pre-mask the iterated color                if (mMasking) {                    build_and_immediate(parts.iterated.reg, parts.iterated.reg,                            mask, bits);                }            }        }    }}void GGLAssembler::build_iterated_color(        component_t& fragment,        const fragment_parts_t& parts,        int component,        Scratch& regs){    fragment.setTo( regs.obtain(), 0, 32, CORRUPTIBLE);     if (!mInfo[component].iterated)        return;    if (parts.iterated_packed) {        // iterated colors are packed, extract the one we need        extract(fragment, parts.iterated, component);    } else {        fragment.h = GGL_COLOR_BITS;        fragment.l = GGL_COLOR_BITS - 8;        fragment.flags |= CLEAR_LO;        // iterated colors are held in their own register,        // (smooth and/or dithering case)        if (parts.reload==3) {            // this implies mSmooth            Scratch scratches(registerFile());            int dx = scratches.obtain();            CONTEXT_LOAD(fragment.reg, generated_vars.argb[component].c);            CONTEXT_LOAD(dx, generated_vars.argb[component].dx);            ADD(AL, 0, dx, fragment.reg, dx);            CONTEXT_STORE(dx, generated_vars.argb[component].c);        } else if (parts.reload & 1) {            CONTEXT_LOAD(fragment.reg, generated_vars.argb[component].c);        } else {            // we don't reload, so simply rename the register and mark as            // non CORRUPTIBLE so that the texture env or blending code            // won't modify this (renamed) register            regs.recycle(fragment.reg);            fragment.reg = parts.argb[component].reg;            fragment.flags &= ~CORRUPTIBLE;        }        if (mInfo[component].smooth && mAA) {            // when using smooth shading AND anti-aliasing, we need to clamp            // the iterators because there is always an extra pixel on the            // edges, which most of the time will cause an overflow            // (since technically its outside of the domain).            BIC(AL, 0, fragment.reg, fragment.reg,                    reg_imm(fragment.reg, ASR, 31));            component_sat(fragment);        }    }}// ---------------------------------------------------------------------------void GGLAssembler::decodeLogicOpNeeds(const needs_t& needs){    // gather some informations about the components we need to process...    const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR;    switch(opcode) {    case GGL_COPY:        mLogicOp = 0;        break;    case GGL_CLEAR:    case GGL_SET:        mLogicOp = LOGIC_OP;        break;    case GGL_AND:    case GGL_AND_REVERSE:    case GGL_AND_INVERTED:    case GGL_XOR:    case GGL_OR:    case GGL_NOR:    case GGL_EQUIV:    case GGL_OR_REVERSE:    case GGL_OR_INVERTED:    case GGL_NAND:        mLogicOp = LOGIC_OP|LOGIC_OP_SRC|LOGIC_OP_DST;        break;    case GGL_NOOP:    case GGL_INVERT:        mLogicOp = LOGIC_OP|LOGIC_OP_DST;        break;            case GGL_COPY_INVERTED:        mLogicOp = LOGIC_OP|LOGIC_OP_SRC;        break;    };        }void GGLAssembler::decodeTMUNeeds(const needs_t& needs, context_t const* c){    uint8_t replaced=0;    mTextureMachine.mask = 0;    mTextureMachine.activeUnits = 0;    for (int i=GGL_TEXTURE_UNIT_COUNT-1 ; i>=0 ; i--) {        texture_unit_t& tmu = mTextureMachine.tmu[i];        if (replaced == 0xF) {            // all components are replaced, skip this TMU.            tmu.format_idx = 0;            tmu.mask = 0;            tmu.replaced = replaced;            continue;        }        tmu.format_idx = GGL_READ_NEEDS(T_FORMAT, needs.t[i]);        tmu.format = c->formats[tmu.format_idx];        tmu.bits = tmu.format.size*8;        tmu.swrap = GGL_READ_NEEDS(T_S_WRAP, needs.t[i]);        tmu.twrap = GGL_READ_NEEDS(T_T_WRAP, needs.t[i]);        tmu.env = ggl_needs_to_env(GGL_READ_NEEDS(T_ENV, needs.t[i]));        tmu.pot = GGL_READ_NEEDS(T_POT, needs.t[i]);        tmu.linear = GGL_READ_NEEDS(T_LINEAR, needs.t[i])                && tmu.format.size!=3; // XXX: only 8, 16 and 32 modes for now        // 5551 linear filtering is not supported        if (tmu.format_idx == GGL_PIXEL_FORMAT_RGBA_5551)            tmu.linear = 0;                tmu.mask = 0;        tmu.replaced = replaced;        if (tmu.format_idx) {            mTextureMachine.activeUnits++;            if (tmu.format.c[0].h)    tmu.mask |= 0x1;            if (tmu.format.c[1].h)    tmu.mask |= 0x2;            if (tmu.format.c[2].h)    tmu.mask |= 0x4;            if (tmu.format.c[3].h)    tmu.mask |= 0x8;            if (tmu.env == GGL_REPLACE) {                replaced |= tmu.mask;            } else if (tmu.env == GGL_DECAL) {                if (!tmu.format.c[GGLFormat::ALPHA].h) {                    // if we don't have alpha, decal does nothing                    tmu.mask = 0;                } else {                    // decal always ignores At                    tmu.mask &= ~(1<<GGLFormat::ALPHA);                }            }        }        mTextureMachine.mask |= tmu.mask;        //printf("%d: mask=%08lx, replaced=%08lx\n",        //    i, int(tmu.mask), int(tmu.replaced));    }    mTextureMachine.replaced = replaced;    mTextureMachine.directTexture = 0;    //printf("replaced=%08lx\n", mTextureMachine.replaced);}void GGLAssembler::init_textures(        tex_coord_t* coords,        const reg_t& x, const reg_t& y){    context_t const* c = mBuilderContext.c;    const needs_t& needs = mBuilderContext.needs;    int Rctx = mBuilderContext.Rctx;    int Rx = x.reg;    int Ry = y.reg;    if (mTextureMachine.mask) {        comment("compute texture coordinates");    }    // init texture coordinates for each tmu    const int cb_format_idx = GGL_READ_NEEDS(CB_FORMAT, needs.n);    const bool multiTexture = mTextureMachine.activeUnits > 1;    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) {        const texture_unit_t& tmu = mTextureMachine.tmu[i];        if (tmu.format_idx == 0)            continue;        if ((tmu.swrap == GGL_NEEDS_WRAP_11) &&            (tmu.twrap == GGL_NEEDS_WRAP_11))         {            // 1:1 texture            pointer_t& txPtr = coords[i].ptr;            txPtr.setTo(obtainReg(), tmu.bits);            CONTEXT_LOAD(txPtr.reg, state.texture[i].iterators.ydsdy);            ADD(AL, 0, Rx, Rx, reg_imm(txPtr.reg, ASR, 16));    // x += (s>>16)            CONTEXT_LOAD(txPtr.reg, state.texture[i].iterators.ydtdy);            ADD(AL, 0, Ry, Ry, reg_imm(txPtr.reg, ASR, 16));    // y += (t>>16)            // merge base & offset            CONTEXT_LOAD(txPtr.reg, generated_vars.texture[i].stride);            SMLABB(AL, Rx, Ry, txPtr.reg, Rx);               // x+y*stride            CONTEXT_LOAD(txPtr.reg, generated_vars.texture[i].data);            base_offset(txPtr, txPtr, Rx);        } else {            Scratch scratches(registerFile());            reg_t& s = coords[i].s;            reg_t& t = coords[i].t;            // s = (x * dsdx)>>16 + ydsdy            // s = (x * dsdx)>>16 + (y*dsdy)>>16 + s0            // t = (x * dtdx)>>16 + ydtdy            // t = (x * dtdx)>>16 + (y*dtdy)>>16 + t0            s.setTo(obtainReg());            t.setTo(obtainReg());            const int need_w = GGL_READ_NEEDS(W, needs.n);            if (need_w) {                CONTEXT_LOAD(s.reg, state.texture[i].iterators.ydsdy);                CONTEXT_LOAD(t.reg, state.texture[i].iterators.ydtdy);            } else {                int ydsdy = scratches.obtain();                int ydtdy = scratches.obtain();                CONTEXT_LOAD(s.reg, generated_vars.texture[i].dsdx);                CONTEXT_LOAD(ydsdy, state.texture[i].iterators.ydsdy);                CONTEXT_LOAD(t.reg, generated_vars.texture[i].dtdx);                CONTEXT_LOAD(ydtdy, state.texture[i].iterators.ydtdy);                MLA(AL, 0, s.reg, Rx, s.reg, ydsdy);                MLA(AL, 0, t.reg, Rx, t.reg, ydtdy);            }                        if ((mOptLevel&1)==0) {                CONTEXT_STORE(s.reg, generated_vars.texture[i].spill[0]);                CONTEXT_STORE(t.reg, generated_vars.texture[i].spill[1]);                recycleReg(s.reg);                recycleReg(t.reg);            }        }        // direct texture?        if (!multiTexture && !mBlending && !mDithering && !mFog &&             cb_format_idx == tmu.format_idx && !tmu.linear &&            mTextureMachine.replaced == tmu.mask)         {                mTextureMachine.directTexture = i + 1;         }    }}void GGLAssembler::build_textures(  fragment_parts_t& parts,                                    Scratch& regs){

⌨️ 快捷键说明

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