COMPMID-2549: Add GLES Runtime Context interfaces.

* Creates interfaces and concrete classes
* Ports GCActivationalLayer
* Adapts test framework and relevant tests

Change-Id: Ide36cd65ebf185958db3c4a5bebd630fcb2f39b3
Signed-off-by: Georgios Pinitas <georgios.pinitas@arm.com>
Reviewed-on: https://review.mlplatform.org/c/2199
Reviewed-by: Pablo Marquez <pablo.tello@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
diff --git a/arm_compute/core/CL/CLCoreRuntimeContext.h b/arm_compute/core/CL/CLCoreRuntimeContext.h
index 6e2bd43..c5d8177 100644
--- a/arm_compute/core/CL/CLCoreRuntimeContext.h
+++ b/arm_compute/core/CL/CLCoreRuntimeContext.h
@@ -28,8 +28,10 @@
 
 namespace arm_compute
 {
+// Forward declarations
 class CLKernelLibrary;
-/** Core runtime context */
+
+/** Core runtime context for OpenCL */
 class CLCoreRuntimeContext final
 {
 public:
@@ -48,10 +50,20 @@
     CLCoreRuntimeContext &operator=(const CLCoreRuntimeContext &) = default;
     /** Default move assignment operator */
     CLCoreRuntimeContext &operator=(CLCoreRuntimeContext &&) = default;
-    /** CPU Scheduler setter */
-
+    /** Kernel Library accessor
+     *
+     * @return The kernel library instance used by the core context
+     */
     CLKernelLibrary *kernel_library() const;
-    cl::Context      context();
+    /** OpenCL context accessor
+     *
+     * @return The OpenCL context used by the core context
+     */
+    cl::Context context();
+    /** OpenCL command queue accessor
+     *
+     * @return The OpenCL queue used by the core context
+     */
     cl::CommandQueue queue();
 
 private:
diff --git a/arm_compute/core/CL/CLHelpers.h b/arm_compute/core/CL/CLHelpers.h
index 9130e05..8801af5 100644
--- a/arm_compute/core/CL/CLHelpers.h
+++ b/arm_compute/core/CL/CLHelpers.h
@@ -182,5 +182,5 @@
  * @return An opencl kernel
  */
 cl::Kernel create_opencl_kernel(CLCoreRuntimeContext *ctx, const std::string &kernel_name, const CLBuildOptions &build_opts);
-}
+} // namespace arm_compute
 #endif /* __ARM_COMPUTE_CLHELPERS_H__ */
diff --git a/arm_compute/core/CL/CLKernelLibrary.h b/arm_compute/core/CL/CLKernelLibrary.h
index f228269..4f5aa76 100644
--- a/arm_compute/core/CL/CLKernelLibrary.h
+++ b/arm_compute/core/CL/CLKernelLibrary.h
@@ -327,5 +327,5 @@
     static const std::map<std::string, std::string> _program_source_map; /**< Contains sources for all programs.
                                                                               Used for compile-time kernel inclusion. >*/
 };
-}
+} // namespace arm_compute
 #endif /* __ARM_COMPUTE_CLKERNELLIBRARY_H__ */
diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h
index b1d50e7..9b402ab 100644
--- a/arm_compute/core/CL/OpenCL.h
+++ b/arm_compute/core/CL/OpenCL.h
@@ -61,9 +61,13 @@
 class CLSymbols final
 {
 public:
+    /** Default Constructor */
     CLSymbols() = default;
+    /** Load OpenCL symbols from handle
+     *
+     * @param[in] handle Handle to load symbols from
+     */
     void load_symbols(void *handle);
-
     /** Get the static instance of CLSymbols.
      *
      * @return The static instance of CLSymbols.
diff --git a/arm_compute/core/GLES_COMPUTE/GCCoreRuntimeContext.h b/arm_compute/core/GLES_COMPUTE/GCCoreRuntimeContext.h
new file mode 100644
index 0000000..be47bfd
--- /dev/null
+++ b/arm_compute/core/GLES_COMPUTE/GCCoreRuntimeContext.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_GCCORERUNTIME_CONTEXT_H__
+#define __ARM_COMPUTE_GCCORERUNTIME_CONTEXT_H__
+
+#include "arm_compute/core/GLES_COMPUTE/OpenGLES.h"
+
+namespace arm_compute
+{
+// Forward declarations
+class GCKernelLibrary;
+
+/** Core runtime context for OpenGL ES */
+class GCCoreRuntimeContext final
+{
+public:
+    /** Legacy constructor */
+    GCCoreRuntimeContext();
+
+    /** Constructor */
+    GCCoreRuntimeContext(GCKernelLibrary *kernel_lib);
+    /** Destructor */
+    ~GCCoreRuntimeContext() = default;
+    /** Default copy constructor */
+    GCCoreRuntimeContext(const GCCoreRuntimeContext &) = default;
+    /** Default move constructor */
+    GCCoreRuntimeContext(GCCoreRuntimeContext &&) = default;
+    /** Default copy assignment */
+    GCCoreRuntimeContext &operator=(const GCCoreRuntimeContext &) = default;
+    /** Default move assignment operator */
+    GCCoreRuntimeContext &operator=(GCCoreRuntimeContext &&) = default;
+    /** Kernel Library accessor
+     *
+     * @return The kernel library instance used by the core context
+     */
+    GCKernelLibrary *kernel_library() const;
+
+private:
+    GCKernelLibrary *_kernel_lib{ nullptr };
+};
+} // namespace arm_compute
+#endif /*__ARM_COMPUTE_GCCORERUNTIME_CONTEXT_H__ */
diff --git a/arm_compute/core/GLES_COMPUTE/GCHelpers.h b/arm_compute/core/GLES_COMPUTE/GCHelpers.h
index 1422afe..ccab6c5 100644
--- a/arm_compute/core/GLES_COMPUTE/GCHelpers.h
+++ b/arm_compute/core/GLES_COMPUTE/GCHelpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -24,13 +24,20 @@
 #ifndef __ARM_COMPUTE_GCHELPERS_H__
 #define __ARM_COMPUTE_GCHELPERS_H__
 
+#include "arm_compute/core/GLES_COMPUTE/IGCKernel.h"
 #include "arm_compute/core/GLES_COMPUTE/OpenGLES.h"
 #include "arm_compute/core/GPUTarget.h"
 #include "arm_compute/core/Helpers.h"
 #include "support/ToolchainSupport.h"
 
+#include <set>
+#include <string>
+
 namespace arm_compute
 {
+// Forward declarations
+class GCCoreRuntimeContext;
+
 /** Max vector width of an GLES vector */
 static constexpr unsigned int max_gc_vector_width = 16;
 
@@ -39,5 +46,14 @@
  * @return the GPU target
  */
 GPUTarget get_target_from_device();
+/** Creates an GLES kernel
+ *
+ * @param[in] ctx         A context to be used to create the GLES kernel.
+ * @param[in] kernel_name The kernel name.
+ * @param[in] build_opts  The build options to be used for the GLES kernel compilation.
+ *
+ * @return A GLES kernel
+ */
+GCKernel create_opengl_kernel(GCCoreRuntimeContext *ctx, const std::string &kernel_name, const std::set<std::string> &build_opts);
 } // namespace arm_compute
 #endif /* __ARM_COMPUTE_GCHELPERS_H__ */
diff --git a/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h b/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h
index 89d6d17..92e6bee 100644
--- a/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h
+++ b/arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h
@@ -36,7 +36,7 @@
 namespace arm_compute
 {
 /** GCProgram class */
-class GCProgram
+class GCProgram final
 {
 public:
     /** Default constructor. */
@@ -84,7 +84,7 @@
 };
 
 /** GCKernel class */
-class GCKernel
+class GCKernel final
 {
 public:
     /** Default Constructor. */
@@ -184,22 +184,21 @@
 };
 
 /** GCKernelLibrary class */
-class GCKernelLibrary
+class GCKernelLibrary final
 {
     using StringSet = std::set<std::string>;
 
-private:
+public:
     /** Default Constructor. */
     GCKernelLibrary();
+    /** Default Destructor */
     ~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;
     /** Get the static instance of @ref GCKernelLibrary.
-     *
+     * This method has been deprecated and will be removed in the next release.
      * @return The static instance of GCKernelLibrary.
      */
     static GCKernelLibrary &get();
@@ -209,40 +208,18 @@
      * @param[in] dpy         (Optional) EGLdisplay set by external application.
      * @param[in] ctx         (Optional) EGLContext set by external application.
      */
-    void init(std::string shader_path = "./", EGLDisplay dpy = EGL_NO_DISPLAY, EGLContext ctx = EGL_NO_CONTEXT)
-    {
-        //TODO: deal with old display and context.
-        _shader_path = std::move(shader_path);
-
-        _display = dpy;
-        _context = ctx;
-
-        eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, _context);
-        setup_dummy_fbo();
-    }
-
+    void init(std::string shader_path = "./", EGLDisplay dpy = EGL_NO_DISPLAY, EGLContext ctx = EGL_NO_CONTEXT);
     /** Sets the path that the shaders reside in.
      *
      * @param[in] shader_path Path of the shader.
      */
-    void set_shader_path(const std::string &shader_path)
-    {
-        _shader_path = shader_path;
-    };
+    void set_shader_path(const std::string &shader_path);
     /** Sets display and context to create kernel.
      *
      * @param[in] dpy EGLdisplay set by external application.
      * @param[in] ctx EGLContext set by external application.
      */
-    void set_context(EGLDisplay dpy, EGLContext ctx)
-    {
-        //TODO: deal with old display and context.
-        _display = dpy;
-        _context = ctx;
-
-        eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
-        setup_dummy_fbo();
-    };
+    void set_context(EGLDisplay dpy, EGLContext ctx);
     /** Creates a kernel from the kernel library.
      *
      * @param[in] shader_name       Shader name.
@@ -251,17 +228,11 @@
      * @return The created kernel.
      */
     GCKernel create_kernel(const std::string &shader_name, const StringSet &build_options_set = {}) const;
-    /** Serializes and saves programs to a binary.
-     *
-     */
+    /** Serializes and saves programs to a binary. */
     void save_binary();
-    /** Load serialized binary with all the programs.
-     *
-     */
+    /** Load serialized binary with all the programs. */
     void load_binary();
-    /** Setup a dummy fbo to workaround an issue on Galaxy S8.
-     *
-     */
+    /** Setup a dummy fbo to workaround an issue on Galaxy S8. */
     void setup_dummy_fbo();
 
 private:
@@ -296,5 +267,5 @@
     static const std::map<std::string, std::string> _program_source_map; /**< Contains sources for all programs.
                                                                               Used for compile-time shader inclusion. */
 };
