Matrix.h revision bd3055f95e67a55648fd84a125e939293115171b
108ae317c21ec3086b5017672bba87420cc38a407Romain Guy/*
208ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Copyright (C) 2010 The Android Open Source Project
308ae317c21ec3086b5017672bba87420cc38a407Romain Guy *
408ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
508ae317c21ec3086b5017672bba87420cc38a407Romain Guy * you may not use this file except in compliance with the License.
608ae317c21ec3086b5017672bba87420cc38a407Romain Guy * You may obtain a copy of the License at
708ae317c21ec3086b5017672bba87420cc38a407Romain Guy *
808ae317c21ec3086b5017672bba87420cc38a407Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
908ae317c21ec3086b5017672bba87420cc38a407Romain Guy *
1008ae317c21ec3086b5017672bba87420cc38a407Romain Guy * Unless required by applicable law or agreed to in writing, software
1108ae317c21ec3086b5017672bba87420cc38a407Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
1208ae317c21ec3086b5017672bba87420cc38a407Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308ae317c21ec3086b5017672bba87420cc38a407Romain Guy * See the License for the specific language governing permissions and
1408ae317c21ec3086b5017672bba87420cc38a407Romain Guy * limitations under the License.
1508ae317c21ec3086b5017672bba87420cc38a407Romain Guy */
1608ae317c21ec3086b5017672bba87420cc38a407Romain Guy
175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_MATRIX_H
185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_MATRIX_H
1908ae317c21ec3086b5017672bba87420cc38a407Romain Guy
20f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy#include <SkMatrix.h>
21f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
2271e36aa7db69449e210d0791284cb810a7471c07Romain Guy#include <cutils/compiler.h>
2371e36aa7db69449e210d0791284cb810a7471c07Romain Guy
249d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "Rect.h"
259d5316e3f56d138504565ff311145ac01621dff4Romain Guy
2608ae317c21ec3086b5017672bba87420cc38a407Romain Guynamespace android {
279d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer {
2808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
2908ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
3008ae317c21ec3086b5017672bba87420cc38a407Romain Guy// Classes
3108ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
3208ae317c21ec3086b5017672bba87420cc38a407Romain Guy
3371e36aa7db69449e210d0791284cb810a7471c07Romain Guyclass ANDROID_API Matrix4 {
3408ae317c21ec3086b5017672bba87420cc38a407Romain Guypublic:
357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float data[16];
36c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
37af28b514964861d81b48902f942f706050936d38Romain Guy    enum Entry {
38af28b514964861d81b48902f942f706050936d38Romain Guy        kScaleX = 0,
39af28b514964861d81b48902f942f706050936d38Romain Guy        kSkewY = 1,
40af28b514964861d81b48902f942f706050936d38Romain Guy        kPerspective0 = 3,
41af28b514964861d81b48902f942f706050936d38Romain Guy        kSkewX = 4,
42af28b514964861d81b48902f942f706050936d38Romain Guy        kScaleY = 5,
43af28b514964861d81b48902f942f706050936d38Romain Guy        kPerspective1 = 7,
44af28b514964861d81b48902f942f706050936d38Romain Guy        kScaleZ = 10,
45af28b514964861d81b48902f942f706050936d38Romain Guy        kTranslateX = 12,
46af28b514964861d81b48902f942f706050936d38Romain Guy        kTranslateY = 13,
47af28b514964861d81b48902f942f706050936d38Romain Guy        kTranslateZ = 14,
48af28b514964861d81b48902f942f706050936d38Romain Guy        kPerspective2 = 15
49af28b514964861d81b48902f942f706050936d38Romain Guy    };
50af28b514964861d81b48902f942f706050936d38Romain Guy
518ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    // NOTE: The flags from kTypeIdentity to kTypePerspective
528ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    //       must be kept in sync with the type flags found
538ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    //       in SkMatrix
548ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    enum Type {
558ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeIdentity = 0,
568ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeTranslate = 0x1,
578ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeScale = 0x2,
588ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeAffine = 0x4,
598ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypePerspective = 0x8,
608ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeRectToRect = 0x10,
618ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeUnknown = 0x20,
628ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    };
638ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
648ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    static const int sGeometryMask = 0xf;
658ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
667ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    Matrix4() {
677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        loadIdentity();
687ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
6908ae317c21ec3086b5017672bba87420cc38a407Romain Guy
707ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    Matrix4(const float* v) {
717ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        load(v);
727ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
7308ae317c21ec3086b5017672bba87420cc38a407Romain Guy
747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    Matrix4(const Matrix4& v) {
757ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        load(v);
767ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
7708ae317c21ec3086b5017672bba87420cc38a407Romain Guy
787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    Matrix4(const SkMatrix& v) {
797ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        load(v);
807ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
81f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
823b753829ae858d424fe109f714745379a6daf455Romain Guy    float operator[](int index) const {
833b753829ae858d424fe109f714745379a6daf455Romain Guy        return data[index];
843b753829ae858d424fe109f714745379a6daf455Romain Guy    }
853b753829ae858d424fe109f714745379a6daf455Romain Guy
863b753829ae858d424fe109f714745379a6daf455Romain Guy    float& operator[](int index) {
873b753829ae858d424fe109f714745379a6daf455Romain Guy        mType = kTypeUnknown;
883b753829ae858d424fe109f714745379a6daf455Romain Guy        return data[index];
893b753829ae858d424fe109f714745379a6daf455Romain Guy    }
903b753829ae858d424fe109f714745379a6daf455Romain Guy
913b753829ae858d424fe109f714745379a6daf455Romain Guy    Matrix4& operator=(const SkMatrix& v) {
923b753829ae858d424fe109f714745379a6daf455Romain Guy        load(v);
933b753829ae858d424fe109f714745379a6daf455Romain Guy        return *this;
943b753829ae858d424fe109f714745379a6daf455Romain Guy    }
953b753829ae858d424fe109f714745379a6daf455Romain Guy
96bd3055f95e67a55648fd84a125e939293115171bRomain Guy    friend bool operator==(const Matrix4& a, const Matrix4& b) {
97bd3055f95e67a55648fd84a125e939293115171bRomain Guy        return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float));
98bd3055f95e67a55648fd84a125e939293115171bRomain Guy    }
99bd3055f95e67a55648fd84a125e939293115171bRomain Guy
100bd3055f95e67a55648fd84a125e939293115171bRomain Guy    friend bool operator!=(const Matrix4& a, const Matrix4& b) {
101bd3055f95e67a55648fd84a125e939293115171bRomain Guy        return !(a == b);
102bd3055f95e67a55648fd84a125e939293115171bRomain Guy    }
103bd3055f95e67a55648fd84a125e939293115171bRomain Guy
1047ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadIdentity();
10508ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1067ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void load(const float* v);
1077ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void load(const Matrix4& v);
1087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void load(const SkMatrix& v);
10908ae317c21ec3086b5017672bba87420cc38a407Romain Guy
110079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy    void loadInverse(const Matrix4& v);
111079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy
1127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadTranslate(float x, float y, float z);
1137ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadScale(float sx, float sy, float sz);
114807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    void loadSkew(float sx, float sy);
1158ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    void loadRotate(float angle);
1167ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadRotate(float angle, float x, float y, float z);
1177ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadMultiply(const Matrix4& u, const Matrix4& v);
11808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1197ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadOrtho(float left, float right, float bottom, float top, float near, float far);
12008ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1218ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    uint32_t getType() const;
1228ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
1237ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void multiply(const Matrix4& v) {
1247ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        Matrix4 u;
1257ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        u.loadMultiply(*this, v);
1267ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        load(u);
1277ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
12808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
129ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy    void multiply(float v);
130ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy
1317ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void translate(float x, float y, float z) {
1327ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        Matrix4 u;
1337ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        u.loadTranslate(x, y, z);
1347ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        multiply(u);
1357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
13608ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1377ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void scale(float sx, float sy, float sz) {
1387ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        Matrix4 u;
1397ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        u.loadScale(sx, sy, sz);
1407ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        multiply(u);
1417ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
14208ae317c21ec3086b5017672bba87420cc38a407Romain Guy
143807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    void skew(float sx, float sy) {
144807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        Matrix4 u;
145807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        u.loadSkew(sx, sy);
146807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        multiply(u);
147807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    }
148807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
1497ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void rotate(float angle, float x, float y, float z) {
1507ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        Matrix4 u;
1517ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        u.loadRotate(angle, x, y, z);
1527ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        multiply(u);
1537ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
15408ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1558ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    /**
1568ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy     * If the matrix is identity or translate and/or scale.
1578ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy     */
158710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik    bool isSimple() const;
1598ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    bool isPureTranslate() const;
160710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik    bool isIdentity() const;
161a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy    bool isPerspective() const;
1628ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    bool rectToRect() const;
1636620c6d413f972819fada92b574f0fa9e96d36c1Romain Guy
164710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik    bool changesBounds() const;
165e8cb9c14309b0f01c0159efdf9a7198f44a62642Romain Guy
1667ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void copyTo(float* v) const;
1677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void copyTo(SkMatrix& v) const;
16808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void mapRect(Rect& r) const;
1700ba681bce12d522c5575dfccb5a6ca12f0fba746Romain Guy    void mapPoint(float& x, float& y) const;
1719d5316e3f56d138504565ff311145ac01621dff4Romain Guy
172624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy    float getTranslateX() const;
173624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy    float getTranslateY() const;
174bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
1753b753829ae858d424fe109f714745379a6daf455Romain Guy    void decomposeScale(float& sx, float& sy) const;
1763b753829ae858d424fe109f714745379a6daf455Romain Guy
1777ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void dump() const;
17808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
179c74f45a334f0e3725c23cdd270cbcb0efac4ea75Romain Guy    static const Matrix4& identity();
180c74f45a334f0e3725c23cdd270cbcb0efac4ea75Romain Guy
181f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyprivate:
1828ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    mutable uint32_t mType;
183af28b514964861d81b48902f942f706050936d38Romain Guy
18408ae317c21ec3086b5017672bba87420cc38a407Romain Guy    inline float get(int i, int j) const {
185c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy        return data[i * 4 + j];
18608ae317c21ec3086b5017672bba87420cc38a407Romain Guy    }
18708ae317c21ec3086b5017672bba87420cc38a407Romain Guy
18808ae317c21ec3086b5017672bba87420cc38a407Romain Guy    inline void set(int i, int j, float v) {
1897ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        data[i * 4 + j] = v;
19008ae317c21ec3086b5017672bba87420cc38a407Romain Guy    }
1918ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
1928ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    uint32_t getGeometryType() const;
1938ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
19408ae317c21ec3086b5017672bba87420cc38a407Romain Guy}; // class Matrix4
19508ae317c21ec3086b5017672bba87420cc38a407Romain Guy
19608ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
19708ae317c21ec3086b5017672bba87420cc38a407Romain Guy// Types
19808ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
19908ae317c21ec3086b5017672bba87420cc38a407Romain Guy
20008ae317c21ec3086b5017672bba87420cc38a407Romain Guytypedef Matrix4 mat4;
20108ae317c21ec3086b5017672bba87420cc38a407Romain Guy
2029d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer
20308ae317c21ec3086b5017672bba87420cc38a407Romain Guy}; // namespace android
20408ae317c21ec3086b5017672bba87420cc38a407Romain Guy
2055b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_MATRIX_H
206