Use Bitmap in Texture.upload

Test: refactoring cl.
bug:32216791

Change-Id: Ib0b16c878d8371e0471e9a502f55626ec5999c60
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index d46c46f93..cc96de7 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -138,11 +138,6 @@
     height = uint32_t(pathHeight + texture->offset * 2.0 + 0.5);
 }
 
-static void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) {
-    bitmap.allocPixels(SkImageInfo::MakeA8(width, height));
-    bitmap.eraseColor(0);
-}
-
 static void initPaint(SkPaint& paint) {
     // Make sure the paint is opaque, color, alpha, filter, etc.
     // will be applied later when compositing the alpha8 texture
@@ -154,7 +149,7 @@
     paint.setBlendMode(SkBlendMode::kSrc);
 }
 
-static SkBitmap* drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
+static sk_sp<Bitmap> drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
         uint32_t maxTextureSize) {
     uint32_t width, height;
     computePathBounds(path, paint, texture, width, height);
@@ -164,13 +159,14 @@
         return nullptr;
     }
 
-    SkBitmap* bitmap = new SkBitmap();
-    initBitmap(*bitmap, width, height);
-
+    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
     SkPaint pathPaint(*paint);
     initPaint(pathPaint);
 
-    SkCanvas canvas(*bitmap);
+    SkBitmap skBitmap;
+    bitmap->getSkBitmap(&skBitmap);
+    skBitmap.eraseColor(0);
+    SkCanvas canvas(skBitmap);
     canvas.translate(-texture->left + texture->offset, -texture->top + texture->offset);
     canvas.drawPath(*path, pathPaint);
     return bitmap;
@@ -227,7 +223,7 @@
 
         // If there is a pending task we must wait for it to return
         // before attempting our cleanup
