Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3af3f75f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor HWC2on1Adapter"

parents 8cf14180 06e908a6
Loading
Loading
Loading
Loading
+324 −517

File changed.

Preview size limit exceeded, changes collapsed.

+100 −89
Original line number Original line Diff line number Diff line
@@ -134,11 +134,6 @@ private:
                    const std::shared_ptr<Layer>& rhs);
                    const std::shared_ptr<Layer>& rhs);
    };
    };


    class DisplayContentsDeleter {
        public:
            void operator()(struct hwc_display_contents_1* contents);
    };

    // The semantics of the fences returned by the device differ between
    // The semantics of the fences returned by the device differ between
    // hwc1.set() and hwc2.present(). Read hwcomposer.h and hwcomposer2.h
    // hwc1.set() and hwc2.present(). Read hwcomposer.h and hwcomposer2.h
    // for more information.
    // for more information.
@@ -193,9 +188,6 @@ private:


    class Display {
    class Display {
        public:
        public:
            typedef std::unique_ptr<hwc_display_contents_1,
                    DisplayContentsDeleter> HWC1Contents;

            Display(HWC2On1Adapter& device, HWC2::DisplayType type);
            Display(HWC2On1Adapter& device, HWC2::DisplayType type);


            hwc2_display_t getId() const { return mId; }
            hwc2_display_t getId() const { return mId; }
@@ -206,10 +198,6 @@ private:
            void setHwc1Id(int32_t id) { mHwc1Id = id; }
            void setHwc1Id(int32_t id) { mHwc1Id = id; }
            int32_t getHwc1Id() const { return mHwc1Id; }
            int32_t getHwc1Id() const { return mHwc1Id; }


            void incDirty() { ++mDirtyCount; }
            void decDirty() { --mDirtyCount; }
            bool isDirty() const { return mDirtyCount > 0 || mZIsDirty; }

            // HWC2 Display functions
            // HWC2 Display functions
            HWC2::Error acceptChanges();
            HWC2::Error acceptChanges();
            HWC2::Error createLayer(hwc2_layer_t* outLayerId);
            HWC2::Error createLayer(hwc2_layer_t* outLayerId);
@@ -233,7 +221,14 @@ private:
                    uint32_t* outNumElements, hwc2_layer_t* outLayers,
                    uint32_t* outNumElements, hwc2_layer_t* outLayers,
                    int32_t* outLayerRequests);
                    int32_t* outLayerRequests);
            HWC2::Error getType(int32_t* outType);
            HWC2::Error getType(int32_t* outType);

            // Since HWC1 "presents" (called "set" in HWC1) all Displays
            // at once, the first call to any Display::present will trigger
            // present() on all Displays in the Device. Subsequent calls without
            // first calling validate() are noop (except for duping/returning
            // the retire fence).
            HWC2::Error present(int32_t* outRetireFence);
            HWC2::Error present(int32_t* outRetireFence);

            HWC2::Error setActiveConfig(hwc2_config_t configId);
            HWC2::Error setActiveConfig(hwc2_config_t configId);
            HWC2::Error setClientTarget(buffer_handle_t target,
            HWC2::Error setClientTarget(buffer_handle_t target,
                    int32_t acquireFence, int32_t dataspace,
                    int32_t acquireFence, int32_t dataspace,
@@ -244,6 +239,10 @@ private:
                    int32_t releaseFence);
                    int32_t releaseFence);
            HWC2::Error setPowerMode(HWC2::PowerMode mode);
            HWC2::Error setPowerMode(HWC2::PowerMode mode);
            HWC2::Error setVsyncEnabled(HWC2::Vsync enabled);
            HWC2::Error setVsyncEnabled(HWC2::Vsync enabled);

            // Since HWC1 "validates" (called "prepare" in HWC1) all Displays
            // at once, the first call to any Display::validate() will trigger
            // validate() on all other Displays in the Device.
            HWC2::Error validate(uint32_t* outNumTypes,
            HWC2::Error validate(uint32_t* outNumTypes,
                    uint32_t* outNumRequests);
                    uint32_t* outNumRequests);


