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
1791eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#pragma once
1808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1991eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#include "Rect.h"
20f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
211bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include <SkMatrix.h>
2271e36aa7db69449e210d0791284cb810a7471c07Romain Guy#include <cutils/compiler.h>
2391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#include <iomanip>
2491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#include <ostream>
259d5316e3f56d138504565ff311145ac01621dff4Romain Guy
2608ae317c21ec3086b5017672bba87420cc38a407Romain Guynamespace android {
279d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer {
2808ae317c21ec3086b5017672bba87420cc38a407Romain Guy
29629f67709b84a6bebdecdc8a500bf83560f557d0Chris Craik#define SK_MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
301bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#define SK_MATRIX_ARGS(m)                                                                      \
311bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    (m)->get(0), (m)->get(1), (m)->get(2), (m)->get(3), (m)->get(4), (m)->get(5), (m)->get(6), \
321bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            (m)->get(7), (m)->get(8)
3328ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik
341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#define MATRIX_4_STRING                           \
351bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    "[%.2f %.2f %.2f %.2f] [%.2f %.2f %.2f %.2f]" \
36629f67709b84a6bebdecdc8a500bf83560f557d0Chris Craik    " [%.2f %.2f %.2f %.2f] [%.2f %.2f %.2f %.2f]"
371bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#define MATRIX_4_ARGS(m)                                                                           \
381bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    (m)->data[0], (m)->data[4], (m)->data[8], (m)->data[12], (m)->data[1], (m)->data[5],           \
391bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            (m)->data[9], (m)->data[13], (m)->data[2], (m)->data[6], (m)->data[10], (m)->data[14], \
401bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            (m)->data[3], (m)->data[7], (m)->data[11], (m)->data[15]
41629f67709b84a6bebdecdc8a500bf83560f557d0Chris Craik
4208ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
4308ae317c21ec3086b5017672bba87420cc38a407Romain Guy// Classes
4408ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
4508ae317c21ec3086b5017672bba87420cc38a407Romain Guy
4671e36aa7db69449e210d0791284cb810a7471c07Romain Guyclass ANDROID_API Matrix4 {
4708ae317c21ec3086b5017672bba87420cc38a407Romain Guypublic:
487ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    float data[16];
49c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
50af28b514964861d81b48902f942f706050936d38Romain Guy    enum Entry {
51af28b514964861d81b48902f942f706050936d38Romain Guy        kScaleX = 0,
52af28b514964861d81b48902f942f706050936d38Romain Guy        kSkewY = 1,
53af28b514964861d81b48902f942f706050936d38Romain Guy        kPerspective0 = 3,
54af28b514964861d81b48902f942f706050936d38Romain Guy        kSkewX = 4,
55af28b514964861d81b48902f942f706050936d38Romain Guy        kScaleY = 5,
56af28b514964861d81b48902f942f706050936d38Romain Guy        kPerspective1 = 7,
57af28b514964861d81b48902f942f706050936d38Romain Guy        kScaleZ = 10,
58af28b514964861d81b48902f942f706050936d38Romain Guy        kTranslateX = 12,
59af28b514964861d81b48902f942f706050936d38Romain Guy        kTranslateY = 13,
60af28b514964861d81b48902f942f706050936d38Romain Guy        kTranslateZ = 14,
61af28b514964861d81b48902f942f706050936d38Romain Guy        kPerspective2 = 15
62af28b514964861d81b48902f942f706050936d38Romain Guy    };
63af28b514964861d81b48902f942f706050936d38Romain Guy
648ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    // NOTE: The flags from kTypeIdentity to kTypePerspective
658ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    //       must be kept in sync with the type flags found
668ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    //       in SkMatrix
678ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    enum Type {
688ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeIdentity = 0,
698ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeTranslate = 0x1,
708ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeScale = 0x2,
718ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeAffine = 0x4,
728ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypePerspective = 0x8,
738ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        kTypeRectToRect = 0x10,
74996fe656340ede058a6f0e6b18f9ec525ddb4e27Chris Craik        kTypeUnknown = 0x20,
758ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    };
768ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
778ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    static const int sGeometryMask = 0xf;
788ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
791bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    Matrix4() { loadIdentity(); }
8008ae317c21ec3086b5017672bba87420cc38a407Romain Guy
811bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    explicit Matrix4(const float* v) { load(v); }
8208ae317c21ec3086b5017672bba87420cc38a407Romain Guy
83faecb78a6b11c780db47bc940ca7662899ab5d5eChih-Hung Hsieh    Matrix4(const SkMatrix& v) {  // NOLINT, implicit
847ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        load(v);
857ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
86f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
871bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    float operator[](int index) const { return data[index]; }
883b753829ae858d424fe109f714745379a6daf455Romain Guy
893b753829ae858d424fe109f714745379a6daf455Romain Guy    float& operator[](int index) {
903b753829ae858d424fe109f714745379a6daf455Romain Guy        mType = kTypeUnknown;
913b753829ae858d424fe109f714745379a6daf455Romain Guy        return data[index];
923b753829ae858d424fe109f714745379a6daf455Romain Guy    }
933b753829ae858d424fe109f714745379a6daf455Romain Guy
943b753829ae858d424fe109f714745379a6daf455Romain Guy    Matrix4& operator=(const SkMatrix& v) {
953b753829ae858d424fe109f714745379a6daf455Romain Guy        load(v);
963b753829ae858d424fe109f714745379a6daf455Romain Guy        return *this;
973b753829ae858d424fe109f714745379a6daf455Romain Guy    }
983b753829ae858d424fe109f714745379a6daf455Romain Guy
99bd3055f95e67a55648fd84a125e939293115171bRomain Guy    friend bool operator==(const Matrix4& a, const Matrix4& b) {
100bd3055f95e67a55648fd84a125e939293115171bRomain Guy        return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float));
101bd3055f95e67a55648fd84a125e939293115171bRomain Guy    }
102bd3055f95e67a55648fd84a125e939293115171bRomain Guy
1031bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    friend bool operator!=(const Matrix4& a, const Matrix4& b) { return !(a == b); }
104bd3055f95e67a55648fd84a125e939293115171bRomain Guy
1057ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void loadIdentity();
10608ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1077ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void load(const float* 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);
1201bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void loadOrtho(int width, int height) { loadOrtho(0, width, height, 0, -1, 1); }
12108ae317c21ec3086b5017672bba87420cc38a407Romain Guy
122f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy    uint8_t getType() const;
1238ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
124fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik    void multiplyInverse(const Matrix4& v) {
125fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik        Matrix4 inv;
126fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik        inv.loadInverse(v);
127fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik        multiply(inv);
128fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik    }
129fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik
1307ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void multiply(const Matrix4& v) {
131d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik        if (!v.isIdentity()) {
132d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik            Matrix4 u;
133d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik            u.loadMultiply(*this, v);
134d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik            *this = u;
135d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik        }
1367ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
13708ae317c21ec3086b5017672bba87420cc38a407Romain Guy
138ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy    void multiply(float v);
139ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy
140f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik    void translate(float x, float y, float z = 0) {
141f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy        if ((getType() & sGeometryMask) <= kTypeTranslate) {
1424c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            data[kTranslateX] += x;
1434c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            data[kTranslateY] += y;
144f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik            data[kTranslateZ] += z;
145a447d29c65fb811cd184775a3476101a1cede929John Reck            mType |= kTypeUnknown;
1464c2547fa9244e78115cde0a259291053108c3dc7Romain Guy        } else {
1474c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            // Doing a translation will only affect the translate bit of the type
1484c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            // Save the type
149f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy            uint8_t type = mType;
1504c2547fa9244e78115cde0a259291053108c3dc7Romain Guy
1514c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            Matrix4 u;
152f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik            u.loadTranslate(x, y, z);
1534c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            multiply(u);
1544c2547fa9244e78115cde0a259291053108c3dc7Romain Guy
1554c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            // Restore the type and fix the translate bit
1564c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            mType = type;
1574c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) {
1584c2547fa9244e78115cde0a259291053108c3dc7Romain Guy                mType |= kTypeTranslate;
1594c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            } else {
1604c2547fa9244e78115cde0a259291053108c3dc7Romain Guy                mType &= ~kTypeTranslate;
1614c2547fa9244e78115cde0a259291053108c3dc7Romain Guy            }
1624c2547fa9244e78115cde0a259291053108c3dc7Romain Guy        }
1637ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
16408ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1657ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void scale(float sx, float sy, float sz) {
1667ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        Matrix4 u;
1677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        u.loadScale(sx, sy, sz);
1687ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        multiply(u);
1697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
17008ae317c21ec3086b5017672bba87420cc38a407Romain Guy
171807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    void skew(float sx, float sy) {
172807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        Matrix4 u;
173807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        u.loadSkew(sx, sy);
174807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy        multiply(u);
175807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    }
176807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
1777ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void rotate(float angle, float x, float y, float z) {
1787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        Matrix4 u;
1797ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        u.loadRotate(angle, x, y, z);
1807ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy        multiply(u);
1817ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    }
18208ae317c21ec3086b5017672bba87420cc38a407Romain Guy
1838ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    /**
1848ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy     * If the matrix is identity or translate and/or scale.
1858ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy     */
186710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik    bool isSimple() const;
1878ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    bool isPureTranslate() const;
188710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik    bool isIdentity() const;
189a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy    bool isPerspective() const;
1908ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    bool rectToRect() const;
191d965bc5823d878a3fd056b8a95fb4eb578ed3fe4Chris Craik    bool positiveScale() const;
1926620c6d413f972819fada92b574f0fa9e96d36c1Romain Guy
193710f46d9d6a5bf9ea1c1833384caf61e1934124fChris Craik    bool changesBounds() const;
194e8cb9c14309b0f01c0159efdf9a7198f44a62642Romain Guy
1957ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void copyTo(float* v) const;
1967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    void copyTo(SkMatrix& v) const;
19708ae317c21ec3086b5017672bba87420cc38a407Romain Guy
198b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0Chris Craik    float mapZ(const Vector3& orig) const;
199f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik    void mapPoint3d(Vector3& vec) const;
2001bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void mapPoint(float& x, float& y) const;  // 2d only
2011bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    void mapRect(Rect& r) const;              // 2d only
2029d5316e3f56d138504565ff311145ac01621dff4Romain Guy
203624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy    float getTranslateX() const;
204624234f69b2a4781d24f3e4c6ae6450729e38397Romain Guy    float getTranslateY() const;
205bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
2063b753829ae858d424fe109f714745379a6daf455Romain Guy    void decomposeScale(float& sx, float& sy) const;
2073b753829ae858d424fe109f714745379a6daf455Romain Guy
208e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik    void dump(const char* label = nullptr) const;
20908ae317c21ec3086b5017672bba87420cc38a407Romain Guy
21091eff22b5d7f8fe551bae01331948858ce932a96Chris Craik    friend std::ostream& operator<<(std::ostream& os, const Matrix4& matrix) {
21191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik        if (matrix.isSimple()) {
21291eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            os << "offset " << matrix.getTranslateX() << "x" << matrix.getTranslateY();
21391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            if (!matrix.isPureTranslate()) {
21491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik                os << ", scale " << matrix[kScaleX] << "x" << matrix[kScaleY];
21591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            }
21691eff22b5d7f8fe551bae01331948858ce932a96Chris Craik        } else {
21791eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            os << "[" << matrix[0];
21891eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            for (int i = 1; i < 16; i++) {
21991eff22b5d7f8fe551bae01331948858ce932a96Chris Craik                os << ", " << matrix[i];
22091eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            }
22191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik            os << "]";
22291eff22b5d7f8fe551bae01331948858ce932a96Chris Craik        }
22391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik        return os;
22491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik    }
22591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik
226c74f45a334f0e3725c23cdd270cbcb0efac4ea75Romain Guy    static const Matrix4& identity();
227c74f45a334f0e3725c23cdd270cbcb0efac4ea75Romain Guy
2282f69d6d4fdd4994912e5515016421625d1e1c4ecJohn Reck    void invalidateType() { mType = kTypeUnknown; }
2292f69d6d4fdd4994912e5515016421625d1e1c4ecJohn Reck
230f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyprivate:
231f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy    mutable uint8_t mType;
232af28b514964861d81b48902f942f706050936d38Romain Guy
2331bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    inline float get(int i, int j) const { return data[i * 4 + j]; }
23408ae317c21ec3086b5017672bba87420cc38a407Romain Guy
2351bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck    inline void set(int i, int j, float v) { data[i * 4 + j] = v; }
2368ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
237f6bed4f12a2c975678fc0bdea15054ab169aafb5Romain Guy    uint8_t getGeometryType() const;
2388ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
2391bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // class Matrix4
24008ae317c21ec3086b5017672bba87420cc38a407Romain Guy
24108ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
24208ae317c21ec3086b5017672bba87420cc38a407Romain Guy// Types
24308ae317c21ec3086b5017672bba87420cc38a407Romain Guy///////////////////////////////////////////////////////////////////////////////
24408ae317c21ec3086b5017672bba87420cc38a407Romain Guy
24508ae317c21ec3086b5017672bba87420cc38a407Romain Guytypedef Matrix4 mat4;
24608ae317c21ec3086b5017672bba87420cc38a407Romain Guy
2471bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace uirenderer
2481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace android
249