Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'android/jni/com/mapswithme/opengl/androidoglcontextfactory.cpp')
-rw-r--r--android/jni/com/mapswithme/opengl/androidoglcontextfactory.cpp215
1 files changed, 215 insertions, 0 deletions
diff --git a/android/jni/com/mapswithme/opengl/androidoglcontextfactory.cpp b/android/jni/com/mapswithme/opengl/androidoglcontextfactory.cpp
new file mode 100644
index 0000000000..d5c79d6aef
--- /dev/null
+++ b/android/jni/com/mapswithme/opengl/androidoglcontextfactory.cpp
@@ -0,0 +1,215 @@
+#include "androidoglcontextfactory.hpp"
+#include "android_gl_utils.hpp"
+
+#include "../../../../../base/assert.hpp"
+#include "../../../../../base/logging.hpp"
+
+#include "../../../../../std/algorithm.hpp"
+
+#include <EGL/egl.h>
+#include <android/native_window_jni.h>
+
+namespace android
+{
+
+static EGLint * getConfigAttributesList()
+{
+ static EGLint attr_list[] = {
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_STENCIL_SIZE, 0,
+ EGL_DEPTH_SIZE, 16,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
+ EGL_NONE
+ };
+ return attr_list;
+}
+
+AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurface)
+ : m_drawContext(NULL)
+ , m_uploadContext(NULL)
+ , m_windowSurface(EGL_NO_SURFACE)
+ , m_pixelbufferSurface(EGL_NO_SURFACE)
+ , m_config(NULL)
+ , m_nativeWindow(NULL)
+ , m_display(EGL_NO_DISPLAY)
+ , m_surfaceWidth(0)
+ , m_surfaceHeight(0)
+ , m_valid(false)
+{
+ LOG(LINFO, ("UVR : Start create factory"));
+ if (!jsurface)
+ {
+ LOG(LINFO, ("Java surface incorrect"));
+ return;
+ }
+
+ m_nativeWindow = ANativeWindow_fromSurface(env, jsurface);
+ if (!m_nativeWindow)
+ {
+ LOG(LINFO, ("Can't get native window from Java surface"));
+ return;
+ }
+
+ m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_display == EGL_NO_DISPLAY)
+ {
+ LOG(LINFO, ("Can't query default egl display. Error code = ", eglGetError()));
+ return;
+ }
+
+ EGLint version[2] = {0};
+ if (!eglInitialize(m_display, &version[0], &version[1]))
+ {
+ LOG(LINFO, ("EGL initialize failed. Error code = ", eglGetError()));
+ return;
+ }
+
+ if (!(createWindowSurface() && createPixelbufferSurface()))
+ {
+ eglTerminate(m_display);
+ return;
+ }
+
+ if (!QuerySurfaceSize())
+ return;
+
+ LOG(LINFO, ("UVR : Correct created factory"));
+ m_valid = true;
+}
+
+AndroidOGLContextFactory::~AndroidOGLContextFactory()
+{
+ if (IsValid())
+ {
+ delete m_drawContext;
+ delete m_uploadContext;
+
+ eglDestroySurface(m_display, m_windowSurface);
+ eglDestroySurface(m_display, m_pixelbufferSurface);
+ eglTerminate(m_display);
+
+ ANativeWindow_release(m_nativeWindow);
+ }
+}
+
+bool AndroidOGLContextFactory::IsValid() const
+{
+ return m_valid;
+}
+
+int AndroidOGLContextFactory::GetWidth() const
+{
+ ASSERT(IsValid(), ());
+ return m_surfaceWidth;
+}
+
+int AndroidOGLContextFactory::GetHeight() const
+{
+ ASSERT(IsValid(), ());
+ return m_surfaceHeight;
+}
+
+void AndroidOGLContextFactory::UpdateSurfaceSize()
+{
+ ASSERT(IsValid(), ());
+ VERIFY(QuerySurfaceSize(), ());
+}
+
+bool AndroidOGLContextFactory::QuerySurfaceSize()
+{
+ EGLint queryResult;
+ if (eglQuerySurface(m_display, m_windowSurface, EGL_WIDTH, &queryResult) == EGL_FALSE)
+ {
+ LOG(LINFO, ("Can't query surface width. Error code = ", eglGetError()));
+ return false;
+ }
+
+ m_surfaceWidth = static_cast<int>(queryResult);
+ if (eglQuerySurface(m_display, m_windowSurface, EGL_HEIGHT, &queryResult) == EGL_FALSE)
+ {
+ LOG(LINFO, ("Can't query surface height. Error code = ", eglGetError()));
+ return false;
+ }
+
+ m_surfaceHeight = static_cast<int>(queryResult);
+ return true;
+}
+
+dp::OGLContext * AndroidOGLContextFactory::getDrawContext()
+{
+ ASSERT(IsValid(), ());
+ ASSERT(m_windowSurface != EGL_NO_SURFACE, ());
+ if (m_drawContext == NULL)
+ m_drawContext = new AndroidOGLContext(m_display, m_windowSurface, m_config, m_uploadContext);
+ return m_drawContext;
+}
+
+dp::OGLContext * AndroidOGLContextFactory::getResourcesUploadContext()
+{
+ ASSERT(IsValid(), ());
+ ASSERT(m_pixelbufferSurface != EGL_NO_SURFACE, ());
+ if (m_uploadContext == NULL)
+ m_uploadContext = new AndroidOGLContext(m_display, m_pixelbufferSurface, m_config, m_drawContext);
+ return m_uploadContext;
+}
+
+bool AndroidOGLContextFactory::createWindowSurface()
+{
+ EGLConfig configs[40];
+ int count = 0;
+ VERIFY(eglChooseConfig(m_display, getConfigAttributesList(), configs, 40, &count) == EGL_TRUE, ());
+ ASSERT(count > 0, ("Didn't find any configs."));
+
+ sort(&configs[0], &configs[count], ConfigComparator(m_display));
+ for (int i = 0; i < count; ++i)
+ {
+ EGLConfig currentConfig = configs[i];
+ EGLint surfaceAttributes[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
+ m_windowSurface = eglCreateWindowSurface(m_display, currentConfig, m_nativeWindow, surfaceAttributes);
+ if (m_windowSurface == EGL_NO_SURFACE)
+ continue;
+ else
+ m_config = currentConfig;
+
+ EGLint configId = 0;
+ eglGetConfigAttrib(m_display, m_config, EGL_CONFIG_ID, &configId);
+ LOG(LINFO, ("Choosen config id:", configId));
+
+ break;
+ }
+
+ if (m_windowSurface == EGL_NO_SURFACE)
+ {
+ LOG(LINFO, ("Can't create EGLWindowSurface. Error code = ", eglGetError()));
+ return false;
+ }
+
+ return true;
+}
+
+bool AndroidOGLContextFactory::createPixelbufferSurface()
+{
+ //ASSERT(m_config != NULL, ());
+
+ const GLuint size = 1; // yes, 1 is the correct size, we dont really draw on it
+ static EGLint surfaceConfig[] = {
+ EGL_WIDTH, size,
+ EGL_HEIGHT, size,
+ EGL_NONE
+ };
+
+ m_pixelbufferSurface = eglCreatePbufferSurface(m_display, m_config, surfaceConfig);
+
+ if (m_pixelbufferSurface == EGL_NO_SURFACE)
+ {
+ LOG(LINFO, ("Can't create buffer surface for UploadThread. Error code = ", eglGetError()));
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace android