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 { };