-}
+} // namespace arm_compute
 #endif /* __ARM_COMPUTE_GCKERNELLIBRARY_H__ */
diff --git a/arm_compute/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.h b/arm_compute/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.h
index fc1d52f..8388222 100644
--- a/arm_compute/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.h
+++ b/arm_compute/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -28,14 +28,19 @@
 
 namespace arm_compute
 {
+// Forward declarations
 class IGCTensor;
+class GCCoreRuntimeContext;
 
 /** Interface for the activation layer kernel. */
 class GCActivationLayerKernel : public IGCKernel
 {
 public:
-    /** Default constructor */
-    GCActivationLayerKernel();
+    /** Default constructor
+     *
+     * @param[in, out] ctx Core context to use
+     */
+    explicit GCActivationLayerKernel(GCCoreRuntimeContext *ctx = nullptr);
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     GCActivationLayerKernel(const GCActivationLayerKernel &) = delete;
     /** Prevent instances of this class from being copied (As this class contains pointers) */
@@ -61,8 +66,9 @@
     void run(const Window &window) override;
 
 private:
-    IGCTensor *_input;
-    IGCTensor *_output;
+    IGCTensor            *_input;
+    IGCTensor            *_output;
+    GCCoreRuntimeContext *_ctx;
 };
-}
+} // namespace arm_compute
 #endif /*__ARM_COMPUTE_GCACTIVATIONLAYERKERNEL_H__ */
diff --git a/arm_compute/runtime/CL/CLHelpers.h b/arm_compute/runtime/CL/CLHelpers.h
index 84f155a..6d00026 100644
--- a/arm_compute/runtime/CL/CLHelpers.h
+++ b/arm_compute/runtime/CL/CLHelpers.h
@@ -29,8 +29,10 @@
 
 namespace arm_compute
 {
+// Forward declarations
 class CLRuntimeContext;
 class ICLKernel;
+
 /** This function creates an OpenCL context and a device.
  *
  * @note In debug builds, the function will automatically enable cl_arm_printf if the driver/device supports it.
diff --git a/arm_compute/runtime/CL/CLScheduler.h b/arm_compute/runtime/CL/CLScheduler.h
index 720c8b3..3620820 100644
--- a/arm_compute/runtime/CL/CLScheduler.h
+++ b/arm_compute/runtime/CL/CLScheduler.h
@@ -153,5 +153,5 @@
     ICLTuner                 *_cl_tuner;
     std::unique_ptr<ICLTuner> _cl_default_static_tuner;
 };
-}
+} // namespace arm_compute
 #endif /* __ARM_COMPUTE_CLSCHEDULER_H__ */
diff --git a/arm_compute/runtime/CL/ICLSimpleFunction.h b/arm_compute/runtime/CL/ICLSimpleFunction.h
index 8399a3d..5b6b608 100644
--- a/arm_compute/runtime/CL/ICLSimpleFunction.h
+++ b/arm_compute/runtime/CL/ICLSimpleFunction.h
@@ -32,7 +32,9 @@
 
 namespace arm_compute
 {
+// Forward declarations
 class CLRuntimeContext;
+
 /** Basic interface for functions which have a single OpenCL kernel */
 class ICLSimpleFunction : public IFunction
 {
@@ -60,5 +62,5 @@
     CLFillBorderKernel         _border_handler; /**< Kernel to handle  borders */
     CLRuntimeContext          *_ctx;            /**< Context to use */
 };
-}
+} // namespace arm_compute
 #endif /*__ARM_COMPUTE_ICLSIMPLEFUNCTION_H__ */
