* commit '96978ee290ea0ef666c49ffa8733a8c74304c9f1': Update framework to use M33 Skia. DO NOT MERGE
This commit is contained in:
@@ -227,7 +227,7 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
|
|||||||
do {
|
do {
|
||||||
*dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
|
*dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
|
||||||
} while (--width != 0);
|
} while (--width != 0);
|
||||||
ctable->unlockColors(false);
|
ctable->unlockColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
|
static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
|
||||||
@@ -240,7 +240,7 @@ static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
|
|||||||
*dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
|
*dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
|
||||||
SkGetPackedG32(c), SkGetPackedB32(c));
|
SkGetPackedG32(c), SkGetPackedB32(c));
|
||||||
} while (--width != 0);
|
} while (--width != 0);
|
||||||
ctable->unlockColors(false);
|
ctable->unlockColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
|
static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
|
||||||
@@ -253,7 +253,7 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
|
|||||||
*dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
|
*dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
|
||||||
SkGetPackedB32(c));
|
SkGetPackedB32(c));
|
||||||
} while (--width != 0);
|
} while (--width != 0);
|
||||||
ctable->unlockColors(false);
|
ctable->unlockColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// can return NULL
|
// can return NULL
|
||||||
@@ -456,10 +456,16 @@ static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) {
|
|||||||
return !bitmap->isOpaque() ? JNI_TRUE : JNI_FALSE;
|
return !bitmap->isOpaque() ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle,
|
static void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle,
|
||||||
jboolean hasAlpha) {
|
jboolean hasAlpha, jboolean isPremul) {
|
||||||
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
|
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
|
||||||
bitmap->setIsOpaque(!hasAlpha);
|
if (!hasAlpha) {
|
||||||
|
bitmap->setAlphaType(kOpaque_SkAlphaType);
|
||||||
|
} else if (isPremul) {
|
||||||
|
bitmap->setAlphaType(kPremul_SkAlphaType);
|
||||||
|
} else {
|
||||||
|
bitmap->setAlphaType(kUnpremul_SkAlphaType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) {
|
static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) {
|
||||||
@@ -561,14 +567,14 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
|
|||||||
p->writeInt32(bitmap->rowBytes());
|
p->writeInt32(bitmap->rowBytes());
|
||||||
p->writeInt32(density);
|
p->writeInt32(density);
|
||||||
|
|
||||||
if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
|
if (bitmap->config() == SkBitmap::kIndex8_Config) {
|
||||||
SkColorTable* ctable = bitmap->getColorTable();
|
SkColorTable* ctable = bitmap->getColorTable();
|
||||||
if (ctable != NULL) {
|
if (ctable != NULL) {
|
||||||
int count = ctable->count();
|
int count = ctable->count();
|
||||||
p->writeInt32(count);
|
p->writeInt32(count);
|
||||||
memcpy(p->writeInplace(count * sizeof(SkPMColor)),
|
memcpy(p->writeInplace(count * sizeof(SkPMColor)),
|
||||||
ctable->lockColors(), count * sizeof(SkPMColor));
|
ctable->lockColors(), count * sizeof(SkPMColor));
|
||||||
ctable->unlockColors(false);
|
ctable->unlockColors();
|
||||||
} else {
|
} else {
|
||||||
p->writeInt32(0); // indicate no ctable
|
p->writeInt32(0); // indicate no ctable
|
||||||
}
|
}
|
||||||
@@ -800,7 +806,7 @@ static JNINativeMethod gBitmapMethods[] = {
|
|||||||
{ "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes },
|
{ "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes },
|
||||||
{ "nativeConfig", "(J)I", (void*)Bitmap_config },
|
{ "nativeConfig", "(J)I", (void*)Bitmap_config },
|
||||||
{ "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha },
|
{ "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha },
|
||||||
{ "nativeSetHasAlpha", "(JZ)V", (void*)Bitmap_setHasAlpha },
|
{ "nativeSetAlphaAndPremultiplied", "(JZZ)V", (void*)Bitmap_setAlphaAndPremultiplied},
|
||||||
{ "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap },
|
{ "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap },
|
||||||
{ "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap },
|
{ "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap },
|
||||||
{ "nativeCreateFromParcel",
|
{ "nativeCreateFromParcel",
|
||||||
|
|||||||
@@ -126,12 +126,18 @@ static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) {
|
|||||||
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
|
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
|
||||||
int sampleSize, bool ditherImage) {
|
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;
|
SkImageRef* pr;
|
||||||
// only use ashmem for large images, since mmaps come at a price
|
// only use ashmem for large images, since mmaps come at a price
|
||||||
if (bitmap->getSize() >= 32 * 1024) {
|
if (bitmap->getSize() >= 32 * 1024) {
|
||||||
pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize);
|
pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize);
|
||||||
} else {
|
} else {
|
||||||
pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize);
|
pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize);
|
||||||
}
|
}
|
||||||
pr->setDitherImage(ditherImage);
|
pr->setDitherImage(ditherImage);
|
||||||
bitmap->setPixelRef(pr)->unref();
|
bitmap->setPixelRef(pr)->unref();
|
||||||
@@ -159,7 +165,7 @@ public:
|
|||||||
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
|
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
|
||||||
// accounts for scale in final allocation, using eventual size and config
|
// accounts for scale in final allocation, using eventual size and config
|
||||||
const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
|
const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
|
||||||
configForScaledOutput(bitmap->getConfig()));
|
configForScaledOutput(bitmap->config()));
|
||||||
const int requestedSize = bytesPerPixel *
|
const int requestedSize = bytesPerPixel *
|
||||||
int(bitmap->width() * mScale + 0.5f) *
|
int(bitmap->width() * mScale + 0.5f) *
|
||||||
int(bitmap->height() * mScale + 0.5f);
|
int(bitmap->height() * mScale + 0.5f);
|
||||||
@@ -193,8 +199,15 @@ public:
|
|||||||
return false;
|
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
|
// 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();
|
bitmap->setPixelRef(pr)->unref();
|
||||||
// since we're already allocated, we lockPixels right away
|
// since we're already allocated, we lockPixels right away
|
||||||
@@ -403,8 +416,11 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
|
|||||||
|
|
||||||
// TODO: avoid copying when scaled size equals decodingBitmap size
|
// TODO: avoid copying when scaled size equals decodingBitmap size
|
||||||
SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
|
SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
|
||||||
outputBitmap->setConfig(config, scaledWidth, scaledHeight);
|
// FIXME: If the alphaType is kUnpremul and the image has alpha, the
|
||||||
outputBitmap->setIsOpaque(decodingBitmap.isOpaque());
|
// colors may not be correct, since Skia does not yet support drawing
|
||||||
|
// to/from unpremultiplied bitmaps.
|
||||||
|
outputBitmap->setConfig(config, scaledWidth, scaledHeight, 0,
|
||||||
|
decodingBitmap.alphaType());
|
||||||
if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
|
if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
|
||||||
return nullObjectReturn("allocation failed for scaled bitmap");
|
return nullObjectReturn("allocation failed for scaled bitmap");
|
||||||
}
|
}
|
||||||
@@ -416,7 +432,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setFilterBitmap(true);
|
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||||
|
|
||||||
SkCanvas canvas(*outputBitmap);
|
SkCanvas canvas(*outputBitmap);
|
||||||
canvas.scale(sx, sy);
|
canvas.scale(sx, sy);
|
||||||
@@ -543,7 +559,9 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset,
|
|||||||
} else {
|
} else {
|
||||||
// since we know we'll be done with the asset when we return, we can
|
// since we know we'll be done with the asset when we return, we can
|
||||||
// just use a simple wrapper
|
// just use a simple wrapper
|
||||||
stream = new AssetStreamAdaptor(asset);
|
stream = new AssetStreamAdaptor(asset,
|
||||||
|
AssetStreamAdaptor::kNo_OwnAsset,
|
||||||
|
AssetStreamAdaptor::kNo_HasMemoryBase);
|
||||||
}
|
}
|
||||||
SkAutoUnref aur(stream);
|
SkAutoUnref aur(stream);
|
||||||
return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
|
return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "CreateJavaOutputStreamAdaptor.h"
|
#include "CreateJavaOutputStreamAdaptor.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "JNIHelp.h"
|
#include "JNIHelp.h"
|
||||||
#include "SkTScopedPtr.h"
|
|
||||||
|
|
||||||
#include <android_runtime/AndroidRuntime.h>
|
#include <android_runtime/AndroidRuntime.h>
|
||||||
#include "android_util_Binder.h"
|
#include "android_util_Binder.h"
|
||||||
@@ -76,7 +75,7 @@ private:
|
|||||||
int fHeight;
|
int fHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) {
|
static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) {
|
||||||
SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
|
SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
|
||||||
int width, height;
|
int width, height;
|
||||||
if (NULL == decoder) {
|
if (NULL == decoder) {
|
||||||
@@ -108,7 +107,7 @@ static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray b
|
|||||||
For now we just always copy the array's data if isShareable.
|
For now we just always copy the array's data if isShareable.
|
||||||
*/
|
*/
|
||||||
AutoJavaByteArray ar(env, byteArray);
|
AutoJavaByteArray ar(env, byteArray);
|
||||||
SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
|
SkStreamRewindable* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
|
||||||
|
|
||||||
jobject brd = createBitmapRegionDecoder(env, stream);
|
jobject brd = createBitmapRegionDecoder(env, stream);
|
||||||
SkSafeUnref(stream); // the decoder now holds a reference
|
SkSafeUnref(stream); // the decoder now holds a reference
|
||||||
@@ -216,7 +215,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle,
|
|||||||
region.fRight = start_x + width;
|
region.fRight = start_x + width;
|
||||||
region.fBottom = start_y + height;
|
region.fBottom = start_y + height;
|
||||||
SkBitmap* bitmap = NULL;
|
SkBitmap* bitmap = NULL;
|
||||||
SkTScopedPtr<SkBitmap> adb;
|
SkAutoTDelete<SkBitmap> adb;
|
||||||
|
|
||||||
if (tileBitmap != NULL) {
|
if (tileBitmap != NULL) {
|
||||||
// Re-use bitmap.
|
// Re-use bitmap.
|
||||||
@@ -247,7 +246,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// detach bitmap from its autodeleter, since we want to own it now
|
// detach bitmap from its autodeleter, since we want to own it now
|
||||||
adb.release();
|
adb.detach();
|
||||||
|
|
||||||
JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
|
JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
|
||||||
jbyteArray buff = allocator->getStorageObjAndReset();
|
jbyteArray buff = allocator->getStorageObjAndReset();
|
||||||
|
|||||||
@@ -549,7 +549,7 @@ public:
|
|||||||
if (paint) {
|
if (paint) {
|
||||||
filteredPaint = *paint;
|
filteredPaint = *paint;
|
||||||
}
|
}
|
||||||
filteredPaint.setFilterBitmap(true);
|
filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||||
canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
|
canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
|
||||||
} else {
|
} else {
|
||||||
canvas->drawBitmap(*bitmap, left_, top_, paint);
|
canvas->drawBitmap(*bitmap, left_, top_, paint);
|
||||||
@@ -564,7 +564,7 @@ public:
|
|||||||
if (paint) {
|
if (paint) {
|
||||||
filteredPaint = *paint;
|
filteredPaint = *paint;
|
||||||
}
|
}
|
||||||
filteredPaint.setFilterBitmap(true);
|
filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||||
|
|
||||||
canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
|
canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
|
||||||
|
|
||||||
@@ -587,7 +587,7 @@ public:
|
|||||||
if (paint) {
|
if (paint) {
|
||||||
filteredPaint = *paint;
|
filteredPaint = *paint;
|
||||||
}
|
}
|
||||||
filteredPaint.setFilterBitmap(true);
|
filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||||
canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
|
canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
|
||||||
} else {
|
} else {
|
||||||
canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
|
canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
|
||||||
|
|||||||
@@ -357,6 +357,18 @@ SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Assert that bitmap's SkAlphaType is consistent with isPremultiplied.
|
||||||
|
static void assert_premultiplied(const SkBitmap& bitmap, bool isPremultiplied) {
|
||||||
|
// kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is
|
||||||
|
// irrelevant. This just tests to ensure that the SkAlphaType is not
|
||||||
|
// opposite of isPremultiplied.
|
||||||
|
if (isPremultiplied) {
|
||||||
|
SkASSERT(bitmap.alphaType() != kUnpremul_SkAlphaType);
|
||||||
|
} else {
|
||||||
|
SkASSERT(bitmap.alphaType() != kPremul_SkAlphaType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
|
jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
|
||||||
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
|
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
|
||||||
{
|
{
|
||||||
@@ -365,6 +377,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buff
|
|||||||
bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
|
bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
|
||||||
bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
|
bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
|
||||||
|
|
||||||
|
// The caller needs to have already set the alpha type properly, so the
|
||||||
|
// native SkBitmap stays in sync with the Java Bitmap.
|
||||||
|
assert_premultiplied(*bitmap, isPremultiplied);
|
||||||
|
|
||||||
jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
|
jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
|
||||||
reinterpret_cast<jlong>(bitmap), buffer,
|
reinterpret_cast<jlong>(bitmap), buffer,
|
||||||
bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
|
bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
|
||||||
@@ -382,6 +398,10 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreat
|
|||||||
void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
|
void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
|
||||||
bool isPremultiplied)
|
bool isPremultiplied)
|
||||||
{
|
{
|
||||||
|
// The caller needs to have already set the alpha type properly, so the
|
||||||
|
// native SkBitmap stays in sync with the Java Bitmap.
|
||||||
|
assert_premultiplied(*bitmap, isPremultiplied);
|
||||||
|
|
||||||
env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
|
env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
|
||||||
bitmap->width(), bitmap->height(), isPremultiplied);
|
bitmap->width(), bitmap->height(), isPremultiplied);
|
||||||
}
|
}
|
||||||
@@ -424,8 +444,9 @@ static JNIEnv* vm2env(JavaVM* vm)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
|
AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage,
|
||||||
SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
|
size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) :
|
||||||
|
SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
|
||||||
fWrappedPixelRef(NULL) {
|
fWrappedPixelRef(NULL) {
|
||||||
SkASSERT(storage);
|
SkASSERT(storage);
|
||||||
SkASSERT(env);
|
SkASSERT(env);
|
||||||
@@ -440,13 +461,13 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteA
|
|||||||
|
|
||||||
// If storageObj is NULL, the memory was NOT allocated on the Java heap
|
// If storageObj is NULL, the memory was NOT allocated on the Java heap
|
||||||
fOnJavaHeap = (storageObj != NULL);
|
fOnJavaHeap = (storageObj != NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
|
AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
|
||||||
SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
|
size_t rowBytes, SkColorTable* ctable) :
|
||||||
|
SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false),
|
||||||
fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
|
fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
|
||||||
wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
|
wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
|
||||||
{
|
{
|
||||||
SkASSERT(fWrappedPixelRef);
|
SkASSERT(fWrappedPixelRef);
|
||||||
SkSafeRef(fWrappedPixelRef);
|
SkSafeRef(fWrappedPixelRef);
|
||||||
@@ -548,6 +569,14 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
|
|||||||
"bitmap size exceeds 32bits");
|
"bitmap size exceeds 32bits");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkImageInfo bitmapInfo;
|
||||||
|
if (!bitmap->asImageInfo(&bitmapInfo)) {
|
||||||
|
jniThrowException(env, "java/lang/IllegalArgumentException",
|
||||||
|
"unknown bitmap configuration");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
size_t size = size64.get32();
|
size_t size = size64.get32();
|
||||||
jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
|
jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
|
||||||
gVMRuntime_newNonMovableArray,
|
gVMRuntime_newNonMovableArray,
|
||||||
@@ -561,7 +590,8 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
SkASSERT(addr);
|
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();
|
bitmap->setPixelRef(pr)->unref();
|
||||||
// since we're already allocated, we lockPixels right away
|
// since we're already allocated, we lockPixels right away
|
||||||
// HeapAllocator behaves this way too
|
// HeapAllocator behaves this way too
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public:
|
|||||||
|
|
||||||
/** Create a java Bitmap object given the native bitmap (required) and optional
|
/** Create a java Bitmap object given the native bitmap (required) and optional
|
||||||
storage array (may be null).
|
storage array (may be null).
|
||||||
|
bitmap's SkAlphaType must already be in sync with bitmapCreateFlags.
|
||||||
*/
|
*/
|
||||||
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
|
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
|
||||||
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1);
|
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1);
|
||||||
@@ -64,6 +65,9 @@ public:
|
|||||||
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
|
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
|
||||||
jbyteArray ninepatch, int density = -1);
|
jbyteArray ninepatch, int density = -1);
|
||||||
|
|
||||||
|
/** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
|
||||||
|
sync with isPremultiplied
|
||||||
|
*/
|
||||||
static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
|
static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
|
||||||
bool isPremultiplied);
|
bool isPremultiplied);
|
||||||
|
|
||||||
@@ -88,15 +92,16 @@ public:
|
|||||||
|
|
||||||
class AndroidPixelRef : public SkMallocPixelRef {
|
class AndroidPixelRef : public SkMallocPixelRef {
|
||||||
public:
|
public:
|
||||||
AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
|
AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes,
|
||||||
SkColorTable* ctable);
|
jbyteArray storageObj, SkColorTable* ctable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
|
* Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
|
||||||
* the same storage and java byte array refcounting, yet have a different
|
* the same storage and java byte array refcounting, yet have a different
|
||||||
* color table.
|
* color table.
|
||||||
*/
|
*/
|
||||||
AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable);
|
AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
|
||||||
|
size_t rowBytes, SkColorTable* ctable);
|
||||||
|
|
||||||
virtual ~AndroidPixelRef();
|
virtual ~AndroidPixelRef();
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,9 @@ static void movie_draw(JNIEnv* env, jobject movie, jobject canvas,
|
|||||||
static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
|
static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
|
||||||
android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
|
android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
|
||||||
if (asset == NULL) return NULL;
|
if (asset == NULL) return NULL;
|
||||||
SkAutoTUnref<SkStreamRewindable> stream (new android::AssetStreamAdaptor(asset));
|
SkAutoTUnref<SkStreamRewindable> stream (new android::AssetStreamAdaptor(asset,
|
||||||
|
android::AssetStreamAdaptor::kNo_OwnAsset,
|
||||||
|
android::AssetStreamAdaptor::kNo_HasMemoryBase));
|
||||||
SkMovie* moov = SkMovie::DecodeStream(stream.get());
|
SkMovie* moov = SkMovie::DecodeStream(stream.get());
|
||||||
return create_jmovie(env, moov);
|
return create_jmovie(env, moov);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,15 +40,14 @@ bool NinePatchPeeker::peek(const char tag[], const void* data, size_t length) {
|
|||||||
// now update our host to force index or 32bit config
|
// now update our host to force index or 32bit config
|
||||||
// 'cause we don't want 565 predithered, since as a 9patch, we know
|
// 'cause we don't want 565 predithered, since as a 9patch, we know
|
||||||
// we will be stretched, and therefore we want to dither afterwards.
|
// we will be stretched, and therefore we want to dither afterwards.
|
||||||
static const SkBitmap::Config gNo565Pref[] = {
|
SkImageDecoder::PrefConfigTable table;
|
||||||
SkBitmap::kIndex8_Config,
|
table.fPrefFor_8Index_NoAlpha_src = SkBitmap::kIndex8_Config;
|
||||||
SkBitmap::kIndex8_Config,
|
table.fPrefFor_8Index_YesAlpha_src = SkBitmap::kIndex8_Config;
|
||||||
SkBitmap::kARGB_8888_Config,
|
table.fPrefFor_8Gray_src = SkBitmap::kARGB_8888_Config;
|
||||||
SkBitmap::kARGB_8888_Config,
|
table.fPrefFor_8bpc_NoAlpha_src = SkBitmap::kARGB_8888_Config;
|
||||||
SkBitmap::kARGB_8888_Config,
|
table.fPrefFor_8bpc_YesAlpha_src = SkBitmap::kARGB_8888_Config;
|
||||||
SkBitmap::kARGB_8888_Config,
|
|
||||||
};
|
fHost->setPrefConfigTable(table);
|
||||||
fHost->setPrefConfigTable(gNo565Pref);
|
|
||||||
} else if (strcmp("npLb", tag) == 0 && length == sizeof(int) * 4) {
|
} else if (strcmp("npLb", tag) == 0 && length == sizeof(int) * 4) {
|
||||||
fLayoutBounds = new int[4];
|
fLayoutBounds = new int[4];
|
||||||
memcpy(fLayoutBounds, data, sizeof(int) * 4);
|
memcpy(fLayoutBounds, data, sizeof(int) * 4);
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ public:
|
|||||||
|
|
||||||
static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
|
static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
|
||||||
NPE_CHECK_RETURN_VOID(env, paint);
|
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) {
|
static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ static jlong Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
|
|||||||
|
|
||||||
SkRegion* region = new SkRegion;
|
SkRegion* region = new SkRegion;
|
||||||
size_t size = p->readInt32();
|
size_t size = p->readInt32();
|
||||||
region->readFromMemory(p->readInplace(size));
|
region->readFromMemory(p->readInplace(size), size);
|
||||||
|
|
||||||
return reinterpret_cast<jlong>(region);
|
return reinterpret_cast<jlong>(region);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "TextLayoutCache.h"
|
#include "TextLayoutCache.h"
|
||||||
#include "TextLayout.h"
|
#include "TextLayout.h"
|
||||||
|
#include "SkGlyphCache.h"
|
||||||
#include "SkTypeface_android.h"
|
#include "SkTypeface_android.h"
|
||||||
#include "HarfBuzzNGFaceSkia.h"
|
#include "HarfBuzzNGFaceSkia.h"
|
||||||
#include <unicode/unistr.h>
|
#include <unicode/unistr.h>
|
||||||
@@ -757,8 +758,8 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte
|
|||||||
outPos->add(ypos);
|
outPos->add(ypos);
|
||||||
totalAdvance += xAdvance;
|
totalAdvance += xAdvance;
|
||||||
|
|
||||||
// TODO: consider using glyph cache
|
SkAutoGlyphCache autoCache(mShapingPaint, NULL, NULL);
|
||||||
const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
|
const SkGlyph& metrics = autoCache.getCache()->getGlyphIDMetrics(glyphId);
|
||||||
outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
|
outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
|
||||||
xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
|
xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
|
#include "Utils.h"
|
||||||
#include <android_runtime/android_util_AssetManager.h>
|
#include <android_runtime/android_util_AssetManager.h>
|
||||||
#include <androidfw/AssetManager.h>
|
#include <androidfw/AssetManager.h>
|
||||||
|
|
||||||
@@ -77,65 +78,6 @@ static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
|
|||||||
return static_cast<jint>(face->style());
|
return static_cast<jint>(face->style());
|
||||||
}
|
}
|
||||||
|
|
||||||
class AssetStream : public SkStream {
|
|
||||||
public:
|
|
||||||
AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset)
|
|
||||||
{
|
|
||||||
fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~AssetStream()
|
|
||||||
{
|
|
||||||
delete fAsset;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const void* getMemoryBase()
|
|
||||||
{
|
|
||||||
return fMemoryBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool rewind()
|
|
||||||
{
|
|
||||||
off64_t pos = fAsset->seek(0, SEEK_SET);
|
|
||||||
return pos != (off64_t)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual size_t read(void* buffer, size_t size)
|
|
||||||
{
|
|
||||||
ssize_t amount;
|
|
||||||
|
|
||||||
if (NULL == buffer)
|
|
||||||
{
|
|
||||||
if (0 == size) // caller is asking us for our total length
|
|
||||||
return fAsset->getLength();
|
|
||||||
|
|
||||||
// asset->seek returns new total offset
|
|
||||||
// we want to return amount that was skipped
|
|
||||||
|
|
||||||
off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
|
|
||||||
if (-1 == oldOffset)
|
|
||||||
return 0;
|
|
||||||
off64_t newOffset = fAsset->seek(size, SEEK_CUR);
|
|
||||||
if (-1 == newOffset)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
amount = newOffset - oldOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
amount = fAsset->read(buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amount < 0)
|
|
||||||
amount = 0;
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Asset* fAsset;
|
|
||||||
const void* fMemoryBase;
|
|
||||||
};
|
|
||||||
|
|
||||||
static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
|
static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
|
||||||
jobject jassetMgr,
|
jobject jassetMgr,
|
||||||
jstring jpath) {
|
jstring jpath) {
|
||||||
@@ -154,7 +96,9 @@ static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkStream* stream = new AssetStream(asset, true);
|
SkStream* stream = new AssetStreamAdaptor(asset,
|
||||||
|
AssetStreamAdaptor::kYes_OwnAsset,
|
||||||
|
AssetStreamAdaptor::kYes_HasMemoryBase);
|
||||||
SkTypeface* face = SkTypeface::CreateFromStream(stream);
|
SkTypeface* face = SkTypeface::CreateFromStream(stream);
|
||||||
// SkTypeFace::CreateFromStream calls ref() on the stream, so we
|
// SkTypeFace::CreateFromStream calls ref() on the stream, so we
|
||||||
// need to unref it here or it won't be freed later on
|
// need to unref it here or it won't be freed later on
|
||||||
|
|||||||
@@ -19,6 +19,21 @@
|
|||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
|
|
||||||
|
AssetStreamAdaptor::AssetStreamAdaptor(Asset* asset, OwnAsset ownAsset,
|
||||||
|
HasMemoryBase hasMemoryBase)
|
||||||
|
: fAsset(asset)
|
||||||
|
, fMemoryBase(kYes_HasMemoryBase == hasMemoryBase ?
|
||||||
|
asset->getBuffer(false) : NULL)
|
||||||
|
, fOwnAsset(ownAsset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetStreamAdaptor::~AssetStreamAdaptor() {
|
||||||
|
if (kYes_OwnAsset == fOwnAsset) {
|
||||||
|
delete fAsset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AssetStreamAdaptor::rewind() {
|
bool AssetStreamAdaptor::rewind() {
|
||||||
off64_t pos = fAsset->seek(0, SEEK_SET);
|
off64_t pos = fAsset->seek(0, SEEK_SET);
|
||||||
if (pos == (off64_t)-1) {
|
if (pos == (off64_t)-1) {
|
||||||
|
|||||||
@@ -28,16 +28,36 @@ namespace android {
|
|||||||
|
|
||||||
class AssetStreamAdaptor : public SkStreamRewindable {
|
class AssetStreamAdaptor : public SkStreamRewindable {
|
||||||
public:
|
public:
|
||||||
AssetStreamAdaptor(Asset* a) : fAsset(a) {}
|
// Enum passed to constructor. If set to kYes_OwnAsset,
|
||||||
|
// the passed in Asset will be deleted upon destruction.
|
||||||
|
enum OwnAsset {
|
||||||
|
kYes_OwnAsset,
|
||||||
|
kNo_OwnAsset,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enum passed to constructor. If set to kYes_HasMemoryBase,
|
||||||
|
// getMemoryBase will return the Asset's buffer.
|
||||||
|
enum HasMemoryBase {
|
||||||
|
kYes_HasMemoryBase,
|
||||||
|
kNo_HasMemoryBase,
|
||||||
|
};
|
||||||
|
|
||||||
|
AssetStreamAdaptor(Asset*, OwnAsset, HasMemoryBase);
|
||||||
|
~AssetStreamAdaptor();
|
||||||
|
|
||||||
virtual bool rewind();
|
virtual bool rewind();
|
||||||
virtual size_t read(void* buffer, size_t size);
|
virtual size_t read(void* buffer, size_t size);
|
||||||
virtual bool hasLength() const { return true; }
|
virtual bool hasLength() const { return true; }
|
||||||
virtual size_t getLength() const;
|
virtual size_t getLength() const;
|
||||||
virtual bool isAtEnd() const;
|
virtual bool isAtEnd() const;
|
||||||
|
|
||||||
|
virtual const void* getMemoryBase() { return fMemoryBase; }
|
||||||
|
|
||||||
virtual SkStreamRewindable* duplicate() const;
|
virtual SkStreamRewindable* duplicate() const;
|
||||||
private:
|
private:
|
||||||
Asset* fAsset;
|
Asset* fAsset;
|
||||||
|
const void* const fMemoryBase;
|
||||||
|
const OwnAsset fOwnAsset;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ static jint util_getInternalFormat(JNIEnv *env, jclass clazz,
|
|||||||
SkBitmap const * nativeBitmap =
|
SkBitmap const * nativeBitmap =
|
||||||
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
||||||
const SkBitmap& bitmap(*nativeBitmap);
|
const SkBitmap& bitmap(*nativeBitmap);
|
||||||
SkBitmap::Config config = bitmap.getConfig();
|
SkBitmap::Config config = bitmap.config();
|
||||||
return getInternalFormat(config);
|
return getInternalFormat(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,7 +642,7 @@ static jint util_getType(JNIEnv *env, jclass clazz,
|
|||||||
SkBitmap const * nativeBitmap =
|
SkBitmap const * nativeBitmap =
|
||||||
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
||||||
const SkBitmap& bitmap(*nativeBitmap);
|
const SkBitmap& bitmap(*nativeBitmap);
|
||||||
SkBitmap::Config config = bitmap.getConfig();
|
SkBitmap::Config config = bitmap.config();
|
||||||
return getType(config);
|
return getType(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,7 +653,7 @@ static jint util_texImage2D(JNIEnv *env, jclass clazz,
|
|||||||
SkBitmap const * nativeBitmap =
|
SkBitmap const * nativeBitmap =
|
||||||
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
||||||
const SkBitmap& bitmap(*nativeBitmap);
|
const SkBitmap& bitmap(*nativeBitmap);
|
||||||
SkBitmap::Config config = bitmap.getConfig();
|
SkBitmap::Config config = bitmap.config();
|
||||||
if (internalformat < 0) {
|
if (internalformat < 0) {
|
||||||
internalformat = getInternalFormat(config);
|
internalformat = getInternalFormat(config);
|
||||||
}
|
}
|
||||||
@@ -681,7 +681,7 @@ static jint util_texImage2D(JNIEnv *env, jclass clazz,
|
|||||||
SkColorTable* ctable = bitmap.getColorTable();
|
SkColorTable* ctable = bitmap.getColorTable();
|
||||||
memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
|
memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
|
||||||
memcpy(pixels, p, size);
|
memcpy(pixels, p, size);
|
||||||
ctable->unlockColors(false);
|
ctable->unlockColors();
|
||||||
glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
|
glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
|
||||||
free(data);
|
free(data);
|
||||||
} else {
|
} else {
|
||||||
@@ -702,7 +702,7 @@ static jint util_texSubImage2D(JNIEnv *env, jclass clazz,
|
|||||||
SkBitmap const * nativeBitmap =
|
SkBitmap const * nativeBitmap =
|
||||||
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
(SkBitmap const *)env->GetLongField(jbitmap, nativeBitmapID);
|
||||||
const SkBitmap& bitmap(*nativeBitmap);
|
const SkBitmap& bitmap(*nativeBitmap);
|
||||||
SkBitmap::Config config = bitmap.getConfig();
|
SkBitmap::Config config = bitmap.config();
|
||||||
if (format < 0) {
|
if (format < 0) {
|
||||||
format = getInternalFormat(config);
|
format = getInternalFormat(config);
|
||||||
if (format == GL_PALETTE8_RGBA8_OES)
|
if (format == GL_PALETTE8_RGBA8_OES)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <SkCanvas.h>
|
#include <SkCanvas.h>
|
||||||
#include <SkBitmap.h>
|
#include <SkBitmap.h>
|
||||||
|
#include <SkImage.h>
|
||||||
#include <SkRegion.h>
|
#include <SkRegion.h>
|
||||||
|
|
||||||
#include <utils/misc.h>
|
#include <utils/misc.h>
|
||||||
@@ -179,7 +180,8 @@ static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jlong n
|
|||||||
static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
|
static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
|
||||||
/* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
|
/* 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
|
we can map to SkBitmap::kARGB_8888_Config, and optionally call
|
||||||
bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
|
bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap
|
||||||
|
(as an accelerator)
|
||||||
*/
|
*/
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
|
case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
|
||||||
@@ -235,7 +237,7 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
|
|||||||
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
|
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
|
||||||
bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr);
|
bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr);
|
||||||
if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
|
if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
|
||||||
bitmap.setIsOpaque(true);
|
bitmap.setAlphaType(kOpaque_SkAlphaType);
|
||||||
}
|
}
|
||||||
if (outBuffer.width > 0 && outBuffer.height > 0) {
|
if (outBuffer.width > 0 && outBuffer.height > 0) {
|
||||||
bitmap.setPixels(outBuffer.bits);
|
bitmap.setPixels(outBuffer.bits);
|
||||||
|
|||||||
@@ -61,51 +61,21 @@ static struct {
|
|||||||
|
|
||||||
class ScreenshotPixelRef : public SkPixelRef {
|
class ScreenshotPixelRef : public SkPixelRef {
|
||||||
public:
|
public:
|
||||||
ScreenshotPixelRef(SkColorTable* ctable) {
|
ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) :
|
||||||
fCTable = ctable;
|
SkPixelRef(info),
|
||||||
SkSafeRef(ctable);
|
mScreenshot(screenshot) {
|
||||||
setImmutable();
|
setImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~ScreenshotPixelRef() {
|
virtual ~ScreenshotPixelRef() {
|
||||||
SkSafeUnref(fCTable);
|
delete mScreenshot;
|
||||||
}
|
|
||||||
|
|
||||||
status_t update(const sp<IBinder>& display, int width, int height,
|
|
||||||
int minLayer, int maxLayer, bool allLayers) {
|
|
||||||
status_t res = (width > 0 && height > 0)
|
|
||||||
? (allLayers
|
|
||||||
? mScreenshot.update(display, width, height)
|
|
||||||
: mScreenshot.update(display, width, height, minLayer, maxLayer))
|
|
||||||
: mScreenshot.update(display);
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// overrides from SkPixelRef
|
// overrides from SkPixelRef
|
||||||
virtual void* onLockPixels(SkColorTable** ct) {
|
virtual void* onLockPixels(SkColorTable** ct) {
|
||||||
*ct = fCTable;
|
*ct = NULL;
|
||||||
return (void*)mScreenshot.getPixels();
|
return (void*)mScreenshot->getPixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onUnlockPixels() {
|
virtual void onUnlockPixels() {
|
||||||
@@ -113,8 +83,7 @@ protected:
|
|||||||
|
|
||||||
SK_DECLARE_UNFLATTENABLE_OBJECT()
|
SK_DECLARE_UNFLATTENABLE_OBJECT()
|
||||||
private:
|
private:
|
||||||
ScreenshotClient mScreenshot;
|
ScreenshotClient* mScreenshot;
|
||||||
SkColorTable* fCTable;
|
|
||||||
|
|
||||||
typedef SkPixelRef INHERITED;
|
typedef SkPixelRef INHERITED;
|
||||||
};
|
};
|
||||||
@@ -147,19 +116,6 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
|
|||||||
ctrl->decStrong((void *)nativeCreate);
|
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.setIsOpaque(true) 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,
|
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
|
||||||
jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
|
jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
|
||||||
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
|
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
|
||||||
@@ -167,26 +123,50 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
|
ScreenshotClient* screenshot = new ScreenshotClient();
|
||||||
if (pixels->update(displayToken, width, height,
|
status_t res = (width > 0 && height > 0)
|
||||||
minLayer, maxLayer, allLayers) != NO_ERROR) {
|
? (allLayers
|
||||||
delete pixels;
|
? screenshot->update(displayToken, width, height)
|
||||||
|
: screenshot->update(displayToken, width, height, minLayer, maxLayer))
|
||||||
|
: screenshot->update(displayToken);
|
||||||
|
if (res != NO_ERROR) {
|
||||||
|
delete screenshot;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t w = pixels->getWidth();
|
SkImageInfo screenshotInfo;
|
||||||
uint32_t h = pixels->getHeight();
|
screenshotInfo.fWidth = screenshot->getWidth();
|
||||||
uint32_t s = pixels->getStride();
|
screenshotInfo.fHeight = screenshot->getHeight();
|
||||||
uint32_t f = pixels->getFormat();
|
|
||||||
ssize_t bpr = s * android::bytesPerPixel(f);
|
|
||||||
|
|
||||||
SkBitmap* bitmap = new SkBitmap();
|
switch (screenshot->getFormat()) {
|
||||||
bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
|
case PIXEL_FORMAT_RGBX_8888: {
|
||||||
if (f == PIXEL_FORMAT_RGBX_8888) {
|
screenshotInfo.fColorType = kRGBA_8888_SkColorType;
|
||||||
bitmap->setIsOpaque(true);
|
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);
|
||||||
|
ssize_t rowBytes = screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
|
||||||
|
|
||||||
|
SkBitmap* bitmap = new SkBitmap();
|
||||||
|
bitmap->setConfig(screenshotInfo, rowBytes);
|
||||||
|
if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
|
||||||
bitmap->setPixelRef(pixels)->unref();
|
bitmap->setPixelRef(pixels)->unref();
|
||||||
bitmap->lockPixels();
|
bitmap->lockPixels();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <SkBitmap.h>
|
#include <SkBitmap.h>
|
||||||
#include <SkCanvas.h>
|
#include <SkCanvas.h>
|
||||||
|
#include <SkImage.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@ static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
|
|||||||
bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount);
|
bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount);
|
||||||
|
|
||||||
if (buffer.format == WINDOW_FORMAT_RGBX_8888) {
|
if (buffer.format == WINDOW_FORMAT_RGBX_8888) {
|
||||||
bitmap.setIsOpaque(true);
|
bitmap.setAlphaType(kOpaque_SkAlphaType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer.width > 0 && buffer.height > 0) {
|
if (buffer.width > 0 && buffer.height > 0) {
|
||||||
|
|||||||
@@ -67,6 +67,16 @@ public final class Bitmap implements Parcelable {
|
|||||||
* setPremultiplied() aren't order dependent, despite being setters.
|
* setPremultiplied() aren't order dependent, despite being setters.
|
||||||
*/
|
*/
|
||||||
private boolean mIsPremultiplied;
|
private boolean mIsPremultiplied;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Bitmap's content is expected to have alpha. Note that hasAlpha()
|
||||||
|
* does not directly return this value, because hasAlpha() may never return true
|
||||||
|
* for a 565 Bitmap.
|
||||||
|
*
|
||||||
|
* Any time this or mIsPremultiplied is changed, both are passed to native so they
|
||||||
|
* are not order dependent.
|
||||||
|
*/
|
||||||
|
private boolean mHasAlpha;
|
||||||
private byte[] mNinePatchChunk; // may be null
|
private byte[] mNinePatchChunk; // may be null
|
||||||
private int[] mLayoutBounds; // may be null
|
private int[] mLayoutBounds; // may be null
|
||||||
private int mWidth;
|
private int mWidth;
|
||||||
@@ -390,7 +400,7 @@ public final class Bitmap implements Parcelable {
|
|||||||
* No color information is stored.
|
* No color information is stored.
|
||||||
* With this configuration, each pixel requires 1 byte of memory.
|
* 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
|
* Each pixel is stored on 2 bytes and only the RGB channels are
|
||||||
@@ -406,7 +416,7 @@ public final class Bitmap implements Parcelable {
|
|||||||
* This configuration may be useful when using opaque bitmaps
|
* This configuration may be useful when using opaque bitmaps
|
||||||
* that do not require high color fidelity.
|
* 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
|
* Each pixel is stored on 2 bytes. The three RGB color channels
|
||||||
@@ -428,7 +438,7 @@ public final class Bitmap implements Parcelable {
|
|||||||
* it is advised to use {@link #ARGB_8888} instead.
|
* it is advised to use {@link #ARGB_8888} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
ARGB_4444 (5),
|
ARGB_4444 (4),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each pixel is stored on 4 bytes. Each channel (RGB and alpha
|
* Each pixel is stored on 4 bytes. Each channel (RGB and alpha
|
||||||
@@ -438,13 +448,13 @@ public final class Bitmap implements Parcelable {
|
|||||||
* This configuration is very flexible and offers the best
|
* This configuration is very flexible and offers the best
|
||||||
* quality. It should be used whenever possible.
|
* quality. It should be used whenever possible.
|
||||||
*/
|
*/
|
||||||
ARGB_8888 (6);
|
ARGB_8888 (5);
|
||||||
|
|
||||||
final int nativeInt;
|
final int nativeInt;
|
||||||
|
|
||||||
@SuppressWarnings({"deprecation"})
|
@SuppressWarnings({"deprecation"})
|
||||||
private static Config sConfigs[] = {
|
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) {
|
Config(int ni) {
|
||||||
@@ -554,7 +564,7 @@ public final class Bitmap implements Parcelable {
|
|||||||
checkRecycled("Can't copy a recycled bitmap");
|
checkRecycled("Can't copy a recycled bitmap");
|
||||||
Bitmap b = nativeCopy(mNativeBitmap, config.nativeInt, isMutable);
|
Bitmap b = nativeCopy(mNativeBitmap, config.nativeInt, isMutable);
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
b.mIsPremultiplied = mIsPremultiplied;
|
b.setAlphaAndPremultiplied(mHasAlpha, mIsPremultiplied);
|
||||||
b.mDensity = mDensity;
|
b.mDensity = mDensity;
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
@@ -727,12 +737,12 @@ public final class Bitmap implements Parcelable {
|
|||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The new bitmap was created from a known bitmap source so assume that
|
// The new bitmap was created from a known bitmap source so assume that
|
||||||
// they use the same density
|
// they use the same density
|
||||||
bitmap.mDensity = source.mDensity;
|
bitmap.mDensity = source.mDensity;
|
||||||
bitmap.mIsPremultiplied = source.mIsPremultiplied;
|
bitmap.setAlphaAndPremultiplied(source.mHasAlpha, source.mIsPremultiplied);
|
||||||
|
|
||||||
canvas.setBitmap(bitmap);
|
canvas.setBitmap(bitmap);
|
||||||
canvas.drawBitmap(source, srcR, dstR, paint);
|
canvas.drawBitmap(source, srcR, dstR, paint);
|
||||||
canvas.setBitmap(null);
|
canvas.setBitmap(null);
|
||||||
@@ -810,9 +820,9 @@ public final class Bitmap implements Parcelable {
|
|||||||
if (display != null) {
|
if (display != null) {
|
||||||
bm.mDensity = display.densityDpi;
|
bm.mDensity = display.densityDpi;
|
||||||
}
|
}
|
||||||
|
bm.setHasAlpha(hasAlpha);
|
||||||
if (config == Config.ARGB_8888 && !hasAlpha) {
|
if (config == Config.ARGB_8888 && !hasAlpha) {
|
||||||
nativeErase(bm.mNativeBitmap, 0xff000000);
|
nativeErase(bm.mNativeBitmap, 0xff000000);
|
||||||
nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha);
|
|
||||||
}
|
}
|
||||||
// No need to initialize the bitmap to zeroes with other configs;
|
// No need to initialize the bitmap to zeroes with other configs;
|
||||||
// it is backed by a VM byte array which is by definition preinitialized
|
// it is backed by a VM byte array which is by definition preinitialized
|
||||||
@@ -884,6 +894,7 @@ public final class Bitmap implements Parcelable {
|
|||||||
if (display != null) {
|
if (display != null) {
|
||||||
bm.mDensity = display.densityDpi;
|
bm.mDensity = display.densityDpi;
|
||||||
}
|
}
|
||||||
|
bm.mHasAlpha = true;
|
||||||
return bm;
|
return bm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,11 +1052,24 @@ public final class Bitmap implements Parcelable {
|
|||||||
* <p>This method will not affect the behavior of a bitmap without an alpha
|
* <p>This method will not affect the behavior of a bitmap without an alpha
|
||||||
* channel, or if {@link #hasAlpha()} returns false.</p>
|
* channel, or if {@link #hasAlpha()} returns false.</p>
|
||||||
*
|
*
|
||||||
|
* <p>Calling {@link createBitmap()} or {@link createScaledBitmap()} with a source
|
||||||
|
* Bitmap whose colors are not pre-multiplied may result in a RuntimeException,
|
||||||
|
* since those functions require drawing the source, which is not supported for
|
||||||
|
* un-pre-multiplied Bitmaps.</p>
|
||||||
|
*
|
||||||
* @see Bitmap#isPremultiplied()
|
* @see Bitmap#isPremultiplied()
|
||||||
* @see BitmapFactory.Options#inPremultiplied
|
* @see BitmapFactory.Options#inPremultiplied
|
||||||
*/
|
*/
|
||||||
public final void setPremultiplied(boolean premultiplied) {
|
public final void setPremultiplied(boolean premultiplied) {
|
||||||
mIsPremultiplied = premultiplied;
|
mIsPremultiplied = premultiplied;
|
||||||
|
nativeSetAlphaAndPremultiplied(mNativeBitmap, mHasAlpha, premultiplied);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper function to set both alpha and premultiplied. **/
|
||||||
|
private final void setAlphaAndPremultiplied(boolean hasAlpha, boolean premultiplied) {
|
||||||
|
mHasAlpha = hasAlpha;
|
||||||
|
mIsPremultiplied = premultiplied;
|
||||||
|
nativeSetAlphaAndPremultiplied(mNativeBitmap, hasAlpha, premultiplied);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the bitmap's width */
|
/** Returns the bitmap's width */
|
||||||
@@ -1206,7 +1230,8 @@ public final class Bitmap implements Parcelable {
|
|||||||
* non-opaque per-pixel alpha values.
|
* non-opaque per-pixel alpha values.
|
||||||
*/
|
*/
|
||||||
public void setHasAlpha(boolean hasAlpha) {
|
public void setHasAlpha(boolean hasAlpha) {
|
||||||
nativeSetHasAlpha(mNativeBitmap, hasAlpha);
|
mHasAlpha = hasAlpha;
|
||||||
|
nativeSetAlphaAndPremultiplied(mNativeBitmap, hasAlpha, mIsPremultiplied);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1611,7 +1636,8 @@ public final class Bitmap implements Parcelable {
|
|||||||
|
|
||||||
private static native void nativePrepareToDraw(long nativeBitmap);
|
private static native void nativePrepareToDraw(long nativeBitmap);
|
||||||
private static native boolean nativeHasAlpha(long nativeBitmap);
|
private static native boolean nativeHasAlpha(long nativeBitmap);
|
||||||
private static native void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha);
|
private static native void nativeSetAlphaAndPremultiplied(long nBitmap, boolean hasAlpha,
|
||||||
|
boolean isPremul);
|
||||||
private static native boolean nativeHasMipMap(long nativeBitmap);
|
private static native boolean nativeHasMipMap(long nativeBitmap);
|
||||||
private static native void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap);
|
private static native void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap);
|
||||||
private static native boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1);
|
private static native boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1);
|
||||||
|
|||||||
@@ -153,8 +153,12 @@ public class BitmapFactory {
|
|||||||
*
|
*
|
||||||
* <p>This does not affect bitmaps without an alpha channel.</p>
|
* <p>This does not affect bitmaps without an alpha channel.</p>
|
||||||
*
|
*
|
||||||
|
* <p>Setting this flag to false while setting {@link #inScaled} to true
|
||||||
|
* may result in incorrect colors.</p>
|
||||||
|
*
|
||||||
* @see Bitmap#hasAlpha()
|
* @see Bitmap#hasAlpha()
|
||||||
* @see Bitmap#isPremultiplied()
|
* @see Bitmap#isPremultiplied()
|
||||||
|
* @see #inScaled
|
||||||
*/
|
*/
|
||||||
public boolean inPremultiplied;
|
public boolean inPremultiplied;
|
||||||
|
|
||||||
@@ -249,6 +253,9 @@ public class BitmapFactory {
|
|||||||
* <p>This flag is turned on by default and should be turned off if you need
|
* <p>This flag is turned on by default and should be turned off if you need
|
||||||
* a non-scaled version of the bitmap. Nine-patch bitmaps ignore this
|
* a non-scaled version of the bitmap. Nine-patch bitmaps ignore this
|
||||||
* flag and are always scaled.
|
* flag and are always scaled.
|
||||||
|
*
|
||||||
|
* <p>If {@link #inPremultiplied} is set to false, and the image has alpha,
|
||||||
|
* setting this flag to true may result in incorrect colors.
|
||||||
*/
|
*/
|
||||||
public boolean inScaled;
|
public boolean inScaled;
|
||||||
|
|
||||||
|
|||||||
@@ -287,10 +287,9 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
|
|||||||
void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
|
void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
|
||||||
uint32_t width, uint32_t height) {
|
uint32_t width, uint32_t height) {
|
||||||
SkBitmap rgbaBitmap;
|
SkBitmap rgbaBitmap;
|
||||||
rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
|
rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0, bitmap->alphaType());
|
||||||
rgbaBitmap.allocPixels();
|
rgbaBitmap.allocPixels();
|
||||||
rgbaBitmap.eraseColor(0);
|
rgbaBitmap.eraseColor(0);
|
||||||
rgbaBitmap.setIsOpaque(bitmap->isOpaque());
|
|
||||||
|
|
||||||
SkCanvas canvas(rgbaBitmap);
|
SkCanvas canvas(rgbaBitmap);
|
||||||
canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);
|
canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <utils/Trace.h>
|
#include <utils/Trace.h>
|
||||||
|
|
||||||
#include <SkGlyph.h>
|
#include <SkGlyph.h>
|
||||||
|
#include <SkGlyphCache.h>
|
||||||
#include <SkUtils.h>
|
#include <SkUtils.h>
|
||||||
|
|
||||||
#include "FontUtil.h"
|
#include "FontUtil.h"
|
||||||
@@ -271,9 +272,9 @@ CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool pre
|
|||||||
if (cachedGlyph) {
|
if (cachedGlyph) {
|
||||||
// Is the glyph still in texture cache?
|
// Is the glyph still in texture cache?
|
||||||
if (!cachedGlyph->mIsValid) {
|
if (!cachedGlyph->mIsValid) {
|
||||||
const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit,
|
SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
|
||||||
&mDescription.mLookupTransform);
|
const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit);
|
||||||
updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
|
updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), cachedGlyph, precaching);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cachedGlyph = cacheGlyph(paint, textUnit, precaching);
|
cachedGlyph = cacheGlyph(paint, textUnit, precaching);
|
||||||
@@ -415,8 +416,8 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
|
void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
|
||||||
bool precaching) {
|
CachedGlyphInfo* glyph, bool precaching) {
|
||||||
glyph->mAdvanceX = skiaGlyph.fAdvanceX;
|
glyph->mAdvanceX = skiaGlyph.fAdvanceX;
|
||||||
glyph->mAdvanceY = skiaGlyph.fAdvanceY;
|
glyph->mAdvanceY = skiaGlyph.fAdvanceY;
|
||||||
glyph->mBitmapLeft = skiaGlyph.fLeft;
|
glyph->mBitmapLeft = skiaGlyph.fLeft;
|
||||||
@@ -429,7 +430,7 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
|
|||||||
|
|
||||||
// Get the bitmap for the glyph
|
// Get the bitmap for the glyph
|
||||||
if (!skiaGlyph.fImage) {
|
if (!skiaGlyph.fImage) {
|
||||||
paint->findImage(skiaGlyph, &mDescription.mLookupTransform);
|
skiaGlyphCache->findImage(skiaGlyph);
|
||||||
}
|
}
|
||||||
mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
|
mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
|
||||||
|
|
||||||
@@ -463,11 +464,12 @@ CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching
|
|||||||
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
|
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
|
||||||
mCachedGlyphs.add(glyph, newGlyph);
|
mCachedGlyphs.add(glyph, newGlyph);
|
||||||
|
|
||||||
const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph, &mDescription.mLookupTransform);
|
SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
|
||||||
|
const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph);
|
||||||
newGlyph->mIsValid = false;
|
newGlyph->mIsValid = false;
|
||||||
newGlyph->mGlyphIndex = skiaGlyph.fID;
|
newGlyph->mGlyphIndex = skiaGlyph.fID;
|
||||||
|
|
||||||
updateGlyphCache(paint, skiaGlyph, newGlyph, precaching);
|
updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), newGlyph, precaching);
|
||||||
|
|
||||||
return newGlyph;
|
return newGlyph;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <utils/KeyedVector.h>
|
#include <utils/KeyedVector.h>
|
||||||
|
|
||||||
|
#include <SkGlyphCache.h>
|
||||||
#include <SkScalerContext.h>
|
#include <SkScalerContext.h>
|
||||||
#include <SkPaint.h>
|
#include <SkPaint.h>
|
||||||
#include <SkPathMeasure.h>
|
#include <SkPathMeasure.h>
|
||||||
@@ -117,8 +118,8 @@ private:
|
|||||||
void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
|
void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
|
||||||
|
|
||||||
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
|
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
|
||||||
void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
|
void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
|
||||||
bool precaching);
|
CachedGlyphInfo* glyph, bool precaching);
|
||||||
|
|
||||||
void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
|
void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
|
||||||
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
|
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
#if RENDER_TEXT_AS_GLYPHS
|
#if RENDER_TEXT_AS_GLYPHS
|
||||||
typedef uint16_t glyph_t;
|
typedef uint16_t glyph_t;
|
||||||
#define TO_GLYPH(g) g
|
#define TO_GLYPH(g) g
|
||||||
#define GET_METRICS(paint, glyph, matrix) paint->getGlyphMetrics(glyph, matrix)
|
#define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph)
|
||||||
#define GET_GLYPH(text) nextGlyph((const uint16_t**) &text)
|
#define GET_GLYPH(text) nextGlyph((const uint16_t**) &text)
|
||||||
#define IS_END_OF_STRING(glyph) false
|
#define IS_END_OF_STRING(glyph) false
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
#else
|
#else
|
||||||
typedef SkUnichar glyph_t;
|
typedef SkUnichar glyph_t;
|
||||||
#define TO_GLYPH(g) ((SkUnichar) g)
|
#define TO_GLYPH(g) ((SkUnichar) g)
|
||||||
#define GET_METRICS(paint, glyph, matrix) paint->getUnicharMetrics(glyph, matrix)
|
#define GET_METRICS(cache, glyph) cache->getUnicharMetrics(glyph)
|
||||||
#define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text)
|
#define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text)
|
||||||
#define IS_END_OF_STRING(glyph) glyph < 0
|
#define IS_END_OF_STRING(glyph) glyph < 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <media/stagefright/MetaData.h>
|
#include <media/stagefright/MetaData.h>
|
||||||
#include <media/stagefright/OMXClient.h>
|
#include <media/stagefright/OMXClient.h>
|
||||||
#include <media/stagefright/OMXCodec.h>
|
#include <media/stagefright/OMXCodec.h>
|
||||||
|
#include <SkImage.h>
|
||||||
#include <SkMallocPixelRef.h>
|
#include <SkMallocPixelRef.h>
|
||||||
|
|
||||||
#include "omx_jpeg_decoder.h"
|
#include "omx_jpeg_decoder.h"
|
||||||
@@ -184,8 +185,7 @@ void OmxJpegImageDecoder::installPixelRef(MediaBuffer *buffer, sp<MediaSource> d
|
|||||||
|
|
||||||
void OmxJpegImageDecoder::configBitmapSize(SkBitmap* bm, SkBitmap::Config pref,
|
void OmxJpegImageDecoder::configBitmapSize(SkBitmap* bm, SkBitmap::Config pref,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
bm->setConfig(getColorSpaceConfig(pref), width, height);
|
bm->setConfig(getColorSpaceConfig(pref), width, height, 0, kOpaque_SkAlphaType);
|
||||||
bm->setIsOpaque(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkBitmap::Config OmxJpegImageDecoder::getColorSpaceConfig(
|
SkBitmap::Config OmxJpegImageDecoder::getColorSpaceConfig(
|
||||||
|
|||||||
Reference in New Issue
Block a user