diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 592a6e6..be7f300 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -345,33 +345,21 @@
 
     srcs: [
         "tests/unit/main.cpp",
-        "tests/unit/BakedOpDispatcherTests.cpp",
-        "tests/unit/BakedOpRendererTests.cpp",
-        "tests/unit/BakedOpStateTests.cpp",
         "tests/unit/CacheManagerTests.cpp",
         "tests/unit/CanvasContextTests.cpp",
         "tests/unit/CanvasStateTests.cpp",
         "tests/unit/ClipAreaTests.cpp",
         "tests/unit/DamageAccumulatorTests.cpp",
         "tests/unit/DeferredLayerUpdaterTests.cpp",
-        "tests/unit/DeviceInfoTests.cpp",
         "tests/unit/FatVectorTests.cpp",
-        "tests/unit/FontRendererTests.cpp",
-        "tests/unit/FrameBuilderTests.cpp",
-        "tests/unit/GlopBuilderTests.cpp",
         "tests/unit/GpuMemoryTrackerTests.cpp",
-        "tests/unit/GradientCacheTests.cpp",
         "tests/unit/GraphicsStatsServiceTests.cpp",
         "tests/unit/LayerUpdateQueueTests.cpp",
-        "tests/unit/LeakCheckTests.cpp",
         "tests/unit/LinearAllocatorTests.cpp",
         "tests/unit/MatrixTests.cpp",
-        "tests/unit/MeshStateTests.cpp",
-        "tests/unit/OffscreenBufferPoolTests.cpp",
         "tests/unit/OpDumperTests.cpp",
         "tests/unit/PathInterpolatorTests.cpp",
         "tests/unit/RenderNodeDrawableTests.cpp",
-        "tests/unit/RecordingCanvasTests.cpp",
         "tests/unit/RenderNodeTests.cpp",
         "tests/unit/RenderPropertiesTests.cpp",
         "tests/unit/ShaderCacheTests.cpp",
@@ -383,8 +371,6 @@
         "tests/unit/SnapshotTests.cpp",
         "tests/unit/StringUtilsTests.cpp",
         "tests/unit/TestUtilsTests.cpp",
-        "tests/unit/TextDropShadowCacheTests.cpp",
-        "tests/unit/TextureCacheTests.cpp",
         "tests/unit/ThreadBaseTests.cpp",
         "tests/unit/TypefaceTests.cpp",
         "tests/unit/VectorDrawableTests.cpp",
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 7b14322..0d1257f 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -193,15 +193,12 @@
     }
     char prop[PROPERTY_VALUE_MAX];
     property_get(PROPERTY_RENDERER, prop, "skiagl");
-    if (!strcmp(prop, "skiagl")) {
-        ALOGD("Skia GL Pipeline");
-        sRenderPipelineType = RenderPipelineType::SkiaGL;
-    } else if (!strcmp(prop, "skiavk")) {
+    if (!strcmp(prop, "skiavk")) {
         ALOGD("Skia Vulkan Pipeline");
         sRenderPipelineType = RenderPipelineType::SkiaVulkan;
-    } else {  //"opengl"
-        ALOGD("HWUI GL Pipeline");
-        sRenderPipelineType = RenderPipelineType::OpenGL;
+    } else {  //"skiagl"
+        ALOGD("Skia GL Pipeline");
+        sRenderPipelineType = RenderPipelineType::SkiaGL;
     }
     return sRenderPipelineType;
 }
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 1a0bdfd..03a3e36 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -206,7 +206,7 @@
 
 enum class StencilClipDebug { Hide, ShowHighlight, ShowRegion };
 
-enum class RenderPipelineType { OpenGL = 0, SkiaGL, SkiaVulkan, NotInitialized = 128 };
+enum class RenderPipelineType { SkiaGL, SkiaVulkan, NotInitialized = 128 };
 
 /**
  * Renderthread-only singleton which manages several static rendering properties. Most of these
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 609d26c..23023e7 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -69,9 +69,6 @@
     auto renderType = Properties::getRenderPipelineType();
 
     switch (renderType) {
-        case RenderPipelineType::OpenGL:
-            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
-                                     std::make_unique<OpenGLPipeline>(thread));
         case RenderPipelineType::SkiaGL:
             return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
                                      std::make_unique<skiapipeline::SkiaOpenGLPipeline>(thread));
@@ -86,28 +83,13 @@
 }
 
 void CanvasContext::destroyLayer(RenderNode* node) {
-    auto renderType = Properties::getRenderPipelineType();
-    switch (renderType) {
-        case RenderPipelineType::OpenGL:
-            OpenGLPipeline::destroyLayer(node);
-            break;
-        case RenderPipelineType::SkiaGL:
-        case RenderPipelineType::SkiaVulkan:
-            skiapipeline::SkiaPipeline::destroyLayer(node);
-            break;
-        default:
-            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
-            break;
-    }
+    skiapipeline::SkiaPipeline::destroyLayer(node);
 }
 
 void CanvasContext::invokeFunctor(const RenderThread& thread, Functor* functor) {
     ATRACE_CALL();
     auto renderType = Properties::getRenderPipelineType();
     switch (renderType) {
-        case RenderPipelineType::OpenGL:
-            OpenGLPipeline::invokeFunctor(thread, functor);
-            break;
         case RenderPipelineType::SkiaGL:
             skiapipeline::SkiaOpenGLPipeline::invokeFunctor(thread, functor);
             break;
@@ -121,19 +103,7 @@
 }
 
 void CanvasContext::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
-    auto renderType = Properties::getRenderPipelineType();
-    switch (renderType) {
-        case RenderPipelineType::OpenGL:
-            OpenGLPipeline::prepareToDraw(thread, bitmap);
-            break;
-        case RenderPipelineType::SkiaGL:
-        case RenderPipelineType::SkiaVulkan:
-            skiapipeline::SkiaPipeline::prepareToDraw(thread, bitmap);
-            break;
-        default:
-            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
-            break;
-    }
+    skiapipeline::SkiaPipeline::prepareToDraw(thread, bitmap);
 }
 
 CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
@@ -586,37 +556,15 @@
 }
 
 void CanvasContext::trimMemory(RenderThread& thread, int level) {
-    auto renderType = Properties::getRenderPipelineType();
-    switch (renderType) {
-        case RenderPipelineType::OpenGL: {
-            // No context means nothing to free
-            if (!thread.eglManager().hasEglContext()) return;
-            ATRACE_CALL();
-            if (level >= TRIM_MEMORY_COMPLETE) {
-                thread.renderState().flush(Caches::FlushMode::Full);
-                thread.eglManager().destroy();
-            } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
-                thread.renderState().flush(Caches::FlushMode::Moderate);
-            }
-            break;
-        }
-        case RenderPipelineType::SkiaGL:
-        case RenderPipelineType::SkiaVulkan: {
-            // No context means nothing to free
-            if (!thread.getGrContext()) return;
-            ATRACE_CALL();
-            if (level >= TRIM_MEMORY_COMPLETE) {
-                thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
-                thread.eglManager().destroy();
-                thread.vulkanManager().destroy();
-            } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
-                thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
-            }
-            break;
-        }
-        default:
-            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
-            break;
+    ATRACE_CALL();
+    if (!thread.getGrContext()) return;
+    ATRACE_CALL();
+    if (level >= TRIM_MEMORY_COMPLETE) {
+        thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+        thread.eglManager().destroy();
+        thread.vulkanManager().destroy();
+    } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
+        thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
     }
 }
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 4b154e6..f4d230e 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -175,16 +175,6 @@
     String8 pipeline;
     auto renderType = Properties::getRenderPipelineType();
     switch (renderType) {
-        case RenderPipelineType::OpenGL: {
-            if (Caches::hasInstance()) {
-                cachesOutput.appendFormat("Caches:\n");
-                Caches::getInstance().dumpMemoryUsage(cachesOutput);
-            } else {
-                cachesOutput.appendFormat("No caches instance.");
-            }
-            pipeline.appendFormat("FrameBuilder");
-            break;
-        }
         case RenderPipelineType::SkiaGL: {
             mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
             pipeline.appendFormat("Skia (OpenGL)");
@@ -208,9 +198,6 @@
     if (!mReadback) {
         auto renderType = Properties::getRenderPipelineType();
         switch (renderType) {
-            case RenderPipelineType::OpenGL:
-                mReadback = new OpenGLReadbackImpl(*this);
-                break;
             case RenderPipelineType::SkiaGL:
                 mReadback = new skiapipeline::SkiaOpenGLReadback(*this);
                 break;
@@ -344,8 +331,6 @@
 sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
     auto renderType = Properties::getRenderPipelineType();
     switch (renderType) {
-        case RenderPipelineType::OpenGL:
-            return OpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
         case RenderPipelineType::SkiaGL:
             return skiapipeline::SkiaOpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
         case RenderPipelineType::SkiaVulkan:
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 0306498..f51e7cc 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -53,9 +53,7 @@
 sp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
         renderthread::RenderThread& renderThread) {
     android::uirenderer::renderthread::IRenderPipeline* pipeline;
-    if (Properties::getRenderPipelineType() == RenderPipelineType::OpenGL) {
-        pipeline = new renderthread::OpenGLPipeline(renderThread);
-    } else if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
         pipeline = new skiapipeline::SkiaOpenGLPipeline(renderThread);
     } else {
         pipeline = new skiapipeline::SkiaVulkanPipeline(renderThread);
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 1bfa046..707d61a 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -60,18 +60,6 @@
         Properties::overrideRenderPipelineType(oldType);                       \
     };
 
-/**
- * Like gtests' TEST, but only runs with the OpenGL RenderPipelineType
- */
-#define OPENGL_PIPELINE_TEST(test_case_name, test_name)                        \
-    class test_case_name##_##test_name##_HwuiTest {                            \
-    public:                                                                    \
-        static void doTheThing();                                              \
-    };                                                                         \
-    INNER_PIPELINE_TEST(test_case_name, test_name, OpenGL,                     \
-                        test_case_name##_##test_name##_HwuiTest::doTheThing()) \
-    void test_case_name##_##test_name##_HwuiTest::doTheThing()
-
 #define INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, pipeline) \
     INNER_PIPELINE_TEST(test_case_name, test_name, pipeline,                  \
                         TestUtils::runOnRenderThread(                         \
@@ -86,7 +74,6 @@
     public:                                                                                 \
         static void doTheThing(renderthread::RenderThread& renderThread);                   \
     };                                                                                      \
-    INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, OpenGL);                    \
     INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL);                    \
     /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \
     /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */          \
@@ -94,18 +81,6 @@
             renderthread::RenderThread& renderThread)
 
 /**
- * Like RENDERTHREAD_TEST, but only runs with the OpenGL RenderPipelineType
- */
-#define RENDERTHREAD_OPENGL_PIPELINE_TEST(test_case_name, test_name)      \
-    class test_case_name##_##test_name##_RenderThreadTest {               \
-    public:                                                               \
-        static void doTheThing(renderthread::RenderThread& renderThread); \
-    };                                                                    \
-    INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, OpenGL);  \
-    void test_case_name##_##test_name##_RenderThreadTest::doTheThing(     \
-            renderthread::RenderThread& renderThread)
-
-/**
  * Like RENDERTHREAD_TEST, but only runs with the Skia RenderPipelineTypes
  */
 #define RENDERTHREAD_SKIA_PIPELINE_TEST(test_case_name, test_name)                          \
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 4cb5cfd..dc8e600 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -67,7 +67,7 @@
   --onscreen           Render tests on device screen. By default tests
                        are offscreen rendered
   --benchmark_format   Set output format. Possible values are tabular, json, csv
-  --renderer=TYPE      Sets the render pipeline to use. May be opengl, skiagl, or skiavk
+  --renderer=TYPE      Sets the render pipeline to use. May be skiagl or skiavk
   --render-ahead=NUM   Sets how far to render-ahead. Must be 0 (default), 1, or 2.
 )");
 }