diff --git a/arm_compute/runtime/GLES_COMPUTE/GCHelpers.h b/arm_compute/runtime/GLES_COMPUTE/GCHelpers.h
new file mode 100644
index 0000000..efc95e7
--- /dev/null
+++ b/arm_compute/runtime/GLES_COMPUTE/GCHelpers.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_GC_HELPERS_H__
+#define __ARM_COMPUTE_GC_HELPERS_H__
+
+#include "arm_compute/core/GLES_COMPUTE/OpenGLES.h"
+
+namespace arm_compute
+{
+/** This function creates an OpenGL-ES context and a display.
+ *
+ * @return A std::tuple where the first element is the opengl display, the second element is the opengl context
+ *         and the third one an error code. The error code will be EGL_TRUE upon successful creation, otherwise
+ *         a value telling why the function failed.
+ */
+std::tuple<EGLDisplay, EGLContext, EGLBoolean> create_opengl_display_and_context();
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GC_HELPERS_H__ */
diff --git a/arm_compute/runtime/GLES_COMPUTE/GCRuntimeContext.h b/arm_compute/runtime/GLES_COMPUTE/GCRuntimeContext.h
new file mode 100644
index 0000000..353e9ec
--- /dev/null
+++ b/arm_compute/runtime/GLES_COMPUTE/GCRuntimeContext.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_GCRUNTIME_CONTEXT_H__
+#define __ARM_COMPUTE_GCRUNTIME_CONTEXT_H__
+
+#include "arm_compute/core/GLES_COMPUTE/GCCoreRuntimeContext.h"
+#include "arm_compute/core/GLES_COMPUTE/GCKernelLibrary.h"
+#include "arm_compute/core/GLES_COMPUTE/OpenGLES.h"
+#include "arm_compute/runtime/GLES_COMPUTE/GCScheduler.h"
+#include "arm_compute/runtime/IScheduler.h"
+#include "arm_compute/runtime/RuntimeContext.h"
+
+namespace arm_compute
+{
+/** Runtime context */
+class GCRuntimeContext : public RuntimeContext
+{
+public:
+    /** Default Constructor */
+    GCRuntimeContext();
+    /** Destructor */
+    ~GCRuntimeContext() = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    GCRuntimeContext(const GCRuntimeContext &) = delete;
+    /** Default move constructor */
+    GCRuntimeContext(GCRuntimeContext &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    GCRuntimeContext &operator=(const GCRuntimeContext &) = delete;
+    /** Default move assignment operator */
+    GCRuntimeContext &operator=(GCRuntimeContext &&) = default;
+    /** CPU Scheduler setter */
+    void set_gpu_scheduler(GCScheduler *scheduler);
+
+    // Inherited overridden methods
+    GCScheduler          *gpu_scheduler();
+    GCKernelLibrary      &kernel_library();
+    GCCoreRuntimeContext *core_runtime_context();
+
+private:
+    std::unique_ptr<GCScheduler> _gpu_owned_scheduler{ nullptr };
+    GCScheduler                 *_gpu_scheduler{ nullptr };
+    GCKernelLibrary              _kernel_lib{};
+    GCCoreRuntimeContext         _core_context{};
+};
+} // namespace arm_compute
+#endif /*__ARM_COMPUTE_GCRUNTIME_CONTEXT_H__ */
diff --git a/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h b/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h
index 1cf2af4..e26e311 100644
--- a/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h
+++ b/arm_compute/runtime/GLES_COMPUTE/GCScheduler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -30,40 +30,50 @@
 
 namespace arm_compute
 {
+// Forward declarations
 class IGCKernel;
 
 /** Provides global access to a OpenGL ES context and command queue. */
-class GCScheduler
+class GCScheduler final
 {
 public:
+    /** 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;
     /** Access the scheduler singleton.
      *
      * @return The scheduler
      */
     static GCScheduler &get();
-
     /** Initialises the context and command queue used by the scheduler to default values
      *  and sets a default device and kernel path for the @ref GCKernelLibrary.
      */
     void default_init();
-
+    /** Initializes the context and display used by the Scheduler.
+     *
+     * @param[in] display Display to use
+     * @param[in] ctx     Context to use
+     */
+    void default_init_with_context(EGLDisplay display, EGLContext ctx);
     /** Schedule the execution of the passed kernel if possible.
      *
      * @param[in] kernel Kernel to execute.
      * @param[in] flush  (Optional) Specifies if the command queue will be flushed after running the kernel.
      */
     void dispatch(IGCKernel &kernel, bool flush = true);
-
     /** Initialises the display and context to be used by the scheduler.
      *
      * @param[in] dpy The EGL display connection
      * @param[in] ctx The EGL rendering context
      */
     void init(EGLDisplay dpy, EGLContext ctx);
-
     /** Defines a barrier ordering memory transactions. */
     void memory_barrier();
-
     /** Get the target GPU.
      *
      * @return The target GPU.
@@ -72,7 +82,6 @@
     {
         return _target;
     }
-
     /** Accessor to set target GPU to be used by the scheduler.
      *
      * @param[in] target The target GPU.
@@ -83,15 +92,6 @@
     }
 
 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();
 
diff --git a/arm_compute/runtime/GLES_COMPUTE/IGCSimpleFunction.h b/arm_compute/runtime/GLES_COMPUTE/IGCSimpleFunction.h
index 15bbfff..c3bd463 100644
--- a/arm_compute/runtime/GLES_COMPUTE/IGCSimpleFunction.h
+++ b/arm_compute/runtime/GLES_COMPUTE/IGCSimpleFunction.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -26,6 +26,7 @@
 
 #include "arm_compute/core/GLES_COMPUTE/IGCKernel.h"
 #include "arm_compute/core/GLES_COMPUTE/kernels/GCFillBorderKernel.h"
+#include "arm_compute/runtime/GLES_COMPUTE/GCRuntimeContext.h"
 #include "arm_compute/runtime/IFunction.h"
 
 #include <memory>
@@ -36,8 +37,19 @@
 class IGCSimpleFunction : public IFunction
 {
 public:
-    /** Default constructor */
-    IGCSimpleFunction();
+    /** Default Constructor
+     *
+     * @param[in] ctx Runtime context to be used by the function
+     */
+    IGCSimpleFunction(GCRuntimeContext *ctx = nullptr);
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    IGCSimpleFunction(const IGCSimpleFunction &) = delete;
+    /** Default move constructor */
+    IGCSimpleFunction(IGCSimpleFunction &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    IGCSimpleFunction &operator=(const IGCSimpleFunction &) = delete;
+    /** Default move assignment operator */
+    IGCSimpleFunction &operator=(IGCSimpleFunction &&) = default;
 
     // Inherited methods overridden:
     void run() override final;
@@ -45,6 +57,7 @@
 protected:
     std::unique_ptr<IGCKernel> _kernel;         /**< Kernel to run */
     GCFillBorderKernel         _border_handler; /**< Kernel to handle  borders */
+    GCRuntimeContext          *_ctx;            /**< Context to use */
 };
-}
+} // namespace arm_compute
 #endif /*__ARM_COMPUTE_IGCSIMPLEFUNCTION_H__ */
diff --git a/arm_compute/runtime/GLES_COMPUTE/functions/GCActivationLayer.h b/arm_compute/runtime/GLES_COMPUTE/functions/GCActivationLayer.h
index 5e0effe..a046d1b 100644
--- a/arm_compute/runtime/GLES_COMPUTE/functions/GCActivationLayer.h
+++ b/arm_compute/runtime/GLES_COMPUTE/functions/GCActivationLayer.h
@@ -29,6 +29,7 @@
 
 namespace arm_compute
 {
+// Forward declarations
 class IGCTensor;
 
 /** Basic function to run @ref GCActivationLayerKernel
@@ -40,9 +41,9 @@
 public:
     /** Constructor
      *
-     * @param[in] ctx Runtime context to be used by the function
+     * @param[in, out] ctx Runtime context to be used by the function
      */
-    GCActivationLayer(void *ctx = nullptr);
+    explicit GCActivationLayer(GCRuntimeContext *ctx = nullptr);
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     GCActivationLayer(const GCActivationLayer &) = delete;
     /** Default move constructor */
diff --git a/src/core/CL/CLHelpers.cpp b/src/core/CL/CLHelpers.cpp
index 1132aa4..26660ce 100644
--- a/src/core/CL/CLHelpers.cpp
+++ b/src/core/CL/CLHelpers.cpp
@@ -338,12 +338,12 @@
 {
     if(ctx && ctx->kernel_library())
     {
-        //New api going through the core context
+        // New api going through the core context
         return static_cast<cl::Kernel>(ctx->kernel_library()->create_kernel(kernel_name, build_opts.options()));
     }
     else
     {
-        //Legacy code through the singleton
+        // Legacy code through the singleton
         return static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options()));
     }
 }
diff --git a/src/core/GLES_COMPUTE/GCCoreRuntimeContext.cpp b/src/core/GLES_COMPUTE/GCCoreRuntimeContext.cpp
new file mode 100644
index 0000000..311dfd2
--- /dev/null
+++ b/src/core/GLES_COMPUTE/GCCoreRuntimeContext.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/GLES_COMPUTE/GCCoreRuntimeContext.h"
+
+namespace arm_compute
+{
+GCCoreRuntimeContext::GCCoreRuntimeContext()
+    : _kernel_lib(nullptr)
+{
+}
+
+GCCoreRuntimeContext::GCCoreRuntimeContext(GCKernelLibrary *kernel_lib)
+    : _kernel_lib(kernel_lib)
+{
+}
+
+GCKernelLibrary *GCCoreRuntimeContext::kernel_library() const
+{
+    return _kernel_lib;
+}
+} // namespace arm_compute
diff --git a/src/core/GLES_COMPUTE/GCHelpers.cpp b/src/core/GLES_COMPUTE/GCHelpers.cpp
index 8970688..b974007 100644
--- a/src/core/GLES_COMPUTE/GCHelpers.cpp
+++ b/src/core/GLES_COMPUTE/GCHelpers.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -23,6 +23,8 @@
  */
 #include "arm_compute/core/GLES_COMPUTE/GCHelpers.h"
 
+#include "arm_compute/core/GLES_COMPUTE/GCCoreRuntimeContext.h"
+
 namespace arm_compute
 {
 GPUTarget get_target_from_device()
@@ -31,4 +33,18 @@
 
     return get_target_from_name(device_name);
 }
+
+GCKernel create_opengl_kernel(GCCoreRuntimeContext *ctx, const std::string &kernel_name, const std::set<std::string> &build_opts)
+{
+    if(ctx && ctx->kernel_library())
+    {
+        // New api going through the core context
+        return ctx->kernel_library()->create_kernel(kernel_name, build_opts);
+    }
+    else
+    {
+        // Legacy code through the singleton
+        return GCKernelLibrary::get().create_kernel(kernel_name, build_opts);
+    }
+}
 } // namespace arm_compute
