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

Commit 349fd2d2 authored by Alec Mouri's avatar Alec Mouri
Browse files

[RenderEngine] Reorder when ImageManager thread starts

Previously the background thread for managing EglImages was intialized
as a member variable before the constructor completed running. In very
rare circumstances this can potentially stop the running thread if the
thread ran before mRunning was initialized. To be less error-prone,
require that ImageManger::initThread be explicitly called to guarantee
that class member variables are well-defined when the thread begins
executing.

In case the issue resurfaces after this change, added a debug log to add
context.

Bug: 146416748
Test: builds. There is no reliable repro, so this fix is speculative
Test: systrace to verify thread is running and configured correctly.
Change-Id: I141c86240b90c7f87c22b3768c2e188293987b76
parent 1c7bc86a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -441,6 +441,7 @@ GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisp
    }

    mImageManager = std::make_unique<ImageManager>(this);
    mImageManager->initThread();
    mDrawingBuffer = createFramebuffer();
}

+9 −1
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "RenderEngine"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include <pthread.h>
@@ -27,7 +30,10 @@ namespace android {
namespace renderengine {
namespace gl {

ImageManager::ImageManager(GLESRenderEngine* engine) : mEngine(engine) {
ImageManager::ImageManager(GLESRenderEngine* engine) : mEngine(engine) {}

void ImageManager::initThread() {
    mThread = std::thread([this]() { threadMain(); });
    pthread_setname_np(mThread.native_handle(), "ImageManager");
    // Use SCHED_FIFO to minimize jitter
    struct sched_param param = {0};
@@ -133,6 +139,8 @@ void ImageManager::threadMain() {
            entry.barrier->condition.notify_one();
        }
    }

    ALOGD("Reached end of threadMain, terminating ImageManager thread!");
}

} // namespace gl
+5 −1
Original line number Diff line number Diff line
@@ -39,6 +39,10 @@ public:
    };
    ImageManager(GLESRenderEngine* engine);
    ~ImageManager();
    // Starts the background thread for the ImageManager
    // We need this to guarantee that the class is fully-constructed before the
    // thread begins running.
    void initThread();
    void cacheAsync(const sp<GraphicBuffer>& buffer, const std::shared_ptr<Barrier>& barrier)
            EXCLUDES(mMutex);
    status_t cache(const sp<GraphicBuffer>& buffer);
@@ -57,7 +61,7 @@ private:
    void queueOperation(const QueueEntry&& entry);
    void threadMain();
    GLESRenderEngine* const mEngine;
    std::thread mThread = std::thread([this]() { threadMain(); });
    std::thread mThread;
    std::condition_variable_any mCondition;
    std::mutex mMutex;
    std::queue<QueueEntry> mQueue GUARDED_BY(mMutex);