/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "GLExtensions.h" #include <string> #include <unordered_set> #include <stdint.h> #include <stdio.h> #include <stdlib.h> ANDROID_SINGLETON_STATIC_INSTANCE(android::renderengine::gl::GLExtensions) namespace android { namespace renderengine { namespace gl { namespace { class ExtensionSet { public: ExtensionSet(const char* extensions) { char const* curr = extensions; char const* head = curr; do { head = strchr(curr, ' '); size_t len = head ? head - curr : strlen(curr); if (len > 0) { mExtensions.emplace(curr, len); } curr = head + 1; } while (head); } bool hasExtension(const char* extension) const { return mExtensions.count(extension) > 0; } private: std::unordered_set<std::string> mExtensions; }; } // anonymous namespace void GLExtensions::initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version, GLubyte const* extensions) { mVendor = (char const*)vendor; mRenderer = (char const*)renderer; mVersion = (char const*)version; mExtensions = (char const*)extensions; ExtensionSet extensionSet(mExtensions.c_str()); if (extensionSet.hasExtension("GL_EXT_protected_textures")) { mHasProtectedTexture = true; } } char const* GLExtensions::getVendor() const { return mVendor.string(); } char const* GLExtensions::getRenderer() const { return mRenderer.string(); } char const* GLExtensions::getVersion() const { return mVersion.string(); } char const* GLExtensions::getExtensions() const { return mExtensions.string(); } void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExtensions) { mEGLVersion = eglVersion; mEGLExtensions = eglExtensions; ExtensionSet extensionSet(eglExtensions); // EGL_ANDROIDX_no_config_context is an experimental extension with no // written specification. It will be replaced by something more formal. // SurfaceFlinger is using it to allow a single EGLContext to render to // both a 16-bit primary display framebuffer and a 32-bit virtual display // framebuffer. // // EGL_KHR_no_config_context is official extension to allow creating a // context that works with any surface of a display. if (extensionSet.hasExtension("EGL_ANDROIDX_no_config_context") || extensionSet.hasExtension("EGL_KHR_no_config_context")) { mHasNoConfigContext = true; } if (extensionSet.hasExtension("EGL_ANDROID_native_fence_sync")) { mHasNativeFenceSync = true; } if (extensionSet.hasExtension("EGL_KHR_fence_sync")) { mHasFenceSync = true; } if (extensionSet.hasExtension("EGL_KHR_wait_sync")) { mHasWaitSync = true; } if (extensionSet.hasExtension("EGL_EXT_protected_content")) { mHasProtectedContent = true; } if (extensionSet.hasExtension("EGL_IMG_context_priority")) { mHasContextPriority = true; } if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) { mHasSurfacelessContext = true; } } char const* GLExtensions::getEGLVersion() const { return mEGLVersion.string(); } char const* GLExtensions::getEGLExtensions() const { return mEGLExtensions.string(); } } // namespace gl } // namespace renderengine } // namespace android