diff --git a/src/core/GLES_COMPUTE/GCKernelLibrary.cpp b/src/core/GLES_COMPUTE/GCKernelLibrary.cpp
index 015e085..4b3c5aa 100644
--- a/src/core/GLES_COMPUTE/GCKernelLibrary.cpp
+++ b/src/core/GLES_COMPUTE/GCKernelLibrary.cpp
@@ -337,6 +337,33 @@
     return _kernel_library;
 }
 
+void GCKernelLibrary::init(std::string shader_path, EGLDisplay dpy, EGLContext ctx)
+{
+    //TODO: deal with old display and context.
+    _shader_path = std::move(shader_path);
+
+    _display = dpy;
+    _context = ctx;
+
+    eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, _context);
+    setup_dummy_fbo();
+}
+
+void GCKernelLibrary::set_shader_path(const std::string &shader_path)
+{
+    _shader_path = shader_path;
+}
+
+void GCKernelLibrary::set_context(EGLDisplay dpy, EGLContext ctx)
+{
+    //TODO: deal with old display and context.
+    _display = dpy;
+    _context = ctx;
+
+    eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
+    setup_dummy_fbo();
+}
+
 GCKernel GCKernelLibrary::create_kernel(const std::string &shader_name, const StringSet &build_options_set) const
 {
     // Find which program contains the kernel
diff --git a/src/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.cpp b/src/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.cpp
index 174e048..ab3e179 100644
--- a/src/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.cpp
+++ b/src/core/GLES_COMPUTE/kernels/GCActivationLayerKernel.cpp
@@ -39,8 +39,8 @@
 
 using namespace arm_compute;
 
-GCActivationLayerKernel::GCActivationLayerKernel()
-    : _input(nullptr), _output(nullptr)
+GCActivationLayerKernel::GCActivationLayerKernel(GCCoreRuntimeContext *ctx)
+    : _input(nullptr), _output(nullptr), _ctx(ctx)
 {
 }
 
@@ -77,7 +77,7 @@
     build_opts.emplace(("#define LOCAL_SIZE_Z " + support::cpp11::to_string(1)));
 
     // Create kernel
-    _kernel = static_cast<GCKernel>(GCKernelLibrary::get().create_kernel("activation_layer", build_opts));
+    _kernel = create_opengl_kernel(_ctx, "activation_layer", build_opts);
 
     // Configure kernel window
     Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
diff --git a/src/runtime/GLES_COMPUTE/GCHelpers.cpp b/src/runtime/GLES_COMPUTE/GCHelpers.cpp
new file mode 100644
index 0000000..df2f4f5
--- /dev/null
+++ b/src/runtime/GLES_COMPUTE/GCHelpers.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "arm_compute/runtime/GLES_COMPUTE/GCHelpers.h"
+
+#include "arm_compute/core/Error.h"
+
+namespace arm_compute
+{
+std::tuple<EGLDisplay, EGLContext, EGLBoolean> create_opengl_display_and_context()
+{
+    EGLBoolean res;
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+    ARM_COMPUTE_ERROR_ON_MSG_VAR(display == EGL_NO_DISPLAY, "Failed to get display: 0x%x.", eglGetError());
+
+    res = eglInitialize(display, nullptr, nullptr);
+
+    ARM_COMPUTE_ERROR_ON_MSG_VAR(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 std::array<EGLint, 3> config_attribs =
+    {
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
+        EGL_NONE
+    };
+    EGLConfig cfg;
+    EGLint    count;
+
+    res = eglChooseConfig(display, config_attribs.data(), &cfg, 1, &count);
+
+    ARM_COMPUTE_ERROR_ON_MSG_VAR(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_VAR(res == EGL_FALSE, "Failed to bind api: 0x%x.", eglGetError());
+
+    const std::array<EGLint, 3> attribs =
+    {
+        EGL_CONTEXT_CLIENT_VERSION, 3,
+        EGL_NONE
+    };
+    EGLContext context = eglCreateContext(display,
+                                          cfg,
+                                          EGL_NO_CONTEXT,
+                                          attribs.data());
+
+    ARM_COMPUTE_ERROR_ON_MSG_VAR(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_VAR(res == EGL_FALSE, "Failed to make current: 0x%x.", eglGetError());
+    ARM_COMPUTE_UNUSED(res);
+
+    return std::make_tuple(display, context, res);
+}
+} // namespace arm_compute
diff --git a/src/runtime/GLES_COMPUTE/GCRuntimeContext.cpp b/src/runtime/GLES_COMPUTE/GCRuntimeContext.cpp
new file mode 100644
index 0000000..1c30af1
--- /dev/null
+++ b/src/runtime/GLES_COMPUTE/GCRuntimeContext.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/GLES_COMPUTE/GCRuntimeContext.h"
+
+#include "arm_compute/core/Validate.h"
+#include "arm_compute/runtime/GLES_COMPUTE/GCHelpers.h"
+#include "arm_compute/runtime/GLES_COMPUTE/GCScheduler.h"
+
+namespace arm_compute
+{
+GCRuntimeContext::GCRuntimeContext()
+    : _gpu_owned_scheduler(support::cpp14::make_unique<GCScheduler>()),
+      _gpu_scheduler(_gpu_owned_scheduler.get()),
+      _core_context()
+{
+    auto attrs   = create_opengl_display_and_context();
+    auto display = std::get<0>(attrs);
+    auto ctx     = std::get<1>(attrs);
+
+    _gpu_owned_scheduler->default_init_with_context(display, ctx);
+    _kernel_lib.init("./cs_shaders/", display, ctx);
+
+    _core_context = GCCoreRuntimeContext(&_kernel_lib);
+}
+
+GCKernelLibrary &GCRuntimeContext::kernel_library()
+{
+    return _kernel_lib;
+}
+
+GCCoreRuntimeContext *GCRuntimeContext::core_runtime_context()
+{
+    return &_core_context;
+}
+
+void GCRuntimeContext::set_gpu_scheduler(GCScheduler *scheduler)
+{
+    ARM_COMPUTE_ERROR_ON_NULLPTR(scheduler);
+    _gpu_scheduler = scheduler;
+}
+
+GCScheduler *GCRuntimeContext::gpu_scheduler()
+{
+    return _gpu_scheduler;
+}
+} // namespace arm_compute
diff --git a/src/runtime/GLES_COMPUTE/GCScheduler.cpp b/src/runtime/GLES_COMPUTE/GCScheduler.cpp
index 0824af3..a45d793 100644
--- a/src/runtime/GLES_COMPUTE/GCScheduler.cpp
+++ b/src/runtime/GLES_COMPUTE/GCScheduler.cpp
@@ -52,6 +52,14 @@
     init(_display, _context);
 }
 
+void GCScheduler::default_init_with_context(EGLDisplay display, EGLContext ctx)
+{
+    _context = ctx;
+    _display = display;
+
+    _target = get_target_from_device();
+}
+
 void GCScheduler::init(EGLDisplay dpy, EGLContext ctx)
 {
     _target = get_target_from_device();
diff --git a/src/runtime/GLES_COMPUTE/IGCSimpleFunction.cpp b/src/runtime/GLES_COMPUTE/IGCSimpleFunction.cpp
index f2926b0..bb9239e 100644
--- a/src/runtime/GLES_COMPUTE/IGCSimpleFunction.cpp
+++ b/src/runtime/GLES_COMPUTE/IGCSimpleFunction.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -28,17 +28,20 @@
 
 using namespace arm_compute;
 
-IGCSimpleFunction::IGCSimpleFunction() //NOLINT
+IGCSimpleFunction::IGCSimpleFunction(GCRuntimeContext *ctx) //NOLINT
     : _kernel(),
-      _border_handler()
+      _border_handler(),
+      _ctx(ctx)
 {
 }
 
 void IGCSimpleFunction::run()
 {
     ARM_COMPUTE_ERROR_ON_MSG(!_kernel, "The child class didn't set the GLES kernel or function isn't configured");
+    GCScheduler *scheduler = (_ctx != nullptr) ? _ctx->gpu_scheduler() : &GCScheduler::get().get();
+    ARM_COMPUTE_ERROR_ON(scheduler == nullptr);
 
-    GCScheduler::get().dispatch(_border_handler, false);
-    GCScheduler::get().memory_barrier();
-    GCScheduler::get().dispatch(*_kernel);
+    scheduler->dispatch(_border_handler, false);
+    scheduler->memory_barrier();
+    scheduler->dispatch(*_kernel);
 }
diff --git a/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp b/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp
index 207e8ce..0700b2b 100644
--- a/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp
+++ b/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp
@@ -29,14 +29,16 @@
 
 namespace arm_compute
 {
-GCActivationLayer::GCActivationLayer(void *ctx)
+GCActivationLayer::GCActivationLayer(GCRuntimeContext *ctx)
+    : IGCSimpleFunction(ctx)
 {
-    ARM_COMPUTE_UNUSED(ctx);
 }
 
 void GCActivationLayer::configure(IGCTensor *input, IGCTensor *output, ActivationLayerInfo act_info)
 {
-    auto k = arm_compute::support::cpp14::make_unique<GCActivationLayerKernel>();
+    auto core_ctx = _ctx ? _ctx->core_runtime_context() : /* Legacy */ nullptr;
+
+    auto k = arm_compute::support::cpp14::make_unique<GCActivationLayerKernel>(core_ctx);
     k->configure(input, output, act_info);
     _kernel = std::move(k);
 }
diff --git a/tests/framework/Framework.cpp b/tests/framework/Framework.cpp
index 5d1600e..0b2ded8 100644
--- a/tests/framework/Framework.cpp
+++ b/tests/framework/Framework.cpp
@@ -576,7 +576,7 @@
                 }
                 if(parameters)
                 {
-                    parameters->set_gpu_ctx(std::move(cl_ctx));
+                    parameters->set_cl_ctx(std::move(cl_ctx));
                 }
             }
 #endif // ARM_COMPUTE_CL
diff --git a/tests/framework/ParametersLibrary.cpp b/tests/framework/ParametersLibrary.cpp
index 65a09ee..4af4179 100644
--- a/tests/framework/ParametersLibrary.cpp
+++ b/tests/framework/ParametersLibrary.cpp
@@ -32,9 +32,14 @@
     _cpu_ctx = std::move(cpu_ctx);
 }
 
-void ParametersLibrary::set_gpu_ctx(std::unique_ptr<IRuntimeContext> gpu_ctx)
+void ParametersLibrary::set_cl_ctx(std::unique_ptr<IRuntimeContext> cl_ctx)
 {
-    _gpu_ctx = std::move(gpu_ctx);
+    _cl_ctx = std::move(cl_ctx);
+}
+
+void ParametersLibrary::set_gc_ctx(std::unique_ptr<IRuntimeContext> gc_ctx)
+{
+    _gc_ctx = std::move(gc_ctx);
 }
 
 template <>
@@ -47,8 +52,16 @@
 template <>
 typename ContextType<CLTensor>::type *ParametersLibrary::get_ctx<CLTensor>()
 {
-    return static_cast<typename ContextType<CLTensor>::type *>(_gpu_ctx.get());
+    return static_cast<typename ContextType<CLTensor>::type *>(_cl_ctx.get());
 }
 #endif /* ARM_COMPUTE_CL */
+
+#if ARM_COMPUTE_GC
+template <>
+typename ContextType<GCTensor>::type *ParametersLibrary::get_ctx<GCTensor>()
+{
+    return static_cast<typename ContextType<GCTensor>::type *>(_gc_ctx.get());
+}
+#endif /* ARM_COMPUTE_GC */
 } // namespace test
 } // namespace arm_compute
