diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index ade82f6..e2f2324 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -54,6 +54,7 @@
     srcs: [
         "src/planner/LayerState.cpp",
         "src/planner/Planner.cpp",
+        "src/planner/Predictor.cpp",
         "src/ClientCompositionRequestCache.cpp",
         "src/CompositionEngine.cpp",
         "src/Display.cpp",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index ae35fb0..044ddd8 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -100,6 +100,7 @@
     const ReleasedLayers& getReleasedLayersForTest() const;
     void setDisplayColorProfileForTest(std::unique_ptr<compositionengine::DisplayColorProfile>);
     void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
+    bool plannerEnabled() const { return mPlanner != nullptr; }
 
 protected:
     std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
index 53eca01..ad53d27 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
@@ -18,9 +18,11 @@
 
 #include <compositionengine/Output.h>
 #include <compositionengine/impl/planner/LayerState.h>
+#include <compositionengine/impl/planner/Predictor.h>
 #include <utils/String16.h>
 #include <utils/Vector.h>
 
+#include <optional>
 #include <string>
 #include <unordered_map>
 
@@ -39,10 +41,23 @@
     void plan(
             compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers);
 
+    // Updates the Planner with the current set of layers after a composition strategy is
+    // determined.
+    void reportFinalPlan(
+            compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers);
+
     void dump(const Vector<String16>& args, std::string&);
 
 private:
+    void dumpUsage(std::string&) const;
+
     std::unordered_map<LayerId, LayerState> mPreviousLayers;
+
+    std::vector<const LayerState*> mCurrentLayers;
+
+    Predictor mPredictor;
+
+    std::optional<Predictor::PredictedPlan> mPredictedPlan;
 };
 
 } // namespace compositionengine::impl::planner
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
new file mode 100644
index 0000000..38c73f7
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <compositionengine/impl/planner/LayerState.h>
+
+namespace android::compositionengine::impl::planner {
+
+class LayerStack {
+public:
+    LayerStack(const std::vector<const LayerState*>& layers) : mLayers(copyLayers(layers)) {}
+
+    struct ApproximateMatch {
+        bool operator==(const ApproximateMatch& other) const {
+            return differingIndex == other.differingIndex &&
+                    differingFields == other.differingFields;
+        }
+
+        size_t differingIndex;
+        Flags<LayerStateField> differingFields;
+    };
+
+    std::optional<ApproximateMatch> getApproximateMatch(
+            const std::vector<const LayerState*>& other) const;
+
+    void compare(const LayerStack& other, std::string& result) const {
+        if (mLayers.size() != other.mLayers.size()) {
+            base::StringAppendF(&result, "Cannot compare stacks of different sizes (%zd vs. %zd)\n",
+                                mLayers.size(), other.mLayers.size());
+            return;
+        }
+
+        for (size_t l = 0; l < mLayers.size(); ++l) {
+            const auto& thisLayer = mLayers[l];
+            const auto& otherLayer = other.mLayers[l];
+            base::StringAppendF(&result, "\n+ - - - - - - - - - Layer %d [%s]\n", thisLayer.getId(),
+                                thisLayer.getName().c_str());
+            auto comparisonOpt = thisLayer.compare(otherLayer);
+            base::StringAppendF(&result,
+                                "    %s     + - - - - - - - - - - - - - - - - - - - - - - - "
+                                "- Layer %d [%s]\n",
+                                comparisonOpt ? "         " : "Identical", otherLayer.getId(),
+                                otherLayer.getName().c_str());
+            if (comparisonOpt) {
+                result.append(*comparisonOpt);
+            }
+        }
+    }
+
+    void dump(std::string& result) const {
+        for (const LayerState& layer : mLayers) {
+            base::StringAppendF(&result, "+ - - - - - - - - - Layer %d [%s]\n", layer.getId(),
+                                layer.getName().c_str());
+            layer.dump(result);
+        }
+    }
+
+    void dumpLayerNames(std::string& result, const std::string& prefix = "  ") const {
+        for (const LayerState& layer : mLayers) {
+            result.append(prefix);
+            result.append(layer.getName());
+            result.append("\n");
+        }
+    }
+
+private:
+    std::vector<const LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
+        std::vector<const LayerState> copiedLayers;
+        copiedLayers.reserve(layers.size());
+        std::transform(layers.cbegin(), layers.cend(), std::back_inserter(copiedLayers),
+                       [](const LayerState* layerState) { return *layerState; });
+        return copiedLayers;
+    }
+
+    std::vector<const LayerState> mLayers;
+
+    // TODO(b/180976743): Tune kMaxDifferingFields
+    constexpr static int kMaxDifferingFields = 6;
+};
+
+class Plan {
+public:
+    static std::optional<Plan> fromString(const std::string&);
+
+    void reset() { mLayerTypes.clear(); }
+    void addLayerType(hardware::graphics::composer::hal::Composition type) {
+        mLayerTypes.emplace_back(type);
+    }
+
+    friend std::string to_string(const Plan& plan);
+
+    friend bool operator==(const Plan& lhs, const Plan& rhs) {
+        return lhs.mLayerTypes == rhs.mLayerTypes;
+    }
+    friend bool operator!=(const Plan& lhs, const Plan& rhs) { return !(lhs == rhs); }
+
+private:
+    std::vector<hardware::graphics::composer::hal::Composition> mLayerTypes;
+};
+
+} // namespace android::compositionengine::impl::planner
+
+namespace std {
+template <>
+struct hash<android::compositionengine::impl::planner::Plan> {
+    size_t operator()(const android::compositionengine::impl::planner::Plan& plan) const {
+        return std::hash<std::string>{}(to_string(plan));
+    }
+};
+} // namespace std
+
+namespace android::compositionengine::impl::planner {
+
+class Prediction {
+public:
+    enum class Type {
+        Exact,
+        Approximate,
+        Total,
+    };
+
+    friend std::string to_string(Type type) {
+        using namespace std::string_literals;
+
+        switch (type) {
+            case Type::Exact:
+                return "Exact";
+            case Type::Approximate:
+                return "Approximate";
+            case Type::Total:
+                return "Total";
+        }
+    }
+
+    Prediction(const std::vector<const LayerState*>& layers, Plan plan)
+          : mExampleLayerStack(layers), mPlan(std::move(plan)) {}
+
+    const LayerStack& getExampleLayerStack() const { return mExampleLayerStack; }
+    const Plan& getPlan() const { return mPlan; }
+
+    size_t getHitCount(Type type) const {
+        if (type == Type::Total) {
+            return getHitCount(Type::Exact) + getHitCount(Type::Approximate);
+        }
+        return getStatsForType(type).hitCount;
+    }
+
+    size_t getMissCount(Type type) const {
+        if (type == Type::Total) {
+            return getMissCount(Type::Exact) + getMissCount(Type::Approximate);
+        }
+        return getStatsForType(type).missCount;
+    }
+
+    void recordHit(Type type) { ++getStatsForType(type).hitCount; }
+
+    void recordMiss(Type type) { ++getStatsForType(type).missCount; }
+
+    void dump(std::string&) const;
+
+private:
+    struct Stats {
+        void dump(std::string& result) const {
+            const size_t totalAttempts = hitCount + missCount;
+            base::StringAppendF(&result, "%.2f%% (%zd/%zd)", 100.0f * hitCount / totalAttempts,
+                                hitCount, totalAttempts);
+        }
+
+        size_t hitCount = 0;
+        size_t missCount = 0;
+    };
+
+    const Stats& getStatsForType(Type type) const {
+        return (type == Type::Exact) ? mExactStats : mApproximateStats;
+    }
+
+    Stats& getStatsForType(Type type) {
+        return const_cast<Stats&>(const_cast<const Prediction*>(this)->getStatsForType(type));
+    }
+
+    LayerStack mExampleLayerStack;
+    Plan mPlan;
+
+    Stats mExactStats;
+    Stats mApproximateStats;
+};
+
+class Predictor {
+public:
+    struct PredictedPlan {
+        NonBufferHash hash;
+        Plan plan;
+        Prediction::Type type;
+    };
+
+    std::optional<PredictedPlan> getPredictedPlan(const std::vector<const LayerState*>&,
+                                                  NonBufferHash) const;
+
+    void recordResult(std::optional<PredictedPlan> predictedPlan,
+                      const std::vector<const LayerState*>&, Plan result);
+
+    void dump(std::string&) const;
+
+    void compareLayerStacks(NonBufferHash leftHash, NonBufferHash rightHash, std::string&) const;
+    void describeLayerStack(NonBufferHash, std::string&) const;
+    void listSimilarStacks(Plan, std::string&) const;
+
+private:
+    // Retrieves a prediction from either the main prediction list or from the candidate list
+    const Prediction& getPrediction(NonBufferHash) const;
+    Prediction& getPrediction(NonBufferHash);
+
+    std::optional<Plan> getExactMatch(NonBufferHash) const;
+    std::optional<NonBufferHash> getApproximateMatch(
+            const std::vector<const LayerState*>& layers) const;
+
+    void promoteIfCandidate(NonBufferHash);
+    void recordPredictedResult(PredictedPlan, const std::vector<const LayerState*>& layers,
+                               Plan result);
+    bool findSimilarPrediction(const std::vector<const LayerState*>& layers, Plan result);
+
+    void dumpPredictionsByFrequency(std::string&) const;
+
+    struct PromotionCandidate {
+        PromotionCandidate(NonBufferHash hash, Prediction&& prediction)
+              : hash(hash), prediction(std::move(prediction)) {}
+
+        NonBufferHash hash;
+        Prediction prediction;
+    };
+
+    static constexpr const size_t MAX_CANDIDATES = 4;
+    std::deque<PromotionCandidate> mCandidates;
+    decltype(mCandidates)::const_iterator getCandidateEntryByHash(NonBufferHash hash) const {
+        const auto candidateMatches = [&](const PromotionCandidate& candidate) {
+            return candidate.hash == hash;
+        };
+
+        return std::find_if(mCandidates.cbegin(), mCandidates.cend(), candidateMatches);
+    }
+
+    std::unordered_map<NonBufferHash, Prediction> mPredictions;
+    std::unordered_map<Plan, std::vector<NonBufferHash>> mSimilarStacks;
+
+    struct ApproximateStack {
+        ApproximateStack(NonBufferHash hash, LayerStack::ApproximateMatch match)
+              : hash(hash), match(match) {}
+
+        bool operator==(const ApproximateStack& other) const {
+            return hash == other.hash && match == other.match;
+        }
+
+        NonBufferHash hash;
+        LayerStack::ApproximateMatch match;
+    };
+
+    std::vector<ApproximateStack> mApproximateStacks;
+
+    mutable size_t mExactHitCount = 0;
+    mutable size_t mApproximateHitCount = 0;
+    mutable size_t mMissCount = 0;
+};
+
+} // namespace android::compositionengine::impl::planner
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 709d7c9..57b7481 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -873,6 +873,10 @@
 
     chooseCompositionStrategy();
 
+    if (mPlanner) {
+        mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
+    }
+
     mRenderSurface->prepareFrame(outputState.usesClientComposition,
                                  outputState.usesDeviceComposition);
 }
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 30f4892..619d008 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -32,6 +32,7 @@
                    std::inserter(removedLayers, removedLayers.begin()),
                    [](const auto& layer) { return layer.first; });
 
+    std::vector<LayerId> currentLayerIds;
     for (auto layer : layers) {
         LayerId id = layer->getLayerFE().getSequence();
         if (const auto layerEntry = mPreviousLayers.find(id); layerEntry != mPreviousLayers.end()) {
@@ -54,6 +55,8 @@
             mPreviousLayers.emplace(std::make_pair(id, std::move(state)));
         }
 
+        currentLayerIds.emplace_back(id);
+
         if (const auto found = removedLayers.find(id); found != removedLayers.end()) {
             removedLayers.erase(found);
         }
@@ -67,10 +70,153 @@
             mPreviousLayers.erase(removedLayer);
         }
     }
+
+    mCurrentLayers.clear();
+    mCurrentLayers.reserve(currentLayerIds.size());
+    std::transform(currentLayerIds.cbegin(), currentLayerIds.cend(),
+                   std::back_inserter(mCurrentLayers),
+                   [this](LayerId id) { return &mPreviousLayers.at(id); });
+
+    mPredictedPlan = mPredictor.getPredictedPlan(mCurrentLayers, getNonBufferHash(mCurrentLayers));
+    if (mPredictedPlan) {
+        ALOGV("[%s] Predicting plan %s", __func__, to_string(mPredictedPlan->plan).c_str());
+    } else {
+        ALOGV("[%s] No prediction found\n", __func__);
+    }
 }
 
