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

Commit ab9bae0d authored by Marin Shalamanov's avatar Marin Shalamanov Committed by Android (Google) Code Review
Browse files

Merge "ComposerClient 2.4: Clean cache on hotplug" into sc-dev

parents 39e0ac26 944b6818
Loading
Loading
Loading
Loading
+52 −51
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ class ComposerClientImpl : public Interface {
                     // display change and thus the framework may want to reallocate buffers. We
                     // need to free all cached handles, since they are holding a strong reference
                     // to the underlying buffers.
                     cleanDisplayResources(display);
                     cleanDisplayResources(display, mResources, mHal);
                     mResources->removeDisplay(display);
                 }
                 mResources->addPhysicalDisplay(display);
@@ -125,56 +125,6 @@ class ComposerClientImpl : public Interface {
         Hal* const mHal;
         const sp<IComposerCallback> mCallback;
         ComposerResources* const mResources;

         void cleanDisplayResources(Display display) {
             size_t cacheSize;
             Error err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize);
             if (err == Error::NONE) {
                 for (int slot = 0; slot < cacheSize; slot++) {
                     ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
                     // Replace the buffer slots with NULLs. Keep the old handle until it is
                     // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
                     const native_handle_t* clientTarget = nullptr;
                     err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true,
                                                              /*rawHandle*/ nullptr, &clientTarget,
                                                              &replacedBuffer);
                     if (err != Error::NONE) {
                         continue;
                     }
                     const std::vector<hwc_rect_t> damage;
                     err = mHal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage);
                     ALOGE_IF(err != Error::NONE,
                              "Can't clean slot %d of the client target buffer"
                              "cache for display %" PRIu64,
                              slot, display);
                 }
             } else {
                 ALOGE("Can't clean client target cache for display %" PRIu64, display);
             }

             err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize);
             if (err == Error::NONE) {
                 for (int slot = 0; slot < cacheSize; slot++) {
                     // Replace the buffer slots with NULLs. Keep the old handle until it is
                     // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
                     ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
                     const native_handle_t* outputBuffer = nullptr;
                     err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
                                                              /*rawHandle*/ nullptr, &outputBuffer,
                                                              &replacedBuffer);
                     if (err != Error::NONE) {
                         continue;
                     }
                     err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ -1);
                     ALOGE_IF(err != Error::NONE,
                              "Can't clean slot %d of the output buffer cache"
                              "for display %" PRIu64,
                              slot, display);
                 }
             } else {
                 ALOGE("Can't clean output buffer cache for display %" PRIu64, display);
             }
         }
    };

    Return<void> registerCallback(const sp<IComposerCallback>& callback) override {
@@ -380,6 +330,57 @@ class ComposerClientImpl : public Interface {
        return std::make_unique<ComposerCommandEngine>(mHal, mResources.get());
    }

    static void cleanDisplayResources(Display display, ComposerResources* const resources,
                                      Hal* const hal) {
        size_t cacheSize;
        Error err = resources->getDisplayClientTargetCacheSize(display, &cacheSize);
        if (err == Error::NONE) {
            for (int slot = 0; slot < cacheSize; slot++) {
                ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
                // Replace the buffer slots with NULLs. Keep the old handle until it is
                // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
                const native_handle_t* clientTarget = nullptr;
                err = resources->getDisplayClientTarget(display, slot, /*useCache*/ true,
                                                        /*rawHandle*/ nullptr, &clientTarget,
                                                        &replacedBuffer);
                if (err != Error::NONE) {
                    continue;
                }
                const std::vector<hwc_rect_t> damage;
                err = hal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage);
                ALOGE_IF(err != Error::NONE,
                         "Can't clean slot %d of the client target buffer"
                         "cache for display %" PRIu64,
                         slot, display);
            }
        } else {
            ALOGE("Can't clean client target cache for display %" PRIu64, display);
        }

        err = resources->getDisplayOutputBufferCacheSize(display, &cacheSize);
        if (err == Error::NONE) {
            for (int slot = 0; slot < cacheSize; slot++) {
                // Replace the buffer slots with NULLs. Keep the old handle until it is
                // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
                ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
                const native_handle_t* outputBuffer = nullptr;
                err = resources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
                                                        /*rawHandle*/ nullptr, &outputBuffer,
                                                        &replacedBuffer);
                if (err != Error::NONE) {
                    continue;
                }
                err = hal->setOutputBuffer(display, outputBuffer, /*fence*/ -1);
                ALOGE_IF(err != Error::NONE,
                         "Can't clean slot %d of the output buffer cache"
                         "for display %" PRIu64,
                         slot, display);
            }
        } else {
            ALOGE("Can't clean output buffer cache for display %" PRIu64, display);
        }
    }

    void destroyResources() {
        // We want to call hwc2_close here (and move hwc2_open to the
        // constructor), with the assumption that hwc2_close would
+14 −3
Original line number Diff line number Diff line
@@ -45,12 +45,21 @@ class ComposerClientImpl : public V2_3::hal::detail::ComposerClientImpl<Interfac

    class HalEventCallback : public Hal::EventCallback_2_4 {
      public:
        HalEventCallback(const sp<IComposerCallback> callback,
        HalEventCallback(Hal* hal, const sp<IComposerCallback> callback,
                         V2_1::hal::ComposerResources* resources)
            : mCallback(callback), mResources(resources) {}
            : mHal(hal), mCallback(callback), mResources(resources) {}

        void onHotplug(Display display, IComposerCallback::Connection connected) override {
            if (connected == IComposerCallback::Connection::CONNECTED) {
                if (mResources->hasDisplay(display)) {
                    // This is a subsequent hotplug "connected" for a display. This signals a
                    // display change and thus the framework may want to reallocate buffers. We
                    // need to free all cached handles, since they are holding a strong reference
                    // to the underlying buffers.
                    V2_1::hal::detail::ComposerClientImpl<Interface, Hal>::cleanDisplayResources(
                            display, mResources, mHal);
                    mResources->removeDisplay(display);
                }
                mResources->addPhysicalDisplay(display);
            } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
                mResources->removeDisplay(display);
@@ -91,13 +100,15 @@ class ComposerClientImpl : public V2_3::hal::detail::ComposerClientImpl<Interfac
        }

      protected:
        Hal* const mHal;
        const sp<IComposerCallback> mCallback;
        V2_1::hal::ComposerResources* const mResources;
    };

    Return<void> registerCallback_2_4(const sp<IComposerCallback>& callback) override {
        // no locking as we require this function to be called only once
        mHalEventCallback_2_4 = std::make_unique<HalEventCallback>(callback, mResources.get());
        mHalEventCallback_2_4 =
                std::make_unique<HalEventCallback>(mHal, callback, mResources.get());
        mHal->registerEventCallback_2_4(mHalEventCallback_2_4.get());
        return Void();
    }