Unify extensions parsing behavior

Removes remnants of EGL extension support, and persistence of
GL extension list.

Change-Id: I35aec12d900bdb33549ea47654bb8146f350ef48
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 3eb13ab..cc0943f 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -24,6 +24,7 @@
     utils/GLUtils.cpp \
     utils/LinearAllocator.cpp \
     utils/NinePatchImpl.cpp \
+    utils/StringUtils.cpp \
     AmbientShadow.cpp \
     AnimationContext.cpp \
     Animator.cpp \
@@ -168,7 +169,8 @@
     unit_tests/CanvasStateTests.cpp \
     unit_tests/ClipAreaTests.cpp \
     unit_tests/DamageAccumulatorTests.cpp \
-    unit_tests/LinearAllocatorTests.cpp
+    unit_tests/LinearAllocatorTests.cpp \
+    unit_tests/StringUtilsTests.cpp
 
 include $(BUILD_NATIVE_TEST)
 
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 5808aac..e98fa04 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -20,9 +20,6 @@
 // Turn on to check for OpenGL errors on each frame
 #define DEBUG_OPENGL 1
 
-// Turn on to display informations about the GPU
-#define DEBUG_EXTENSIONS 0
-
 // Turn on to enable initialization information
 #define DEBUG_INIT 0
 
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 3d350c9..06c8a21 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -18,23 +18,14 @@
 
 #include "Debug.h"
 #include "Properties.h"