-void Planner::dump(const Vector<String16>& /* args */, std::string& result) {
-    result.append("Dumping Planner state");
+void Planner::reportFinalPlan(
+        compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers) {
+    Plan finalPlan;
+    for (auto layer : layers) {
+        const bool forcedOrRequestedClient =
+                layer->getState().forceClientComposition || layer->requiresClientComposition();
+
+        finalPlan.addLayerType(
+                forcedOrRequestedClient
+                        ? hardware::graphics::composer::hal::Composition::CLIENT
+                        : layer->getLayerFE().getCompositionState()->compositionType);
+    }
+
+    mPredictor.recordResult(mPredictedPlan, mCurrentLayers, finalPlan);
+}
+
+void Planner::dump(const Vector<String16>& args, std::string& result) {
+    if (args.size() > 1) {
+        const String8 command(args[1]);
+        if (command == "--compare" || command == "-c") {
+            if (args.size() < 4) {
+                base::StringAppendF(&result,
+                                    "Expected two layer stack hashes, e.g. '--planner %s "
+                                    "<left_hash> <right_hash>'\n",
+                                    command.string());
+                return;
+            }
+            if (args.size() > 4) {
+                base::StringAppendF(&result,
+                                    "Too many arguments found, expected '--planner %s <left_hash> "
+                                    "<right_hash>'\n",
+                                    command.string());
+                return;
+            }
+
+            const String8 leftHashString(args[2]);
+            size_t leftHash = 0;
+            int fieldsRead = sscanf(leftHashString.string(), "%zx", &leftHash);
+            if (fieldsRead != 1) {
+                base::StringAppendF(&result, "Failed to parse %s as a size_t\n",
+                                    leftHashString.string());
+                return;
+            }
+
+            const String8 rightHashString(args[3]);
+            size_t rightHash = 0;
+            fieldsRead = sscanf(rightHashString.string(), "%zx", &rightHash);
+            if (fieldsRead != 1) {
+                base::StringAppendF(&result, "Failed to parse %s as a size_t\n",
+                                    rightHashString.string());
+                return;
+            }
+
+            mPredictor.compareLayerStacks(leftHash, rightHash, result);
+        } else if (command == "--describe" || command == "-d") {
+            if (args.size() < 3) {
+                base::StringAppendF(&result,
+                                    "Expected a layer stack hash, e.g. '--planner %s <hash>'\n",
+                                    command.string());
+                return;
+            }
+            if (args.size() > 3) {
+                base::StringAppendF(&result,
+                                    "Too many arguments found, expected '--planner %s <hash>'\n",
+                                    command.string());
+                return;
+            }
+
+            const String8 hashString(args[2]);
+            size_t hash = 0;
+            const int fieldsRead = sscanf(hashString.string(), "%zx", &hash);
+            if (fieldsRead != 1) {
+                base::StringAppendF(&result, "Failed to parse %s as a size_t\n",
+                                    hashString.string());
+                return;
+            }
+
+            mPredictor.describeLayerStack(hash, result);
+        } else if (command == "--help" || command == "-h") {
+            dumpUsage(result);
+        } else if (command == "--similar" || command == "-s") {
+            if (args.size() < 3) {
+                base::StringAppendF(&result, "Expected a plan string, e.g. '--planner %s <plan>'\n",
+                                    command.string());
+                return;
+            }
+            if (args.size() > 3) {
+                base::StringAppendF(&result,
+                                    "Too many arguments found, expected '--planner %s <plan>'\n",
+                                    command.string());
+                return;
+            }
+
+            const String8 planString(args[2]);
+            std::optional<Plan> plan = Plan::fromString(std::string(planString.string()));
+            if (!plan) {
+                base::StringAppendF(&result, "Failed to parse %s as a Plan\n", planString.string());
+                return;
+            }
+
+            mPredictor.listSimilarStacks(*plan, result);
+        } else {
+            base::StringAppendF(&result, "Unknown command '%s'\n\n", command.string());
+            dumpUsage(result);
+        }
+        return;
+    }
+
+    // If there are no specific commands, dump the usual state
+    mPredictor.dump(result);
+}
+
+void Planner::dumpUsage(std::string& result) const {
+    result.append("Planner command line interface usage\n");
+    result.append("  dumpsys SurfaceFlinger --planner <command> [arguments]\n\n");
+
+    result.append("If run without a command, dumps current Planner state\n\n");
+
+    result.append("Commands:\n");
+
+    result.append("[--compare|-c] <left_hash> <right_hash>\n");
+    result.append("  Compares the predictions <left_hash> and <right_hash> by showing differences"
+                  " in their example layer stacks\n");
+
+    result.append("[--describe|-d] <hash>\n");
+    result.append("  Prints the example layer stack and prediction statistics for <hash>\n");
+
+    result.append("[--help|-h]\n");
+    result.append("  Shows this message\n");
+
+    result.append("[--similar|-s] <plan>\n");
+    result.append("  Prints the example layer names for similar stacks matching <plan>\n");
 }
 
 } // namespace android::compositionengine::impl::planner
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Predictor.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Predictor.cpp
new file mode 100644
index 0000000..28be9db
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Predictor.cpp
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2021 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.
+ */
+
+// #define LOG_NDEBUG 0
+
+#undef LOG_TAG
+#define LOG_TAG "Planner"
+
+#include <compositionengine/impl/planner/Predictor.h>
+
+namespace android::compositionengine::impl::planner {
+
+std::optional<LayerStack::ApproximateMatch> LayerStack::getApproximateMatch(
+        const std::vector<const LayerState*>& other) const {
+    // Differing numbers of layers are never an approximate match
+    if (mLayers.size() != other.size()) {
+        return std::nullopt;
+    }
+
+    std::optional<ApproximateMatch> approximateMatch = {};
+    for (size_t i = 0; i < mLayers.size(); ++i) {
+        // Skip identical layers
+        if (mLayers[i].getHash(LayerStateField::Buffer) ==
+            other[i]->getHash(LayerStateField::Buffer)) {
+            continue;
+        }
+
+        // Skip layers where both are client-composited, since that doesn't change the
+        // composition plan
+        if (mLayers[i].getCompositionType() == hal::Composition::CLIENT &&
+            other[i]->getCompositionType() == hal::Composition::CLIENT) {
+            continue;
+        }
+
+        // If layers differ in composition type, their stacks are too different
+        if (mLayers[i].getCompositionType() != other[i]->getCompositionType()) {
+            return std::nullopt;
+        }
+
+        // If layers are not identical, but we already have a prior approximate match,
+        // the LayerStacks differ by too much, so return nothing
+        if (approximateMatch) {
+            return std::nullopt;
+        }
+
+        Flags<LayerStateField> differingFields =
+                mLayers[i].getDifferingFields(*other[i], LayerStateField::Buffer);
+
+        // If we don't find an approximate match on this layer, then the LayerStacks differ
+        // by too much, so return nothing
+        const int differingFieldCount = __builtin_popcount(differingFields.get());
+        if (differingFieldCount <= kMaxDifferingFields) {
+            approximateMatch = ApproximateMatch{
+                    .differingIndex = i,
+                    .differingFields = differingFields,
+            };
+        } else {
+            return std::nullopt;
+        }
+    }
+
+    // If we make it through the layer-by-layer comparison without an approximate match,
+    // it means that all layers were either identical or had client-composited layers in common,
+    // which don't affect the composition strategy, so return a successful result with
+    // no differences.
+    return ApproximateMatch{
+            .differingIndex = 0,
+            .differingFields = {},
+    };
+}
+
+std::optional<Plan> Plan::fromString(const std::string& string) {
+    Plan plan;
+    for (char c : string) {
+        switch (c) {
+            case 'C':
+                plan.addLayerType(hal::Composition::CLIENT);
+                continue;
+            case 'U':
+                plan.addLayerType(hal::Composition::CURSOR);
+                continue;
+            case 'D':
+                plan.addLayerType(hal::Composition::DEVICE);
+                continue;
+            case 'I':
+                plan.addLayerType(hal::Composition::INVALID);
+                continue;
+            case 'B':
+                plan.addLayerType(hal::Composition::SIDEBAND);
+                continue;
+            case 'S':
+                plan.addLayerType(hal::Composition::SOLID_COLOR);
+                continue;
+            default:
+                return std::nullopt;
+        }
+    }
+    return plan;
+}
+
+std::string to_string(const Plan& plan) {
+    std::string result;
+    for (auto type : plan.mLayerTypes) {
+        switch (type) {
+            case hal::Composition::CLIENT:
+                result.append("C");
+                break;
+            case hal::Composition::CURSOR:
+                result.append("U");
+                break;
+            case hal::Composition::DEVICE:
+                result.append("D");
+                break;
+            case hal::Composition::INVALID:
+                result.append("I");
+                break;
+            case hal::Composition::SIDEBAND:
+                result.append("B");
+                break;
+            case hal::Composition::SOLID_COLOR:
+                result.append("S");
+                break;
+        }
+    }
+    return result;
+}
+
+void Prediction::dump(std::string& result) const {
+    result.append(to_string(mPlan));
+    result.append(" [Exact ");
+    mExactStats.dump(result);
+    result.append("] [Approximate ");
+    mApproximateStats.dump(result);
+    result.append("]");
+}
+
+std::optional<Predictor::PredictedPlan> Predictor::getPredictedPlan(
+        const std::vector<const LayerState*>& layers, NonBufferHash hash) const {
+    // First check for an exact match
+    if (std::optional<Plan> exactMatch = getExactMatch(hash); exactMatch) {
+        ALOGV("[%s] Found an exact match for %zx", __func__, hash);
+        return PredictedPlan{.hash = hash, .plan = *exactMatch, .type = Prediction::Type::Exact};
+    }
+
+    // If only a hash was passed in for a layer stack with a cached set, don't perform
+    // approximate matches and return early
+    if (layers.empty()) {
+        ALOGV("[%s] Only hash was passed, but no exact match was found", __func__);
+        return std::nullopt;
+    }
+
+    // Then check for approximate matches
+    if (std::optional<NonBufferHash> approximateMatch = getApproximateMatch(layers);
+        approximateMatch) {
+        ALOGV("[%s] Found an approximate match for %zx", __func__, *approximateMatch);
+        const Prediction& prediction = getPrediction(*approximateMatch);
+        return PredictedPlan{.hash = *approximateMatch,
+                             .plan = prediction.getPlan(),
+                             .type = Prediction::Type::Approximate};
+    }
+
+    return std::nullopt;
+}
+
+void Predictor::recordResult(std::optional<PredictedPlan> predictedPlan,
+                             const std::vector<const LayerState*>& layers, Plan result) {
+    if (predictedPlan) {
+        recordPredictedResult(*predictedPlan, layers, std::move(result));
+        return;
+    }
+
+    ++mMissCount;
+
+    if (findSimilarPrediction(layers, result)) {
+        return;
+    }
+
+    const NonBufferHash hash = getNonBufferHash(layers);
+
+    ALOGV("[%s] Adding novel candidate %zx", __func__, hash);
+    mCandidates.emplace_front(hash, Prediction(layers, result));
+    if (mCandidates.size() > MAX_CANDIDATES) {
+        mCandidates.pop_back();
+    }
+}
+
+void Predictor::dump(std::string& result) const {
+    result.append("Predictor state:\n");
+
+    const size_t hitCount = mExactHitCount + mApproximateHitCount;
+    const size_t totalAttempts = hitCount + mMissCount;
+    base::StringAppendF(&result, "Global non-skipped hit rate: %.2f%% (%zd/%zd)\n",
+                        100.0f * hitCount / totalAttempts, hitCount, totalAttempts);
+    base::StringAppendF(&result, "  Exact hits: %zd\n", mExactHitCount);
+    base::StringAppendF(&result, "  Approximate hits: %zd\n", mApproximateHitCount);
+    base::StringAppendF(&result, "  Misses: %zd\n\n", mMissCount);
+
+    dumpPredictionsByFrequency(result);
+}
+
+void Predictor::compareLayerStacks(NonBufferHash leftHash, NonBufferHash rightHash,
+                                   std::string& result) const {
+    const auto& [leftPredictionEntry, rightPredictionEntry] =
+            std::make_tuple(mPredictions.find(leftHash), mPredictions.find(rightHash));
+    if (leftPredictionEntry == mPredictions.end()) {
+        base::StringAppendF(&result, "No prediction found for %zx\n", leftHash);
+        return;
+    }
+    if (rightPredictionEntry == mPredictions.end()) {
+        base::StringAppendF(&result, "No prediction found for %zx\n", rightHash);
+        return;
+    }
+
+    base::StringAppendF(&result,
+                        "Comparing           %-16zx                                %-16zx\n",
+                        leftHash, rightHash);
+
+    const auto& [leftPrediction, rightPrediction] =
+            std::make_tuple(leftPredictionEntry->second, rightPredictionEntry->second);
+    const auto& [leftStack, rightStack] = std::make_tuple(leftPrediction.getExampleLayerStack(),
+                                                          rightPrediction.getExampleLayerStack());
+    leftStack.compare(rightStack, result);
+}
+
+void Predictor::describeLayerStack(NonBufferHash hash, std::string& result) const {
+    base::StringAppendF(&result, "Describing %zx:\n\n", hash);
+
+    if (const auto predictionsEntry = mPredictions.find(hash);
+        predictionsEntry != mPredictions.cend()) {
+        const auto& [hash, prediction] = *predictionsEntry;
+
+        prediction.getExampleLayerStack().dump(result);
+
+        result.append("Prediction: ");
+        prediction.dump(result);
+        result.append("\n");
+    } else {
+        result.append("No predictions found\n");
+    }
+}
+
+void Predictor::listSimilarStacks(Plan plan, std::string& result) const {
+    base::StringAppendF(&result, "Similar stacks for plan %s:\n", to_string(plan).c_str());
+
+    if (const auto similarStacksEntry = mSimilarStacks.find(plan);
+        similarStacksEntry != mSimilarStacks.end()) {
+        const auto& [_, similarStacks] = *similarStacksEntry;
+        for (NonBufferHash hash : similarStacks) {
+            base::StringAppendF(&result, "\nPrediction hash %zx:\n", hash);
+            const Prediction& prediction = mPredictions.at(hash);
+            prediction.getExampleLayerStack().dumpLayerNames(result);
+        }
+    } else {
+        result.append("No similar stacks found\n");
+    }
+}
+
+const Prediction& Predictor::getPrediction(NonBufferHash hash) const {
+    if (const auto predictionEntry = mPredictions.find(hash);
+        predictionEntry != mPredictions.end()) {
+        const auto& [_, prediction] = *predictionEntry;
+        return prediction;
+    } else {
+        const auto candidateEntry = getCandidateEntryByHash(hash);
+        ALOGE_IF(candidateEntry == mCandidates.cend(),
+                 "Hash should have been found in either predictions or candidates");
+        const auto& [_, prediction] = *candidateEntry;
+        return prediction;
+    }
+}
+
+Prediction& Predictor::getPrediction(NonBufferHash hash) {
+    return const_cast<Prediction&>(const_cast<const Predictor*>(this)->getPrediction(hash));
+}
+
+std::optional<Plan> Predictor::getExactMatch(NonBufferHash hash) const {
+    const Prediction* match = nullptr;
+    if (const auto predictionEntry = mPredictions.find(hash);
+        predictionEntry != mPredictions.end()) {
+        const auto& [hash, prediction] = *predictionEntry;
+        match = &prediction;
+    } else if (const auto candidateEntry = getCandidateEntryByHash(hash);
+               candidateEntry != mCandidates.cend()) {
+        match = &(candidateEntry->prediction);
+    }
+
+    if (match == nullptr) {
+        return std::nullopt;
+    }
+
+    if (match->getMissCount(Prediction::Type::Exact) != 0) {
+        ALOGV("[%s] Skipping exact match for %zx because of prior miss", __func__, hash);
+        return std::nullopt;
+    }
+
+    return match->getPlan();
+}
+
+std::optional<NonBufferHash> Predictor::getApproximateMatch(
+        const std::vector<const LayerState*>& layers) const {
+    const auto approximateStackMatches = [&](const ApproximateStack& approximateStack) {
+        const auto& exampleStack = mPredictions.at(approximateStack.hash).getExampleLayerStack();
+        if (const auto approximateMatchOpt = exampleStack.getApproximateMatch(layers);
+            approximateMatchOpt) {
+            return *approximateMatchOpt == approximateStack.match;
+        }
+        return false;
+    };
+
+    const auto candidateMatches = [&](const PromotionCandidate& candidate) {
+        ALOGV("[getApproximateMatch] checking against %zx", candidate.hash);
+        return candidate.prediction.getExampleLayerStack().getApproximateMatch(layers) !=
+                std::nullopt;
+    };
+
+    const Prediction* match = nullptr;
+    NonBufferHash hash;
+    if (const auto approximateStackIter =
+                std::find_if(mApproximateStacks.cbegin(), mApproximateStacks.cend(),
+                             approximateStackMatches);
+        approximateStackIter != mApproximateStacks.cend()) {
+        match = &mPredictions.at(approximateStackIter->hash);
+        hash = approximateStackIter->hash;
+    } else if (const auto candidateEntry =
+                       std::find_if(mCandidates.cbegin(), mCandidates.cend(), candidateMatches);
+               candidateEntry != mCandidates.cend()) {
+        match = &(candidateEntry->prediction);
+        hash = candidateEntry->hash;
+    }
+
+    if (match == nullptr) {
+        return std::nullopt;
+    }
+
+    if (match->getMissCount(Prediction::Type::Approximate) != 0) {
+        ALOGV("[%s] Skipping approximate match for %zx because of prior miss", __func__, hash);
+        return std::nullopt;
+    }
+
+    return hash;
+}
+
+void Predictor::promoteIfCandidate(NonBufferHash predictionHash) {
+    // Return if the candidate has already been promoted
+    if (mPredictions.count(predictionHash) != 0) {
+        return;
+    }
+
+    ALOGV("[%s] Promoting %zx from candidate to prediction", __func__, predictionHash);
+
+    auto candidateEntry = getCandidateEntryByHash(predictionHash);
+    ALOGE_IF(candidateEntry == mCandidates.end(), "Expected to find candidate");
+
+    mSimilarStacks[candidateEntry->prediction.getPlan()].push_back(predictionHash);
+    mPredictions.emplace(predictionHash, std::move(candidateEntry->prediction));
+    mCandidates.erase(candidateEntry);
+}
+
+void Predictor::recordPredictedResult(PredictedPlan predictedPlan,
+                                      const std::vector<const LayerState*>& layers, Plan result) {
+    Prediction& prediction = getPrediction(predictedPlan.hash);
+    if (prediction.getPlan() != result) {
+        ALOGV("[%s] %s prediction missed, expected %s, found %s", __func__,
+              to_string(predictedPlan.type).c_str(), to_string(prediction.getPlan()).c_str(),
+              to_string(result).c_str());
+        prediction.recordMiss(predictedPlan.type);
+        ++mMissCount;
+        return;
+    }
+
+    switch (predictedPlan.type) {
+        case Prediction::Type::Approximate:
+            ++mApproximateHitCount;
+            break;
+        case Prediction::Type::Exact:
+            ++mExactHitCount;
+            break;
+        default:
+            break;
+    }
+
+    ALOGV("[%s] %s prediction hit", __func__, to_string(predictedPlan.type).c_str());
+    ALOGV("[%s] Plan: %s", __func__, to_string(result).c_str());
+    prediction.recordHit(predictedPlan.type);
+
+    const auto stackMatchesHash = [hash = predictedPlan.hash](const ApproximateStack& stack) {
+        return stack.hash == hash;
+    };
+
+    if (predictedPlan.type == Prediction::Type::Approximate) {
+        // If this approximate match is not already in the list of approximate stacks, add it
+        if (std::find_if(mApproximateStacks.cbegin(), mApproximateStacks.cend(),
+                         stackMatchesHash) == mApproximateStacks.cend()) {
+            ALOGV("[%s] Adding approximate match to list", __func__);
+            const auto approximateMatchOpt =
+                    prediction.getExampleLayerStack().getApproximateMatch(layers);
+            ALOGE_IF(!approximateMatchOpt, "Expected an approximate match");
+            mApproximateStacks.emplace_back(predictedPlan.hash, *approximateMatchOpt);
+        }
+    }
+
+    promoteIfCandidate(predictedPlan.hash);
+}
+
+bool Predictor::findSimilarPrediction(const std::vector<const LayerState*>& layers, Plan result) {
+    const auto stacksEntry = mSimilarStacks.find(result);
+    if (stacksEntry == mSimilarStacks.end()) {
+        return false;
+    }
+
+    std::optional<ApproximateStack> bestMatch;
+    const auto& [plan, similarStacks] = *stacksEntry;
+    for (NonBufferHash hash : similarStacks) {
+        const Prediction& prediction = mPredictions.at(hash);
+        auto approximateMatch = prediction.getExampleLayerStack().getApproximateMatch(layers);
+        if (!approximateMatch) {
+            continue;
+        }
+
+        const int differingFieldCount = __builtin_popcount(approximateMatch->differingFields.get());
+        if (!bestMatch ||
+            differingFieldCount < __builtin_popcount(bestMatch->match.differingFields.get())) {
+            bestMatch = {hash, *approximateMatch};
+        }
+    }
+
+    if (!bestMatch) {
+        return false;
+    }
+
+    ALOGV("[%s] Adding %zx to approximate stacks", __func__, bestMatch->hash);
+
+    mApproximateStacks.emplace_back(*bestMatch);
+    return true;
+}
+
+void Predictor::dumpPredictionsByFrequency(std::string& result) const {
+    struct HashFrequency {
+        HashFrequency(NonBufferHash hash, size_t totalAttempts)
+              : hash(hash), totalAttempts(totalAttempts) {}
+
+        NonBufferHash hash;
+        size_t totalAttempts;
+    };
+
+    std::vector<HashFrequency> hashFrequencies;
+    for (const auto& [hash, prediction] : mPredictions) {
+        hashFrequencies.emplace_back(hash,
+                                     prediction.getHitCount(Prediction::Type::Total) +
+                                             prediction.getMissCount(Prediction::Type::Total));
+    }
+
+    std::sort(hashFrequencies.begin(), hashFrequencies.end(),
+              [](const HashFrequency& lhs, const HashFrequency& rhs) {
+                  return lhs.totalAttempts > rhs.totalAttempts;
+              });
+
+    result.append("Predictions:\n");
+    for (const auto& [hash, totalAttempts] : hashFrequencies) {
+        base::StringAppendF(&result, "  %016zx ", hash);
+        mPredictions.at(hash).dump(result);
+        result.append("\n");
+    }
+}
+
+} // namespace android::compositionengine::impl::planner
\ No newline at end of file
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index f654c2f..8dcace6 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -891,6 +891,9 @@
     mOutput.editState().usesDeviceComposition = true;
 
     EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
+    if (mOutput.plannerEnabled()) {
+        EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
+    }
     EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
 
     mOutput.prepareFrame();
