Pass Bitmap instead of SkBitmap for bitmap rect operation
Test: refactoring cl.
bug:32216791
Change-Id: I66d19194c57b3aa2c400aa87acffc774a533776a
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index f35d605..f2ae847 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -631,13 +631,15 @@
}
void FrameBuilder::deferVectorDrawableOp(const VectorDrawableOp& op) {
- const SkBitmap& bitmap = op.vectorDrawable->getBitmapUpdateIfDirty();
+ SkBitmap bitmap;
+ op.vectorDrawable->getBitmapUpdateIfDirty().getSkBitmap(&bitmap);
+ SkBitmap* localBitmap = mAllocator.create<SkBitmap>(bitmap);
SkPaint* paint = op.vectorDrawable->getPaint();
const BitmapRectOp* resolvedOp = mAllocator.create_trivial<BitmapRectOp>(op.unmappedBounds,
op.localMatrix,
op.localClip,
paint,
- &bitmap,
+ localBitmap,
Rect(bitmap.width(), bitmap.height()));
deferBitmapRectOp(*resolvedOp);
}
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 2730ed9..d252026 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -478,8 +478,10 @@
restore();
}
-void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+void RecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
const SkPaint* paint) {
+ SkBitmap bitmap;
+ hwuiBitmap.getSkBitmap(&bitmap);
if (matrix.isIdentity()) {
drawBitmap(&bitmap, paint);
} else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))
@@ -490,7 +492,7 @@
SkRect dst;
bitmap.getBounds(&src);
matrix.mapRect(&dst, src);
- drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
+ drawBitmap(hwuiBitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
} else {
save(SaveFlags::Matrix);
@@ -500,9 +502,11 @@
}
}
-void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+void RecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) {
+ SkBitmap bitmap;
+ hwuiBitmap.getSkBitmap(&bitmap);
if (srcLeft == 0 && srcTop == 0
&& srcRight == bitmap.width()
&& srcBottom == bitmap.height()
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index c5ed61c..cdb8dfc2 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -177,9 +177,8 @@
// Bitmap-based
virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
- virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
- const SkPaint* paint) override;
- virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+ virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
+ virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) override;
virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index c99219f..ab899f9 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -497,15 +497,19 @@
mCanvas->drawBitmap(skBitmap, left, top, paint);
}
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
+void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix, const SkPaint* paint) {
+ SkBitmap bitmap;
+ hwuiBitmap.getSkBitmap(&bitmap);
SkAutoCanvasRestore acr(mCanvas.get(), true);
mCanvas->concat(matrix);
mCanvas->drawBitmap(bitmap, 0, 0, paint);
}
-void SkiaCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) {
+ SkBitmap bitmap;
+ hwuiBitmap.getSkBitmap(&bitmap);
SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
mCanvas->drawBitmapRect(bitmap, srcRect, dstRect, paint);
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 9c4d7c4..49aea8e 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -125,9 +125,8 @@
const uint16_t* indices, int indexCount, const SkPaint& paint) override;
virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
- virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
- const SkPaint* paint) override;
- virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+ virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
+ virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) override;
virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 6620458..863146e 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -107,16 +107,12 @@
void SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint* paint) {
- SkPixelRef* pxRef = bitmap.pixelRef();
-
+ sk_sp<Bitmap> hwuiBitmap = Bitmap::createFrom(bitmap.info(), *bitmap.pixelRef());
// HWUI doesn't support extractSubset(), so convert any subsetted bitmap into
// a drawBitmapRect(); pass through an un-subsetted bitmap.
- if (pxRef && bitmap.dimensions() != pxRef->info().dimensions()) {
- SkBitmap fullBitmap;
- fullBitmap.setInfo(pxRef->info());
- fullBitmap.setPixelRef(pxRef, 0, 0);
+ if (hwuiBitmap && bitmap.dimensions() != hwuiBitmap->info().dimensions()) {
SkIPoint origin = bitmap.pixelRefOrigin();
- mCanvas->drawBitmap(fullBitmap, origin.fX, origin.fY,
+ mCanvas->drawBitmap(*hwuiBitmap, origin.fX, origin.fY,
origin.fX + bitmap.dimensions().width(),
origin.fY + bitmap.dimensions().height(),
left, top,
@@ -124,16 +120,16 @@
top + bitmap.dimensions().height(),
paint);
} else {
- auto hwuiBitmap= Bitmap::createFrom(bitmap.info(), *pxRef);
mCanvas->drawBitmap(*hwuiBitmap, left, top, paint);
}
}
-void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* srcPtr,
+void SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& skBitmap, const SkRect* srcPtr,
const SkRect& dst, const SkPaint* paint, SrcRectConstraint) {
- SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(bitmap.width(), bitmap.height());
+ SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(skBitmap.width(), skBitmap.height());
// TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src?
- mCanvas->drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
+ Bitmap* bitmap = reinterpret_cast<Bitmap*>(skBitmap.pixelRef());
+ mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
}
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 715681d..b50647a 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -502,18 +502,18 @@
}
void Tree::drawStaging(Canvas* outCanvas) {
- bool redrawNeeded = allocateBitmapIfNeeded(&mStagingCache.bitmap,
+ bool redrawNeeded = allocateBitmapIfNeeded(mStagingCache,
mStagingProperties.getScaledWidth(), mStagingProperties.getScaledHeight());
// draw bitmap cache
if (redrawNeeded || mStagingCache.dirty) {
- updateBitmapCache(&mStagingCache.bitmap, true);
+ updateBitmapCache(*mStagingCache.bitmap, true);
mStagingCache.dirty = false;
}
SkPaint tmpPaint;
SkPaint* paint = updatePaint(&tmpPaint, &mStagingProperties);
- outCanvas->drawBitmap(mStagingCache.bitmap, 0, 0,
- mStagingCache.bitmap.width(), mStagingCache.bitmap.height(),
+ outCanvas->drawBitmap(*mStagingCache.bitmap, 0, 0,
+ mStagingCache.bitmap->width(), mStagingCache.bitmap->height(),
mStagingProperties.getBounds().left(), mStagingProperties.getBounds().top(),
mStagingProperties.getBounds().right(), mStagingProperties.getBounds().bottom(), paint);
}
@@ -535,46 +535,46 @@
}
}
-const SkBitmap& Tree::getBitmapUpdateIfDirty() {
- bool redrawNeeded = allocateBitmapIfNeeded(&mCache.bitmap, mProperties.getScaledWidth(),
+Bitmap& Tree::getBitmapUpdateIfDirty() {
+ bool redrawNeeded = allocateBitmapIfNeeded(mCache, mProperties.getScaledWidth(),
mProperties.getScaledHeight());
if (redrawNeeded || mCache.dirty) {
- updateBitmapCache(&mCache.bitmap, false);
+ updateBitmapCache(*mCache.bitmap, false);
mCache.dirty = false;
}
- return mCache.bitmap;
+ return *mCache.bitmap;
}
-void Tree::updateBitmapCache(SkBitmap* outCache, bool useStagingData) {
- outCache->eraseColor(SK_ColorTRANSPARENT);
- SkCanvas outCanvas(*outCache);
+void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {
+ SkBitmap outCache;
+ bitmap.getSkBitmap(&outCache);
+ outCache.eraseColor(SK_ColorTRANSPARENT);
+ SkCanvas outCanvas(outCache);
float viewportWidth = useStagingData ?
mStagingProperties.getViewportWidth() : mProperties.getViewportWidth();
float viewportHeight = useStagingData ?
mStagingProperties.getViewportHeight() : mProperties.getViewportHeight();
- float scaleX = outCache->width() / viewportWidth;
- float scaleY = outCache->height() / viewportHeight;
+ float scaleX = outCache.width() / viewportWidth;
+ float scaleY = outCache.height() / viewportHeight;
mRootNode->draw(&outCanvas, SkMatrix::I(), scaleX, scaleY, useStagingData);
}
-bool Tree::allocateBitmapIfNeeded(SkBitmap* outCache, int width, int height) {
- if (!canReuseBitmap(*outCache, width, height)) {
+bool Tree::allocateBitmapIfNeeded(Cache& cache, int width, int height) {
+ if (!canReuseBitmap(cache.bitmap.get(), width, height)) {
#ifndef ANDROID_ENABLE_LINEAR_BLENDING
sk_sp<SkColorSpace> colorSpace = nullptr;
#else
sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
#endif
SkImageInfo info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType, colorSpace);
- outCache->setInfo(info);
- // TODO: Count the bitmap cache against app's java heap
- outCache->allocPixels(info);
+ cache.bitmap = Bitmap::allocateHeapBitmap(info);
return true;
}
return false;
}
-bool Tree::canReuseBitmap(const SkBitmap& bitmap, int width, int height) {
- return width == bitmap.width() && height == bitmap.height();
+bool Tree::canReuseBitmap(Bitmap* bitmap, int width, int height) {
+ return bitmap && width == bitmap->width() && height == bitmap->height();
}
void Tree::onPropertyChanged(TreeProperties* prop) {
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index e68fbf4..e9a9c71 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -18,6 +18,7 @@
#define ANDROID_HWUI_VPATH_H
#include "hwui/Canvas.h"
+#include "hwui/Bitmap.h"
#include "DisplayList.h"
#include <SkBitmap.h>
@@ -561,7 +562,7 @@
const SkRect& bounds, bool needsMirroring, bool canReuseCache);
void drawStaging(Canvas* canvas);
- const SkBitmap& getBitmapUpdateIfDirty();
+ Bitmap& getBitmapUpdateIfDirty();
void setAllowCaching(bool allowCaching) {
mAllowCaching = allowCaching;
}
@@ -691,11 +692,15 @@
void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; }
private:
+ struct Cache {
+ sk_sp<Bitmap> bitmap;
+ bool dirty = true;
+ };
SkPaint* updatePaint(SkPaint* outPaint, TreeProperties* prop);
- bool allocateBitmapIfNeeded(SkBitmap* outCache, int width, int height);
- bool canReuseBitmap(const SkBitmap&, int width, int height);
- void updateBitmapCache(SkBitmap* outCache, bool useStagingData);
+ bool allocateBitmapIfNeeded(Cache& cache, int width, int height);
+ bool canReuseBitmap(Bitmap*, int width, int height);
+ void updateBitmapCache(Bitmap& outCache, bool useStagingData);
// Cap the bitmap size, such that it won't hurt the performance too much
// and it won't crash due to a very large scale.
// The drawable will look blurry above this size.
@@ -708,10 +713,6 @@
TreeProperties mStagingProperties = TreeProperties(this);
SkPaint mPaint;
- struct Cache {
- SkBitmap bitmap;
- bool dirty = true;
- };
Cache mStagingCache;
Cache mCache;
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 341ece3..d9534f2 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -23,9 +23,9 @@
namespace android {
-static bool computeAllocationSize(const SkBitmap& bitmap, size_t* size) {
- int32_t rowBytes32 = SkToS32(bitmap.rowBytes());
- int64_t bigSize = (int64_t)bitmap.height() * rowBytes32;
+static bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
+ int32_t rowBytes32 = SkToS32(rowBytes);
+ int64_t bigSize = (int64_t) height * rowBytes32;
if (rowBytes32 < 0 || !sk_64_isS32(bigSize)) {
return false; // allocation will be too large
}
@@ -45,13 +45,14 @@
}
size_t size;
- if (!computeAllocationSize(*bitmap, &size)) {
- return nullptr;
- }
// we must respect the rowBytes value already set on the bitmap instead of
// attempting to compute our own.
const size_t rowBytes = bitmap->rowBytes();
+ if (!computeAllocationSize(rowBytes, bitmap->height(), &size)) {
+ return nullptr;
+ }
+
auto wrapper = alloc(size, info, rowBytes, ctable);
if (wrapper) {
wrapper->getSkBitmap(bitmap);
@@ -62,15 +63,11 @@
return wrapper;
}
-sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
- return allocateBitmap(bitmap, ctable, &Bitmap::allocateHeapBitmap);
-}
-
sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
}
-sk_sp<Bitmap> Bitmap::allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
+static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
SkColorTable* ctable) {
void* addr = calloc(size, 1);
if (!addr) {
@@ -79,6 +76,19 @@
return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
}
+sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
+ return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
+}
+
+sk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
+ size_t size;
+ if (!computeAllocationSize(info.minRowBytes(), info.height(), &size)) {
+ LOG_ALWAYS_FATAL("trying to allocate too large bitmap");
+ return nullptr;
+ }
+ return android::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
+}
+
sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
size_t rowBytes, SkColorTable* ctable) {
// Create new ashmem region with read/write priv
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 2a5d00b..029d80d 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -34,8 +34,7 @@
class ANDROID_API Bitmap : public SkPixelRef {
public:
static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable);
- static sk_sp<Bitmap> allocateHeapBitmap(size_t allocSize, const SkImageInfo& info,
- size_t rowBytes, SkColorTable* ctable);
+ static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable);
static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 8d08608..baee8fd 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -220,9 +220,9 @@
// Bitmap-based
virtual void drawBitmap(Bitmap& bitmap, float left, float top,
const SkPaint* paint) = 0;
- virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+ virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix,
const SkPaint* paint) = 0;
- virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+ virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) = 0;
virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index cdfa2f4..b8dfb01 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -125,8 +125,7 @@
static sk_sp<Bitmap> createBitmap(int width, int height,
SkColorType colorType = kN32_SkColorType) {
SkImageInfo info = SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType);
- size_t size = height * info.minRowBytes();
- return Bitmap::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
+ return Bitmap::allocateHeapBitmap(info);
}
static sk_sp<Bitmap> createBitmap(int width, int height, SkBitmap* outBitmap) {
diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
index 584f684..8256024 100644
--- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
@@ -45,12 +45,14 @@
int x = dp(32);
for (int i = 0; i < 4; i++) {
int y = (height / 4) * i;
- SkBitmap thumb = TestUtils::createSkBitmap(thumbnailSize, thumbnailSize);
- thumb.eraseColor(COLORS[i]);
- sp<RenderNode> card = createCard(x, y, cardsize, cardsize, thumb);
+ SkBitmap bitmap;
+ sk_sp<Bitmap> thumb(TestUtils::createBitmap(thumbnailSize, thumbnailSize, &bitmap));
+
+ bitmap.eraseColor(COLORS[i]);
+ sp<RenderNode> card = createCard(x, y, cardsize, cardsize, *thumb);
card->mutateStagingProperties().setElevation(i * dp(8));
renderer.drawRenderNode(card.get());
- mThumbnail = thumb;
+ mThumbnail = bitmap;
mCards.push_back(card);
}
@@ -68,8 +70,7 @@
}
private:
- sp<RenderNode> createCard(int x, int y, int width, int height,
- const SkBitmap& thumb) {
+ sp<RenderNode> createCard(int x, int y, int width, int height, Bitmap& thumb) {
return TestUtils::createNode(x, y, x + width, y + height,
[&thumb, width, height](RenderProperties& props, Canvas& canvas) {
props.setElevation(dp(16));