Use android::skia::BitmapRegionDecoder
Bug: skbug.com/10154
Bug: 140600285
Test: BitmapRegionDecoderTest in CtsGraphicsTestCases
Skia is renaming this class in https://skia-review.googlesource.com/c/skia/+/287498
Use the new name for this and android::skia::BitmapRegionDecoder.
Convert CopyAssetToStream to CopyAssetToData. It was already using an
SkData, held by an SkMemoryStream. Using an SkData directly will allow
sharing it with other decoders for a multithreaded BitmapRegionDecoder.
Remove comment about ref/reopen-ing the asset.
Change-Id: Ib51a8d697ad0f5dc1f461257311b31443b5f9dfb
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 09196cf..0113b28 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -8,7 +8,6 @@
#include "MimeType.h"
#include "NinePatchPeeker.h"
#include "SkAndroidCodec.h"
-#include "SkBRDAllocator.h"
#include "SkMath.h"
#include "SkPixelRef.h"
#include "SkStream.h"
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index 3c427f9..4cc05ef 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -22,8 +22,8 @@
#include "GraphicsJNI.h"
#include "Utils.h"
+#include "BitmapRegionDecoder.h"
#include "SkBitmap.h"
-#include "SkBitmapRegionDecoder.h"
#include "SkCodec.h"
#include "SkData.h"
#include "SkStream.h"
@@ -36,10 +36,8 @@
using namespace android;
-static jobject createBitmapRegionDecoder(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream) {
- std::unique_ptr<SkBitmapRegionDecoder> brd(
- SkBitmapRegionDecoder::Create(stream.release(),
- SkBitmapRegionDecoder::kAndroidCodec_Strategy));
+static jobject createBitmapRegionDecoder(JNIEnv* env, sk_sp<SkData> data) {
+ auto brd = skia::BitmapRegionDecoder::Make(std::move(data));
if (!brd) {
doThrowIOE(env, "Image format not supported");
return nullObjectReturn("CreateBitmapRegionDecoder returned null");
@@ -51,11 +49,7 @@
static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
jint offset, jint length) {
AutoJavaByteArray ar(env, byteArray);
- std::unique_ptr<SkMemoryStream> stream(new SkMemoryStream(ar.ptr() + offset, length, true));
-
- // the decoder owns the stream.
- jobject brd = createBitmapRegionDecoder(env, std::move(stream));
- return brd;
+ return createBitmapRegionDecoder(env, SkData::MakeWithCopy(ar.ptr() + offset, length));
}
static jobject nativeNewInstanceFromFileDescriptor(JNIEnv* env, jobject clazz,
@@ -70,36 +64,28 @@
return nullObjectReturn("fstat return -1");
}
- sk_sp<SkData> data(SkData::MakeFromFD(descriptor));
- std::unique_ptr<SkMemoryStream> stream(new SkMemoryStream(std::move(data)));
-
- // the decoder owns the stream.
- jobject brd = createBitmapRegionDecoder(env, std::move(stream));
- return brd;
+ return createBitmapRegionDecoder(env, SkData::MakeFromFD(descriptor));
}
static jobject nativeNewInstanceFromStream(JNIEnv* env, jobject clazz, jobject is, // InputStream
jbyteArray storage) { // byte[]
- jobject brd = NULL;
- std::unique_ptr<SkStreamRewindable> stream(CopyJavaInputStream(env, is, storage));
+ jobject brd = nullptr;
+ sk_sp<SkData> data = CopyJavaInputStream(env, is, storage);
- if (stream) {
- // the decoder owns the stream.
- brd = createBitmapRegionDecoder(env, std::move(stream));
+ if (data) {
+ brd = createBitmapRegionDecoder(env, std::move(data));
}
return brd;
}
static jobject nativeNewInstanceFromAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
Asset* asset = reinterpret_cast<Asset*>(native_asset);
- std::unique_ptr<SkMemoryStream> stream(CopyAssetToStream(asset));
- if (NULL == stream) {
- return NULL;
+ sk_sp<SkData> data = CopyAssetToData(asset);
+ if (!data) {
+ return nullptr;
}
- // the decoder owns the stream.
- jobject brd = createBitmapRegionDecoder(env, std::move(stream));
- return brd;
+ return createBitmapRegionDecoder(env, data);
}
/*
@@ -149,7 +135,7 @@
recycledBytes = recycledBitmap->getAllocationByteCount();
}
- SkBitmapRegionDecoder* brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+ auto* brd = reinterpret_cast<skia::BitmapRegionDecoder*>(brdHandle);
SkColorType decodeColorType = brd->computeOutputColorType(colorType);
if (decodeColorType == kRGBA_F16_SkColorType && isHardware &&
!uirenderer::HardwareBitmapUploader::hasFP16Support()) {
@@ -157,7 +143,7 @@
}
// Set up the pixel allocator
- SkBRDAllocator* allocator = nullptr;
+ skia::BRDAllocator* allocator = nullptr;
RecyclingClippingPixelAllocator recycleAlloc(recycledBitmap, recycledBytes);
HeapAllocator heapAlloc;
if (javaBitmap) {
@@ -221,20 +207,17 @@
}
static jint nativeGetHeight(JNIEnv* env, jobject, jlong brdHandle) {
- SkBitmapRegionDecoder* brd =
- reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+ auto* brd = reinterpret_cast<skia::BitmapRegionDecoder*>(brdHandle);
return static_cast<jint>(brd->height());
}
static jint nativeGetWidth(JNIEnv* env, jobject, jlong brdHandle) {
- SkBitmapRegionDecoder* brd =
- reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+ auto* brd = reinterpret_cast<skia::BitmapRegionDecoder*>(brdHandle);
return static_cast<jint>(brd->width());
}
static void nativeClean(JNIEnv* env, jobject, jlong brdHandle) {
- SkBitmapRegionDecoder* brd =
- reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+ auto* brd = reinterpret_cast<skia::BitmapRegionDecoder*>(brdHandle);
delete brd;
}
diff --git a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp
index f1c6b29..785a5dc 100644
--- a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp
+++ b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp
@@ -177,8 +177,12 @@
return JavaInputStreamAdaptor::Create(env, stream, storage, swallowExceptions);
}
-static SkMemoryStream* adaptor_to_mem_stream(SkStream* stream) {
- SkASSERT(stream != NULL);
+sk_sp<SkData> CopyJavaInputStream(JNIEnv* env, jobject inputStream, jbyteArray storage) {
+ std::unique_ptr<SkStream> stream(CreateJavaInputStreamAdaptor(env, inputStream, storage));
+ if (!stream) {
+ return nullptr;
+ }
+
size_t bufferSize = 4096;
size_t streamLen = 0;
size_t len;
@@ -194,18 +198,7 @@
}
data = (char*)sk_realloc_throw(data, streamLen);
- SkMemoryStream* streamMem = new SkMemoryStream();
- streamMem->setMemoryOwned(data, streamLen);
- return streamMem;
-}
-
-SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
- jbyteArray storage) {
- std::unique_ptr<SkStream> adaptor(CreateJavaInputStreamAdaptor(env, stream, storage));
- if (NULL == adaptor.get()) {
- return NULL;
- }
- return adaptor_to_mem_stream(adaptor.get());
+ return SkData::MakeFromMalloc(data, streamLen);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h
index 849418d..bae40f1 100644
--- a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h
+++ b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.h
@@ -2,6 +2,7 @@
#define _ANDROID_GRAPHICS_CREATE_JAVA_OUTPUT_STREAM_ADAPTOR_H_
#include "jni.h"
+#include "SkData.h"
class SkMemoryStream;
class SkStream;
@@ -27,15 +28,14 @@
bool swallowExceptions = true);
/**
- * Copy a Java InputStream. The result will be rewindable.
+ * Copy a Java InputStream to an SkData.
* @param env JNIEnv object.
* @param stream Pointer to Java InputStream.
* @param storage Java byte array for retrieving data from the
* Java InputStream.
- * @return SkStreamRewindable The data in stream will be copied
- * to a new SkStreamRewindable.
+ * @return SkData containing the stream's data.
*/
-SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream, jbyteArray storage);
+sk_sp<SkData> CopyJavaInputStream(JNIEnv* env, jobject stream, jbyteArray storage);
SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream, jbyteArray storage);
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index f76ecb4..ecbb55ec 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -470,7 +470,7 @@
///////////////////////////////////////////////////////////////////////////////////////////
-jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap)
+jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, skia::BitmapRegionDecoder* bitmap)
{
ALOG_ASSERT(bitmap != NULL);
diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h
index b58a740..79ab617 100644
--- a/libs/hwui/jni/GraphicsJNI.h
+++ b/libs/hwui/jni/GraphicsJNI.h
@@ -4,8 +4,8 @@
#include <cutils/compiler.h>
#include "Bitmap.h"
+#include "BRDAllocator.h"
#include "SkBitmap.h"
-#include "SkBRDAllocator.h"
#include "SkCodec.h"
#include "SkPixelRef.h"
#include "SkMallocPixelRef.h"
@@ -17,10 +17,12 @@
#include "graphics_jni_helpers.h"
-class SkBitmapRegionDecoder;
class SkCanvas;
namespace android {
+namespace skia {
+ class BitmapRegionDecoder;
+}
class Paint;
struct Typeface;
}
@@ -103,7 +105,8 @@
static jobject createRegion(JNIEnv* env, SkRegion* region);
- static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
+ static jobject createBitmapRegionDecoder(JNIEnv* env,
+ android::skia::BitmapRegionDecoder* bitmap);
/**
* Given a bitmap we natively allocate a memory block to store the contents
@@ -154,7 +157,7 @@
static JavaVM* mJavaVM;
};
-class HeapAllocator : public SkBRDAllocator {
+class HeapAllocator : public android::skia::BRDAllocator {
public:
HeapAllocator() { };
~HeapAllocator() { };
@@ -181,7 +184,7 @@
* the decoded output to fit in the recycled bitmap if necessary.
* This allocator implements that behavior.
*
- * Skia's SkBitmapRegionDecoder expects the memory that
+ * Skia's BitmapRegionDecoder expects the memory that
* is allocated to be large enough to decode the entire region
* that is requested. It will decode directly into the memory
* that is provided.
@@ -200,7 +203,7 @@
* reuse it again, given that it still may be in use from our
* first allocation.
*/
-class RecyclingClippingPixelAllocator : public SkBRDAllocator {
+class RecyclingClippingPixelAllocator : public android::skia::BRDAllocator {
public:
RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
diff --git a/libs/hwui/jni/Utils.cpp b/libs/hwui/jni/Utils.cpp
index 34fd668..ac2f5b7 100644
--- a/libs/hwui/jni/Utils.cpp
+++ b/libs/hwui/jni/Utils.cpp
@@ -114,7 +114,7 @@
return amount;
}
-SkMemoryStream* android::CopyAssetToStream(Asset* asset) {
+sk_sp<SkData> android::CopyAssetToData(Asset* asset) {
if (NULL == asset) {
return NULL;
}
@@ -138,7 +138,7 @@
return NULL;
}
- return new SkMemoryStream(std::move(data));
+ return data;
}
jobject android::nullObjectReturn(const char msg[]) {
diff --git a/libs/hwui/jni/Utils.h b/libs/hwui/jni/Utils.h
index f628cc3..6cdf44d 100644
--- a/libs/hwui/jni/Utils.h
+++ b/libs/hwui/jni/Utils.h
@@ -46,12 +46,11 @@
};
/**
- * Make a deep copy of the asset, and return it as a stream, or NULL if there
+ * Make a deep copy of the asset, and return it as an SkData, or NULL if there
* was an error.
- * FIXME: If we could "ref/reopen" the asset, we may not need to copy it here.
*/
-SkMemoryStream* CopyAssetToStream(Asset*);
+sk_sp<SkData> CopyAssetToData(Asset*);
/** Restore the file descriptor's offset in our destructor
*/