@@ -256,10 +255,9 @@ private:
            void populateConfigs(uint32_t width, uint32_t height);
            void populateConfigs(uint32_t width, uint32_t height);


            bool prepare();
            bool prepare();
            HWC1Contents cloneRequestedContents() const;


            // Called after hwc.prepare() with responses from the device.
            // Called after hwc.prepare() with responses from the device.
            void setReceivedContents(HWC1Contents contents);
            void generateChanges();


            bool hasChanges() const;
            bool hasChanges() const;
            HWC2::Error set(hwc_display_contents_1& hwcContents);
            HWC2::Error set(hwc_display_contents_1& hwcContents);
@@ -270,6 +268,13 @@ private:


            std::string dump() const;
            std::string dump() const;


            // Return a rect from the pool allocated during validate()
            hwc_rect_t* GetRects(size_t numRects);

            hwc_display_contents_1* getDisplayContents();

            void markGeometryChanged() { mGeometryChanged = true; }
            void resetGeometryMarker() { mGeometryChanged = false;}
        private:
        private:
            class Config {
            class Config {
                public:
                public:
@@ -314,7 +319,7 @@ private:
                    std::unordered_map<android_color_mode_t, uint32_t> mHwc1Ids;
                    std::unordered_map<android_color_mode_t, uint32_t> mHwc1Ids;
            };
            };


            // Store changes requested from the device upon calling prepare().
            // Stores changes requested from the device upon calling prepare().
            // Handles change request to:
            // Handles change request to:
            //   - Layer composition type.
            //   - Layer composition type.
            //   - Layer hints.
            //   - Layer hints.
@@ -363,7 +368,9 @@ private:
            void populateColorModes();
            void populateColorModes();
            void initializeActiveConfig();
            void initializeActiveConfig();


            void reallocateHwc1Contents();
            // Creates a bi-directional mapping between index in HWC1
            // prepare/set array and Layer object. Stores mapping in
            // mHwc1LayerMap and also updates Layer's attribute mHwc1Id.
            void assignHwc1LayerIds();
            void assignHwc1LayerIds();


            // Called after a response to prepare() has been received:
            // Called after a response to prepare() has been received:
@@ -376,13 +383,16 @@ private:
            void updateLayerRequests(const struct hwc_layer_1& hwc1Layer,
            void updateLayerRequests(const struct hwc_layer_1& hwc1Layer,
                    const Layer& layer);
                    const Layer& layer);


            // Set all fields in HWC1 comm array for layer containing the
            // HWC_FRAMEBUFFER_TARGET (always the last layer).
            void prepareFramebufferTarget();
            void prepareFramebufferTarget();


            // Display ID generator.
            static std::atomic<hwc2_display_t> sNextId;
            static std::atomic<hwc2_display_t> sNextId;
            const hwc2_display_t mId;
            const hwc2_display_t mId;
            HWC2On1Adapter& mDevice;


            std::atomic<size_t> mDirtyCount;

            HWC2On1Adapter& mDevice;


            // The state of this display should only be modified from
            // The state of this display should only be modified from
            // SurfaceFlinger's main loop, with the exception of when dump is
            // SurfaceFlinger's main loop, with the exception of when dump is
@@ -395,15 +405,18 @@ private:
            // which require locking.
            // which require locking.
            mutable std::recursive_mutex mStateMutex;
            mutable std::recursive_mutex mStateMutex;


            bool mZIsDirty;
            // Allocate RAM able to store all layers and rects used for
            // communication with HWC1. Place allocated RAM in variable
            // mHwc1RequestedContents.
            void allocateRequestedContents();


            // Array of structs exchanged between client and hwc1 device.
            // Array of structs exchanged between client and hwc1 device.
            HWC1Contents mHwc1RequestedContents; // Sent to device upon calling prepare().
            // Sent to device upon calling prepare().
            HWC1Contents mHwc1ReceivedContents;  // Returned by device after prepare().
            std::unique_ptr<hwc_display_contents_1> mHwc1RequestedContents;

    private:
            DeferredFence mRetireFence;
            DeferredFence mRetireFence;


            // Will only be non-null after the layer has been validated but
            // Will only be non-null after the Display has been validated and
            // before it has been presented
            // before it has been presented
            std::unique_ptr<Changes> mChanges;
            std::unique_ptr<Changes> mChanges;


