[go: nahoru, domu]

Refactored Vector Graphics APIs to Use DrawScope

-Refactored Vector graphics to use DrawScope
instead of Canvas + Paint APIs
-Renamed CanvasTransform to DrawTransform
to match filename
-Fixed issue where cached ImageAsset was not
cleared across draw calls
-Updated VectorPainter to be remembered/re-used
across compositions
-Created CacheDrawScope to handle rendering contents
into an ImageAsset and drawing that ImageAsset into
a different DrawScope target

Change-Id: I861634f746f9d801911cbf7dc06c38458cfd3d3c
Fixes: 158881674
Test: Re-ran compose tests
diff --git a/ui/ui-core/api/0.1.0-dev14.txt b/ui/ui-core/api/0.1.0-dev14.txt
index c7e48bd..7c47f7a 100644
--- a/ui/ui-core/api/0.1.0-dev14.txt
+++ b/ui/ui-core/api/0.1.0-dev14.txt
@@ -1906,86 +1906,9 @@
 
 package androidx.ui.graphics.vector {
 
-  public final class GroupComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public String component1();
-    method public androidx.ui.graphics.vector.GroupComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getClipPathData();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vector.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> clipPathData;
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class PathComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public PathComponent(String name);
-    method public String component1();
-    method public androidx.ui.graphics.vector.PathComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public androidx.ui.graphics.Brush? getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getPathData();
-    method public androidx.ui.graphics.Brush? getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.graphics.StrokeCap getStrokeLineCap();
-    method public androidx.ui.graphics.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.Brush? value);
-    method public void setFillAlpha(float value);
-    method public void setPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setStroke(androidx.ui.graphics.Brush? value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.graphics.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.graphics.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.Brush? fill;
-    property public final float fillAlpha;
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> pathData;
-    property public final androidx.ui.graphics.Brush? stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.graphics.StrokeCap strokeLineCap;
-    property public final androidx.ui.graphics.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
   public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.graphics.Canvas canvas);
-    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getInvalidateListener();
+    method public abstract void draw(androidx.ui.graphics.drawscope.DrawScope);
     method public final void invalidate();
