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

📄 blending.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        ADD(AL, 0, factor.reg, fragment.reg,            reg_imm(fragment.reg, LSR, fragment.s-1));        break;    case GGL_ONE_MINUS_SRC_ALPHA:    case GGL_SRC_ALPHA:        factor.s = src_alpha.s;        ADD(AL, 0, factor.reg, src_alpha.reg,                reg_imm(src_alpha.reg, LSR, src_alpha.s-1));        break;    case GGL_ONE_MINUS_DST_ALPHA:    case GGL_DST_ALPHA:        // XXX: should be precomputed        extract(factor, dst_pixel, GGLFormat::ALPHA);        ADD(AL, 0, factor.reg, factor.reg,                reg_imm(factor.reg, LSR, factor.s-1));        break;    case GGL_SRC_ALPHA_SATURATE:        // XXX: should be precomputed        // XXX: f = min(As, 1-Ad)        // btw, we're guaranteed that Ad's size is <= 8, because        // it's extracted from the framebuffer        break;    }    switch(f) {    case GGL_ONE_MINUS_DST_COLOR:    case GGL_ONE_MINUS_SRC_COLOR:    case GGL_ONE_MINUS_DST_ALPHA:    case GGL_ONE_MINUS_SRC_ALPHA:        RSB(AL, 0, factor.reg, factor.reg, imm((1<<factor.s)));    }        // don't need more than 8-bits for the blend factor    // and this will prevent overflows in the multiplies later    if (factor.s > 8) {        MOV(AL, 0, factor.reg, reg_imm(factor.reg, LSR, factor.s-8));        factor.s = 8;    }}int GGLAssembler::blending_codes(int fs, int fd){    int blending = 0;    switch(fs) {    case GGL_ONE:        blending |= BLEND_SRC;        break;    case GGL_ONE_MINUS_DST_COLOR:    case GGL_DST_COLOR:        blending |= FACTOR_DST|BLEND_SRC;        break;    case GGL_ONE_MINUS_DST_ALPHA:    case GGL_DST_ALPHA:        // no need to extract 'component' from the destination        // for the blend factor, because we need ALPHA only.        blending |= BLEND_SRC;        break;    case GGL_ONE_MINUS_SRC_COLOR:    case GGL_SRC_COLOR:            blending |= FACTOR_SRC|BLEND_SRC;        break;    case GGL_ONE_MINUS_SRC_ALPHA:    case GGL_SRC_ALPHA:    case GGL_SRC_ALPHA_SATURATE:        blending |= FACTOR_SRC|BLEND_SRC;        break;    }    switch(fd) {    case GGL_ONE:        blending |= BLEND_DST;        break;    case GGL_ONE_MINUS_DST_COLOR:    case GGL_DST_COLOR:        blending |= FACTOR_DST|BLEND_DST;        break;    case GGL_ONE_MINUS_DST_ALPHA:    case GGL_DST_ALPHA:        blending |= FACTOR_DST|BLEND_DST;        break;    case GGL_ONE_MINUS_SRC_COLOR:    case GGL_SRC_COLOR:            blending |= FACTOR_SRC|BLEND_DST;        break;    case GGL_ONE_MINUS_SRC_ALPHA:    case GGL_SRC_ALPHA:        // no need to extract 'component' from the source        // for the blend factor, because we need ALPHA only.        blending |= BLEND_DST;        break;    }    return blending;}// ---------------------------------------------------------------------------void GGLAssembler::build_blendFOneMinusF(        component_t& temp,        const integer_t& factor,         const integer_t& fragment,        const integer_t& fb){    //  R = S*f + D*(1-f) = (S-D)*f + D    Scratch scratches(registerFile());    // compute S-D    integer_t diff(fragment.flags & CORRUPTIBLE ?            fragment.reg : scratches.obtain(), fb.size(), CORRUPTIBLE);    const int shift = fragment.size() - fb.size();    if (shift>0)        RSB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSR, shift));    else if (shift<0)   RSB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSL,-shift));    else                RSB(AL, 0, diff.reg, fb.reg, fragment.reg);    mul_factor_add(temp, diff, factor, component_t(fb));}void GGLAssembler::build_blendOneMinusFF(        component_t& temp,        const integer_t& factor,         const integer_t& fragment,        const integer_t& fb){    //  R = S*f + D*(1-f) = (S-D)*f + D    Scratch scratches(registerFile());    // compute D-S    integer_t diff(fb.flags & CORRUPTIBLE ?            fb.reg : scratches.obtain(), fb.size(), CORRUPTIBLE);    const int shift = fragment.size() - fb.size();    if (shift>0)        SUB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSR, shift));    else if (shift<0)   SUB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSL,-shift));    else                SUB(AL, 0, diff.reg, fb.reg, fragment.reg);    mul_factor_add(temp, diff, factor, component_t(fragment));}// ---------------------------------------------------------------------------void GGLAssembler::mul_factor(  component_t& d,                                const integer_t& v,                                const integer_t& f){    int vs = v.size();    int fs = f.size();    int ms = vs+fs;    // XXX: we could have special cases for 1 bit mul    // all this code below to use the best multiply instruction    // wrt the parameters size. We take advantage of the fact    // that the 16-bits multiplies allow a 16-bit shift    // The trick is that we just make sure that we have at least 8-bits    // per component (which is enough for a 8 bits display).    int xy;    int vshift = 0;    int fshift = 0;    int smulw = 0;    if (vs<16) {        if (fs<16) {            xy = xyBB;        } else if (GGL_BETWEEN(fs, 24, 31)) {            ms -= 16;            xy = xyTB;        } else {            // eg: 15 * 18  ->  15 * 15            fshift = fs - 15;            ms -= fshift;            xy = xyBB;        }    } else if (GGL_BETWEEN(vs, 24, 31)) {        if (fs<16) {            ms -= 16;            xy = xyTB;        } else if (GGL_BETWEEN(fs, 24, 31)) {            ms -= 32;            xy = xyTT;        } else {            // eg: 24 * 18  ->  8 * 18            fshift = fs - 15;            ms -= 16 + fshift;            xy = xyTB;        }    } else {        if (fs<16) {            // eg: 18 * 15  ->  15 * 15            vshift = vs - 15;            ms -= vshift;            xy = xyBB;        } else if (GGL_BETWEEN(fs, 24, 31)) {            // eg: 18 * 24  ->  15 * 8            vshift = vs - 15;            ms -= 16 + vshift;            xy = xyBT;        } else {            // eg: 18 * 18  ->  (15 * 18)>>16            fshift = fs - 15;            ms -= 16 + fshift;            xy = yB;    //XXX SMULWB            smulw = 1;        }    }    LOGE_IF(ms>=32, "mul_factor overflow vs=%d, fs=%d", vs, fs);    int vreg = v.reg;    int freg = f.reg;    if (vshift) {        MOV(AL, 0, d.reg, reg_imm(vreg, LSR, vshift));        vreg = d.reg;    }    if (fshift) {        MOV(AL, 0, d.reg, reg_imm(vreg, LSR, fshift));        freg = d.reg;    }    if (smulw)  SMULW(AL, xy, d.reg, vreg, freg);    else        SMUL(AL, xy, d.reg, vreg, freg);    d.h = ms;    if (mDithering) {        d.l = 0;     } else {        d.l = fs;         d.flags |= CLEAR_LO;    }}void GGLAssembler::mul_factor_add(  component_t& d,                                    const integer_t& v,                                    const integer_t& f,                                    const component_t& a){    // XXX: we could have special cases for 1 bit mul    Scratch scratches(registerFile());    int vs = v.size();    int fs = f.size();    int as = a.h;    int ms = vs+fs;    LOGE_IF(ms>=32, "mul_factor_add overflow vs=%d, fs=%d, as=%d", vs, fs, as);    integer_t add(a.reg, a.h, a.flags);    // 'a' is a component_t but it is guaranteed to have    // its high bits set to 0. However in the dithering case,    // we can't get away with truncating the potentially bad bits    // so extraction is needed.   if ((mDithering) && (a.size() < ms)) {        // we need to expand a        if (!(a.flags & CORRUPTIBLE)) {            // ... but it's not corruptible, so we need to pick a            // temporary register.            // Try to uses the destination register first (it's likely            // to be usable, unless it aliases an input).            if (d.reg!=a.reg && d.reg!=v.reg && d.reg!=f.reg) {                add.reg = d.reg;            } else {                add.reg = scratches.obtain();            }        }        expand(add, a, ms); // extracts and expands        as = ms;    }    if (ms == as) {        if (vs<16 && fs<16) SMLABB(AL, d.reg, v.reg, f.reg, add.reg);        else                MLA(AL, 0, d.reg, v.reg, f.reg, add.reg);    } else {        int temp = d.reg;        if (temp == add.reg) {            // the mul will modify add.reg, we need an intermediary reg            if (v.flags & CORRUPTIBLE)      temp = v.reg;            else if (f.flags & CORRUPTIBLE) temp = f.reg;            else                            temp = scratches.obtain();        }        if (vs<16 && fs<16) SMULBB(AL, temp, v.reg, f.reg);        else                MUL(AL, 0, temp, v.reg, f.reg);        if (ms>as) {            ADD(AL, 0, d.reg, temp, reg_imm(add.reg, LSL, ms-as));        } else if (ms<as) {            // not sure if we should expand the mul instead?            ADD(AL, 0, d.reg, temp, reg_imm(add.reg, LSR, as-ms));        }    }    d.h = ms;    if (mDithering) {        d.l = a.l;     } else {        d.l = fs>a.l ? fs : a.l;        d.flags |= CLEAR_LO;    }}void GGLAssembler::component_add(component_t& d,        const integer_t& dst, const integer_t& src){    // here we're guaranteed that fragment.size() >= fb.size()    const int shift = src.size() - dst.size();    if (!shift) {        ADD(AL, 0, d.reg, src.reg, dst.reg);    } else {        ADD(AL, 0, d.reg, src.reg, reg_imm(dst.reg, LSL, shift));    }    d.h = src.size();    if (mDithering) {        d.l = 0;    } else {        d.l = shift;        d.flags |= CLEAR_LO;    }}void GGLAssembler::component_sat(const component_t& v){    const int one = ((1<<v.size())-1)<<v.l;    CMP(AL, v.reg, imm( 1<<v.h ));    if (isValidImmediate(one)) {        MOV(HS, 0, v.reg, imm( one ));    } else if (isValidImmediate(~one)) {        MVN(HS, 0, v.reg, imm( ~one ));    } else {        MOV(HS, 0, v.reg, imm( 1<<v.h ));        SUB(HS, 0, v.reg, v.reg, imm( 1<<v.l ));    }}// ----------------------------------------------------------------------------}; // namespace android

⌨️ 快捷键说明

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