Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvements to CompilerThreadPool and OpenGLPlatform #7088

Merged
merged 1 commit into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions filament/backend/include/backend/platforms/OpenGLPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ class OpenGLPlatform : public Platform {
* @see terminate()
*/
virtual void createContext(bool shared);

/**
* Detach and destroy the current context if any and releases all resources associated to
* this thread.
*/
virtual void releaseContext() noexcept;
};

} // namespace filament
Expand Down
1 change: 1 addition & 0 deletions filament/backend/include/backend/platforms/PlatformEGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class PlatformEGL : public OpenGLPlatform {
PlatformEGL() noexcept;
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
void releaseContext() noexcept override;

protected:

Expand Down
13 changes: 6 additions & 7 deletions filament/backend/src/CompilerThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,14 @@ CompilerThreadPool::~CompilerThreadPool() noexcept {
assert_invariant(mQueues[1].empty());
}

void CompilerThreadPool::init(uint32_t threadCount, JobSystem::Priority priority,
ThreadSetup&& threadSetup) noexcept {
void CompilerThreadPool::init(uint32_t threadCount,
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) noexcept {
auto setup = std::make_shared<ThreadSetup>(std::move(threadSetup));
auto cleanup = std::make_shared<ThreadCleanup>(std::move(threadCleanup));

for (size_t i = 0; i < threadCount; i++) {
mCompilerThreads.emplace_back([this, priority, setup]() {
mCompilerThreads.emplace_back([this, setup, cleanup]() {
SYSTRACE_CONTEXT();
// give the thread a name
JobSystem::setThreadName("CompilerThreadPool");
// run at a slightly lower priority than other filament threads
JobSystem::setThreadPriority(priority);

(*setup)();

Expand Down Expand Up @@ -80,6 +77,8 @@ void CompilerThreadPool::init(uint32_t threadCount, JobSystem::Priority priority
job();
}
}

(*cleanup)();
});

}
Expand Down
16 changes: 9 additions & 7 deletions filament/backend/src/CompilerThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
#include <backend/DriverEnums.h>

#include <utils/Invocable.h>
#include <utils/JobSystem.h>
#include <utils/Mutex.h>
#include <utils/Condition.h>

#include <array>
#include <atomic>
#include <deque>
#include <memory>
#include <thread>
#include <utility>
#include <vector>

Expand All @@ -45,18 +46,19 @@ class CompilerThreadPool {
~CompilerThreadPool() noexcept;
using Job = utils::Invocable<void()>;
using ThreadSetup = utils::Invocable<void()>;
void init(uint32_t threadCount, utils::JobSystem::Priority priority,
ThreadSetup&& threadSetup) noexcept;
using ThreadCleanup = utils::Invocable<void()>;
void init(uint32_t threadCount,
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) noexcept;
void terminate() noexcept;
void queue(CompilerPriorityQueue priorityQueue, program_token_t const& token, Job&& job);
Job dequeue(program_token_t const& token);

private:
using Queue = std::deque<std::pair<program_token_t, Job>>;
std::vector<std::thread> mCompilerThreads;
std::atomic_bool mExitRequested{false};
std::mutex mQueueLock;
std::condition_variable mQueueCondition;
bool mExitRequested{ false };
utils::Mutex mQueueLock;
utils::Condition mQueueCondition;
std::array<Queue, 2> mQueues;
// lock must be held for methods below
std::pair<Queue&, Queue::iterator> find(program_token_t const& token);
Expand Down
3 changes: 3 additions & 0 deletions filament/backend/src/opengl/OpenGLPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,7 @@ bool OpenGLPlatform::isExtraContextSupported() const noexcept {
void OpenGLPlatform::createContext(bool) {
}

void OpenGLPlatform::releaseContext() noexcept {
}

} // namespace filament::backend
14 changes: 11 additions & 3 deletions filament/backend/src/opengl/ShaderCompilerService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,18 @@ void ShaderCompilerService::init() noexcept {
}

mShaderCompilerThreadCount = poolSize;
mCompilerThreadPool.init(mShaderCompilerThreadCount, priority,
[platform = &mDriver.mPlatform]() {
mCompilerThreadPool.init(mShaderCompilerThreadCount,
[&platform = mDriver.mPlatform, priority]() {
// give the thread a name
JobSystem::setThreadName("CompilerThreadPool");
// run at a slightly lower priority than other filament threads
JobSystem::setThreadPriority(priority);
// create a gl context current to this thread
platform->createContext(true);
platform.createContext(true);
},
[&platform = mDriver.mPlatform]() {
// release context and thread state
platform.releaseContext();
});
}
}
Expand Down
19 changes: 18 additions & 1 deletion filament/backend/src/opengl/platforms/PlatformEGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,22 @@ void PlatformEGL::createContext(bool shared) {
mAdditionalContexts.push_back(context);
}

void PlatformEGL::releaseContext() noexcept {
EGLContext context = eglGetCurrentContext();
eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (context != EGL_NO_CONTEXT) {
eglDestroyContext(mEGLDisplay, context);
}

mAdditionalContexts.erase(
std::remove_if(mAdditionalContexts.begin(), mAdditionalContexts.end(),
[context](EGLContext c) {
return c == context;
}), mAdditionalContexts.end());

eglReleaseThread();
}

EGLBoolean PlatformEGL::makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept {
if (UTILS_UNLIKELY((drawSurface != mCurrentDrawSurface || readSurface != mCurrentReadSurface))) {
mCurrentDrawSurface = drawSurface;
Expand All @@ -304,7 +320,8 @@ EGLBoolean PlatformEGL::makeCurrent(EGLSurface drawSurface, EGLSurface readSurfa
}

void PlatformEGL::terminate() noexcept {
eglMakeCurrent(mEGLDisplay, mEGLDummySurface, mEGLDummySurface, EGL_NO_CONTEXT);
// it's always allowed to use EGL_NO_SURFACE, EGL_NO_CONTEXT
eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (mEGLDummySurface) {
eglDestroySurface(mEGLDisplay, mEGLDummySurface);
}
Expand Down
Loading