@@ -418,15 +431,34 @@ private:
            HWC2::PowerMode mPowerMode;
            HWC2::PowerMode mPowerMode;
            HWC2::Vsync mVsyncEnabled;
            HWC2::Vsync mVsyncEnabled;


            // Used to populate HWC1 HWC_FRAMEBUFFER_TARGET layer
            FencedBuffer mClientTarget;
            FencedBuffer mClientTarget;


            FencedBuffer mOutputBuffer;
            FencedBuffer mOutputBuffer;


            bool mHasColorTransform;
            bool mHasColorTransform;


            // All layers this Display is aware of.
            std::multiset<std::shared_ptr<Layer>, SortLayersByZ> mLayers;
            std::multiset<std::shared_ptr<Layer>, SortLayersByZ> mLayers;

            // Mapping between layer index in array of hwc_display_contents_1*
            // passed to HWC1 during validate/set and Layer object.
            std::unordered_map<size_t, std::shared_ptr<Layer>> mHwc1LayerMap;
            std::unordered_map<size_t, std::shared_ptr<Layer>> mHwc1LayerMap;

            // All communication with HWC1 via prepare/set is done with one
            // alloc. This pointer is pointing to a pool of hwc_rect_t.
            size_t mNumAvailableRects;
            hwc_rect_t* mNextAvailableRect;

            // True if any of the Layers contained in this Display have been
            // updated with anything other than a buffer since last call to
            // Display::set()
            bool mGeometryChanged;
    };
    };


    // Utility template calling a Display object method directly based on the
    // hwc2_display_t displayId parameter.
    template <typename ...Args>
    template <typename ...Args>
    static int32_t callDisplayFunction(hwc2_device_t* device,
    static int32_t callDisplayFunction(hwc2_device_t* device,
            hwc2_display_t displayId, HWC2::Error (Display::*member)(Args...),
            hwc2_display_t displayId, HWC2::Error (Display::*member)(Args...),
@@ -468,7 +500,8 @@ private:
    static int32_t setColorModeHook(hwc2_device_t* device,
    static int32_t setColorModeHook(hwc2_device_t* device,
            hwc2_display_t display, int32_t /*android_color_mode_t*/ intMode) {
            hwc2_display_t display, int32_t /*android_color_mode_t*/ intMode) {
        auto mode = static_cast<android_color_mode_t>(intMode);
        auto mode = static_cast<android_color_mode_t>(intMode);
        return callDisplayFunction(device, display, &Display::setColorMode, mode);
        return callDisplayFunction(device, display, &Display::setColorMode,
                mode);
    }
    }


    static int32_t setPowerModeHook(hwc2_device_t* device,
    static int32_t setPowerModeHook(hwc2_device_t* device,
@@ -485,46 +518,6 @@ private:
                enabled);
                enabled);
    }
    }


    // Layer functions

    template <typename T>
    class LatchedState {
        public:
            LatchedState(Layer& parent, T initialValue)
              : mParent(parent),
                mPendingValue(initialValue),
                mValue(initialValue) {}

            void setPending(T value) {
                if (value == mPendingValue) {
                    return;
                }
                if (mPendingValue == mValue) {
                    mParent.incDirty();
                } else if (value == mValue) {
                    mParent.decDirty();
                }
                mPendingValue = value;
            }

            T getValue() const { return mValue; }
            T getPendingValue() const { return mPendingValue; }

            bool isDirty() const { return mPendingValue != mValue; }

            void latch() {
                if (isDirty()) {
                    mValue = mPendingValue;
                    mParent.decDirty();
                }
            }

        private:
            Layer& mParent;
            T mPendingValue;
            T mValue;
    };

    class Layer {
    class Layer {
        public:
        public:
            explicit Layer(Display& display);
            explicit Layer(Display& display);
@@ -535,10 +528,6 @@ private:
            hwc2_layer_t getId() const { return mId; }
            hwc2_layer_t getId() const { return mId; }
            Display& getDisplay() const { return mDisplay; }
            Display& getDisplay() const { return mDisplay; }


            void incDirty() { if (mDirtyCount++ == 0) mDisplay.incDirty(); }
            void decDirty() { if (--mDirtyCount == 0) mDisplay.decDirty(); }
            bool isDirty() const { return mDirtyCount > 0; }

            // HWC2 Layer functions
            // HWC2 Layer functions
            HWC2::Error setBuffer(buffer_handle_t buffer, int32_t acquireFence);
            HWC2::Error setBuffer(buffer_handle_t buffer, int32_t acquireFence);
            HWC2::Error setCursorPosition(int32_t x, int32_t y);
            HWC2::Error setCursorPosition(int32_t x, int32_t y);
@@ -558,7 +547,7 @@ private:
            HWC2::Error setZ(uint32_t z);
            HWC2::Error setZ(uint32_t z);


            HWC2::Composition getCompositionType() const {
            HWC2::Composition getCompositionType() const {
                return mCompositionType.getValue();
                return mCompositionType;
            }
            }
            uint32_t getZ() const { return mZ; }
            uint32_t getZ() const { return mZ; }


@@ -568,47 +557,57 @@ private:
            void setHwc1Id(size_t id) { mHwc1Id = id; }
            void setHwc1Id(size_t id) { mHwc1Id = id; }
            size_t getHwc1Id() const { return mHwc1Id; }
            size_t getHwc1Id() const { return mHwc1Id; }


            void applyState(struct hwc_layer_1& hwc1Layer, bool applyAllState);
            // Write state to HWC1 communication struct.
            void applyState(struct hwc_layer_1& hwc1Layer);


            std::string dump() const;
            std::string dump() const;


            std::size_t getNumVisibleRegions() { return mVisibleRegion.size(); }

            std::size_t getNumSurfaceDamages() { return mSurfaceDamage.size(); }

            // True if a layer cannot be properly rendered by the device due
            // to usage of SolidColor (a.k.a BackgroundColor in HWC1).
            bool hasUnsupportedBackgroundColor() {
                return (mCompositionType == HWC2::Composition::SolidColor &&
                        !mDisplay.getDevice().supportsBackgroundColor());
            }
        private:
        private:
            void applyCommonState(struct hwc_layer_1& hwc1Layer,
            void applyCommonState(struct hwc_layer_1& hwc1Layer);
                    bool applyAllState);
            void applySolidColorState(struct hwc_layer_1& hwc1Layer);
            void applySolidColorState(struct hwc_layer_1& hwc1Layer,
            void applySidebandState(struct hwc_layer_1& hwc1Layer);
                    bool applyAllState);
            void applySidebandState(struct hwc_layer_1& hwc1Layer,
                    bool applyAllState);
            void applyBufferState(struct hwc_layer_1& hwc1Layer);
            void applyBufferState(struct hwc_layer_1& hwc1Layer);
            void applyCompositionType(struct hwc_layer_1& hwc1Layer,
            void applyCompositionType(struct hwc_layer_1& hwc1Layer);
                    bool applyAllState);


            static std::atomic<hwc2_layer_t> sNextId;
            static std::atomic<hwc2_layer_t> sNextId;
            const hwc2_layer_t mId;
            const hwc2_layer_t mId;
            Display& mDisplay;
            Display& mDisplay;
            size_t mDirtyCount;


            FencedBuffer mBuffer;
            FencedBuffer mBuffer;
            std::vector<hwc_rect_t> mSurfaceDamage;
            std::vector<hwc_rect_t> mSurfaceDamage;


            LatchedState<HWC2::BlendMode> mBlendMode;
            HWC2::BlendMode mBlendMode;
            LatchedState<hwc_color_t> mColor;
            hwc_color_t mColor;
            LatchedState<HWC2::Composition> mCompositionType;
            HWC2::Composition mCompositionType;
            LatchedState<hwc_rect_t> mDisplayFrame;
            hwc_rect_t mDisplayFrame;
            LatchedState<float> mPlaneAlpha;
            float mPlaneAlpha;
            LatchedState<const native_handle_t*> mSidebandStream;
            const native_handle_t* mSidebandStream;
            LatchedState<hwc_frect_t> mSourceCrop;
            hwc_frect_t mSourceCrop;
            LatchedState<HWC2::Transform> mTransform;
            HWC2::Transform mTransform;
            LatchedState<std::vector<hwc_rect_t>> mVisibleRegion;
            std::vector<hwc_rect_t> mVisibleRegion;

            uint32_t mZ;
            uint32_t mZ;


            DeferredFence mReleaseFence;
            DeferredFence mReleaseFence;


            size_t mHwc1Id;
            size_t mHwc1Id;
            bool mHasUnsupportedPlaneAlpha;
            bool mHasUnsupportedPlaneAlpha;
            bool mHasUnsupportedBackgroundColor;
    };
    };


    // Utility tempate calling a Layer object method based on ID parameters:
    // hwc2_display_t displayId
    // and
    // hwc2_layer_t layerId
    template <typename ...Args>
    template <typename ...Args>
    static int32_t callLayerFunction(hwc2_device_t* device,
    static int32_t callLayerFunction(hwc2_device_t* device,
            hwc2_display_t displayId, hwc2_layer_t layerId,
            hwc2_display_t displayId, hwc2_layer_t layerId,
@@ -677,6 +676,7 @@ private:
    std::vector<struct hwc_display_contents_1*> mHwc1Contents;
    std::vector<struct hwc_display_contents_1*> mHwc1Contents;
    HWC2::Error setAllDisplays();
    HWC2::Error setAllDisplays();


    // Callbacks
    void hwc1Invalidate();
    void hwc1Invalidate();
    void hwc1Vsync(int hwc1DisplayId, int64_t timestamp);
    void hwc1Vsync(int hwc1DisplayId, int64_t timestamp);
    void hwc1Hotplug(int hwc1DisplayId, int connected);
    void hwc1Hotplug(int hwc1DisplayId, int connected);
@@ -698,6 +698,8 @@ private:
    // callbacks or dump
    // callbacks or dump


    std::map<hwc2_layer_t, std::shared_ptr<Layer>> mLayers;
    std::map<hwc2_layer_t, std::shared_ptr<Layer>> mLayers;

    // A HWC1 supports only one virtual display.
    std::shared_ptr<Display> mHwc1VirtualDisplay;
    std::shared_ptr<Display> mHwc1VirtualDisplay;


    // These are potentially accessed from multiple threads, and are protected
    // These are potentially accessed from multiple threads, and are protected
@@ -712,10 +714,19 @@ private:
    };
    };
    std::unordered_map<HWC2::Callback, CallbackInfo> mCallbacks;
    std::unordered_map<HWC2::Callback, CallbackInfo> mCallbacks;
    bool mHasPendingInvalidate;
    bool mHasPendingInvalidate;

    // There is a small gap between the time the HWC1 module is started and
    // when the callbacks for vsync and hotplugs are registered by the
    // HWC2on1Adapter. To prevent losing events they are stored in these arrays
    // and fed to the callback as soon as possible.
    std::vector<std::pair<int, int64_t>> mPendingVsyncs;
    std::vector<std::pair<int, int64_t>> mPendingVsyncs;
    std::vector<std::pair<int, int>> mPendingHotplugs;
    std::vector<std::pair<int, int>> mPendingHotplugs;


    // Mapping between HWC1 display id and Display objects.
    std::map<hwc2_display_t, std::shared_ptr<Display>> mDisplays;
    std::map<hwc2_display_t, std::shared_ptr<Display>> mDisplays;

    // Map HWC1 display type (HWC_DISPLAY_PRIMARY, HWC_DISPLAY_EXTERNAL,
    // HWC_DISPLAY_VIRTUAL) to Display IDs generated by HWC2on1Adapter objects.
    std::unordered_map<int, hwc2_display_t> mHwc1DisplayMap;
    std::unordered_map<int, hwc2_display_t> mHwc1DisplayMap;
};
};