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

📄 blending.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* libs/pixelflinger/codeflinger/blending.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 {void GGLAssembler::build_fog(                        component_t& temp,      // incomming fragment / output                        int component,                        Scratch& regs){   if (mInfo[component].fog) {        Scratch scratches(registerFile());        comment("fog");        integer_t fragment(temp.reg, temp.h, temp.flags);        if (!(temp.flags & CORRUPTIBLE)) {            temp.reg = regs.obtain();            temp.flags |= CORRUPTIBLE;        }        integer_t fogColor(scratches.obtain(), 8, CORRUPTIBLE);         LDRB(AL, fogColor.reg, mBuilderContext.Rctx,                immed12_pre(GGL_OFFSETOF(state.fog.color[component])));        integer_t factor(scratches.obtain(), 16, CORRUPTIBLE);        CONTEXT_LOAD(factor.reg, generated_vars.f);        build_blendFOneMinusF(temp, factor, fragment, fogColor);    }}void GGLAssembler::build_blending(                        component_t& temp,      // incomming fragment / output                        const pixel_t& pixel,   // framebuffer                        int component,                        Scratch& regs){   if (!mInfo[component].blend)        return;            int fs = component==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc;    int fd = component==GGLFormat::ALPHA ? mBlendDstA : mBlendDst;    if (fs==GGL_SRC_ALPHA_SATURATE && component==GGLFormat::ALPHA)        fs = GGL_ONE;    const int blending = blending_codes(fs, fd);    if (!temp.size()) {        // here, blending will produce something which doesn't depend on        // that component (eg: GL_ZERO:GL_*), so the register has not been        // allocated yet. Will never be used as a source.        temp = component_t(regs.obtain(), CORRUPTIBLE);    }    // we are doing real blending...    // fb:          extracted dst    // fragment:    extracted src    // temp:        component_t(fragment) and result    // scoped register allocator    Scratch scratches(registerFile());    comment("blending");    // we can optimize these cases a bit...    // (1) saturation is not needed    // (2) we can use only one multiply instead of 2    // (3) we can reduce the register pressure    //      R = S*f + D*(1-f) = (S-D)*f + D    //      R = S*(1-f) + D*f = (D-S)*f + S    const bool same_factor_opt1 =        (fs==GGL_DST_COLOR && fd==GGL_ONE_MINUS_DST_COLOR) ||        (fs==GGL_SRC_COLOR && fd==GGL_ONE_MINUS_SRC_COLOR) ||        (fs==GGL_DST_ALPHA && fd==GGL_ONE_MINUS_DST_ALPHA) ||        (fs==GGL_SRC_ALPHA && fd==GGL_ONE_MINUS_SRC_ALPHA);    const bool same_factor_opt2 =        (fs==GGL_ONE_MINUS_DST_COLOR && fd==GGL_DST_COLOR) ||        (fs==GGL_ONE_MINUS_SRC_COLOR && fd==GGL_SRC_COLOR) ||         (fs==GGL_ONE_MINUS_DST_ALPHA && fd==GGL_DST_ALPHA) ||        (fs==GGL_ONE_MINUS_SRC_ALPHA && fd==GGL_SRC_ALPHA);    // XXX: we could also optimize these cases:    // R = S*f + D*f = (S+D)*f    // R = S*(1-f) + D*(1-f) = (S+D)*(1-f)    // R = S*D + D*S = 2*S*D    // see if we need to extract 'component' from the destination (fb)    integer_t fb;    if (blending & (BLEND_DST|FACTOR_DST)) {         fb.setTo(scratches.obtain(), 32);         extract(fb, pixel, component);        if (mDithering) {            // XXX: maybe what we should do instead, is simply            // expand fb -or- fragment to the larger of the two            if (fb.size() < temp.size()) {                // for now we expand 'fb' to min(fragment, 8)                int new_size = temp.size() < 8 ? temp.size() : 8;                expand(fb, fb, new_size);            }        }    }    // convert input fragment to integer_t    if (temp.l && (temp.flags & CORRUPTIBLE)) {        MOV(AL, 0, temp.reg, reg_imm(temp.reg, LSR, temp.l));        temp.h -= temp.l;        temp.l = 0;    }    integer_t fragment(temp.reg, temp.size(), temp.flags);    // if not done yet, convert input fragment to integer_t    if (temp.l) {        // here we know temp is not CORRUPTIBLE        fragment.reg = scratches.obtain();        MOV(AL, 0, fragment.reg, reg_imm(temp.reg, LSR, temp.l));        fragment.flags |= CORRUPTIBLE;    }    if (!(temp.flags & CORRUPTIBLE)) {        // temp is not corruptible, but since it's the destination it        // will be modified, so we need to allocate a new register.        temp.reg = regs.obtain();        temp.flags &= ~CORRUPTIBLE;        fragment.flags &= ~CORRUPTIBLE;    }    if ((blending & BLEND_SRC) && !same_factor_opt1) {        // source (fragment) is needed for the blending stage        // so it's not CORRUPTIBLE (unless we're doing same_factor_opt1)        fragment.flags &= ~CORRUPTIBLE;    }    if (same_factor_opt1) {        //  R = S*f + D*(1-f) = (S-D)*f + D        integer_t factor;        build_blend_factor(factor, fs,                 component, pixel, fragment, fb, scratches);        // fb is always corruptible from this point        fb.flags |= CORRUPTIBLE;        build_blendFOneMinusF(temp, factor, fragment, fb);    } else if (same_factor_opt2) {        //  R = S*(1-f) + D*f = (D-S)*f + S        integer_t factor;        // fb is always corrruptible here        fb.flags |= CORRUPTIBLE;        build_blend_factor(factor, fd,                component, pixel, fragment, fb, scratches);        build_blendOneMinusFF(temp, factor, fragment, fb);    } else {        integer_t src_factor;        integer_t dst_factor;        // if destination (fb) is not needed for the blending stage,         // then it can be marked as CORRUPTIBLE        if (!(blending & BLEND_DST)) {            fb.flags |= CORRUPTIBLE;        }        // XXX: try to mark some registers as CORRUPTIBLE        // in most case we could make those corruptible        // when we're processing the last component        // but not always, for instance        //    when fragment is constant and not reloaded        //    when fb is needed for logic-ops or masking        //    when a register is aliased (for instance with mAlphaSource)        // blend away...        if (fs==GGL_ZERO) {            if (fd==GGL_ZERO) {         // R = 0                // already taken care of            } else if (fd==GGL_ONE) {   // R = D                // already taken care of            } else {                    // R = D*fd                // compute fd                build_blend_factor(dst_factor, fd,                        component, pixel, fragment, fb, scratches);                mul_factor(temp, fb, dst_factor);            }        } else if (fs==GGL_ONE) {            if (fd==GGL_ZERO) {         // R = S                // NOP, taken care of            } else if (fd==GGL_ONE) {   // R = S + D                component_add(temp, fb, fragment); // args order matters                component_sat(temp);            } else {                    // R = S + D*fd                // compute fd                build_blend_factor(dst_factor, fd,                        component, pixel, fragment, fb, scratches);                mul_factor_add(temp, fb, dst_factor, component_t(fragment));                if (fd==GGL_ONE_MINUS_SRC_ALPHA) {                    // XXX: in theory this is not correct, we should                    // saturate here. However, this mode is often                    // used for displaying alpha-premultiplied graphics,                    // in which case, saturation is not necessary.                    // unfortunatelly, we have no way to know.                    // This is a case, where we sacrifice correctness for                    // performance. we should probably have some heuristics.                } else {                    component_sat(temp);                }            }        } else {            // compute fs            build_blend_factor(src_factor, fs,                     component, pixel, fragment, fb, scratches);            if (fd==GGL_ZERO) {         // R = S*fs                mul_factor(temp, fragment, src_factor);            } else if (fd==GGL_ONE) {   // R = S*fs + D                mul_factor_add(temp, fragment, src_factor, component_t(fb));                component_sat(temp);            } else {                    // R = S*fs + D*fd                mul_factor(temp, fragment, src_factor);                if (scratches.isUsed(src_factor.reg))                    scratches.recycle(src_factor.reg);                // compute fd                build_blend_factor(dst_factor, fd,                        component, pixel, fragment, fb, scratches);                mul_factor_add(temp, fb, dst_factor, temp);                if (!same_factor_opt1 && !same_factor_opt2) {                    component_sat(temp);                }            }        }    }    // now we can be corrupted (it's the dest)    temp.flags |= CORRUPTIBLE;}void GGLAssembler::build_blend_factor(        integer_t& factor, int f, int component,        const pixel_t& dst_pixel,        integer_t& fragment,        integer_t& fb,        Scratch& scratches){    integer_t src_alpha(fragment);    // src_factor/dst_factor won't be used after blending,    // so it's fine to mark them as CORRUPTIBLE (if not aliased)    factor.flags |= CORRUPTIBLE;    switch(f) {    case GGL_ONE_MINUS_SRC_ALPHA:    case GGL_SRC_ALPHA:        if (component==GGLFormat::ALPHA && !isAlphaSourceNeeded()) {            // we're processing alpha, so we already have            // src-alpha in fragment, and we need src-alpha just this time.        } else {           // alpha-src will be needed for other components            if (!mBlendFactorCached || mBlendFactorCached==f) {                src_alpha = mAlphaSource;                factor = mAlphaSource;                factor.flags &= ~CORRUPTIBLE;                           // we already computed the blend factor before, nothing to do.                if (mBlendFactorCached)                    return;                // this is the first time, make sure to compute the blend                // factor properly.                mBlendFactorCached = f;                break;            } else {                // we have a cached alpha blend factor, but we want another one,                // this should really not happen because by construction,                // we cannot have BOTH source and destination                // blend factors use ALPHA *and* ONE_MINUS_ALPHA (because                // the blending stage uses the f/(1-f) optimization                                // for completeness, we handle this case though. Since there                // are only 2 choices, this meens we want "the other one"                // (1-factor)                factor = mAlphaSource;                factor.flags &= ~CORRUPTIBLE;                           RSB(AL, 0, factor.reg, factor.reg, imm((1<<factor.s)));                mBlendFactorCached = f;                return;            }                        }        // fall-through...    case GGL_ONE_MINUS_DST_COLOR:    case GGL_DST_COLOR:    case GGL_ONE_MINUS_SRC_COLOR:    case GGL_SRC_COLOR:    case GGL_ONE_MINUS_DST_ALPHA:    case GGL_DST_ALPHA:    case GGL_SRC_ALPHA_SATURATE:        // help us find out what register we can use for the blend-factor        // CORRUPTIBLE registers are chosen first, or a new one is allocated.        if (fragment.flags & CORRUPTIBLE) {            factor.setTo(fragment.reg, 32, CORRUPTIBLE);            fragment.flags &= ~CORRUPTIBLE;        } else if (fb.flags & CORRUPTIBLE) {            factor.setTo(fb.reg, 32, CORRUPTIBLE);            fb.flags &= ~CORRUPTIBLE;        } else {            factor.setTo(scratches.obtain(), 32, CORRUPTIBLE);        }         break;    }    // XXX: doesn't work if size==1    switch(f) {    case GGL_ONE_MINUS_DST_COLOR:    case GGL_DST_COLOR:        factor.s = fb.s;        ADD(AL, 0, factor.reg, fb.reg, reg_imm(fb.reg, LSR, fb.s-1));        break;    case GGL_ONE_MINUS_SRC_COLOR:    case GGL_SRC_COLOR:        factor.s = fragment.s;

⌨️ 快捷键说明

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