diff --git a/tests/framework/ParametersLibrary.h b/tests/framework/ParametersLibrary.h
index 4079ab2..d5039fc 100644
--- a/tests/framework/ParametersLibrary.h
+++ b/tests/framework/ParametersLibrary.h
@@ -31,6 +31,7 @@
 #include "arm_compute/runtime/CL/CLTensor.h"
 #endif /* ARM_COMPUTE_CL */
 #ifdef ARM_COMPUTE_GC
+#include "arm_compute/runtime/GLES_COMPUTE/GCRuntimeContext.h"
 #include "arm_compute/runtime/GLES_COMPUTE/GCTensor.h"
 #endif /* ARM_COMPUTE_GC */
 
@@ -64,7 +65,7 @@
 template <>
 struct ContextType<GCTensor>
 {
-    using type = IRuntimeContext;
+    using type = GCRuntimeContext;
 };
 #endif /* ARM_COMPUTE_GC */
 
@@ -81,9 +82,14 @@
     void set_cpu_ctx(std::unique_ptr<IRuntimeContext> cpu_ctx);
     /** Set gpu context to be used by the tests
      *
-     * @param[in] gpu_ctx GPU context to use
+     * @param[in] cl_ctx GPU context to use
      */
-    void set_gpu_ctx(std::unique_ptr<IRuntimeContext> gpu_ctx);
+    void set_cl_ctx(std::unique_ptr<IRuntimeContext> cl_ctx);
+    /** Set gpu context to be used by the tests
+     *
+     * @param[in] gc_ctx GPU context to use
+     */
+    void set_gc_ctx(std::unique_ptr<IRuntimeContext> gc_ctx);
     /** Get context given a tensor type
      *
      * @tparam TensorType
@@ -98,7 +104,8 @@
 
 private:
     std::unique_ptr<IRuntimeContext> _cpu_ctx{ nullptr };
-    std::unique_ptr<IRuntimeContext> _gpu_ctx{ nullptr };
+    std::unique_ptr<IRuntimeContext> _cl_ctx{ nullptr };
+    std::unique_ptr<IRuntimeContext> _gc_ctx{ nullptr };
 };
 } // namespace test
 } // namespace arm_compute
diff --git a/tests/main.cpp b/tests/main.cpp
index 415dba0..5757249 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -92,10 +92,6 @@
 
 int main(int argc, char **argv)
 {
-#ifdef ARM_COMPUTE_GC
-    GCScheduler::get().default_init();
-#endif /* ARM_COMPUTE_GC */
-
     framework::Framework &framework = framework::Framework::get();
 
     utils::CommandLineParser parser;