+#include "utils/StringUtils.h"
 
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
 #include <GLES2/gl2ext.h>
 #include <utils/Log.h>
 
 namespace android {
-
-using namespace uirenderer;
-ANDROID_SINGLETON_STATIC_INSTANCE(Extensions);
-
 namespace uirenderer {
 
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
 // Debug
 #if DEBUG_EXTENSIONS
     #define EXT_LOGD(...) ALOGD(__VA_ARGS__)
@@ -42,20 +33,16 @@
     #define EXT_LOGD(...)
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-// Constructors
-///////////////////////////////////////////////////////////////////////////////
 
 Extensions::Extensions() {
-    // Query GL extensions
-    findExtensions((const char*) glGetString(GL_EXTENSIONS), mGlExtensionList);
-    mHasNPot = hasGlExtension("GL_OES_texture_npot");
-    mHasFramebufferFetch = hasGlExtension("GL_NV_shader_framebuffer_fetch");
-    mHasDiscardFramebuffer = hasGlExtension("GL_EXT_discard_framebuffer");
-    mHasDebugMarker = hasGlExtension("GL_EXT_debug_marker");
-    mHas1BitStencil = hasGlExtension("GL_OES_stencil1");
-    mHas4BitStencil = hasGlExtension("GL_OES_stencil4");
-    mHasUnpackSubImage = hasGlExtension("GL_EXT_unpack_subimage");
+    StringCollection extensions((const char*) glGetString(GL_EXTENSIONS));
+    mHasNPot = extensions.has("GL_OES_texture_npot");
+    mHasFramebufferFetch = extensions.has("GL_NV_shader_framebuffer_fetch");
+    mHasDiscardFramebuffer = extensions.has("GL_EXT_discard_framebuffer");
+    mHasDebugMarker = extensions.has("GL_EXT_debug_marker");
+    mHas1BitStencil = extensions.has("GL_OES_stencil1");
+    mHas4BitStencil = extensions.has("GL_OES_stencil4");
+    mHasUnpackSubImage = extensions.has("GL_EXT_unpack_subimage");
 
     const char* version = (const char*) glGetString(GL_VERSION);
 
@@ -78,40 +65,5 @@
     }
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Methods
-///////////////////////////////////////////////////////////////////////////////
-
-bool Extensions::hasGlExtension(const char* extension) const {
-   const String8 s(extension);
-   return mGlExtensionList.indexOf(s) >= 0;
-}
-
-bool Extensions::hasEglExtension(const char* extension) const {
-   const String8 s(extension);
-   return mEglExtensionList.indexOf(s) >= 0;
-}
-
-void Extensions::findExtensions(const char* extensions, SortedVector<String8>& list) const {
-    const char* current = extensions;
-    const char* head = current;
-    EXT_LOGD("Available extensions:");
-    do {
-        head = strchr(current, ' ');
-        String8 s(current, head ? head - current : strlen(current));
-        if (s.length()) {
-            list.add(s);
-            EXT_LOGD("  %s", s.string());
-        }
-        current = head + 1;
-    } while (head);
-}
-
-void Extensions::dump() const {
-   ALOGD("%s", (const char*) glGetString(GL_VERSION));
-   ALOGD("Supported GL extensions:\n%s", (const char*) glGetString(GL_EXTENSIONS));
-   ALOGD("Supported EGL extensions:\n%s", eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS));
-}
-
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 636b631..0a30d16 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -50,17 +50,7 @@
     inline int getMajorGlVersion() const { return mVersionMajor; }
     inline int getMinorGlVersion() const { return mVersionMinor; }
 
-    bool hasGlExtension(const char* extension) const;
-    bool hasEglExtension(const char* extension) const;
-
-    void dump() const;
-
 private:
-    void findExtensions(const char* extensions, SortedVector<String8>& list) const;
-
-    SortedVector<String8> mGlExtensionList;
-    SortedVector<String8> mEglExtensionList;
-
     bool mHasNPot;
     bool mHasFramebufferFetch;
     bool mHasDiscardFramebuffer;
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index d2ce49f..c9b9637 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -20,6 +20,7 @@
 #include "Properties.h"
 #include "RenderThread.h"
 #include "renderstate/RenderState.h"
+#include "utils/StringUtils.h"
 
 #include <cutils/log.h>
 #include <cutils/properties.h>
@@ -133,12 +134,9 @@
 }
 
 void EglManager::initExtensions() {
-    std::string extensions(eglQueryString(mEglDisplay, EGL_EXTENSIONS));
-    auto has = [&](const char* ext) {
-        return extensions.find(ext) != std::string::npos;
-    };
-    EglExtensions.bufferAge = has("EGL_EXT_buffer_age");
-    EglExtensions.setDamage = has("EGL_KHR_partial_update");
+    StringCollection extensions(eglQueryString(mEglDisplay, EGL_EXTENSIONS));
+    EglExtensions.bufferAge = extensions.has("EGL_EXT_buffer_age");
+    EglExtensions.setDamage = extensions.has("EGL_KHR_partial_update");
 }
 
 bool EglManager::hasEglContext() {
diff --git a/libs/hwui/unit_tests/StringUtilsTests.cpp b/libs/hwui/unit_tests/StringUtilsTests.cpp
new file mode 100644
index 0000000..5174ae9
--- /dev/null
+++ b/libs/hwui/unit_tests/StringUtilsTests.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include "utils/StringUtils.h"
+
+namespace android {
+namespace uirenderer {
+
+TEST(StringUtils, simpleBuildSet) {
+    StringCollection collection("a b c");
+
+    EXPECT_TRUE(collection.has("a"));
+    EXPECT_TRUE(collection.has("b"));
+    EXPECT_TRUE(collection.has("c"));
+    EXPECT_FALSE(collection.has("d"));
+}
+
+TEST(StringUtils, advancedBuildSet) {
+    StringCollection collection("GL_ext1 GL_ext2 GL_ext3");
+
+    EXPECT_TRUE(collection.has("GL_ext1"));
+    EXPECT_FALSE(collection.has("GL_ext")); // string present, but not in list
+}
+
+};
+};
diff --git a/libs/hwui/utils/StringUtils.cpp b/libs/hwui/utils/StringUtils.cpp
new file mode 100644
index 0000000..a1df0e7
--- /dev/null
+++ b/libs/hwui/utils/StringUtils.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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 "StringUtils.h"
+
+namespace android {
+namespace uirenderer {
+
+StringCollection::StringCollection(const char* spacedList) {
+    const char* current = spacedList;
+    const char* head = current;
+    do {
+        head = strchr(current, ' ');
+        std::string s(current, head ? head - current : strlen(current));
+        if (s.length()) {
+            mSet.insert(s);
+        }
+        current = head + 1;
+    } while (head);
+}
+
+bool StringCollection::has(const char* s) {
+    return mSet.find(std::string(s)) != mSet.end();
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/utils/StringUtils.h b/libs/hwui/utils/StringUtils.h
new file mode 100644
index 0000000..ef2a6d5
--- /dev/null
+++ b/libs/hwui/utils/StringUtils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+#ifndef STRING_UTILS_H
+#define STRING_UTILS_H
+
+#include <string>
+#include <unordered_set>
+
+namespace android {
+namespace uirenderer {
+
+class StringCollection {
+public:
+    StringCollection(const char* spacedList);
+    bool has(const char* string);
+private:
+    std::unordered_set<std::string> mSet;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* GLUTILS_H */