Add ColorSpace information on Bitmap

This is the first step toward interpreting color spaces at render time.

Bug: 32984164
Test: BitmapColorSpaceTest in CtsGraphicsTestCases

Change-Id: I0164a18f1ed74a745874fe5229168042afe27a04
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 7c2e78c..19063e3 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -133,7 +133,7 @@
      * this function returns GL_SRGB8_ALPHA8, otherwise it returns GL_RGBA
      */
     constexpr GLint rgbaInternalFormat(bool needSRGB = true) const {
-        return extensions().hasSRGB() && needSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA;
+        return extensions().hasLinearBlending() && needSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA;
     }
 
     /**
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 00238a2..1e71cb0 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -20,6 +20,8 @@
 #include "Properties.h"
 #include "utils/StringUtils.h"
 
+#include <cutils/compiler.h>
+
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
@@ -28,14 +30,6 @@
 namespace android {
 namespace uirenderer {
 
-// Debug
-#if DEBUG_EXTENSIONS
-    #define EXT_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-    #define EXT_LOGD(...)
-#endif
-
-
 Extensions::Extensions() {
     const char* version = (const char*) glGetString(GL_VERSION);
 
@@ -66,17 +60,18 @@
     mHas4BitStencil = extensions.has("GL_OES_stencil4");
     mHasUnpackSubImage = extensions.has("GL_EXT_unpack_subimage");
 
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
     mHasSRGB = mVersionMajor >= 3 || extensions.has("GL_EXT_sRGB");
     mHasSRGBWriteControl = extensions.has("GL_EXT_sRGB_write_control");
 
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
     // If linear blending is enabled, the device must have (ES3.0 or EXT_sRGB)
     // and EXT_sRGB_write_control
     LOG_ALWAYS_FATAL_IF(!mHasSRGB, "Linear blending requires ES 3.0 or EXT_sRGB");
     LOG_ALWAYS_FATAL_IF(!mHasSRGBWriteControl, "Linear blending requires EXT_sRGB_write_control");
+
+    mHasLinearBlending = true;
 #else
-    mHasSRGB = false;
-    mHasSRGBWriteControl = false;
+    mHasLinearBlending = false;
 #endif
 }
 
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 2c38507..0ecfdb1 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -17,11 +17,6 @@
 #ifndef ANDROID_HWUI_EXTENSIONS_H
 #define ANDROID_HWUI_EXTENSIONS_H
 
-#include <cutils/compiler.h>
-
-#include <string>
-#include <unordered_set>
-
 namespace android {
 namespace uirenderer {
 
@@ -45,6 +40,7 @@
     inline bool hasFloatTextures() const { return mVersionMajor >= 3; }
     inline bool hasSRGB() const { return mHasSRGB; }
     inline bool hasSRGBWriteControl() const { return hasSRGB() && mHasSRGBWriteControl; }
+    inline bool hasLinearBlending() const { return hasSRGB() && mHasLinearBlending; }
 
     inline int getMajorGlVersion() const { return mVersionMajor; }
     inline int getMinorGlVersion() const { return mVersionMinor; }
@@ -59,6 +55,7 @@
     bool mHasUnpackSubImage;
     bool mHasSRGB;
     bool mHasSRGBWriteControl;
+    bool mHasLinearBlending;
 
     int mVersionMajor;
     int mVersionMinor;
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 71bee93..18bfcc2 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -68,7 +68,7 @@
         , mMaxSize(Properties::gradientCacheSize)
         , mUseFloatTexture(extensions.hasFloatTextures())
         , mHasNpot(extensions.hasNPot())
-        , mHasSRGB(extensions.hasSRGB()) {
+        , mHasLinearBlending(extensions.hasLinearBlending()) {
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
 
     mCache.setOnEntryRemovedListener(this);
@@ -263,7 +263,7 @@
     if (mUseFloatTexture) {
         texture->upload(GL_RGBA16F, width, height, GL_RGBA, GL_FLOAT, pixels);
     } else {
-        GLint internalFormat = mHasSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA;
+        GLint internalFormat = mHasLinearBlending ? GL_SRGB8_ALPHA8 : GL_RGBA;
         texture->upload(internalFormat, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
     }
 
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 5e35435..f299a40 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -170,7 +170,7 @@
     GLint mMaxTextureSize;
     bool mUseFloatTexture;
     bool mHasNpot;
-    bool mHasSRGB;
+    bool mHasLinearBlending;
 
     mutable Mutex mLock;
 }; // class GradientCache
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index ca05648..40ab778 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -418,7 +418,7 @@
 
 ProgramCache::ProgramCache(Extensions& extensions)
         : mHasES3(extensions.getMajorGlVersion() >= 3)
-        , mHasSRGB(extensions.hasSRGB()) {
+        , mHasLinearBlending(extensions.hasLinearBlending()) {
 }
 
 ProgramCache::~ProgramCache() {
@@ -642,11 +642,11 @@
     }
     if (description.hasBitmap || ((description.hasTexture || description.hasExternalTexture) &&
             !description.hasAlpha8Texture)) {
-        shader.append(gFS_OETF[description.hasLinearTexture && !mHasSRGB]);
+        shader.append(gFS_OETF[description.hasLinearTexture && !mHasLinearBlending]);
     }
     if (description.hasGradient) {
         shader.append(gFS_Gradient_Functions);
-        shader.append(gFS_Gradient_Preamble[mHasSRGB]);
+        shader.append(gFS_Gradient_Preamble[mHasLinearBlending]);
     }
 
     // Begin the shader
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index c2f715d..cedd854b 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -59,7 +59,7 @@
     std::map<programid, std::unique_ptr<Program>> mCache;
 
     const bool mHasES3;
-    const bool mHasSRGB;
+    const bool mHasLinearBlending;
 }; // class ProgramCache
 
 }; // namespace uirenderer
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 0dbd767..cfc2744 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -241,21 +241,23 @@
     }
 }
 
-SkBitmap Texture::uploadToN32(const SkBitmap& bitmap, bool hasSRGB, sk_sp<SkColorSpace> sRGB) {
+SkBitmap Texture::uploadToN32(const SkBitmap& bitmap, bool hasLinearBlending,
+        sk_sp<SkColorSpace> sRGB) {
     SkBitmap rgbaBitmap;
     rgbaBitmap.allocPixels(SkImageInfo::MakeN32(bitmap.width(), bitmap.height(),
-            bitmap.info().alphaType(), hasSRGB ? sRGB : nullptr));
+            bitmap.info().alphaType(), hasLinearBlending ? sRGB : nullptr));
     rgbaBitmap.eraseColor(0);
     SkCanvas canvas(rgbaBitmap);
     canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
     return rgbaBitmap;
 }
 
-bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasSRGB, SkColorSpace* sRGB) {
+bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending,
+        SkColorSpace* sRGB) {
     bool needSRGB = info.colorSpace() == sRGB;
     return info.colorType() == kARGB_4444_SkColorType
         || info.colorType() == kIndex_8_SkColorType
-        || (info.colorType() == kRGB_565_SkColorType && hasSRGB && needSRGB);
+        || (info.colorType() == kRGB_565_SkColorType && hasLinearBlending && needSRGB);
 }
 
 
@@ -295,11 +297,11 @@
     mCaches.textureState().bindTexture(mTarget, mId);
 
     // TODO: Handle sRGB gray bitmaps
-    bool hasSRGB = mCaches.extensions().hasSRGB();
-    if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasSRGB, sRGB.get()))) {
+    bool hasLinearBlending = mCaches.extensions().hasLinearBlending();
+    if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasLinearBlending, sRGB.get()))) {
         SkBitmap skBitmap;
         bitmap.getSkBitmap(&skBitmap);
-        SkBitmap rgbaBitmap = uploadToN32(skBitmap, hasSRGB, std::move(sRGB));
+        SkBitmap rgbaBitmap = uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
         uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(),
                 rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(),
                 rgbaBitmap.height(), rgbaBitmap.getPixels());
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index ce9d4dc..e7fbf20 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -40,8 +40,10 @@
  */
 class Texture : public GpuMemoryTracker {
 public:
-    static SkBitmap uploadToN32(const SkBitmap& bitmap, bool hasSRGB, sk_sp<SkColorSpace> sRGB);
-    static bool hasUnsupportedColorType(const SkImageInfo& info, bool hasSRGB, SkColorSpace* sRGB);
+    static SkBitmap uploadToN32(const SkBitmap& bitmap,
+            bool hasLinearBlending, sk_sp<SkColorSpace> sRGB);
+    static bool hasUnsupportedColorType(const SkImageInfo& info,
+            bool hasLinearBlending, SkColorSpace* sRGB);
     static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
             bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType);
 
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index a55b061..db4ff39 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -19,6 +19,8 @@
 
 #include <SkBitmap.h>
 
