summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gl/egl/android
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl/egl/android')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp385
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h78
2 files changed, 463 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
new file mode 100755
index 000000000..b689578c9
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
@@ -0,0 +1,385 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayAndroid.cpp: Android implementation of egl::Display
+
+#include <android/native_window.h>
+
+#include "common/debug.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+#include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
+#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
+#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
+#include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
+
+namespace
+{
+const char *GetEGLPath()
+{
+#if defined(__LP64__)
+ return "/system/lib64/libEGL.so";
+#else
+ return "/system/lib/libEGL.so";
+#endif
+}
+} // namespace
+
+namespace rx
+{
+
+DisplayAndroid::DisplayAndroid() : DisplayEGL(), mDummyPbuffer(EGL_NO_SURFACE)
+{
+}
+
+DisplayAndroid::~DisplayAndroid()
+{
+}
+
+egl::Error DisplayAndroid::initialize(egl::Display *display)
+{
+ FunctionsEGLDL *egl = new FunctionsEGLDL();
+ mEGL = egl;
+ ANGLE_TRY(egl->initialize(display->getNativeDisplayId(), GetEGLPath()));
+
+ gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
+ ASSERT(eglVersion >= gl::Version(1, 4));
+
+ static_assert(EGL_OPENGL_ES3_BIT == EGL_OPENGL_ES3_BIT_KHR, "Extension define must match core");
+ EGLint esBit = (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
+ ? EGL_OPENGL_ES3_BIT
+ : EGL_OPENGL_ES2_BIT;
+
+ // clang-format off
+ mConfigAttribList =
+ {
+ // Choose RGBA8888
+ EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ // EGL1.5 spec Section 2.2 says that depth, multisample and stencil buffer depths
+ // must match for contexts to be compatible.
+ EGL_DEPTH_SIZE, 24,
+ EGL_STENCIL_SIZE, 8,
+ EGL_SAMPLE_BUFFERS, 0,
+ // Android doesn't support pixmaps
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_CONFIG_CAVEAT, EGL_NONE,
+ EGL_CONFORMANT, esBit,
+ EGL_RENDERABLE_TYPE, esBit,
+ EGL_NONE
+ };
+ // clang-format on
+ EGLint numConfig;
+
+ EGLBoolean success = mEGL->chooseConfig(mConfigAttribList.data(), &mConfig, 1, &numConfig);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglChooseConfig failed");
+ }
+
+ ANGLE_TRY(initializeContext(display->getAttributeMap()));
+
+ int dummyPbufferAttribs[] = {
+ EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE,
+ };
+ mDummyPbuffer = mEGL->createPbufferSurface(mConfig, dummyPbufferAttribs);
+ if (mDummyPbuffer == EGL_NO_SURFACE)
+ {
+ return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed");
+ }
+
+ success = mEGL->makeCurrent(mDummyPbuffer, mContext);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
+ }
+
+ mFunctionsGL = mEGL->makeFunctionsGL();
+ mFunctionsGL->initialize();
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayAndroid::terminate()
+{
+ DisplayGL::terminate();
+
+ EGLBoolean success = mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (success == EGL_FALSE)
+ {
+ ERR("eglMakeCurrent error 0x%04x", mEGL->getError());
+ }
+
+ if (mDummyPbuffer != EGL_NO_SURFACE)
+ {
+ success = mEGL->destroySurface(mDummyPbuffer);
+ mDummyPbuffer = EGL_NO_SURFACE;
+ if (success == EGL_FALSE)
+ {
+ ERR("eglDestroySurface error 0x%04x", mEGL->getError());
+ }
+ }
+
+ if (mContext != EGL_NO_CONTEXT)
+ {
+ success = mEGL->destroyContext(mContext);
+ mContext = EGL_NO_CONTEXT;
+ if (success == EGL_FALSE)
+ {
+ ERR("eglDestroyContext error 0x%04x", mEGL->getError());
+ }
+ }
+
+ egl::Error result = mEGL->terminate();
+ if (result.isError())
+ {
+ ERR("eglTerminate error 0x%04x", result.getCode());
+ }
+
+ SafeDelete(mEGL);
+ SafeDelete(mFunctionsGL);
+}
+
+SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ EGLConfig config;
+ EGLint numConfig;
+ EGLBoolean success;
+
+ const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[configuration->configID],
+ EGL_NONE};
+ success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
+ ASSERT(success && numConfig == 1);
+
+ return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), mContext,
+ getRenderer());
+}
+
+SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ EGLConfig config;
+ EGLint numConfig;
+ EGLBoolean success;
+
+ const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[configuration->configID],
+ EGL_NONE};
+ success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
+ ASSERT(success && numConfig == 1);
+
+ return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), mContext,
+ getRenderer());
+}
+
+SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+SurfaceImpl *DisplayAndroid::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+ImageImpl *DisplayAndroid::createImage(EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return DisplayGL::createImage(target, buffer, attribs);
+}
+
+template <typename T>
+void DisplayAndroid::getConfigAttrib(EGLConfig config, EGLint attribute, T *value) const
+{
+ EGLint tmp;
+ EGLBoolean success = mEGL->getConfigAttrib(config, attribute, &tmp);
+ ASSERT(success == EGL_TRUE);
+ *value = tmp;
+}
+
+egl::ConfigSet DisplayAndroid::generateConfigs()
+{
+ egl::ConfigSet configSet;
+ mConfigIds.clear();
+
+ EGLint numConfigs;
+ EGLBoolean success = mEGL->chooseConfig(mConfigAttribList.data(), nullptr, 0, &numConfigs);
+ ASSERT(success == EGL_TRUE && numConfigs > 0);
+
+ std::vector<EGLConfig> configs(numConfigs);
+ EGLint numConfigs2;
+ success =
+ mEGL->chooseConfig(mConfigAttribList.data(), configs.data(), numConfigs, &numConfigs2);
+ ASSERT(success == EGL_TRUE && numConfigs2 == numConfigs);
+
+ for (int i = 0; i < numConfigs; i++)
+ {
+ egl::Config config;
+
+ getConfigAttrib(configs[i], EGL_BUFFER_SIZE, &config.bufferSize);
+ getConfigAttrib(configs[i], EGL_RED_SIZE, &config.redSize);
+ getConfigAttrib(configs[i], EGL_GREEN_SIZE, &config.greenSize);
+ getConfigAttrib(configs[i], EGL_BLUE_SIZE, &config.blueSize);
+ getConfigAttrib(configs[i], EGL_LUMINANCE_SIZE, &config.luminanceSize);
+ getConfigAttrib(configs[i], EGL_ALPHA_SIZE, &config.alphaSize);
+ getConfigAttrib(configs[i], EGL_ALPHA_MASK_SIZE, &config.alphaMaskSize);
+ getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGB, &config.bindToTextureRGB);
+ getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGBA, &config.bindToTextureRGBA);
+ getConfigAttrib(configs[i], EGL_COLOR_BUFFER_TYPE, &config.colorBufferType);
+ getConfigAttrib(configs[i], EGL_CONFIG_CAVEAT, &config.configCaveat);
+ getConfigAttrib(configs[i], EGL_CONFIG_ID, &config.configID);
+ getConfigAttrib(configs[i], EGL_CONFORMANT, &config.conformant);
+ getConfigAttrib(configs[i], EGL_DEPTH_SIZE, &config.depthSize);
+ getConfigAttrib(configs[i], EGL_LEVEL, &config.level);
+ getConfigAttrib(configs[i], EGL_MAX_PBUFFER_WIDTH, &config.maxPBufferWidth);
+ getConfigAttrib(configs[i], EGL_MAX_PBUFFER_HEIGHT, &config.maxPBufferHeight);
+ getConfigAttrib(configs[i], EGL_MAX_PBUFFER_PIXELS, &config.maxPBufferPixels);
+ getConfigAttrib(configs[i], EGL_MAX_SWAP_INTERVAL, &config.maxSwapInterval);
+ getConfigAttrib(configs[i], EGL_MIN_SWAP_INTERVAL, &config.minSwapInterval);
+ getConfigAttrib(configs[i], EGL_NATIVE_RENDERABLE, &config.nativeRenderable);
+ getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_ID, &config.nativeVisualID);
+ getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_TYPE, &config.nativeVisualType);
+ getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE, &config.renderableType);
+ getConfigAttrib(configs[i], EGL_SAMPLE_BUFFERS, &config.sampleBuffers);
+ getConfigAttrib(configs[i], EGL_SAMPLES, &config.samples);
+ getConfigAttrib(configs[i], EGL_STENCIL_SIZE, &config.stencilSize);
+ getConfigAttrib(configs[i], EGL_SURFACE_TYPE, &config.surfaceType);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_TYPE, &config.transparentType);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_RED_VALUE, &config.transparentRedValue);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_GREEN_VALUE, &config.transparentGreenValue);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_BLUE_VALUE, &config.transparentBlueValue);
+
+ if (config.colorBufferType == EGL_RGB_BUFFER)
+ {
+ if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 &&
+ config.alphaSize == 8)
+ {
+ config.renderTargetFormat = GL_RGBA8;
+ }
+ else if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 &&
+ config.alphaSize == 0)
+ {
+ config.renderTargetFormat = GL_RGB8;
+ }
+ else if (config.redSize == 5 && config.greenSize == 6 && config.blueSize == 5 &&
+ config.alphaSize == 0)
+ {
+ config.renderTargetFormat = GL_RGB565;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ if (config.depthSize == 0 && config.stencilSize == 0)
+ {
+ config.depthStencilFormat = GL_ZERO;
+ }
+ else if (config.depthSize == 16 && config.stencilSize == 0)
+ {
+ config.depthStencilFormat = GL_DEPTH_COMPONENT16;
+ }
+ else if (config.depthSize == 24 && config.stencilSize == 0)
+ {
+ config.depthStencilFormat = GL_DEPTH_COMPONENT24;
+ }
+ else if (config.depthSize == 24 && config.stencilSize == 8)
+ {
+ config.depthStencilFormat = GL_DEPTH24_STENCIL8;
+ }
+ else if (config.depthSize == 0 && config.stencilSize == 8)
+ {
+ config.depthStencilFormat = GL_STENCIL_INDEX8;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ config.matchNativePixmap = EGL_NONE;
+ config.optimalOrientation = 0;
+
+ int internalId = configSet.add(config);
+ mConfigIds[internalId] = config.configID;
+ }
+
+ return configSet;
+}
+
+bool DisplayAndroid::testDeviceLost()
+{
+ return false;
+}
+
+egl::Error DisplayAndroid::restoreLostDevice()
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+bool DisplayAndroid::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return ANativeWindow_getFormat(window) >= 0;
+}
+
+egl::Error DisplayAndroid::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayAndroid::waitClient() const
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayAndroid::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayAndroid::getDriverVersion(std::string *version) const
+{
+ VendorID vendor = GetVendorID(mFunctionsGL);
+
+ switch (vendor)
+ {
+ case VENDOR_ID_QUALCOMM:
+ *version = reinterpret_cast<const char *>(mFunctionsGL->getString(GL_VERSION));
+ return egl::Error(EGL_SUCCESS);
+ default:
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h
new file mode 100755
index 000000000..0be9bb465
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h
@@ -0,0 +1,78 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayAndroid.h: Android implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_ANDROID_DISPLAYANDROID_H_
+#define LIBANGLE_RENDERER_GL_EGL_ANDROID_DISPLAYANDROID_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
+
+namespace rx
+{
+
+class DisplayAndroid : public DisplayEGL
+{
+ public:
+ DisplayAndroid();
+ ~DisplayAndroid() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ ImageImpl *createImage(EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ egl::Error getDevice(DeviceImpl **device) override;
+
+ egl::Error waitClient() const override;
+ egl::Error waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const override;
+
+ egl::Error getDriverVersion(std::string *version) const override;
+
+ private:
+ template <typename T>
+ void getConfigAttrib(EGLConfig config, EGLint attribute, T *value) const;
+
+ std::vector<EGLint> mConfigAttribList;
+ std::map<EGLint, EGLint> mConfigIds;
+ EGLSurface mDummyPbuffer;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_ANDROID_DISPLAYANDROID_H_