diff options
-rw-r--r-- | core/jni/android/graphics/BitmapFactory.cpp | 21 | ||||
-rw-r--r-- | core/jni/android/graphics/Canvas.cpp | 6 | ||||
-rw-r--r-- | core/jni/android/graphics/Graphics.cpp | 23 | ||||
-rw-r--r-- | core/jni/android/graphics/GraphicsJNI.h | 7 | ||||
-rw-r--r-- | core/jni/android/graphics/Paint.cpp | 3 | ||||
-rw-r--r-- | core/jni/android/graphics/Region.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_view_SurfaceControl.cpp | 121 | ||||
-rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 10 |
8 files changed, 101 insertions, 92 deletions
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index fae93ba89194..e8feacb952a0 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -125,12 +125,18 @@ static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) { static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream, int sampleSize, bool ditherImage) { + SkImageInfo bitmapInfo; + if (!bitmap->asImageInfo(&bitmapInfo)) { + ALOGW("bitmap has unknown configuration so no memory has been allocated"); + return NULL; + } + SkImageRef* pr; // only use ashmem for large images, since mmaps come at a price if (bitmap->getSize() >= 32 * 1024) { - pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize); + pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize); } else { - pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize); + pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize); } pr->setDitherImage(ditherImage); bitmap->setPixelRef(pr)->unref(); @@ -192,8 +198,15 @@ public: return false; } + SkImageInfo bitmapInfo; + if (!bitmap->asImageInfo(&bitmapInfo)) { + ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration"); + return false; + } + // Create a new pixelref with the new ctable that wraps the previous pixelref - SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable); + SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), + bitmapInfo, bitmap->rowBytes(), ctable); bitmap->setPixelRef(pr)->unref(); // since we're already allocated, we lockPixels right away @@ -418,7 +431,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } SkPaint paint; - paint.setFilterBitmap(true); + paint.setFilterLevel(SkPaint::kLow_FilterLevel); SkCanvas canvas(*outputBitmap); canvas.scale(sx, sy); diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp index e98d45b1eeba..7420055567d8 100644 --- a/core/jni/android/graphics/Canvas.cpp +++ b/core/jni/android/graphics/Canvas.cpp @@ -555,7 +555,7 @@ public: if (paint) { filteredPaint = *paint; } - filteredPaint.setFilterBitmap(true); + filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint); } else { canvas->drawBitmap(*bitmap, left_, top_, paint); @@ -570,7 +570,7 @@ public: if (paint) { filteredPaint = *paint; } - filteredPaint.setFilterBitmap(true); + filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); @@ -593,7 +593,7 @@ public: if (paint) { filteredPaint = *paint; } - filteredPaint.setFilterBitmap(true); + filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint); } else { canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint); diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index 66f9f3dc9ec4..98edbdb1a901 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -444,8 +444,9 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// -AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, - SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)), +AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, + size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) : + SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)), fWrappedPixelRef(NULL) { SkASSERT(storage); SkASSERT(env); @@ -463,10 +464,11 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteA } -AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) : - SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false), +AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, + size_t rowBytes, SkColorTable* ctable) : + SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false), fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ? - wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef) + wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef) { SkASSERT(fWrappedPixelRef); SkSafeRef(fWrappedPixelRef); @@ -568,6 +570,14 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, "bitmap size exceeds 32bits"); return NULL; } + + SkImageInfo bitmapInfo; + if (!bitmap->asImageInfo(&bitmapInfo)) { + jniThrowException(env, "java/lang/IllegalArgumentException", + "unknown bitmap configuration"); + return NULL; + } + size_t size = size64.get32(); jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime, gVMRuntime_newNonMovableArray, @@ -581,7 +591,8 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, return NULL; } SkASSERT(addr); - SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable); + SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr, + bitmap->rowBytes(), arrayObj, ctable); bitmap->setPixelRef(pr)->unref(); // since we're already allocated, we lockPixels right away // HeapAllocator behaves this way too diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index 5f2960426382..cb154aaf28e5 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -92,15 +92,16 @@ public: class AndroidPixelRef : public SkMallocPixelRef { public: - AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, - SkColorTable* ctable); + AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, + jbyteArray storageObj, SkColorTable* ctable); /** * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share * the same storage and java byte array refcounting, yet have a different * color table. */ - AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable); + AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, + size_t rowBytes, SkColorTable* ctable); virtual ~AndroidPixelRef(); diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 6c81f060184d..189fe47a7fdf 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -155,7 +155,8 @@ public: static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) { NPE_CHECK_RETURN_VOID(env, paint); - GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap); + GraphicsJNI::getNativePaint(env, paint)->setFilterLevel( + filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel); } static void setDither(JNIEnv* env, jobject paint, jboolean dither) { diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp index bcf127399fcb..912968a9da3f 100644 --- a/core/jni/android/graphics/Region.cpp +++ b/core/jni/android/graphics/Region.cpp @@ -214,7 +214,7 @@ static jlong Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel) SkRegion* region = new SkRegion; size_t size = p->readInt32(); - region->readFromMemory(p->readInplace(size)); + region->readFromMemory(p->readInplace(size), size); return reinterpret_cast<jlong>(region); } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 480d0acfb0c2..c5ab284f765d 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -61,54 +61,21 @@ static struct { class ScreenshotPixelRef : public SkPixelRef { public: - ScreenshotPixelRef(SkColorTable* ctable) { - fCTable = ctable; - SkSafeRef(ctable); + ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) : + SkPixelRef(info), + mScreenshot(screenshot) { setImmutable(); } virtual ~ScreenshotPixelRef() { - SkSafeUnref(fCTable); - } - - status_t update(const sp<IBinder>& display, int width, int height, - int minLayer, int maxLayer, bool allLayers, - bool useIdentityTransform) { - status_t res = (width > 0 && height > 0) - ? (allLayers - ? mScreenshot.update(display, width, height, - useIdentityTransform) - : mScreenshot.update(display, width, height, - minLayer, maxLayer, useIdentityTransform)) - : mScreenshot.update(display, useIdentityTransform); - if (res != NO_ERROR) { - return res; - } - - return NO_ERROR; - } - - uint32_t getWidth() const { - return mScreenshot.getWidth(); - } - - uint32_t getHeight() const { - return mScreenshot.getHeight(); - } - - uint32_t getStride() const { - return mScreenshot.getStride(); - } - - uint32_t getFormat() const { - return mScreenshot.getFormat(); + delete mScreenshot; } protected: // overrides from SkPixelRef virtual void* onLockPixels(SkColorTable** ct) { - *ct = fCTable; - return (void*)mScreenshot.getPixels(); + *ct = NULL; + return (void*)mScreenshot->getPixels(); } virtual void onUnlockPixels() { @@ -116,8 +83,7 @@ protected: SK_DECLARE_UNFLATTENABLE_OBJECT() private: - ScreenshotClient mScreenshot; - SkColorTable* fCTable; + ScreenshotClient* mScreenshot; typedef SkPixelRef INHERITED; }; @@ -150,20 +116,6 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { ctrl->decStrong((void *)nativeCreate); } -static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { - /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then - we can map to SkBitmap::kARGB_8888_Config, and optionally call - bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap - (as an accelerator) - */ - switch (format) { - case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config; - case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config; - case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config; - default: return SkBitmap::kNo_Config; - } -} - static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { @@ -172,26 +124,57 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display return NULL; } - ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL); - if (pixels->update(displayToken, width, height, - minLayer, maxLayer, allLayers, useIdentityTransform) != NO_ERROR) { - delete pixels; + ScreenshotClient* screenshot = new ScreenshotClient(); + status_t res; + if (width > 0 && height > 0) { + if (allLayers) { + res = screenshot->update(displayToken, width, height, useIdentityTransform); + } else { + res = screenshot->update(displayToken, width, height, minLayer, maxLayer, + useIdentityTransform); + } + } else { + res = screenshot->update(displayToken, useIdentityTransform); + } + if (res != NO_ERROR) { + delete screenshot; return NULL; } - uint32_t w = pixels->getWidth(); - uint32_t h = pixels->getHeight(); - uint32_t s = pixels->getStride(); - uint32_t f = pixels->getFormat(); - ssize_t bpr = s * android::bytesPerPixel(f); + SkImageInfo screenshotInfo; + screenshotInfo.fWidth = screenshot->getWidth(); + screenshotInfo.fHeight = screenshot->getHeight(); - SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(convertPixelFormat(f), w, h, bpr); - if (f == PIXEL_FORMAT_RGBX_8888) { - bitmap->setAlphaType(kOpaque_SkAlphaType); + switch (screenshot->getFormat()) { + case PIXEL_FORMAT_RGBX_8888: { + screenshotInfo.fColorType = kRGBA_8888_SkColorType; + screenshotInfo.fAlphaType = kIgnore_SkAlphaType; + break; + } + case PIXEL_FORMAT_RGBA_8888: { + screenshotInfo.fColorType = kRGBA_8888_SkColorType; + screenshotInfo.fAlphaType = kPremul_SkAlphaType; + break; + } + case PIXEL_FORMAT_RGB_565: { + screenshotInfo.fColorType = kRGB_565_SkColorType; + screenshotInfo.fAlphaType = kIgnore_SkAlphaType; + break; + } + default: { + delete screenshot; + return NULL; + } } - if (w > 0 && h > 0) { + // takes ownership of ScreenshotClient + ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot); + const ssize_t rowBytes = + screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat()); + + SkBitmap* bitmap = new SkBitmap(); + bitmap->setConfig(screenshotInfo, (size_t)rowBytes); + if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) { bitmap->setPixelRef(pixels)->unref(); bitmap->lockPixels(); } else { diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index d6b73fd27fb4..7676143f11e7 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -400,7 +400,7 @@ public final class Bitmap implements Parcelable { * No color information is stored. * With this configuration, each pixel requires 1 byte of memory. */ - ALPHA_8 (2), + ALPHA_8 (1), /** * Each pixel is stored on 2 bytes and only the RGB channels are @@ -416,7 +416,7 @@ public final class Bitmap implements Parcelable { * This configuration may be useful when using opaque bitmaps * that do not require high color fidelity. */ - RGB_565 (4), + RGB_565 (3), /** * Each pixel is stored on 2 bytes. The three RGB color channels @@ -438,7 +438,7 @@ public final class Bitmap implements Parcelable { * it is advised to use {@link #ARGB_8888} instead. */ @Deprecated - ARGB_4444 (5), + ARGB_4444 (4), /** * Each pixel is stored on 4 bytes. Each channel (RGB and alpha @@ -448,13 +448,13 @@ public final class Bitmap implements Parcelable { * This configuration is very flexible and offers the best * quality. It should be used whenever possible. */ - ARGB_8888 (6); + ARGB_8888 (5); final int nativeInt; @SuppressWarnings({"deprecation"}) private static Config sConfigs[] = { - null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888 + null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888 }; Config(int ni) { |