aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIoan-Cristian Szabo <ioan-cristian.szabo@arm.com>2017-12-22 17:32:17 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:42:33 +0000
commit77eb21f7d9c6e34e985dfa96152fb8b6c40f9a8a (patch)
tree0b1cb2c0d7bd38bd2f7eacf41d90ea3a2b758f21
parent88b8d8c2651ee52467fb9e2029ddc9820d442228 (diff)
downloadComputeLibrary-77eb21f7d9c6e34e985dfa96152fb8b6c40f9a8a.tar.gz
Fix destruction order of singleton objects and resolve hang GLES issue.
Change-Id: I9df42d4255b371b275a74aa521406e6796ee436b Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/113901 Reviewed-by: Anthony Barbier <anthony.barbier@arm.com> Tested-by: Anthony Barbier <anthony.barbier@arm.com>
-rw-r--r--arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h14
-rw-r--r--arm_compute/runtime/CL/CLScheduler.h3
-rw-r--r--arm_compute/runtime/GLES_COMPUTE/GCScheduler.h24
-rw-r--r--src/core/GLES_COMPUTE/GCKernelLibrary.cpp64
-rw-r--r--src/runtime/CL/CLScheduler.cpp5
-rw-r--r--src/runtime/GLES_COMPUTE/GCScheduler.cpp74
6 files changed, 100 insertions, 84 deletions
diff --git a/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h b/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h
index db2d979156..34bd5673b8 100644
--- a/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h
+++ b/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h
@@ -191,14 +191,13 @@ class GCKernelLibrary
private:
/** Default Constructor. */
GCKernelLibrary();
+ ~GCKernelLibrary();
public:
/** Prevent instances of this class from being copied. */
GCKernelLibrary(const GCKernelLibrary &) = delete;
/** Prevent instances of this class from being copied. */
const GCKernelLibrary &operator=(const GCKernelLibrary &) = delete;
- /** Default Destructor. */
- ~GCKernelLibrary();
static GCKernelLibrary &get();
/** Initialises the kernel library.
@@ -215,13 +214,6 @@ public:
_display = dpy;
_context = ctx;
- if(_display == EGL_NO_DISPLAY || _context == EGL_NO_CONTEXT)
- {
- setup_context();
-
- _own_context = true;
- }
-
eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, _context);
setup_dummy_fbo();
}
@@ -289,15 +281,11 @@ private:
* @return Concatenated string.
*/
std::string stringify_set(const StringSet &s) const;
- /** Set up EGL context.
- */
- void setup_context();
EGLDisplay _display; /**< Underlying EGL Display. */
EGLContext _context; /**< Underlying EGL Context. */
GLuint _frame_buffer; /**< Dummy fbo */
GLuint _tex_rt; /**< Dummy texture for render target */
- bool _own_context; /**< Self created context or not. */
std::string _shader_path; /**< Path to the shaders folder. */
mutable std::map<std::string, const GCProgram> _programs_map; /**< Map with all already loaded program data. */
mutable std::map<std::string, const GCKernel> _built_programs_map; /**< Map with all already built program data. */
diff --git a/arm_compute/runtime/CL/CLScheduler.h b/arm_compute/runtime/CL/CLScheduler.h
index 1a7befc046..f700bbb679 100644
--- a/arm_compute/runtime/CL/CLScheduler.h
+++ b/arm_compute/runtime/CL/CLScheduler.h
@@ -199,6 +199,9 @@ private:
*/
cl::NDRange tune_kernel(ICLKernel &kernel);
+ /** Flag to ensure symbols initialisation is happening before Scheduler creation */
+ static std::once_flag _initialize_symbols;
+
cl::Context _context;
cl::CommandQueue _queue;
GPUTarget _target;
diff --git a/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h b/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h
index 817f8b54b1..8aac9c4023 100644
--- a/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h
+++ b/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h
@@ -35,10 +35,6 @@ class IGCKernel;
/** Provides global access to a OpenGL ES context and command queue. */
class GCScheduler
{
-private:
- /** Constructor */
- GCScheduler();
-
public:
/** Access the scheduler singleton.
*
@@ -67,7 +63,25 @@ public:
/** Blocks until all commands in the associated command queue have finished. */
void sync();
+
+private:
+ /** Constructor */
+ GCScheduler();
+ /** Destructor */
+ ~GCScheduler();
+ /** Prevent instances of this class from being copied */
+ GCScheduler(const GCScheduler &) = delete;
+ /** Prevent instances of this class from being copied */
+ GCScheduler &operator=(const GCScheduler &) = delete;
+
+ /** Set up EGL context */
+ void setup_context();
+
+ /** Flag to ensure symbols initialisation is happening before Scheduler creation */
+ static std::once_flag _initialize_symbols;
+
+ EGLDisplay _display; /**< Underlying EGL Display. */
+ EGLContext _context; /**< Underlying EGL Context. */
};
}
-
#endif /* __ARM_COMPUTE_GCSCHEDULER_H__ */
diff --git a/src/core/GLES_COMPUTE/GCKernelLibrary.cpp b/src/core/GLES_COMPUTE/GCKernelLibrary.cpp
index 484c8aadfb..549c869bfe 100644
--- a/src/core/GLES_COMPUTE/GCKernelLibrary.cpp
+++ b/src/core/GLES_COMPUTE/GCKernelLibrary.cpp
@@ -298,7 +298,7 @@ const std::map<std::string, std::string> GCKernelLibrary::_program_source_map =
};
GCKernelLibrary::GCKernelLibrary()
- : _display(EGL_NO_DISPLAY), _context(EGL_NO_CONTEXT), _frame_buffer(0), _tex_rt(0), _own_context(false), _shader_path("./"), _programs_map(), _built_programs_map()
+ : _display(EGL_NO_DISPLAY), _context(EGL_NO_CONTEXT), _frame_buffer(0), _tex_rt(0), _shader_path("./"), _programs_map(), _built_programs_map()
{
}
@@ -632,59 +632,6 @@ const GCProgram &GCKernelLibrary::load_program(const std::string &program_name)
return new_program.first->second;
}
-void GCKernelLibrary::setup_context()
-{
- EGLBoolean res;
- _display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-
- ARM_COMPUTE_ERROR_ON_MSG(_display == EGL_NO_DISPLAY, "Failed to get display: 0x%x.", eglGetError());
-
- res = eglInitialize(_display, nullptr, nullptr);
-
- ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to initialize egl: 0x%x.", eglGetError());
- ARM_COMPUTE_UNUSED(res);
-
- const char *egl_extension_st = eglQueryString(_display, EGL_EXTENSIONS);
- ARM_COMPUTE_ERROR_ON_MSG((strstr(egl_extension_st, "EGL_KHR_create_context") == nullptr), "Failed to query EGL_KHR_create_context");
- ARM_COMPUTE_ERROR_ON_MSG((strstr(egl_extension_st, "EGL_KHR_surfaceless_context") == nullptr), "Failed to query EGL_KHR_surfaceless_context");
- ARM_COMPUTE_UNUSED(egl_extension_st);
-
- const EGLint config_attribs[] =
- {
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
- EGL_NONE
- };
- EGLConfig cfg;
- EGLint count;
-
- res = eglChooseConfig(_display, config_attribs, &cfg, 1, &count);
-
- ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to choose config: 0x%x.", eglGetError());
- ARM_COMPUTE_UNUSED(res);
-
- res = eglBindAPI(EGL_OPENGL_ES_API);
-
- ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to bind api: 0x%x.", eglGetError());
-
- const EGLint attribs[] =
- {
- EGL_CONTEXT_CLIENT_VERSION, 3,
- EGL_NONE
- };
- _context = eglCreateContext(_display,
- cfg,
- EGL_NO_CONTEXT,
- attribs);
-
- ARM_COMPUTE_ERROR_ON_MSG(_context == EGL_NO_CONTEXT, "Failed to create context: 0x%x.", eglGetError());
- ARM_COMPUTE_UNUSED(res);
-
- res = eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, _context);
-
- ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to make current: 0x%x.", eglGetError());
- ARM_COMPUTE_UNUSED(res);
-}
-
void GCKernelLibrary::setup_dummy_fbo()
{
ARM_COMPUTE_GL_CHECK(glGenFramebuffers(1, &_frame_buffer));
@@ -706,15 +653,6 @@ GCKernelLibrary::~GCKernelLibrary()
ARM_COMPUTE_GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
ARM_COMPUTE_GL_CHECK(glDeleteTextures(1, &_tex_rt));
ARM_COMPUTE_GL_CHECK(glDeleteFramebuffers(1, &_frame_buffer));
-
- if(_own_context)
- {
- eglDestroyContext(_display, _context);
- eglTerminate(_display);
-
- _context = EGL_NO_CONTEXT;
- _display = EGL_NO_DISPLAY;
- }
}
std::string GCKernelLibrary::stringify_set(const StringSet &s) const
diff --git a/src/runtime/CL/CLScheduler.cpp b/src/runtime/CL/CLScheduler.cpp
index 71a749fe52..bf13a25693 100644
--- a/src/runtime/CL/CLScheduler.cpp
+++ b/src/runtime/CL/CLScheduler.cpp
@@ -28,6 +28,8 @@
using namespace arm_compute;
+std::once_flag CLScheduler::_initialize_symbols;
+
CLScheduler::CLScheduler()
: _context(), _queue(), _target(GPUTarget::MIDGARD), _is_initialised(false), _cl_tuner()
{
@@ -35,6 +37,7 @@ CLScheduler::CLScheduler()
CLScheduler &CLScheduler::get()
{
+ std::call_once(_initialize_symbols, opencl_is_available);
static CLScheduler scheduler;
return scheduler;
}
@@ -59,4 +62,4 @@ void CLScheduler::enqueue(ICLKernel &kernel, bool flush)
{
_queue.flush();
}
-} \ No newline at end of file
+}
diff --git a/src/runtime/GLES_COMPUTE/GCScheduler.cpp b/src/runtime/GLES_COMPUTE/GCScheduler.cpp
index b2235ea6f9..f19b43348d 100644
--- a/src/runtime/GLES_COMPUTE/GCScheduler.cpp
+++ b/src/runtime/GLES_COMPUTE/GCScheduler.cpp
@@ -28,11 +28,27 @@
using namespace arm_compute;
-GCScheduler::GCScheduler() = default;
+std::once_flag GCScheduler::_initialize_symbols;
+
+GCScheduler::GCScheduler()
+ : _display(EGL_NO_DISPLAY), _context(EGL_NO_CONTEXT)
+{
+}
+
+GCScheduler::~GCScheduler()
+{
+ eglDestroyContext(_display, _context);
+ eglTerminate(_display);
+
+ _context = EGL_NO_CONTEXT;
+ _display = EGL_NO_DISPLAY;
+}
void GCScheduler::default_init()
{
- GCKernelLibrary::get().init("./cs_shaders/");
+ setup_context();
+
+ GCKernelLibrary::get().init("./cs_shaders/", _display, _context);
}
void GCScheduler::init(EGLDisplay dpy, EGLContext ctx)
@@ -42,6 +58,7 @@ void GCScheduler::init(EGLDisplay dpy, EGLContext ctx)
GCScheduler &GCScheduler::get()
{
+ std::call_once(_initialize_symbols, opengles31_is_available);
static GCScheduler scheduler;
return scheduler;
}
@@ -59,3 +76,56 @@ void GCScheduler::sync()
{
ARM_COMPUTE_GL_CHECK(glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT));
}
+
+void GCScheduler::setup_context()
+{
+ EGLBoolean res;
+ _display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ ARM_COMPUTE_ERROR_ON_MSG(_display == EGL_NO_DISPLAY, "Failed to get display: 0x%x.", eglGetError());
+
+ res = eglInitialize(_display, nullptr, nullptr);
+
+ ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to initialize egl: 0x%x.", eglGetError());
+ ARM_COMPUTE_UNUSED(res);
+
+ const char *egl_extension_st = eglQueryString(_display, EGL_EXTENSIONS);
+ ARM_COMPUTE_ERROR_ON_MSG((strstr(egl_extension_st, "EGL_KHR_create_context") == nullptr), "Failed to query EGL_KHR_create_context");
+ ARM_COMPUTE_ERROR_ON_MSG((strstr(egl_extension_st, "EGL_KHR_surfaceless_context") == nullptr), "Failed to query EGL_KHR_surfaceless_context");
+ ARM_COMPUTE_UNUSED(egl_extension_st);
+
+ const EGLint config_attribs[] =
+ {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
+ EGL_NONE
+ };
+ EGLConfig cfg;
+ EGLint count;
+
+ res = eglChooseConfig(_display, config_attribs, &cfg, 1, &count);
+
+ ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to choose config: 0x%x.", eglGetError());
+ ARM_COMPUTE_UNUSED(res);
+
+ res = eglBindAPI(EGL_OPENGL_ES_API);
+
+ ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to bind api: 0x%x.", eglGetError());
+
+ const EGLint attribs[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, 3,
+ EGL_NONE
+ };
+ _context = eglCreateContext(_display,
+ cfg,
+ EGL_NO_CONTEXT,
+ attribs);
+
+ ARM_COMPUTE_ERROR_ON_MSG(_context == EGL_NO_CONTEXT, "Failed to create context: 0x%x.", eglGetError());
+ ARM_COMPUTE_UNUSED(res);
+
+ res = eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, _context);
+
+ ARM_COMPUTE_ERROR_ON_MSG(res == EGL_FALSE, "Failed to make current: 0x%x.", eglGetError());
+ ARM_COMPUTE_UNUSED(res);
+}