Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "GLExtensions.h"
     18 
     19 #include <string>
     20 #include <unordered_set>
     21 
     22 #include <stdint.h>
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 
     26 ANDROID_SINGLETON_STATIC_INSTANCE(android::renderengine::gl::GLExtensions)
     27 
     28 namespace android {
     29 namespace renderengine {
     30 namespace gl {
     31 
     32 namespace {
     33 
     34 class ExtensionSet {
     35 public:
     36     ExtensionSet(const char* extensions) {
     37         char const* curr = extensions;
     38         char const* head = curr;
     39         do {
     40             head = strchr(curr, ' ');
     41             size_t len = head ? head - curr : strlen(curr);
     42             if (len > 0) {
     43                 mExtensions.emplace(curr, len);
     44             }
     45             curr = head + 1;
     46         } while (head);
     47     }
     48 
     49     bool hasExtension(const char* extension) const { return mExtensions.count(extension) > 0; }
     50 
     51 private:
     52     std::unordered_set<std::string> mExtensions;
     53 };
     54 
     55 } // anonymous namespace
     56 
     57 void GLExtensions::initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer,
     58                                      GLubyte const* version, GLubyte const* extensions) {
     59     mVendor = (char const*)vendor;
     60     mRenderer = (char const*)renderer;
     61     mVersion = (char const*)version;
     62     mExtensions = (char const*)extensions;
     63 
     64     ExtensionSet extensionSet(mExtensions.c_str());
     65     if (extensionSet.hasExtension("GL_EXT_protected_textures")) {
     66         mHasProtectedTexture = true;
     67     }
     68 }
     69 
     70 char const* GLExtensions::getVendor() const {
     71     return mVendor.string();
     72 }
     73 
     74 char const* GLExtensions::getRenderer() const {
     75     return mRenderer.string();
     76 }
     77 
     78 char const* GLExtensions::getVersion() const {
     79     return mVersion.string();
     80 }
     81 
     82 char const* GLExtensions::getExtensions() const {
     83     return mExtensions.string();
     84 }
     85 
     86 void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExtensions) {
     87     mEGLVersion = eglVersion;
     88     mEGLExtensions = eglExtensions;
     89 
     90     ExtensionSet extensionSet(eglExtensions);
     91 
     92     // EGL_ANDROIDX_no_config_context is an experimental extension with no
     93     // written specification. It will be replaced by something more formal.
     94     // SurfaceFlinger is using it to allow a single EGLContext to render to
     95     // both a 16-bit primary display framebuffer and a 32-bit virtual display
     96     // framebuffer.
     97     //
     98     // EGL_KHR_no_config_context is official extension to allow creating a
     99     // context that works with any surface of a display.
    100     if (extensionSet.hasExtension("EGL_ANDROIDX_no_config_context") ||
    101         extensionSet.hasExtension("EGL_KHR_no_config_context")) {
    102         mHasNoConfigContext = true;
    103     }
    104 
    105     if (extensionSet.hasExtension("EGL_ANDROID_native_fence_sync")) {
    106         mHasNativeFenceSync = true;
    107     }
    108     if (extensionSet.hasExtension("EGL_KHR_fence_sync")) {
    109         mHasFenceSync = true;
    110     }
    111     if (extensionSet.hasExtension("EGL_KHR_wait_sync")) {
    112         mHasWaitSync = true;
    113     }
    114     if (extensionSet.hasExtension("EGL_EXT_protected_content")) {
    115         mHasProtectedContent = true;
    116     }
    117     if (extensionSet.hasExtension("EGL_IMG_context_priority")) {
    118         mHasContextPriority = true;
    119     }
    120     if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) {
    121         mHasSurfacelessContext = true;
    122     }
    123 }
    124 
    125 char const* GLExtensions::getEGLVersion() const {
    126     return mEGLVersion.string();
    127 }
    128 
    129 char const* GLExtensions::getEGLExtensions() const {
    130     return mEGLExtensions.string();
    131 }
    132 
    133 } // namespace gl
    134 } // namespace renderengine
    135 } // namespace android
    136