@@ -173,6 +169,20 @@
         parameters = support::cpp14::make_unique<ParametersLibrary>();
         parameters->set_cpu_ctx(std::move(cpu_ctx));
 
+#ifdef ARM_COMPUTE_GC
+        // Setup OpenGL context
+        {
+            auto gles_ctx = support::cpp14::make_unique<GCRuntimeContext>();
+            ARM_COMPUTE_ERROR_ON(gles_ctx == nullptr);
+            {
+                // Legacy singletons API: This has been deprecated and the singletons will be removed
+                // Setup singleton for backward compatibility
+                GCScheduler::get().default_init();
+            }
+            parameters->set_gc_ctx(std::move(gles_ctx));
+        };
+#endif /* ARM_COMPUTE_GC */
+
 #ifdef ARM_COMPUTE_CL
         CLTuner cl_tuner(false);
         // Create GPU context
@@ -186,7 +196,7 @@
             // Setup singleton for backward compatibility
             CLScheduler::get().init(gpu_scheduler->context(), gpu_scheduler->queue(), cl_ctx->kernel_library().get_device(), &cl_tuner);
         }
-        parameters->set_gpu_ctx(std::move(cl_ctx));
+        parameters->set_cl_ctx(std::move(cl_ctx));
 
         if(enable_tuner->is_set())
         {