SF: Split FE and CE

Make LayerFE a standalone class with no links back to Layer. Pass
LayerSnapshot from Layer into LayerFE before CompositionEngine::present
and back after.

Bug: 238781169
Test: go/wm-smoke
Test: presubmit

Change-Id: I5395fb717a931f88e2bf26395acd21e8b308961e
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
new file mode 100644
index 0000000..e4f6889
--- /dev/null
+++ b/services/surfaceflinger/LayerFE.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2022 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 <gui/LayerMetadata.h>
+
+#include "compositionengine/LayerFE.h"
+#include "compositionengine/LayerFECompositionState.h"
+#include "renderengine/LayerSettings.h"
+
+namespace android {
+struct RoundedCornerState {
+    RoundedCornerState() = default;
+    RoundedCornerState(const FloatRect& cropRect, const vec2& radius)
+          : cropRect(cropRect), radius(radius) {}
+
+    // Rounded rectangle in local layer coordinate space.
+    FloatRect cropRect = FloatRect();
+    // Radius of the rounded rectangle.
+    vec2 radius;
+    bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; }
+};
+
+// LayerSnapshot stores Layer state used by CompositionEngine and RenderEngine. Composition
+// Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
+// passed to Render Engine are created using properties stored on this struct.
+struct LayerSnapshot : public compositionengine::LayerFECompositionState {
+    int32_t sequence;
+    std::string name;
+    uint32_t textureName;
+    bool contentOpaque;
+    RoundedCornerState roundedCorner;
+    StretchEffect stretchEffect;
+    FloatRect transformedBounds;
+    renderengine::ShadowSettings shadowSettings;
+    bool premultipliedAlpha;
+    bool isHdrY410;
+    bool bufferNeedsFiltering;
+    ui::Transform transform;
+    Rect bufferSize;
+    std::shared_ptr<renderengine::ExternalTexture> externalTexture;
+    gui::LayerMetadata layerMetadata;
+    gui::LayerMetadata relativeLayerMetadata;
+    bool contentDirty;
+    bool hasReadyFrame;
+};
+
+struct CompositionResult {
+    // TODO(b/238781169) update CE to no longer pass refreshStartTime to LayerFE::onPreComposition
+    // and remove this field.
+    nsecs_t refreshStartTime = 0;
+    std::vector<ftl::SharedFuture<FenceResult>> releaseFences;
+    sp<Fence> lastClientCompositionFence = nullptr;
+};
+
+class LayerFE : public virtual RefBase, public virtual compositionengine::LayerFE {
+public:
+    LayerFE(const std::string& name);
+
+    // compositionengine::LayerFE overrides
+    const compositionengine::LayerFECompositionState* getCompositionState() const override;
+    bool onPreComposition(nsecs_t refreshStartTime, bool updatingOutputGeometryThisFrame) override;
+    void onLayerDisplayed(ftl::SharedFuture<FenceResult>) override;
+    const char* getDebugName() const override;
+    int32_t getSequence() const override;
+    bool hasRoundedCorners() const override;
+    void setWasClientComposed(const sp<Fence>&) override;
+    const gui::LayerMetadata* getMetadata() const override;
+    const gui::LayerMetadata* getRelativeMetadata() const override;
+    std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
+            compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+    CompositionResult&& stealCompositionResult();
+
+    std::unique_ptr<LayerSnapshot> mSnapshot;
+
+private:
+    std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal(
+            compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+    // Modifies the passed in layer settings to clear the contents. If the blackout flag is set,
+    // the settings clears the content with a solid black fill.
+    void prepareClearClientComposition(LayerFE::LayerSettings&, bool blackout) const;
+    void prepareShadowClientComposition(LayerFE::LayerSettings& caster,
+                                        const Rect& layerStackRect) const;
+    void prepareBufferStateClientComposition(
+            compositionengine::LayerFE::LayerSettings&,
+            compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+    void prepareEffectsClientComposition(
+            compositionengine::LayerFE::LayerSettings&,
+            compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+
+    bool hasEffect() const { return fillsColor() || drawShadows() || hasBlur(); }
+    bool hasBufferOrSidebandStream() const;
+
+    bool fillsColor() const;
+    bool hasBlur() const;
+    bool drawShadows() const;
+
+    const sp<GraphicBuffer> getBuffer() const;
+
+    CompositionResult mCompositionResult;
+    std::string mName;
+};
+
+} // namespace android