-    method public void setInvalidateListener(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
   }
 
   public final class VectorAsset {
@@ -2021,36 +1944,9 @@
     method public static androidx.ui.graphics.vector.VectorAssetBuilder path(androidx.ui.graphics.vector.VectorAssetBuilder, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
   }
 
-  public final class VectorComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public VectorComponent(float viewportWidth, float viewportHeight, float defaultWidth, float defaultHeight, String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas, float alpha, androidx.ui.graphics.ColorFilter? colorFilter);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public float getDefaultHeight();
-    method public float getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vector.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(float p);
-    method public void setDefaultWidth(float p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vector.GroupComponent root;
-    property public final int size;
-  }
-
   public final class VectorComposeKt {
     method @androidx.compose.Composable public static void Group(androidx.ui.graphics.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, java.util.List<? extends androidx.ui.graphics.vector.PathNode> clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.VectorScope,kotlin.Unit> children);
     method @androidx.compose.Composable public static void Path(androidx.ui.graphics.vector.VectorScope, java.util.List<? extends androidx.ui.graphics.vector.PathNode> pathData, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
-    method public static androidx.compose.Composition composeVector(androidx.ui.graphics.vector.VectorComponent container, androidx.compose.Recomposer recomposer, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function3<? super androidx.ui.graphics.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> composable);
-  }
-
-  public final class VectorComposer extends androidx.compose.Composer<androidx.ui.graphics.vector.VNode> {
-    ctor public VectorComposer(androidx.ui.graphics.vector.VNode root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
-    method public inline <T extends androidx.ui.graphics.vector.VNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.VNode>,kotlin.Unit> update);
-    method public inline void emit(Object key, kotlin.jvm.functions.Function0<androidx.ui.graphics.vector.GroupComponent> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.GroupComponent>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.graphics.vector.VNode getRoot();
   }
 
   public final class VectorGroup extends androidx.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2079,7 +1975,6 @@
     method public static androidx.ui.graphics.BlendMode getDefaultTintBlendMode();
     method public static long getDefaultTintColor();
     method public static java.util.List<androidx.ui.graphics.vector.PathNode> getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
     field public static final String DefaultGroupName = "";
     field public static final String DefaultPathName = "";
     field public static final float DefaultPivotX = 0.0f;
@@ -2134,8 +2029,6 @@
   }
 
   public final class VectorScope {
-    ctor public VectorScope(androidx.ui.graphics.vector.VectorComposer composer);
-    method public androidx.ui.graphics.vector.VectorComposer getComposer();
   }
 
 }
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index c7e48bd..7c47f7a 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -1906,86 +1906,9 @@
 
 package androidx.ui.graphics.vector {
 
-  public final class GroupComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public String component1();
-    method public androidx.ui.graphics.vector.GroupComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getClipPathData();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vector.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> clipPathData;
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class PathComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public PathComponent(String name);
-    method public String component1();
-    method public androidx.ui.graphics.vector.PathComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public androidx.ui.graphics.Brush? getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getPathData();
-    method public androidx.ui.graphics.Brush? getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.graphics.StrokeCap getStrokeLineCap();
-    method public androidx.ui.graphics.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.Brush? value);
-    method public void setFillAlpha(float value);
-    method public void setPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setStroke(androidx.ui.graphics.Brush? value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.graphics.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.graphics.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.Brush? fill;
-    property public final float fillAlpha;
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> pathData;
-    property public final androidx.ui.graphics.Brush? stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.graphics.StrokeCap strokeLineCap;
-    property public final androidx.ui.graphics.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
   public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.graphics.Canvas canvas);
-    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getInvalidateListener();
+    method public abstract void draw(androidx.ui.graphics.drawscope.DrawScope);
     method public final void invalidate();
-    method public void setInvalidateListener(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
   }
 
   public final class VectorAsset {
@@ -2021,36 +1944,9 @@
     method public static androidx.ui.graphics.vector.VectorAssetBuilder path(androidx.ui.graphics.vector.VectorAssetBuilder, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
   }
 
-  public final class VectorComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public VectorComponent(float viewportWidth, float viewportHeight, float defaultWidth, float defaultHeight, String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas, float alpha, androidx.ui.graphics.ColorFilter? colorFilter);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public float getDefaultHeight();
-    method public float getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vector.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(float p);
-    method public void setDefaultWidth(float p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vector.GroupComponent root;
-    property public final int size;
-  }
-
   public final class VectorComposeKt {
     method @androidx.compose.Composable public static void Group(androidx.ui.graphics.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, java.util.List<? extends androidx.ui.graphics.vector.PathNode> clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.VectorScope,kotlin.Unit> children);
     method @androidx.compose.Composable public static void Path(androidx.ui.graphics.vector.VectorScope, java.util.List<? extends androidx.ui.graphics.vector.PathNode> pathData, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
-    method public static androidx.compose.Composition composeVector(androidx.ui.graphics.vector.VectorComponent container, androidx.compose.Recomposer recomposer, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function3<? super androidx.ui.graphics.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> composable);
-  }
-
-  public final class VectorComposer extends androidx.compose.Composer<androidx.ui.graphics.vector.VNode> {
-    ctor public VectorComposer(androidx.ui.graphics.vector.VNode root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
-    method public inline <T extends androidx.ui.graphics.vector.VNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.VNode>,kotlin.Unit> update);
-    method public inline void emit(Object key, kotlin.jvm.functions.Function0<androidx.ui.graphics.vector.GroupComponent> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.GroupComponent>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.graphics.vector.VNode getRoot();
   }
 
   public final class VectorGroup extends androidx.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2079,7 +1975,6 @@
     method public static androidx.ui.graphics.BlendMode getDefaultTintBlendMode();
     method public static long getDefaultTintColor();
     method public static java.util.List<androidx.ui.graphics.vector.PathNode> getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
     field public static final String DefaultGroupName = "";
     field public static final String DefaultPathName = "";
     field public static final float DefaultPivotX = 0.0f;
@@ -2134,8 +2029,6 @@
   }
 
   public final class VectorScope {
-    ctor public VectorScope(androidx.ui.graphics.vector.VectorComposer composer);
-    method public androidx.ui.graphics.vector.VectorComposer getComposer();
   }
 
 }
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev14.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev14.txt
index 9ef0e0f..6042744 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev14.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev14.txt
@@ -1908,86 +1908,9 @@
 
 package androidx.ui.graphics.vector {
 
-  public final class GroupComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public String component1();
-    method public androidx.ui.graphics.vector.GroupComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getClipPathData();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vector.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> clipPathData;
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class PathComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public PathComponent(String name);
-    method public String component1();
-    method public androidx.ui.graphics.vector.PathComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public androidx.ui.graphics.Brush? getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getPathData();
-    method public androidx.ui.graphics.Brush? getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.graphics.StrokeCap getStrokeLineCap();
-    method public androidx.ui.graphics.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.Brush? value);
-    method public void setFillAlpha(float value);
-    method public void setPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setStroke(androidx.ui.graphics.Brush? value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.graphics.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.graphics.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.Brush? fill;
-    property public final float fillAlpha;
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> pathData;
-    property public final androidx.ui.graphics.Brush? stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.graphics.StrokeCap strokeLineCap;
-    property public final androidx.ui.graphics.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
   public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.graphics.Canvas canvas);
-    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getInvalidateListener();
+    method public abstract void draw(androidx.ui.graphics.drawscope.DrawScope);
     method public final void invalidate();
-    method public void setInvalidateListener(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
   }
 
   public final class VectorAsset {
@@ -2023,36 +1946,9 @@
     method public static androidx.ui.graphics.vector.VectorAssetBuilder path(androidx.ui.graphics.vector.VectorAssetBuilder, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
   }
 
-  public final class VectorComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public VectorComponent(float viewportWidth, float viewportHeight, float defaultWidth, float defaultHeight, String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas, float alpha, androidx.ui.graphics.ColorFilter? colorFilter);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public float getDefaultHeight();
-    method public float getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vector.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(float p);
-    method public void setDefaultWidth(float p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vector.GroupComponent root;
-    property public final int size;
-  }
-
   public final class VectorComposeKt {
     method @androidx.compose.Composable public static void Group(androidx.ui.graphics.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, java.util.List<? extends androidx.ui.graphics.vector.PathNode> clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.VectorScope,kotlin.Unit> children);
     method @androidx.compose.Composable public static void Path(androidx.ui.graphics.vector.VectorScope, java.util.List<? extends androidx.ui.graphics.vector.PathNode> pathData, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
-    method public static androidx.compose.Composition composeVector(androidx.ui.graphics.vector.VectorComponent container, androidx.compose.Recomposer recomposer, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function3<? super androidx.ui.graphics.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> composable);
-  }
-
-  public final class VectorComposer extends androidx.compose.Composer<androidx.ui.graphics.vector.VNode> {
-    ctor public VectorComposer(androidx.ui.graphics.vector.VNode root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
-    method public inline <T extends androidx.ui.graphics.vector.VNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.VNode>,kotlin.Unit> update);
-    method public inline void emit(Object key, kotlin.jvm.functions.Function0<androidx.ui.graphics.vector.GroupComponent> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.GroupComponent>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.graphics.vector.VNode getRoot();
   }
 
   public final class VectorGroup extends androidx.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2081,7 +1977,6 @@
     method public static androidx.ui.graphics.BlendMode getDefaultTintBlendMode();
     method public static long getDefaultTintColor();
     method public static java.util.List<androidx.ui.graphics.vector.PathNode> getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
     field public static final String DefaultGroupName = "";
     field public static final String DefaultPathName = "";
     field public static final float DefaultPivotX = 0.0f;
@@ -2136,8 +2031,6 @@
   }
 
   public final class VectorScope {
-    ctor public VectorScope(androidx.ui.graphics.vector.VectorComposer composer);
-    method public androidx.ui.graphics.vector.VectorComposer getComposer();
   }
 
 }
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index 9ef0e0f..6042744 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -1908,86 +1908,9 @@
 
 package androidx.ui.graphics.vector {
 
-  public final class GroupComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public String component1();
-    method public androidx.ui.graphics.vector.GroupComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getClipPathData();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vector.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> clipPathData;
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class PathComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public PathComponent(String name);
-    method public String component1();
-    method public androidx.ui.graphics.vector.PathComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public androidx.ui.graphics.Brush? getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getPathData();
-    method public androidx.ui.graphics.Brush? getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.graphics.StrokeCap getStrokeLineCap();
-    method public androidx.ui.graphics.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.Brush? value);
-    method public void setFillAlpha(float value);
-    method public void setPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setStroke(androidx.ui.graphics.Brush? value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.graphics.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.graphics.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.Brush? fill;
-    property public final float fillAlpha;
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> pathData;
-    property public final androidx.ui.graphics.Brush? stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.graphics.StrokeCap strokeLineCap;
-    property public final androidx.ui.graphics.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
   public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.graphics.Canvas canvas);
-    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getInvalidateListener();
+    method public abstract void draw(androidx.ui.graphics.drawscope.DrawScope);
     method public final void invalidate();
-    method public void setInvalidateListener(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
   }
 
   public final class VectorAsset {
@@ -2023,36 +1946,9 @@
     method public static androidx.ui.graphics.vector.VectorAssetBuilder path(androidx.ui.graphics.vector.VectorAssetBuilder, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
   }
 
-  public final class VectorComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public VectorComponent(float viewportWidth, float viewportHeight, float defaultWidth, float defaultHeight, String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas, float alpha, androidx.ui.graphics.ColorFilter? colorFilter);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public float getDefaultHeight();
-    method public float getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vector.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(float p);
-    method public void setDefaultWidth(float p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vector.GroupComponent root;
-    property public final int size;
-  }
-
   public final class VectorComposeKt {
     method @androidx.compose.Composable public static void Group(androidx.ui.graphics.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, java.util.List<? extends androidx.ui.graphics.vector.PathNode> clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.VectorScope,kotlin.Unit> children);
     method @androidx.compose.Composable public static void Path(androidx.ui.graphics.vector.VectorScope, java.util.List<? extends androidx.ui.graphics.vector.PathNode> pathData, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
-    method public static androidx.compose.Composition composeVector(androidx.ui.graphics.vector.VectorComponent container, androidx.compose.Recomposer recomposer, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function3<? super androidx.ui.graphics.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> composable);
-  }
-
-  public final class VectorComposer extends androidx.compose.Composer<androidx.ui.graphics.vector.VNode> {
-    ctor public VectorComposer(androidx.ui.graphics.vector.VNode root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
-    method public inline <T extends androidx.ui.graphics.vector.VNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.VNode>,kotlin.Unit> update);
-    method public inline void emit(Object key, kotlin.jvm.functions.Function0<androidx.ui.graphics.vector.GroupComponent> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.GroupComponent>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.graphics.vector.VNode getRoot();
   }
 
   public final class VectorGroup extends androidx.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2081,7 +1977,6 @@
     method public static androidx.ui.graphics.BlendMode getDefaultTintBlendMode();
     method public static long getDefaultTintColor();
     method public static java.util.List<androidx.ui.graphics.vector.PathNode> getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
     field public static final String DefaultGroupName = "";
     field public static final String DefaultPathName = "";
     field public static final float DefaultPivotX = 0.0f;
@@ -2136,8 +2031,6 @@
   }
 
   public final class VectorScope {
-    ctor public VectorScope(androidx.ui.graphics.vector.VectorComposer composer);
-    method public androidx.ui.graphics.vector.VectorComposer getComposer();
   }
 
 }
diff --git a/ui/ui-core/api/restricted_0.1.0-dev14.txt b/ui/ui-core/api/restricted_0.1.0-dev14.txt
index bf08b01..db32100 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev14.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev14.txt
@@ -1958,86 +1958,9 @@
 
 package androidx.ui.graphics.vector {
 
-  public final class GroupComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public String component1();
-    method public androidx.ui.graphics.vector.GroupComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getClipPathData();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vector.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> clipPathData;
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class PathComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public PathComponent(String name);
-    method public String component1();
-    method public androidx.ui.graphics.vector.PathComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public androidx.ui.graphics.Brush? getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getPathData();
-    method public androidx.ui.graphics.Brush? getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.graphics.StrokeCap getStrokeLineCap();
-    method public androidx.ui.graphics.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.Brush? value);
-    method public void setFillAlpha(float value);
-    method public void setPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setStroke(androidx.ui.graphics.Brush? value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.graphics.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.graphics.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.Brush? fill;
-    property public final float fillAlpha;
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> pathData;
-    property public final androidx.ui.graphics.Brush? stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.graphics.StrokeCap strokeLineCap;
-    property public final androidx.ui.graphics.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
   public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.graphics.Canvas canvas);
-    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getInvalidateListener();
+    method public abstract void draw(androidx.ui.graphics.drawscope.DrawScope);
     method public final void invalidate();
-    method public void setInvalidateListener(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
   }
 
   public final class VectorAsset {
@@ -2073,36 +1996,9 @@
     method public static androidx.ui.graphics.vector.VectorAssetBuilder path(androidx.ui.graphics.vector.VectorAssetBuilder, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
   }
 
-  public final class VectorComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public VectorComponent(float viewportWidth, float viewportHeight, float defaultWidth, float defaultHeight, String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas, float alpha, androidx.ui.graphics.ColorFilter? colorFilter);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public float getDefaultHeight();
-    method public float getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vector.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(float p);
-    method public void setDefaultWidth(float p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vector.GroupComponent root;
-    property public final int size;
-  }
-
   public final class VectorComposeKt {
     method @androidx.compose.Composable public static void Group(androidx.ui.graphics.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, java.util.List<? extends androidx.ui.graphics.vector.PathNode> clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.VectorScope,kotlin.Unit> children);
     method @androidx.compose.Composable public static void Path(androidx.ui.graphics.vector.VectorScope, java.util.List<? extends androidx.ui.graphics.vector.PathNode> pathData, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
-    method public static androidx.compose.Composition composeVector(androidx.ui.graphics.vector.VectorComponent container, androidx.compose.Recomposer recomposer, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function3<? super androidx.ui.graphics.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> composable);
-  }
-
-  public final class VectorComposer extends androidx.compose.Composer<androidx.ui.graphics.vector.VNode> {
-    ctor public VectorComposer(androidx.ui.graphics.vector.VNode root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
-    method public inline <T extends androidx.ui.graphics.vector.VNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.VNode>,kotlin.Unit> update);
-    method public inline void emit(Object key, kotlin.jvm.functions.Function0<androidx.ui.graphics.vector.GroupComponent> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.GroupComponent>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.graphics.vector.VNode getRoot();
   }
 
   public final class VectorGroup extends androidx.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2131,7 +2027,6 @@
     method public static androidx.ui.graphics.BlendMode getDefaultTintBlendMode();
     method public static long getDefaultTintColor();
     method public static java.util.List<androidx.ui.graphics.vector.PathNode> getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
     field public static final String DefaultGroupName = "";
     field public static final String DefaultPathName = "";
     field public static final float DefaultPivotX = 0.0f;
@@ -2186,8 +2081,6 @@
   }
 
   public final class VectorScope {
-    ctor public VectorScope(androidx.ui.graphics.vector.VectorComposer composer);
-    method public androidx.ui.graphics.vector.VectorComposer getComposer();
   }
 
 }
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index bf08b01..db32100 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -1958,86 +1958,9 @@
 
 package androidx.ui.graphics.vector {
 
-  public final class GroupComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public GroupComponent(String name);
-    ctor public GroupComponent();
-    method public String component1();
-    method public androidx.ui.graphics.vector.GroupComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getClipPathData();
-    method public String getName();
-    method public float getPivotX();
-    method public float getPivotY();
-    method public float getRotation();
-    method public float getScaleX();
-    method public float getScaleY();
-    method public int getSize();
-    method public float getTranslationX();
-    method public float getTranslationY();
-    method public void insertAt(int index, androidx.ui.graphics.vector.VNode instance);
-    method public void move(int from, int to, int count);
-    method public void remove(int index, int count);
-    method public void setClipPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setPivotX(float value);
-    method public void setPivotY(float value);
-    method public void setRotation(float value);
-    method public void setScaleX(float value);
-    method public void setScaleY(float value);
-    method public void setTranslationX(float value);
-    method public void setTranslationY(float value);
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> clipPathData;
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
-    property public final float pivotX;
-    property public final float pivotY;
-    property public final float rotation;
-    property public final float scaleX;
-    property public final float scaleY;
-    property public final int size;
-    property public final float translationX;
-    property public final float translationY;
-  }
-
-  public final class PathComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public PathComponent(String name);
-    method public String component1();
-    method public androidx.ui.graphics.vector.PathComponent copy(String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public androidx.ui.graphics.Brush? getFill();
-    method public float getFillAlpha();
-    method public String getName();
-    method public java.util.List<androidx.ui.graphics.vector.PathNode> getPathData();
-    method public androidx.ui.graphics.Brush? getStroke();
-    method public float getStrokeAlpha();
-    method public androidx.ui.graphics.StrokeCap getStrokeLineCap();
-    method public androidx.ui.graphics.StrokeJoin getStrokeLineJoin();
-    method public float getStrokeLineMiter();
-    method public float getStrokeLineWidth();
-    method public void setFill(androidx.ui.graphics.Brush? value);
-    method public void setFillAlpha(float value);
-    method public void setPathData(java.util.List<? extends androidx.ui.graphics.vector.PathNode> value);
-    method public void setStroke(androidx.ui.graphics.Brush? value);
-    method public void setStrokeAlpha(float value);
-    method public void setStrokeLineCap(androidx.ui.graphics.StrokeCap value);
-    method public void setStrokeLineJoin(androidx.ui.graphics.StrokeJoin value);
-    method public void setStrokeLineMiter(float value);
-    method public void setStrokeLineWidth(float value);
-    property public final androidx.ui.graphics.Brush? fill;
-    property public final float fillAlpha;
-    property public final java.util.List<androidx.ui.graphics.vector.PathNode> pathData;
-    property public final androidx.ui.graphics.Brush? stroke;
-    property public final float strokeAlpha;
-    property public final androidx.ui.graphics.StrokeCap strokeLineCap;
-    property public final androidx.ui.graphics.StrokeJoin strokeLineJoin;
-    property public final float strokeLineMiter;
-    property public final float strokeLineWidth;
-  }
-
   public abstract sealed class VNode {
-    method public abstract void draw(androidx.ui.graphics.Canvas canvas);
-    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getInvalidateListener();
+    method public abstract void draw(androidx.ui.graphics.drawscope.DrawScope);
     method public final void invalidate();
-    method public void setInvalidateListener(kotlin.jvm.functions.Function0<kotlin.Unit>? p);
-    property public kotlin.jvm.functions.Function0<kotlin.Unit>? invalidateListener;
   }
 
   public final class VectorAsset {
@@ -2073,36 +1996,9 @@
     method public static androidx.ui.graphics.vector.VectorAssetBuilder path(androidx.ui.graphics.vector.VectorAssetBuilder, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
   }
 
-  public final class VectorComponent extends androidx.ui.graphics.vector.VNode {
-    ctor public VectorComponent(float viewportWidth, float viewportHeight, float defaultWidth, float defaultHeight, String name);
-    method public void draw(androidx.ui.graphics.Canvas canvas, float alpha, androidx.ui.graphics.ColorFilter? colorFilter);
-    method public void draw(androidx.ui.graphics.Canvas canvas);
-    method public float getDefaultHeight();
-    method public float getDefaultWidth();
-    method public String getName();
-    method public androidx.ui.graphics.vector.GroupComponent getRoot();
-    method public int getSize();
-    method public float getViewportHeight();
-    method public float getViewportWidth();
-    method public void setDefaultHeight(float p);
-    method public void setDefaultWidth(float p);
-    method public void setViewportHeight(float p);
-    method public void setViewportWidth(float p);
-    property public final androidx.ui.graphics.vector.GroupComponent root;
-    property public final int size;
-  }
-
   public final class VectorComposeKt {
     method @androidx.compose.Composable public static void Group(androidx.ui.graphics.vector.VectorScope, String name = "", float rotation = 0.0f, float pivotX = 0.0f, float pivotY = 0.0f, float scaleX = 1.0f, float scaleY = 1.0f, float translationX = 0.0f, float translationY = 0.0f, java.util.List<? extends androidx.ui.graphics.vector.PathNode> clipPathData = EmptyPath, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.vector.VectorScope,kotlin.Unit> children);
     method @androidx.compose.Composable public static void Path(androidx.ui.graphics.vector.VectorScope, java.util.List<? extends androidx.ui.graphics.vector.PathNode> pathData, String name = "", androidx.ui.graphics.Brush? fill = null, float fillAlpha = 1.0f, androidx.ui.graphics.Brush? stroke = null, float strokeAlpha = 1.0f, float strokeLineWidth = 0.0f, androidx.ui.graphics.StrokeCap strokeLineCap = DefaultStrokeLineCap, androidx.ui.graphics.StrokeJoin strokeLineJoin = DefaultStrokeLineJoin, float strokeLineMiter = 4.0f);
-    method public static androidx.compose.Composition composeVector(androidx.ui.graphics.vector.VectorComponent container, androidx.compose.Recomposer recomposer, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function3<? super androidx.ui.graphics.vector.VectorScope,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> composable);
-  }
-
-  public final class VectorComposer extends androidx.compose.Composer<androidx.ui.graphics.vector.VNode> {
-    ctor public VectorComposer(androidx.ui.graphics.vector.VNode root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
-    method public inline <T extends androidx.ui.graphics.vector.VNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.VNode>,kotlin.Unit> update);
-    method public inline void emit(Object key, kotlin.jvm.functions.Function0<androidx.ui.graphics.vector.GroupComponent> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<androidx.ui.graphics.vector.VNode,androidx.ui.graphics.vector.GroupComponent>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
-    method public androidx.ui.graphics.vector.VNode getRoot();
   }
 
   public final class VectorGroup extends androidx.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2131,7 +2027,6 @@
     method public static androidx.ui.graphics.BlendMode getDefaultTintBlendMode();
     method public static long getDefaultTintColor();
     method public static java.util.List<androidx.ui.graphics.vector.PathNode> getEmptyPath();
-    field public static final float DefaultAlpha = 1.0f;
     field public static final String DefaultGroupName = "";
     field public static final String DefaultPathName = "";
     field public static final float DefaultPivotX = 0.0f;
@@ -2186,8 +2081,6 @@
   }
 
   public final class VectorScope {
-    ctor public VectorScope(androidx.ui.graphics.vector.VectorComposer composer);
-    method public androidx.ui.graphics.vector.VectorComposer getComposer();
   }
 
 }
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/DrawCache.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/DrawCache.kt
new file mode 100644
index 0000000..6640b09
--- /dev/null
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/DrawCache.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2020 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.
+ */
+
+package androidx.ui.graphics.vector
+
+import androidx.ui.core.LayoutDirection
+import androidx.ui.geometry.Offset
+import androidx.ui.geometry.Size
+import androidx.ui.graphics.BlendMode
+import androidx.ui.graphics.Canvas
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.ColorFilter
+import androidx.ui.graphics.ImageAsset
+import androidx.ui.graphics.drawscope.DrawScope
+import androidx.ui.unit.Density
+import androidx.ui.unit.IntSize
+import androidx.ui.unit.toSize
+
+/**
+ * Creates a drawing environment that directs its drawing commands to an [ImageAsset]
+ * which can be drawn directly in another [DrawScope] instance. This is useful to cache
+ * complicated drawing commands across frames especially if the content has not changed.
+ * Additionally some drawing operations such as rendering paths are done purely in
+ * software so it is beneficial to cache the result and render the contents
+ * directly through a texture as done by [DrawScope.drawImage]
+ */
+internal class DrawCache {
+
+    @PublishedApi internal lateinit var cachedImage: ImageAsset
+    private lateinit var cachedCanvas: Canvas
+    private lateinit var scopeDensity: Density
+    private lateinit var layoutDirection: LayoutDirection
+
+    private val cacheScope = CacheDrawScope()
+
+    /**
+     * Draw the contents of the lambda with receiver scope into an [ImageAsset] with the provided
+     * size. If the same size is provided across calls, the same [ImageAsset] instance is
+     * re-used and the contents are cleared out before drawing content in it again
+     */
+    fun drawCachedImage(
+        size: IntSize,
+        density: Density,
+        layoutDirection: LayoutDirection,
+        block: DrawScope.() -> Unit
+    ) {
+        this.scopeDensity = density
+        this.layoutDirection = layoutDirection
+        val isInitialized = ::cachedImage.isInitialized
+        if (!isInitialized ||
+            size.width > cachedImage.width ||
+            size.height > cachedImage.height
+        ) {
+            cachedImage = ImageAsset(size.width, size.height)
+            cachedCanvas = Canvas(cachedImage)
+        }
+        cacheScope.drawInto(cachedCanvas, size.toSize()) {
+            cacheScope.clear()
+            block()
+        }
+        cachedImage.prepareToDraw()
+    }
+
+    /**
+     * Draw the cached content into the provided [DrawScope] instance
+     */
+    fun drawInto(
+        target: DrawScope,
+        alpha: Float = 1.0f,
+        colorFilter: ColorFilter? = null
+    ) {
+        check(::cachedImage.isInitialized) {
+            "drawCachedImage must be invoked first before attempting to draw the result " +
+                    "into another destination"
+        }
+        target.drawImage(cachedImage, Offset.Zero, alpha = alpha, colorFilter = colorFilter)
+    }
+
+    /**
+     * Inner class to avoid exposing DrawScope drawing commands on the DrawCache directly
+     */
+    private inner class CacheDrawScope : DrawScope() {
+
+        fun drawInto(
+            canvas: Canvas,
+            size: Size,
+            block: DrawScope.() -> Unit
+        ) = draw(canvas, size, block)
+
+        override val layoutDirection: LayoutDirection
+            get() = this@DrawCache.layoutDirection
+
+        override val density: Float
+            get() = this@DrawCache.scopeDensity.density
+
+        override val fontScale: Float
+            get() = this@DrawCache.scopeDensity.fontScale
+
+        /**
+         * Helper method to clear contents of the draw environment from the given bounds of the
+         * DrawScope
+         */
+        fun clear() {
+            drawRect(color = Color.Black, blendMode = BlendMode.clear)
+        }
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/Vector.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/Vector.kt
index 98b35131..1553762 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/Vector.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/Vector.kt
@@ -16,20 +16,18 @@
 
 package androidx.ui.graphics.vector
 
-import androidx.ui.geometry.Offset
 import androidx.ui.graphics.BlendMode
 import androidx.ui.graphics.Brush
-import androidx.ui.graphics.Canvas
 import androidx.ui.graphics.Color
 import androidx.ui.graphics.ColorFilter
-import androidx.ui.graphics.ImageAsset
-import androidx.ui.graphics.Paint
-import androidx.ui.graphics.PaintingStyle
 import androidx.ui.graphics.Path
 import androidx.ui.graphics.StrokeCap
 import androidx.ui.graphics.StrokeJoin
+import androidx.ui.graphics.drawscope.DrawScope
+import androidx.ui.graphics.drawscope.Stroke
+import androidx.ui.graphics.drawscope.withTransform
 import androidx.ui.graphics.vectormath.Matrix4
-import androidx.ui.graphics.withSave
+import androidx.ui.unit.IntSize
 import androidx.ui.util.fastForEach
 import androidx.ui.util.toRadians
 import kotlin.math.ceil
@@ -45,12 +43,6 @@
 
 val EmptyPath = emptyList<PathNode>()
 
-/**
- * paint used to draw the cached vector graphic to the provided canvas
- */
-// TODO (njawad) Can we update the Compose Canvas API to make this paint optional?
-internal val EmptyPaint = Paint()
-
 inline fun PathData(block: PathBuilder.() -> Unit): List<PathNode> =
     with(PathBuilder()) {
         block()
@@ -58,7 +50,6 @@
     }
 
 const val DefaultPathName = ""
-const val DefaultAlpha = 1.0f
 const val DefaultStrokeLineWidth = 0.0f
 const val DefaultStrokeLineMiter = 4.0f
 
@@ -80,18 +71,16 @@
      * Callback invoked whenever the node in the vector tree is modified in a way that would
      * change the output of the Vector
      */
-    // TODO (b/144849567) don't make this publicly accessible after the vector graphics modules
-    //  are merged
-    open var invalidateListener: (() -> Unit)? = null
+    internal open var invalidateListener: (() -> Unit)? = null
 
     fun invalidate() {
         invalidateListener?.invoke()
     }
 
-    abstract fun draw(canvas: Canvas)
+    abstract fun DrawScope.draw()
 }
 
-class VectorComponent(
+internal class VectorComponent(
     var viewportWidth: Float,
     var viewportHeight: Float,
     var defaultWidth: Float,
@@ -111,36 +100,33 @@
 
     private var isDirty: Boolean = true
 
-    private var vectorPaint: Paint? = null
-
-    /**
-     * Cached Image of the Vector Graphic to be re-used across draw calls
-     * if the Vector graphic is not dirty
-     */
-    // TODO (njawad) add invalidation logic to re-draw into the offscreen Image
-    private var cachedImage: ImageAsset? = null
+    private val cacheDrawScope = DrawCache()
 
     val size: Int
         get() = root.size
 
-    fun draw(canvas: Canvas, alpha: Float, colorFilter: ColorFilter?) {
-        var targetImage = cachedImage
-        if (targetImage == null) {
-            targetImage = ImageAsset(
-                ceil(defaultWidth).toInt(),
-                ceil(defaultHeight).toInt()
-            )
-            cachedImage = targetImage
-        }
-        if (isDirty) {
-            root.draw(Canvas(targetImage))
-            isDirty = false
-        }
-        canvas.drawImage(targetImage, Offset.Zero, obtainVectorPaint(alpha, colorFilter))
+    /**
+     * Cached lambda used to avoid allocating the lambda on each draw invocation
+     */
+    private val drawVectorBlock: DrawScope.() -> Unit = {
+        with (root) { draw() }
     }
 
-    override fun draw(canvas: Canvas) {
-        draw(canvas, DefaultAlpha, null)
+    fun DrawScope.draw(alpha: Float, colorFilter: ColorFilter?) {
+        if (isDirty) {
+            cacheDrawScope.drawCachedImage(
+                IntSize(ceil(defaultWidth).toInt(), ceil(defaultHeight).toInt()),
+                this@draw,
+                layoutDirection,
+                drawVectorBlock
+            )
+            isDirty = false
+        }
+        cacheDrawScope.drawInto(this, alpha, colorFilter)
+    }
+
+    override fun DrawScope.draw() {
+        draw(1.0f, null)
     }
 
     override fun toString(): String {
@@ -153,44 +139,22 @@
             append("\tviewportHeight: ").append(viewportHeight).append("\n")
         }
     }
-
-    private fun obtainVectorPaint(alpha: Float, colorFilter: ColorFilter?): Paint {
-        return if (colorFilter == null && alpha == DefaultAlpha) {
-            EmptyPaint
-        } else {
-            val targetPaint = vectorPaint ?: Paint().also { vectorPaint = it }
-            val currentColorFilter = targetPaint.colorFilter
-            if (currentColorFilter != colorFilter) {
-                targetPaint.colorFilter = colorFilter
-            }
-            if (targetPaint.alpha != alpha) {
-                targetPaint.alpha = alpha
-            }
-            targetPaint
-        }
-    }
 }
 
-data class PathComponent(val name: String) : VNode() {
+internal data class PathComponent(val name: String) : VNode() {
 
     var fill: Brush? = null
         set(value) {
             if (field != value) {
                 field = value
-                updateFillPaint {
-                    field?.applyTo(this, fillAlpha)
-                }
                 invalidate()
             }
         }
 
-    var fillAlpha: Float = DefaultAlpha
+    var fillAlpha: Float = 1.0f
         set(value) {
             if (field != value) {
                 field = value
-                updateFillPaint {
-                    alpha = field
-                }
                 invalidate()
             }
         }
@@ -204,13 +168,10 @@
             }
         }
 
-    var strokeAlpha: Float = DefaultAlpha
+    var strokeAlpha: Float = 1.0f
         set(value) {
             if (field != value) {
                 field = value
-                updateStrokePaint {
-                    alpha = field
-                }
                 invalidate()
             }
         }
@@ -219,9 +180,6 @@
         set(value) {
             if (field != value) {
                 field = value
-                updateStrokePaint {
-                    strokeWidth = field
-                }
                 invalidate()
             }
         }
@@ -230,9 +188,6 @@
         set(value) {
             if (field != value) {
                 field = value
-                updateStrokePaint {
-                    field?.applyTo(this, strokeAlpha)
-                }
                 invalidate()
             }
         }
@@ -241,9 +196,7 @@
         set(value) {
             if (field != value) {
                 field = value
-                updateStrokePaint {
-                    strokeCap = field
-                }
+                isStrokeDirty = true
                 invalidate()
             }
         }
@@ -252,9 +205,7 @@
         set(value) {
             if (field != value) {
                 field = value
-                updateStrokePaint {
-                    strokeJoin = field
-                }
+                isStrokeDirty = true
                 invalidate()
             }
         }
@@ -263,84 +214,42 @@
         set(value) {
             if (field != value) {
                 field = value
-                updateStrokePaint {
-                    strokeMiterLimit = field
-                }
+                isStrokeDirty = true
                 invalidate()
             }
         }
 
     private var isPathDirty = true
+    private var isStrokeDirty = true
+
+    private var strokeStyle: Stroke? = null
 
     private val path = Path()
 
-    private var fillPaint: Paint? = null
-    private var strokePaint: Paint? = null
-
     private val parser = PathParser()
 
-    private inline fun updateStrokePaint(strokePaintUpdater: Paint.() -> Unit) {
-        if (strokePaint == null) {
-            strokePaint = createStrokePaint()
-        } else {
-            strokePaint?.strokePaintUpdater()
-        }
-    }
-
-    private fun createStrokePaint(): Paint = Paint().apply {
-        isAntiAlias = true
-        style = PaintingStyle.stroke
-        strokeWidth = strokeLineWidth
-        strokeCap = strokeLineCap
-        strokeJoin = strokeLineJoin
-        strokeMiterLimit = strokeLineMiter
-        stroke?.applyTo(this, strokeAlpha)
-    }
-
-    private fun updateFillPaint(fillPaintUpdater: Paint.() -> Unit) {
-        if (fillPaint == null) {
-            fillPaint = createFillPaint()
-        } else {
-            fillPaint?.fillPaintUpdater()
-        }
-    }
-
-    private fun createFillPaint(): Paint = Paint().apply {
-        isAntiAlias = true
-        style = PaintingStyle.fill
-        fill?.applyTo(this, fillAlpha)
-    }
-
     private fun updatePath() {
         parser.clear()
         path.reset()
         parser.addPathNodes(pathData).toPath(path)
     }
 
-    override fun draw(canvas: Canvas) {
+    override fun DrawScope.draw() {
         if (isPathDirty) {
             updatePath()
             isPathDirty = false
         }
 
-        val fillBrush = fill
-        if (fillBrush != null) {
-            var targetFillPaint = fillPaint
-            if (targetFillPaint == null) {
-                targetFillPaint = createFillPaint()
-                fillPaint = targetFillPaint
+        fill?.let { drawPath(path, brush = it, alpha = fillAlpha) }
+        stroke?.let {
+            var targetStroke = strokeStyle
+            if (isStrokeDirty || targetStroke == null) {
+                targetStroke =
+                    Stroke(strokeLineWidth, strokeLineMiter, strokeLineCap, strokeLineJoin)
+                strokeStyle = targetStroke
+                isStrokeDirty = false
             }
-            canvas.drawPath(path, targetFillPaint)
-        }
-
-        val strokeBrush = stroke
-        if (strokeBrush != null) {
-            var targetStrokePaint = strokePaint
-            if (targetStrokePaint == null) {
-                targetStrokePaint = createStrokePaint()
-                strokePaint = targetStrokePaint
-            }
-            canvas.drawPath(path, targetStrokePaint)
+            drawPath(path, brush = it, alpha = strokeAlpha, style = targetStroke)
         }
     }
 
@@ -349,7 +258,7 @@
     }
 }
 
-data class GroupComponent(val name: String = DefaultGroupName) : VNode() {
+internal data class GroupComponent(val name: String = DefaultGroupName) : VNode() {
 
     private var groupMatrix: Matrix4? = null
 
@@ -523,7 +432,7 @@
         invalidate()
     }
 
-    override fun draw(canvas: Canvas) {
+    override fun DrawScope.draw() {
         if (isMatrixDirty) {
             updateMatrix()
             isMatrixDirty = false
@@ -534,20 +443,17 @@
             isClipPathDirty = false
         }
 
-        canvas.withSave {
+        withTransform({
             val targetClip = clipPath
             if (willClipPath && targetClip != null) {
-                canvas.clipPath(targetClip)
+                clipPath(targetClip)
             }
-
-            val matrix = groupMatrix
-            if (matrix != null) {
-                // TODO (njawad) add concat support to matrix
-                canvas.concat(matrix)
-            }
-
+            groupMatrix?.let { transform(it) }
+        }) {
             children.fastForEach { node ->
-                node.draw(canvas)
+                with(node) {
+                    this@draw.draw()
+                }
             }
         }
     }
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAsset.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAsset.kt
index 3217d18..cf07a79 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAsset.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAsset.kt
@@ -197,7 +197,7 @@
     /**
      * Opacity to fill the path
      */
-    val fillAlpha: Float = DefaultAlpha,
+    val fillAlpha: Float = 1.0f,
 
     /**
      * Specifies the color or gradient used to fill the stroke
@@ -207,7 +207,7 @@
     /**
      * Opacity to stroke the path
      */
-    val strokeAlpha: Float = DefaultAlpha,
+    val strokeAlpha: Float = 1.0f,
 
     /**
      * Width of the line to stroke the path
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAssetBuilder.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAssetBuilder.kt
index 0326062..a65f7ca 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAssetBuilder.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorAssetBuilder.kt
@@ -147,9 +147,9 @@
         pathData: List<PathNode>,
         name: String = DefaultPathName,
         fill: Brush? = null,
-        fillAlpha: Float = DefaultAlpha,
+        fillAlpha: Float = 1.0f,
         stroke: Brush? = null,
-        strokeAlpha: Float = DefaultAlpha,
+        strokeAlpha: Float = 1.0f,
         strokeLineWidth: Float = DefaultStrokeLineWidth,
         strokeLineCap: StrokeCap = DefaultStrokeLineCap,
         strokeLineJoin: StrokeJoin = DefaultStrokeLineJoin,
@@ -223,9 +223,9 @@
 fun VectorAssetBuilder.path(
     name: String = DefaultPathName,
     fill: Brush? = null,
-    fillAlpha: Float = DefaultAlpha,
+    fillAlpha: Float = 1.0f,
     stroke: Brush? = null,
-    strokeAlpha: Float = DefaultAlpha,
+    strokeAlpha: Float = 1.0f,
     strokeLineWidth: Float = DefaultStrokeLineWidth,
     strokeLineCap: StrokeCap = DefaultStrokeLineCap,
     strokeLineJoin: StrokeJoin = DefaultStrokeLineJoin,
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorCompose.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorCompose.kt
index ef05a8c..85db0b7 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorCompose.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorCompose.kt
@@ -66,9 +66,9 @@
     pathData: List<PathNode>,
     name: String = DefaultPathName,
     fill: Brush? = null,
-    fillAlpha: Float = DefaultAlpha,
+    fillAlpha: Float = 1.0f,
     stroke: Brush? = null,
-    strokeAlpha: Float = DefaultAlpha,
+    strokeAlpha: Float = 1.0f,
     strokeLineWidth: Float = DefaultStrokeLineWidth,
     strokeLineCap: StrokeCap = DefaultStrokeLineCap,
     strokeLineJoin: StrokeJoin = DefaultStrokeLineJoin,
@@ -88,10 +88,10 @@
     )
 }
 
-class VectorScope(val composer: VectorComposer)
+class VectorScope internal constructor (internal val composer: VectorComposer)
 
 @Suppress("NAME_SHADOWING")
-fun composeVector(
+internal fun composeVector(
     container: VectorComponent,
     recomposer: Recomposer,
     parent: CompositionReference? = null,
@@ -110,7 +110,7 @@
 }
 
 @OptIn(ComposeCompilerApi::class)
-class VectorComposer(
+internal class VectorComposer(
     val root: VNode,
     slotTable: SlotTable,
     recomposer: Recomposer
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorPainter.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorPainter.kt
index fe285c6..6973254 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorPainter.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/graphics/vector/VectorPainter.kt
@@ -20,14 +20,16 @@
 import androidx.compose.ExperimentalComposeApi
 import androidx.compose.compositionReference
 import androidx.compose.currentComposer
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
 import androidx.compose.onPreCommit
 import androidx.compose.remember
+import androidx.compose.setValue
 import androidx.ui.core.DensityAmbient
 import androidx.ui.geometry.Size
 import androidx.ui.graphics.ColorFilter
 import androidx.ui.graphics.painter.Painter
 import androidx.ui.graphics.drawscope.DrawScope
-import androidx.ui.graphics.drawscope.drawCanvas
 import androidx.ui.unit.Dp
 
 /**
@@ -66,8 +68,10 @@
     val vpWidth = if (viewportWidth.isNaN()) widthPx else viewportWidth
     val vpHeight = if (viewportHeight.isNaN()) heightPx else viewportHeight
 
-    return VectorPainter(
-        createVector(
+    return remember { VectorPainter() }.apply {
+        // This assignment is thread safe as the internal VectorComponent parameter is backed
+        // by a mutableState object
+        vector = createVector(
             name = name,
             defaultWidth = widthPx,
             defaultHeight = heightPx,
@@ -75,7 +79,7 @@
             viewportHeight = vpHeight,
             children = children
         )
-    )
+    }
 }
 
 /**
@@ -101,15 +105,18 @@
  * This can be represented by either a [VectorAsset] or a programmatic
  * composition of a vector
  */
-class VectorPainter internal constructor(private val vector: VectorComponent) : Painter() {
+class VectorPainter internal constructor() : Painter() {
 
-    private var currentAlpha: Float = DefaultAlpha
+    internal var vector by mutableStateOf<VectorComponent?>(null)
+
+    private var currentAlpha: Float = 1.0f
     private var currentColorFilter: ColorFilter? = null
 
-    override val intrinsicSize: Size = Size(vector.defaultWidth, vector.defaultHeight)
+    override val intrinsicSize: Size
+        get() = vector?.let { Size(it.defaultWidth, it.defaultHeight) } ?: Size.zero
 
     override fun DrawScope.onDraw() {
-        drawCanvas { canvas, _ -> vector.draw(canvas, currentAlpha, currentColorFilter) }
+        vector?.let { with (it) { draw(currentAlpha, currentColorFilter) } }
     }
 
     override fun applyAlpha(alpha: Float): Boolean {
diff --git a/ui/ui-graphics/api/0.1.0-dev14.txt b/ui/ui-graphics/api/0.1.0-dev14.txt
index 5685197..a6b5aa8 100644
--- a/ui/ui-graphics/api/0.1.0-dev14.txt
+++ b/ui/ui-graphics/api/0.1.0-dev14.txt
@@ -722,19 +722,6 @@
 
 package androidx.ui.graphics.drawscope {
 
-  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface CanvasTransform {
-    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public default androidx.ui.geometry.Offset getCenter();
-    method public androidx.ui.geometry.Size getSize();
-    method public void inset(float left, float top, float right, float bottom);
-    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
-    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
-    method public void translate(float left = 0.0f, float top = 0.0f);
-    property public default androidx.ui.geometry.Offset center;
-    property public abstract androidx.ui.geometry.Size size;
-  }
-
   @androidx.ui.graphics.drawscope.DrawScopeMarker public abstract class DrawScope implements androidx.ui.unit.Density {
     ctor public DrawScope();
     method public final void draw(androidx.ui.graphics.Canvas canvas, androidx.ui.geometry.Size size, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
@@ -781,7 +768,7 @@
     method public static inline androidx.ui.graphics.Canvas? rotateRad(androidx.ui.graphics.drawscope.DrawScope, float radians, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? scale(androidx.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? translate(androidx.ui.graphics.drawscope.DrawScope, float left = 0.0f, float top = 0.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
-    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.CanvasTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
   }
 
   @kotlin.DslMarker public @interface DrawScopeMarker {
@@ -790,9 +777,23 @@
   public abstract sealed class DrawStyle {
   }
 
+  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface DrawTransform {
+    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public default androidx.ui.geometry.Offset getCenter();
+    method public androidx.ui.geometry.Size getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
+    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
+    method public void transform(androidx.ui.graphics.vectormath.Matrix4 matrix);
+    method public void translate(float left = 0.0f, float top = 0.0f);
+    property public default androidx.ui.geometry.Offset center;
+    property public abstract androidx.ui.geometry.Size size;
+  }
+
   public final class DrawTransformKt {
-    method public static inline void inset(androidx.ui.graphics.drawscope.CanvasTransform, float dx = 0.0f, float dy = 0.0f);
-    method public static inline void rotateRad(androidx.ui.graphics.drawscope.CanvasTransform, float radians, float pivotX = center.x, float pivotY = center.y);
+    method public static inline void inset(androidx.ui.graphics.drawscope.DrawTransform, float dx = 0.0f, float dy = 0.0f);
+    method public static inline void rotateRad(androidx.ui.graphics.drawscope.DrawTransform, float radians, float pivotX = center.x, float pivotY = center.y);
   }
 
   public final class Fill extends androidx.ui.graphics.drawscope.DrawStyle {
diff --git a/ui/ui-graphics/api/current.txt b/ui/ui-graphics/api/current.txt
index 5685197..a6b5aa8 100644
--- a/ui/ui-graphics/api/current.txt
+++ b/ui/ui-graphics/api/current.txt
@@ -722,19 +722,6 @@
 
 package androidx.ui.graphics.drawscope {
 
-  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface CanvasTransform {
-    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public default androidx.ui.geometry.Offset getCenter();
-    method public androidx.ui.geometry.Size getSize();
-    method public void inset(float left, float top, float right, float bottom);
-    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
-    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
-    method public void translate(float left = 0.0f, float top = 0.0f);
-    property public default androidx.ui.geometry.Offset center;
-    property public abstract androidx.ui.geometry.Size size;
-  }
-
   @androidx.ui.graphics.drawscope.DrawScopeMarker public abstract class DrawScope implements androidx.ui.unit.Density {
     ctor public DrawScope();
     method public final void draw(androidx.ui.graphics.Canvas canvas, androidx.ui.geometry.Size size, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
@@ -781,7 +768,7 @@
     method public static inline androidx.ui.graphics.Canvas? rotateRad(androidx.ui.graphics.drawscope.DrawScope, float radians, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? scale(androidx.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? translate(androidx.ui.graphics.drawscope.DrawScope, float left = 0.0f, float top = 0.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
-    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.CanvasTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
   }
 
   @kotlin.DslMarker public @interface DrawScopeMarker {
@@ -790,9 +777,23 @@
   public abstract sealed class DrawStyle {
   }
 
+  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface DrawTransform {
+    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public default androidx.ui.geometry.Offset getCenter();
+    method public androidx.ui.geometry.Size getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
+    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
+    method public void transform(androidx.ui.graphics.vectormath.Matrix4 matrix);
+    method public void translate(float left = 0.0f, float top = 0.0f);
+    property public default androidx.ui.geometry.Offset center;
+    property public abstract androidx.ui.geometry.Size size;
+  }
+
   public final class DrawTransformKt {
-    method public static inline void inset(androidx.ui.graphics.drawscope.CanvasTransform, float dx = 0.0f, float dy = 0.0f);
-    method public static inline void rotateRad(androidx.ui.graphics.drawscope.CanvasTransform, float radians, float pivotX = center.x, float pivotY = center.y);
+    method public static inline void inset(androidx.ui.graphics.drawscope.DrawTransform, float dx = 0.0f, float dy = 0.0f);
+    method public static inline void rotateRad(androidx.ui.graphics.drawscope.DrawTransform, float radians, float pivotX = center.x, float pivotY = center.y);
   }
 
   public final class Fill extends androidx.ui.graphics.drawscope.DrawStyle {
diff --git a/ui/ui-graphics/api/public_plus_experimental_0.1.0-dev14.txt b/ui/ui-graphics/api/public_plus_experimental_0.1.0-dev14.txt
index 5685197..a6b5aa8 100644
--- a/ui/ui-graphics/api/public_plus_experimental_0.1.0-dev14.txt
+++ b/ui/ui-graphics/api/public_plus_experimental_0.1.0-dev14.txt
@@ -722,19 +722,6 @@
 
 package androidx.ui.graphics.drawscope {
 
-  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface CanvasTransform {
-    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public default androidx.ui.geometry.Offset getCenter();
-    method public androidx.ui.geometry.Size getSize();
-    method public void inset(float left, float top, float right, float bottom);
-    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
-    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
-    method public void translate(float left = 0.0f, float top = 0.0f);
-    property public default androidx.ui.geometry.Offset center;
-    property public abstract androidx.ui.geometry.Size size;
-  }
-
   @androidx.ui.graphics.drawscope.DrawScopeMarker public abstract class DrawScope implements androidx.ui.unit.Density {
     ctor public DrawScope();
     method public final void draw(androidx.ui.graphics.Canvas canvas, androidx.ui.geometry.Size size, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
@@ -781,7 +768,7 @@
     method public static inline androidx.ui.graphics.Canvas? rotateRad(androidx.ui.graphics.drawscope.DrawScope, float radians, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? scale(androidx.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? translate(androidx.ui.graphics.drawscope.DrawScope, float left = 0.0f, float top = 0.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
-    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.CanvasTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
   }
 
   @kotlin.DslMarker public @interface DrawScopeMarker {
@@ -790,9 +777,23 @@
   public abstract sealed class DrawStyle {
   }
 
+  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface DrawTransform {
+    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public default androidx.ui.geometry.Offset getCenter();
+    method public androidx.ui.geometry.Size getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
+    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
+    method public void transform(androidx.ui.graphics.vectormath.Matrix4 matrix);
+    method public void translate(float left = 0.0f, float top = 0.0f);
+    property public default androidx.ui.geometry.Offset center;
+    property public abstract androidx.ui.geometry.Size size;
+  }
+
   public final class DrawTransformKt {
-    method public static inline void inset(androidx.ui.graphics.drawscope.CanvasTransform, float dx = 0.0f, float dy = 0.0f);
-    method public static inline void rotateRad(androidx.ui.graphics.drawscope.CanvasTransform, float radians, float pivotX = center.x, float pivotY = center.y);
+    method public static inline void inset(androidx.ui.graphics.drawscope.DrawTransform, float dx = 0.0f, float dy = 0.0f);
+    method public static inline void rotateRad(androidx.ui.graphics.drawscope.DrawTransform, float radians, float pivotX = center.x, float pivotY = center.y);
   }
 
   public final class Fill extends androidx.ui.graphics.drawscope.DrawStyle {
diff --git a/ui/ui-graphics/api/public_plus_experimental_current.txt b/ui/ui-graphics/api/public_plus_experimental_current.txt
index 5685197..a6b5aa8 100644
--- a/ui/ui-graphics/api/public_plus_experimental_current.txt
+++ b/ui/ui-graphics/api/public_plus_experimental_current.txt
@@ -722,19 +722,6 @@
 
 package androidx.ui.graphics.drawscope {
 
-  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface CanvasTransform {
-    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public default androidx.ui.geometry.Offset getCenter();
-    method public androidx.ui.geometry.Size getSize();
-    method public void inset(float left, float top, float right, float bottom);
-    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
-    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
-    method public void translate(float left = 0.0f, float top = 0.0f);
-    property public default androidx.ui.geometry.Offset center;
-    property public abstract androidx.ui.geometry.Size size;
-  }
-
   @androidx.ui.graphics.drawscope.DrawScopeMarker public abstract class DrawScope implements androidx.ui.unit.Density {
     ctor public DrawScope();
     method public final void draw(androidx.ui.graphics.Canvas canvas, androidx.ui.geometry.Size size, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
@@ -781,7 +768,7 @@
     method public static inline androidx.ui.graphics.Canvas? rotateRad(androidx.ui.graphics.drawscope.DrawScope, float radians, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? scale(androidx.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? translate(androidx.ui.graphics.drawscope.DrawScope, float left = 0.0f, float top = 0.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
-    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.CanvasTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
   }
 
   @kotlin.DslMarker public @interface DrawScopeMarker {
@@ -790,9 +777,23 @@
   public abstract sealed class DrawStyle {
   }
 
+  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface DrawTransform {
+    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public default androidx.ui.geometry.Offset getCenter();
+    method public androidx.ui.geometry.Size getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
+    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
+    method public void transform(androidx.ui.graphics.vectormath.Matrix4 matrix);
+    method public void translate(float left = 0.0f, float top = 0.0f);
+    property public default androidx.ui.geometry.Offset center;
+    property public abstract androidx.ui.geometry.Size size;
+  }
+
   public final class DrawTransformKt {
-    method public static inline void inset(androidx.ui.graphics.drawscope.CanvasTransform, float dx = 0.0f, float dy = 0.0f);
-    method public static inline void rotateRad(androidx.ui.graphics.drawscope.CanvasTransform, float radians, float pivotX = center.x, float pivotY = center.y);
+    method public static inline void inset(androidx.ui.graphics.drawscope.DrawTransform, float dx = 0.0f, float dy = 0.0f);
+    method public static inline void rotateRad(androidx.ui.graphics.drawscope.DrawTransform, float radians, float pivotX = center.x, float pivotY = center.y);
   }
 
   public final class Fill extends androidx.ui.graphics.drawscope.DrawStyle {
diff --git a/ui/ui-graphics/api/restricted_0.1.0-dev14.txt b/ui/ui-graphics/api/restricted_0.1.0-dev14.txt
index cc358bd..28157ee 100644
--- a/ui/ui-graphics/api/restricted_0.1.0-dev14.txt
+++ b/ui/ui-graphics/api/restricted_0.1.0-dev14.txt
@@ -755,19 +755,6 @@
 
 package androidx.ui.graphics.drawscope {
 
-  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface CanvasTransform {
-    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public default androidx.ui.geometry.Offset getCenter();
-    method public androidx.ui.geometry.Size getSize();
-    method public void inset(float left, float top, float right, float bottom);
-    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
-    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
-    method public void translate(float left = 0.0f, float top = 0.0f);
-    property public default androidx.ui.geometry.Offset center;
-    property public abstract androidx.ui.geometry.Size size;
-  }
-
   @androidx.ui.graphics.drawscope.DrawScopeMarker public abstract class DrawScope implements androidx.ui.unit.Density {
     ctor public DrawScope();
     method public final void draw(androidx.ui.graphics.Canvas canvas, androidx.ui.geometry.Size size, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
@@ -799,7 +786,7 @@
     field public static final androidx.ui.graphics.drawscope.DrawScope.Companion! Companion;
     field public static final float DefaultAlpha = 1.0f;
     field @kotlin.PublishedApi internal androidx.ui.graphics.Canvas? canvas;
-    field @kotlin.PublishedApi internal final androidx.ui.graphics.drawscope.CanvasTransform transform;
+    field @kotlin.PublishedApi internal final androidx.ui.graphics.drawscope.DrawTransform transform;
   }
 
   public static final class DrawScope.Companion {
@@ -817,7 +804,7 @@
     method public static inline androidx.ui.graphics.Canvas? rotateRad(androidx.ui.graphics.drawscope.DrawScope, float radians, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? scale(androidx.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? translate(androidx.ui.graphics.drawscope.DrawScope, float left = 0.0f, float top = 0.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
-    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.CanvasTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
   }
 
   @kotlin.DslMarker public @interface DrawScopeMarker {
@@ -826,9 +813,23 @@
   public abstract sealed class DrawStyle {
   }
 
+  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface DrawTransform {
+    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public default androidx.ui.geometry.Offset getCenter();
+    method public androidx.ui.geometry.Size getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
+    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
+    method public void transform(androidx.ui.graphics.vectormath.Matrix4 matrix);
+    method public void translate(float left = 0.0f, float top = 0.0f);
+    property public default androidx.ui.geometry.Offset center;
+    property public abstract androidx.ui.geometry.Size size;
+  }
+
   public final class DrawTransformKt {
-    method public static inline void inset(androidx.ui.graphics.drawscope.CanvasTransform, float dx = 0.0f, float dy = 0.0f);
-    method public static inline void rotateRad(androidx.ui.graphics.drawscope.CanvasTransform, float radians, float pivotX = center.x, float pivotY = center.y);
+    method public static inline void inset(androidx.ui.graphics.drawscope.DrawTransform, float dx = 0.0f, float dy = 0.0f);
+    method public static inline void rotateRad(androidx.ui.graphics.drawscope.DrawTransform, float radians, float pivotX = center.x, float pivotY = center.y);
   }
 
   public final class Fill extends androidx.ui.graphics.drawscope.DrawStyle {
diff --git a/ui/ui-graphics/api/restricted_current.txt b/ui/ui-graphics/api/restricted_current.txt
index cc358bd..28157ee 100644
--- a/ui/ui-graphics/api/restricted_current.txt
+++ b/ui/ui-graphics/api/restricted_current.txt
@@ -755,19 +755,6 @@
 
 package androidx.ui.graphics.drawscope {
 
-  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface CanvasTransform {
-    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
-    method public default androidx.ui.geometry.Offset getCenter();
-    method public androidx.ui.geometry.Size getSize();
-    method public void inset(float left, float top, float right, float bottom);
-    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
-    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
-    method public void translate(float left = 0.0f, float top = 0.0f);
-    property public default androidx.ui.geometry.Offset center;
-    property public abstract androidx.ui.geometry.Size size;
-  }
-
   @androidx.ui.graphics.drawscope.DrawScopeMarker public abstract class DrawScope implements androidx.ui.unit.Density {
     ctor public DrawScope();
     method public final void draw(androidx.ui.graphics.Canvas canvas, androidx.ui.geometry.Size size, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
@@ -799,7 +786,7 @@
     field public static final androidx.ui.graphics.drawscope.DrawScope.Companion! Companion;
     field public static final float DefaultAlpha = 1.0f;
     field @kotlin.PublishedApi internal androidx.ui.graphics.Canvas? canvas;
-    field @kotlin.PublishedApi internal final androidx.ui.graphics.drawscope.CanvasTransform transform;
+    field @kotlin.PublishedApi internal final androidx.ui.graphics.drawscope.DrawTransform transform;
   }
 
   public static final class DrawScope.Companion {
@@ -817,7 +804,7 @@
     method public static inline androidx.ui.graphics.Canvas? rotateRad(androidx.ui.graphics.drawscope.DrawScope, float radians, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? scale(androidx.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
     method public static inline androidx.ui.graphics.Canvas? translate(androidx.ui.graphics.drawscope.DrawScope, float left = 0.0f, float top = 0.0f, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
-    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.CanvasTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+    method public static inline androidx.ui.graphics.Canvas? withTransform(androidx.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
   }
 
   @kotlin.DslMarker public @interface DrawScopeMarker {
@@ -826,9 +813,23 @@
   public abstract sealed class DrawStyle {
   }
 
+  @androidx.ui.graphics.drawscope.DrawScopeMarker public interface DrawTransform {
+    method public void clipPath(androidx.ui.graphics.Path path, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public void clipRect(float left = 0.0f, float top = 0.0f, float right = size.width, float bottom = size.height, androidx.ui.graphics.ClipOp clipOp = androidx.ui.graphics.ClipOp.intersect);
+    method public default androidx.ui.geometry.Offset getCenter();
+    method public androidx.ui.geometry.Size getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, float pivotX = center.x, float pivotY = center.y);
+    method public void scale(float scaleX, float scaleY = scaleX, float pivotX = center.x, float pivotY = center.y);
+    method public void transform(androidx.ui.graphics.vectormath.Matrix4 matrix);
+    method public void translate(float left = 0.0f, float top = 0.0f);
+    property public default androidx.ui.geometry.Offset center;
+    property public abstract androidx.ui.geometry.Size size;
+  }
+
   public final class DrawTransformKt {
-    method public static inline void inset(androidx.ui.graphics.drawscope.CanvasTransform, float dx = 0.0f, float dy = 0.0f);
-    method public static inline void rotateRad(androidx.ui.graphics.drawscope.CanvasTransform, float radians, float pivotX = center.x, float pivotY = center.y);
+    method public static inline void inset(androidx.ui.graphics.drawscope.DrawTransform, float dx = 0.0f, float dy = 0.0f);
+    method public static inline void rotateRad(androidx.ui.graphics.drawscope.DrawTransform, float radians, float pivotX = center.x, float pivotY = center.y);
   }
 
   public final class Fill extends androidx.ui.graphics.drawscope.DrawStyle {
diff --git a/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawScope.kt b/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawScope.kt
index d51f933d..c33716ac 100644
--- a/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawScope.kt
+++ b/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawScope.kt
@@ -36,6 +36,7 @@
 import androidx.ui.graphics.StrokeCap
 import androidx.ui.graphics.StrokeJoin
 import androidx.ui.graphics.setNativePathEffect
+import androidx.ui.graphics.vectormath.Matrix4
 import androidx.ui.graphics.vectormath.degrees
 import androidx.ui.unit.Density
 
@@ -224,7 +225,7 @@
  * applied
  */
 inline fun DrawScope.withTransform(
-    transformBlock: CanvasTransform.() -> Unit,
+    transformBlock: DrawTransform.() -> Unit,
     drawBlock: DrawScope.() -> Unit
 ) = canvas?.apply {
         // Transformation can include inset calls which change the drawing area
@@ -255,7 +256,7 @@
 
     @PublishedApi internal var canvas: Canvas? = null
 
-    @PublishedApi internal val transform = object : CanvasTransform {
+    @PublishedApi internal val transform = object : DrawTransform {
 
         override val size: Size
             get() = this@DrawScope.size
@@ -307,6 +308,10 @@
                 translate(-pivotX, -pivotY)
             }
         }
+
+        override fun transform(matrix: Matrix4) {
+            this@DrawScope.canvas?.concat(matrix)
+        }
     }
 
     /**
diff --git a/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawTransform.kt b/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawTransform.kt
index 26be071..0524661 100644
--- a/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawTransform.kt
+++ b/ui/ui-graphics/src/commonMain/kotlin/androidx/ui/graphics/drawscope/DrawTransform.kt
@@ -20,10 +20,11 @@
 import androidx.ui.geometry.Size
 import androidx.ui.graphics.ClipOp
 import androidx.ui.graphics.Path
+import androidx.ui.graphics.vectormath.Matrix4
 import androidx.ui.graphics.vectormath.degrees
 
 /**
- * Convenience method modifies the [CanvasTransform] bounds to inset both left and right bounds by
+ * Convenience method modifies the [DrawTransform] bounds to inset both left and right bounds by
  * [dx] as well as the top and bottom by [dy]. If only [dx] is provided, the same inset is applied
  * to all 4 bounds
  *
@@ -32,7 +33,7 @@
  * insets the top and bottom by [dx] pixels
  */
 @Suppress("NOTHING_TO_INLINE")
-inline fun CanvasTransform.inset(dx: Float = 0.0f, dy: Float = 0.0f) = inset(dx, dy, dx, dy)
+inline fun DrawTransform.inset(dx: Float = 0.0f, dy: Float = 0.0f) = inset(dx, dy, dx, dy)
 
 /**
  * Add a rotation (in radians clockwise) to the current transform at the given pivot point.
@@ -45,7 +46,7 @@
  * coordinate space vertically
  */
 @Suppress("NOTHING_TO_INLINE")
-inline fun CanvasTransform.rotateRad(
+inline fun DrawTransform.rotateRad(
     radians: Float,
     pivotX: Float = center.x,
     pivotY: Float = center.y
@@ -55,7 +56,7 @@
  * Defines transformations that can be applied to a drawing environment
  */
 @DrawScopeMarker
-interface CanvasTransform {
+interface DrawTransform {
 
     /**
      * Get the current size of the CanvasTransform
@@ -155,4 +156,10 @@
         pivotX: Float = center.x,
         pivotY: Float = center.y
     )
+
+    /**
+     * Transform the drawing environment by the given matrix
+     * @param matrix transformation matrix used to transform the drawing environment
+     */
+    fun transform(matrix: Matrix4)
 }
\ No newline at end of file