@@ -148,9 +148,7 @@
 }
 
 static bool setRenderer(const char* renderer) {
-    if (!strcmp(renderer, "opengl")) {
-        Properties::overrideRenderPipelineType(RenderPipelineType::OpenGL);
-    } else if (!strcmp(renderer, "skiagl")) {
+    if (!strcmp(renderer, "skiagl")) {
         Properties::overrideRenderPipelineType(RenderPipelineType::SkiaGL);
     } else if (!strcmp(renderer, "skiavk")) {
         Properties::overrideRenderPipelineType(RenderPipelineType::SkiaVulkan);
diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
deleted file mode 100644
index 09f0b06..0000000
--- a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <BakedOpDispatcher.h>
-#include <BakedOpRenderer.h>
-#include <FrameBuilder.h>
-#include <LayerUpdateQueue.h>
-#include <RecordedOp.h>
-#include <hwui/Paint.h>
-#include <tests/common/TestUtils.h>
-#include <utils/Color.h>
-
-#include <SkBlurDrawLooper.h>
-#include <SkDashPathEffect.h>
-#include <SkPath.h>
-
-using namespace android::uirenderer;
-
-static BakedOpRenderer::LightInfo sLightInfo;
-const FrameBuilder::LightGeometry sLightGeometry = {{100, 100, 100}, 50};
-
-class ValidatingBakedOpRenderer : public BakedOpRenderer {
-public:
-    ValidatingBakedOpRenderer(RenderState& renderState,
-                              std::function<void(const Glop& glop)> validator)
-            : BakedOpRenderer(Caches::getInstance(), renderState, true, false, sLightInfo)
-            , mValidator(validator) {
-        mGlopReceiver = ValidatingGlopReceiver;
-    }
-
-private:
-    static void ValidatingGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds,
-                                       const ClipBase* clip, const Glop& glop) {
-        auto vbor = reinterpret_cast<ValidatingBakedOpRenderer*>(&renderer);
-        vbor->mValidator(glop);
-    }
-    std::function<void(const Glop& glop)> mValidator;
-};
-
-typedef void (*TestBakedOpReceiver)(BakedOpRenderer&, const BakedOpState&);
-
-static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op,
-                                     std::function<void(const Glop& glop)> glopVerifier,
-                                     int expectedGlopCount = 1) {
-    // Create op, and wrap with basic state.
-    LinearAllocator allocator;
-    auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 100));
-    auto state = BakedOpState::tryConstruct(allocator, *snapshot, *op);
-    ASSERT_NE(nullptr, state);
-
-    int glopCount = 0;
-    auto glopReceiver = [&glopVerifier, &glopCount, &expectedGlopCount](const Glop& glop) {
-        ASSERT_LE(glopCount++, expectedGlopCount) << expectedGlopCount << "glop(s) expected";
-        glopVerifier(glop);
-    };
-    ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver);
-
-// Dispatch based on op type created, similar to Frame/LayerBuilder dispatch behavior
-#define X(Type)                                                                              \
-    [](BakedOpRenderer& renderer, const BakedOpState& state) {                               \
-        BakedOpDispatcher::on##Type(renderer, static_cast<const Type&>(*(state.op)), state); \
-    },
-    static TestBakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X);
-#undef X
-    unmergedReceivers[op->opId](renderer, *state);
-    ASSERT_EQ(expectedGlopCount, glopCount) << "Exactly " << expectedGlopCount
-                                            << "Glop(s) expected";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, pathTexture_positionOvalArc) {
-    SkPaint strokePaint;
-    strokePaint.setStyle(SkPaint::kStroke_Style);
-    strokePaint.setStrokeWidth(4);
-
-    float intervals[] = {1.0f, 1.0f};
-    strokePaint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
-
-    auto textureGlopVerifier = [](const Glop& glop) {
-        // validate glop produced by renderPathTexture (so texture, unit quad)
-        auto texture = glop.fill.texture.texture;
-        ASSERT_NE(nullptr, texture);
-        float expectedOffset = floor(4 * 1.5f + 0.5f);
-        EXPECT_EQ(expectedOffset, reinterpret_cast<PathTexture*>(texture)->offset)
-                << "Should see conservative offset from PathCache::computeBounds";
-        Rect expectedBounds(10, 15, 20, 25);
-        expectedBounds.outset(expectedOffset);
-
-        Matrix4 expectedModelView;
-        expectedModelView.loadTranslate(10 - expectedOffset, 15 - expectedOffset, 0);
-        expectedModelView.scale(10 + 2 * expectedOffset, 10 + 2 * expectedOffset, 1);
-        EXPECT_EQ(expectedModelView, glop.transform.modelView)
-                << "X and Y offsets, and scale both applied to model view";
-    };
-
-    // Arc and Oval will render functionally the same glop, differing only in texture content
-    ArcOp arcOp(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint, 0, 270, true);
-    testUnmergedGlopDispatch(renderThread, &arcOp, textureGlopVerifier);
-
-    OvalOp ovalOp(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint);
-    testUnmergedGlopDispatch(renderThread, &ovalOp, textureGlopVerifier);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, onLayerOp_bufferless) {
-    SkPaint layerPaint;
-    layerPaint.setAlpha(128);
-    OffscreenBuffer* buffer = nullptr;  // no providing a buffer, should hit rect fallback case
-    LayerOp op(Rect(10, 10), Matrix4::identity(), nullptr, &layerPaint, &buffer);
-    testUnmergedGlopDispatch(renderThread, &op,
-                             [](const Glop& glop) { ADD_FAILURE() << "Nothing should happen"; }, 0);
-}
-
-static int getGlopTransformFlags(renderthread::RenderThread& renderThread, RecordedOp* op) {
-    int result = 0;
-    testUnmergedGlopDispatch(renderThread, op, [&result](const Glop& glop) {
-        result = glop.transform.transformFlags;
-    });
-    return result;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, offsetFlags) {
-    Rect bounds(10, 15, 20, 25);
-    SkPaint paint;
-    SkPaint aaPaint;
-    aaPaint.setAntiAlias(true);
-
-    RoundRectOp roundRectOp(bounds, Matrix4::identity(), nullptr, &paint, 0, 270);
-    EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &roundRectOp))
-            << "Expect no offset for round rect op.";
-
-    const float points[4] = {0.5, 0.5, 1.0, 1.0};
-    PointsOp antiAliasedPointsOp(bounds, Matrix4::identity(), nullptr, &aaPaint, points, 4);
-    EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &antiAliasedPointsOp))
-            << "Expect no offset for AA points.";
-    PointsOp pointsOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4);
-    EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &pointsOp))
-            << "Expect an offset for non-AA points.";
-
-    LinesOp antiAliasedLinesOp(bounds, Matrix4::identity(), nullptr, &aaPaint, points, 4);
-    EXPECT_EQ(TransformFlags::None, getGlopTransformFlags(renderThread, &antiAliasedLinesOp))
-            << "Expect no offset for AA lines.";
-    LinesOp linesOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4);
-    EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &linesOp))
-            << "Expect an offset for non-AA lines.";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, renderTextWithShadow) {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-
-                android::Paint shadowPaint;
-                shadowPaint.setColor(SK_ColorRED);
-
-                SkScalar sigma = Blur::convertRadiusToSigma(5);
-                shadowPaint.setLooper(SkBlurDrawLooper::Make(SK_ColorWHITE, sigma, 3, 3));
-
-                TestUtils::drawUtf8ToCanvas(&canvas, "A", shadowPaint, 25, 25);
-                TestUtils::drawUtf8ToCanvas(&canvas, "B", shadowPaint, 50, 50);
-            });
-
-    int glopCount = 0;
-    auto glopReceiver = [&glopCount](const Glop& glop) {
-        if (glopCount < 2) {
-            // two white shadows
-            EXPECT_EQ(FloatColor({1, 1, 1, 1}), glop.fill.color);
-        } else {
-            // two text draws merged into one, drawn after both shadows
-            EXPECT_EQ(FloatColor({1, 0, 0, 1}), glop.fill.color);
-        }
-        glopCount++;
-    };
-
-    ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver);
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-    ASSERT_EQ(3, glopCount) << "Exactly three glops expected";
-}
-
-static void validateLayerDraw(renderthread::RenderThread& renderThread,
-                              std::function<void(const Glop& glop)> validator) {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                props.mutateLayerProperties().setType(LayerType::RenderLayer);
-
-                // provide different blend mode, so decoration draws contrast
-                props.mutateLayerProperties().setXferMode(SkBlendMode::kSrc);
-                canvas.drawColor(Color::Black, SkBlendMode::kSrcOver);
-            });
-    OffscreenBuffer** layerHandle = node->getLayerHandle();
-
-    auto syncedNode = TestUtils::getSyncedNode(node);
-
-    // create RenderNode's layer here in same way prepareTree would
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
-    *layerHandle = &layer;
-    {
-        LayerUpdateQueue layerUpdateQueue;  // Note: enqueue damage post-sync, so bounds are valid
-        layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(0, 0, 100, 100));
-
-        ValidatingBakedOpRenderer renderer(renderThread.renderState(), validator);
-        FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                                  Caches::getInstance());
-        frameBuilder.deferLayers(layerUpdateQueue);
-        frameBuilder.deferRenderNode(*syncedNode);
-        frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-    }
-
-    // clean up layer pointer, so we can safely destruct RenderNode
-    *layerHandle = nullptr;
-}
-
-static FloatColor makeFloatColor(uint32_t color) {
-    FloatColor c;
-    c.set(color);
-    return c;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, layerUpdateProperties) {
-    for (bool debugOverdraw : {false, true}) {
-        for (bool debugLayersUpdates : {false, true}) {
-            ScopedProperty<bool> ovdProp(Properties::debugOverdraw, debugOverdraw);
-            ScopedProperty<bool> lupProp(Properties::debugLayersUpdates, debugLayersUpdates);
-
-            int glopCount = 0;
-            validateLayerDraw(renderThread, [&glopCount, &debugLayersUpdates](const Glop& glop) {
-                if (glopCount == 0) {
-                    // 0 - Black layer fill
-                    EXPECT_TRUE(glop.fill.colorEnabled);
-                    EXPECT_EQ(makeFloatColor(Color::Black), glop.fill.color);
-                } else if (glopCount == 1) {
-                    // 1 - Uncolored (textured) layer draw
-                    EXPECT_FALSE(glop.fill.colorEnabled);
-                } else if (glopCount == 2) {
-                    // 2 - layer overlay, if present
-                    EXPECT_TRUE(glop.fill.colorEnabled);
-                    // blend srcover, different from that of layer
-                    EXPECT_EQ(GLenum(GL_ONE), glop.blend.src);
-                    EXPECT_EQ(GLenum(GL_ONE_MINUS_SRC_ALPHA), glop.blend.dst);
-                    EXPECT_EQ(makeFloatColor(debugLayersUpdates ? 0x7f00ff00 : 0), glop.fill.color)
-                            << "Should be transparent green if debugLayersUpdates";
-                } else if (glopCount < 7) {
-                    // 3 - 6 - overdraw indicator overlays, if present
-                    EXPECT_TRUE(glop.fill.colorEnabled);
-                    uint32_t expectedColor = Caches::getInstance().getOverdrawColor(glopCount - 2);
-                    ASSERT_EQ(makeFloatColor(expectedColor), glop.fill.color);
-                } else {
-                    ADD_FAILURE() << "Too many glops observed";
-                }
-                glopCount++;
-            });
-            int expectedCount = 2;
-            if (debugLayersUpdates || debugOverdraw) expectedCount++;
-            if (debugOverdraw) expectedCount += 4;
-            EXPECT_EQ(expectedCount, glopCount);
-        }
-    }
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpDispatcher, pathTextureSnapping) {
-    Rect bounds(10, 15, 20, 25);
-    SkPaint paint;
-    SkPath path;
-    path.addRect(SkRect::MakeXYWH(1.5, 3.8, 100, 90));
-    PathOp op(bounds, Matrix4::identity(), nullptr, &paint, &path);
-    testUnmergedGlopDispatch(renderThread, &op, [](const Glop& glop) {
-        auto texture = glop.fill.texture.texture;
-        ASSERT_NE(nullptr, texture);
-        EXPECT_EQ(1, reinterpret_cast<PathTexture*>(texture)->left);
-        EXPECT_EQ(3, reinterpret_cast<PathTexture*>(texture)->top);
-    });
-}
diff --git a/libs/hwui/tests/unit/BakedOpRendererTests.cpp b/libs/hwui/tests/unit/BakedOpRendererTests.cpp
deleted file mode 100644
index 1a3ec39..0000000
--- a/libs/hwui/tests/unit/BakedOpRendererTests.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <BakedOpRenderer.h>
-#include <GlopBuilder.h>
-#include <tests/common/TestUtils.h>
-
-using namespace android::uirenderer;
-
-const BakedOpRenderer::LightInfo sLightInfo = {128, 128};
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, startRepaintLayer_clear) {
-    BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, false,
-                             sLightInfo);
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u);
-
-    layer.dirty(Rect(200, 200));
-    {
-        renderer.startRepaintLayer(&layer, Rect(200, 200));
-        EXPECT_TRUE(layer.region.isEmpty()) << "Repaint full layer should clear region";
-        renderer.endLayer();
-    }
-
-    layer.dirty(Rect(200, 200));
-    {
-        renderer.startRepaintLayer(&layer, Rect(100, 200));  // repainting left side
-        EXPECT_TRUE(layer.region.isRect());
-        // ALOGD("bounds %d %d %d %d", RECT_ARGS(layer.region.getBounds()));
-        EXPECT_EQ(android::Rect(100, 0, 200, 200), layer.region.getBounds())
-                << "Left side being repainted, so right side should be clear";
-        renderer.endLayer();
-    }
-
-    // right side is now only dirty portion
-    {
-        renderer.startRepaintLayer(&layer, Rect(100, 0, 200, 200));  // repainting right side
-        EXPECT_TRUE(layer.region.isEmpty())
-                << "Now right side being repainted, so region should be entirely clear";
-        renderer.endLayer();
-    }
-}
-
-static void drawFirstOp(RenderState& renderState, int color, SkBlendMode mode) {
-    BakedOpRenderer renderer(Caches::getInstance(), renderState, true, false, sLightInfo);
-
-    renderer.startFrame(100, 100, Rect(100, 100));
-    SkPaint paint;
-    paint.setColor(color);
-    paint.setBlendMode(mode);
-
-    Rect dest(0, 0, 100, 100);
-    Glop glop;
-    GlopBuilder(renderState, Caches::getInstance(), &glop)
-            .setRoundRectClipState(nullptr)
-            .setMeshUnitQuad()
-            .setFillPaint(paint, 1.0f)
-            .setTransform(Matrix4::identity(), TransformFlags::None)
-            .setModelViewMapUnitToRectSnap(dest)
-            .build();
-    renderer.renderGlop(nullptr, nullptr, glop);
-    renderer.endFrame(Rect(100, 100));
-}
-
-static void verifyBlend(RenderState& renderState, GLenum expectedSrc, GLenum expectedDst) {
-    EXPECT_TRUE(renderState.blend().getEnabled());
-    GLenum src;
-    GLenum dst;
-    renderState.blend().getFactors(&src, &dst);
-    EXPECT_EQ(expectedSrc, src);
-    EXPECT_EQ(expectedDst, dst);
-}
-
-static void verifyBlendDisabled(RenderState& renderState) {
-    EXPECT_FALSE(renderState.blend().getEnabled());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, firstDrawBlend_clear) {
-    // initialize blend state to nonsense value
-    renderThread.renderState().blend().setFactors(GL_ONE, GL_ONE);
-
-    drawFirstOp(renderThread.renderState(), 0xfeff0000, SkBlendMode::kClear);
-    verifyBlend(renderThread.renderState(), GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(BakedOpRenderer, firstDrawBlend_srcover) {
-    // initialize blend state to nonsense value
-    renderThread.renderState().blend().setFactors(GL_ONE, GL_ONE);
-
-    drawFirstOp(renderThread.renderState(), 0xfeff0000, SkBlendMode::kSrcOver);
-    verifyBlendDisabled(renderThread.renderState());
-}
diff --git a/libs/hwui/tests/unit/BakedOpStateTests.cpp b/libs/hwui/tests/unit/BakedOpStateTests.cpp
deleted file mode 100644
index 6f8e249..0000000
--- a/libs/hwui/tests/unit/BakedOpStateTests.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <BakedOpState.h>
-#include <ClipArea.h>
-#include <RecordedOp.h>
-#include <tests/common/TestUtils.h>
-
-namespace android {
-namespace uirenderer {
-
-TEST(ResolvedRenderState, construct) {
-    LinearAllocator allocator;
-    Matrix4 translate10x20;
-    translate10x20.loadTranslate(10, 20, 0);
-
-    SkPaint paint;
-    ClipRect clip(Rect(100, 200));
-    RectOp recordedOp(Rect(30, 40, 100, 200), translate10x20, &clip, &paint);
-    {
-        // recorded with transform, no parent transform
-        auto parentSnapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
-        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
-        EXPECT_MATRIX_APPROX_EQ(state.transform, translate10x20);
-        EXPECT_EQ(Rect(100, 200), state.clipRect());
-        EXPECT_EQ(Rect(40, 60, 100, 200), state.clippedBounds);  // translated and also clipped
-        EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
-    }
-    {
-        // recorded with transform and parent transform
-        auto parentSnapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
-        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
-
-        Matrix4 expectedTranslate;
-        expectedTranslate.loadTranslate(20, 40, 0);
-        EXPECT_MATRIX_APPROX_EQ(expectedTranslate, state.transform);
-
-        // intersection of parent & transformed child clip
-        EXPECT_EQ(Rect(10, 20, 100, 200), state.clipRect());
-
-        // translated and also clipped
-        EXPECT_EQ(Rect(50, 80, 100, 200), state.clippedBounds);
-        EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
-    }
-}
-
-TEST(ResolvedRenderState, computeLocalSpaceClip) {
-    LinearAllocator allocator;
-    Matrix4 translate10x20;
-    translate10x20.loadTranslate(10, 20, 0);
-
-    SkPaint paint;
-    ClipRect clip(Rect(100, 200));
-    RectOp recordedOp(Rect(1000, 1000), translate10x20, &clip, &paint);
-    {
-        // recorded with transform, no parent transform
-        auto parentSnapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
-        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
-        EXPECT_EQ(Rect(-10, -20, 90, 180), state.computeLocalSpaceClip())
-                << "Local clip rect should be 100x200, offset by -10,-20";
-    }
-    {
-        // recorded with transform + parent transform
-        auto parentSnapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
-        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
-        EXPECT_EQ(Rect(-10, -20, 80, 160), state.computeLocalSpaceClip())
-                << "Local clip rect should be 90x190, offset by -10,-20";
-    }
-}
-
-const float HAIRLINE = 0.0f;
-
-// Note: bounds will be conservative, but not precise for non-hairline
-// - use approx bounds checks for these
-const float SEMI_HAIRLINE = 0.3f;
-
-struct StrokeTestCase {
-    float scale;
-    float strokeWidth;
-    const std::function<void(const ResolvedRenderState&)> validator;
-};
-
-const static StrokeTestCase sStrokeTestCases[] = {
-        {1, HAIRLINE,
-         [](const ResolvedRenderState& state) {
-             EXPECT_EQ(Rect(49.5f, 49.5f, 150.5f, 150.5f), state.clippedBounds);
-         }},
-        {1, SEMI_HAIRLINE,
-         [](const ResolvedRenderState& state) {
-             EXPECT_TRUE(state.clippedBounds.contains(49.5f, 49.5f, 150.5f, 150.5f));
-             EXPECT_TRUE(Rect(49, 49, 151, 151).contains(state.clippedBounds));
-         }},
-        {1, 20,
-         [](const ResolvedRenderState& state) {
-             EXPECT_EQ(Rect(40, 40, 160, 160), state.clippedBounds);
-         }},
-
-        // 3x3 scale:
-        {3, HAIRLINE,
-         [](const ResolvedRenderState& state) {
-             EXPECT_EQ(Rect(149.5f, 149.5f, 200, 200), state.clippedBounds);
-             EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
-         }},
-        {3, SEMI_HAIRLINE,
-         [](const ResolvedRenderState& state) {
-             EXPECT_TRUE(state.clippedBounds.contains(149.5f, 149.5f, 200, 200));
-             EXPECT_TRUE(Rect(149, 149, 200, 200).contains(state.clippedBounds));
-         }},
-        {3, 20,
-         [](const ResolvedRenderState& state) {
-             EXPECT_TRUE(state.clippedBounds.contains(120, 120, 200, 200));
-             EXPECT_TRUE(Rect(119, 119, 200, 200).contains(state.clippedBounds));
-         }},
-
-        // 0.5f x 0.5f scale
-        {0.5f, HAIRLINE,
-         [](const ResolvedRenderState& state) {
-             EXPECT_EQ(Rect(24.5f, 24.5f, 75.5f, 75.5f), state.clippedBounds);
-         }},
-        {0.5f, SEMI_HAIRLINE,
-         [](const ResolvedRenderState& state) {
-             EXPECT_TRUE(state.clippedBounds.contains(24.5f, 24.5f, 75.5f, 75.5f));
-             EXPECT_TRUE(Rect(24, 24, 76, 76).contains(state.clippedBounds));
-         }},
-        {0.5f, 20, [](const ResolvedRenderState& state) {
-             EXPECT_TRUE(state.clippedBounds.contains(19.5f, 19.5f, 80.5f, 80.5f));
-             EXPECT_TRUE(Rect(19, 19, 81, 81).contains(state.clippedBounds));
-         }}};
-
-TEST(ResolvedRenderState, construct_expandForStroke) {
-    LinearAllocator allocator;
-    // Loop over table of test cases and verify different combinations of stroke width and transform
-    for (auto&& testCase : sStrokeTestCases) {
-        SkPaint strokedPaint;
-        strokedPaint.setAntiAlias(true);
-        strokedPaint.setStyle(SkPaint::kStroke_Style);
-        strokedPaint.setStrokeWidth(testCase.strokeWidth);
-
-        ClipRect clip(Rect(200, 200));
-        RectOp recordedOp(Rect(50, 50, 150, 150), Matrix4::identity(), &clip, &strokedPaint);
-
-        Matrix4 snapshotMatrix;
-        snapshotMatrix.loadScale(testCase.scale, testCase.scale, 1);
-        auto parentSnapshot = TestUtils::makeSnapshot(snapshotMatrix, Rect(200, 200));
-
-        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, true, false);
-        testCase.validator(state);
-    }
-}
-
-TEST(BakedOpState, tryConstruct) {
-    Matrix4 translate100x0;
-    translate100x0.loadTranslate(100, 0, 0);
-
-    SkPaint paint;
-    ClipRect clip(Rect(100, 200));
-
-    LinearAllocator allocator;
-    RectOp successOp(Rect(30, 40, 100, 200), Matrix4::identity(), &clip, &paint);
-    auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
-    EXPECT_NE(nullptr, BakedOpState::tryConstruct(allocator, *snapshot, successOp))
-            << "successOp NOT rejected by clip, so should be constructed";
-    size_t successAllocSize = allocator.usedSize();
-    EXPECT_LE(64u, successAllocSize) << "relatively large alloc for non-rejected op";
-
-    RectOp rejectOp(Rect(30, 40, 100, 200), translate100x0, &clip, &paint);
-    EXPECT_EQ(nullptr, BakedOpState::tryConstruct(allocator, *snapshot, rejectOp))
-            << "rejectOp rejected by clip, so should not be constructed";
-
-    // NOTE: this relies on the clip having already been serialized by the op above
-    EXPECT_EQ(successAllocSize, allocator.usedSize()) << "no extra allocation used for rejected op";
-}
-
-TEST(BakedOpState, tryShadowOpConstruct) {
-    Matrix4 translate10x20;
-    translate10x20.loadTranslate(10, 20, 0);
-
-    LinearAllocator allocator;
-    {
-        auto snapshot = TestUtils::makeSnapshot(translate10x20, Rect());  // Note: empty clip
-        BakedOpState* bakedState =
-                BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
-
-        EXPECT_EQ(nullptr, bakedState) << "op should be rejected by clip, so not constructed";
-        EXPECT_EQ(0u, allocator.usedSize()) << "no serialization, even for clip,"
-                                               "since op is quick rejected based on snapshot clip";
-    }
-    {
-        auto snapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
-        BakedOpState* bakedState =
-                BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
-
-        ASSERT_NE(nullptr, bakedState) << "NOT rejected by clip, so op should be constructed";
-        EXPECT_LE(64u, allocator.usedSize()) << "relatively large alloc for non-rejected op";
-
-        EXPECT_MATRIX_APPROX_EQ(translate10x20, bakedState->computedState.transform);
-        EXPECT_EQ(Rect(100, 200), bakedState->computedState.clippedBounds);
-    }
-}
-
-TEST(BakedOpState, tryStrokeableOpConstruct) {
-    LinearAllocator allocator;
-    {
-        // check regular rejection
-        SkPaint paint;
-        paint.setStyle(SkPaint::kStrokeAndFill_Style);
-        paint.setStrokeWidth(0.0f);
-        ClipRect clip(Rect(100, 200));
-        RectOp rejectOp(Rect(100, 200), Matrix4::identity(), &clip, &paint);
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect());  // Note: empty clip
-        auto bakedState = BakedOpState::tryStrokeableOpConstruct(
-                allocator, *snapshot, rejectOp, BakedOpState::StrokeBehavior::StyleDefined, false);
-
-        EXPECT_EQ(nullptr, bakedState);
-        EXPECT_GT(8u,
-                  allocator.usedSize());  // no significant allocation space used for rejected op
-    }
-    {
-        // check simple unscaled expansion
-        SkPaint paint;
-        paint.setStyle(SkPaint::kStrokeAndFill_Style);
-        paint.setStrokeWidth(10.0f);
-        ClipRect clip(Rect(200, 200));
-        RectOp rejectOp(Rect(50, 50, 150, 150), Matrix4::identity(), &clip, &paint);
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(200, 200));
-        auto bakedState = BakedOpState::tryStrokeableOpConstruct(
-                allocator, *snapshot, rejectOp, BakedOpState::StrokeBehavior::StyleDefined, false);
-
-        ASSERT_NE(nullptr, bakedState);
-        EXPECT_EQ(Rect(45, 45, 155, 155), bakedState->computedState.clippedBounds);
-        EXPECT_EQ(0, bakedState->computedState.clipSideFlags);
-    }
-    {
-        // check simple unscaled expansion, and fill style with stroke forced
-        SkPaint paint;
-        paint.setStyle(SkPaint::kFill_Style);
-        paint.setStrokeWidth(10.0f);
-        ClipRect clip(Rect(200, 200));
-        RectOp rejectOp(Rect(50, 50, 150, 150), Matrix4::identity(), &clip, &paint);
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(200, 200));
-        auto bakedState = BakedOpState::tryStrokeableOpConstruct(
-                allocator, *snapshot, rejectOp, BakedOpState::StrokeBehavior::Forced, false);
-
-        ASSERT_NE(nullptr, bakedState);
-        EXPECT_EQ(Rect(45, 45, 155, 155), bakedState->computedState.clippedBounds);
-        EXPECT_EQ(0, bakedState->computedState.clipSideFlags);
-    }
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/tests/unit/DeviceInfoTests.cpp b/libs/hwui/tests/unit/DeviceInfoTests.cpp
deleted file mode 100644
index af37938..0000000
--- a/libs/hwui/tests/unit/DeviceInfoTests.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <DeviceInfo.h>
-
-#include <gtest/gtest.h>
-#include "tests/common/TestUtils.h"
-
-using namespace android;
-using namespace android::uirenderer;
-
-OPENGL_PIPELINE_TEST(DeviceInfo, basic) {
-    // can't assert state before init - another test may have initialized the singleton
-    DeviceInfo::initialize();
-    const DeviceInfo* di = DeviceInfo::get();
-    ASSERT_NE(nullptr, di) << "DeviceInfo initialization failed";
-    EXPECT_EQ(2048, di->maxTextureSize()) << "Max texture size didn't match";
-}
diff --git a/libs/hwui/tests/unit/FontRendererTests.cpp b/libs/hwui/tests/unit/FontRendererTests.cpp
deleted file mode 100644
index c78f131..0000000
--- a/libs/hwui/tests/unit/FontRendererTests.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "GammaFontRenderer.h"
-#include "tests/common/TestUtils.h"
-
-using namespace android::uirenderer;
-
-static bool isZero(uint8_t* data, int size) {
-    for (int i = 0; i < size; i++) {
-        if (data[i]) return false;
-    }
-    return true;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, renderDropShadow) {
-    SkPaint paint;
-    paint.setTextSize(10);
-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-    GammaFontRenderer gammaFontRenderer;
-    FontRenderer& fontRenderer = gammaFontRenderer.getFontRenderer();
-    fontRenderer.setFont(&paint, SkMatrix::I());
-
-    std::vector<glyph_t> glyphs;
-    std::vector<float> positions;
-    float totalAdvance;
-    Rect bounds;
-    TestUtils::layoutTextUnscaled(paint, "This is a test", &glyphs, &positions, &totalAdvance,
-                                  &bounds);
-
-    for (int radius : {28, 20, 2}) {
-        auto result = fontRenderer.renderDropShadow(&paint, glyphs.data(), glyphs.size(), radius,
-                                                    positions.data());
-        ASSERT_NE(nullptr, result.image);
-        EXPECT_FALSE(isZero(result.image, result.width * result.height));
-        EXPECT_LE(bounds.getWidth() + radius * 2, (int)result.width);
-        EXPECT_LE(bounds.getHeight() + radius * 2, (int)result.height);
-        delete result.image;
-    }
-}
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
deleted file mode 100644
index 4eb7751..0000000
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ /dev/null
@@ -1,2705 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <BakedOpState.h>
-#include <DeferredLayerUpdater.h>
-#include <FrameBuilder.h>
-#include <GlLayer.h>
-#include <LayerUpdateQueue.h>
-#include <RecordedOp.h>
-#include <RecordingCanvas.h>
-#include <tests/common/TestUtils.h>
-
-#include <unordered_map>
-
-namespace android {
-namespace uirenderer {
-
-const FrameBuilder::LightGeometry sLightGeometry = {{100, 100, 100}, 50};
-
-/**
- * Virtual class implemented by each test to redirect static operation / state transitions to
- * virtual methods.
- *
- * Virtual dispatch allows for default behaviors to be specified (very common case in below tests),
- * and allows Renderer vs Dispatching behavior to be merged.
- *
- * onXXXOp methods fail by default - tests should override ops they expect
- * startRepaintLayer fails by default - tests should override if expected
- * startFrame/endFrame do nothing by default - tests should override to intercept
- */
-class TestRendererBase {
-public:
-    virtual ~TestRendererBase() {}
-    virtual OffscreenBuffer* startTemporaryLayer(uint32_t, uint32_t) {
-        ADD_FAILURE() << "Temporary layers not expected in this test";
-        return nullptr;
-    }
-    virtual void recycleTemporaryLayer(OffscreenBuffer*) {
-        ADD_FAILURE() << "Temporary layers not expected in this test";
-    }
-    virtual void startRepaintLayer(OffscreenBuffer*, const Rect& repaintRect) {
-        ADD_FAILURE() << "Layer repaint not expected in this test";
-    }
-    virtual void endLayer() { ADD_FAILURE() << "Layer updates not expected in this test"; }
-    virtual void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {}
-    virtual void endFrame(const Rect& repaintRect) {}
-
-// define virtual defaults for single draw methods
-#define X(Type)                                               \
-    virtual void on##Type(const Type&, const BakedOpState&) { \
-        ADD_FAILURE() << #Type " not expected in this test";  \
-    }
-    MAP_RENDERABLE_OPS(X)
-#undef X
-
-// define virtual defaults for merged draw methods
-#define X(Type)                                                         \
-    virtual void onMerged##Type##s(const MergedBakedOpList& opList) {   \
-        ADD_FAILURE() << "Merged " #Type "s not expected in this test"; \
-    }
-    MAP_MERGEABLE_OPS(X)
-#undef X
-
-    int getIndex() { return mIndex; }
-
-protected:
-    int mIndex = 0;
-};
-
-/**
- * Dispatches all static methods to similar formed methods on renderer, which fail by default but
- * are overridden by subclasses per test.
- */
-class TestDispatcher {
-public:
-// define single op methods, which redirect to TestRendererBase
-#define X(Type)                                                                                   \
-    static void on##Type(TestRendererBase& renderer, const Type& op, const BakedOpState& state) { \
-        renderer.on##Type(op, state);                                                             \
-    }
-    MAP_RENDERABLE_OPS(X);
-#undef X
-
-// define merged op methods, which redirect to TestRendererBase
-#define X(Type)                                                                                  \
-    static void onMerged##Type##s(TestRendererBase& renderer, const MergedBakedOpList& opList) { \
-        renderer.onMerged##Type##s(opList);                                                      \
-    }
-    MAP_MERGEABLE_OPS(X);
-#undef X
-};
-
-class FailRenderer : public TestRendererBase {};
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, simple) {
-    class SimpleTestRenderer : public TestRendererBase {
-    public:
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(100u, width);
-            EXPECT_EQ(200u, height);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-        }
-        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(2, mIndex++);
-        }
-        void endFrame(const Rect& repaintRect) override { EXPECT_EQ(3, mIndex++); }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                sk_sp<Bitmap> bitmap(TestUtils::createBitmap(25, 25));
-                canvas.drawRect(0, 0, 100, 200, SkPaint());
-                canvas.drawBitmap(*bitmap, 10, 10, nullptr);
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SimpleTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());  // 2 ops + start + end
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, simpleStroke) {
-    class SimpleStrokeTestRenderer : public TestRendererBase {
-    public:
-        void onPointsOp(const PointsOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            // even though initial bounds are empty...
-            EXPECT_TRUE(op.unmappedBounds.isEmpty())
-                    << "initial bounds should be empty, since they're unstroked";
-            EXPECT_EQ(Rect(45, 45, 55, 55), state.computedState.clippedBounds)
-                    << "final bounds should account for stroke";
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                SkPaint strokedPaint;
-                strokedPaint.setStrokeWidth(10);
-                canvas.drawPoint(50, 50, strokedPaint);
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SimpleStrokeTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, arcStrokeClip) {
-    class ArcStrokeClipTestRenderer : public TestRendererBase {
-    public:
-        void onArcOp(const ArcOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(25, 25, 175, 175), op.unmappedBounds);
-            EXPECT_EQ(Rect(25, 25, 175, 175), state.computedState.clippedBounds);
-            EXPECT_EQ(OpClipSideFlags::Full, state.computedState.clipSideFlags)
-                    << "Arc op clipped conservatively, since path texture may be expanded";
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.clipRect(25, 25, 175, 175, SkClipOp::kIntersect);
-                SkPaint aaPaint;
-                aaPaint.setAntiAlias(true);
-                canvas.drawArc(25, 25, 175, 175, 40, 180, true, aaPaint);
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    ArcStrokeClipTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, simpleRejection) {
-    auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [](RenderProperties& props,
-                                                                          RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(200, 200, 400, 400, SkClipOp::kIntersect);  // intersection should be empty
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-        canvas.restore();
-    });
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    FailRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, simpleBatching) {
-    const int LOOPS = 5;
-    class SimpleBatchingTestRenderer : public TestRendererBase {
-    public:
-        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-            EXPECT_TRUE(mIndex++ >= LOOPS) << "Bitmaps should be above all rects";
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_TRUE(mIndex++ < LOOPS) << "Rects should be below all bitmaps";
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-
-                sk_sp<Bitmap> bitmap(TestUtils::createBitmap(
-                        10, 10,
-                        kAlpha_8_SkColorType));  // Disable merging by using alpha 8 bitmap
-
-                // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
-                // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
-                canvas.save(SaveFlags::MatrixClip);
-                for (int i = 0; i < LOOPS; i++) {
-                    canvas.translate(0, 10);
-                    canvas.drawRect(0, 0, 10, 10, SkPaint());
-                    canvas.drawBitmap(*bitmap, 5, 0, nullptr);
-                }
-                canvas.restore();
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SimpleBatchingTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2 * LOOPS, renderer.getIndex()) << "Expect number of ops = 2 * loop count";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, deferRenderNode_translateClip) {
-    class DeferRenderNodeTranslateClipTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(5, 10, 55, 60), state.computedState.clippedBounds);
-            EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom,
-                      state.computedState.clipSideFlags);
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawRect(0, 0, 100, 100, SkPaint());
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(5, 10, Rect(50, 50),  // translate + clip node
-                                 *TestUtils::getSyncedNode(node));
-
-    DeferRenderNodeTranslateClipTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, deferRenderNodeScene) {
-    class DeferRenderNodeSceneTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            const Rect& clippedBounds = state.computedState.clippedBounds;
-            Matrix4 expected;
-            switch (mIndex++) {
-                case 0:
-                    // background - left side
-                    EXPECT_EQ(Rect(600, 100, 700, 500), clippedBounds);
-                    expected.loadTranslate(100, 100, 0);
-                    break;
-                case 1:
-                    // background - top side
-                    EXPECT_EQ(Rect(100, 400, 600, 500), clippedBounds);
-                    expected.loadTranslate(100, 100, 0);
-                    break;
-                case 2:
-                    // content
-                    EXPECT_EQ(Rect(100, 100, 700, 500), clippedBounds);
-                    expected.loadTranslate(-50, -50, 0);
-                    break;
-                case 3:
-                    // overlay
-                    EXPECT_EQ(Rect(0, 0, 800, 200), clippedBounds);
-                    break;
-                default:
-                    ADD_FAILURE() << "Too many rects observed";
-            }
-            EXPECT_EQ(expected, state.computedState.transform);
-        }
-    };
-
-    std::vector<sp<RenderNode>> nodes;
-    SkPaint transparentPaint;
-    transparentPaint.setAlpha(128);
-
-    // backdrop
-    nodes.push_back(TestUtils::createNode<RecordingCanvas>(
-            100, 100, 700, 500,  // 600x400
-            [&transparentPaint](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawRect(0, 0, 600, 400, transparentPaint);
-            }));
-
-    // content
-    Rect contentDrawBounds(150, 150, 650, 450);  // 500x300
-    nodes.push_back(TestUtils::createNode<RecordingCanvas>(
-            0, 0, 800, 600, [&transparentPaint](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawRect(0, 0, 800, 600, transparentPaint);
-            }));
-
-    // overlay
-    nodes.push_back(TestUtils::createNode<RecordingCanvas>(
-            0, 0, 800, 600, [&transparentPaint](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawRect(0, 0, 800, 200, transparentPaint);
-            }));
-
-    for (auto& node : nodes) {
-        TestUtils::syncHierarchyPropertiesAndDisplayList(node);
-    }
-
-    {
-        FrameBuilder frameBuilder(SkRect::MakeWH(800, 600), 800, 600, sLightGeometry,
-                                  Caches::getInstance());
-        frameBuilder.deferRenderNodeScene(nodes, contentDrawBounds);
-
-        DeferRenderNodeSceneTestRenderer renderer;
-        frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-        EXPECT_EQ(4, renderer.getIndex());
-    }
-
-    for (auto& node : nodes) {
-        EXPECT_TRUE(node->isValid());
-        EXPECT_FALSE(node->nothingToDraw());
-        node->setStagingDisplayList(nullptr);
-        EXPECT_FALSE(node->isValid());
-        EXPECT_FALSE(node->nothingToDraw());
-        node->destroyHardwareResources();
-        EXPECT_TRUE(node->nothingToDraw());
-        EXPECT_FALSE(node->isValid());
-    }
-
-    {
-        // Validate no crashes if any nodes are missing DisplayLists
-        FrameBuilder frameBuilder(SkRect::MakeWH(800, 600), 800, 600, sLightGeometry,
-                                  Caches::getInstance());
-        frameBuilder.deferRenderNodeScene(nodes, contentDrawBounds);
-
-        FailRenderer renderer;
-        frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    }
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, empty_noFbo0) {
-    class EmptyNoFbo0TestRenderer : public TestRendererBase {
-    public:
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            ADD_FAILURE() << "Primary frame draw not expected in this test";
-        }
-        void endFrame(const Rect& repaintRect) override {
-            ADD_FAILURE() << "Primary frame draw not expected in this test";
-        }
-    };
-
-    // Use layer update constructor, so no work is enqueued for Fbo0
-    LayerUpdateQueue emptyLayerUpdateQueue;
-    FrameBuilder frameBuilder(emptyLayerUpdateQueue, sLightGeometry, Caches::getInstance());
-    EmptyNoFbo0TestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, empty_withFbo0) {
-    class EmptyWithFbo0TestRenderer : public TestRendererBase {
-    public:
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            EXPECT_EQ(0, mIndex++);
-        }
-        void endFrame(const Rect& repaintRect) override { EXPECT_EQ(1, mIndex++); }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            10, 10, 110, 110, [](RenderProperties& props, RecordingCanvas& canvas) {
-                // no drawn content
-            });
-
-    // Draw, but pass node without draw content, so no work is done for primary frame
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    EmptyWithFbo0TestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex()) << "No drawing content produced,"
-                                         " but fbo0 update lifecycle should still be observed";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, avoidOverdraw_rects) {
-    class AvoidOverdrawRectsTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(mIndex++, 0) << "Should be one rect";
-            EXPECT_EQ(Rect(10, 10, 190, 190), op.unmappedBounds)
-                    << "Last rect should occlude others.";
-        }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawRect(0, 0, 200, 200, SkPaint());
-                canvas.drawRect(0, 0, 200, 200, SkPaint());
-                canvas.drawRect(10, 10, 190, 190, SkPaint());
-            });
-
-    // Damage (and therefore clip) is same as last draw, subset of renderable area.
-    // This means last op occludes other contents, and they'll be rejected to avoid overdraw.
-    FrameBuilder frameBuilder(SkRect::MakeLTRB(10, 10, 190, 190), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    EXPECT_EQ(3u, node->getDisplayList()->getOps().size())
-            << "Recording must not have rejected ops, in order for this test to be valid";
-
-    AvoidOverdrawRectsTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex()) << "Expect exactly one op";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, avoidOverdraw_bitmaps) {
-    static sk_sp<Bitmap> opaqueBitmap(
-            TestUtils::createBitmap(50, 50, SkColorType::kRGB_565_SkColorType));
-    static sk_sp<Bitmap> transpBitmap(
-            TestUtils::createBitmap(50, 50, SkColorType::kAlpha_8_SkColorType));
-    class AvoidOverdrawBitmapsTestRenderer : public TestRendererBase {
-    public:
-        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-            switch (mIndex++) {
-                case 0:
-                    EXPECT_EQ(opaqueBitmap.get(), op.bitmap);
-                    break;
-                case 1:
-                    EXPECT_EQ(transpBitmap.get(), op.bitmap);
-                    break;
-                default:
-                    ADD_FAILURE() << "Only two ops expected.";
-            }
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 50, 50, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawRect(0, 0, 50, 50, SkPaint());
-                canvas.drawRect(0, 0, 50, 50, SkPaint());
-                canvas.drawBitmap(*transpBitmap, 0, 0, nullptr);
-
-                // only the below draws should remain, since they're
-                canvas.drawBitmap(*opaqueBitmap, 0, 0, nullptr);
-                canvas.drawBitmap(*transpBitmap, 0, 0, nullptr);
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(50, 50), 50, 50, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    EXPECT_EQ(5u, node->getDisplayList()->getOps().size())
-            << "Recording must not have rejected ops, in order for this test to be valid";
-
-    AvoidOverdrawBitmapsTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex()) << "Expect exactly two ops";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, clippedMerging) {
-    class ClippedMergingTestRenderer : public TestRendererBase {
-    public:
-        void onMergedBitmapOps(const MergedBakedOpList& opList) override {
-            EXPECT_EQ(0, mIndex);
-            mIndex += opList.count;
-            EXPECT_EQ(4u, opList.count);
-            EXPECT_EQ(Rect(10, 10, 90, 90), opList.clip);
-            EXPECT_EQ(OpClipSideFlags::Left | OpClipSideFlags::Top | OpClipSideFlags::Right,
-                      opList.clipSideFlags);
-        }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                sk_sp<Bitmap> bitmap(TestUtils::createBitmap(20, 20));
-
-                // left side clipped (to inset left half)
-                canvas.clipRect(10, 0, 50, 100, SkClipOp::kReplace_deprecated);
-                canvas.drawBitmap(*bitmap, 0, 40, nullptr);
-
-                // top side clipped (to inset top half)
-                canvas.clipRect(0, 10, 100, 50, SkClipOp::kReplace_deprecated);
-                canvas.drawBitmap(*bitmap, 40, 0, nullptr);
-
-                // right side clipped (to inset right half)
-                canvas.clipRect(50, 0, 90, 100, SkClipOp::kReplace_deprecated);
-                canvas.drawBitmap(*bitmap, 80, 40, nullptr);
-
-                // bottom not clipped, just abutting (inset bottom half)
-                canvas.clipRect(0, 50, 100, 90, SkClipOp::kReplace_deprecated);
-                canvas.drawBitmap(*bitmap, 40, 70, nullptr);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    ClippedMergingTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, regionClipStopsMerge) {
-    class RegionClipStopsMergeTestRenderer : public TestRendererBase {
-    public:
-        void onTextOp(const TextOp& op, const BakedOpState& state) override { mIndex++; }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400, [](RenderProperties& props, RecordingCanvas& canvas) {
-                SkPath path;
-                path.addCircle(200, 200, 200, SkPath::kCW_Direction);
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.clipPath(&path, SkClipOp::kIntersect);
-                SkPaint paint;
-                paint.setAntiAlias(true);
-                paint.setTextSize(50);
-                TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100);
-                TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 200);
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(400, 400), 400, 400, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    RegionClipStopsMergeTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, textMerging) {
-    class TextMergingTestRenderer : public TestRendererBase {
-    public:
-        void onMergedTextOps(const MergedBakedOpList& opList) override {
-            EXPECT_EQ(0, mIndex);
-            mIndex += opList.count;
-            EXPECT_EQ(2u, opList.count);
-            EXPECT_EQ(OpClipSideFlags::Top, opList.clipSideFlags);
-            EXPECT_EQ(OpClipSideFlags::Top, opList.states[0]->computedState.clipSideFlags);
-            EXPECT_EQ(OpClipSideFlags::None, opList.states[1]->computedState.clipSideFlags);
-        }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 400, 400, [](RenderProperties& props,
-                                                                          RecordingCanvas& canvas) {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(50);
-        TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 0);  // will be top clipped
-        TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100);  // not clipped
-    });
-    FrameBuilder frameBuilder(SkRect::MakeWH(400, 400), 400, 400, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    TextMergingTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex()) << "Expect 2 ops";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, textStrikethrough) {
-    const int LOOPS = 5;
-    class TextStrikethroughTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_TRUE(mIndex++ >= LOOPS) << "Strikethrough rects should be above all text";
-        }
-        void onMergedTextOps(const MergedBakedOpList& opList) override {
-            EXPECT_EQ(0, mIndex);
-            mIndex += opList.count;
-            EXPECT_EQ(5u, opList.count);
-        }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 2000, [](RenderProperties& props, RecordingCanvas& canvas) {
-                SkPaint textPaint;
-                textPaint.setAntiAlias(true);
-                textPaint.setTextSize(20);
-                textPaint.setFlags(textPaint.getFlags() | SkPaint::kStrikeThruText_ReserveFlag);
-                for (int i = 0; i < LOOPS; i++) {
-                    TestUtils::drawUtf8ToCanvas(&canvas, "test text", textPaint, 10, 100 * (i + 1));
-                }
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 2000), 200, 2000, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    TextStrikethroughTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2 * LOOPS, renderer.getIndex()) << "Expect number of ops = 2 * loop count";
-}
-
-static auto styles = {SkPaint::kFill_Style, SkPaint::kStroke_Style, SkPaint::kStrokeAndFill_Style};
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, textStyle) {
-    class TextStyleTestRenderer : public TestRendererBase {
-    public:
-        void onMergedTextOps(const MergedBakedOpList& opList) override {
-            ASSERT_EQ(0, mIndex);
-            ASSERT_EQ(3u, opList.count);
-            mIndex += opList.count;
-
-            int index = 0;
-            for (auto style : styles) {
-                auto state = opList.states[index++];
-                ASSERT_EQ(style, state->op->paint->getStyle())
-                        << "Remainder of validation relies upon stable merged order";
-                ASSERT_EQ(0, state->computedState.clipSideFlags)
-                        << "Clipped bounds validation requires unclipped ops";
-            }
-
-            Rect fill = opList.states[0]->computedState.clippedBounds;
-            Rect stroke = opList.states[1]->computedState.clippedBounds;
-            EXPECT_EQ(stroke, opList.states[2]->computedState.clippedBounds)
-                    << "Stroke+Fill should be same as stroke";
-
-            EXPECT_TRUE(stroke.contains(fill));
-            EXPECT_FALSE(fill.contains(stroke));
-
-            // outset by half the stroke width
-            Rect outsetFill(fill);
-            outsetFill.outset(5);
-            EXPECT_EQ(stroke, outsetFill);
-        }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400, [](RenderProperties& props, RecordingCanvas& canvas) {
-                SkPaint paint;
-                paint.setAntiAlias(true);
-                paint.setTextSize(50);
-                paint.setStrokeWidth(10);
-
-                // draw 3 copies of the same text overlapping, each with a different style.
-                // They'll get merged, but with
-                for (auto style : styles) {
-                    paint.setStyle(style);
-                    TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100);
-                }
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(400, 400), 400, 400, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    TextStyleTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex()) << "Expect 3 ops";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, textureLayer_clipLocalMatrix) {
-    class TextureLayerClipLocalMatrixTestRenderer : public TestRendererBase {
-    public:
-        void onTextureLayerOp(const TextureLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(50, 50, 150, 150), state.computedState.clipRect());
-            EXPECT_EQ(Rect(50, 50, 105, 105), state.computedState.clippedBounds);
-
-            Matrix4 expected;
-            expected.loadTranslate(5, 5, 0);
-            EXPECT_MATRIX_APPROX_EQ(expected, state.computedState.transform);
-        }
-    };
-
-    auto layerUpdater =
-            TestUtils::createTextureLayerUpdater(renderThread, 100, 100, SkMatrix::MakeTrans(5, 5));
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.clipRect(50, 50, 150, 150, SkClipOp::kIntersect);
-                canvas.drawLayer(layerUpdater.get());
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    TextureLayerClipLocalMatrixTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, textureLayer_combineMatrices) {
-    class TextureLayerCombineMatricesTestRenderer : public TestRendererBase {
-    public:
-        void onTextureLayerOp(const TextureLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-
-            Matrix4 expected;
-            expected.loadTranslate(35, 45, 0);
-            EXPECT_MATRIX_APPROX_EQ(expected, state.computedState.transform);
-        }
-    };
-
-    auto layerUpdater =
-            TestUtils::createTextureLayerUpdater(renderThread, 100, 100, SkMatrix::MakeTrans(5, 5));
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.translate(30, 40);
-                canvas.drawLayer(layerUpdater.get());
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    TextureLayerCombineMatricesTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, textureLayer_reject) {
-    auto layerUpdater =
-            TestUtils::createTextureLayerUpdater(renderThread, 100, 100, SkMatrix::MakeTrans(5, 5));
-    EXPECT_EQ(Layer::Api::OpenGL, layerUpdater->backingLayer()->getApi());
-
-    GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
-    glLayer->setRenderTarget(GL_NONE);  // Should be rejected
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.drawLayer(layerUpdater.get());
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    FailRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, functor_reject) {
-    class FunctorTestRenderer : public TestRendererBase {
-    public:
-        void onFunctorOp(const FunctorOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-        }
-    };
-    Functor noopFunctor;
-
-    // 1 million pixel tall view, scrolled down 80%
-    auto scrolledFunctorView = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 1000000, [&noopFunctor](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.translate(0, -800000);
-                canvas.callDrawGLFunction(&noopFunctor, nullptr);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(scrolledFunctorView));
-
-    FunctorTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, deferColorOp_unbounded) {
-    class ColorTestRenderer : public TestRendererBase {
-    public:
-        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(200, 200), state.computedState.clippedBounds)
-                    << "Color op should be expanded to bounds of surrounding";
-        }
-    };
-
-    auto unclippedColorView = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 10, 10, [](RenderProperties& props, RecordingCanvas& canvas) {
-                props.setClipToBounds(false);
-                canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(unclippedColorView));
-
-    ColorTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex()) << "ColorOp should not be rejected";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderNode) {
-    class RenderNodeTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            switch (mIndex++) {
-                case 0:
-                    EXPECT_EQ(Rect(200, 200), state.computedState.clippedBounds);
-                    EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
-                    break;
-                case 1:
-                    EXPECT_EQ(Rect(50, 50, 150, 150), state.computedState.clippedBounds);
-                    EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
-                    break;
-                default:
-                    ADD_FAILURE();
-            }
-        }
-    };
-
-    auto child = TestUtils::createNode<RecordingCanvas>(
-            10, 10, 110, 110, [](RenderProperties& props, RecordingCanvas& canvas) {
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [&child](RenderProperties& props, RecordingCanvas& canvas) {
-                SkPaint paint;
-                paint.setColor(SK_ColorDKGRAY);
-                canvas.drawRect(0, 0, 200, 200, paint);
-
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.translate(40, 40);
-                canvas.drawRenderNode(child.get());
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    RenderNodeTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, clipped) {
-    class ClippedTestRenderer : public TestRendererBase {
-    public:
-        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clippedBounds);
-            EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clipRect());
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                sk_sp<Bitmap> bitmap(TestUtils::createBitmap(200, 200));
-                canvas.drawBitmap(*bitmap, 0, 0, nullptr);
-            });
-
-    // clip to small area, should see in receiver
-    FrameBuilder frameBuilder(SkRect::MakeLTRB(10, 20, 30, 40), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    ClippedTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayer_simple) {
-    class SaveLayerSimpleTestRenderer : public TestRendererBase {
-    public:
-        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(180u, width);
-            EXPECT_EQ(180u, height);
-            return nullptr;
-        }
-        void endLayer() override { EXPECT_EQ(2, mIndex++); }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            EXPECT_EQ(Rect(10, 10, 190, 190), op.unmappedBounds);
-            EXPECT_EQ(Rect(180, 180), state.computedState.clippedBounds);
-            EXPECT_EQ(Rect(180, 180), state.computedState.clipRect());
-
-            Matrix4 expectedTransform;
-            expectedTransform.loadTranslate(-10, -10, 0);
-            EXPECT_MATRIX_APPROX_EQ(expectedTransform, state.computedState.transform);
-        }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(3, mIndex++);
-            EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds);
-            EXPECT_EQ(Rect(200, 200), state.computedState.clipRect());
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-        void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
-            EXPECT_EQ(4, mIndex++);
-            EXPECT_EQ(nullptr, offscreenBuffer);
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.saveLayerAlpha(10, 10, 190, 190, 128, SaveFlags::ClipToLayer);
-                canvas.drawRect(10, 10, 190, 190, SkPaint());
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerSimpleTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(5, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayer_nested) {
-    /* saveLayer1 { rect1, saveLayer2 { rect2 } } will play back as:
-     * - startTemporaryLayer2, rect2 endLayer2
-     * - startTemporaryLayer1, rect1, drawLayer2, endLayer1
-     * - startFrame, layerOp1, endFrame
-     */
-    class SaveLayerNestedTestRenderer : public TestRendererBase {
-    public:
-        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
-            const int index = mIndex++;
-            if (index == 0) {
-                EXPECT_EQ(400u, width);
-                EXPECT_EQ(400u, height);
-                return (OffscreenBuffer*)0x400;
-            } else if (index == 3) {
-                EXPECT_EQ(800u, width);
-                EXPECT_EQ(800u, height);
-                return (OffscreenBuffer*)0x800;
-            } else {
-                ADD_FAILURE();
-            }
-            return (OffscreenBuffer*)nullptr;
-        }
-        void endLayer() override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 2 || index == 6);
-        }
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            EXPECT_EQ(7, mIndex++);
-        }
-        void endFrame(const Rect& repaintRect) override { EXPECT_EQ(9, mIndex++); }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            const int index = mIndex++;
-            if (index == 1) {
-                EXPECT_EQ(Rect(400, 400), op.unmappedBounds);  // inner rect
-            } else if (index == 4) {
-                EXPECT_EQ(Rect(800, 800), op.unmappedBounds);  // outer rect
-            } else {
-                ADD_FAILURE();
-            }
-        }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            const int index = mIndex++;
-            if (index == 5) {
-                EXPECT_EQ((OffscreenBuffer*)0x400, *op.layerHandle);
-                EXPECT_EQ(Rect(400, 400), op.unmappedBounds);  // inner layer
-            } else if (index == 8) {
-                EXPECT_EQ((OffscreenBuffer*)0x800, *op.layerHandle);
-                EXPECT_EQ(Rect(800, 800), op.unmappedBounds);  // outer layer
-            } else {
-                ADD_FAILURE();
-            }
-        }
-        void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
-            const int index = mIndex++;
-            // order isn't important, but we need to see both
-            if (index == 10) {
-                EXPECT_EQ((OffscreenBuffer*)0x400, offscreenBuffer);
-            } else if (index == 11) {
-                EXPECT_EQ((OffscreenBuffer*)0x800, offscreenBuffer);
-            } else {
-                ADD_FAILURE();
-            }
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 800, 800, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.saveLayerAlpha(0, 0, 800, 800, 128, SaveFlags::ClipToLayer);
-                {
-                    canvas.drawRect(0, 0, 800, 800, SkPaint());
-                    canvas.saveLayerAlpha(0, 0, 400, 400, 128, SaveFlags::ClipToLayer);
-                    { canvas.drawRect(0, 0, 400, 400, SkPaint()); }
-                    canvas.restore();
-                }
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(800, 800), 800, 800, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerNestedTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(12, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayer_contentRejection) {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.clipRect(200, 200, 400, 400, SkClipOp::kIntersect);
-                canvas.saveLayerAlpha(200, 200, 400, 400, 128, SaveFlags::ClipToLayer);
-
-                // draw within save layer may still be recorded, but shouldn't be drawn
-                canvas.drawRect(200, 200, 400, 400, SkPaint());
-
-                canvas.restore();
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    FailRenderer renderer;
-    // should see no ops, even within the layer, since the layer should be rejected
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayerUnclipped_simple) {
-    class SaveLayerUnclippedSimpleTestRenderer : public TestRendererBase {
-    public:
-        void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds);
-            EXPECT_CLIP_RECT(Rect(200, 200), state.computedState.clipState);
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-        void onSimpleRectsOp(const SimpleRectsOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            ASSERT_NE(nullptr, op.paint);
-            ASSERT_EQ(SkBlendMode::kClear, PaintUtils::getBlendModeDirect(op.paint));
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(2, mIndex++);
-            EXPECT_EQ(Rect(200, 200), op.unmappedBounds);
-            EXPECT_EQ(Rect(200, 200), state.computedState.clippedBounds);
-            EXPECT_EQ(Rect(200, 200), state.computedState.clipRect());
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-        void onCopyFromLayerOp(const CopyFromLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(3, mIndex++);
-            EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds);
-            EXPECT_CLIP_RECT(Rect(200, 200), state.computedState.clipState);
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SaveFlags::Flags)(0));
-                canvas.drawRect(0, 0, 200, 200, SkPaint());
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerUnclippedSimpleTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayerUnclipped_round) {
-    class SaveLayerUnclippedRoundTestRenderer : public TestRendererBase {
-    public:
-        void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds)
-                    << "Bounds rect should round out";
-        }
-        void onSimpleRectsOp(const SimpleRectsOp& op, const BakedOpState& state) override {}
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {}
-        void onCopyFromLayerOp(const CopyFromLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds)
-                    << "Bounds rect should round out";
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [](RenderProperties& props,
-                                                                          RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10.95f, 10.5f, 189.75f, 189.25f,  // values should all round out
-                              128, (SaveFlags::Flags)(0));
-        canvas.drawRect(0, 0, 200, 200, SkPaint());
-        canvas.restore();
-    });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerUnclippedRoundTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayerUnclipped_mergedClears) {
-    class SaveLayerUnclippedMergedClearsTestRenderer : public TestRendererBase {
-    public:
-        void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            EXPECT_GT(4, index);
-            EXPECT_EQ(5, op.unmappedBounds.getWidth());
-            EXPECT_EQ(5, op.unmappedBounds.getHeight());
-            if (index == 0) {
-                EXPECT_EQ(Rect(10, 10), state.computedState.clippedBounds);
-            } else if (index == 1) {
-                EXPECT_EQ(Rect(190, 0, 200, 10), state.computedState.clippedBounds);
-            } else if (index == 2) {
-                EXPECT_EQ(Rect(0, 190, 10, 200), state.computedState.clippedBounds);
-            } else if (index == 3) {
-                EXPECT_EQ(Rect(190, 190, 200, 200), state.computedState.clippedBounds);
-            }
-        }
-        void onSimpleRectsOp(const SimpleRectsOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(4, mIndex++);
-            ASSERT_EQ(op.vertexCount, 16u);
-            for (size_t i = 0; i < op.vertexCount; i++) {
-                auto v = op.vertices[i];
-                EXPECT_TRUE(v.x == 0 || v.x == 10 || v.x == 190 || v.x == 200);
-                EXPECT_TRUE(v.y == 0 || v.y == 10 || v.y == 190 || v.y == 200);
-            }
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(5, mIndex++);
-        }
-        void onCopyFromLayerOp(const CopyFromLayerOp& op, const BakedOpState& state) override {
-            EXPECT_LT(5, mIndex++);
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-
-                int restoreTo = canvas.save(SaveFlags::MatrixClip);
-                canvas.scale(2, 2);
-                canvas.saveLayerAlpha(0, 0, 5, 5, 128, SaveFlags::MatrixClip);
-                canvas.saveLayerAlpha(95, 0, 100, 5, 128, SaveFlags::MatrixClip);
-                canvas.saveLayerAlpha(0, 95, 5, 100, 128, SaveFlags::MatrixClip);
-                canvas.saveLayerAlpha(95, 95, 100, 100, 128, SaveFlags::MatrixClip);
-                canvas.drawRect(0, 0, 100, 100, SkPaint());
-                canvas.restoreToCount(restoreTo);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerUnclippedMergedClearsTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(10, renderer.getIndex())
-            << "Expect 4 copyTos, 4 copyFroms, 1 clear SimpleRects, and 1 rect.";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayerUnclipped_clearClip) {
-    class SaveLayerUnclippedClearClipTestRenderer : public TestRendererBase {
-    public:
-        void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-        }
-        void onSimpleRectsOp(const SimpleRectsOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            ASSERT_NE(nullptr, op.paint);
-            EXPECT_EQ(SkBlendMode::kClear, PaintUtils::getBlendModeDirect(op.paint));
-            EXPECT_EQ(Rect(50, 50, 150, 150), state.computedState.clippedBounds)
-                    << "Expect dirty rect as clip";
-            ASSERT_NE(nullptr, state.computedState.clipState);
-            EXPECT_EQ(Rect(50, 50, 150, 150), state.computedState.clipState->rect);
-            EXPECT_EQ(ClipMode::Rectangle, state.computedState.clipState->mode);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(2, mIndex++);
-        }
-        void onCopyFromLayerOp(const CopyFromLayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(3, mIndex++);
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                // save smaller than clip, so we get unclipped behavior
-                canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SaveFlags::Flags)(0));
-                canvas.drawRect(0, 0, 200, 200, SkPaint());
-                canvas.restore();
-            });
-
-    // draw with partial screen dirty, and assert we see that rect later
-    FrameBuilder frameBuilder(SkRect::MakeLTRB(50, 50, 150, 150), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerUnclippedClearClipTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayerUnclipped_reject) {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                // unclipped savelayer + rect both in area that won't intersect with dirty
-                canvas.saveLayerAlpha(100, 100, 200, 200, 128, (SaveFlags::Flags)(0));
-                canvas.drawRect(100, 100, 200, 200, SkPaint());
-                canvas.restore();
-            });
-
-    // draw with partial screen dirty that doesn't intersect with savelayer
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    FailRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-}
-
-/* saveLayerUnclipped { saveLayer { saveLayerUnclipped { rect } } } will play back as:
- * - startTemporaryLayer, onCopyToLayer, onSimpleRects, onRect, onCopyFromLayer, endLayer
- * - startFrame, onCopyToLayer, onSimpleRects, drawLayer, onCopyFromLayer, endframe
- */
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, saveLayerUnclipped_complex) {
-    class SaveLayerUnclippedComplexTestRenderer : public TestRendererBase {
-    public:
-        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) {
-            EXPECT_EQ(0, mIndex++);  // savelayer first
-            return (OffscreenBuffer*)0xabcd;
-        }
-        void onCopyToLayerOp(const CopyToLayerOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 1 || index == 7);
-        }
-        void onSimpleRectsOp(const SimpleRectsOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 2 || index == 8);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(3, mIndex++);
-            Matrix4 expected;
-            expected.loadTranslate(-100, -100, 0);
-            EXPECT_EQ(Rect(100, 100, 200, 200), state.computedState.clippedBounds);
-            EXPECT_MATRIX_APPROX_EQ(expected, state.computedState.transform);
-        }
-        void onCopyFromLayerOp(const CopyFromLayerOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 4 || index == 10);
-        }
-        void endLayer() override { EXPECT_EQ(5, mIndex++); }
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            EXPECT_EQ(6, mIndex++);
-        }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(9, mIndex++);
-            EXPECT_EQ((OffscreenBuffer*)0xabcd, *op.layerHandle);
-        }
-        void endFrame(const Rect& repaintRect) override { EXPECT_EQ(11, mIndex++); }
-        void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
-            EXPECT_EQ(12, mIndex++);
-            EXPECT_EQ((OffscreenBuffer*)0xabcd, offscreenBuffer);
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 600, 600,  // 500x500 triggers clipping
-            [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.saveLayerAlpha(0, 0, 500, 500, 128, (SaveFlags::Flags)0);  // unclipped
-                canvas.saveLayerAlpha(100, 100, 400, 400, 128, SaveFlags::ClipToLayer);  // clipped
-                canvas.saveLayerAlpha(200, 200, 300, 300, 128, (SaveFlags::Flags)0);  // unclipped
-                canvas.drawRect(200, 200, 300, 300, SkPaint());
-                canvas.restore();
-                canvas.restore();
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(600, 600), 600, 600, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    SaveLayerUnclippedComplexTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(13, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, hwLayer_simple) {
-    class HwLayerSimpleTestRenderer : public TestRendererBase {
-    public:
-        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(100u, offscreenBuffer->viewportWidth);
-            EXPECT_EQ(100u, offscreenBuffer->viewportHeight);
-            EXPECT_EQ(Rect(25, 25, 75, 75), repaintRect);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-
-            EXPECT_TRUE(state.computedState.transform.isIdentity())
-                    << "Transform should be reset within layer";
-
-            EXPECT_EQ(Rect(25, 25, 75, 75), state.computedState.clipRect())
-                    << "Damage rect should be used to clip layer content";
-        }
-        void endLayer() override { EXPECT_EQ(2, mIndex++); }
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            EXPECT_EQ(3, mIndex++);
-        }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(4, mIndex++);
-        }
-        void endFrame(const Rect& repaintRect) override { EXPECT_EQ(5, mIndex++); }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            10, 10, 110, 110, [](RenderProperties& props, RecordingCanvas& canvas) {
-                props.mutateLayerProperties().setType(LayerType::RenderLayer);
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-    OffscreenBuffer** layerHandle = node->getLayerHandle();
-
-    // create RenderNode's layer here in same way prepareTree would
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
-    *layerHandle = &layer;
-
-    auto syncedNode = TestUtils::getSyncedNode(node);
-
-    // only enqueue partial damage
-    LayerUpdateQueue layerUpdateQueue;  // Note: enqueue damage post-sync, so bounds are valid
-    layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(25, 25, 75, 75));
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferLayers(layerUpdateQueue);
-    frameBuilder.deferRenderNode(*syncedNode);
-
-    HwLayerSimpleTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(6, renderer.getIndex());
-
-    // clean up layer pointer, so we can safely destruct RenderNode
-    *layerHandle = nullptr;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, hwLayer_complex) {
-    /* parentLayer { greyRect, saveLayer { childLayer { whiteRect } } } will play back as:
-     * - startRepaintLayer(child), rect(grey), endLayer
-     * - startTemporaryLayer, drawLayer(child), endLayer
-     * - startRepaintLayer(parent), rect(white), drawLayer(saveLayer), endLayer
-     * - startFrame, drawLayer(parent), endLayerb
-     */
-    class HwLayerComplexTestRenderer : public TestRendererBase {
-    public:
-        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) {
-            EXPECT_EQ(3, mIndex++);  // savelayer first
-            return (OffscreenBuffer*)0xabcd;
-        }
-        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
-            int index = mIndex++;
-            if (index == 0) {
-                // starting inner layer
-                EXPECT_EQ(100u, offscreenBuffer->viewportWidth);
-                EXPECT_EQ(100u, offscreenBuffer->viewportHeight);
-            } else if (index == 6) {
-                // starting outer layer
-                EXPECT_EQ(200u, offscreenBuffer->viewportWidth);
-                EXPECT_EQ(200u, offscreenBuffer->viewportHeight);
-            } else {
-                ADD_FAILURE();
-            }
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            if (index == 1) {
-                // inner layer's rect (white)
-                EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
-            } else if (index == 7) {
-                // outer layer's rect (grey)
-                EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
-            } else {
-                ADD_FAILURE();
-            }
-        }
-        void endLayer() override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 2 || index == 5 || index == 9);
-        }
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            EXPECT_EQ(10, mIndex++);
-        }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            OffscreenBuffer* layer = *op.layerHandle;
-            int index = mIndex++;
-            if (index == 4) {
-                EXPECT_EQ(100u, layer->viewportWidth);
-                EXPECT_EQ(100u, layer->viewportHeight);
-            } else if (index == 8) {
-                EXPECT_EQ((OffscreenBuffer*)0xabcd, *op.layerHandle);
-            } else if (index == 11) {
-                EXPECT_EQ(200u, layer->viewportWidth);
-                EXPECT_EQ(200u, layer->viewportHeight);
-            } else {
-                ADD_FAILURE();
-            }
-        }
-        void endFrame(const Rect& repaintRect) override { EXPECT_EQ(12, mIndex++); }
-        void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
-            EXPECT_EQ(13, mIndex++);
-        }
-    };
-
-    auto child = TestUtils::createNode<RecordingCanvas>(
-            50, 50, 150, 150, [](RenderProperties& props, RecordingCanvas& canvas) {
-                props.mutateLayerProperties().setType(LayerType::RenderLayer);
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-    OffscreenBuffer childLayer(renderThread.renderState(), Caches::getInstance(), 100, 100);
-    *(child->getLayerHandle()) = &childLayer;
-
-    RenderNode* childPtr = child.get();
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [childPtr](RenderProperties& props, RecordingCanvas& canvas) {
-                props.mutateLayerProperties().setType(LayerType::RenderLayer);
-                SkPaint paint;
-                paint.setColor(SK_ColorDKGRAY);
-                canvas.drawRect(0, 0, 200, 200, paint);
-
-                canvas.saveLayerAlpha(50, 50, 150, 150, 128, SaveFlags::ClipToLayer);
-                canvas.drawRenderNode(childPtr);
-                canvas.restore();
-            });
-    OffscreenBuffer parentLayer(renderThread.renderState(), Caches::getInstance(), 200, 200);
-    *(parent->getLayerHandle()) = &parentLayer;
-
-    auto syncedNode = TestUtils::getSyncedNode(parent);
-
-    LayerUpdateQueue layerUpdateQueue;  // Note: enqueue damage post-sync, so bounds are valid
-    layerUpdateQueue.enqueueLayerWithDamage(child.get(), Rect(100, 100));
-    layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(200, 200));
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferLayers(layerUpdateQueue);
-    frameBuilder.deferRenderNode(*syncedNode);
-
-    HwLayerComplexTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(14, renderer.getIndex());
-
-    // clean up layer pointers, so we can safely destruct RenderNodes
-    *(child->getLayerHandle()) = nullptr;
-    *(parent->getLayerHandle()) = nullptr;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, buildLayer) {
-    class BuildLayerTestRenderer : public TestRendererBase {
-    public:
-        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(100u, offscreenBuffer->viewportWidth);
-            EXPECT_EQ(100u, offscreenBuffer->viewportHeight);
-            EXPECT_EQ(Rect(25, 25, 75, 75), repaintRect);
-        }
-        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-
-            EXPECT_TRUE(state.computedState.transform.isIdentity())
-                    << "Transform should be reset within layer";
-
-            EXPECT_EQ(Rect(25, 25, 75, 75), state.computedState.clipRect())
-                    << "Damage rect should be used to clip layer content";
-        }
-        void endLayer() override { EXPECT_EQ(2, mIndex++); }
-        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
-            ADD_FAILURE() << "Primary frame draw not expected in this test";
-        }
-        void endFrame(const Rect& repaintRect) override {
-            ADD_FAILURE() << "Primary frame draw not expected in this test";
-        }
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            10, 10, 110, 110, [](RenderProperties& props, RecordingCanvas& canvas) {
-                props.mutateLayerProperties().setType(LayerType::RenderLayer);
-                canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
-            });
-    OffscreenBuffer** layerHandle = node->getLayerHandle();
-
-    // create RenderNode's layer here in same way prepareTree would
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
-    *layerHandle = &layer;
-
-    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
-
-    // only enqueue partial damage
-    LayerUpdateQueue layerUpdateQueue;  // Note: enqueue damage post-sync, so bounds are valid
-    layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(25, 25, 75, 75));
-
-    // Draw, but pass empty node list, so no work is done for primary frame
-    FrameBuilder frameBuilder(layerUpdateQueue, sLightGeometry, Caches::getInstance());
-    BuildLayerTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-
-    // clean up layer pointer, so we can safely destruct RenderNode
-    *layerHandle = nullptr;
-}
-
-namespace {
-
-static void drawOrderedRect(Canvas* canvas, uint8_t expectedDrawOrder) {
-    SkPaint paint;
-    // order put in blue channel, transparent so overlapped content doesn't get rejected
-    paint.setColor(SkColorSetARGB(1, 0, 0, expectedDrawOrder));
-    canvas->drawRect(0, 0, 100, 100, paint);
-}
-static void drawOrderedNode(Canvas* canvas, uint8_t expectedDrawOrder, float z) {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [expectedDrawOrder](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedRect(&canvas, expectedDrawOrder);
-            });
-    node->mutateStagingProperties().setTranslationZ(z);
-    node->setPropertyFieldsDirty(RenderNode::TRANSLATION_Z);
-    canvas->drawRenderNode(node.get());  // canvas takes reference/sole ownership
-}
-
-static void drawOrderedNode(
-        Canvas* canvas, uint8_t expectedDrawOrder,
-        std::function<void(RenderProperties& props, RecordingCanvas& canvas)> setup) {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100,
-            [expectedDrawOrder, setup](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedRect(&canvas, expectedDrawOrder);
-                if (setup) {
-                    setup(props, canvas);
-                }
-            });
-    canvas->drawRenderNode(node.get());  // canvas takes reference/sole ownership
-}
-
-class ZReorderTestRenderer : public TestRendererBase {
-public:
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        int expectedOrder = SkColorGetB(op.paint->getColor());  // extract order from blue channel
-        EXPECT_EQ(expectedOrder, mIndex++) << "An op was drawn out of order";
-    }
-};
-
-}  // end anonymous namespace
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, zReorder) {
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.insertReorderBarrier(true);
-                canvas.insertReorderBarrier(false);
-                drawOrderedNode(&canvas, 0,
-                                10.0f);  // in reorder=false at this point, so played inorder
-                drawOrderedRect(&canvas, 1);
-                canvas.insertReorderBarrier(true);
-                drawOrderedNode(&canvas, 6, 2.0f);
-                drawOrderedRect(&canvas, 3);
-                drawOrderedNode(&canvas, 4, 0.0f);
-                drawOrderedRect(&canvas, 5);
-                drawOrderedNode(&canvas, 2, -2.0f);
-                drawOrderedNode(&canvas, 7, 2.0f);
-                canvas.insertReorderBarrier(false);
-                drawOrderedRect(&canvas, 8);
-                drawOrderedNode(&canvas, 9,
-                                -10.0f);  // in reorder=false at this point, so played inorder
-                canvas.insertReorderBarrier(true);  // reorder a node ahead of drawrect op
-                drawOrderedRect(&canvas, 11);
-                drawOrderedNode(&canvas, 10, -1.0f);
-                canvas.insertReorderBarrier(false);
-                canvas.insertReorderBarrier(true);  // test with two empty reorder sections
-                canvas.insertReorderBarrier(true);
-                canvas.insertReorderBarrier(false);
-                drawOrderedRect(&canvas, 12);
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(13, renderer.getIndex());
-};
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorder) {
-    static const int scrollX = 5;
-    static const int scrollY = 10;
-    class ProjectionReorderTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            const int index = mIndex++;
-
-            Matrix4 expectedMatrix;
-            switch (index) {
-                case 0:
-                    EXPECT_EQ(Rect(100, 100), op.unmappedBounds);
-                    EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
-                    expectedMatrix.loadIdentity();
-                    EXPECT_EQ(nullptr, state.computedState.localProjectionPathMask);
-                    break;
-                case 1:
-                    EXPECT_EQ(Rect(-10, -10, 60, 60), op.unmappedBounds);
-                    EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
-                    expectedMatrix.loadTranslate(50 - scrollX, 50 - scrollY, 0);
-                    ASSERT_NE(nullptr, state.computedState.localProjectionPathMask);
-                    EXPECT_EQ(Rect(-35, -30, 45, 50),
-                              Rect(state.computedState.localProjectionPathMask->getBounds()));
-                    break;
-                case 2:
-                    EXPECT_EQ(Rect(100, 50), op.unmappedBounds);
-                    EXPECT_EQ(SK_ColorBLUE, op.paint->getColor());
-                    expectedMatrix.loadTranslate(-scrollX, 50 - scrollY, 0);
-                    EXPECT_EQ(nullptr, state.computedState.localProjectionPathMask);
-                    break;
-                default:
-                    ADD_FAILURE();
-            }
-            EXPECT_EQ(expectedMatrix, state.computedState.transform);
-        }
-    };
-
-    /**
-     * Construct a tree of nodes, where the root (A) has a receiver background (B), and a child (C)
-     * with a projecting child (P) of its own. P would normally draw between B and C's "background"
-     * draw, but because it is projected backwards, it's drawn in between B and C.
-     *
-     * The parent is scrolled by scrollX/scrollY, but this does not affect the background
-     * (which isn't affected by scroll).
-     */
-    auto receiverBackground = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setProjectionReceiver(true);
-                // scroll doesn't apply to background, so undone via translationX/Y
-                // NOTE: translationX/Y only! no other transform properties may be set for a proj
-                // receiver!
-                properties.setTranslationX(scrollX);
-                properties.setTranslationY(scrollY);
-
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-    auto projectingRipple = TestUtils::createNode<RecordingCanvas>(
-            50, 0, 100, 50, [](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setProjectBackwards(true);
-                properties.setClipToBounds(false);
-                SkPaint paint;
-                paint.setColor(SK_ColorDKGRAY);
-                canvas.drawRect(-10, -10, 60, 60, paint);
-            });
-    auto child = TestUtils::createNode<RecordingCanvas>(
-            0, 50, 100, 100,
-            [&projectingRipple](RenderProperties& properties, RecordingCanvas& canvas) {
-                SkPaint paint;
-                paint.setColor(SK_ColorBLUE);
-                canvas.drawRect(0, 0, 100, 50, paint);
-                canvas.drawRenderNode(projectingRipple.get());
-            });
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100,
-            [&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
-                // Set a rect outline for the projecting ripple to be masked against.
-                properties.mutableOutline().setRoundRect(10, 10, 90, 90, 5, 1.0f);
-
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.translate(-scrollX,
-                                 -scrollY);  // Apply scroll (note: bg undoes this internally)
-                canvas.drawRenderNode(receiverBackground.get());
-                canvas.drawRenderNode(child.get());
-                canvas.restore();
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ProjectionReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionHwLayer) {
-    static const int scrollX = 5;
-    static const int scrollY = 10;
-    class ProjectionHwLayerTestRenderer : public TestRendererBase {
-    public:
-        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
-            EXPECT_EQ(0, mIndex++);
-        }
-        void onArcOp(const ArcOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            ASSERT_EQ(nullptr, state.computedState.localProjectionPathMask);
-        }
-        void endLayer() override { EXPECT_EQ(2, mIndex++); }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(3, mIndex++);
-            ASSERT_EQ(nullptr, state.computedState.localProjectionPathMask);
-        }
-        void onOvalOp(const OvalOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(4, mIndex++);
-            ASSERT_NE(nullptr, state.computedState.localProjectionPathMask);
-            Matrix4 expected;
-            expected.loadTranslate(100 - scrollX, 100 - scrollY, 0);
-            EXPECT_EQ(expected, state.computedState.transform);
-            EXPECT_EQ(Rect(-85, -80, 295, 300),
-                      Rect(state.computedState.localProjectionPathMask->getBounds()));
-        }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(5, mIndex++);
-            ASSERT_EQ(nullptr, state.computedState.localProjectionPathMask);
-        }
-    };
-    auto receiverBackground = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400, [](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setProjectionReceiver(true);
-                // scroll doesn't apply to background, so undone via translationX/Y
-                // NOTE: translationX/Y only! no other transform properties may be set for a proj
-                // receiver!
-                properties.setTranslationX(scrollX);
-                properties.setTranslationY(scrollY);
-
-                canvas.drawRect(0, 0, 400, 400, SkPaint());
-            });
-    auto projectingRipple = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setProjectBackwards(true);
-                properties.setClipToBounds(false);
-                canvas.drawOval(100, 100, 300, 300, SkPaint());  // drawn mostly out of layer bounds
-            });
-    auto child = TestUtils::createNode<RecordingCanvas>(
-            100, 100, 300, 300,
-            [&projectingRipple](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.mutateLayerProperties().setType(LayerType::RenderLayer);
-                canvas.drawRenderNode(projectingRipple.get());
-                canvas.drawArc(0, 0, 200, 200, 0.0f, 280.0f, true, SkPaint());
-            });
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400,
-            [&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
-                // Set a rect outline for the projecting ripple to be masked against.
-                properties.mutableOutline().setRoundRect(10, 10, 390, 390, 0, 1.0f);
-                canvas.translate(-scrollX,
-                                 -scrollY);  // Apply scroll (note: bg undoes this internally)
-                canvas.drawRenderNode(receiverBackground.get());
-                canvas.drawRenderNode(child.get());
-            });
-
-    OffscreenBuffer** layerHandle = child->getLayerHandle();
-
-    // create RenderNode's layer here in same way prepareTree would, setting windowTransform
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200, 200);
-    Matrix4 windowTransform;
-    windowTransform.loadTranslate(100, 100, 0);  // total transform of layer's origin
-    layer.setWindowTransform(windowTransform);
-    *layerHandle = &layer;
-
-    auto syncedNode = TestUtils::getSyncedNode(parent);
-
-    LayerUpdateQueue layerUpdateQueue;  // Note: enqueue damage post-sync, so bounds are valid
-    layerUpdateQueue.enqueueLayerWithDamage(child.get(), Rect(200, 200));
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(400, 400), 400, 400, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferLayers(layerUpdateQueue);
-    frameBuilder.deferRenderNode(*syncedNode);
-
-    ProjectionHwLayerTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(6, renderer.getIndex());
-
-    // clean up layer pointer, so we can safely destruct RenderNode
-    *layerHandle = nullptr;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionChildScroll) {
-    static const int scrollX = 500000;
-    static const int scrollY = 0;
-    class ProjectionChildScrollTestRenderer : public TestRendererBase {
-    public:
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-        void onOvalOp(const OvalOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            ASSERT_NE(nullptr, state.computedState.clipState);
-            ASSERT_EQ(ClipMode::Rectangle, state.computedState.clipState->mode);
-            ASSERT_EQ(Rect(400, 400), state.computedState.clipState->rect);
-            EXPECT_TRUE(state.computedState.transform.isIdentity());
-        }
-    };
-    auto receiverBackground = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400, [](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setProjectionReceiver(true);
-                canvas.drawRect(0, 0, 400, 400, SkPaint());
-            });
-    auto projectingRipple = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& properties, RecordingCanvas& canvas) {
-                // scroll doesn't apply to background, so undone via translationX/Y
-                // NOTE: translationX/Y only! no other transform properties may be set for a proj
-                // receiver!
-                properties.setTranslationX(scrollX);
-                properties.setTranslationY(scrollY);
-                properties.setProjectBackwards(true);
-                properties.setClipToBounds(false);
-                canvas.drawOval(0, 0, 200, 200, SkPaint());
-            });
-    auto child = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400,
-            [&projectingRipple](RenderProperties& properties, RecordingCanvas& canvas) {
-                // Record time clip will be ignored by projectee
-                canvas.clipRect(100, 100, 300, 300, SkClipOp::kIntersect);
-
-                canvas.translate(-scrollX,
-                                 -scrollY);  // Apply scroll (note: bg undoes this internally)
-                canvas.drawRenderNode(projectingRipple.get());
-            });
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 400, 400,
-            [&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
-                canvas.drawRenderNode(receiverBackground.get());
-                canvas.drawRenderNode(child.get());
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(400, 400), 400, 400, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ProjectionChildScrollTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-// creates a 100x100 shadow casting node with provided translationZ
-static sp<RenderNode> createWhiteRectShadowCaster(float translationZ) {
-    return TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [translationZ](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setTranslationZ(translationZ);
-                properties.mutableOutline().setRoundRect(0, 0, 100, 100, 0.0f, 1.0f);
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, shadow) {
-    class ShadowTestRenderer : public TestRendererBase {
-    public:
-        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_FLOAT_EQ(1.0f, op.casterAlpha);
-            EXPECT_TRUE(op.shadowTask->casterPerimeter.isRect(nullptr));
-            EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), op.shadowTask->transformXY);
-
-            Matrix4 expectedZ;
-            expectedZ.loadTranslate(0, 0, 5);
-            EXPECT_MATRIX_APPROX_EQ(expectedZ, op.shadowTask->transformZ);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-        }
-    };
-
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.insertReorderBarrier(true);
-                canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ShadowTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, shadowSaveLayer) {
-    class ShadowSaveLayerTestRenderer : public TestRendererBase {
-    public:
-        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
-            EXPECT_EQ(0, mIndex++);
-            return nullptr;
-        }
-        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            EXPECT_FLOAT_EQ(50, op.shadowTask->lightCenter.x);
-            EXPECT_FLOAT_EQ(40, op.shadowTask->lightCenter.y);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(2, mIndex++);
-        }
-        void endLayer() override { EXPECT_EQ(3, mIndex++); }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(4, mIndex++);
-        }
-        void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
-            EXPECT_EQ(5, mIndex++);
-        }
-    };
-
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                // save/restore outside of reorderBarrier, so they don't get moved out of place
-                canvas.translate(20, 10);
-                int count = canvas.saveLayerAlpha(30, 50, 130, 150, 128, SaveFlags::ClipToLayer);
-                canvas.insertReorderBarrier(true);
-                canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
-                canvas.insertReorderBarrier(false);
-                canvas.restoreToCount(count);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200,
-                              (FrameBuilder::LightGeometry){{100, 100, 100}, 50},
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ShadowSaveLayerTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(6, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, shadowHwLayer) {
-    class ShadowHwLayerTestRenderer : public TestRendererBase {
-    public:
-        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
-            EXPECT_EQ(0, mIndex++);
-        }
-        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-            EXPECT_FLOAT_EQ(50, op.shadowTask->lightCenter.x);
-            EXPECT_FLOAT_EQ(40, op.shadowTask->lightCenter.y);
-            EXPECT_FLOAT_EQ(30, op.shadowTask->lightRadius);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(2, mIndex++);
-        }
-        void endLayer() override { EXPECT_EQ(3, mIndex++); }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(4, mIndex++);
-        }
-    };
-
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            50, 60, 150, 160, [](RenderProperties& props, RecordingCanvas& canvas) {
-                props.mutateLayerProperties().setType(LayerType::RenderLayer);
-                canvas.insertReorderBarrier(true);
-                canvas.save(SaveFlags::MatrixClip);
-                canvas.translate(20, 10);
-                canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
-                canvas.restore();
-            });
-    OffscreenBuffer** layerHandle = parent->getLayerHandle();
-
-    // create RenderNode's layer here in same way prepareTree would, setting windowTransform
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
-    Matrix4 windowTransform;
-    windowTransform.loadTranslate(50, 60, 0);  // total transform of layer's origin
-    layer.setWindowTransform(windowTransform);
-    *layerHandle = &layer;
-
-    auto syncedNode = TestUtils::getSyncedNode(parent);
-    LayerUpdateQueue layerUpdateQueue;  // Note: enqueue damage post-sync, so bounds are valid
-    layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(100, 100));
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200,
-                              (FrameBuilder::LightGeometry){{100, 100, 100}, 30},
-                              Caches::getInstance());
-    frameBuilder.deferLayers(layerUpdateQueue);
-    frameBuilder.deferRenderNode(*syncedNode);
-
-    ShadowHwLayerTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(5, renderer.getIndex());
-
-    // clean up layer pointer, so we can safely destruct RenderNode
-    *layerHandle = nullptr;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, shadowLayering) {
-    class ShadowLayeringTestRenderer : public TestRendererBase {
-    public:
-        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 0 || index == 1);
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            int index = mIndex++;
-            EXPECT_TRUE(index == 2 || index == 3);
-        }
-    };
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.insertReorderBarrier(true);
-                canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
-                canvas.drawRenderNode(createWhiteRectShadowCaster(5.0001f).get());
-            });
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200,
-                              (FrameBuilder::LightGeometry){{100, 100, 100}, 50},
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ShadowLayeringTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, shadowClipping) {
-    class ShadowClippingTestRenderer : public TestRendererBase {
-    public:
-        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_EQ(Rect(25, 25, 75, 75), state.computedState.clipState->rect)
-                    << "Shadow must respect pre-barrier canvas clip value.";
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-        }
-    };
-    auto parent = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                // Apply a clip before the reorder barrier/shadow casting child is drawn.
-                // This clip must be applied to the shadow cast by the child.
-                canvas.clipRect(25, 25, 75, 75, SkClipOp::kIntersect);
-                canvas.insertReorderBarrier(true);
-                canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100,
-                              (FrameBuilder::LightGeometry){{100, 100, 100}, 50},
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(parent));
-
-    ShadowClippingTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-static void testProperty(
-        std::function<void(RenderProperties&)> propSetupCallback,
-        std::function<void(const RectOp&, const BakedOpState&)> opValidateCallback) {
-    class PropertyTestRenderer : public TestRendererBase {
-    public:
-        explicit PropertyTestRenderer(
-                std::function<void(const RectOp&, const BakedOpState&)> callback)
-                : mCallback(callback) {}
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(mIndex++, 0);
-            mCallback(op, state);
-        }
-        std::function<void(const RectOp&, const BakedOpState&)> mCallback;
-    };
-
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [propSetupCallback](RenderProperties& props, RecordingCanvas& canvas) {
-                propSetupCallback(props);
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    PropertyTestRenderer renderer(opValidateCallback);
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex()) << "Should have seen one op";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropOverlappingRenderingAlpha) {
-    testProperty(
-            [](RenderProperties& properties) {
-                properties.setAlpha(0.5f);
-                properties.setHasOverlappingRendering(false);
-            },
-            [](const RectOp& op, const BakedOpState& state) {
-                EXPECT_EQ(0.5f, state.alpha) << "Alpha should be applied directly to op";
-            });
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropClipping) {
-    testProperty(
-            [](RenderProperties& properties) {
-                properties.setClipToBounds(true);
-                properties.setClipBounds(Rect(10, 20, 300, 400));
-            },
-            [](const RectOp& op, const BakedOpState& state) {
-                EXPECT_EQ(Rect(10, 20, 100, 100), state.computedState.clippedBounds)
-                        << "Clip rect should be intersection of node bounds and clip bounds";
-            });
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropRevealClip) {
-    testProperty(
-            [](RenderProperties& properties) {
-                properties.mutableRevealClip().set(true, 50, 50, 25);
-            },
-            [](const RectOp& op, const BakedOpState& state) {
-                ASSERT_NE(nullptr, state.roundRectClipState);
-                EXPECT_TRUE(state.roundRectClipState->highPriority);
-                EXPECT_EQ(25, state.roundRectClipState->radius);
-                EXPECT_EQ(Rect(50, 50, 50, 50), state.roundRectClipState->innerRect);
-            });
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropOutlineClip) {
-    testProperty(
-            [](RenderProperties& properties) {
-                properties.mutableOutline().setShouldClip(true);
-                properties.mutableOutline().setRoundRect(10, 20, 30, 40, 5.0f, 0.5f);
-            },
-            [](const RectOp& op, const BakedOpState& state) {
-                ASSERT_NE(nullptr, state.roundRectClipState);
-                EXPECT_FALSE(state.roundRectClipState->highPriority);
-                EXPECT_EQ(5, state.roundRectClipState->radius);
-                EXPECT_EQ(Rect(15, 25, 25, 35), state.roundRectClipState->innerRect);
-            });
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropTransform) {
-    testProperty(
-            [](RenderProperties& properties) {
-                properties.setLeftTopRightBottom(10, 10, 110, 110);
-
-                SkMatrix staticMatrix = SkMatrix::MakeScale(1.2f, 1.2f);
-                properties.setStaticMatrix(&staticMatrix);
-
-                // ignored, since static overrides animation
-                SkMatrix animationMatrix = SkMatrix::MakeTrans(15, 15);
-                properties.setAnimationMatrix(&animationMatrix);
-
-                properties.setTranslationX(10);
-                properties.setTranslationY(20);
-                properties.setScaleX(0.5f);
-                properties.setScaleY(0.7f);
-            },
-            [](const RectOp& op, const BakedOpState& state) {
-                Matrix4 matrix;
-                matrix.loadTranslate(10, 10, 0);  // left, top
-                matrix.scale(1.2f, 1.2f, 1);      // static matrix
-                // ignore animation matrix, since static overrides it
-
-                // translation xy
-                matrix.translate(10, 20);
-
-                // scale xy (from default pivot - center)
-                matrix.translate(50, 50);
-                matrix.scale(0.5f, 0.7f, 1);
-                matrix.translate(-50, -50);
-                EXPECT_MATRIX_APPROX_EQ(matrix, state.computedState.transform)
-                        << "Op draw matrix must match expected combination of transformation "
-                           "properties";
-            });
-}
-
-struct SaveLayerAlphaData {
-    uint32_t layerWidth = 0;
-    uint32_t layerHeight = 0;
-    Rect rectClippedBounds;
-    Matrix4 rectMatrix;
-    Matrix4 drawLayerMatrix;
-};
-/**
- * Constructs a view to hit the temporary layer alpha property implementation:
- *     a) 0 < alpha < 1
- *     b) too big for layer (larger than maxTextureSize)
- *     c) overlapping rendering content
- * returning observed data about layer size and content clip/transform.
- *
- * Used to validate clipping behavior of temporary layer, where requested layer size is reduced
- * (for efficiency, and to fit in layer size constraints) based on parent clip.
- */
-void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData,
-                            std::function<void(RenderProperties&)> propSetupCallback) {
-    class SaveLayerAlphaClipTestRenderer : public TestRendererBase {
-    public:
-        explicit SaveLayerAlphaClipTestRenderer(SaveLayerAlphaData* outData) : mOutData(outData) {}
-
-        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
-            EXPECT_EQ(0, mIndex++);
-            mOutData->layerWidth = width;
-            mOutData->layerHeight = height;
-            return nullptr;
-        }
-        void onRectOp(const RectOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(1, mIndex++);
-
-            mOutData->rectClippedBounds = state.computedState.clippedBounds;
-            mOutData->rectMatrix = state.computedState.transform;
-        }
-        void endLayer() override { EXPECT_EQ(2, mIndex++); }
-        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(3, mIndex++);
-            mOutData->drawLayerMatrix = state.computedState.transform;
-        }
-        void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
-            EXPECT_EQ(4, mIndex++);
-        }
-
-    private:
-        SaveLayerAlphaData* mOutData;
-    };
-
-    ASSERT_GT(10000, DeviceInfo::get()->maxTextureSize())
-            << "Node must be bigger than max texture size to exercise saveLayer codepath";
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 10000, 10000,
-            [&propSetupCallback](RenderProperties& properties, RecordingCanvas& canvas) {
-                properties.setHasOverlappingRendering(true);
-                properties.setAlpha(0.5f);  // force saveLayer, since too big for HW layer
-                // apply other properties
-                propSetupCallback(properties);
-
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 10000, 10000, paint);
-            });
-    auto syncedNode = TestUtils::getSyncedNode(node);  // sync before querying height
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*syncedNode);
-
-    SaveLayerAlphaClipTestRenderer renderer(outObservedData);
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-
-    // assert, since output won't be valid if we haven't seen a save layer triggered
-    ASSERT_EQ(5, renderer.getIndex()) << "Test must trigger saveLayer alpha behavior.";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropSaveLayerAlphaClipBig) {
-    SaveLayerAlphaData observedData;
-    testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) {
-        properties.setTranslationX(10);     // offset rendering content
-        properties.setTranslationY(-2000);  // offset rendering content
-    });
-    EXPECT_EQ(190u, observedData.layerWidth);
-    EXPECT_EQ(200u, observedData.layerHeight);
-    EXPECT_EQ(Rect(190, 200), observedData.rectClippedBounds)
-            << "expect content to be clipped to screen area";
-    Matrix4 expected;
-    expected.loadTranslate(0, -2000, 0);
-    EXPECT_MATRIX_APPROX_EQ(expected, observedData.rectMatrix)
-            << "expect content to be translated as part of being clipped";
-    expected.loadTranslate(10, 0, 0);
-    EXPECT_MATRIX_APPROX_EQ(expected, observedData.drawLayerMatrix)
-            << "expect drawLayer to be translated as part of being clipped";
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropSaveLayerAlphaRotate) {
-    SaveLayerAlphaData observedData;
-    testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) {
-        // Translate and rotate the view so that the only visible part is the top left corner of
-        // the view. It will form an isosceles right triangle with a long side length of 200 at the
-        // bottom of the viewport.
-        properties.setTranslationX(100);
-        properties.setTranslationY(100);
-        properties.setPivotX(0);
-        properties.setPivotY(0);
-        properties.setRotation(45);
-    });
-    // ceil(sqrt(2) / 2 * 200) = 142
-    EXPECT_EQ(142u, observedData.layerWidth);
-    EXPECT_EQ(142u, observedData.layerHeight);
-    EXPECT_EQ(Rect(142, 142), observedData.rectClippedBounds);
-    EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderPropSaveLayerAlphaScale) {
-    SaveLayerAlphaData observedData;
-    testSaveLayerAlphaClip(&observedData, [](RenderProperties& properties) {
-        properties.setPivotX(0);
-        properties.setPivotY(0);
-        properties.setScaleX(2);
-        properties.setScaleY(0.5f);
-    });
-    EXPECT_EQ(100u, observedData.layerWidth);
-    EXPECT_EQ(400u, observedData.layerHeight);
-    EXPECT_EQ(Rect(100, 400), observedData.rectClippedBounds);
-    EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), observedData.rectMatrix);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, clip_replace) {
-    class ClipReplaceTestRenderer : public TestRendererBase {
-    public:
-        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
-            EXPECT_EQ(0, mIndex++);
-            EXPECT_TRUE(op.localClip->intersectWithRoot);
-            EXPECT_EQ(Rect(20, 10, 30, 40), state.computedState.clipState->rect)
-                    << "Expect resolved clip to be intersection of viewport clip and clip op";
-        }
-    };
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            20, 20, 30, 30, [](RenderProperties& props, RecordingCanvas& canvas) {
-                canvas.clipRect(0, -20, 10, 30, SkClipOp::kReplace_deprecated);
-                canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
-            });
-
-    FrameBuilder frameBuilder(SkRect::MakeLTRB(10, 10, 40, 40), 50, 50, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-
-    ClipReplaceTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(1, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedInMiddle) {
-    /* R is backward projected on B
-                A
-               / \
-              B   C
-                  |
-                  R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    props.setProjectionReceiver(true);
-                });  // nodeB
-                drawOrderedNode(&canvas, 2, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    drawOrderedNode(&canvas, 1,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeR
-                });                      // nodeC
-            });                          // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectLast) {
-    /* R is backward projected on E
-                  A
-                / | \
-               /  |  \
-              B   C   E
-                  |
-                  R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, nullptr);  // nodeB
-                drawOrderedNode(&canvas, 1, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    drawOrderedNode(&canvas, 3, [](RenderProperties& props,
-                                                   RecordingCanvas& canvas) {  // drawn as 2
-                        props.setProjectBackwards(true);
-                        props.setClipToBounds(false);
-                    });  // nodeR
-                });      // nodeC
-                drawOrderedNode(&canvas, 2, [](RenderProperties& props,
-                                               RecordingCanvas& canvas) {  // drawn as 3
-                    props.setProjectionReceiver(true);
-                });  // nodeE
-            });      // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderNoReceivable) {
-    /* R is backward projected without receiver
-                A
-               / \
-              B   C
-                  |
-                  R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, nullptr);  // nodeB
-                drawOrderedNode(&canvas, 1, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    drawOrderedNode(&canvas, 255,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {
-                                        // not having a projection receiver is an undefined behavior
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeR
-                });                      // nodeC
-            });                          // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderParentReceivable) {
-    /* R is backward projected on C
-                A
-               / \
-              B   C
-                  |
-                  R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, nullptr);  // nodeB
-                drawOrderedNode(&canvas, 1, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    props.setProjectionReceiver(true);
-                    drawOrderedNode(&canvas, 2,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeR
-                });                      // nodeC
-            });                          // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderSameNodeReceivable) {
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, nullptr);  // nodeB
-                drawOrderedNode(&canvas, 1, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    drawOrderedNode(&canvas, 255,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {
-                                        // having a node that is projected on itself is an
-                                        // undefined/unexpected behavior
-                                        props.setProjectionReceiver(true);
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeR
-                });                      // nodeC
-            });                          // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(2, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedSibling) {
-    // TODO: this test together with the next "projectionReorderProjectedSibling2" likely expose a
-    // bug in HWUI. First test draws R, while the second test does not draw R for a nearly identical
-    // tree setup. The correct behaviour is to not draw R, because the receiver cannot be a sibling
-    /* R is backward projected on B. R is not expected to be drawn (see Sibling2 outcome below),
-       but for some reason it is drawn.
-                A
-               /|\
-              / | \
-             B  C  R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    props.setProjectionReceiver(true);
-                });  // nodeB
-                drawOrderedNode(&canvas, 2,
-                                [](RenderProperties& props, RecordingCanvas& canvas) {});  // nodeC
-                drawOrderedNode(&canvas, 1, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    props.setProjectBackwards(true);
-                    props.setClipToBounds(false);
-                });  // nodeR
-            });      // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedSibling2) {
-    /* R is set to project on B, but R is not drawn because projecting on a sibling is not allowed.
-                A
-                |
-                G
-               /|\
-              / | \
-             B  C  R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, [](RenderProperties& props,
-                                               RecordingCanvas& canvas) {  // G
-                    drawOrderedNode(&canvas, 1,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // B
-                                        props.setProjectionReceiver(true);
-                                    });  // nodeB
-                    drawOrderedNode(&canvas, 2,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // C
-                                    });                                                     // nodeC
-                    drawOrderedNode(&canvas, 255,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // R
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeR
-                });                      // nodeG
-            });                          // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderGrandparentReceivable) {
-    /* R is backward projected on B
-                A
-                |
-                B
-                |
-                C
-                |
-                R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0, [](RenderProperties& props, RecordingCanvas& canvas) {
-                    props.setProjectionReceiver(true);
-                    drawOrderedNode(&canvas, 1,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {
-                                        drawOrderedNode(&canvas, 2, [](RenderProperties& props,
-                                                                       RecordingCanvas& canvas) {
-                                            props.setProjectBackwards(true);
-                                            props.setClipToBounds(false);
-                                        });  // nodeR
-                                    });      // nodeC
-                });                          // nodeB
-            });                              // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(3, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivables) {
-    /* B and G are receivables, R is backward projected
-                A
-               / \
-              B   C
-                 / \
-                G   R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0,
-                                [](RenderProperties& props, RecordingCanvas& canvas) {  // B
-                                    props.setProjectionReceiver(true);
-                                });  // nodeB
-                drawOrderedNode(&canvas, 2, [](RenderProperties& props,
-                                               RecordingCanvas& canvas) {  // C
-                    drawOrderedNode(&canvas, 3,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // G
-                                        props.setProjectionReceiver(true);
-                                    });  // nodeG
-                    drawOrderedNode(&canvas, 1,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // R
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeR
-                });                      // nodeC
-            });                          // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivablesLikelyScenario) {
-    /* B and G are receivables, G is backward projected
-                A
-               / \
-              B   C
-                 / \
-                G   R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0,
-                                [](RenderProperties& props, RecordingCanvas& canvas) {  // B
-                                    props.setProjectionReceiver(true);
-                                });  // nodeB
-                drawOrderedNode(&canvas, 2, [](RenderProperties& props,
-                                               RecordingCanvas& canvas) {  // C
-                    drawOrderedNode(&canvas, 1,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // G
-                                        props.setProjectionReceiver(true);
-                                        props.setProjectBackwards(true);
-                                        props.setClipToBounds(false);
-                                    });  // nodeG
-                    drawOrderedNode(&canvas, 3,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // R
-                                    });                                                     // nodeR
-                });                                                                         // nodeC
-            });                                                                             // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(4, renderer.getIndex());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivablesDeeper) {
-    /* B and G are receivables, R is backward projected
-                A
-               / \
-              B   C
-                 / \
-                G   D
-                    |
-                    R
-    */
-    auto nodeA = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 100, 100, [](RenderProperties& props, RecordingCanvas& canvas) {
-                drawOrderedNode(&canvas, 0,
-                                [](RenderProperties& props, RecordingCanvas& canvas) {  // B
-                                    props.setProjectionReceiver(true);
-                                });  // nodeB
-                drawOrderedNode(&canvas, 1, [](RenderProperties& props,
-                                               RecordingCanvas& canvas) {  // C
-                    drawOrderedNode(&canvas, 2,
-                                    [](RenderProperties& props, RecordingCanvas& canvas) {  // G
-                                        props.setProjectionReceiver(true);
-                                    });  // nodeG
-                    drawOrderedNode(
-                            &canvas, 4, [](RenderProperties& props, RecordingCanvas& canvas) {  // D
-                                drawOrderedNode(&canvas, 3, [](RenderProperties& props,
-                                                               RecordingCanvas& canvas) {  // R
-                                    props.setProjectBackwards(true);
-                                    props.setClipToBounds(false);
-                                });  // nodeR
-                            });      // nodeD
-                });                  // nodeC
-            });                      // nodeA
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometry,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(nodeA));
-
-    ZReorderTestRenderer renderer;
-    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
-    EXPECT_EQ(5, renderer.getIndex());
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/tests/unit/GlopBuilderTests.cpp b/libs/hwui/tests/unit/GlopBuilderTests.cpp
deleted file mode 100644
index c8bfc99..0000000
--- a/libs/hwui/tests/unit/GlopBuilderTests.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "Glop.h"
-#include "GlopBuilder.h"
-#include "Rect.h"
-#include "tests/common/TestUtils.h"
-#include "utils/Color.h"
-
-#include <SkPaint.h>
-
-using namespace android::uirenderer;
-
-static void expectFillEq(Glop::Fill& expectedFill, Glop::Fill& builtFill) {
-    EXPECT_EQ(expectedFill.colorEnabled, builtFill.colorEnabled);
-    if (expectedFill.colorEnabled) EXPECT_EQ(expectedFill.color, builtFill.color);
-
-    EXPECT_EQ(expectedFill.filterMode, builtFill.filterMode);
-    if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Blend) {
-        EXPECT_EQ(expectedFill.filter.color, builtFill.filter.color);
-    } else if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Matrix) {
-        Glop::Fill::Filter::Matrix& expectedMatrix = expectedFill.filter.matrix;
-        Glop::Fill::Filter::Matrix& builtMatrix = expectedFill.filter.matrix;
-        EXPECT_TRUE(std::memcmp(expectedMatrix.matrix, builtMatrix.matrix,
-                                sizeof(Glop::Fill::Filter::Matrix::matrix)));
-        EXPECT_TRUE(std::memcmp(expectedMatrix.vector, builtMatrix.vector,
-                                sizeof(Glop::Fill::Filter::Matrix::vector)));
-    }
-    EXPECT_EQ(expectedFill.skiaShaderData.skiaShaderType, builtFill.skiaShaderData.skiaShaderType);
-    EXPECT_EQ(expectedFill.texture.clamp, builtFill.texture.clamp);
-    EXPECT_EQ(expectedFill.texture.filter, builtFill.texture.filter);
-    EXPECT_TRUE((expectedFill.texture.texture && builtFill.texture.texture) ||
-                (!expectedFill.texture.texture && !builtFill.texture.texture));
-    if (expectedFill.texture.texture) {
-        EXPECT_EQ(expectedFill.texture.texture->target(), builtFill.texture.texture->target());
-    }
-    EXPECT_EQ(expectedFill.texture.textureTransform, builtFill.texture.textureTransform);
-}
-
-static void expectBlendEq(Glop::Blend& expectedBlend, Glop::Blend& builtBlend) {
-    EXPECT_EQ(expectedBlend.src, builtBlend.src);
-    EXPECT_EQ(expectedBlend.dst, builtBlend.dst);
-}
-
-static void expectMeshEq(Glop::Mesh& expectedMesh, Glop::Mesh& builtMesh) {
-    EXPECT_EQ(expectedMesh.elementCount, builtMesh.elementCount);
-    EXPECT_EQ(expectedMesh.primitiveMode, builtMesh.primitiveMode);
-    EXPECT_EQ(expectedMesh.indices.indices, builtMesh.indices.indices);
-    EXPECT_EQ(expectedMesh.indices.bufferObject, builtMesh.indices.bufferObject);
-    EXPECT_EQ(expectedMesh.vertices.attribFlags, builtMesh.vertices.attribFlags);
-    EXPECT_EQ(expectedMesh.vertices.bufferObject, builtMesh.vertices.bufferObject);
-    EXPECT_EQ(expectedMesh.vertices.color, builtMesh.vertices.color);
-    EXPECT_EQ(expectedMesh.vertices.position, builtMesh.vertices.position);
-    EXPECT_EQ(expectedMesh.vertices.stride, builtMesh.vertices.stride);
-    EXPECT_EQ(expectedMesh.vertices.texCoord, builtMesh.vertices.texCoord);
-
-    if (builtMesh.vertices.position) {
-        for (int i = 0; i < 4; i++) {
-            TextureVertex& expectedVertex = expectedMesh.mappedVertices[i];
-            TextureVertex& builtVertex = builtMesh.mappedVertices[i];
-            EXPECT_EQ(expectedVertex.u, builtVertex.u);
-            EXPECT_EQ(expectedVertex.v, builtVertex.v);
-            EXPECT_EQ(expectedVertex.x, builtVertex.x);
-            EXPECT_EQ(expectedVertex.y, builtVertex.y);
-        }
-    }
-}
-
-static void expectTransformEq(Glop::Transform& expectedTransform, Glop::Transform& builtTransform) {
-    EXPECT_EQ(expectedTransform.canvas, builtTransform.canvas);
-    EXPECT_EQ(expectedTransform.modelView, builtTransform.modelView);
-    EXPECT_EQ(expectedTransform.transformFlags, expectedTransform.transformFlags);
-}
-
-static void expectGlopEq(Glop& expectedGlop, Glop& builtGlop) {
-    expectBlendEq(expectedGlop.blend, builtGlop.blend);
-    expectFillEq(expectedGlop.fill, builtGlop.fill);
-    expectMeshEq(expectedGlop.mesh, builtGlop.mesh);
-    expectTransformEq(expectedGlop.transform, builtGlop.transform);
-}
-
-static std::unique_ptr<Glop> blackUnitQuadGlop(RenderState& renderState) {
-    std::unique_ptr<Glop> glop(new Glop());
-    glop->blend = {GL_ZERO, GL_ZERO};
-    glop->mesh.elementCount = 4;
-    glop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
-    glop->mesh.indices.indices = nullptr;
-    glop->mesh.indices.bufferObject = GL_ZERO;
-    glop->mesh.vertices = {renderState.meshState().getUnitQuadVBO(),
-                           VertexAttribFlags::None,
-                           nullptr,
-                           nullptr,
-                           nullptr,
-                           kTextureVertexStride};
-    glop->transform.modelView.loadIdentity();
-    glop->fill.colorEnabled = true;
-    glop->fill.color.set(Color::Black);
-    glop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType;
-    glop->fill.filterMode = ProgramDescription::ColorFilterMode::None;
-    glop->fill.texture = {nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
-    return glop;
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(GlopBuilder, rectSnapTest) {
-    RenderState& renderState = renderThread.renderState();
-    Caches& caches = Caches::getInstance();
-    SkPaint paint;
-    Rect dest(1, 1, 100, 100);
-    Matrix4 simpleTranslate;
-    simpleTranslate.loadTranslate(0.7, 0.7, 0);
-    Glop glop;
-    GlopBuilder(renderState, caches, &glop)
-            .setRoundRectClipState(nullptr)
-            .setMeshUnitQuad()
-            .setFillPaint(paint, 1.0f)
-            .setTransform(simpleTranslate, TransformFlags::None)
-            .setModelViewMapUnitToRectSnap(dest)
-            .build();
-
-    std::unique_ptr<Glop> goldenGlop(blackUnitQuadGlop(renderState));
-    // Rect(1,1,100,100) is the set destination,
-    // so unit quad should be translated by (1,1) and scaled by (99, 99)
-    // Tricky part: because translate (0.7, 0.7) and snapping were set in glopBuilder,
-    // unit quad also should be translate by additional (0.3, 0.3) to snap to exact pixels.
-    goldenGlop->transform.modelView.loadTranslate(1.3, 1.3, 0);
-    goldenGlop->transform.modelView.scale(99, 99, 1);
-    goldenGlop->transform.canvas = simpleTranslate;
-    goldenGlop->fill.texture.filter = GL_NEAREST;
-    expectGlopEq(*goldenGlop, glop);
-}
diff --git a/libs/hwui/tests/unit/GradientCacheTests.cpp b/libs/hwui/tests/unit/GradientCacheTests.cpp
deleted file mode 100644
index 6710c71..0000000
--- a/libs/hwui/tests/unit/GradientCacheTests.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "Extensions.h"
-#include "GradientCache.h"
-#include "tests/common/TestUtils.h"
-
-using namespace android;
-using namespace android::uirenderer;
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(GradientCache, addRemove) {
-    Extensions extensions;
-    GradientCache cache(extensions);
-    ASSERT_LT(1000u, cache.getMaxSize()) << "Expect non-trivial size";
-
-    SkColor colors[] = {0xFF00FF00, 0xFFFF0000, 0xFF0000FF};
-    float positions[] = {1, 2, 3};
-    Texture* texture = cache.get(colors, positions, 3);
-    ASSERT_TRUE(texture);
-    ASSERT_FALSE(texture->cleanup);
-    ASSERT_EQ((uint32_t)texture->objectSize(), cache.getSize());
-    ASSERT_TRUE(cache.getSize());
-    cache.clear();
-    ASSERT_EQ(cache.getSize(), 0u);
-}
diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp
deleted file mode 100644
index 20ec084..0000000
--- a/libs/hwui/tests/unit/LeakCheckTests.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
-#include "FrameBuilder.h"
-#include "LayerUpdateQueue.h"
-#include "RecordingCanvas.h"
-#include "tests/common/TestUtils.h"
-
-#include <gtest/gtest.h>
-
-using namespace android;
-using namespace android::uirenderer;
-
-const FrameBuilder::LightGeometry sLightGeometery = {{100, 100, 100}, 50};
-const BakedOpRenderer::LightInfo sLightInfo = {128, 128};
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(LeakCheck, saveLayer_overdrawRejection) {
-    auto node = TestUtils::createNode(0, 0, 100, 100, [](RenderProperties& props, Canvas& canvas) {
-        canvas.saveLayerAlpha(0, 0, 100, 100, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(0, 0, 100, 100, SkPaint());
-        canvas.restore();
-
-        // opaque draw, rejects saveLayer beneath
-        canvas.drawRect(0, 0, 100, 100, SkPaint());
-    });
-    RenderState& renderState = renderThread.renderState();
-    Caches& caches = Caches::getInstance();
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100, sLightGeometery,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
-    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(LeakCheck, saveLayerUnclipped_simple) {
-    auto node = TestUtils::createNode(0, 0, 200, 200, [](RenderProperties& props, Canvas& canvas) {
-        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SaveFlags::Flags)(0));
-        canvas.drawRect(0, 0, 200, 200, SkPaint());
-        canvas.restore();
-    });
-    RenderState& renderState = renderThread.renderState();
-    Caches& caches = Caches::getInstance();
-
-    FrameBuilder frameBuilder(SkRect::MakeWH(200, 200), 200, 200, sLightGeometery,
-                              Caches::getInstance());
-    frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
-    BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
-    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-}
diff --git a/libs/hwui/tests/unit/MeshStateTests.cpp b/libs/hwui/tests/unit/MeshStateTests.cpp
deleted file mode 100644
index 1573fd3..0000000
--- a/libs/hwui/tests/unit/MeshStateTests.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <debug/MockGlesDriver.h>
-#include <debug/ScopedReplaceDriver.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <renderstate/MeshState.h>
-#include <tests/common/TestUtils.h>
-
-using namespace android::uirenderer;
-using namespace testing;
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(MeshState, genOrUpdate) {
-    debug::ScopedReplaceDriver<debug::MockGlesDriver> driverRef;
-    auto& mockGlDriver = driverRef.get();
-    EXPECT_CALL(mockGlDriver, glGenBuffers_(_, _)).WillOnce(SetArgPointee<1>(35));
-    EXPECT_CALL(mockGlDriver, glBindBuffer_(_, 35));
-    EXPECT_CALL(mockGlDriver, glBufferData_(_, _, _, _));
-
-    GLuint buffer = 0;
-    renderThread.renderState().meshState().genOrUpdateMeshBuffer(&buffer, 10, nullptr,
-                                                                 GL_DYNAMIC_DRAW);
-}
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
deleted file mode 100644
index 0d47367..0000000
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <Rect.h>
-#include <gtest/gtest.h>
-#include <renderstate/OffscreenBufferPool.h>
-
-#include <tests/common/TestUtils.h>
-
-using namespace android::uirenderer;
-
-TEST(OffscreenBuffer, computeIdealDimension) {
-    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(1));
-    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(31));
-    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(33));
-    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(64));
-    EXPECT_EQ(1024u, OffscreenBuffer::computeIdealDimension(1000));
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, construct) {
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u);
-    EXPECT_EQ(49u, layer.viewportWidth);
-    EXPECT_EQ(149u, layer.viewportHeight);
-
-    EXPECT_EQ(64u, layer.texture.width());
-    EXPECT_EQ(192u, layer.texture.height());
-
-    EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, constructWideColorGamut) {
-    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u, true);
-    EXPECT_EQ(49u, layer.viewportWidth);
-    EXPECT_EQ(149u, layer.viewportHeight);
-
-    EXPECT_EQ(64u, layer.texture.width());
-    EXPECT_EQ(192u, layer.texture.height());
-
-    EXPECT_TRUE(layer.wideColorGamut);
-
-    EXPECT_EQ(64u * 192u * 8u, layer.getSizeInBytes());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, getTextureCoordinates) {
-    OffscreenBuffer layerAligned(renderThread.renderState(), Caches::getInstance(), 256u, 256u);
-    EXPECT_EQ(Rect(0, 1, 1, 0), layerAligned.getTextureCoordinates());
-
-    OffscreenBuffer layerUnaligned(renderThread.renderState(), Caches::getInstance(), 200u, 225u);
-    EXPECT_EQ(Rect(0, 225.0f / 256.0f, 200.0f / 256.0f, 0), layerUnaligned.getTextureCoordinates());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBuffer, dirty) {
-    OffscreenBuffer buffer(renderThread.renderState(), Caches::getInstance(), 256u, 256u);
-    buffer.dirty(Rect(-100, -100, 100, 100));
-    EXPECT_EQ(android::Rect(100, 100), buffer.region.getBounds());
-}
-
-RENDERTHREAD_TEST(OffscreenBufferPool, construct) {
-    OffscreenBufferPool pool;
-    EXPECT_EQ(0u, pool.getCount()) << "pool must be created empty";
-    EXPECT_EQ(0u, pool.getSize()) << "pool must be created empty";
-    // TODO: Does this really make sense as a test?
-    EXPECT_EQ(DeviceInfo::multiplyByResolution(4 * 4), pool.getMaxSize());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClear) {
-    OffscreenBufferPool pool;
-
-    auto layer = pool.get(renderThread.renderState(), 100u, 200u);
-    EXPECT_EQ(100u, layer->viewportWidth);
-    EXPECT_EQ(200u, layer->viewportHeight);
-
-    ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize());
-
-    pool.putOrDelete(layer);
-    ASSERT_EQ(layer->getSizeInBytes(), pool.getSize());
-
-    auto layer2 = pool.get(renderThread.renderState(), 102u, 202u);
-    EXPECT_EQ(layer, layer2) << "layer should be recycled";
-    ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer";
-
-    pool.putOrDelete(layer);
-    EXPECT_EQ(1u, pool.getCount());
-    pool.clear();
-    EXPECT_EQ(0u, pool.getSize());
-    EXPECT_EQ(0u, pool.getCount());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClearWideColorGamut) {
-    OffscreenBufferPool pool;
-
-    auto layer = pool.get(renderThread.renderState(), 100u, 200u, true);
-    EXPECT_EQ(100u, layer->viewportWidth);
-    EXPECT_EQ(200u, layer->viewportHeight);
-    EXPECT_TRUE(layer->wideColorGamut);
-
-    ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize());
-
-    pool.putOrDelete(layer);
-    ASSERT_EQ(layer->getSizeInBytes(), pool.getSize());
-
-    auto layer2 = pool.get(renderThread.renderState(), 102u, 202u, true);
-    EXPECT_EQ(layer, layer2) << "layer should be recycled";
-    ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer";
-
-    pool.putOrDelete(layer2);
-    EXPECT_EQ(1u, pool.getCount());
-    pool.clear();
-    EXPECT_EQ(0u, pool.getSize());
-    EXPECT_EQ(0u, pool.getCount());
-
-    // add non wide gamut layer
-    auto layer3 = pool.get(renderThread.renderState(), 100u, 200u);
-    EXPECT_FALSE(layer3->wideColorGamut);
-    pool.putOrDelete(layer3);
-    EXPECT_EQ(1u, pool.getCount());
-
-    auto layer4 = pool.get(renderThread.renderState(), 100u, 200u, true);
-    EXPECT_TRUE(layer4->wideColorGamut);
-    EXPECT_EQ(1u, pool.getCount());
-    ASSERT_NE(layer3, layer4);
-
-    pool.putOrDelete(layer4);
-
-    pool.clear();
-    EXPECT_EQ(0u, pool.getSize());
-    EXPECT_EQ(0u, pool.getCount());
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resize) {
-    OffscreenBufferPool pool;
-
-    auto layer = pool.get(renderThread.renderState(), 64u, 64u);
-    layer->dirty(Rect(64, 64));
-
-    // resize in place
-    ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
-    EXPECT_TRUE(layer->region.isEmpty()) << "In place resize should clear usage region";
-    EXPECT_EQ(60u, layer->viewportWidth);
-    EXPECT_EQ(55u, layer->viewportHeight);
-    EXPECT_EQ(64u, layer->texture.width());
-    EXPECT_EQ(64u, layer->texture.height());
-
-    // resized to use different object in pool
-    auto layer2 = pool.get(renderThread.renderState(), 128u, 128u);
-    layer2->dirty(Rect(128, 128));
-    EXPECT_FALSE(layer2->region.isEmpty());
-    pool.putOrDelete(layer2);
-    ASSERT_EQ(1u, pool.getCount());
-
-    ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
-    EXPECT_TRUE(layer2->region.isEmpty()) << "Swap resize should clear usage region";
-    EXPECT_EQ(120u, layer2->viewportWidth);
-    EXPECT_EQ(125u, layer2->viewportHeight);
-    EXPECT_EQ(128u, layer2->texture.width());
-    EXPECT_EQ(128u, layer2->texture.height());
-
-    // original allocation now only thing in pool
-    EXPECT_EQ(1u, pool.getCount());
-    EXPECT_EQ(layer->getSizeInBytes(), pool.getSize());
-
-    pool.putOrDelete(layer2);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, resizeWideColorGamut) {
-    OffscreenBufferPool pool;
-
-    auto layer = pool.get(renderThread.renderState(), 64u, 64u, true);
-
-    // resize in place
-    ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
-    EXPECT_EQ(60u, layer->viewportWidth);
-    EXPECT_EQ(55u, layer->viewportHeight);
-    EXPECT_EQ(64u, layer->texture.width());
-    EXPECT_EQ(64u, layer->texture.height());
-
-    EXPECT_TRUE(layer->wideColorGamut);
-    EXPECT_EQ(64u * 64u * 8u, layer->getSizeInBytes());
-
-    // resized to use different object in pool
-    auto layer2 = pool.get(renderThread.renderState(), 128u, 128u, true);
-    pool.putOrDelete(layer2);
-    ASSERT_EQ(1u, pool.getCount());
-
-    // add a non-wide gamut layer
-    auto layer3 = pool.get(renderThread.renderState(), 128u, 128u);
-    pool.putOrDelete(layer3);
-    ASSERT_EQ(2u, pool.getCount());
-
-    ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
-    EXPECT_EQ(120u, layer2->viewportWidth);
-    EXPECT_EQ(125u, layer2->viewportHeight);
-    EXPECT_EQ(128u, layer2->texture.width());
-    EXPECT_EQ(128u, layer2->texture.height());
-
-    EXPECT_TRUE(layer2->wideColorGamut);
-    EXPECT_EQ(128u * 128u * 8u, layer2->getSizeInBytes());
-
-    pool.putOrDelete(layer2);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, putAndDestroy) {
-    OffscreenBufferPool pool;
-    // layer too big to return to the pool
-    // Note: this relies on the fact that the pool won't reject based on max texture size
-    auto hugeLayer = pool.get(renderThread.renderState(), pool.getMaxSize() / 64, 64);
-    EXPECT_GT(hugeLayer->getSizeInBytes(), pool.getMaxSize());
-    pool.putOrDelete(hugeLayer);
-    EXPECT_EQ(0u, pool.getCount());  // failed to put (so was destroyed instead)
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, clear) {
-    EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer));
-    OffscreenBufferPool pool;
-
-    // Create many buffers, with several at each size
-    std::vector<OffscreenBuffer*> buffers;
-    for (int size = 32; size <= 128; size += 32) {
-        for (int i = 0; i < 10; i++) {
-            buffers.push_back(pool.get(renderThread.renderState(), size, size));
-        }
-    }
-    EXPECT_EQ(0u, pool.getCount()) << "Expect nothing inside";
-    for (auto& buffer : buffers) pool.putOrDelete(buffer);
-    EXPECT_EQ(40u, pool.getCount()) << "Expect all items added";
-    EXPECT_EQ(40, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer));
-    pool.clear();
-    EXPECT_EQ(0u, pool.getCount()) << "Expect all items cleared";
-
-    EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer));
-}
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
deleted file mode 100644
index 8a9e34f..0000000
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <DeferredLayerUpdater.h>
-#include <RecordedOp.h>
-#include <RecordingCanvas.h>
-#include <hwui/Paint.h>
-#include <minikin/Layout.h>
-#include <tests/common/TestUtils.h>
-#include <utils/Color.h>
-
-#include <SkGradientShader.h>
-#include <SkImagePriv.h>
-#include <SkShader.h>
-
-namespace android {
-namespace uirenderer {
-
-static void playbackOps(const DisplayList& displayList,
-                        std::function<void(const RecordedOp&)> opReceiver) {
-    for (auto& chunk : displayList.getChunks()) {
-        for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
-            RecordedOp* op = displayList.getOps()[opIndex];
-            opReceiver(*op);
-        }
-    }
-}
-
-static void validateSingleOp(std::unique_ptr<DisplayList>& dl,
-                             std::function<void(const RecordedOp& op)> opValidator) {
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
-    opValidator(*(dl->getOps()[0]));
-}
-
-// The RecordingCanvas is only ever used by the OpenGL RenderPipeline and never when Skia is in use.
-// Thus, even though many of these test are not directly dependent on the current RenderPipeline, we
-// set them all to be OPENGL_PIPELINE_TESTs in case the underlying code in RecordingCanvas ever
-// changes to require the use of the OPENGL_PIPELINE. Currently the textureLayer test is the only
-// test that requires being an OPENGL_PIPELINE_TEST.
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, emptyPlayback) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.restore();
-    });
-    playbackOps(*dl, [](const RecordedOp& op) { ADD_FAILURE(); });
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, clipRect) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(0, 0, 100, 100, SkClipOp::kIntersect);
-        canvas.drawRect(0, 0, 50, 50, SkPaint());
-        canvas.drawRect(50, 50, 100, 100, SkPaint());
-        canvas.restore();
-    });
-
-    ASSERT_EQ(2u, dl->getOps().size()) << "Must be exactly two ops";
-    EXPECT_CLIP_RECT(Rect(100, 100), dl->getOps()[0]->localClip);
-    EXPECT_CLIP_RECT(Rect(100, 100), dl->getOps()[1]->localClip);
-    EXPECT_EQ(dl->getOps()[0]->localClip, dl->getOps()[1]->localClip)
-            << "Clip should be serialized once";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, emptyClipRect) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(0, 0, 100, 100, SkClipOp::kIntersect);
-        canvas.clipRect(100, 100, 200, 200, SkClipOp::kIntersect);
-        canvas.drawRect(0, 0, 50, 50, SkPaint());  // rejected at record time
-        canvas.restore();
-    });
-    ASSERT_EQ(0u, dl->getOps().size()) << "Must be zero ops. Rect should be rejected.";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, emptyPaintRejection) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        SkPaint emptyPaint;
-        emptyPaint.setColor(Color::Transparent);
-
-        float points[] = {0, 0, 200, 200};
-        canvas.drawPoints(points, 4, emptyPaint);
-        canvas.drawLines(points, 4, emptyPaint);
-        canvas.drawRect(0, 0, 200, 200, emptyPaint);
-        canvas.drawRegion(SkRegion(SkIRect::MakeWH(200, 200)), emptyPaint);
-        canvas.drawRoundRect(0, 0, 200, 200, 10, 10, emptyPaint);
-        canvas.drawCircle(100, 100, 100, emptyPaint);
-        canvas.drawOval(0, 0, 200, 200, emptyPaint);
-        canvas.drawArc(0, 0, 200, 200, 0, 360, true, emptyPaint);
-        SkPath path;
-        path.addRect(0, 0, 200, 200);
-        canvas.drawPath(path, emptyPaint);
-    });
-    EXPECT_EQ(0u, dl->getOps().size()) << "Op should be rejected";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawArc) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.drawArc(0, 0, 200, 200, 0, 180, true, SkPaint());
-        canvas.drawArc(0, 0, 100, 100, 0, 360, true, SkPaint());
-    });
-
-    auto&& ops = dl->getOps();
-    ASSERT_EQ(2u, ops.size()) << "Must be exactly two ops";
-    EXPECT_EQ(RecordedOpId::ArcOp, ops[0]->opId);
-    EXPECT_EQ(Rect(200, 200), ops[0]->unmappedBounds);
-
-    EXPECT_EQ(RecordedOpId::OvalOp, ops[1]->opId) << "Circular arcs should be converted to ovals";
-    EXPECT_EQ(Rect(100, 100), ops[1]->unmappedBounds);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawLines) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        SkPaint paint;
-        paint.setStrokeWidth(
-                20);  // doesn't affect recorded bounds - would be resolved at bake time
-        float points[] = {0, 0, 20, 10, 30, 40, 90};  // NB: only 1 valid line
-        canvas.drawLines(&points[0], 7, paint);
-    });
-
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
-    auto op = dl->getOps()[0];
-    ASSERT_EQ(RecordedOpId::LinesOp, op->opId);
-    EXPECT_EQ(4, ((LinesOp*)op)->floatCount)
-            << "float count must be rounded down to closest multiple of 4";
-    EXPECT_EQ(Rect(20, 10), op->unmappedBounds)
-            << "unmapped bounds must be size of line, and not outset for stroke width";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawRect) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            100, 200, [](RecordingCanvas& canvas) { canvas.drawRect(10, 20, 90, 180, SkPaint()); });
-
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
-    auto op = *(dl->getOps()[0]);
-    ASSERT_EQ(RecordedOpId::RectOp, op.opId);
-    EXPECT_EQ(nullptr, op.localClip);
-    EXPECT_EQ(Rect(10, 20, 90, 180), op.unmappedBounds);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawRoundRect) {
-    // Round case - stays rounded
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        canvas.drawRoundRect(0, 0, 100, 100, 10, 10, SkPaint());
-    });
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
-    ASSERT_EQ(RecordedOpId::RoundRectOp, dl->getOps()[0]->opId);
-
-    // Non-rounded case - turned into drawRect
-    dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        canvas.drawRoundRect(0, 0, 100, 100, 0, -1, SkPaint());
-    });
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
-    ASSERT_EQ(RecordedOpId::RectOp, dl->getOps()[0]->opId)
-            << "Non-rounded rects should be converted";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawGlyphs) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(20);
-        TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
-    });
-
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        count++;
-        ASSERT_EQ(RecordedOpId::TextOp, op.opId);
-        EXPECT_EQ(nullptr, op.localClip);
-        EXPECT_TRUE(op.localMatrix.isIdentity());
-        EXPECT_TRUE(op.unmappedBounds.contains(25, 15, 50, 25))
-                << "Op expected to be 25+ pixels wide, 10+ pixels tall";
-    });
-    ASSERT_EQ(1, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawGlyphs_strikeThruAndUnderline) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(20);
-        for (int i = 0; i < 2; i++) {
-            for (int j = 0; j < 2; j++) {
-                uint32_t flags = paint.getFlags();
-                if (i != 0) {
-                    flags |= SkPaint::kUnderlineText_ReserveFlag;
-                } else {
-                    flags &= ~SkPaint::kUnderlineText_ReserveFlag;
-                }
-                if (j != 0) {
-                    flags |= SkPaint::kStrikeThruText_ReserveFlag;
-                } else {
-                    flags &= ~SkPaint::kStrikeThruText_ReserveFlag;
-                }
-                paint.setFlags(flags);
-                TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
-            }
-        }
-    });
-
-    auto ops = dl->getOps();
-    ASSERT_EQ(8u, ops.size());
-
-    int index = 0;
-    EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId);  // no underline or strikethrough
-
-    EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId);
-    EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId);  // strikethrough only
-
-    EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId);
-    EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId);  // underline only
-
-    EXPECT_EQ(RecordedOpId::TextOp, ops[index++]->opId);
-    EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId);  // underline
-    EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId);  // strikethrough
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawGlyphs_forceAlignLeft) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(20);
-        paint.setTextAlign(SkPaint::kLeft_Align);
-        TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
-        paint.setTextAlign(SkPaint::kCenter_Align);
-        TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
-        paint.setTextAlign(SkPaint::kRight_Align);
-        TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
-    });
-
-    int count = 0;
-    float lastX = FLT_MAX;
-    playbackOps(*dl, [&count, &lastX](const RecordedOp& op) {
-        count++;
-        ASSERT_EQ(RecordedOpId::TextOp, op.opId);
-        EXPECT_EQ(SkPaint::kLeft_Align, op.paint->getTextAlign())
-                << "recorded drawText commands must force kLeft_Align on their paint";
-
-        // verify TestUtils alignment offsetting (TODO: move asserts to Canvas base class)
-        EXPECT_GT(lastX, ((const TextOp&)op).x)
-                << "x coordinate should reduce across each of the draw commands, from alignment";
-        lastX = ((const TextOp&)op).x;
-    });
-    ASSERT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawColor) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.drawColor(Color::Black, SkBlendMode::kSrcOver);
-    });
-
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
-    auto op = *(dl->getOps()[0]);
-    EXPECT_EQ(RecordedOpId::ColorOp, op.opId);
-    EXPECT_EQ(nullptr, op.localClip);
-    EXPECT_TRUE(op.unmappedBounds.isEmpty()) << "Expect undefined recorded bounds";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, backgroundAndImage) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        sk_sp<Bitmap> bitmap(TestUtils::createBitmap(25, 25));
-        SkPaint paint;
-        paint.setColor(SK_ColorBLUE);
-
-        canvas.save(SaveFlags::MatrixClip);
-        {
-            // a background!
-            canvas.save(SaveFlags::MatrixClip);
-            canvas.drawRect(0, 0, 100, 200, paint);
-            canvas.restore();
-        }
-        {
-            // an image!
-            canvas.save(SaveFlags::MatrixClip);
-            canvas.translate(25, 25);
-            canvas.scale(2, 2);
-            canvas.drawBitmap(*bitmap, 0, 0, nullptr);
-            canvas.restore();
-        }
-        canvas.restore();
-    });
-
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        if (count == 0) {
-            ASSERT_EQ(RecordedOpId::RectOp, op.opId);
-            ASSERT_NE(nullptr, op.paint);
-            EXPECT_EQ(SK_ColorBLUE, op.paint->getColor());
-            EXPECT_EQ(Rect(100, 200), op.unmappedBounds);
-            EXPECT_EQ(nullptr, op.localClip);
-
-            Matrix4 expectedMatrix;
-            expectedMatrix.loadIdentity();
-            EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix);
-        } else {
-            ASSERT_EQ(RecordedOpId::BitmapOp, op.opId);
-            EXPECT_EQ(nullptr, op.paint);
-            EXPECT_EQ(Rect(25, 25), op.unmappedBounds);
-            EXPECT_EQ(nullptr, op.localClip);
-
-            Matrix4 expectedMatrix;
-            expectedMatrix.loadTranslate(25, 25, 0);
-            expectedMatrix.scale(2, 2, 1);
-            EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix);
-        }
-        count++;
-    });
-    ASSERT_EQ(2, count);
-}
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(RecordingCanvas, textureLayer) {
-    auto layerUpdater =
-            TestUtils::createTextureLayerUpdater(renderThread, 100, 100, SkMatrix::MakeTrans(5, 5));
-
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            200, 200,
-            [&layerUpdater](RecordingCanvas& canvas) { canvas.drawLayer(layerUpdater.get()); });
-
-    validateSingleOp(dl, [](const RecordedOp& op) {
-        ASSERT_EQ(RecordedOpId::TextureLayerOp, op.opId);
-        ASSERT_TRUE(op.localMatrix.isIdentity()) << "Op must not apply matrix at record time.";
-    });
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_simple) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 20, 190, 180, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(10, 20, 190, 180, SkPaint());
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        Matrix4 expectedMatrix;
-        switch (count++) {
-            case 0:
-                EXPECT_EQ(RecordedOpId::BeginLayerOp, op.opId);
-                EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds);
-                EXPECT_EQ(nullptr, op.localClip);
-                EXPECT_TRUE(op.localMatrix.isIdentity());
-                break;
-            case 1:
-                EXPECT_EQ(RecordedOpId::RectOp, op.opId);
-                EXPECT_CLIP_RECT(Rect(180, 160), op.localClip);
-                EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds);
-                expectedMatrix.loadTranslate(-10, -20, 0);
-                EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix);
-                break;
-            case 2:
-                EXPECT_EQ(RecordedOpId::EndLayerOp, op.opId);
-                // Don't bother asserting recording state data - it's not used
-                break;
-            default:
-                ADD_FAILURE();
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_rounding) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10.25f, 10.75f, 89.25f, 89.75f, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(20, 20, 80, 80, SkPaint());
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        Matrix4 expectedMatrix;
-        switch (count++) {
-            case 0:
-                EXPECT_EQ(RecordedOpId::BeginLayerOp, op.opId);
-                EXPECT_EQ(Rect(10, 10, 90, 90), op.unmappedBounds) << "Expect bounds rounded out";
-                break;
-            case 1:
-                EXPECT_EQ(RecordedOpId::RectOp, op.opId);
-                expectedMatrix.loadTranslate(-10, -10, 0);
-                EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix) << "Expect rounded offset";
-                break;
-            case 2:
-                EXPECT_EQ(RecordedOpId::EndLayerOp, op.opId);
-                // Don't bother asserting recording state data - it's not used
-                break;
-            default:
-                ADD_FAILURE();
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_missingRestore) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(0, 0, 200, 200, SkPaint());
-        // Note: restore omitted, shouldn't result in unmatched save
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        if (count++ == 2) {
-            EXPECT_EQ(RecordedOpId::EndLayerOp, op.opId);
-        }
-    });
-    EXPECT_EQ(3, count) << "Missing a restore shouldn't result in an unmatched saveLayer";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_simpleUnclipped) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0);  // unclipped
-        canvas.drawRect(10, 20, 190, 180, SkPaint());
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        switch (count++) {
-            case 0:
-                EXPECT_EQ(RecordedOpId::BeginUnclippedLayerOp, op.opId);
-                EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds);
-                EXPECT_EQ(nullptr, op.localClip);
-                EXPECT_TRUE(op.localMatrix.isIdentity());
-                break;
-            case 1:
-                EXPECT_EQ(RecordedOpId::RectOp, op.opId);
-                EXPECT_EQ(nullptr, op.localClip);
-                EXPECT_EQ(Rect(10, 20, 190, 180), op.unmappedBounds);
-                EXPECT_TRUE(op.localMatrix.isIdentity());
-                break;
-            case 2:
-                EXPECT_EQ(RecordedOpId::EndUnclippedLayerOp, op.opId);
-                // Don't bother asserting recording state data - it's not used
-                break;
-            default:
-                ADD_FAILURE();
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_addClipFlag) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(10, 20, 190, 180, SkClipOp::kIntersect);
-        canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0);  // unclipped
-        canvas.drawRect(10, 20, 190, 180, SkPaint());
-        canvas.restore();
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        if (count++ == 0) {
-            EXPECT_EQ(RecordedOpId::BeginLayerOp, op.opId)
-                    << "Clip + unclipped saveLayer should result in a clipped layer";
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_viewportCrop) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        // shouldn't matter, since saveLayer will clip to its bounds
-        canvas.clipRect(-1000, -1000, 1000, 1000, SkClipOp::kReplace_deprecated);
-
-        canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        if (count++ == 1) {
-            Matrix4 expectedMatrix;
-            EXPECT_EQ(RecordedOpId::RectOp, op.opId);
-            EXPECT_CLIP_RECT(Rect(100, 100), op.localClip)  // Recorded clip rect should be
-            // intersection of viewport and saveLayer bounds, in layer space;
-            EXPECT_EQ(Rect(400, 400), op.unmappedBounds);
-            expectedMatrix.loadTranslate(-100, -100, 0);
-            EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix);
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_rotateUnclipped) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.translate(100, 100);
-        canvas.rotate(45);
-        canvas.translate(-50, -50);
-
-        canvas.saveLayerAlpha(0, 0, 100, 100, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(0, 0, 100, 100, SkPaint());
-        canvas.restore();
-
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        if (count++ == 1) {
-            EXPECT_EQ(RecordedOpId::RectOp, op.opId);
-            EXPECT_CLIP_RECT(Rect(100, 100), op.localClip);
-            EXPECT_EQ(Rect(100, 100), op.unmappedBounds);
-            EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), op.localMatrix)
-                    << "Recorded op shouldn't see any canvas transform before the saveLayer";
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_rotateClipped) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.translate(100, 100);
-        canvas.rotate(45);
-        canvas.translate(-200, -200);
-
-        // area of saveLayer will be clipped to parent viewport, so we ask for 400x400...
-        canvas.saveLayerAlpha(0, 0, 400, 400, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-        canvas.restore();
-
-        canvas.restore();
-    });
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        if (count++ == 1) {
-            Matrix4 expectedMatrix;
-            EXPECT_EQ(RecordedOpId::RectOp, op.opId);
-
-            // ...and get about 58.6, 58.6, 341.4 341.4, because the bounds are clipped by
-            // the parent 200x200 viewport, but prior to rotation
-            ASSERT_NE(nullptr, op.localClip);
-            ASSERT_EQ(ClipMode::Rectangle, op.localClip->mode);
-            // NOTE: this check relies on saveLayer altering the clip post-viewport init. This
-            // causes the clip to be recorded by contained draw commands, though it's not necessary
-            // since the same clip will be computed at draw time. If such a change is made, this
-            // check could be done at record time by querying the clip, or the clip could be altered
-            // slightly so that it is serialized.
-            EXPECT_EQ(Rect(59, 59, 341, 341), op.localClip->rect);
-            EXPECT_EQ(Rect(400, 400), op.unmappedBounds);
-            expectedMatrix.loadIdentity();
-            EXPECT_MATRIX_APPROX_EQ(expectedMatrix, op.localMatrix);
-        }
-    });
-    EXPECT_EQ(3, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, saveLayer_rejectBegin) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.translate(0, -20);  // avoid identity case
-        // empty clip rect should force layer + contents to be rejected
-        canvas.clipRect(0, -20, 200, -20, SkClipOp::kIntersect);
-        canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer);
-        canvas.drawRect(0, 0, 200, 200, SkPaint());
-        canvas.restore();
-        canvas.restore();
-    });
-
-    ASSERT_EQ(0u, dl->getOps().size()) << "Begin/Rect/End should all be rejected.";
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawRenderNode_rejection) {
-    auto child =
-            TestUtils::createNode(50, 50, 150, 150, [](RenderProperties& props, Canvas& canvas) {
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            200, 200, [&child](RecordingCanvas& canvas) {
-                canvas.clipRect(0, 0, 0, 0, SkClipOp::kIntersect);  // empty clip, reject node
-                canvas.drawRenderNode(child.get());  // shouldn't crash when rejecting node...
-            });
-    ASSERT_TRUE(dl->isEmpty());
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawRenderNode_projection) {
-    sp<RenderNode> background =
-            TestUtils::createNode(50, 50, 150, 150, [](RenderProperties& props, Canvas& canvas) {
-                SkPaint paint;
-                paint.setColor(SK_ColorWHITE);
-                canvas.drawRect(0, 0, 100, 100, paint);
-            });
-    {
-        background->mutateStagingProperties().setProjectionReceiver(false);
-
-        // NO RECEIVER PRESENT
-        auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-                200, 200, [&background](RecordingCanvas& canvas) {
-                    canvas.drawRect(0, 0, 100, 100, SkPaint());
-                    canvas.drawRenderNode(background.get());
-                    canvas.drawRect(0, 0, 100, 100, SkPaint());
-                });
-        EXPECT_EQ(-1, dl->projectionReceiveIndex)
-                << "no projection receiver should have been observed";
-    }
-    {
-        background->mutateStagingProperties().setProjectionReceiver(true);
-
-        // RECEIVER PRESENT
-        auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-                200, 200, [&background](RecordingCanvas& canvas) {
-                    canvas.drawRect(0, 0, 100, 100, SkPaint());
-                    canvas.drawRenderNode(background.get());
-                    canvas.drawRect(0, 0, 100, 100, SkPaint());
-                });
-
-        ASSERT_EQ(3u, dl->getOps().size()) << "Must be three ops";
-        auto op = dl->getOps()[1];
-        EXPECT_EQ(RecordedOpId::RenderNodeOp, op->opId);
-        EXPECT_EQ(1, dl->projectionReceiveIndex) << "correct projection receiver not identified";
-
-        // verify the behavior works even though projection receiver hasn't been sync'd yet
-        EXPECT_TRUE(background->stagingProperties().isProjectionReceiver());
-        EXPECT_FALSE(background->properties().isProjectionReceiver());
-    }
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, firstClipWillReplace) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        // since no explicit clip set on canvas, this should be the one observed on op:
-        canvas.clipRect(-100, -100, 300, 300, SkClipOp::kIntersect);
-
-        SkPaint paint;
-        paint.setColor(SK_ColorWHITE);
-        canvas.drawRect(0, 0, 100, 100, paint);
-
-        canvas.restore();
-    });
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op";
-    // first clip must be preserved, even if it extends beyond canvas bounds
-    EXPECT_CLIP_RECT(Rect(-100, -100, 300, 300), dl->getOps()[0]->localClip);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, replaceClipIntersectWithRoot) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
-        canvas.save(SaveFlags::MatrixClip);
-        canvas.clipRect(-10, -10, 110, 110, SkClipOp::kReplace_deprecated);
-        canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
-        canvas.restore();
-    });
-    ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op";
-    // first clip must be preserved, even if it extends beyond canvas bounds
-    EXPECT_CLIP_RECT(Rect(-10, -10, 110, 110), dl->getOps()[0]->localClip);
-    EXPECT_TRUE(dl->getOps()[0]->localClip->intersectWithRoot);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, insertReorderBarrier) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-        canvas.insertReorderBarrier(true);
-        canvas.insertReorderBarrier(false);
-        canvas.insertReorderBarrier(false);
-        canvas.insertReorderBarrier(true);
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-        canvas.insertReorderBarrier(false);
-    });
-
-    auto chunks = dl->getChunks();
-    EXPECT_EQ(0u, chunks[0].beginOpIndex);
-    EXPECT_EQ(1u, chunks[0].endOpIndex);
-    EXPECT_FALSE(chunks[0].reorderChildren);
-
-    EXPECT_EQ(1u, chunks[1].beginOpIndex);
-    EXPECT_EQ(2u, chunks[1].endOpIndex);
-    EXPECT_TRUE(chunks[1].reorderChildren);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, insertReorderBarrier_clip) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        // first chunk: no recorded clip
-        canvas.insertReorderBarrier(true);
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-
-        // second chunk: no recorded clip, since inorder region
-        canvas.clipRect(0, 0, 200, 200, SkClipOp::kIntersect);
-        canvas.insertReorderBarrier(false);
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-
-        // third chunk: recorded clip
-        canvas.insertReorderBarrier(true);
-        canvas.drawRect(0, 0, 400, 400, SkPaint());
-    });
-
-    auto chunks = dl->getChunks();
-    ASSERT_EQ(3u, chunks.size());
-
-    EXPECT_TRUE(chunks[0].reorderChildren);
-    EXPECT_EQ(nullptr, chunks[0].reorderClip);
-
-    EXPECT_FALSE(chunks[1].reorderChildren);
-    EXPECT_EQ(nullptr, chunks[1].reorderClip);
-
-    EXPECT_TRUE(chunks[2].reorderChildren);
-    ASSERT_NE(nullptr, chunks[2].reorderClip);
-    EXPECT_EQ(Rect(200, 200), chunks[2].reorderClip->rect);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, refPaint) {
-    SkPaint paint;
-
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            200, 200, [&paint](RecordingCanvas& canvas) {
-                paint.setColor(SK_ColorBLUE);
-                // first two should use same paint
-                canvas.drawRect(0, 0, 200, 10, paint);
-                SkPaint paintCopy(paint);
-                canvas.drawRect(0, 10, 200, 20, paintCopy);
-
-                // only here do we use different paint ptr
-                paint.setColor(SK_ColorRED);
-                canvas.drawRect(0, 20, 200, 30, paint);
-            });
-    auto ops = dl->getOps();
-    ASSERT_EQ(3u, ops.size());
-
-    // first two are the same
-    EXPECT_NE(nullptr, ops[0]->paint);
-    EXPECT_NE(&paint, ops[0]->paint);
-    EXPECT_EQ(ops[0]->paint, ops[1]->paint);
-
-    // last is different, but still copied / non-null
-    EXPECT_NE(nullptr, ops[2]->paint);
-    EXPECT_NE(ops[0]->paint, ops[2]->paint);
-    EXPECT_NE(&paint, ops[2]->paint);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, refBitmap) {
-    sk_sp<Bitmap> bitmap(TestUtils::createBitmap(100, 100));
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            100, 100,
-            [&bitmap](RecordingCanvas& canvas) { canvas.drawBitmap(*bitmap, 0, 0, nullptr); });
-    auto& bitmaps = dl->getBitmapResources();
-    EXPECT_EQ(1u, bitmaps.size());
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, refBitmapInShader_bitmapShader) {
-    sk_sp<Bitmap> bitmap = TestUtils::createBitmap(100, 100);
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            100, 100, [&bitmap](RecordingCanvas& canvas) {
-                SkPaint paint;
-                SkBitmap skBitmap;
-                bitmap->getSkBitmap(&skBitmap);
-                sk_sp<SkImage> image =
-                        SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
-                sk_sp<SkShader> shader =
-                        image->makeShader(SkShader::TileMode::kClamp_TileMode,
-                                          SkShader::TileMode::kClamp_TileMode, nullptr);
-                paint.setShader(std::move(shader));
-                canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
-            });
-    auto& bitmaps = dl->getBitmapResources();
-    EXPECT_EQ(1u, bitmaps.size());
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, refBitmapInShader_composeShader) {
-    sk_sp<Bitmap> bitmap = TestUtils::createBitmap(100, 100);
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(
-            100, 100, [&bitmap](RecordingCanvas& canvas) {
-                SkPaint paint;
-                SkBitmap skBitmap;
-                bitmap->getSkBitmap(&skBitmap);
-                sk_sp<SkImage> image =
-                        SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
-                sk_sp<SkShader> shader1 =
-                        image->makeShader(SkShader::TileMode::kClamp_TileMode,
-                                          SkShader::TileMode::kClamp_TileMode, nullptr);
-
-                SkPoint center;
-                center.set(50, 50);
-                SkColor colors[2];
-                colors[0] = Color::Black;
-                colors[1] = Color::White;
-                sk_sp<SkShader> shader2 = SkGradientShader::MakeRadial(
-                        center, 50, colors, nullptr, 2, SkShader::TileMode::kRepeat_TileMode);
-
-                sk_sp<SkShader> composeShader = SkShader::MakeComposeShader(
-                        std::move(shader1), std::move(shader2), SkBlendMode::kMultiply);
-                paint.setShader(std::move(composeShader));
-                canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
-            });
-    auto& bitmaps = dl->getBitmapResources();
-    EXPECT_EQ(1u, bitmaps.size());
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawText) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        Paint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(20);
-        TestUtils::drawUtf8ToCanvas(&canvas, "HELLO", paint, 25, 25);
-    });
-
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        count++;
-        ASSERT_EQ(RecordedOpId::TextOp, op.opId);
-        EXPECT_EQ(nullptr, op.localClip);
-        EXPECT_TRUE(op.localMatrix.isIdentity());
-        EXPECT_TRUE(op.unmappedBounds.getHeight() >= 10);
-        EXPECT_TRUE(op.unmappedBounds.getWidth() >= 25);
-    });
-    ASSERT_EQ(1, count);
-}
-
-OPENGL_PIPELINE_TEST(RecordingCanvas, drawTextInHighContrast) {
-    Properties::enableHighContrastText = true;
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        Paint paint;
-        paint.setColor(SK_ColorWHITE);
-        paint.setAntiAlias(true);
-        paint.setTextSize(20);
-        TestUtils::drawUtf8ToCanvas(&canvas, "HELLO", paint, 25, 25);
-    });
-    Properties::enableHighContrastText = false;
-
-    int count = 0;
-    playbackOps(*dl, [&count](const RecordedOp& op) {
-        ASSERT_EQ(RecordedOpId::TextOp, op.opId);
-        if (count++ == 0) {
-            EXPECT_EQ(SK_ColorBLACK, op.paint->getColor());
-            EXPECT_EQ(SkPaint::kStrokeAndFill_Style, op.paint->getStyle());
-        } else {
-            EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
-            EXPECT_EQ(SkPaint::kFill_Style, op.paint->getStyle());
-        }
-
-    });
-    ASSERT_EQ(2, count);
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index 1d7dc3d..2e4de0b 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -26,41 +26,6 @@
 using namespace android;
 using namespace android::uirenderer;
 
