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

Commit 5dad489a authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Improve performance for certain queries/functions in REThreaded." into sc-dev

parents cdc60881 4bea01e7
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ public:
    // do any work.
    virtual bool cleanupPostRender(CleanupMode mode = CleanupMode::CLEAN_OUTPUT_RESOURCES) = 0;

    // queries
    // queries that are required to be thread safe
    virtual size_t getMaxTextureSize() const = 0;
    virtual size_t getMaxViewportDims() const = 0;

@@ -149,8 +149,11 @@ public:

    // ----- BEGIN NEW INTERFACE -----

    // queries that are required to be thread safe
    virtual bool isProtected() const = 0;
    virtual bool supportsProtectedContent() const = 0;

    // Attempt to switch RenderEngine into and out of protectedContext mode
    virtual bool useProtectedContext(bool useProtectedContext) = 0;

    // Notify RenderEngine of changes to the dimensions of the primary display
@@ -197,7 +200,8 @@ public:
    virtual int getContextPriority() = 0;

    // Returns true if blur was requested in the RenderEngineCreationArgs and the implementation
    // also supports background blur.  If false, no blur will be applied when drawing layers.
    // also supports background blur.  If false, no blur will be applied when drawing layers. This
    // query is required to be thread safe.
    virtual bool supportsBackgroundBlur() = 0;

    // Returns the current type of RenderEngine instance that was created.
+3 −0
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@ TEST_F(RenderEngineThreadedTest, dump) {
TEST_F(RenderEngineThreadedTest, primeCache) {
    EXPECT_CALL(*mRenderEngine, primeCache());
    mThreadedRE->primeCache();
    // need to call ANY synchronous function after primeCache to ensure that primeCache has
    // completed asynchronously before the test completes execution.
    mThreadedRE->getContextPriority();
}

TEST_F(RenderEngineThreadedTest, genTextures) {
+33 −75
Original line number Diff line number Diff line
@@ -74,6 +74,12 @@ void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_S
    std::unique_lock<std::mutex> lock(mThreadMutex);
    pthread_setname_np(pthread_self(), mThreadName);

    {
        std::unique_lock<std::mutex> lock(mInitializedMutex);
        mIsInitialized = true;
    }
    mInitializedCondition.notify_all();

    while (mRunning) {
        if (!mFunctionCalls.empty()) {
            auto task = mFunctionCalls.front();
@@ -86,19 +92,22 @@ void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_S
    }
}

void RenderEngineThreaded::waitUntilInitialized() const {
    std::unique_lock<std::mutex> lock(mInitializedMutex);
    mInitializedCondition.wait(lock, [=] { return mIsInitialized; });
}

void RenderEngineThreaded::primeCache() {
    std::promise<void> resultPromise;
    std::future<void> resultFuture = resultPromise.get_future();
    // This function is designed so it can run asynchronously, so we do not need to wait
    // for the futures.
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
        mFunctionCalls.push([](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::primeCache");
            instance.primeCache();
            resultPromise.set_value();
        });
    }
    mCondition.notify_one();
    resultFuture.wait();
}

void RenderEngineThreaded::dump(std::string& result) {
@@ -175,63 +184,26 @@ void RenderEngineThreaded::unbindExternalTextureBuffer(uint64_t bufferId) {
}

size_t RenderEngineThreaded::getMaxTextureSize() const {
    std::promise<size_t> resultPromise;
    std::future<size_t> resultFuture = resultPromise.get_future();
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::getMaxTextureSize");
            size_t size = instance.getMaxTextureSize();
            resultPromise.set_value(size);
        });
    }
    mCondition.notify_one();
    return resultFuture.get();
    waitUntilInitialized();
    return mRenderEngine->getMaxTextureSize();
}

size_t RenderEngineThreaded::getMaxViewportDims() const {
    std::promise<size_t> resultPromise;
    std::future<size_t> resultFuture = resultPromise.get_future();
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::getMaxViewportDims");
            size_t size = instance.getMaxViewportDims();
            resultPromise.set_value(size);
        });
    }
    mCondition.notify_one();
    return resultFuture.get();
    waitUntilInitialized();
    return mRenderEngine->getMaxViewportDims();
}

bool RenderEngineThreaded::isProtected() const {
    std::promise<bool> resultPromise;
    std::future<bool> resultFuture = resultPromise.get_future();
    {
    waitUntilInitialized();
    // ensure that useProtectedContext is not currently being changed by some
    // other thread.
    std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::isProtected");
            bool returnValue = instance.isProtected();
            resultPromise.set_value(returnValue);
        });
    }
    mCondition.notify_one();
    return resultFuture.get();
    return mRenderEngine->isProtected();
}

bool RenderEngineThreaded::supportsProtectedContent() const {
    std::promise<bool> resultPromise;
    std::future<bool> resultFuture = resultPromise.get_future();
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::supportsProtectedContent");
            bool returnValue = instance.supportsProtectedContent();
            resultPromise.set_value(returnValue);
        });
    }
    mCondition.notify_one();
    return resultFuture.get();
    waitUntilInitialized();
    return mRenderEngine->supportsProtectedContent();
}

bool RenderEngineThreaded::useProtectedContext(bool useProtectedContext) {
@@ -288,18 +260,16 @@ status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display,
}

void RenderEngineThreaded::cleanFramebufferCache() {
    std::promise<void> resultPromise;
    std::future<void> resultFuture = resultPromise.get_future();
    // This function is designed so it can run asynchronously, so we do not need to wait
    // for the futures.
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
        mFunctionCalls.push([](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::cleanFramebufferCache");
            instance.cleanFramebufferCache();
            resultPromise.set_value();
        });
    }
    mCondition.notify_one();
    resultFuture.wait();
}

int RenderEngineThreaded::getContextPriority() {
@@ -318,33 +288,21 @@ int RenderEngineThreaded::getContextPriority() {
}

bool RenderEngineThreaded::supportsBackgroundBlur() {
    std::promise<bool> resultPromise;
    std::future<bool> resultFuture = resultPromise.get_future();
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::supportsBackgroundBlur");
            bool returnValue = instance.supportsBackgroundBlur();
            resultPromise.set_value(returnValue);
        });
    }
    mCondition.notify_one();
    return resultFuture.get();
    waitUntilInitialized();
    return mRenderEngine->supportsBackgroundBlur();
}

void RenderEngineThreaded::onPrimaryDisplaySizeChanged(ui::Size size) {
    std::promise<void> resultPromise;
    std::future<void> resultFuture = resultPromise.get_future();
    // This function is designed so it can run asynchronously, so we do not need to wait
    // for the futures.
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise, size](renderengine::RenderEngine& instance) {
        mFunctionCalls.push([size](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::onPrimaryDisplaySizeChanged");
            instance.onPrimaryDisplaySizeChanged(size);
            resultPromise.set_value();
        });
    }
    mCondition.notify_one();
    resultFuture.wait();
}

} // namespace threaded
+7 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ public:

private:
    void threadMain(CreateInstanceFactory factory);
    void waitUntilInitialized() const;

    /* ------------------------------------------------------------------------
     * Threading
@@ -83,6 +84,12 @@ private:
            GUARDED_BY(mThreadMutex);
    mutable std::condition_variable mCondition;

    // Used to allow select thread safe methods to be accessed without requiring the
    // method to be invoked on the RenderEngine thread
    bool mIsInitialized = false;
    mutable std::mutex mInitializedMutex;
    mutable std::condition_variable mInitializedCondition;

    /* ------------------------------------------------------------------------
     * Render Engine
     */