Support CHROMIUM_path_rendering

This is partial support for CHROMIUM_path_rendering
and implements basic path management and non-instanced
rendering.

BUG=angleproject:1382

Change-Id: I9c0e88183e0a915d522889323933439d25b45b5f
Reviewed-on: https://chromium-review.googlesource.com/348630
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/common/mathutil.cpp b/src/common/mathutil.cpp
index 927b6eb..acbcbdf 100644
--- a/src/common/mathutil.cpp
+++ b/src/common/mathutil.cpp
@@ -64,4 +64,4 @@
     *blue = inputData->B * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
 }
 
-}
+}  // namespace gl
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index 27329ba..06421f0 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -721,8 +721,42 @@
     return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast<uint32_t>(f) & 0x7fffffu);
 }
 
+namespace priv
+{
+template <unsigned int N, unsigned int R>
+struct iSquareRoot
+{
+    static constexpr unsigned int solve()
+    {
+        return (R * R > N)
+                   ? 0
+                   : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value));
+    }
+    enum Result
+    {
+        value = iSquareRoot::solve()
+    };
+};
+
+template <unsigned int N>
+struct iSquareRoot<N, N>
+{
+    enum result
+    {
+        value = N
+    };
+};
+
+}  // namespace priv
+
+template <unsigned int N>
+constexpr unsigned int iSquareRoot()
+{
+    return priv::iSquareRoot<N, 1>::value;
 }
 
+}  // namespace gl
+
 namespace rx
 {
 
diff --git a/src/common/matrix_utils.h b/src/common/matrix_utils.h
index 6f3187c..aa3f895 100644
--- a/src/common/matrix_utils.h
+++ b/src/common/matrix_utils.h
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "common/debug.h"
+#include "common/mathutil.h"
 
 namespace angle
 {
@@ -337,6 +338,42 @@
         return result;
     }
 
+    void setToIdentity()
+    {
+        ASSERT(rows() == columns());
+
+        const auto one  = T(1);
+        const auto zero = T(0);
+
+        for (auto &e : mElements)
+            e = zero;
+
+        for (unsigned int i = 0; i < rows(); ++i)
+        {
+            const auto pos = i * columns() + (i % columns());
+            mElements[pos] = one;
+        }
+    }
+
+    template <unsigned int Size>
+    static void setToIdentity(T(&matrix)[Size])
+    {
+        static_assert(gl::iSquareRoot<Size>() != 0, "Matrix is not square.");
+
+        const auto cols = gl::iSquareRoot<Size>();
+        const auto one  = T(1);
+        const auto zero = T(0);
+
+        for (auto &e : matrix)
+            e = zero;
+
+        for (unsigned int i = 0; i < cols; ++i)
+        {
+            const auto pos = i * cols + (i % cols);
+            matrix[pos]    = one;
+        }
+    }
+
   private:
     std::vector<T> mElements;
     unsigned int mRows;