-/**
- * Verify that we get the same culling bounds for text for (1) drawing glyphs
- * directly to a Canvas or (2) going through a SkPicture as an intermediate step.
- */
-OPENGL_PIPELINE_TEST(SkiaCanvasProxy, drawGlyphsViaPicture) {
-    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        // setup test variables
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setTextSize(20);
-        static const char* text = "testing text bounds";
-
-        // draw text directly into Recording canvas
-        TestUtils::drawUtf8ToCanvas(&canvas, text, paint, 25, 25);
-
-        // record the same text draw into a SkPicture and replay it into a Recording canvas
-        SkPictureRecorder recorder;
-        SkCanvas* skCanvas = recorder.beginRecording(200, 200, NULL, 0);
-        std::unique_ptr<Canvas> pictCanvas(Canvas::create_canvas(skCanvas));
-        TestUtils::drawUtf8ToCanvas(pictCanvas.get(), text, paint, 25, 25);
-        sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
-
-        canvas.asSkCanvas()->drawPicture(picture);
-    });
-
-    // verify that the text bounds and matrices match
-    ASSERT_EQ(2U, dl->getOps().size());
-    auto directOp = dl->getOps()[0];
-    auto pictureOp = dl->getOps()[1];
-    ASSERT_EQ(RecordedOpId::TextOp, directOp->opId);
-    EXPECT_EQ(directOp->opId, pictureOp->opId);
-    EXPECT_EQ(directOp->unmappedBounds, pictureOp->unmappedBounds);
-    EXPECT_EQ(directOp->localMatrix, pictureOp->localMatrix);
-}
-
 TEST(SkiaCanvas, drawShadowLayer) {
     auto surface = SkSurface::MakeRasterN32Premul(10, 10);
     SkiaCanvas canvas(surface->getCanvas());
diff --git a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
deleted file mode 100644
index 92d05e4..0000000
--- a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "GammaFontRenderer.h"
-#include "TextDropShadowCache.h"
-#include "tests/common/TestUtils.h"
-#include "utils/Blur.h"
-
-#include <SkPaint.h>
-
-using namespace android;
-using namespace android::uirenderer;
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, addRemove) {
-    SkPaint paint;
-    paint.setTextSize(20);
-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
-    GammaFontRenderer gammaFontRenderer;
-    FontRenderer& fontRenderer = gammaFontRenderer.getFontRenderer();
-    fontRenderer.setFont(&paint, SkMatrix::I());
-    TextDropShadowCache cache(MB(5));
-    cache.setFontRenderer(fontRenderer);
-
-    std::vector<glyph_t> glyphs;
-    std::vector<float> positions;
-    float totalAdvance;
-    uirenderer::Rect bounds;
-    TestUtils::layoutTextUnscaled(paint, "This is a test", &glyphs, &positions, &totalAdvance,
-                                  &bounds);
-    EXPECT_TRUE(bounds.contains(5, -10, 100, 0)) << "Expect input to be nontrivially sized";
-
-    ShadowTexture* texture = cache.get(&paint, glyphs.data(), glyphs.size(), 10, positions.data());
-
-    ASSERT_TRUE(texture);
-    ASSERT_FALSE(texture->cleanup);
-    ASSERT_EQ((uint32_t)texture->objectSize(), cache.getSize());
-    ASSERT_TRUE(cache.getSize());
-    cache.clear();
-    ASSERT_EQ(cache.getSize(), 0u);
-}
diff --git a/libs/hwui/tests/unit/TextureCacheTests.cpp b/libs/hwui/tests/unit/TextureCacheTests.cpp
deleted file mode 100644
index ab740dd..0000000
--- a/libs/hwui/tests/unit/TextureCacheTests.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "Extensions.h"
-#include "TextureCache.h"
-#include "tests/common/TestUtils.h"
-
-using namespace android;
-using namespace android::uirenderer;
-
-RENDERTHREAD_OPENGL_PIPELINE_TEST(TextureCache, clear) {
-    TextureCache cache;
-    ASSERT_EQ(cache.getSize(), 0u);
-    // it is not 0, because FontRenderer allocates one texture
-    int initialCount = GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture);
-    SkBitmap skBitmap;
-    SkImageInfo info = SkImageInfo::Make(100, 100, kN32_SkColorType, kPremul_SkAlphaType);
-    skBitmap.setInfo(info);
-    sk_sp<Bitmap> hwBitmap(renderThread.allocateHardwareBitmap(skBitmap));
-    cache.get(hwBitmap.get());
-    ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount + 1);
-    cache.clear();
-    ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount);
-}
diff --git a/native/webview/plat_support/draw_gl_functor.cpp b/native/webview/plat_support/draw_gl_functor.cpp
index d54f558..7cb49da 100644
--- a/native/webview/plat_support/draw_gl_functor.cpp
+++ b/native/webview/plat_support/draw_gl_functor.cpp
@@ -21,7 +21,6 @@
 
 #include "draw_gl.h"
 
-#include <Properties.h>
 #include <errno.h>
 #include <jni.h>
 #include <private/hwui/DrawGlInfo.h>
@@ -54,13 +53,7 @@
     }
 
     AwDrawGLInfo aw_info;
-    // TODO(boliu): Remove property check once OpenGL fallback is removed.
-    auto render_pipeline_type =
-        android::uirenderer::Properties::getRenderPipelineType();
-    aw_info.version = (render_pipeline_type ==
-                       android::uirenderer::RenderPipelineType::OpenGL)
-                          ? 2
-                          : kAwDrawGLInfoVersion;
+    aw_info.version = kAwDrawGLInfoVersion;
     switch (what) {
       case DrawGlInfo::kModeDraw: {
         aw_info.mode = AwDrawGLInfo::kModeDraw;