+#include <cutils/compiler.h>
+
 #include <utils/LruCache.h>
 #include <utils/Mutex.h>
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index f9730c9..49b69eb 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -234,7 +234,7 @@
 
     sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
     bool needSRGB = skBitmap.info().colorSpace() == sRGB.get();
-    bool hasSRGB = caches.extensions().hasSRGB();
+    bool hasLinearBlending = caches.extensions().hasLinearBlending();
     GLint format, type, internalFormat;
     uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
             needSRGB, &internalFormat, &format, &type);
@@ -252,8 +252,8 @@
 
     SkBitmap bitmap;
     if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
-            hasSRGB, sRGB.get()))) {
-        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasSRGB, std::move(sRGB));
+            hasLinearBlending, sRGB.get()))) {
+        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
     } else {
         bitmap = skBitmap;
     }
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 7dfc2ee..8bce990 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -174,13 +174,15 @@
     meshState().disableTexCoordsVertexArray();
     debugOverdraw(false, false);
     // TODO: We need a way to know whether the functor is sRGB aware (b/32072673)
-    if (mCaches->extensions().hasSRGBWriteControl()) {
+    if (mCaches->extensions().hasLinearBlending() &&
+            mCaches->extensions().hasSRGBWriteControl()) {
         glDisable(GL_FRAMEBUFFER_SRGB_EXT);
     }
 }
 
 void RenderState::resumeFromFunctorInvoke() {
-    if (mCaches->extensions().hasSRGBWriteControl()) {
+    if (mCaches->extensions().hasLinearBlending() &&
+            mCaches->extensions().hasSRGBWriteControl()) {
         glEnable(GL_FRAMEBUFFER_SRGB_EXT);
     }
 
diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h
index 0950eb8..4a27ca2f 100644
--- a/libs/hwui/utils/Color.h
+++ b/libs/hwui/utils/Color.h
@@ -121,4 +121,4 @@
 } /* namespace uirenderer */
 } /* namespace android */
 
-#endif /* TEST_UTILS_H */
+#endif /* COLOR_H */