1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
77d68335eb427547606497eb4edea81acce7891f9reed@google.com
8125002a94ccba991d151d226b98f100beb5e4b31reed@google.com#include "SkMatrix44.h"
98f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
10125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
113959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.orgstatic bool nearly_equal_double(double a, double b) {
123959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org    const double tolerance = 1e-7;
133959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org    double diff = a - b;
143959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org    if (diff < 0)
153959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org        diff = -diff;
163959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org    return diff <= tolerance;
173959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org}
183959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org
19722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.orgstatic bool nearly_equal_mscalar(SkMScalar a, SkMScalar b) {
20722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    const SkMScalar tolerance = SK_MScalar1 / 200000;
21722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
22722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    return SkTAbs<SkMScalar>(a - b) <= tolerance;
23722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org}
24722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
25722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.orgstatic bool nearly_equal_scalar(SkScalar a, SkScalar b) {
26125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    const SkScalar tolerance = SK_Scalar1 / 200000;
27722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    return SkScalarAbs(a - b) <= tolerance;
28125002a94ccba991d151d226b98f100beb5e4b31reed@google.com}
29125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
30da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.comtemplate <typename T> void assert16(skiatest::Reporter* reporter, const T data[],
31da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                                    T m0,  T m1,  T m2,  T m3,
32da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                                    T m4,  T m5,  T m6,  T m7,
33da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                                    T m8,  T m9,  T m10, T m11,
34da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                                    T m12, T m13, T m14, T m15) {
35da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[0] == m0);
36da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[1] == m1);
37da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[2] == m2);
38da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[3] == m3);
39da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com
40da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[4] == m4);
41da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[5] == m5);
42da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[6] == m6);
43da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[7] == m7);
44da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com
45da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[8] == m8);
46da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[9] == m9);
47da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[10] == m10);
48da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[11] == m11);
49da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com
50da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[12] == m12);
51da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[13] == m13);
52da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[14] == m14);
53da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    REPORTER_ASSERT(reporter, data[15] == m15);
54da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com}
55da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com
56125002a94ccba991d151d226b98f100beb5e4b31reed@google.comstatic bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
57125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    for (int i = 0; i < 4; ++i) {
58125002a94ccba991d151d226b98f100beb5e4b31reed@google.com        for (int j = 0; j < 4; ++j) {
59722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org            if (!nearly_equal_mscalar(a.get(i, j), b.get(i, j))) {
60fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                SkDebugf("not equal %g %g\n", a.get(i, j), b.get(i, j));
61125002a94ccba991d151d226b98f100beb5e4b31reed@google.com                return false;
62125002a94ccba991d151d226b98f100beb5e4b31reed@google.com            }
63125002a94ccba991d151d226b98f100beb5e4b31reed@google.com        }
64125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    }
65125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    return true;
66125002a94ccba991d151d226b98f100beb5e4b31reed@google.com}
67125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
68125002a94ccba991d151d226b98f100beb5e4b31reed@google.comstatic bool is_identity(const SkMatrix44& m) {
694469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 identity(SkMatrix44::kIdentity_Constructor);
70125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    return nearly_equal(m, identity);
71125002a94ccba991d151d226b98f100beb5e4b31reed@google.com}
72125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
7399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com///////////////////////////////////////////////////////////////////////////////
7499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic bool bits_isonly(int value, int mask) {
7599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    return 0 == (value & ~mask);
7699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
7799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
7857a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.orgstatic void test_constructor(skiatest::Reporter* reporter) {
7957a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    // Allocate a matrix on the heap
804469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44* placeholderMatrix = new SkMatrix44(SkMatrix44::kUninitialized_Constructor);
8135300c47fc6e59d8415a06042f230ed36deb60b3robertphillips@google.com    SkAutoTDelete<SkMatrix44> deleteMe(placeholderMatrix);
8235300c47fc6e59d8415a06042f230ed36deb60b3robertphillips@google.com
8357a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    for (int row = 0; row < 4; ++row) {
8457a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org        for (int col = 0; col < 4; ++col) {
8557a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org            placeholderMatrix->setDouble(row, col, row * col);
8657a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org        }
8757a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    }
8857a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org
8957a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    // Use placement-new syntax to trigger the constructor on top of the heap
9057a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    // address we already initialized. This allows us to check that the
9157a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    // constructor did avoid initializing the matrix contents.
9257a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    SkMatrix44* testMatrix = new(placeholderMatrix) SkMatrix44(SkMatrix44::kUninitialized_Constructor);
9357a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    REPORTER_ASSERT(reporter, testMatrix == placeholderMatrix);
9457a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    REPORTER_ASSERT(reporter, !testMatrix->isIdentity());
9557a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    for (int row = 0; row < 4; ++row) {
9657a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org        for (int col = 0; col < 4; ++col) {
9757a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org            REPORTER_ASSERT(reporter, nearly_equal_double(row * col, testMatrix->getDouble(row, col)));
9857a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org        }
9957a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    }
10057a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org
10157a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    // Verify that kIdentity_Constructor really does initialize to an identity matrix.
10257a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    testMatrix = 0;
103c7b4be7f110bc7b487c3c3f28d82877584e74c2fskia.committer@gmail.com    testMatrix = new(placeholderMatrix) SkMatrix44(SkMatrix44::kIdentity_Constructor);
10457a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    REPORTER_ASSERT(reporter, testMatrix == placeholderMatrix);
10557a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    REPORTER_ASSERT(reporter, testMatrix->isIdentity());
10657a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    REPORTER_ASSERT(reporter, *testMatrix == SkMatrix44::I());
10757a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org}
10857a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org
10999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void test_translate(skiatest::Reporter* reporter) {
1104469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
1114469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
11299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
11399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.setTranslate(0, 0, 0);
11499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kIdentity_Mask));
11599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.setTranslate(1, 2, 3);
11699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kTranslate_Mask));
11799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, mat.invert(&inverse));
11899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, bits_isonly(inverse.getType(), SkMatrix44::kTranslate_Mask));
1190264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com
1204469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kUninitialized_Constructor);
1214469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 b(SkMatrix44::kUninitialized_Constructor);
1224469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 c(SkMatrix44::kUninitialized_Constructor);
12399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    a.set3x3(1, 2, 3, 4, 5, 6, 7, 8, 9);
12499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    b.setTranslate(10, 11, 12);
12599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
12699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    c.setConcat(a, b);
12799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat = a;
12899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.preTranslate(10, 11, 12);
12999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, mat == c);
13099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
13199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    c.setConcat(b, a);
13299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat = a;
13399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.postTranslate(10, 11, 12);
13499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, mat == c);
13599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
13699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
13799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void test_scale(skiatest::Reporter* reporter) {
1384469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
1394469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
1400264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com
14199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.setScale(1, 1, 1);
14299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kIdentity_Mask));
14399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.setScale(1, 2, 3);
14499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kScale_Mask));
14599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, mat.invert(&inverse));
14699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, bits_isonly(inverse.getType(), SkMatrix44::kScale_Mask));
14799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
1484469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kUninitialized_Constructor);
1494469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 b(SkMatrix44::kUninitialized_Constructor);
1504469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 c(SkMatrix44::kUninitialized_Constructor);
15199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    a.set3x3(1, 2, 3, 4, 5, 6, 7, 8, 9);
15299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    b.setScale(10, 11, 12);
1530264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com
15499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    c.setConcat(a, b);
15599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat = a;
15699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.preScale(10, 11, 12);
15799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, mat == c);
1580264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com
15999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    c.setConcat(b, a);
16099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat = a;
16199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.postScale(10, 11, 12);
16299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    REPORTER_ASSERT(reporter, mat == c);
16399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
16499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
16599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void make_i(SkMatrix44* mat) { mat->setIdentity(); }
16699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void make_t(SkMatrix44* mat) { mat->setTranslate(1, 2, 3); }
16799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void make_s(SkMatrix44* mat) { mat->setScale(1, 2, 3); }
16899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void make_st(SkMatrix44* mat) {
16999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat->setScale(1, 2, 3);
17099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat->postTranslate(1, 2, 3);
17199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
17299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void make_a(SkMatrix44* mat) {
17399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat->setRotateDegreesAbout(1, 2, 3, 45);
17499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
17599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void make_p(SkMatrix44* mat) {
17699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    SkMScalar data[] = {
17799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        1, 2, 3, 4, 5, 6, 7, 8,
17899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        1, 2, 3, 4, 5, 6, 7, 8,
17999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    };
18099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat->setRowMajor(data);
18199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
18299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
18399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comtypedef void (*Make44Proc)(SkMatrix44*);
18499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
18599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic const Make44Proc gMakeProcs[] = {
18699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    make_i, make_t, make_s, make_st, make_a, make_p
18799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com};
18899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
18999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void test_map2(skiatest::Reporter* reporter, const SkMatrix44& mat) {
19099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    SkMScalar src2[] = { 1, 2 };
19199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    SkMScalar src4[] = { src2[0], src2[1], 0, 1 };
19299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    SkMScalar dstA[4], dstB[4];
19399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
19499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    for (int i = 0; i < 4; ++i) {
19599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        dstA[i] = 123456789;
19699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        dstB[i] = 987654321;
19799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    }
19899b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
19999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.map2(src2, 1, dstA);
20099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    mat.mapMScalars(src4, dstB);
2010264fb4543b0d8cebe00f1ee32433784f4ceb074skia.committer@gmail.com
20299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    for (int i = 0; i < 4; ++i) {
20399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        REPORTER_ASSERT(reporter, dstA[i] == dstB[i]);
20499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    }
20599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
20699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
20799b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.comstatic void test_map2(skiatest::Reporter* reporter) {
2084469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
20999b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
21099b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gMakeProcs); ++i) {
21199b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        gMakeProcs[i](&mat);
21299b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com        test_map2(reporter, mat);
21399b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    }
21499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com}
21599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com
2167d68335eb427547606497eb4edea81acce7891f9reed@google.comstatic void test_gettype(skiatest::Reporter* reporter) {
2174469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 matrix(SkMatrix44::kIdentity_Constructor);
218e659c2e820de0b8d12d81247ed4430022ded0a90skia.committer@gmail.com
2197d68335eb427547606497eb4edea81acce7891f9reed@google.com    REPORTER_ASSERT(reporter, matrix.isIdentity());
2207d68335eb427547606497eb4edea81acce7891f9reed@google.com    REPORTER_ASSERT(reporter, SkMatrix44::kIdentity_Mask == matrix.getType());
221e659c2e820de0b8d12d81247ed4430022ded0a90skia.committer@gmail.com
2227d68335eb427547606497eb4edea81acce7891f9reed@google.com    int expectedMask;
2237d68335eb427547606497eb4edea81acce7891f9reed@google.com
2247d68335eb427547606497eb4edea81acce7891f9reed@google.com    matrix.set(1, 1, 0);
2257d68335eb427547606497eb4edea81acce7891f9reed@google.com    expectedMask = SkMatrix44::kScale_Mask;
2267d68335eb427547606497eb4edea81acce7891f9reed@google.com    REPORTER_ASSERT(reporter, matrix.getType() == expectedMask);
2277d68335eb427547606497eb4edea81acce7891f9reed@google.com
2287d68335eb427547606497eb4edea81acce7891f9reed@google.com    matrix.set(0, 3, 1);    // translate-x
2297d68335eb427547606497eb4edea81acce7891f9reed@google.com    expectedMask |= SkMatrix44::kTranslate_Mask;
2307d68335eb427547606497eb4edea81acce7891f9reed@google.com    REPORTER_ASSERT(reporter, matrix.getType() == expectedMask);
2317d68335eb427547606497eb4edea81acce7891f9reed@google.com
2327d68335eb427547606497eb4edea81acce7891f9reed@google.com    matrix.set(2, 0, 1);
2337d68335eb427547606497eb4edea81acce7891f9reed@google.com    expectedMask |= SkMatrix44::kAffine_Mask;
2347d68335eb427547606497eb4edea81acce7891f9reed@google.com    REPORTER_ASSERT(reporter, matrix.getType() == expectedMask);
235e659c2e820de0b8d12d81247ed4430022ded0a90skia.committer@gmail.com
2367d68335eb427547606497eb4edea81acce7891f9reed@google.com    matrix.set(3, 2, 1);
2377d68335eb427547606497eb4edea81acce7891f9reed@google.com    REPORTER_ASSERT(reporter, matrix.getType() & SkMatrix44::kPerspective_Mask);
23887f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com
23987f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    // ensure that negative zero is treated as zero
24087f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    SkMScalar dx = 0;
24187f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    SkMScalar dy = 0;
24287f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    SkMScalar dz = 0;
24387f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    matrix.setTranslate(-dx, -dy, -dz);
24487f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    REPORTER_ASSERT(reporter, matrix.isIdentity());
24587f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    matrix.preTranslate(-dx, -dy, -dz);
24687f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    REPORTER_ASSERT(reporter, matrix.isIdentity());
24787f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    matrix.postTranslate(-dx, -dy, -dz);
24887f99cb543dbba608136bbd2a7b1e6b3356fd6f9reed@google.com    REPORTER_ASSERT(reporter, matrix.isIdentity());
2497d68335eb427547606497eb4edea81acce7891f9reed@google.com}
2507d68335eb427547606497eb4edea81acce7891f9reed@google.com
2516f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.comstatic void test_common_angles(skiatest::Reporter* reporter) {
2524469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
2536f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com    // Test precision of rotation in common cases
2546f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com    int common_angles[] = { 0, 90, -90, 180, -180, 270, -270, 360, -360 };
2556f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com    for (int i = 0; i < 9; ++i) {
25609042b80d22837c760bb530124aaa67469b19b8frobertphillips@google.com        rot.setRotateDegreesAbout(0, 0, -1, SkIntToScalar(common_angles[i]));
2576f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com
2586f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com        SkMatrix rot3x3 = rot;
2596f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com        REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
2606f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com    }
2616f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com}
2626f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com
26380b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.comstatic void test_concat(skiatest::Reporter* reporter) {
26480b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    int i;
2654469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kUninitialized_Constructor);
2664469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 b(SkMatrix44::kUninitialized_Constructor);
2674469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 c(SkMatrix44::kUninitialized_Constructor);
2684469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 d(SkMatrix44::kUninitialized_Constructor);
26980b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
27080b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    a.setTranslate(10, 10, 10);
27180b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    b.setScale(2, 2, 2);
27280b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
27380b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    SkScalar src[8] = {
27480b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com        0, 0, 0, 1,
27580b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com        1, 1, 1, 1
27680b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    };
27780b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    SkScalar dst[8];
27880b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
27980b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    c.setConcat(a, b);
28080b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
28180b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    d = a;
28280b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    d.preConcat(b);
28380b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    REPORTER_ASSERT(reporter, d == c);
284453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com
2851ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com    c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4);
28680b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    for (i = 0; i < 3; ++i) {
28780b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com        REPORTER_ASSERT(reporter, 10 == dst[i]);
28880b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com        REPORTER_ASSERT(reporter, 12 == dst[i + 4]);
28980b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    }
290453995e01d884d62ce2e808e0067e494c0c9c7faskia.committer@gmail.com
29180b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    c.setConcat(b, a);
29280b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
29380b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    d = a;
29480b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    d.postConcat(b);
29580b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    REPORTER_ASSERT(reporter, d == c);
29680b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
2971ea95be560b38a71e3f24749c4e5e3d3564e4c6creed@google.com    c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4);
29880b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    for (i = 0; i < 3; ++i) {
29980b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com        REPORTER_ASSERT(reporter, 20 == dst[i]);
30080b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com        REPORTER_ASSERT(reporter, 22 == dst[i + 4]);
30180b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    }
30280b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com}
30380b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
3043959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.orgstatic void test_determinant(skiatest::Reporter* reporter) {
3054469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kIdentity_Constructor);
306f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_double(1, a.determinant()));
3077d68335eb427547606497eb4edea81acce7891f9reed@google.com    a.set(1, 1, 2);
308f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_double(2, a.determinant()));
3094469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 b(SkMatrix44::kUninitialized_Constructor);
310f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, a.invert(&b));
311f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_double(0.5, b.determinant()));
312f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    SkMatrix44 c = b = a;
3137d68335eb427547606497eb4edea81acce7891f9reed@google.com    c.set(0, 1, 4);
3147d68335eb427547606497eb4edea81acce7891f9reed@google.com    b.set(1, 0, 4);
315f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter,
316f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org                    nearly_equal_double(a.determinant(),
317f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org                                        b.determinant()));
318f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    SkMatrix44 d = a;
3197d68335eb427547606497eb4edea81acce7891f9reed@google.com    d.set(0, 0, 8);
320f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_double(16, d.determinant()));
321f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org
322f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    SkMatrix44 e = a;
323f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    e.postConcat(d);
324f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_double(32, e.determinant()));
3257d68335eb427547606497eb4edea81acce7891f9reed@google.com    e.set(0, 0, 0);
326f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_double(0, e.determinant()));
3273959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org}
3283959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org
329950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.orgstatic void test_invert(skiatest::Reporter* reporter) {
3304469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
331950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    double inverseData[16];
332950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
3334469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 identity(SkMatrix44::kIdentity_Constructor);
334950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    identity.invert(&inverse);
335950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    inverse.asRowMajord(inverseData);
336950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    assert16<double>(reporter, inverseData,
337950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     1, 0, 0, 0,
338950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0, 1, 0, 0,
339950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0, 0, 1, 0,
340950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0, 0, 0, 1);
341950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
3424469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 translation(SkMatrix44::kUninitialized_Constructor);
343950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    translation.setTranslate(2, 3, 4);
344950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    translation.invert(&inverse);
345950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    inverse.asRowMajord(inverseData);
346950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    assert16<double>(reporter, inverseData,
347950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     1, 0, 0, -2,
348950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0, 1, 0, -3,
349950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0, 0, 1, -4,
350950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0, 0, 0, 1);
351950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
3524469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 scale(SkMatrix44::kUninitialized_Constructor);
353950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    scale.setScale(2, 4, 8);
354950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    scale.invert(&inverse);
355950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    inverse.asRowMajord(inverseData);
356950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    assert16<double>(reporter, inverseData,
357950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0.5, 0,    0,     0,
358950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0,   0.25, 0,     0,
359950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0,   0,    0.125, 0,
360950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0,   0,    0,     1);
361950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
3624469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 scaleTranslation(SkMatrix44::kUninitialized_Constructor);
363950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    scaleTranslation.setScale(10, 100, 1000);
364950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    scaleTranslation.preTranslate(2, 3, 4);
365950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    scaleTranslation.invert(&inverse);
366950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    inverse.asRowMajord(inverseData);
367950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    assert16<double>(reporter, inverseData,
368950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0.1,  0,    0,   -2,
369950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0,   0.01,  0,   -3,
370950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0,    0,  0.001, -4,
371950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org                     0,    0,    0,   1);
372950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
3734469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 rotation(SkMatrix44::kUninitialized_Constructor);
374950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    rotation.setRotateDegreesAbout(0, 0, 1, 90);
375950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    rotation.invert(&inverse);
3764469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 expected(SkMatrix44::kUninitialized_Constructor);
377950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    double expectedInverseRotation[16] =
378950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org            {0,  1, 0, 0,
379950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             -1, 0, 0, 0,
380950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,  0, 1, 0,
381950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,  0, 0, 1};
382950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    expected.setRowMajord(expectedInverseRotation);
383950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));
384b74bdf024930e71ca1be8f874ed49dd0b31449b1skia.committer@gmail.com
3854469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 affine(SkMatrix44::kUninitialized_Constructor);
386950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affine.setRotateDegreesAbout(0, 0, 1, 90);
387950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affine.preScale(10, 20, 100);
388950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affine.preTranslate(2, 3, 4);
389950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affine.invert(&inverse);
390950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    double expectedInverseAffine[16] =
391950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org            {0,    0.1,  0,   -2,
392950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             -0.05, 0,   0,   -3,
393950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,     0,  0.01, -4,
394950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,     0,   0,   1};
395950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    expected.setRowMajord(expectedInverseAffine);
396950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));
397950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
3984469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 perspective(SkMatrix44::kIdentity_Constructor);
399950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    perspective.setDouble(3, 2, 1.0);
400950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    perspective.invert(&inverse);
401950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    double expectedInversePerspective[16] =
402950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org            {1, 0,  0, 0,
403950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0, 1,  0, 0,
404950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0, 0,  1, 0,
405950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0, 0, -1, 1};
406950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    expected.setRowMajord(expectedInversePerspective);
407950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));
408950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
4094469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 affineAndPerspective(SkMatrix44::kIdentity_Constructor);
410950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affineAndPerspective.setDouble(3, 2, 1.0);
411950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affineAndPerspective.preScale(10, 20, 100);
412950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affineAndPerspective.preTranslate(2, 3, 4);
413950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    affineAndPerspective.invert(&inverse);
414950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    double expectedInverseAffineAndPerspective[16] =
415950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org            {0.1, 0,    2,   -2,
416950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,  0.05,  3,   -3,
417950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,   0,   4.01, -4,
418950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org             0,   0,   -1,    1};
419950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    expected.setRowMajord(expectedInverseAffineAndPerspective);
420950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));
421950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org}
422950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org
4239b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.orgstatic void test_transpose(skiatest::Reporter* reporter) {
4244469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kUninitialized_Constructor);
4254469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 b(SkMatrix44::kUninitialized_Constructor);
426f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org
427f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    int i = 0;
428f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    for (int row = 0; row < 4; ++row) {
429f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org        for (int col = 0; col < 4; ++col) {
430f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            a.setDouble(row, col, i);
431f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            b.setDouble(col, row, i++);
432f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org        }
4339b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org    }
4349b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org
435f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    a.transpose();
436f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(a, b));
4379b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org}
4389b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org
4399b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.orgstatic void test_get_set_double(skiatest::Reporter* reporter) {
4404469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kUninitialized_Constructor);
441f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    for (int row = 0; row < 4; ++row) {
442f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org        for (int col = 0; col < 4; ++col) {
443f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            a.setDouble(row, col, 3.141592653589793);
444f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            REPORTER_ASSERT(reporter,
445f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org                            nearly_equal_double(3.141592653589793,
446f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org                                                a.getDouble(row, col)));
447f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            a.setDouble(row, col, 0);
448f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            REPORTER_ASSERT(reporter,
449f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org                            nearly_equal_double(0, a.getDouble(row, col)));
450f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org        }
4519b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org    }
452f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org}
453f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org
454f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.orgstatic void test_set_row_col_major(skiatest::Reporter* reporter) {
4554469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a(SkMatrix44::kUninitialized_Constructor);
4564469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 b(SkMatrix44::kUninitialized_Constructor);
4574469938e92d779dff05e745559e67907bbf21e78reed@google.com
4587d68335eb427547606497eb4edea81acce7891f9reed@google.com    for (int row = 0; row < 4; ++row) {
4597d68335eb427547606497eb4edea81acce7891f9reed@google.com        for (int col = 0; col < 4; ++col) {
460f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org            a.setDouble(row, col, row * 4 + col);
4617d68335eb427547606497eb4edea81acce7891f9reed@google.com        }
4627d68335eb427547606497eb4edea81acce7891f9reed@google.com    }
463e659c2e820de0b8d12d81247ed4430022ded0a90skia.committer@gmail.com
464f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    double bufferd[16];
465f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    float bufferf[16];
466f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    a.asColMajord(bufferd);
467f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    b.setColMajord(bufferd);
468f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(a, b));
469f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    b.setRowMajord(bufferd);
470f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    b.transpose();
471f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(a, b));
472f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    a.asColMajorf(bufferf);
473f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    b.setColMajorf(bufferf);
474f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(a, b));
475f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    b.setRowMajorf(bufferf);
476f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    b.transpose();
477f11cf9ff885c81e29f55283174ca34ce2fc5fd23vollick@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(a, b));
4789b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org}
4799b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org
480722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.orgstatic void test_3x3_conversion(skiatest::Reporter* reporter) {
481722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkMScalar values4x4[16] = { 1, 2, 3, 4,
482722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                                5, 6, 7, 8,
483722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                                9, 10, 11, 12,
484722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                                13, 14, 15, 16 };
485722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkScalar values3x3[9] = { 1, 2, 4,
486722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                              5, 6, 8,
487722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                              13, 14, 16 };
488722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkMScalar values4x4flattened[16] = { 1, 2, 0, 4,
489722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                                         5, 6, 0, 8,
490722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                                         0, 0, 1, 0,
491722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org                                         13, 14, 0, 16 };
4924469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 a44(SkMatrix44::kUninitialized_Constructor);
493722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    a44.setRowMajor(values4x4);
494722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
495722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkMatrix a33 = a44;
496722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkMatrix expected33;
497722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    for (int i = 0; i < 9; i++) expected33[i] = values3x3[i];
498722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, expected33 == a33);
499722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
500722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkMatrix44 a44flattened = a33;
5014469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 expected44flattened(SkMatrix44::kUninitialized_Constructor);
502722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    expected44flattened.setRowMajor(values4x4flattened);
503722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal(a44flattened, expected44flattened));
504722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
505722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    // Test that a point with a Z value of 0 is transformed the same way.
506722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkScalar vec4[4] = { 2, 4, 0, 8 };
507722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkScalar vec3[3] = { 2, 4, 8 };
508722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
509722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkScalar vec4transformed[4];
510722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkScalar vec3transformed[3];
511722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    SkScalar vec4transformed2[4];
512722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    a44.mapScalars(vec4, vec4transformed);
513722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    a33.mapHomogeneousPoints(vec3transformed, vec3, 1);
514722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    a44flattened.mapScalars(vec4, vec4transformed2);
515722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec3transformed[0]));
516722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec3transformed[1]));
517722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec3transformed[2]));
518722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec4transformed2[0]));
519722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec4transformed2[1]));
520722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, !nearly_equal_scalar(vec4transformed[2], vec4transformed2[2]));
521722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec4transformed2[3]));
522722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org}
523722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org
524a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudsonstatic void test_has_perspective(skiatest::Reporter* reporter) {
525a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    SkMatrix44 transform(SkMatrix44::kIdentity_Constructor);
526a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
527a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.set(3, 2, -0.1);
528a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, transform.hasPerspective());
529a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
530a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.reset();
531a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, !transform.hasPerspective());
532a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
533a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.set(3, 0, -1.0);
534a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, transform.hasPerspective());
535a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
536a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.reset();
537a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.set(3, 1, -1.0);
538a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, transform.hasPerspective());
539a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
540a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.reset();
541a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.set(3, 2, -0.3);
542a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, transform.hasPerspective());
543a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
544a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.reset();
545a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.set(3, 3, 0.5);
546a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, transform.hasPerspective());
547a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
548a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.reset();
549a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    transform.set(3, 3, 0.0);
550a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    REPORTER_ASSERT(reporter, transform.hasPerspective());
551a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson}
552a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson
553e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Matrix44, reporter) {
5544469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
5554469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 inverse(SkMatrix44::kUninitialized_Constructor);
5564469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 iden1(SkMatrix44::kUninitialized_Constructor);
5574469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 iden2(SkMatrix44::kUninitialized_Constructor);
5584469938e92d779dff05e745559e67907bbf21e78reed@google.com    SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
559125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
5607d68335eb427547606497eb4edea81acce7891f9reed@google.com    mat.setTranslate(1, 1, 1);
561125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    mat.invert(&inverse);
562125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    iden1.setConcat(mat, inverse);
563125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    REPORTER_ASSERT(reporter, is_identity(iden1));
564125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
5657d68335eb427547606497eb4edea81acce7891f9reed@google.com    mat.setScale(2, 2, 2);
566125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    mat.invert(&inverse);
567125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    iden1.setConcat(mat, inverse);
568125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    REPORTER_ASSERT(reporter, is_identity(iden1));
569125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
5707d68335eb427547606497eb4edea81acce7891f9reed@google.com    mat.setScale(SK_MScalar1/2, SK_MScalar1/2, SK_MScalar1/2);
571125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    mat.invert(&inverse);
572125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    iden1.setConcat(mat, inverse);
573125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    REPORTER_ASSERT(reporter, is_identity(iden1));
574125002a94ccba991d151d226b98f100beb5e4b31reed@google.com
5757d68335eb427547606497eb4edea81acce7891f9reed@google.com    mat.setScale(3, 3, 3);
5767d68335eb427547606497eb4edea81acce7891f9reed@google.com    rot.setRotateDegreesAbout(0, 0, -1, 90);
577125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    mat.postConcat(rot);
578125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    REPORTER_ASSERT(reporter, mat.invert(NULL));
579125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    mat.invert(&inverse);
580125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    iden1.setConcat(mat, inverse);
581125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    REPORTER_ASSERT(reporter, is_identity(iden1));
582125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    iden2.setConcat(inverse, mat);
583125002a94ccba991d151d226b98f100beb5e4b31reed@google.com    REPORTER_ASSERT(reporter, is_identity(iden2));
584da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com
585f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    // test tiny-valued matrix inverse
586f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.reset();
587f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.setScale(1.0e-12, 1.0e-12, 1.0e-12);
588f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    rot.setRotateDegreesAbout(0, 0, -1, 90);
589f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.postConcat(rot);
590f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.postTranslate(1.0e-12, 1.0e-12, 1.0e-12);
591f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    REPORTER_ASSERT(reporter, mat.invert(NULL));
592f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.invert(&inverse);
593f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    iden1.setConcat(mat, inverse);
594f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    REPORTER_ASSERT(reporter, is_identity(iden1));
595b74bdf024930e71ca1be8f874ed49dd0b31449b1skia.committer@gmail.com
596f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    // test mixed-valued matrix inverse
597f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.reset();
59825f72ed03485f58998846d80858d64b5a3c40c7fjvanverth@google.com    mat.setScale(1.0e-10, 3.0, 1.0e+10);
599f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    rot.setRotateDegreesAbout(0, 0, -1, 90);
600f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.postConcat(rot);
60125f72ed03485f58998846d80858d64b5a3c40c7fjvanverth@google.com    mat.postTranslate(1.0e+10, 3.0, 1.0e-10);
602f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    REPORTER_ASSERT(reporter, mat.invert(NULL));
603f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.invert(&inverse);
604f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    iden1.setConcat(mat, inverse);
605f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    REPORTER_ASSERT(reporter, is_identity(iden1));
606b74bdf024930e71ca1be8f874ed49dd0b31449b1skia.committer@gmail.com
607f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    // test degenerate matrix
608f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.reset();
609f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    mat.set3x3(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0);
610f02f07835e417a5baff27dc8ef0b0e773ab7be00commit-bot@chromium.org    REPORTER_ASSERT(reporter, !mat.invert(NULL));
611b74bdf024930e71ca1be8f874ed49dd0b31449b1skia.committer@gmail.com
612da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    // test rol/col Major getters
613da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    {
614da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        mat.setTranslate(2, 3, 4);
615da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        float dataf[16];
616da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        double datad[16];
617d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
618da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        mat.asColMajorf(dataf);
619da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        assert16<float>(reporter, dataf,
620da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                 1, 0, 0, 0,
621da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                 0, 1, 0, 0,
622da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                 0, 0, 1, 0,
623da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                 2, 3, 4, 1);
624da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        mat.asColMajord(datad);
625da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        assert16<double>(reporter, datad, 1, 0, 0, 0,
626da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 1, 0, 0,
627da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 0, 1, 0,
628da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        2, 3, 4, 1);
629da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        mat.asRowMajorf(dataf);
630da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        assert16<float>(reporter, dataf, 1, 0, 0, 2,
631da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 1, 0, 3,
632da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 0, 1, 4,
633da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 0, 0, 1);
634da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        mat.asRowMajord(datad);
635da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com        assert16<double>(reporter, datad, 1, 0, 0, 2,
636da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 1, 0, 3,
637da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 0, 1, 4,
638da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com                        0, 0, 0, 1);
639da9fac0aa13d1445f8b58a75d9390638845c814dreed@google.com    }
6406f2b44d2ff24dd704aa673ab653371d62c1ac931reed@google.com
64180b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com    test_concat(reporter);
64280b577eba6bd8ad2065e3bd9113b9bb86c4a5288reed@google.com
64342639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    if (false) { // avoid bit rot, suppress warning (working on making this pass)
64442639cddc33746b351bbf07c540711eefffe191acaryclark@google.com        test_common_angles(reporter);
64542639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    }
6463959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org
64757a54e33cfe771c792b1086ba67484cb95938d5dvollick@chromium.org    test_constructor(reporter);
6487d68335eb427547606497eb4edea81acce7891f9reed@google.com    test_gettype(reporter);
6493959a76ab086a4adbdb9d48977fa276ce0213cb1vollick@chromium.org    test_determinant(reporter);
650950457543860eb1c545e0ef8bb2c20e2ddc6196ecommit-bot@chromium.org    test_invert(reporter);
6519b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org    test_transpose(reporter);
6529b21c25e742d6a8b69bee8b049e79877f93b5936vollick@chromium.org    test_get_set_double(reporter);
6537d68335eb427547606497eb4edea81acce7891f9reed@google.com    test_set_row_col_major(reporter);
65499b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    test_translate(reporter);
65599b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    test_scale(reporter);
65699b5c7f94ba5ef0c9cb464e34834cd5adea37a0ereed@google.com    test_map2(reporter);
657722555bebbe9128783b8dbe0e897c09c9ccb88cecommit-bot@chromium.org    test_3x3_conversion(reporter);
658a32f1758b7ebd889eecfdc67c935e7edcedc5be3tomhudson    test_has_perspective(reporter);
659125002a94ccba991d151d226b98f100beb5e4b31reed@google.com}
660