1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/codeflinger/blending.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 <stdint.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "codeflinger/GGLAssembler.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_fog( 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_t& temp, // incomming fragment / output 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int component, 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch& regs) 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mInfo[component].fog) { 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch scratches(registerFile()); 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project comment("fog"); 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t fragment(temp.reg, temp.h, temp.flags); 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(temp.flags & CORRUPTIBLE)) { 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.reg = regs.obtain(); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.flags |= CORRUPTIBLE; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t fogColor(scratches.obtain(), 8, CORRUPTIBLE); 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LDRB(AL, fogColor.reg, mBuilderContext.Rctx, 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project immed12_pre(GGL_OFFSETOF(state.fog.color[component]))); 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t factor(scratches.obtain(), 16, CORRUPTIBLE); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CONTEXT_LOAD(factor.reg, generated_vars.f); 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // clamp fog factor (TODO: see if there is a way to guarantee 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we won't overflow, when setting the iterators) 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project BIC(AL, 0, factor.reg, factor.reg, reg_imm(factor.reg, ASR, 31)); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CMP(AL, factor.reg, imm( 0x10000 )); 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(HS, 0, factor.reg, imm( 0x10000 )); 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blendFOneMinusF(temp, factor, fragment, fogColor); 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_blending( 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_t& temp, // incomming fragment / output 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const pixel_t& pixel, // framebuffer 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int component, 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch& regs) 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mInfo[component].blend) 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fs = component==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = component==GGLFormat::ALPHA ? mBlendDstA : mBlendDst; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fs==GGL_SRC_ALPHA_SATURATE && component==GGLFormat::ALPHA) 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fs = GGL_ONE; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int blending = blending_codes(fs, fd); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!temp.size()) { 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // here, blending will produce something which doesn't depend on 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // that component (eg: GL_ZERO:GL_*), so the register has not been 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // allocated yet. Will never be used as a source. 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp = component_t(regs.obtain(), CORRUPTIBLE); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we are doing real blending... 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fb: extracted dst 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fragment: extracted src 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // temp: component_t(fragment) and result 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // scoped register allocator 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch scratches(registerFile()); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project comment("blending"); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we can optimize these cases a bit... 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // (1) saturation is not needed 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // (2) we can use only one multiply instead of 2 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // (3) we can reduce the register pressure 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*f + D*(1-f) = (S-D)*f + D 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*(1-f) + D*f = (D-S)*f + S 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const bool same_factor_opt1 = 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_DST_COLOR && fd==GGL_ONE_MINUS_DST_COLOR) || 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_SRC_COLOR && fd==GGL_ONE_MINUS_SRC_COLOR) || 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_DST_ALPHA && fd==GGL_ONE_MINUS_DST_ALPHA) || 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_SRC_ALPHA && fd==GGL_ONE_MINUS_SRC_ALPHA); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const bool same_factor_opt2 = 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_ONE_MINUS_DST_COLOR && fd==GGL_DST_COLOR) || 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_ONE_MINUS_SRC_COLOR && fd==GGL_SRC_COLOR) || 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_ONE_MINUS_DST_ALPHA && fd==GGL_DST_ALPHA) || 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (fs==GGL_ONE_MINUS_SRC_ALPHA && fd==GGL_SRC_ALPHA); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: we could also optimize these cases: 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*f + D*f = (S+D)*f 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*(1-f) + D*(1-f) = (S+D)*(1-f) 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*D + D*S = 2*S*D 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // see if we need to extract 'component' from the destination (fb) 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t fb; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (blending & (BLEND_DST|FACTOR_DST)) { 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb.setTo(scratches.obtain(), 32); 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project extract(fb, pixel, component); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mDithering) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: maybe what we should do instead, is simply 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // expand fb -or- fragment to the larger of the two 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fb.size() < temp.size()) { 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // for now we expand 'fb' to min(fragment, 8) 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int new_size = temp.size() < 8 ? temp.size() : 8; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project expand(fb, fb, new_size); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // convert input fragment to integer_t 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (temp.l && (temp.flags & CORRUPTIBLE)) { 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(AL, 0, temp.reg, reg_imm(temp.reg, LSR, temp.l)); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.h -= temp.l; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.l = 0; 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t fragment(temp.reg, temp.size(), temp.flags); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // if not done yet, convert input fragment to integer_t 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (temp.l) { 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // here we know temp is not CORRUPTIBLE 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fragment.reg = scratches.obtain(); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(AL, 0, fragment.reg, reg_imm(temp.reg, LSR, temp.l)); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fragment.flags |= CORRUPTIBLE; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(temp.flags & CORRUPTIBLE)) { 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // temp is not corruptible, but since it's the destination it 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // will be modified, so we need to allocate a new register. 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.reg = regs.obtain(); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.flags &= ~CORRUPTIBLE; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fragment.flags &= ~CORRUPTIBLE; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((blending & BLEND_SRC) && !same_factor_opt1) { 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // source (fragment) is needed for the blending stage 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // so it's not CORRUPTIBLE (unless we're doing same_factor_opt1) 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fragment.flags &= ~CORRUPTIBLE; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (same_factor_opt1) { 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*f + D*(1-f) = (S-D)*f + D 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t factor; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blend_factor(factor, fs, 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component, pixel, fragment, fb, scratches); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fb is always corruptible from this point 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb.flags |= CORRUPTIBLE; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blendFOneMinusF(temp, factor, fragment, fb); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (same_factor_opt2) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*(1-f) + D*f = (D-S)*f + S 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t factor; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fb is always corrruptible here 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb.flags |= CORRUPTIBLE; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blend_factor(factor, fd, 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component, pixel, fragment, fb, scratches); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blendOneMinusFF(temp, factor, fragment, fb); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t src_factor; 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t dst_factor; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // if destination (fb) is not needed for the blending stage, 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // then it can be marked as CORRUPTIBLE 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(blending & BLEND_DST)) { 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb.flags |= CORRUPTIBLE; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: try to mark some registers as CORRUPTIBLE 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // in most case we could make those corruptible 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // when we're processing the last component 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // but not always, for instance 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // when fragment is constant and not reloaded 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // when fb is needed for logic-ops or masking 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // when a register is aliased (for instance with mAlphaSource) 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // blend away... 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fs==GGL_ZERO) { 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd==GGL_ZERO) { // R = 0 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // already taken care of 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (fd==GGL_ONE) { // R = D 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // already taken care of 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { // R = D*fd 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // compute fd 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blend_factor(dst_factor, fd, 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component, pixel, fragment, fb, scratches); 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor(temp, fb, dst_factor); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (fs==GGL_ONE) { 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd==GGL_ZERO) { // R = S 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // NOP, taken care of 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (fd==GGL_ONE) { // R = S + D 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_add(temp, fb, fragment); // args order matters 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_sat(temp); 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { // R = S + D*fd 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // compute fd 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blend_factor(dst_factor, fd, 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component, pixel, fragment, fb, scratches); 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor_add(temp, fb, dst_factor, component_t(fragment)); 224665a2227e5212c6a7452f080d87f377b8471a8b0Mathias Agopian component_sat(temp); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // compute fs 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blend_factor(src_factor, fs, 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component, pixel, fragment, fb, scratches); 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd==GGL_ZERO) { // R = S*fs 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor(temp, fragment, src_factor); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (fd==GGL_ONE) { // R = S*fs + D 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor_add(temp, fragment, src_factor, component_t(fb)); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_sat(temp); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { // R = S*fs + D*fd 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor(temp, fragment, src_factor); 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (scratches.isUsed(src_factor.reg)) 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scratches.recycle(src_factor.reg); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // compute fd 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project build_blend_factor(dst_factor, fd, 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component, pixel, fragment, fb, scratches); 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor_add(temp, fb, dst_factor, temp); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!same_factor_opt1 && !same_factor_opt2) { 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_sat(temp); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // now we can be corrupted (it's the dest) 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp.flags |= CORRUPTIBLE; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_blend_factor( 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t& factor, int f, int component, 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const pixel_t& dst_pixel, 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t& fragment, 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t& fb, 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch& scratches) 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t src_alpha(fragment); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // src_factor/dst_factor won't be used after blending, 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // so it's fine to mark them as CORRUPTIBLE (if not aliased) 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.flags |= CORRUPTIBLE; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(f) { 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_ALPHA: 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA: 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (component==GGLFormat::ALPHA && !isAlphaSourceNeeded()) { 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we're processing alpha, so we already have 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // src-alpha in fragment, and we need src-alpha just this time. 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // alpha-src will be needed for other components 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mBlendFactorCached || mBlendFactorCached==f) { 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project src_alpha = mAlphaSource; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor = mAlphaSource; 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.flags &= ~CORRUPTIBLE; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we already computed the blend factor before, nothing to do. 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mBlendFactorCached) 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this is the first time, make sure to compute the blend 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // factor properly. 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mBlendFactorCached = f; 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we have a cached alpha blend factor, but we want another one, 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this should really not happen because by construction, 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we cannot have BOTH source and destination 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // blend factors use ALPHA *and* ONE_MINUS_ALPHA (because 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // the blending stage uses the f/(1-f) optimization 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // for completeness, we handle this case though. Since there 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // are only 2 choices, this meens we want "the other one" 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // (1-factor) 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor = mAlphaSource; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.flags &= ~CORRUPTIBLE; 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project RSB(AL, 0, factor.reg, factor.reg, imm((1<<factor.s))); 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mBlendFactorCached = f; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // fall-through... 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_COLOR: 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_COLOR: 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_COLOR: 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_COLOR: 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_ALPHA: 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_ALPHA: 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA_SATURATE: 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // help us find out what register we can use for the blend-factor 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // CORRUPTIBLE registers are chosen first, or a new one is allocated. 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fragment.flags & CORRUPTIBLE) { 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.setTo(fragment.reg, 32, CORRUPTIBLE); 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fragment.flags &= ~CORRUPTIBLE; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (fb.flags & CORRUPTIBLE) { 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.setTo(fb.reg, 32, CORRUPTIBLE); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb.flags &= ~CORRUPTIBLE; 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.setTo(scratches.obtain(), 32, CORRUPTIBLE); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: doesn't work if size==1 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(f) { 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_COLOR: 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_COLOR: 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.s = fb.s; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, factor.reg, fb.reg, reg_imm(fb.reg, LSR, fb.s-1)); 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_COLOR: 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_COLOR: 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.s = fragment.s; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, factor.reg, fragment.reg, 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg_imm(fragment.reg, LSR, fragment.s-1)); 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_ALPHA: 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA: 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.s = src_alpha.s; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, factor.reg, src_alpha.reg, 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg_imm(src_alpha.reg, LSR, src_alpha.s-1)); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_ALPHA: 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_ALPHA: 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: should be precomputed 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project extract(factor, dst_pixel, GGLFormat::ALPHA); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, factor.reg, factor.reg, 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project reg_imm(factor.reg, LSR, factor.s-1)); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA_SATURATE: 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: should be precomputed 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: f = min(As, 1-Ad) 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // btw, we're guaranteed that Ad's size is <= 8, because 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // it's extracted from the framebuffer 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(f) { 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_COLOR: 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_COLOR: 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_ALPHA: 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_ALPHA: 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project RSB(AL, 0, factor.reg, factor.reg, imm((1<<factor.s))); 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // don't need more than 8-bits for the blend factor 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // and this will prevent overflows in the multiplies later 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (factor.s > 8) { 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(AL, 0, factor.reg, reg_imm(factor.reg, LSR, factor.s-8)); 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project factor.s = 8; 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint GGLAssembler::blending_codes(int fs, int fd) 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int blending = 0; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(fs) { 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE: 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= BLEND_SRC; 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_COLOR: 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_COLOR: 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= FACTOR_DST|BLEND_SRC; 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_ALPHA: 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_ALPHA: 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // no need to extract 'component' from the destination 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // for the blend factor, because we need ALPHA only. 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= BLEND_SRC; 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_COLOR: 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_COLOR: 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= FACTOR_SRC|BLEND_SRC; 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_ALPHA: 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA: 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA_SATURATE: 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= FACTOR_SRC|BLEND_SRC; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(fd) { 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE: 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= BLEND_DST; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_COLOR: 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_COLOR: 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= FACTOR_DST|BLEND_DST; 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_DST_ALPHA: 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_DST_ALPHA: 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= FACTOR_DST|BLEND_DST; 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_COLOR: 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_COLOR: 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= FACTOR_SRC|BLEND_DST; 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_ONE_MINUS_SRC_ALPHA: 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case GGL_SRC_ALPHA: 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // no need to extract 'component' from the source 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // for the blend factor, because we need ALPHA only. 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project blending |= BLEND_DST; 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return blending; 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// --------------------------------------------------------------------------- 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_blendFOneMinusF( 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_t& temp, 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& factor, 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& fragment, 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& fb) 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*f + D*(1-f) = (S-D)*f + D 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch scratches(registerFile()); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // compute S-D 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t diff(fragment.flags & CORRUPTIBLE ? 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fragment.reg : scratches.obtain(), fb.size(), CORRUPTIBLE); 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int shift = fragment.size() - fb.size(); 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (shift>0) RSB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSR, shift)); 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (shift<0) RSB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSL,-shift)); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else RSB(AL, 0, diff.reg, fb.reg, fragment.reg); 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor_add(temp, diff, factor, component_t(fb)); 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_blendOneMinusFF( 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component_t& temp, 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& factor, 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& fragment, 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& fb) 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // R = S*f + D*(1-f) = (S-D)*f + D 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch scratches(registerFile()); 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // compute D-S 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t diff(fb.flags & CORRUPTIBLE ? 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fb.reg : scratches.obtain(), fb.size(), CORRUPTIBLE); 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int shift = fragment.size() - fb.size(); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (shift>0) SUB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSR, shift)); 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (shift<0) SUB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSL,-shift)); 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else SUB(AL, 0, diff.reg, fb.reg, fragment.reg); 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mul_factor_add(temp, diff, factor, component_t(fragment)); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// --------------------------------------------------------------------------- 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::mul_factor( component_t& d, 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& v, 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& f) 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int vs = v.size(); 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fs = f.size(); 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ms = vs+fs; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: we could have special cases for 1 bit mul 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // all this code below to use the best multiply instruction 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // wrt the parameters size. We take advantage of the fact 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // that the 16-bits multiplies allow a 16-bit shift 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // The trick is that we just make sure that we have at least 8-bits 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // per component (which is enough for a 8 bits display). 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int xy; 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int vshift = 0; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fshift = 0; 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int smulw = 0; 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (vs<16) { 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fs<16) { 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyBB; 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (GGL_BETWEEN(fs, 24, 31)) { 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= 16; 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyTB; 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // eg: 15 * 18 -> 15 * 15 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fshift = fs - 15; 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= fshift; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyBB; 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (GGL_BETWEEN(vs, 24, 31)) { 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fs<16) { 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= 16; 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyTB; 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (GGL_BETWEEN(fs, 24, 31)) { 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= 32; 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyTT; 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // eg: 24 * 18 -> 8 * 18 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fshift = fs - 15; 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= 16 + fshift; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyTB; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fs<16) { 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // eg: 18 * 15 -> 15 * 15 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vshift = vs - 15; 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= vshift; 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyBB; 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (GGL_BETWEEN(fs, 24, 31)) { 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // eg: 18 * 24 -> 15 * 8 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vshift = vs - 15; 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= 16 + vshift; 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = xyBT; 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // eg: 18 * 18 -> (15 * 18)>>16 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fshift = fs - 15; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ms -= 16 + fshift; 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xy = yB; //XXX SMULWB 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project smulw = 1; 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53901dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE_IF(ms>=32, "mul_factor overflow vs=%d, fs=%d", vs, fs); 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int vreg = v.reg; 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int freg = f.reg; 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (vshift) { 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(AL, 0, d.reg, reg_imm(vreg, LSR, vshift)); 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vreg = d.reg; 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fshift) { 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(AL, 0, d.reg, reg_imm(vreg, LSR, fshift)); 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freg = d.reg; 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (smulw) SMULW(AL, xy, d.reg, vreg, freg); 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else SMUL(AL, xy, d.reg, vreg, freg); 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.h = ms; 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mDithering) { 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.l = 0; 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.l = fs; 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.flags |= CLEAR_LO; 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::mul_factor_add( component_t& d, 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& v, 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& f, 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const component_t& a) 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // XXX: we could have special cases for 1 bit mul 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Scratch scratches(registerFile()); 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int vs = v.size(); 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fs = f.size(); 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int as = a.h; 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ms = vs+fs; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE_IF(ms>=32, "mul_factor_add overflow vs=%d, fs=%d, as=%d", vs, fs, as); 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project integer_t add(a.reg, a.h, a.flags); 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // 'a' is a component_t but it is guaranteed to have 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // its high bits set to 0. However in the dithering case, 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we can't get away with truncating the potentially bad bits 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // so extraction is needed. 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((mDithering) && (a.size() < ms)) { 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // we need to expand a 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(a.flags & CORRUPTIBLE)) { 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // ... but it's not corruptible, so we need to pick a 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // temporary register. 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Try to uses the destination register first (it's likely 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // to be usable, unless it aliases an input). 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (d.reg!=a.reg && d.reg!=v.reg && d.reg!=f.reg) { 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add.reg = d.reg; 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add.reg = scratches.obtain(); 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project expand(add, a, ms); // extracts and expands 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project as = ms; 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ms == as) { 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (vs<16 && fs<16) SMLABB(AL, d.reg, v.reg, f.reg, add.reg); 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else MLA(AL, 0, d.reg, v.reg, f.reg, add.reg); 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int temp = d.reg; 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (temp == add.reg) { 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // the mul will modify add.reg, we need an intermediary reg 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (v.flags & CORRUPTIBLE) temp = v.reg; 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (f.flags & CORRUPTIBLE) temp = f.reg; 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else temp = scratches.obtain(); 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (vs<16 && fs<16) SMULBB(AL, temp, v.reg, f.reg); 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else MUL(AL, 0, temp, v.reg, f.reg); 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ms>as) { 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, d.reg, temp, reg_imm(add.reg, LSL, ms-as)); 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (ms<as) { 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // not sure if we should expand the mul instead? 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, d.reg, temp, reg_imm(add.reg, LSR, as-ms)); 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.h = ms; 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mDithering) { 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.l = a.l; 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.l = fs>a.l ? fs : a.l; 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.flags |= CLEAR_LO; 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::component_add(component_t& d, 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const integer_t& dst, const integer_t& src) 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // here we're guaranteed that fragment.size() >= fb.size() 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int shift = src.size() - dst.size(); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!shift) { 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, d.reg, src.reg, dst.reg); 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADD(AL, 0, d.reg, src.reg, reg_imm(dst.reg, LSL, shift)); 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.h = src.size(); 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mDithering) { 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.l = 0; 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.l = shift; 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d.flags |= CLEAR_LO; 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::component_sat(const component_t& v) 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int one = ((1<<v.size())-1)<<v.l; 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CMP(AL, v.reg, imm( 1<<v.h )); 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (isValidImmediate(one)) { 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(HS, 0, v.reg, imm( one )); 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (isValidImmediate(~one)) { 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MVN(HS, 0, v.reg, imm( ~one )); 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project MOV(HS, 0, v.reg, imm( 1<<v.h )); 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SUB(HS, 0, v.reg, v.reg, imm( 1<<v.l )); 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 673