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 09f0b06d..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;
