Color management, the missing pieces

Implement missing color management pieces for bitmaps:

- Bitmap.createBitmap(Bitmap src, ...) now creates a bitmap
  in the same color space as the source bitmap
- Bitmap.createScaledBitmap() now creates a bitmap in the
  same color space as the source bitmap
- Bitmap.createBitmap(..., ColorSpace colorSpace) to create
  bitmaps in a specific color space
- Fix copy from A8 to F16
- Copying bitmaps in F16 or with a color space does not work,
  it's currently a limitation in Skia

Bug: 36905374
Test: BitmapColorSpaceTest
Change-Id: I0092fe4432511db50daa3a9393389a9db05e0c2a
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 13d7e09..9f649ea 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -58,8 +58,10 @@
 }
 
 SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
+    sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
     mCanvasOwned = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
-    mCanvasWrapper = SkCreateColorSpaceXformCanvas(mCanvasOwned.get(), SkColorSpace::MakeSRGB());
+    mCanvasWrapper = SkCreateColorSpaceXformCanvas(mCanvasOwned.get(),
+            cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
     mCanvas = mCanvasWrapper.get();
 }
 
@@ -97,9 +99,10 @@
 };
 
 void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
+    sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
     std::unique_ptr<SkCanvas> newCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
-    std::unique_ptr<SkCanvas> newCanvasWrapper =
-            SkCreateColorSpaceXformCanvas(newCanvas.get(), SkColorSpace::MakeSRGB());
+    std::unique_ptr<SkCanvas> newCanvasWrapper = SkCreateColorSpaceXformCanvas(newCanvas.get(),
+            cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
 
     if (!bitmap.isNull()) {
         // Copy the canvas matrix & clip state.
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 729c7b8..d7f75fc 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -322,6 +322,12 @@
     return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info));
 }
 
+void Bitmap::setColorSpace(sk_sp<SkColorSpace> colorSpace) {
+    // TODO: See todo in reconfigure() below
+    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
+    *myInfo = info().makeColorSpace(std::move(colorSpace));
+}
+
 void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
     if (kIndex_8_SkColorType != newInfo.colorType()) {
         ctable = nullptr;
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 518be03..da45f76 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -16,6 +16,7 @@
 #pragma once
 
 #include <SkBitmap.h>
+#include <SkColorSpace.h>
 #include <SkColorTable.h>
 #include <SkImageInfo.h>
 #include <SkPixelRef.h>
@@ -82,6 +83,7 @@
 
     void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
     void reconfigure(const SkImageInfo& info);
+    void setColorSpace(sk_sp<SkColorSpace> colorSpace);
     void setAlphaType(SkAlphaType alphaType);
 
     void getSkBitmap(SkBitmap* outBitmap);