-        const sp<Task<SkBitmap*> >& task = texture->task();
+        const sp<PathTask>& task = texture->task();
         if (task != nullptr) {
             task->getResult();
             texture->clearTask();
@@ -280,20 +276,20 @@
     ATRACE_NAME("Generate Path Texture");
 
     PathTexture* texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
-    std::unique_ptr<SkBitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
-    if (!bitmap.get()) {
+    sk_sp<Bitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
+    if (!bitmap) {
         delete texture;
         return nullptr;
     }
 
     purgeCache(bitmap->width(), bitmap->height());
-    generateTexture(entry, bitmap.get(), texture);
+    generateTexture(entry, *bitmap, texture);
     return texture;
 }
 
-void PathCache::generateTexture(const PathDescription& entry, SkBitmap* bitmap,
+void PathCache::generateTexture(const PathDescription& entry, Bitmap& bitmap,
         PathTexture* texture, bool addToCache) {
-    generateTexture(*bitmap, texture);
+    generateTexture(bitmap, texture);
 
     // Note here that we upload to a texture even if it's bigger than mMaxSize.
     // Such an entry in mCache will only be temporary, since it will be evicted
@@ -314,7 +310,7 @@
     mCache.clear();
 }
 
-void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
+void PathCache::generateTexture(Bitmap& bitmap, Texture* texture) {
     ATRACE_NAME("Upload Path Texture");
     texture->upload(bitmap);
     texture->setFilter(GL_LINEAR);
@@ -325,10 +321,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PathCache::PathProcessor::PathProcessor(Caches& caches):
-        TaskProcessor<SkBitmap*>(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {
+        TaskProcessor<sk_sp<Bitmap> >(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {
 }
 
-void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) {
+void PathCache::PathProcessor::onProcess(const sp<Task<sk_sp<Bitmap> > >& task) {
     PathTask* t = static_cast<PathTask*>(task.get());
     ATRACE_NAME("pathPrecache");
 
@@ -377,13 +373,13 @@
     } else {
         // A bitmap is attached to the texture, this means we need to
         // upload it as a GL texture
-        const sp<Task<SkBitmap*> >& task = texture->task();
+        const sp<PathTask>& task = texture->task();
         if (task != nullptr) {
             // But we must first wait for the worker thread to be done
             // producing the bitmap, so let's wait
-            SkBitmap* bitmap = task->getResult();
+            sk_sp<Bitmap> bitmap = task->getResult();
             if (bitmap) {
-                generateTexture(entry, bitmap, texture, false);
+                generateTexture(entry, *bitmap, texture, false);
                 texture->clearTask();
             } else {
                 texture->clearTask();
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 18bcc56..7bd190d 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -19,6 +19,7 @@
 
 #include "Debug.h"
 #include "Texture.h"
+#include "hwui/Bitmap.h"
 #include "thread/Task.h"
 #include "thread/TaskProcessor.h"
 #include "utils/Macros.h"
@@ -32,7 +33,6 @@
 
 #include <vector>
 
-class SkBitmap;
 class SkCanvas;
 class SkPaint;
 struct SkRect;
@@ -41,7 +41,6 @@
 namespace uirenderer {
 
 class Caches;
-
 ///////////////////////////////////////////////////////////////////////////////
 // Defines
 ///////////////////////////////////////////////////////////////////////////////
@@ -57,6 +56,21 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
+struct PathTexture;
+class PathTask: public Task<sk_sp<Bitmap>> {
+public:
+    PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
+        path(*path), paint(*paint), texture(texture) {
+    }
+
+    // copied, since input path not guaranteed to survive for duration of task
+    const SkPath path;
+
+    // copied, since input paint may not be immutable
+    const SkPaint paint;
+    PathTexture* texture;
+};
+
 /**
  * Alpha texture used to represent a path.
  */
@@ -83,11 +97,11 @@
      */
     float offset = 0;
 
-    sp<Task<SkBitmap*> > task() const {
+    sp<PathTask> task() const {
         return mTask;
     }
 
-    void setTask(const sp<Task<SkBitmap*> >& task) {
+    void setTask(const sp<PathTask>& task) {
         mTask = task;
     }
 
@@ -98,7 +112,7 @@
     }
 
 private:
-    sp<Task<SkBitmap*> > mTask;
+    sp<PathTask> mTask;
 }; // struct PathTexture
 
 enum class ShapeType {
@@ -222,13 +236,12 @@
 private:
     PathTexture* addTexture(const PathDescription& entry,
             const SkPath *path, const SkPaint* paint);
-    PathTexture* addTexture(const PathDescription& entry, SkBitmap* bitmap);
 
     /**
      * Generates the texture from a bitmap into the specified texture structure.
      */
-    void generateTexture(SkBitmap& bitmap, Texture* texture);
-    void generateTexture(const PathDescription& entry, SkBitmap* bitmap, PathTexture* texture,
+    void generateTexture(Bitmap& bitmap, Texture* texture);
+    void generateTexture(const PathDescription& entry, Bitmap& bitmap, PathTexture* texture,
             bool addToCache = true);
 
     PathTexture* get(const PathDescription& entry) {
@@ -245,30 +258,13 @@
 
     void init();
 
-    class PathTask: public Task<SkBitmap*> {
-    public:
-        PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
-            path(*path), paint(*paint), texture(texture) {
-        }
 
-        ~PathTask() {
-            delete future()->get();
-        }
-
-        // copied, since input path not guaranteed to survive for duration of task
-        const SkPath path;
-
-        // copied, since input paint may not be immutable
-        const SkPaint paint;
-        PathTexture* texture;
-    };
-
-    class PathProcessor: public TaskProcessor<SkBitmap*> {
+    class PathProcessor: public TaskProcessor<sk_sp<Bitmap> > {
     public:
         explicit PathProcessor(Caches& caches);
         ~PathProcessor() { }
 
-        virtual void onProcess(const sp<Task<SkBitmap*> >& task) override;
+        virtual void onProcess(const sp<Task<sk_sp<Bitmap> > >& task) override;
 
     private:
         uint32_t mMaxTextureSize;
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f5bcba2..9d18484 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -666,7 +666,6 @@
     SkBitmap bitmap;
     SkShader::TileMode xy[2];
     if (shader->isABitmap(&bitmap, nullptr, xy)) {
-        // TODO: create  hwui-owned BitmapShader.
         Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
         refBitmap(*hwuiBitmap);
         return;
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 908f572..09e107e 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -171,12 +171,6 @@
     }
 }
 
-static void uploadSkBitmapToTexture(const SkBitmap& bitmap,
-        bool resize, GLint internalFormat, GLenum format, GLenum type) {
-    uploadToTexture(resize, internalFormat, format, type, bitmap.rowBytesAsPixels(),
-            bitmap.bytesPerPixel(), bitmap.width(), bitmap.height(), bitmap.getPixels());
-}
-
 static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
         bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType) {
     switch (colorType) {
@@ -218,9 +212,7 @@
     }
 }
 
-void Texture::upload(const SkBitmap& bitmap) {
-    SkAutoLockPixels alp(bitmap);
-
+void Texture::upload(Bitmap& bitmap) {
     if (!bitmap.readyToDraw()) {
         ALOGE("Cannot generate texture from bitmap");
         return;
@@ -244,7 +236,7 @@
     }
 
     sk_sp<SkColorSpace> sRGB = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
-    bool needSRGB = bitmap.colorSpace() == sRGB.get();
+    bool needSRGB = bitmap.info().colorSpace() == sRGB.get();
 
     GLint internalFormat, format, type;
     colorTypeToGlFormatAndType(mCaches, bitmap.colorType(), needSRGB, &internalFormat, &format, &type);
@@ -264,15 +256,21 @@
 
         SkBitmap rgbaBitmap;
         rgbaBitmap.allocPixels(SkImageInfo::MakeN32(
-                mWidth, mHeight, bitmap.alphaType(), hasSRGB ? sRGB : nullptr));
+                mWidth, mHeight, bitmap.info().alphaType(), hasSRGB ? sRGB : nullptr));
         rgbaBitmap.eraseColor(0);
 
         SkCanvas canvas(rgbaBitmap);
-        canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
+        SkBitmap skBitmap;
+        bitmap.getSkBitmap(&skBitmap);
+        canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);
 
-        uploadSkBitmapToTexture(rgbaBitmap, needsAlloc, internalFormat, format, type);
+        uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(),
+                rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(),
+                rgbaBitmap.height(), rgbaBitmap.getPixels());
+
     } else {
-        uploadSkBitmapToTexture(bitmap, needsAlloc, internalFormat, format, type);
+        uploadToTexture(needsAlloc, internalFormat, format, type, bitmap.rowBytesAsPixels(),
+                bitmap.info().bytesPerPixel(), bitmap.width(), bitmap.height(), bitmap.pixels());
     }
 
     if (canMipMap) {
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index aa8a6d3..57cfc2b 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -18,9 +18,9 @@
 #define ANDROID_HWUI_TEXTURE_H
 
 #include "GpuMemoryTracker.h"
+#include "hwui/Bitmap.h"
 
 #include <GLES2/gl2.h>
-#include <SkBitmap.h>
 
 namespace android {
 namespace uirenderer {
@@ -74,13 +74,13 @@
     }
 
     /**
-     * Updates this Texture with the contents of the provided SkBitmap,
+     * Updates this Texture with the contents of the provided Bitmap,
      * also setting the appropriate width, height, and format. It is not necessary
      * to call resize() prior to this.
      *
-     * Note this does not set the generation from the SkBitmap.
+     * Note this does not set the generation from the Bitmap.
      */
-    void upload(const SkBitmap& source);
+    void upload(Bitmap& source);
 
     /**
      * Basically glTexImage2D/glTexSubImage2D.
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 08641b7..14ffc85 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -127,9 +127,7 @@
             texture = new Texture(Caches::getInstance());
             texture->bitmapSize = size;
             texture->generation = bitmap->getGenerationID();
-            SkBitmap skBitmap;
-            bitmap->getSkBitmap(&skBitmap);
-            texture->upload(skBitmap);
+            texture->upload(*bitmap);
 
             mSize += size;
             TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d",
@@ -142,9 +140,7 @@
     } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) {
         // Texture was in the cache but is dirty, re-upload
         // TODO: Re-adjust the cache size if the bitmap's dimensions have changed
-        SkBitmap skBitmap;
-        bitmap->getSkBitmap(&skBitmap);
-        texture->upload(skBitmap);
+        texture->upload(*bitmap);
         texture->generation = bitmap->getGenerationID();
     }
 
@@ -174,9 +170,7 @@
         const uint32_t size = bitmap->rowBytes() * bitmap->height();
         texture = new Texture(Caches::getInstance());
         texture->bitmapSize = size;
-        SkBitmap skBitmap;
-        bitmap->getSkBitmap(&skBitmap);
-        texture->upload(skBitmap);
+        texture->upload(*bitmap);
         texture->generation = bitmap->getGenerationID();
         texture->cleanup = true;
     }
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index e86ac11..c175690 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -57,6 +57,11 @@
     // doing on a Bitmap type, not a SkPixelRef, so static
     // dispatching will do what we want.
     size_t rowBytes() const { return mRowBytes; }
+
+    int rowBytesAsPixels() const {
+        return mRowBytes >> info().shiftPerPixel();
+    }
+
     void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
     void reconfigure(const SkImageInfo& info);
     void setAlphaType(SkAlphaType alphaType);
@@ -73,6 +78,9 @@
     SkColorType colorType() const { return info().colorType(); }
     void getBounds(SkRect* bounds) const;
 
+    bool readyToDraw() const {
+        return this->colorType() != kIndex_8_SkColorType || mColorTable;
+    }
 protected:
     virtual bool onNewLockPixels(LockRec* rec) override;
     virtual void onUnlockPixels() override { };