180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2008 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkFloat_DEFINED 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkFloat_DEFINED 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFixed.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkFloat { 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFloat() {} 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setZero() { fPacked = 0; } 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// void setShift(int value, int shift) { fPacked = SetShift(value, shift); } 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setInt(int value) { fPacked = SetShift(value, 0); } 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setFixed(SkFixed value) { fPacked = SetShift(value, -16); } 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setFract(SkFract value) { fPacked = SetShift(value, -30); } 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// int getShift(int shift) const { return GetShift(fPacked, shift); } 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int getInt() const { return GetShift(fPacked, 0); } 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed getFixed() const { return GetShift(fPacked, -16); } 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFract getFract() const { return GetShift(fPacked, -30); } 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void abs() { fPacked = Abs(fPacked); } 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void negate() { fPacked = Neg(fPacked); } 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void shiftLeft(int bits) { fPacked = Shift(fPacked, bits); } 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setShiftLeft(const SkFloat& a, int bits) { fPacked = Shift(a.fPacked, bits); } 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void shiftRight(int bits) { fPacked = Shift(fPacked, -bits); } 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setShiftRight(const SkFloat& a, int bits) { fPacked = Shift(a.fPacked, -bits); } 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void add(const SkFloat& a) { fPacked = Add(fPacked, a.fPacked); } 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setAdd(const SkFloat& a, const SkFloat& b) { fPacked = Add(a.fPacked, b.fPacked); } 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void sub(const SkFloat& a) { fPacked = Add(fPacked, Neg(a.fPacked)); } 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setSub(const SkFloat& a, const SkFloat& b) { fPacked = Add(a.fPacked, Neg(b.fPacked)); } 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void mul(const SkFloat& a) { fPacked = Mul(fPacked, a.fPacked); } 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setMul(const SkFloat& a, const SkFloat& b) { fPacked = Mul(a.fPacked, b.fPacked); } 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void div(const SkFloat& a) { fPacked = Div(fPacked, a.fPacked); } 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setDiv(const SkFloat& a, const SkFloat& b) { fPacked = Div(a.fPacked, b.fPacked); } 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void sqrt() { fPacked = Sqrt(fPacked); } 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setSqrt(const SkFloat& a) { fPacked = Sqrt(a.fPacked); } 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void cubeRoot() { fPacked = CubeRoot(fPacked); } 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setCubeRoot(const SkFloat& a) { fPacked = CubeRoot(a.fPacked); } 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend bool operator==(const SkFloat& a, const SkFloat& b) { return a.fPacked == b.fPacked; } 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend bool operator!=(const SkFloat& a, const SkFloat& b) { return a.fPacked != b.fPacked; } 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend bool operator<(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) < 0; } 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend bool operator<=(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) <= 0; } 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend bool operator>(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) > 0; } 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend bool operator>=(const SkFloat& a, const SkFloat& b) { return Cmp(a.fPacked, b.fPacked) >= 0; } 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static void UnitTest(); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void assertEquals(float f, int tolerance = 0) 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru union { 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float fFloat; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t fPacked; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } tmp; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.fFloat = f; 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int d = tmp.fPacked - fPacked; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkAbs32(d) <= tolerance); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float getFloat() const 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru union { 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float fFloat; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t fPacked; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } tmp; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.fPacked = fPacked; 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return tmp.fFloat; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t fPacked; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int GetShift(int32_t packed, int shift); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t SetShift(int value, int shift); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Neg(int32_t); 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Abs(int32_t packed) { return (uint32_t)(packed << 1) >> 1; } 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Shift(int32_t, int bits); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Add(int32_t, int32_t); 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Mul(int32_t, int32_t); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t MulInt(int32_t, int); 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Div(int32_t, int32_t); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t DivInt(int32_t, int); 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Invert(int32_t); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t Sqrt(int32_t); 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int32_t CubeRoot(int32_t); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int Cmp(int32_t, int32_t); 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 110