diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index d25ad1a..e3ef2a9 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -65,6 +65,7 @@
         "PixelFormat.cpp",
         "Rect.cpp",
         "Region.cpp",
+        "Transform.cpp",
         "UiConfig.cpp",
     ],
 
diff --git a/libs/ui/Transform.cpp b/libs/ui/Transform.cpp
new file mode 100644
index 0000000..8e949ec
--- /dev/null
+++ b/libs/ui/Transform.cpp
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+
+#include <cutils/compiler.h>
+#include <ui/Region.h>
+#include <ui/Transform.h>
+#include <utils/String8.h>
+
+namespace android {
+namespace ui {
+
+Transform::Transform() {
+    reset();
+}
+
+Transform::Transform(const Transform&  other)
+    : mMatrix(other.mMatrix), mType(other.mType) {
+}
+
+Transform::Transform(uint32_t orientation) {
+    set(orientation, 0, 0);
+}
+
+Transform::~Transform() = default;
+
+static const float EPSILON = 0.0f;
+
+bool Transform::isZero(float f) {
+    return fabs(f) <= EPSILON;
+}
+
+bool Transform::absIsOne(float f) {
+    return isZero(fabs(f) - 1.0f);
+}
+
+Transform Transform::operator * (const Transform& rhs) const
+{
+    if (CC_LIKELY(mType == IDENTITY))
+        return rhs;
+
+    Transform r(*this);
+    if (rhs.mType == IDENTITY)
+        return r;
+
+    // TODO: we could use mType to optimize the matrix multiply
+    const mat33& A(mMatrix);
+    const mat33& B(rhs.mMatrix);
+          mat33& D(r.mMatrix);
+    for (size_t i = 0; i < 3; i++) {
+        const float v0 = A[0][i];
+        const float v1 = A[1][i];
+        const float v2 = A[2][i];
+        D[0][i] = v0*B[0][0] + v1*B[0][1] + v2*B[0][2];
+        D[1][i] = v0*B[1][0] + v1*B[1][1] + v2*B[1][2];
+        D[2][i] = v0*B[2][0] + v1*B[2][1] + v2*B[2][2];
+    }
+    r.mType |= rhs.mType;
+
+    // TODO: we could recompute this value from r and rhs
+    r.mType &= 0xFF;
+    r.mType |= UNKNOWN_TYPE;
+    return r;
+}
+
+Transform& Transform::operator=(const Transform& other) {
+    mMatrix = other.mMatrix;
+    mType = other.mType;
+    return *this;
+}
+
+const vec3& Transform::operator [] (size_t i) const {
+    return mMatrix[i];
+}
+
+float Transform::tx() const {
+    return mMatrix[2][0];
+}
+
+float Transform::ty() const {
+    return mMatrix[2][1];
+}
+
+void Transform::reset() {
+    mType = IDENTITY;
+    for(size_t i = 0; i < 3; i++) {
+        vec3& v(mMatrix[i]);
+        for (size_t j = 0; j < 3; j++)
+            v[j] = ((i == j) ? 1.0f : 0.0f);
+    }
+}
+
+void Transform::set(float tx, float ty)
+{
+    mMatrix[2][0] = tx;
+    mMatrix[2][1] = ty;
+    mMatrix[2][2] = 1.0f;
+
+    if (isZero(tx) && isZero(ty)) {
+        mType &= ~TRANSLATE;
+    } else {
+        mType |= TRANSLATE;
+    }
+}
+
+void Transform::set(float a, float b, float c, float d)
+{
+    mat33& M(mMatrix);
+    M[0][0] = a;    M[1][0] = b;
+    M[0][1] = c;    M[1][1] = d;
+    M[0][2] = 0;    M[1][2] = 0;
+    mType = UNKNOWN_TYPE;
+}
+
+status_t Transform::set(uint32_t flags, float w, float h)
+{
+    if (flags & ROT_INVALID) {
+        // that's not allowed!
+        reset();
+        return BAD_VALUE;
+    }
+
+    Transform H, V, R;
+    if (flags & ROT_90) {
+        // w & h are inverted when rotating by 90 degrees
+        std::swap(w, h);
+    }
+
+    if (flags & FLIP_H) {
+        H.mType = (FLIP_H << 8) | SCALE;
+        H.mType |= isZero(w) ? IDENTITY : TRANSLATE;
+        mat33& M(H.mMatrix);
+        M[0][0] = -1;
+        M[2][0] = w;
+    }
+
+    if (flags & FLIP_V) {
+        V.mType = (FLIP_V << 8) | SCALE;
+        V.mType |= isZero(h) ? IDENTITY : TRANSLATE;
+        mat33& M(V.mMatrix);
+        M[1][1] = -1;
+        M[2][1] = h;
+    }
+
+    if (flags & ROT_90) {
+        const float original_w = h;
+        R.mType = (ROT_90 << 8) | ROTATE;
+        R.mType |= isZero(original_w) ? IDENTITY : TRANSLATE;
+        mat33& M(R.mMatrix);
+        M[0][0] = 0;    M[1][0] =-1;    M[2][0] = original_w;
+        M[0][1] = 1;    M[1][1] = 0;
+    }
+
+    *this = (R*(H*V));
+    return NO_ERROR;
+}
+
+vec2 Transform::transform(const vec2& v) const {
+    vec2 r;
+    const mat33& M(mMatrix);
+    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0];
+    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1];
+    return r;
+}
+
+vec3 Transform::transform(const vec3& v) const {
+    vec3 r;
+    const mat33& M(mMatrix);
+    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0]*v[2];
+    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1]*v[2];
+    r[2] = M[0][2]*v[0] + M[1][2]*v[1] + M[2][2]*v[2];
+    return r;
+}
+
+vec2 Transform::transform(int x, int y) const
+{
+    return transform(vec2(x,y));
+}
+
+Rect Transform::makeBounds(int w, int h) const
+{
+    return transform( Rect(w, h) );
+}
+
+Rect Transform::transform(const Rect& bounds, bool roundOutwards) const
+{
+    Rect r;
+    vec2 lt( bounds.left,  bounds.top    );
+    vec2 rt( bounds.right, bounds.top    );
+    vec2 lb( bounds.left,  bounds.bottom );
+    vec2 rb( bounds.right, bounds.bottom );
+
+    lt = transform(lt);
+    rt = transform(rt);
+    lb = transform(lb);
+    rb = transform(rb);
+
+    if (roundOutwards) {
+        r.left   = static_cast<int32_t>(floorf(std::min({lt[0], rt[0], lb[0], rb[0]})));
+        r.top    = static_cast<int32_t>(floorf(std::min({lt[1], rt[1], lb[1], rb[1]})));
+        r.right  = static_cast<int32_t>(ceilf(std::max({lt[0], rt[0], lb[0], rb[0]})));
+        r.bottom = static_cast<int32_t>(ceilf(std::max({lt[1], rt[1], lb[1], rb[1]})));
+    } else {
+        r.left   = static_cast<int32_t>(floorf(std::min({lt[0], rt[0], lb[0], rb[0]}) + 0.5f));
+        r.top    = static_cast<int32_t>(floorf(std::min({lt[1], rt[1], lb[1], rb[1]}) + 0.5f));
+        r.right  = static_cast<int32_t>(floorf(std::max({lt[0], rt[0], lb[0], rb[0]}) + 0.5f));
+        r.bottom = static_cast<int32_t>(floorf(std::max({lt[1], rt[1], lb[1], rb[1]}) + 0.5f));
+    }
+
+    return r;
+}
+
+FloatRect Transform::transform(const FloatRect& bounds) const
+{
+    vec2 lt(bounds.left, bounds.top);
+    vec2 rt(bounds.right, bounds.top);
+    vec2 lb(bounds.left, bounds.bottom);
+    vec2 rb(bounds.right, bounds.bottom);
+
+    lt = transform(lt);
+    rt = transform(rt);
+    lb = transform(lb);
+    rb = transform(rb);
+
+    FloatRect r;
+    r.left = std::min({lt[0], rt[0], lb[0], rb[0]});
+    r.top = std::min({lt[1], rt[1], lb[1], rb[1]});
+    r.right = std::max({lt[0], rt[0], lb[0], rb[0]});
+    r.bottom = std::max({lt[1], rt[1], lb[1], rb[1]});
+
+    return r;
+}
+
+Region Transform::transform(const Region& reg) const
+{
+    Region out;
+    if (CC_UNLIKELY(type() > TRANSLATE)) {
+        if (CC_LIKELY(preserveRects())) {
+            Region::const_iterator it = reg.begin();
+            Region::const_iterator const end = reg.end();
+            while (it != end) {
+                out.orSelf(transform(*it++));
+            }
+        } else {
+            out.set(transform(reg.bounds()));
+        }
+    } else {
+        int xpos = static_cast<int>(floorf(tx() + 0.5f));
+        int ypos = static_cast<int>(floorf(ty() + 0.5f));
+        out = reg.translate(xpos, ypos);
+    }
+    return out;
+}
+
+uint32_t Transform::type() const
+{
+    if (mType & UNKNOWN_TYPE) {
+        // recompute what this transform is
+
+        const mat33& M(mMatrix);
+        const float a = M[0][0];
+        const float b = M[1][0];
+        const float c = M[0][1];
+        const float d = M[1][1];
+        const float x = M[2][0];
+        const float y = M[2][1];
+
+        bool scale = false;
+        uint32_t flags = ROT_0;
+        if (isZero(b) && isZero(c)) {
+            if (a<0)    flags |= FLIP_H;
+            if (d<0)    flags |= FLIP_V;
+            if (!absIsOne(a) || !absIsOne(d)) {
+                scale = true;
+            }
+        } else if (isZero(a) && isZero(d)) {
+            flags |= ROT_90;
+            if (b>0)    flags |= FLIP_V;
+            if (c<0)    flags |= FLIP_H;
+            if (!absIsOne(b) || !absIsOne(c)) {
+                scale = true;
+            }
+        } else {
+            // there is a skew component and/or a non 90 degrees rotation
+            flags = ROT_INVALID;
+        }
+
+        mType = flags << 8;
+        if (flags & ROT_INVALID) {
+            mType |= UNKNOWN;
+        } else {
+            if ((flags & ROT_90) || ((flags & ROT_180) == ROT_180))
+                mType |= ROTATE;
+            if (flags & FLIP_H)
+                mType ^= SCALE;
+            if (flags & FLIP_V)
+                mType ^= SCALE;
+            if (scale)
+                mType |= SCALE;
+        }
+
+        if (!isZero(x) || !isZero(y))
+            mType |= TRANSLATE;
+    }
+    return mType;
+}
+
+Transform Transform::inverse() const {
+    // our 3x3 matrix is always of the form of a 2x2 transformation
+    // followed by a translation: T*M, therefore:
+    // (T*M)^-1 = M^-1 * T^-1
+    Transform result;
+    if (mType <= TRANSLATE) {
+        // 1 0 0
+        // 0 1 0
+        // x y 1
+        result = *this;
+        result.mMatrix[2][0] = -result.mMatrix[2][0];
+        result.mMatrix[2][1] = -result.mMatrix[2][1];
+    } else {
+        // a c 0
+        // b d 0
+        // x y 1
+        const mat33& M(mMatrix);
+        const float a = M[0][0];
+        const float b = M[1][0];
+        const float c = M[0][1];
+        const float d = M[1][1];
+        const float x = M[2][0];
+        const float y = M[2][1];
+
+        const float idet = 1.0f / (a*d - b*c);
+        result.mMatrix[0][0] =  d*idet;
+        result.mMatrix[0][1] = -c*idet;
+        result.mMatrix[1][0] = -b*idet;
+        result.mMatrix[1][1] =  a*idet;
+        result.mType = mType;
+
+        vec2 T(-x, -y);
+        T = result.transform(T);
+        result.mMatrix[2][0] = T[0];
+        result.mMatrix[2][1] = T[1];
+    }
+    return result;
+}
+
+uint32_t Transform::getType() const {
+    return type() & 0xFF;
+}
+
+uint32_t Transform::getOrientation() const
+{
+    return (type() >> 8) & 0xFF;
+}
+
+bool Transform::preserveRects() const
+{
+    return (getOrientation() & ROT_INVALID) ? false : true;
+}
+
+void Transform::dump(const char* name) const
+{
+    type(); // updates the type
+
+    String8 flags, type;
+    const mat33& m(mMatrix);
+    uint32_t orient = mType >> 8;
+
+    if (orient&ROT_INVALID) {
+        flags.append("ROT_INVALID ");
+    } else {
+        if (orient&ROT_90) {
+            flags.append("ROT_90 ");
+        } else {
+            flags.append("ROT_0 ");
+        }
+        if (orient&FLIP_V)
+            flags.append("FLIP_V ");
+        if (orient&FLIP_H)
+            flags.append("FLIP_H ");
+    }
+
+    if (!(mType&(SCALE|ROTATE|TRANSLATE)))
+        type.append("IDENTITY ");
+    if (mType&SCALE)
+        type.append("SCALE ");
+    if (mType&ROTATE)
+        type.append("ROTATE ");
+    if (mType&TRANSLATE)
+        type.append("TRANSLATE ");
+
+    ALOGD("%s 0x%08x (%s, %s)", name, mType, flags.string(), type.string());
+    ALOGD("%.4f  %.4f  %.4f", static_cast<double>(m[0][0]), static_cast<double>(m[1][0]),
+          static_cast<double>(m[2][0]));
+    ALOGD("%.4f  %.4f  %.4f", static_cast<double>(m[0][1]), static_cast<double>(m[1][1]),
+          static_cast<double>(m[2][1]));
+    ALOGD("%.4f  %.4f  %.4f", static_cast<double>(m[0][2]), static_cast<double>(m[1][2]),
+          static_cast<double>(m[2][2]));
+}
+
+}  // namespace ui
+}  // namespace android
diff --git a/libs/ui/include/ui/Transform.h b/libs/ui/include/ui/Transform.h
new file mode 100644
index 0000000..42dca75
--- /dev/null
+++ b/libs/ui/include/ui/Transform.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TRANSFORM_H
+#define ANDROID_TRANSFORM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware/hardware.h>
+#include <math/vec2.h>
+#include <math/vec3.h>
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+namespace android {
+
+class Region;
+
+namespace ui {
+
+class Transform {
+public:
+    Transform();
+    Transform(const Transform&  other);
+    explicit Transform(uint32_t orientation);
+    ~Transform();
+
+    enum orientation_flags {
+        ROT_0   = 0x00000000,
+        FLIP_H  = HAL_TRANSFORM_FLIP_H,
+        FLIP_V  = HAL_TRANSFORM_FLIP_V,
+        ROT_90  = HAL_TRANSFORM_ROT_90,
+        ROT_180 = FLIP_H|FLIP_V,
+        ROT_270 = ROT_180|ROT_90,
+        ROT_INVALID = 0x80
+    };
+
+    enum type_mask : uint32_t {
+        IDENTITY            = 0,
+        TRANSLATE           = 0x1,
+        ROTATE              = 0x2,
+        SCALE               = 0x4,
+        UNKNOWN             = 0x8
+    };
+
+    // query the transform
+    bool        preserveRects() const;
+    uint32_t    getType() const;
+    uint32_t    getOrientation() const;
+
+    const vec3& operator [] (size_t i) const;  // returns column i
+    float   tx() const;
+    float   ty() const;
+
+    // modify the transform
+    void        reset();
+    void        set(float tx, float ty);
+    void        set(float a, float b, float c, float d);
+    status_t    set(uint32_t flags, float w, float h);
+
+    // transform data
+    Rect    makeBounds(int w, int h) const;
+    vec2    transform(int x, int y) const;
+    Region  transform(const Region& reg) const;
+    Rect    transform(const Rect& bounds,
+                      bool roundOutwards = false) const;
+    FloatRect transform(const FloatRect& bounds) const;
+    Transform& operator = (const Transform& other);
+    Transform operator * (const Transform& rhs) const;
+    // assumes the last row is < 0 , 0 , 1 >
+    vec2 transform(const vec2& v) const;
+    vec3 transform(const vec3& v) const;
+
+    Transform inverse() const;
+
+    // for debugging
+    void dump(const char* name) const;
+
+private:
+    struct mat33 {
+        vec3 v[3];
+        inline const vec3& operator [] (size_t i) const { return v[i]; }
+        inline vec3& operator [] (size_t i) { return v[i]; }
+    };
+
+    enum { UNKNOWN_TYPE = 0x80000000 };
+
+    uint32_t type() const;
+    static bool absIsOne(float f);
+    static bool isZero(float f);
+
+    mat33               mMatrix;
+    mutable uint32_t    mType;
+};
+
+}  // namespace ui
+}  // namespace android
+
+#endif /* ANDROID_TRANSFORM_H */
