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

Commit d502268f authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11373247 from 9ecd6c1c to 24Q2-release

Change-Id: Id8b6018aeb9832af04e7fafe20875cbab766368b
parents c6e03491 9ecd6c1c
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -73,8 +73,18 @@ class BaseFuture<Self, T, std::future> {
    return std::get<Impl>(self()).get();
  }

  template <class Rep, class Period>
  std::future_status wait_for(const std::chrono::duration<Rep, Period>& timeout_duration) const {
    if (std::holds_alternative<T>(self())) {
      return std::future_status::ready;
    }

    return std::get<Impl>(self()).wait_for(timeout_duration);
  }

 private:
  auto& self() { return static_cast<Self&>(*this).future_; }
  const auto& self() const { return static_cast<const Self&>(*this).future_; }
};

template <typename Self, typename T>
@@ -90,6 +100,15 @@ class BaseFuture<Self, T, std::shared_future> {
    return std::get<Impl>(self()).get();
  }

  template <class Rep, class Period>
  std::future_status wait_for(const std::chrono::duration<Rep, Period>& timeout_duration) const {
    if (std::holds_alternative<T>(self())) {
      return std::future_status::ready;
    }

    return std::get<Impl>(self()).wait_for(timeout_duration);
  }

 private:
  const auto& self() const { return static_cast<const Self&>(*this).future_; }
};
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ class Future final : public details::BaseFuture<Future<T, FutureImpl>, T, Future
  // Forwarding functions. Base::share is only defined when FutureImpl is std::future, whereas the
  // following are defined for either FutureImpl:
  using Base::get;
  using Base::wait_for;

  // Attaches a continuation to the future. The continuation is a function that maps T to either R
  // or ftl::Future<R>. In the former case, the chain wraps the result in a future as if by
+38 −0
Original line number Diff line number Diff line
@@ -102,4 +102,42 @@ TEST(Future, Chain) {
  decrement_thread.join();
}

TEST(Future, WaitFor) {
  using namespace std::chrono_literals;
  {
    auto future = ftl::yield(42);
    // Check that we can wait_for multiple times without invalidating the future
    EXPECT_EQ(future.wait_for(1s), std::future_status::ready);
    EXPECT_EQ(future.wait_for(1s), std::future_status::ready);
    EXPECT_EQ(future.get(), 42);
  }

  {
    std::condition_variable cv;
    std::mutex m;
    bool ready = false;

    std::packaged_task<int32_t()> get_int([&] {
      std::unique_lock lk(m);
      cv.wait(lk, [&] { return ready; });
      return 24;
    });

    auto get_future = ftl::Future(get_int.get_future());
    std::thread get_thread(std::move(get_int));

    EXPECT_EQ(get_future.wait_for(0s), std::future_status::timeout);
    {
      std::unique_lock lk(m);
      ready = true;
    }
    cv.notify_one();

    EXPECT_EQ(get_future.wait_for(1s), std::future_status::ready);
    EXPECT_EQ(get_future.get(), 24);

    get_thread.join();
  }
}

}  // namespace android::test
+1 −1
Original line number Diff line number Diff line
@@ -1016,7 +1016,7 @@ void SkiaRenderEngine::drawLayersInternal(
                                                  .fakeOutputDataspace = fakeDataspace}));

            // Turn on dithering when dimming beyond this (arbitrary) threshold...
            static constexpr float kDimmingThreshold = 0.2f;
            static constexpr float kDimmingThreshold = 0.9f;
            // ...or we're rendering an HDR layer down to an 8-bit target
            // Most HDR standards require at least 10-bits of color depth for source content, so we
            // can just extract the transfer function rather than dig into precise gralloc layout.
+43 −1
Original line number Diff line number Diff line
@@ -78,11 +78,13 @@
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
#include "TunnelModeEnabledReporter.h"
#include "Utils/FenceUtils.h"

#define DEBUG_RESIZE 0
#define EARLY_RELEASE_ENABLED false

namespace android {
using namespace std::chrono_literals;
namespace {
constexpr int kDumpTableRowLength = 159;

@@ -2911,7 +2913,8 @@ void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& l
}

void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult,
                             ui::LayerStack layerStack) {
                             ui::LayerStack layerStack,
                             std::function<FenceResult(FenceResult)>&& continuation) {
    // If we are displayed on multiple displays in a single composition cycle then we would
    // need to do careful tracking to enable the use of the mLastClientCompositionFence.
    //  For example we can only use it if all the displays are client comp, and we need
@@ -2946,11 +2949,41 @@ void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult,
            break;
        }
    }

    if (!FlagManager::getInstance().screenshot_fence_preservation() && continuation) {
        futureFenceResult = ftl::Future(futureFenceResult).then(std::move(continuation)).share();
    }

    if (ch != nullptr) {
        ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
        ch->previousReleaseFences.emplace_back(std::move(futureFenceResult));
        ch->name = mName;
    } else if (FlagManager::getInstance().screenshot_fence_preservation()) {
        // If we didn't get a release callback yet, e.g. some scenarios when capturing screenshots
        // asynchronously, then make sure we don't drop the fence.
        mAdditionalPreviousReleaseFences.emplace_back(std::move(futureFenceResult),
                                                      std::move(continuation));
        std::vector<FenceAndContinuation> mergedFences;
        sp<Fence> prevFence = nullptr;
        // For a layer that's frequently screenshotted, try to merge fences to make sure we don't
        // grow unbounded.
        for (const auto& futureAndContinution : mAdditionalPreviousReleaseFences) {
            auto result = futureAndContinution.future.wait_for(0s);
            if (result != std::future_status::ready) {
                mergedFences.emplace_back(futureAndContinution);
                continue;
            }

            mergeFence(getDebugName(), futureAndContinution.chain().get().value_or(Fence::NO_FENCE),
                       prevFence);
        }
        if (prevFence != nullptr) {
            mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence))).share());
        }

        mAdditionalPreviousReleaseFences.swap(mergedFences);
    }

    if (mBufferInfo.mBuffer) {
        mPreviouslyPresentedLayerStacks.push_back(layerStack);
    }
@@ -3440,6 +3473,15 @@ bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle
            handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
            handle->frameNumber = mDrawingState.frameNumber;
            handle->previousFrameNumber = mDrawingState.previousFrameNumber;
            if (FlagManager::getInstance().screenshot_fence_preservation() &&
                mPreviousReleaseBufferEndpoint == handle->listener) {
                // Add fences from previous screenshots now so that they can be dispatched to the
                // client.
                for (const auto& futureAndContinution : mAdditionalPreviousReleaseFences) {
                    handle->previousReleaseFences.emplace_back(futureAndContinution.chain());
                }
                mAdditionalPreviousReleaseFences.clear();
            }

            // Store so latched time and release fence can be set
            mDrawingState.callbackHandles.push_back(handle);
Loading