diff options
Diffstat (limited to 'core/jni')
27 files changed, 1004 insertions, 460 deletions
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index fb0d5d5..149d7bc 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -838,8 +838,8 @@ jstring AndroidRuntime::NewStringLatin1(JNIEnv* env, const char* bytes) { */ void AndroidRuntime::start(const char* className, const Vector<String8>& options) { - ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n", - className != NULL ? className : "(unknown)"); + ALOGD(">>>>>> START %s uid %d <<<<<<\n", + className != NULL ? className : "(unknown)", getuid()); static const String8 startSystemServer("start-system-server"); diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index fbc1b35..ceec0e3 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -19,7 +19,7 @@ #include <jni.h> -#include <Caches.h> +#include <ResourceCache.h> /////////////////////////////////////////////////////////////////////////////// // Conversions to/from SkColor, for get/setPixels, and the create method, which @@ -364,8 +364,8 @@ static jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); #ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().resourceCache.destructor(bitmap); + if (android::uirenderer::ResourceCache::hasInstance()) { + android::uirenderer::ResourceCache::getInstance().destructor(bitmap); return; } #endif // USE_OPENGL_RENDERER @@ -375,9 +375,9 @@ static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) { static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); #ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { + if (android::uirenderer::ResourceCache::hasInstance()) { bool result; - result = android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap); + result = android::uirenderer::ResourceCache::getInstance().recycle(bitmap); return result ? JNI_TRUE : JNI_FALSE; } #endif // USE_OPENGL_RENDERER diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 592559a..e346fc3 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -311,7 +311,8 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } SkBitmap decodingBitmap; - if (!decoder->decode(stream, &decodingBitmap, prefColorType, decodeMode)) { + if (decoder->decode(stream, &decodingBitmap, prefColorType, decodeMode) + != SkImageDecoder::kSuccess) { return nullObjectReturn("decoder->decode returned false"); } diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp index 1a3fa14..7937941 100644 --- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp +++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp @@ -77,6 +77,8 @@ private: env->ExceptionDescribe(); env->ExceptionClear(); SkDebugf("---- read threw an exception\n"); + // Consider the stream to be at the end, since there was an error. + fIsAtEnd = true; return 0; } @@ -91,6 +93,9 @@ private: env->ExceptionDescribe(); env->ExceptionClear(); SkDebugf("---- read:GetByteArrayRegion threw an exception\n"); + // The error was not with the stream itself, but consider it to be at the + // end, since we do not have a way to recover. + fIsAtEnd = true; return 0; } diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index d7b75db..a51af40 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -365,6 +365,9 @@ SkCanvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) { SkASSERT(canvas); SkASSERT(env->IsInstanceOf(canvas, gCanvas_class)); jlong canvasHandle = env->GetLongField(canvas, gCanvas_nativeInstanceID); + if (!canvasHandle) { + return NULL; + } SkCanvas* c = reinterpret_cast<android::Canvas*>(canvasHandle)->getSkCanvas(); SkASSERT(c); return c; @@ -489,19 +492,15 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* sto SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)), fWrappedPixelRef(NULL) { SkASSERT(storage); + SkASSERT(storageObj); SkASSERT(env); if (env->GetJavaVM(&fVM) != JNI_OK) { SkDebugf("------ [%p] env->GetJavaVM failed\n", env); sk_throw(); } - fStorageObj = storageObj; - fHasGlobalRef = false; - fGlobalRefCnt = 0; - - // If storageObj is NULL, the memory was NOT allocated on the Java heap - fOnJavaHeap = (storageObj != NULL); + fStorageObj = (jbyteArray) env->NewGlobalRef(storageObj); } AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, @@ -513,91 +512,18 @@ AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImage SkASSERT(fWrappedPixelRef); SkSafeRef(fWrappedPixelRef); - // don't need to initialize these, as all the relevant logic delegates to the wrapped ref + // don't need to initialize this, as all the relevant logic delegates to the wrapped ref fStorageObj = NULL; - fHasGlobalRef = false; - fGlobalRefCnt = 0; - fOnJavaHeap = false; } AndroidPixelRef::~AndroidPixelRef() { if (fWrappedPixelRef) { SkSafeUnref(fWrappedPixelRef); - } else if (fOnJavaHeap) { + } else { + SkASSERT(fStorageObj); JNIEnv* env = vm2env(fVM); - - if (fStorageObj && fHasGlobalRef) { - env->DeleteGlobalRef(fStorageObj); - } - fStorageObj = NULL; - } -} -jbyteArray AndroidPixelRef::getStorageObj() { - if (fWrappedPixelRef) { - return fWrappedPixelRef->fStorageObj; - } - return fStorageObj; -} - -void AndroidPixelRef::setLocalJNIRef(jbyteArray arr) { - if (fWrappedPixelRef) { - // delegate java obj management to the wrapped ref - fWrappedPixelRef->setLocalJNIRef(arr); - } else if (!fHasGlobalRef) { - fStorageObj = arr; - } -} - -void AndroidPixelRef::globalRef(void* localref) { - if (fWrappedPixelRef) { - // delegate java obj management to the wrapped ref - fWrappedPixelRef->globalRef(localref); - - // Note: we only ref and unref the wrapped AndroidPixelRef so that - // bitmap->pixelRef()->globalRef() and globalUnref() can be used in a pair, even if - // the bitmap has its underlying AndroidPixelRef swapped out/wrapped - return; - } - if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) { - JNIEnv *env = vm2env(fVM); - - // If JNI ref was passed, it is always used - if (localref) fStorageObj = (jbyteArray) localref; - - if (fStorageObj == NULL) { - SkDebugf("No valid local ref to create a JNI global ref\n"); - sk_throw(); - } - if (fHasGlobalRef) { - // This should never happen - SkDebugf("Already holding a JNI global ref"); - sk_throw(); - } - - fStorageObj = (jbyteArray) env->NewGlobalRef(fStorageObj); - // TODO: Check for failure here - fHasGlobalRef = true; - } - ref(); -} - -void AndroidPixelRef::globalUnref() { - if (fWrappedPixelRef) { - // delegate java obj management to the wrapped ref - fWrappedPixelRef->globalUnref(); - return; - } - if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) { - JNIEnv *env = vm2env(fVM); - if (!fHasGlobalRef) { - SkDebugf("We don't have a global ref!"); - sk_throw(); - } env->DeleteGlobalRef(fStorageObj); - fStorageObj = NULL; - fHasGlobalRef = false; } - unref(); } /////////////////////////////////////////////////////////////////////////////// @@ -654,25 +580,6 @@ bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) { //////////////////////////////////////////////////////////////////////////////// -JavaHeapBitmapRef::JavaHeapBitmapRef(JNIEnv* env, SkBitmap* nativeBitmap, jbyteArray buffer) { - fEnv = env; - fNativeBitmap = nativeBitmap; - fBuffer = buffer; - - // If the buffer is NULL, the backing memory wasn't allocated on the Java heap - if (fBuffer) { - ((AndroidPixelRef*) fNativeBitmap->pixelRef())->setLocalJNIRef(fBuffer); - } -} - -JavaHeapBitmapRef::~JavaHeapBitmapRef() { - if (fBuffer) { - ((AndroidPixelRef*) fNativeBitmap->pixelRef())->setLocalJNIRef(NULL); - } -} - -//////////////////////////////////////////////////////////////////////////////// - static jclass make_globalref(JNIEnv* env, const char classname[]) { jclass c = env->FindClass(classname); diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index 0ce6e49..a48b764 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -123,52 +123,11 @@ public: virtual ~AndroidPixelRef(); - jbyteArray getStorageObj(); - - void setLocalJNIRef(jbyteArray arr); - - /** Used to hold a ref to the pixels when the Java bitmap may be collected. - * If specified, 'localref' is a valid JNI local reference to the byte array - * containing the pixel data. - * - * 'localref' may only be NULL if setLocalJNIRef() was already called with - * a JNI local ref that is still valid. - */ - virtual void globalRef(void* localref=NULL); - - /** Release a ref that was acquired using globalRef(). */ - virtual void globalUnref(); - private: AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this JavaVM* fVM; - bool fOnJavaHeap; // If true, the memory was allocated on the Java heap - jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store - bool fHasGlobalRef; // If true, fStorageObj holds a JNI global ref - - mutable int32_t fGlobalRefCnt; -}; - -/** A helper class for accessing Java-heap-allocated bitmaps. - * This should be used when calling into a JNI method that retains a - * reference to the bitmap longer than the lifetime of the Java Bitmap. - * - * After creating an instance of this class, a call to - * AndroidPixelRef::globalRef() will allocate a JNI global reference - * to the backing buffer object. - */ -class JavaHeapBitmapRef { -public: - - JavaHeapBitmapRef(JNIEnv *env, SkBitmap* nativeBitmap, jbyteArray buffer); - ~JavaHeapBitmapRef(); - -private: - JNIEnv* fEnv; - SkBitmap* fNativeBitmap; - jbyteArray fBuffer; }; /** Allocator which allocates the backing buffer in the Java heap. diff --git a/core/jni/android/graphics/Matrix.cpp b/core/jni/android/graphics/Matrix.cpp index 43c1dc9..0ff7c78 100644 --- a/core/jni/android/graphics/Matrix.cpp +++ b/core/jni/android/graphics/Matrix.cpp @@ -308,46 +308,47 @@ public: static JNINativeMethod methods[] = { {"finalizer", "(J)V", (void*) SkMatrixGlue::finalizer}, {"native_create","(J)J", (void*) SkMatrixGlue::create}, - {"native_isIdentity","(J)Z", (void*) SkMatrixGlue::isIdentity}, - {"native_isAffine","(J)Z", (void*) SkMatrixGlue::isAffine}, - {"native_rectStaysRect","(J)Z", (void*) SkMatrixGlue::rectStaysRect}, - {"native_reset","(J)V", (void*) SkMatrixGlue::reset}, - {"native_set","(JJ)V", (void*) SkMatrixGlue::set}, - {"native_setTranslate","(JFF)V", (void*) SkMatrixGlue::setTranslate}, - {"native_setScale","(JFFFF)V", (void*) SkMatrixGlue::setScale__FFFF}, - {"native_setScale","(JFF)V", (void*) SkMatrixGlue::setScale__FF}, - {"native_setRotate","(JFFF)V", (void*) SkMatrixGlue::setRotate__FFF}, - {"native_setRotate","(JF)V", (void*) SkMatrixGlue::setRotate__F}, - {"native_setSinCos","(JFFFF)V", (void*) SkMatrixGlue::setSinCos__FFFF}, - {"native_setSinCos","(JFF)V", (void*) SkMatrixGlue::setSinCos__FF}, - {"native_setSkew","(JFFFF)V", (void*) SkMatrixGlue::setSkew__FFFF}, - {"native_setSkew","(JFF)V", (void*) SkMatrixGlue::setSkew__FF}, - {"native_setConcat","(JJJ)V", (void*) SkMatrixGlue::setConcat}, - {"native_preTranslate","(JFF)V", (void*) SkMatrixGlue::preTranslate}, - {"native_preScale","(JFFFF)V", (void*) SkMatrixGlue::preScale__FFFF}, - {"native_preScale","(JFF)V", (void*) SkMatrixGlue::preScale__FF}, - {"native_preRotate","(JFFF)V", (void*) SkMatrixGlue::preRotate__FFF}, - {"native_preRotate","(JF)V", (void*) SkMatrixGlue::preRotate__F}, - {"native_preSkew","(JFFFF)V", (void*) SkMatrixGlue::preSkew__FFFF}, - {"native_preSkew","(JFF)V", (void*) SkMatrixGlue::preSkew__FF}, - {"native_preConcat","(JJ)V", (void*) SkMatrixGlue::preConcat}, - {"native_postTranslate","(JFF)V", (void*) SkMatrixGlue::postTranslate}, - {"native_postScale","(JFFFF)V", (void*) SkMatrixGlue::postScale__FFFF}, - {"native_postScale","(JFF)V", (void*) SkMatrixGlue::postScale__FF}, - {"native_postRotate","(JFFF)V", (void*) SkMatrixGlue::postRotate__FFF}, - {"native_postRotate","(JF)V", (void*) SkMatrixGlue::postRotate__F}, - {"native_postSkew","(JFFFF)V", (void*) SkMatrixGlue::postSkew__FFFF}, - {"native_postSkew","(JFF)V", (void*) SkMatrixGlue::postSkew__FF}, - {"native_postConcat","(JJ)V", (void*) SkMatrixGlue::postConcat}, - {"native_setRectToRect","(JLandroid/graphics/RectF;Landroid/graphics/RectF;I)Z", (void*) SkMatrixGlue::setRectToRect}, - {"native_setPolyToPoly","(J[FI[FII)Z", (void*) SkMatrixGlue::setPolyToPoly}, - {"native_invert","(JJ)Z", (void*) SkMatrixGlue::invert}, - {"native_mapPoints","(J[FI[FIIZ)V", (void*) SkMatrixGlue::mapPoints}, - {"native_mapRect","(JLandroid/graphics/RectF;Landroid/graphics/RectF;)Z", (void*) SkMatrixGlue::mapRect__RectFRectF}, - {"native_mapRadius","(JF)F", (void*) SkMatrixGlue::mapRadius}, - {"native_getValues","(J[F)V", (void*) SkMatrixGlue::getValues}, - {"native_setValues","(J[F)V", (void*) SkMatrixGlue::setValues}, - {"native_equals", "(JJ)Z", (void*) SkMatrixGlue::equals} + + {"native_isIdentity","!(J)Z", (void*) SkMatrixGlue::isIdentity}, + {"native_isAffine","!(J)Z", (void*) SkMatrixGlue::isAffine}, + {"native_rectStaysRect","!(J)Z", (void*) SkMatrixGlue::rectStaysRect}, + {"native_reset","!(J)V", (void*) SkMatrixGlue::reset}, + {"native_set","!(JJ)V", (void*) SkMatrixGlue::set}, + {"native_setTranslate","!(JFF)V", (void*) SkMatrixGlue::setTranslate}, + {"native_setScale","!(JFFFF)V", (void*) SkMatrixGlue::setScale__FFFF}, + {"native_setScale","!(JFF)V", (void*) SkMatrixGlue::setScale__FF}, + {"native_setRotate","!(JFFF)V", (void*) SkMatrixGlue::setRotate__FFF}, + {"native_setRotate","!(JF)V", (void*) SkMatrixGlue::setRotate__F}, + {"native_setSinCos","!(JFFFF)V", (void*) SkMatrixGlue::setSinCos__FFFF}, + {"native_setSinCos","!(JFF)V", (void*) SkMatrixGlue::setSinCos__FF}, + {"native_setSkew","!(JFFFF)V", (void*) SkMatrixGlue::setSkew__FFFF}, + {"native_setSkew","!(JFF)V", (void*) SkMatrixGlue::setSkew__FF}, + {"native_setConcat","!(JJJ)V", (void*) SkMatrixGlue::setConcat}, + {"native_preTranslate","!(JFF)V", (void*) SkMatrixGlue::preTranslate}, + {"native_preScale","!(JFFFF)V", (void*) SkMatrixGlue::preScale__FFFF}, + {"native_preScale","!(JFF)V", (void*) SkMatrixGlue::preScale__FF}, + {"native_preRotate","!(JFFF)V", (void*) SkMatrixGlue::preRotate__FFF}, + {"native_preRotate","!(JF)V", (void*) SkMatrixGlue::preRotate__F}, + {"native_preSkew","!(JFFFF)V", (void*) SkMatrixGlue::preSkew__FFFF}, + {"native_preSkew","!(JFF)V", (void*) SkMatrixGlue::preSkew__FF}, + {"native_preConcat","!(JJ)V", (void*) SkMatrixGlue::preConcat}, + {"native_postTranslate","!(JFF)V", (void*) SkMatrixGlue::postTranslate}, + {"native_postScale","!(JFFFF)V", (void*) SkMatrixGlue::postScale__FFFF}, + {"native_postScale","!(JFF)V", (void*) SkMatrixGlue::postScale__FF}, + {"native_postRotate","!(JFFF)V", (void*) SkMatrixGlue::postRotate__FFF}, + {"native_postRotate","!(JF)V", (void*) SkMatrixGlue::postRotate__F}, + {"native_postSkew","!(JFFFF)V", (void*) SkMatrixGlue::postSkew__FFFF}, + {"native_postSkew","!(JFF)V", (void*) SkMatrixGlue::postSkew__FF}, + {"native_postConcat","!(JJ)V", (void*) SkMatrixGlue::postConcat}, + {"native_setRectToRect","!(JLandroid/graphics/RectF;Landroid/graphics/RectF;I)Z", (void*) SkMatrixGlue::setRectToRect}, + {"native_setPolyToPoly","!(J[FI[FII)Z", (void*) SkMatrixGlue::setPolyToPoly}, + {"native_invert","!(JJ)Z", (void*) SkMatrixGlue::invert}, + {"native_mapPoints","!(J[FI[FIIZ)V", (void*) SkMatrixGlue::mapPoints}, + {"native_mapRect","!(JLandroid/graphics/RectF;Landroid/graphics/RectF;)Z", (void*) SkMatrixGlue::mapRect__RectFRectF}, + {"native_mapRadius","!(JF)F", (void*) SkMatrixGlue::mapRadius}, + {"native_getValues","!(J[F)V", (void*) SkMatrixGlue::getValues}, + {"native_setValues","!(J[F)V", (void*) SkMatrixGlue::setValues}, + {"native_equals", "!(JJ)Z", (void*) SkMatrixGlue::equals} }; static jfieldID sNativeInstanceField; diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp index c7c5131..d868f28 100644 --- a/core/jni/android/graphics/NinePatch.cpp +++ b/core/jni/android/graphics/NinePatch.cpp @@ -21,7 +21,7 @@ #include <androidfw/ResourceTypes.h> #include <utils/Log.h> -#include <Caches.h> +#include <ResourceCache.h> #include "Paint.h" #include "Canvas.h" @@ -81,9 +81,9 @@ public: static void finalize(JNIEnv* env, jobject, jlong patchHandle) { int8_t* patch = reinterpret_cast<int8_t*>(patchHandle); #ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { + if (android::uirenderer::ResourceCache::hasInstance()) { Res_png_9patch* p = (Res_png_9patch*) patch; - android::uirenderer::Caches::getInstance().resourceCache.destructor(p); + android::uirenderer::ResourceCache::getInstance().destructor(p); return; } #endif // USE_OPENGL_RENDERER diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 8b5a730..2cd2db7 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -939,58 +939,60 @@ static JNINativeMethod methods[] = { {"finalizer", "(J)V", (void*) PaintGlue::finalizer}, {"native_init","()J", (void*) PaintGlue::init}, {"native_initWithPaint","(J)J", (void*) PaintGlue::initWithPaint}, - {"native_reset","(J)V", (void*) PaintGlue::reset}, - {"native_set","(JJ)V", (void*) PaintGlue::assign}, - {"getFlags","()I", (void*) PaintGlue::getFlags}, - {"setFlags","(I)V", (void*) PaintGlue::setFlags}, - {"getHinting","()I", (void*) PaintGlue::getHinting}, - {"setHinting","(I)V", (void*) PaintGlue::setHinting}, - {"setAntiAlias","(Z)V", (void*) PaintGlue::setAntiAlias}, - {"setSubpixelText","(Z)V", (void*) PaintGlue::setSubpixelText}, - {"setLinearText","(Z)V", (void*) PaintGlue::setLinearText}, - {"setUnderlineText","(Z)V", (void*) PaintGlue::setUnderlineText}, - {"setStrikeThruText","(Z)V", (void*) PaintGlue::setStrikeThruText}, - {"setFakeBoldText","(Z)V", (void*) PaintGlue::setFakeBoldText}, - {"setFilterBitmap","(Z)V", (void*) PaintGlue::setFilterBitmap}, - {"setDither","(Z)V", (void*) PaintGlue::setDither}, - {"native_getStyle","(J)I", (void*) PaintGlue::getStyle}, - {"native_setStyle","(JI)V", (void*) PaintGlue::setStyle}, - {"getColor","()I", (void*) PaintGlue::getColor}, - {"setColor","(I)V", (void*) PaintGlue::setColor}, - {"getAlpha","()I", (void*) PaintGlue::getAlpha}, - {"setAlpha","(I)V", (void*) PaintGlue::setAlpha}, - {"getStrokeWidth","()F", (void*) PaintGlue::getStrokeWidth}, - {"setStrokeWidth","(F)V", (void*) PaintGlue::setStrokeWidth}, - {"getStrokeMiter","()F", (void*) PaintGlue::getStrokeMiter}, - {"setStrokeMiter","(F)V", (void*) PaintGlue::setStrokeMiter}, - {"native_getStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap}, - {"native_setStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap}, - {"native_getStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin}, - {"native_setStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin}, - {"native_getFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath}, - {"native_setShader","(JJ)J", (void*) PaintGlue::setShader}, - {"native_setColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter}, - {"native_setXfermode","(JJ)J", (void*) PaintGlue::setXfermode}, - {"native_setPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect}, - {"native_setMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter}, - {"native_setTypeface","(JJ)J", (void*) PaintGlue::setTypeface}, - {"native_setRasterizer","(JJ)J", (void*) PaintGlue::setRasterizer}, - {"native_getTextAlign","(J)I", (void*) PaintGlue::getTextAlign}, - {"native_setTextAlign","(JI)V", (void*) PaintGlue::setTextAlign}, - {"native_setTextLocale","(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocale}, - {"isElegantTextHeight","()Z", (void*) PaintGlue::isElegantTextHeight}, - {"setElegantTextHeight","(Z)V", (void*) PaintGlue::setElegantTextHeight}, - {"getTextSize","()F", (void*) PaintGlue::getTextSize}, - {"setTextSize","(F)V", (void*) PaintGlue::setTextSize}, - {"getTextScaleX","()F", (void*) PaintGlue::getTextScaleX}, - {"setTextScaleX","(F)V", (void*) PaintGlue::setTextScaleX}, - {"getTextSkewX","()F", (void*) PaintGlue::getTextSkewX}, - {"setTextSkewX","(F)V", (void*) PaintGlue::setTextSkewX}, - {"native_getLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing}, - {"native_setLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing}, + + {"native_reset","!(J)V", (void*) PaintGlue::reset}, + {"native_set","!(JJ)V", (void*) PaintGlue::assign}, + {"getFlags","!()I", (void*) PaintGlue::getFlags}, + {"setFlags","!(I)V", (void*) PaintGlue::setFlags}, + {"getHinting","!()I", (void*) PaintGlue::getHinting}, + {"setHinting","!(I)V", (void*) PaintGlue::setHinting}, + {"setAntiAlias","!(Z)V", (void*) PaintGlue::setAntiAlias}, + {"setSubpixelText","!(Z)V", (void*) PaintGlue::setSubpixelText}, + {"setLinearText","!(Z)V", (void*) PaintGlue::setLinearText}, + {"setUnderlineText","!(Z)V", (void*) PaintGlue::setUnderlineText}, + {"setStrikeThruText","!(Z)V", (void*) PaintGlue::setStrikeThruText}, + {"setFakeBoldText","!(Z)V", (void*) PaintGlue::setFakeBoldText}, + {"setFilterBitmap","!(Z)V", (void*) PaintGlue::setFilterBitmap}, + {"setDither","!(Z)V", (void*) PaintGlue::setDither}, + {"native_getStyle","!(J)I", (void*) PaintGlue::getStyle}, + {"native_setStyle","!(JI)V", (void*) PaintGlue::setStyle}, + {"getColor","!()I", (void*) PaintGlue::getColor}, + {"setColor","!(I)V", (void*) PaintGlue::setColor}, + {"getAlpha","!()I", (void*) PaintGlue::getAlpha}, + {"setAlpha","!(I)V", (void*) PaintGlue::setAlpha}, + {"getStrokeWidth","!()F", (void*) PaintGlue::getStrokeWidth}, + {"setStrokeWidth","!(F)V", (void*) PaintGlue::setStrokeWidth}, + {"getStrokeMiter","!()F", (void*) PaintGlue::getStrokeMiter}, + {"setStrokeMiter","!(F)V", (void*) PaintGlue::setStrokeMiter}, + {"native_getStrokeCap","!(J)I", (void*) PaintGlue::getStrokeCap}, + {"native_setStrokeCap","!(JI)V", (void*) PaintGlue::setStrokeCap}, + {"native_getStrokeJoin","!(J)I", (void*) PaintGlue::getStrokeJoin}, + {"native_setStrokeJoin","!(JI)V", (void*) PaintGlue::setStrokeJoin}, + {"native_getFillPath","!(JJJ)Z", (void*) PaintGlue::getFillPath}, + {"native_setShader","!(JJ)J", (void*) PaintGlue::setShader}, + {"native_setColorFilter","!(JJ)J", (void*) PaintGlue::setColorFilter}, + {"native_setXfermode","!(JJ)J", (void*) PaintGlue::setXfermode}, + {"native_setPathEffect","!(JJ)J", (void*) PaintGlue::setPathEffect}, + {"native_setMaskFilter","!(JJ)J", (void*) PaintGlue::setMaskFilter}, + {"native_setTypeface","!(JJ)J", (void*) PaintGlue::setTypeface}, + {"native_setRasterizer","!(JJ)J", (void*) PaintGlue::setRasterizer}, + {"native_getTextAlign","!(J)I", (void*) PaintGlue::getTextAlign}, + {"native_setTextAlign","!(JI)V", (void*) PaintGlue::setTextAlign}, + {"native_setTextLocale","!(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocale}, + {"isElegantTextHeight","!()Z", (void*) PaintGlue::isElegantTextHeight}, + {"setElegantTextHeight","!(Z)V", (void*) PaintGlue::setElegantTextHeight}, + {"getTextSize","!()F", (void*) PaintGlue::getTextSize}, + {"setTextSize","!(F)V", (void*) PaintGlue::setTextSize}, + {"getTextScaleX","!()F", (void*) PaintGlue::getTextScaleX}, + {"setTextScaleX","!(F)V", (void*) PaintGlue::setTextScaleX}, + {"getTextSkewX","!()F", (void*) PaintGlue::getTextSkewX}, + {"setTextSkewX","!(F)V", (void*) PaintGlue::setTextSkewX}, + {"native_getLetterSpacing","!(J)F", (void*) PaintGlue::getLetterSpacing}, + {"native_setLetterSpacing","!(JF)V", (void*) PaintGlue::setLetterSpacing}, {"native_setFontFeatureSettings","(JLjava/lang/String;)V", (void*) PaintGlue::setFontFeatureSettings}, - {"ascent","()F", (void*) PaintGlue::ascent}, - {"descent","()F", (void*) PaintGlue::descent}, + {"ascent","!()F", (void*) PaintGlue::ascent}, + {"descent","!()F", (void*) PaintGlue::descent}, + {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)PaintGlue::getFontMetrics}, {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)PaintGlue::getFontMetricsInt}, {"native_measureText","([CIII)F", (void*) PaintGlue::measureText_CIII}, @@ -1014,8 +1016,9 @@ static JNINativeMethod methods[] = { (void*) PaintGlue::getStringBounds }, {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", (void*) PaintGlue::getCharArrayBounds }, - {"native_setShadowLayer", "(JFFFI)V", (void*)PaintGlue::setShadowLayer}, - {"native_hasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer} + + {"native_setShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, + {"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} }; int register_android_graphics_Paint(JNIEnv* env) { diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index ad46053..1e4eb75 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -27,7 +27,7 @@ #include "SkPath.h" #include "SkPathOps.h" -#include <Caches.h> +#include <ResourceCache.h> #include <vector> #include <map> @@ -39,8 +39,8 @@ public: static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) { SkPath* obj = reinterpret_cast<SkPath*>(objHandle); #ifdef USE_OPENGL_RENDERER - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().resourceCache.destructor(obj); + if (android::uirenderer::ResourceCache::hasInstance()) { + android::uirenderer::ResourceCache::getInstance().destructor(obj); return; } #endif diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index f06bd21..35d69fe 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -121,7 +121,7 @@ class JNISurfaceTextureContext : public GLConsumer::FrameAvailableListener public: JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); virtual ~JNISurfaceTextureContext(); - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); private: static JNIEnv* getJNIEnv(bool* needsDetach); @@ -177,7 +177,7 @@ JNISurfaceTextureContext::~JNISurfaceTextureContext() } } -void JNISurfaceTextureContext::onFrameAvailable() +void JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */) { bool needsDetach = false; JNIEnv* env = getJNIEnv(&needsDetach); diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp index a1196af..cb228f2 100644 --- a/core/jni/android/graphics/pdf/PdfEditor.cpp +++ b/core/jni/android/graphics/pdf/PdfEditor.cpp @@ -16,9 +16,17 @@ #include "jni.h" #include "JNIHelp.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" #include "fpdfview.h" #include "fpdfedit.h" #include "fpdfsave.h" +#include "fsdk_rendercontext.h" +#include "fpdf_transformpage.h" +#pragma GCC diagnostic pop + +#include "SkMatrix.h" #include <core_jni_helpers.h> #include <vector> @@ -29,6 +37,20 @@ namespace android { +enum PageBox {PAGE_BOX_MEDIA, PAGE_BOX_CROP}; + +static struct { + jfieldID x; + jfieldID y; +} gPointClassInfo; + +static struct { + jfieldID left; + jfieldID top; + jfieldID right; + jfieldID bottom; +} gRectClassInfo; + static Mutex sLock; static int sUnmatchedInitRequestCount = 0; @@ -72,8 +94,17 @@ static jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) { if (!document) { const long error = FPDF_GetLastError(); - jniThrowExceptionFmt(env, "java/io/IOException", - "cannot create document. Error: %ld", error); + switch (error) { + case FPDF_ERR_PASSWORD: + case FPDF_ERR_SECURITY: { + jniThrowExceptionFmt(env, "java/lang/SecurityException", + "cannot create document. Error: %ld", error); + } break; + default: { + jniThrowExceptionFmt(env, "java/io/IOException", + "cannot create document. Error: %ld", error); + } break; + } destroyLibraryIfNeeded(); return -1; } @@ -144,18 +175,201 @@ static void nativeWrite(JNIEnv* env, jclass thiz, jlong documentPtr, jint fd) { } } +static void nativeSetTransformAndClip(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + jlong transformPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + + CPDF_Page* page = (CPDF_Page*) FPDF_LoadPage(document, pageIndex); + if (!page) { + jniThrowException(env, "java/lang/IllegalStateException", + "cannot open page"); + return; + } + + double width = 0; + double height = 0; + + const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height); + if (!result) { + jniThrowException(env, "java/lang/IllegalStateException", + "cannot get page size"); + return; + } + + CFX_AffineMatrix matrix; + + SkMatrix* skTransform = reinterpret_cast<SkMatrix*>(transformPtr); + + SkScalar transformValues[6]; + skTransform->asAffine(transformValues); + + // PDF's coordinate system origin is left-bottom while in graphics it + // is the top-left. So, translate the PDF coordinates to ours. + matrix.Set(1, 0, 0, -1, 0, page->GetPageHeight()); + + // Apply the transformation what was created in our coordinates. + matrix.Concat(transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY], + transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY], + transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]); + + // Translate the result back to PDF coordinates. + matrix.Concat(1, 0, 0, -1, 0, page->GetPageHeight()); + + FS_MATRIX transform = {matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f}; + FS_RECTF clip = {(float) clipLeft, (float) clipTop, (float) clipRight, (float) clipBottom}; + + FPDFPage_TransFormWithClip(page, &transform, &clip); + + FPDF_ClosePage(page); +} + +static void nativeGetPageSize(JNIEnv* env, jclass thiz, jlong documentPtr, + jint pageIndex, jobject outSize) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + + FPDF_PAGE page = FPDF_LoadPage(document, pageIndex); + if (!page) { + jniThrowException(env, "java/lang/IllegalStateException", + "cannot open page"); + return; + } + + double width = 0; + double height = 0; + + const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height); + if (!result) { + jniThrowException(env, "java/lang/IllegalStateException", + "cannot get page size"); + return; + } + + env->SetIntField(outSize, gPointClassInfo.x, width); + env->SetIntField(outSize, gPointClassInfo.y, height); + + FPDF_ClosePage(page); +} + +static jboolean nativeScaleForPrinting(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDF_BOOL success = FPDF_VIEWERREF_GetPrintScaling(document); + return success ? JNI_TRUE : JNI_FALSE; +} + +static bool nativeGetPageBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + PageBox pageBox, jobject outBox) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + + FPDF_PAGE page = FPDF_LoadPage(document, pageIndex); + if (!page) { + jniThrowException(env, "java/lang/IllegalStateException", + "cannot open page"); + return false; + } + + float left; + float top; + float right; + float bottom; + + const FPDF_BOOL success = (pageBox == PAGE_BOX_MEDIA) + ? FPDFPage_GetMediaBox(page, &left, &top, &right, &bottom) + : FPDFPage_GetCropBox(page, &left, &top, &right, &bottom); + + FPDF_ClosePage(page); + + if (!success) { + return false; + } + + env->SetIntField(outBox, gRectClassInfo.left, (int) left); + env->SetIntField(outBox, gRectClassInfo.top, (int) top); + env->SetIntField(outBox, gRectClassInfo.right, (int) right); + env->SetIntField(outBox, gRectClassInfo.bottom, (int) bottom); + + return true; +} + +static jboolean nativeGetPageMediaBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + jobject outMediaBox) { + const bool success = nativeGetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_MEDIA, + outMediaBox); + return success ? JNI_TRUE : JNI_FALSE; +} + +static jboolean nativeGetPageCropBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + jobject outMediaBox) { + const bool success = nativeGetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_CROP, + outMediaBox); + return success ? JNI_TRUE : JNI_FALSE; +} + +static void nativeSetPageBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + PageBox pageBox, jobject box) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + + FPDF_PAGE page = FPDF_LoadPage(document, pageIndex); + if (!page) { + jniThrowException(env, "java/lang/IllegalStateException", + "cannot open page"); + return; + } + + const int left = env->GetIntField(box, gRectClassInfo.left); + const int top = env->GetIntField(box, gRectClassInfo.top); + const int right = env->GetIntField(box, gRectClassInfo.right); + const int bottom = env->GetIntField(box, gRectClassInfo.bottom); + + if (pageBox == PAGE_BOX_MEDIA) { + FPDFPage_SetMediaBox(page, left, top, right, bottom); + } else { + FPDFPage_SetCropBox(page, left, top, right, bottom); + } + + FPDF_ClosePage(page); +} + +static void nativeSetPageMediaBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + jobject mediaBox) { + nativeSetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_MEDIA, mediaBox); +} + +static void nativeSetPageCropBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex, + jobject mediaBox) { + nativeSetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_CROP, mediaBox); +} + static JNINativeMethod gPdfEditor_Methods[] = { {"nativeOpen", "(IJ)J", (void*) nativeOpen}, {"nativeClose", "(J)V", (void*) nativeClose}, {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount}, {"nativeRemovePage", "(JI)I", (void*) nativeRemovePage}, - {"nativeWrite", "(JI)V", (void*) nativeWrite} + {"nativeWrite", "(JI)V", (void*) nativeWrite}, + {"nativeSetTransformAndClip", "(JIJIIII)V", (void*) nativeSetTransformAndClip}, + {"nativeGetPageSize", "(JILandroid/graphics/Point;)V", (void*) nativeGetPageSize}, + {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting}, + {"nativeGetPageMediaBox", "(JILandroid/graphics/Rect;)Z", (void*) nativeGetPageMediaBox}, + {"nativeSetPageMediaBox", "(JILandroid/graphics/Rect;)V", (void*) nativeSetPageMediaBox}, + {"nativeGetPageCropBox", "(JILandroid/graphics/Rect;)Z", (void*) nativeGetPageCropBox}, + {"nativeSetPageCropBox", "(JILandroid/graphics/Rect;)V", (void*) nativeSetPageCropBox} }; int register_android_graphics_pdf_PdfEditor(JNIEnv* env) { - return android::RegisterMethodsOrDie( + const int result = RegisterMethodsOrDie( env, "android/graphics/pdf/PdfEditor", gPdfEditor_Methods, NELEM(gPdfEditor_Methods)); + + jclass pointClass = FindClassOrDie(env, "android/graphics/Point"); + gPointClassInfo.x = GetFieldIDOrDie(env, pointClass, "x", "I"); + gPointClassInfo.y = GetFieldIDOrDie(env, pointClass, "y", "I"); + + jclass rectClass = FindClassOrDie(env, "android/graphics/Rect"); + gRectClassInfo.left = GetFieldIDOrDie(env, rectClass, "left", "I"); + gRectClassInfo.top = GetFieldIDOrDie(env, rectClass, "top", "I"); + gRectClassInfo.right = GetFieldIDOrDie(env, rectClass, "right", "I"); + gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClass, "bottom", "I"); + + return result; }; }; diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp index bb729ea..ae23cb4 100644 --- a/core/jni/android/graphics/pdf/PdfRenderer.cpp +++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp @@ -86,8 +86,17 @@ static jlong nativeCreate(JNIEnv* env, jclass thiz, jint fd, jlong size) { if (!document) { const long error = FPDF_GetLastError(); - jniThrowExceptionFmt(env, "java/io/IOException", - "cannot create document. Error: %ld", error); + switch (error) { + case FPDF_ERR_PASSWORD: + case FPDF_ERR_SECURITY: { + jniThrowExceptionFmt(env, "java/lang/SecurityException", + "cannot create document. Error: %ld", error); + } break; + default: { + jniThrowExceptionFmt(env, "java/io/IOException", + "cannot create document. Error: %ld", error); + } break; + } destroyLibraryIfNeeded(); return -1; } diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 6f433c5..7a0f511 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -48,13 +48,20 @@ struct fields_t { jfieldID canDisableShutterSound; jfieldID face_rect; jfieldID face_score; + jfieldID face_id; + jfieldID face_left_eye; + jfieldID face_right_eye; + jfieldID face_mouth; jfieldID rect_left; jfieldID rect_top; jfieldID rect_right; jfieldID rect_bottom; + jfieldID point_x; + jfieldID point_y; jmethodID post_event; jmethodID rect_constructor; jmethodID face_constructor; + jmethodID point_constructor; }; static fields_t fields; @@ -88,6 +95,7 @@ private: sp<Camera> mCamera; // strong reference to native object jclass mFaceClass; // strong reference to Face class jclass mRectClass; // strong reference to Rect class + jclass mPointClass; // strong reference to Point class Mutex mLock; /* @@ -144,6 +152,9 @@ JNICameraContext::JNICameraContext(JNIEnv* env, jobject weak_this, jclass clazz, jclass rectClazz = env->FindClass("android/graphics/Rect"); mRectClass = (jclass) env->NewGlobalRef(rectClazz); + jclass pointClazz = env->FindClass("android/graphics/Point"); + mPointClass = (jclass) env->NewGlobalRef(pointClazz); + mManualBufferMode = false; mManualCameraCallbackSet = false; } @@ -170,6 +181,10 @@ void JNICameraContext::release() env->DeleteGlobalRef(mRectClass); mRectClass = NULL; } + if (mPointClass != NULL) { + env->DeleteGlobalRef(mPointClass); + mPointClass = NULL; + } clearCallbackBuffers_l(env); mCamera.clear(); } @@ -356,6 +371,33 @@ void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_m env->SetObjectField(face, fields.face_rect, rect); env->SetIntField(face, fields.face_score, metadata->faces[i].score); + bool optionalFields = metadata->faces[i].id != 0 + && metadata->faces[i].left_eye[0] != -2000 && metadata->faces[i].left_eye[1] != -2000 + && metadata->faces[i].right_eye[0] != -2000 && metadata->faces[i].right_eye[1] != -2000 + && metadata->faces[i].mouth[0] != -2000 && metadata->faces[i].mouth[1] != -2000; + if (optionalFields) { + int32_t id = metadata->faces[i].id; + env->SetIntField(face, fields.face_id, id); + + jobject leftEye = env->NewObject(mPointClass, fields.point_constructor); + env->SetIntField(leftEye, fields.point_x, metadata->faces[i].left_eye[0]); + env->SetIntField(leftEye, fields.point_y, metadata->faces[i].left_eye[1]); + env->SetObjectField(face, fields.face_left_eye, leftEye); + env->DeleteLocalRef(leftEye); + + jobject rightEye = env->NewObject(mPointClass, fields.point_constructor); + env->SetIntField(rightEye, fields.point_x, metadata->faces[i].right_eye[0]); + env->SetIntField(rightEye, fields.point_y, metadata->faces[i].right_eye[1]); + env->SetObjectField(face, fields.face_right_eye, rightEye); + env->DeleteLocalRef(rightEye); + + jobject mouth = env->NewObject(mPointClass, fields.point_constructor); + env->SetIntField(mouth, fields.point_x, metadata->faces[i].mouth[0]); + env->SetIntField(mouth, fields.point_y, metadata->faces[i].mouth[1]); + env->SetObjectField(face, fields.face_mouth, mouth); + env->DeleteLocalRef(mouth); + } + env->DeleteLocalRef(face); env->DeleteLocalRef(rect); } @@ -1011,11 +1053,17 @@ int register_android_hardware_Camera(JNIEnv *env) { "android/hardware/Camera$CameraInfo", "canDisableShutterSound", "Z", &fields.canDisableShutterSound }, { "android/hardware/Camera$Face", "rect", "Landroid/graphics/Rect;", &fields.face_rect }, + { "android/hardware/Camera$Face", "leftEye", "Landroid/graphics/Point;", &fields.face_left_eye}, + { "android/hardware/Camera$Face", "rightEye", "Landroid/graphics/Point;", &fields.face_right_eye}, + { "android/hardware/Camera$Face", "mouth", "Landroid/graphics/Point;", &fields.face_mouth}, { "android/hardware/Camera$Face", "score", "I", &fields.face_score }, + { "android/hardware/Camera$Face", "id", "I", &fields.face_id}, { "android/graphics/Rect", "left", "I", &fields.rect_left }, { "android/graphics/Rect", "top", "I", &fields.rect_top }, { "android/graphics/Rect", "right", "I", &fields.rect_right }, { "android/graphics/Rect", "bottom", "I", &fields.rect_bottom }, + { "android/graphics/Point", "x", "I", &fields.point_x}, + { "android/graphics/Point", "y", "I", &fields.point_y}, }; find_fields(env, fields_to_find, NELEM(fields_to_find)); @@ -1030,6 +1078,13 @@ int register_android_hardware_Camera(JNIEnv *env) clazz = FindClassOrDie(env, "android/hardware/Camera$Face"); fields.face_constructor = GetMethodIDOrDie(env, clazz, "<init>", "()V"); + clazz = env->FindClass("android/graphics/Point"); + fields.point_constructor = env->GetMethodID(clazz, "<init>", "()V"); + if (fields.point_constructor == NULL) { + ALOGE("Can't find android/graphics/Point()"); + return -1; + } + // Register native functions return RegisterMethodsOrDie(env, "android/hardware/Camera", camMethods, NELEM(camMethods)); } diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp index 90d1c42..28e5030 100644 --- a/core/jni/android_hardware_SoundTrigger.cpp +++ b/core/jni/android_hardware_SoundTrigger.cpp @@ -265,19 +265,22 @@ void JNISoundTriggerCallback::onRecognitionEvent(struct sound_trigger_recognitio event->capture_session, event->capture_delay_ms, event->capture_preamble_ms, event->trigger_in_data, jAudioFormat, jData, jExtras); - env->DeleteLocalRef(jAudioFormat); - env->DeleteLocalRef(jData); + env->DeleteLocalRef(jExtras); } else { jEvent = env->NewObject(gRecognitionEventClass, gRecognitionEventCstor, event->status, event->model, event->capture_available, event->capture_session, event->capture_delay_ms, event->capture_preamble_ms, event->trigger_in_data, jAudioFormat, jData); + } + + if (jAudioFormat != NULL) { env->DeleteLocalRef(jAudioFormat); + } + if (jData != NULL) { env->DeleteLocalRef(jData); } - env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, SOUNDTRIGGER_EVENT_RECOGNITION, 0, 0, jEvent); diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index f75ab17..aabf320 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -49,36 +49,35 @@ using namespace android; #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) /** - * Convert from RGB 888 to Y'CbCr using the conversion specified in ITU-R BT.601 for - * digital RGB with K_b = 0.114, and K_r = 0.299. + * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02 */ static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane, uint8_t* uPlane, uint8_t* vPlane, size_t chromaStep, size_t yStride, size_t chromaStride) { uint8_t R, G, B; size_t index = 0; - - size_t cStrideDiff = chromaStride - width; - for (size_t j = 0; j < height; j++) { + uint8_t* u = uPlane; + uint8_t* v = vPlane; + uint8_t* y = yPlane; + bool jEven = (j & 1) == 0; for (size_t i = 0; i < width; i++) { R = rgbBuf[index++]; G = rgbBuf[index++]; B = rgbBuf[index++]; - *(yPlane + i) = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16; - - if (j % 2 == 0 && i % 2 == 0){ - *uPlane = (( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128; - *vPlane = (( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128; - uPlane += chromaStep; - vPlane += chromaStep; + *y++ = (77 * R + 150 * G + 29 * B) >> 8; + if (jEven && (i & 1) == 0) { + *v = (( -43 * R - 85 * G + 128 * B) >> 8) + 128; + *u = (( 128 * R - 107 * G - 21 * B) >> 8) + 128; + u += chromaStep; + v += chromaStep; } // Skip alpha index++; } yPlane += yStride; - if (j % 2 == 0) { - uPlane += cStrideDiff; - vPlane += cStrideDiff; + if (jEven) { + uPlane += chromaStride; + vPlane += chromaStride; } } } @@ -87,8 +86,10 @@ static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_yc size_t cStep = ycbcr->chroma_step; size_t cStride = ycbcr->cstride; size_t yStride = ycbcr->ystride; + ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride, + cStep); rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y), - reinterpret_cast<uint8_t*>(ycbcr->cb), reinterpret_cast<uint8_t*>(ycbcr->cr), + reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb), cStep, yStride, cStride); } @@ -231,6 +232,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, size_t totalSizeBytes = tmpSize; + ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt); switch(pixelFmt) { case HAL_PIXEL_FORMAT_YCrCb_420_SP: { if (bufferLength < totalSizeBytes) { @@ -276,6 +278,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, } uint32_t stride = buf->getStride(); + ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride); LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride); uint32_t cStride = ALIGN(stride / 2, 16); @@ -470,6 +473,26 @@ static jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject th return NO_ERROR; } +static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz, + jobject surface) { + ALOGV("nativeDetectSurfaceUsageFlags"); + + sp<ANativeWindow> anw; + if ((anw = getNativeWindow(env, surface)) == NULL) { + jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", + "Could not retrieve native window from surface."); + return BAD_VALUE; + } + int32_t usage = 0; + status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage); + if(err != NO_ERROR) { + jniThrowException(env, "Ljava/lang/UnsupportedOperationException;", + "Error while querying surface usage bits"); + return err; + } + return usage; +} + static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz, jobject surfaceTexture, jintArray dimens) { ALOGV("nativeDetectTextureDimens"); @@ -713,6 +736,9 @@ static JNINativeMethod gCameraDeviceMethods[] = { { "nativeGetJpegFooterSize", "()I", (void *)LegacyCameraDevice_nativeGetJpegFooterSize }, + { "nativeDetectSurfaceUsageFlags", + "(Landroid/view/Surface;)I", + (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags }, }; // Get all the required offsets in java class and register native functions diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 2c36d3d..df9f893 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -239,7 +239,8 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this, true, // threadCanCallJava sessionId, AudioRecord::TRANSFER_DEFAULT, - flags); + flags, + paa); if (status != NO_ERROR) { ALOGE("Error creating AudioRecord instance: initialization check failed with status %d.", @@ -431,7 +432,7 @@ static jint android_media_AudioRecord_readInShortArray(JNIEnv *env, jobject thi // read the new audio data from the native AudioRecord object const size_t recorderBuffSize = lpRecorder->frameCount()*lpRecorder->frameSize(); const size_t sizeInBytes = sizeInShorts * sizeof(short); - ssize_t readSize = lpRecorder->read(recordBuff + offsetInShorts * sizeof(short), + ssize_t readSize = lpRecorder->read(recordBuff + offsetInShorts, sizeInBytes > recorderBuffSize ? recorderBuffSize : sizeInBytes); diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 1ef70ea..0bf269f 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -25,6 +25,7 @@ #include "core_jni_helpers.h" #include <media/AudioSystem.h> +#include <media/AudioPolicy.h> #include <system/audio.h> #include <system/audio_policy.h> @@ -40,6 +41,7 @@ static const char* const kClassPathName = "android/media/AudioSystem"; static jclass gArrayListClass; static struct { jmethodID add; + jmethodID toArray; } gArrayListMethods; static jclass gAudioHandleClass; @@ -102,6 +104,42 @@ static struct { // other fields unused by JNI } gAudioPatchFields; +static jclass gAudioMixClass; +static struct { + jfieldID mRule; + jfieldID mFormat; + jfieldID mRouteFlags; + jfieldID mRegistrationId; + jfieldID mMixType; +} gAudioMixFields; + +static jclass gAudioFormatClass; +static struct { + jfieldID mEncoding; + jfieldID mSampleRate; + jfieldID mChannelMask; + // other fields unused by JNI +} gAudioFormatFields; + +static jclass gAudioMixingRuleClass; +static struct { + jfieldID mCriteria; + // other fields unused by JNI +} gAudioMixingRuleFields; + +static jclass gAttributeMatchCriterionClass; +static struct { + jfieldID mAttr; + jfieldID mRule; +} gAttributeMatchCriterionFields; + +static jclass gAudioAttributesClass; +static struct { + jfieldID mUsage; + jfieldID mSource; +} gAudioAttributesFields; + + static const char* const kEventHandlerClassPathName = "android/media/AudioPortEventHandler"; static jmethodID gPostEventFromNative; @@ -160,6 +198,9 @@ JNIAudioPortCallback::~JNIAudioPortCallback() { // remove global references JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + return; + } env->DeleteGlobalRef(mObject); env->DeleteGlobalRef(mClass); } @@ -167,7 +208,9 @@ JNIAudioPortCallback::~JNIAudioPortCallback() void JNIAudioPortCallback::sendEvent(int event) { JNIEnv *env = AndroidRuntime::getJNIEnv(); - + if (env == NULL) { + return; + } env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject, event, 0, 0, NULL); if (env->ExceptionCheck()) { @@ -482,7 +525,8 @@ static void convertAudioGainConfigToNative(JNIEnv *env, static jint convertAudioPortConfigToNative(JNIEnv *env, struct audio_port_config *nAudioPortConfig, - const jobject jAudioPortConfig) + const jobject jAudioPortConfig, + bool useConfigMask) { jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort); jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle); @@ -501,8 +545,13 @@ static jint convertAudioPortConfigToNative(JNIEnv *env, ALOGV("convertAudioPortConfigToNative handle %d role %d type %d", nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type); + unsigned int configMask = 0; + nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mSamplingRate); + if (nAudioPortConfig->sample_rate != 0) { + configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE; + } bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role); audio_channel_mask_t nMask; @@ -516,22 +565,34 @@ static jint convertAudioPortConfigToNative(JNIEnv *env, ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask); } nAudioPortConfig->channel_mask = nMask; + if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) { + configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK; + } jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat); audio_format_t nFormat = audioFormatToNative(jFormat); ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat); nAudioPortConfig->format = nFormat; + if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT && + nAudioPortConfig->format != AUDIO_FORMAT_INVALID) { + configMask |= AUDIO_PORT_CONFIG_FORMAT; + } + jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain); if (jGain != NULL) { convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask); env->DeleteLocalRef(jGain); + configMask |= AUDIO_PORT_CONFIG_GAIN; } else { ALOGV("convertAudioPortConfigToNative no gain"); nAudioPortConfig->gain.index = -1; } - nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig, - gAudioPortConfigFields.mConfigMask); - + if (useConfigMask) { + nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig, + gAudioPortConfigFields.mConfigMask); + } else { + nAudioPortConfig->config_mask = configMask; + } env->DeleteLocalRef(jAudioPort); env->DeleteLocalRef(jHandle); return (jint)AUDIO_JAVA_SUCCESS; @@ -996,7 +1057,7 @@ android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz, jStatus = (jint)AUDIO_JAVA_BAD_VALUE; goto exit; } - jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource); + jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false); env->DeleteLocalRef(jSource); jSource = NULL; if (jStatus != AUDIO_JAVA_SUCCESS) { @@ -1011,7 +1072,7 @@ android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz, jStatus = (jint)AUDIO_JAVA_BAD_VALUE; goto exit; } - jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink); + jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false); env->DeleteLocalRef(jSink); jSink = NULL; if (jStatus != AUDIO_JAVA_SUCCESS) { @@ -1266,7 +1327,7 @@ android_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz, return AUDIO_JAVA_BAD_VALUE; } struct audio_port_config nAudioPortConfig; - jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig); + jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true); if (jStatus != AUDIO_JAVA_SUCCESS) { return jStatus; } @@ -1302,6 +1363,128 @@ android_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, ji return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId); } + + + +static jint convertAudioMixToNative(JNIEnv *env, + AudioMix *nAudioMix, + const jobject jAudioMix) +{ + nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType); + nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags); + + jstring jRegistrationId = (jstring)env->GetObjectField(jAudioMix, + gAudioMixFields.mRegistrationId); + const char *nRegistrationId = env->GetStringUTFChars(jRegistrationId, NULL); + nAudioMix->mRegistrationId = String8(nRegistrationId); + env->ReleaseStringUTFChars(jRegistrationId, nRegistrationId); + env->DeleteLocalRef(jRegistrationId); + + jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat); + nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat, + gAudioFormatFields.mSampleRate); + nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat, + gAudioFormatFields.mChannelMask)); + nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat, + gAudioFormatFields.mEncoding)); + env->DeleteLocalRef(jFormat); + + jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); + jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); + env->DeleteLocalRef(jRule); + jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria, + gArrayListMethods.toArray); + env->DeleteLocalRef(jRuleCriteria); + + jint numCriteria = env->GetArrayLength(jCriteria); + if (numCriteria > MAX_CRITERIA_PER_MIX) { + numCriteria = MAX_CRITERIA_PER_MIX; + } + + for (jint i = 0; i < numCriteria; i++) { + AttributeMatchCriterion nCriterion; + + jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); + + nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule); + + jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr); + if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE || + nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { + nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes, + gAudioAttributesFields.mUsage); + } else { + nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes, + gAudioAttributesFields.mSource); + } + env->DeleteLocalRef(jAttributes); + + nAudioMix->mCriteria.add(nCriterion); + env->DeleteLocalRef(jCriterion); + } + + env->DeleteLocalRef(jCriteria); + + return (jint)AUDIO_JAVA_SUCCESS; +} + +static jint +android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz, + jobject jMixesList, jboolean registration) +{ + ALOGV("registerPolicyMixes"); + + if (jMixesList == NULL) { + return (jint)AUDIO_JAVA_BAD_VALUE; + } + if (!env->IsInstanceOf(jMixesList, gArrayListClass)) { + return (jint)AUDIO_JAVA_BAD_VALUE; + } + jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList, + gArrayListMethods.toArray); + jint numMixes = env->GetArrayLength(jMixes); + if (numMixes > MAX_MIXES_PER_POLICY) { + numMixes = MAX_MIXES_PER_POLICY; + } + + status_t status; + jint jStatus; + jobject jAudioMix = NULL; + Vector <AudioMix> mixes; + for (jint i = 0; i < numMixes; i++) { + jAudioMix = env->GetObjectArrayElement(jMixes, i); + if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) { + jStatus = (jint)AUDIO_JAVA_BAD_VALUE; + goto exit; + } + AudioMix mix; + jStatus = convertAudioMixToNative(env, &mix, jAudioMix); + env->DeleteLocalRef(jAudioMix); + jAudioMix = NULL; + if (jStatus != AUDIO_JAVA_SUCCESS) { + goto exit; + } + mixes.add(mix); + } + + ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration); + status = AudioSystem::registerPolicyMixes(mixes, registration); + ALOGV("AudioSystem::registerPolicyMixes() returned %d", status); + + jStatus = nativeToJavaStatus(status); + if (jStatus != AUDIO_JAVA_SUCCESS) { + goto exit; + } + +exit: + if (jAudioMix != NULL) { + env->DeleteLocalRef(jAudioMix); + } + return jStatus; +} + + + // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { @@ -1343,6 +1526,9 @@ static JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_setAudioPortConfig}, {"getAudioHwSyncForSession", "(I)I", (void *)android_media_AudioSystem_getAudioHwSyncForSession}, + {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", + (void *)android_media_AudioSystem_registerPolicyMixes}, + }; @@ -1360,6 +1546,7 @@ int register_android_media_AudioSystem(JNIEnv *env) jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); + gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;"); jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle"); gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass); @@ -1442,6 +1629,41 @@ int register_android_media_AudioSystem(JNIEnv *env) "(Ljava/lang/Object;IIILjava/lang/Object;)V"); + jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); + gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); + gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule", + "Landroid/media/audiopolicy/AudioMixingRule;"); + gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat", + "Landroid/media/AudioFormat;"); + gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I"); + gAudioMixFields.mRegistrationId = GetFieldIDOrDie(env, audioMixClass, "mRegistrationId", + "Ljava/lang/String;"); + gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I"); + + jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat"); + gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass); + gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I"); + gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I"); + gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I"); + + jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule"); + gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass); + gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria", + "Ljava/util/ArrayList;"); + + jclass attributeMatchCriterionClass = + FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion"); + gAttributeMatchCriterionClass = MakeGlobalRefOrDie(env, attributeMatchCriterionClass); + gAttributeMatchCriterionFields.mAttr = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mAttr", + "Landroid/media/AudioAttributes;"); + gAttributeMatchCriterionFields.mRule = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mRule", + "I"); + + jclass audioAttributesClass = FindClassOrDie(env, "android/media/AudioAttributes"); + gAudioAttributesClass = MakeGlobalRefOrDie(env, audioAttributesClass); + gAudioAttributesFields.mUsage = GetFieldIDOrDie(env, audioAttributesClass, "mUsage", "I"); + gAudioAttributesFields.mSource = GetFieldIDOrDie(env, audioAttributesClass, "mSource", "I"); + AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback); RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index 141138d..773d42e 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -46,10 +46,12 @@ enum { HEAP_UNKNOWN, HEAP_DALVIK, HEAP_NATIVE, + HEAP_DALVIK_OTHER, HEAP_STACK, HEAP_CURSOR, HEAP_ASHMEM, + HEAP_GL_DEV, HEAP_UNKNOWN_DEV, HEAP_SO, HEAP_JAR, @@ -306,7 +308,11 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } else if (strncmp(name, "[stack", 6) == 0) { whichHeap = HEAP_STACK; } else if (strncmp(name, "/dev/", 5) == 0) { - whichHeap = HEAP_UNKNOWN_DEV; + if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) { + whichHeap = HEAP_GL_DEV; + } else { + whichHeap = HEAP_UNKNOWN_DEV; + } } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { whichHeap = HEAP_SO; is_swappable = true; @@ -488,18 +494,20 @@ static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject o android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); } -static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss) +static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss, + jlongArray outMemtrack) { char line[1024]; jlong pss = 0; jlong uss = 0; + jlong memtrack = 0; char tmp[128]; FILE *fp; struct graphics_memory_pss graphics_mem; if (read_memtrack_memory(pid, &graphics_mem) == 0) { - pss = uss = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; + pss = uss = memtrack = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; } sprintf(tmp, "/proc/%d/smaps", pid); @@ -518,8 +526,8 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jl c++; } pss += atoi(c); - } else if (strncmp(line, "Private_Clean:", 14) - || strncmp(line, "Private_Dirty:", 14)) { + } else if (strncmp(line, "Private_Clean:", 14) == 0 + || strncmp(line, "Private_Dirty:", 14) == 0) { char* c = line + 14; while (*c != 0 && (*c < '0' || *c > '9')) { c++; @@ -542,12 +550,22 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jl } } + if (outMemtrack != NULL) { + if (env->GetArrayLength(outMemtrack) >= 1) { + jlong* outMemtrackArray = env->GetLongArrayElements(outMemtrack, 0); + if (outMemtrackArray != NULL) { + outMemtrackArray[0] = memtrack; + } + env->ReleaseLongArrayElements(outMemtrack, outMemtrackArray, 0); + } + } + return pss; } static jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz) { - return android_os_Debug_getPssPid(env, clazz, getpid(), NULL); + return android_os_Debug_getPssPid(env, clazz, getpid(), NULL, NULL); } enum { @@ -560,6 +578,10 @@ enum { MEMINFO_SWAP_TOTAL, MEMINFO_SWAP_FREE, MEMINFO_ZRAM_TOTAL, + MEMINFO_MAPPED, + MEMINFO_VMALLOC_USED, + MEMINFO_PAGE_TABLES, + MEMINFO_KERNEL_STACK, MEMINFO_COUNT }; @@ -598,6 +620,11 @@ static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray o "Slab:", "SwapTotal:", "SwapFree:", + "ZRam:", + "Mapped:", + "VmallocUsed:", + "PageTables:", + "KernelStack:", NULL }; static const int tagsLen[] = { @@ -609,12 +636,17 @@ static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray o 5, 10, 9, + 5, + 7, + 12, + 11, + 12, 0 }; - long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char* p = buffer; - while (*p && numFound < 8) { + while (*p && numFound < 13) { int i = 0; while (tags[i]) { if (strncmp(p, tags[i], tagsLen[i]) == 0) { @@ -942,7 +974,7 @@ static JNINativeMethod gMethods[] = { (void*) android_os_Debug_getDirtyPagesPid }, { "getPss", "()J", (void*) android_os_Debug_getPss }, - { "getPss", "(I[J)J", + { "getPss", "(I[J[J)J", (void*) android_os_Debug_getPssPid }, { "getMemInfo", "([J)V", (void*) android_os_Debug_getMemInfo }, diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 16f7d12..4f29c50 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -694,6 +694,16 @@ static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong "Binder invocation to an incorrect interface"); } +static jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz) +{ + return Parcel::getGlobalAllocSize(); +} + +static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz) +{ + return Parcel::getGlobalAllocCount(); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gParcelMethods[] = { @@ -743,6 +753,9 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors}, {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, {"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, + + {"getGlobalAllocSize", "()J", (void*)android_os_Parcel_getGlobalAllocSize}, + {"getGlobalAllocCount", "()J", (void*)android_os_Parcel_getGlobalAllocCount}, }; const char* const kParcelPathName = "android/os/Parcel"; diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index e5cdee0..daf5a61 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -27,16 +27,17 @@ #include <private/android_filesystem_config.h> // for AID_SYSTEM -#include "JNIHelp.h" -#include "ScopedStringChars.h" -#include "ScopedUtfChars.h" -#include "android_runtime/AndroidRuntime.h" -#include "android_util_Binder.h" #include "androidfw/Asset.h" #include "androidfw/AssetManager.h" +#include "androidfw/AttributeFinder.h" #include "androidfw/ResourceTypes.h" +#include "android_runtime/AndroidRuntime.h" +#include "android_util_Binder.h" #include "core_jni_helpers.h" #include "jni.h" +#include "JNIHelp.h" +#include "ScopedStringChars.h" +#include "ScopedUtfChars.h" #include "utils/Log.h" #include "utils/misc.h" @@ -1010,6 +1011,30 @@ static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz, theme->dumpToLog(); } +class XmlAttributeFinder : public BackTrackingAttributeFinder<XmlAttributeFinder, jsize> { +public: + XmlAttributeFinder(const ResXMLParser* parser) + : BackTrackingAttributeFinder(0, parser != NULL ? parser->getAttributeCount() : 0) + , mParser(parser) {} + + inline uint32_t getAttribute(jsize index) const { + return mParser->getAttributeNameResID(index); + } + +private: + const ResXMLParser* mParser; +}; + +class BagAttributeFinder : public BackTrackingAttributeFinder<BagAttributeFinder, const ResTable::bag_entry*> { +public: + BagAttributeFinder(const ResTable::bag_entry* start, const ResTable::bag_entry* end) + : BackTrackingAttributeFinder(start, end) {} + + inline uint32_t getAttribute(const ResTable::bag_entry* entry) const { + return entry->map.name.ident; + } +}; + static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz, jlong themeToken, jint defStyleAttr, @@ -1087,13 +1112,13 @@ static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject c res.lock(); // Retrieve the default style bag, if requested. - const ResTable::bag_entry* defStyleEnt = NULL; + const ResTable::bag_entry* defStyleStart = NULL; uint32_t defStyleTypeSetFlags = 0; ssize_t bagOff = defStyleRes != 0 - ? res.getBagLocked(defStyleRes, &defStyleEnt, &defStyleTypeSetFlags) : -1; + ? res.getBagLocked(defStyleRes, &defStyleStart, &defStyleTypeSetFlags) : -1; defStyleTypeSetFlags |= defStyleBagTypeSetFlags; - const ResTable::bag_entry* endDefStyleEnt = defStyleEnt + - (bagOff >= 0 ? bagOff : 0);; + const ResTable::bag_entry* const defStyleEnd = defStyleStart + (bagOff >= 0 ? bagOff : 0); + BagAttributeFinder defStyleAttrFinder(defStyleStart, defStyleEnd); // Now iterate through all of the attributes that the client has requested, // filling in each with whatever data we can find. @@ -1110,7 +1135,7 @@ static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject c // coming from, first XML attributes, then XML style, then default // style, and finally the theme. value.dataType = Res_value::TYPE_NULL; - value.data = 0; + value.data = Res_value::DATA_NULL_UNDEFINED; typeSetFlags = 0; config.density = 0; @@ -1124,21 +1149,16 @@ static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject c } } - // Skip through the default style values until the end or the next possible match. - while (defStyleEnt < endDefStyleEnt && curIdent > defStyleEnt->map.name.ident) { - defStyleEnt++; - } - // Retrieve the current default style attribute if it matches, and step to next. - if (defStyleEnt < endDefStyleEnt && curIdent == defStyleEnt->map.name.ident) { - if (value.dataType == Res_value::TYPE_NULL) { - block = defStyleEnt->stringBlock; + if (value.dataType == Res_value::TYPE_NULL) { + const ResTable::bag_entry* const defStyleEntry = defStyleAttrFinder.find(curIdent); + if (defStyleEntry != defStyleEnd) { + block = defStyleEntry->stringBlock; typeSetFlags = defStyleTypeSetFlags; - value = defStyleEnt->map.value; + value = defStyleEntry->map.value; if (kDebugStyles) { ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data); } } - defStyleEnt++; } uint32_t resid = 0; @@ -1179,6 +1199,7 @@ static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject c ALOGI("-> Setting to @null!"); } value.dataType = Res_value::TYPE_NULL; + value.data = Res_value::DATA_NULL_UNDEFINED; block = -1; } @@ -1310,34 +1331,32 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla res.lock(); // Retrieve the default style bag, if requested. - const ResTable::bag_entry* defStyleEnt = NULL; + const ResTable::bag_entry* defStyleAttrStart = NULL; uint32_t defStyleTypeSetFlags = 0; ssize_t bagOff = defStyleRes != 0 - ? res.getBagLocked(defStyleRes, &defStyleEnt, &defStyleTypeSetFlags) : -1; + ? res.getBagLocked(defStyleRes, &defStyleAttrStart, &defStyleTypeSetFlags) : -1; defStyleTypeSetFlags |= defStyleBagTypeSetFlags; - const ResTable::bag_entry* endDefStyleEnt = defStyleEnt + - (bagOff >= 0 ? bagOff : 0); + const ResTable::bag_entry* const defStyleAttrEnd = defStyleAttrStart + (bagOff >= 0 ? bagOff : 0); + BagAttributeFinder defStyleAttrFinder(defStyleAttrStart, defStyleAttrEnd); // Retrieve the style class bag, if requested. - const ResTable::bag_entry* styleEnt = NULL; + const ResTable::bag_entry* styleAttrStart = NULL; uint32_t styleTypeSetFlags = 0; - bagOff = style != 0 ? res.getBagLocked(style, &styleEnt, &styleTypeSetFlags) : -1; + bagOff = style != 0 ? res.getBagLocked(style, &styleAttrStart, &styleTypeSetFlags) : -1; styleTypeSetFlags |= styleBagTypeSetFlags; - const ResTable::bag_entry* endStyleEnt = styleEnt + - (bagOff >= 0 ? bagOff : 0); + const ResTable::bag_entry* const styleAttrEnd = styleAttrStart + (bagOff >= 0 ? bagOff : 0); + BagAttributeFinder styleAttrFinder(styleAttrStart, styleAttrEnd); // Retrieve the XML attributes, if requested. - const jsize NX = xmlParser ? xmlParser->getAttributeCount() : 0; - jsize ix=0; - uint32_t curXmlAttr = xmlParser ? xmlParser->getAttributeNameResID(ix) : 0; - static const ssize_t kXmlBlock = 0x10000000; + XmlAttributeFinder xmlAttrFinder(xmlParser); + const jsize xmlAttrEnd = xmlParser != NULL ? xmlParser->getAttributeCount() : 0; // Now iterate through all of the attributes that the client has requested, // filling in each with whatever data we can find. ssize_t block = 0; uint32_t typeSetFlags; - for (jsize ii=0; ii<NI; ii++) { + for (jsize ii = 0; ii < NI; ii++) { const uint32_t curIdent = (uint32_t)src[ii]; if (kDebugStyles) { @@ -1348,58 +1367,47 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla // coming from, first XML attributes, then XML style, then default // style, and finally the theme. value.dataType = Res_value::TYPE_NULL; - value.data = 0; + value.data = Res_value::DATA_NULL_UNDEFINED; typeSetFlags = 0; config.density = 0; - // Skip through XML attributes until the end or the next possible match. - while (ix < NX && curIdent > curXmlAttr) { - ix++; - curXmlAttr = xmlParser->getAttributeNameResID(ix); - } - // Retrieve the current XML attribute if it matches, and step to next. - if (ix < NX && curIdent == curXmlAttr) { + // Walk through the xml attributes looking for the requested attribute. + const jsize xmlAttrIdx = xmlAttrFinder.find(curIdent); + if (xmlAttrIdx != xmlAttrEnd) { + // We found the attribute we were looking for. block = kXmlBlock; - xmlParser->getAttributeValue(ix, &value); - ix++; - curXmlAttr = xmlParser->getAttributeNameResID(ix); + xmlParser->getAttributeValue(xmlAttrIdx, &value); if (kDebugStyles) { ALOGI("-> From XML: type=0x%x, data=0x%08x", value.dataType, value.data); } } - // Skip through the style values until the end or the next possible match. - while (styleEnt < endStyleEnt && curIdent > styleEnt->map.name.ident) { - styleEnt++; - } - // Retrieve the current style attribute if it matches, and step to next. - if (styleEnt < endStyleEnt && curIdent == styleEnt->map.name.ident) { - if (value.dataType == Res_value::TYPE_NULL) { - block = styleEnt->stringBlock; + if (value.dataType == Res_value::TYPE_NULL) { + // Walk through the style class values looking for the requested attribute. + const ResTable::bag_entry* const styleAttrEntry = styleAttrFinder.find(curIdent); + if (styleAttrEntry != styleAttrEnd) { + // We found the attribute we were looking for. + block = styleAttrEntry->stringBlock; typeSetFlags = styleTypeSetFlags; - value = styleEnt->map.value; + value = styleAttrEntry->map.value; if (kDebugStyles) { ALOGI("-> From style: type=0x%x, data=0x%08x", value.dataType, value.data); } } - styleEnt++; } - // Skip through the default style values until the end or the next possible match. - while (defStyleEnt < endDefStyleEnt && curIdent > defStyleEnt->map.name.ident) { - defStyleEnt++; - } - // Retrieve the current default style attribute if it matches, and step to next. - if (defStyleEnt < endDefStyleEnt && curIdent == defStyleEnt->map.name.ident) { - if (value.dataType == Res_value::TYPE_NULL) { - block = defStyleEnt->stringBlock; - typeSetFlags = defStyleTypeSetFlags; - value = defStyleEnt->map.value; + if (value.dataType == Res_value::TYPE_NULL) { + // Walk through the default style values looking for the requested attribute. + const ResTable::bag_entry* const defStyleAttrEntry = defStyleAttrFinder.find(curIdent); + if (defStyleAttrEntry != defStyleAttrEnd) { + // We found the attribute we were looking for. + block = defStyleAttrEntry->stringBlock; + typeSetFlags = styleTypeSetFlags; + value = defStyleAttrEntry->map.value; if (kDebugStyles) { ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data); } } - defStyleEnt++; } uint32_t resid = 0; @@ -1407,7 +1415,10 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla // Take care of resolving the found resource to its final value. ssize_t newBlock = theme->resolveAttributeReference(&value, block, &resid, &typeSetFlags, &config); - if (newBlock >= 0) block = newBlock; + if (newBlock >= 0) { + block = newBlock; + } + if (kDebugStyles) { ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, value.data); } @@ -1427,7 +1438,11 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla return JNI_FALSE; } } - if (newBlock >= 0) block = newBlock; + + if (newBlock >= 0) { + block = newBlock; + } + if (kDebugStyles) { ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data); } @@ -1440,6 +1455,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla ALOGI("-> Setting to @null!"); } value.dataType = Res_value::TYPE_NULL; + value.data = Res_value::DATA_NULL_UNDEFINED; block = kXmlBlock; } @@ -1450,8 +1466,8 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla // Write the final value back to Java. dest[STYLE_TYPE] = value.dataType; dest[STYLE_DATA] = value.data; - dest[STYLE_ASSET_COOKIE] = - block != kXmlBlock ? reinterpret_cast<jint>(res.getTableCookie(block)) : (jint)-1; + dest[STYLE_ASSET_COOKIE] = block != kXmlBlock ? + static_cast<jint>(res.getTableCookie(block)) : -1; dest[STYLE_RESOURCE_ID] = resid; dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags; dest[STYLE_DENSITY] = config.density; @@ -1550,7 +1566,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job // Try to find a value for this attribute... value.dataType = Res_value::TYPE_NULL; - value.data = 0; + value.data = Res_value::DATA_NULL_UNDEFINED; typeSetFlags = 0; config.density = 0; @@ -1586,6 +1602,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job // Deal with the special @null value -- it turns back to TYPE_NULL. if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) { value.dataType = Res_value::TYPE_NULL; + value.data = Res_value::DATA_NULL_UNDEFINED; } //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data); @@ -1699,6 +1716,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz // Deal with the special @null value -- it turns back to TYPE_NULL. if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) { value.dataType = Res_value::TYPE_NULL; + value.data = Res_value::DATA_NULL_UNDEFINED; } //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data); diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index bd125a5..da8a9ed 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -43,6 +43,7 @@ #include <RenderNode.h> #include <CanvasProperty.h> #include <Paint.h> +#include <renderthread/RenderProxy.h> #include "MinikinUtils.h" @@ -340,11 +341,8 @@ static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz, // ---------------------------------------------------------------------------- static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, - jfloat left, jfloat top, jlong paintPtr) { + jlong rendererPtr, jlong bitmapPtr, jfloat left, jfloat top, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); @@ -357,12 +355,10 @@ static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, + jlong rendererPtr, jlong bitmapPtr, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Paint* paint = reinterpret_cast<Paint*>(paintPtr); @@ -371,11 +367,8 @@ static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, - jlong matrixPtr, jlong paintPtr) { + jlong rendererPtr, jlong bitmapPtr, jlong matrixPtr, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); @@ -420,12 +413,9 @@ static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, - jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors, - jint colorOffset, jlong paintPtr) { + jlong rendererPtr, jlong bitmapPtr, jint meshWidth, jint meshHeight, + jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL; jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL; @@ -439,11 +429,9 @@ static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, } static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, - jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr, + jlong rendererPtr, jlong bitmapPtr, jlong patchPtr, float left, float top, float right, float bottom, jlong paintPtr) { SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); - // This object allows the renderer to allocate a global JNI ref to the buffer object. - JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); @@ -821,7 +809,7 @@ static jint android_view_GLES20Canvas_drawRenderNode(JNIEnv* env, static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz, jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); - Layer* layer = reinterpret_cast<Layer*>(layerPtr); + DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); renderer->drawLayer(layer, x, y); } @@ -861,7 +849,7 @@ static void android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { if (kUseOpenGLRenderer) { int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); - android::uirenderer::RenderNode::outputLogBuffer(fd); + android::uirenderer::renderthread::RenderProxy::outputLogBuffer(fd); } } @@ -913,14 +901,14 @@ static JNINativeMethod gMethods[] = { { "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix }, { "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix }, - { "nDrawBitmap", "(JJ[BFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap }, - { "nDrawBitmap", "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect }, - { "nDrawBitmap", "(JJ[BJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, + { "nDrawBitmap", "(JJFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap }, + { "nDrawBitmap", "(JJFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect }, + { "nDrawBitmap", "(JJJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, { "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData }, - { "nDrawBitmapMesh", "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh }, + { "nDrawBitmapMesh", "(JJII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh }, - { "nDrawPatch", "(JJ[BJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch }, + { "nDrawPatch", "(JJJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch }, { "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor }, { "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect }, diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp index 648d1e3..cefb3da 100644 --- a/core/jni/android_view_HardwareLayer.cpp +++ b/core/jni/android_view_HardwareLayer.cpp @@ -81,12 +81,6 @@ static void android_view_HardwareLayer_updateSurfaceTexture(JNIEnv* env, jobject layer->updateTexImage(); } -static jlong android_view_HardwareLayer_getLayer(JNIEnv* env, jobject clazz, - jlong layerUpdaterPtr) { - DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr); - return reinterpret_cast<jlong>( layer->backingLayer() ); -} - static jint android_view_HardwareLayer_getTexName(JNIEnv* env, jobject clazz, jlong layerUpdaterPtr) { DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr); @@ -111,7 +105,6 @@ static JNINativeMethod gMethods[] = { (void*) android_view_HardwareLayer_setSurfaceTexture }, { "nUpdateSurfaceTexture", "(J)V", (void*) android_view_HardwareLayer_updateSurfaceTexture }, - { "nGetLayer", "(J)J", (void*) android_view_HardwareLayer_getLayer }, { "nGetTexName", "(J)I", (void*) android_view_HardwareLayer_getTexName }, #endif }; diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index d1e693b..a1d3bc6 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -485,68 +485,68 @@ static JNINativeMethod gMethods[] = { { "nOutput", "(J)V", (void*) android_view_RenderNode_output }, { "nGetDebugSize", "(J)I", (void*) android_view_RenderNode_getDebugSize }, - { "nSetLayerType", "(JI)Z", (void*) android_view_RenderNode_setLayerType }, - { "nSetLayerPaint", "(JJ)Z", (void*) android_view_RenderNode_setLayerPaint }, - { "nSetStaticMatrix", "(JJ)Z", (void*) android_view_RenderNode_setStaticMatrix }, - { "nSetAnimationMatrix", "(JJ)Z", (void*) android_view_RenderNode_setAnimationMatrix }, - { "nSetClipToBounds", "(JZ)Z", (void*) android_view_RenderNode_setClipToBounds }, - { "nSetClipBounds", "(JIIII)Z", (void*) android_view_RenderNode_setClipBounds }, - { "nSetClipBoundsEmpty", "(J)Z", (void*) android_view_RenderNode_setClipBoundsEmpty }, - { "nSetProjectBackwards", "(JZ)Z", (void*) android_view_RenderNode_setProjectBackwards }, - { "nSetProjectionReceiver","(JZ)Z", (void*) android_view_RenderNode_setProjectionReceiver }, + { "nSetLayerType", "!(JI)Z", (void*) android_view_RenderNode_setLayerType }, + { "nSetLayerPaint", "!(JJ)Z", (void*) android_view_RenderNode_setLayerPaint }, + { "nSetStaticMatrix", "!(JJ)Z", (void*) android_view_RenderNode_setStaticMatrix }, + { "nSetAnimationMatrix", "!(JJ)Z", (void*) android_view_RenderNode_setAnimationMatrix }, + { "nSetClipToBounds", "!(JZ)Z", (void*) android_view_RenderNode_setClipToBounds }, + { "nSetClipBounds", "!(JIIII)Z", (void*) android_view_RenderNode_setClipBounds }, + { "nSetClipBoundsEmpty", "!(J)Z", (void*) android_view_RenderNode_setClipBoundsEmpty }, + { "nSetProjectBackwards", "!(JZ)Z", (void*) android_view_RenderNode_setProjectBackwards }, + { "nSetProjectionReceiver","!(JZ)Z", (void*) android_view_RenderNode_setProjectionReceiver }, { "nSetOutlineRoundRect", "(JIIIIFF)Z", (void*) android_view_RenderNode_setOutlineRoundRect }, { "nSetOutlineConvexPath", "(JJF)Z", (void*) android_view_RenderNode_setOutlineConvexPath }, { "nSetOutlineEmpty", "(J)Z", (void*) android_view_RenderNode_setOutlineEmpty }, { "nSetOutlineNone", "(J)Z", (void*) android_view_RenderNode_setOutlineNone }, - { "nHasShadow", "(J)Z", (void*) android_view_RenderNode_hasShadow }, - { "nSetClipToOutline", "(JZ)Z", (void*) android_view_RenderNode_setClipToOutline }, + { "nHasShadow", "!(J)Z", (void*) android_view_RenderNode_hasShadow }, + { "nSetClipToOutline", "!(JZ)Z", (void*) android_view_RenderNode_setClipToOutline }, { "nSetRevealClip", "(JZFFF)Z", (void*) android_view_RenderNode_setRevealClip }, - { "nSetAlpha", "(JF)Z", (void*) android_view_RenderNode_setAlpha }, - { "nSetHasOverlappingRendering", "(JZ)Z", + { "nSetAlpha", "!(JF)Z", (void*) android_view_RenderNode_setAlpha }, + { "nSetHasOverlappingRendering", "!(JZ)Z", (void*) android_view_RenderNode_setHasOverlappingRendering }, - { "nSetElevation", "(JF)Z", (void*) android_view_RenderNode_setElevation }, - { "nSetTranslationX", "(JF)Z", (void*) android_view_RenderNode_setTranslationX }, - { "nSetTranslationY", "(JF)Z", (void*) android_view_RenderNode_setTranslationY }, - { "nSetTranslationZ", "(JF)Z", (void*) android_view_RenderNode_setTranslationZ }, - { "nSetRotation", "(JF)Z", (void*) android_view_RenderNode_setRotation }, - { "nSetRotationX", "(JF)Z", (void*) android_view_RenderNode_setRotationX }, - { "nSetRotationY", "(JF)Z", (void*) android_view_RenderNode_setRotationY }, - { "nSetScaleX", "(JF)Z", (void*) android_view_RenderNode_setScaleX }, - { "nSetScaleY", "(JF)Z", (void*) android_view_RenderNode_setScaleY }, - { "nSetPivotX", "(JF)Z", (void*) android_view_RenderNode_setPivotX }, - { "nSetPivotY", "(JF)Z", (void*) android_view_RenderNode_setPivotY }, - { "nSetCameraDistance", "(JF)Z", (void*) android_view_RenderNode_setCameraDistance }, - { "nSetLeft", "(JI)Z", (void*) android_view_RenderNode_setLeft }, - { "nSetTop", "(JI)Z", (void*) android_view_RenderNode_setTop }, - { "nSetRight", "(JI)Z", (void*) android_view_RenderNode_setRight }, - { "nSetBottom", "(JI)Z", (void*) android_view_RenderNode_setBottom }, - { "nSetLeftTopRightBottom","(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom }, - { "nOffsetLeftAndRight", "(JI)Z", (void*) android_view_RenderNode_offsetLeftAndRight }, - { "nOffsetTopAndBottom", "(JI)Z", (void*) android_view_RenderNode_offsetTopAndBottom }, - - { "nHasOverlappingRendering", "(J)Z", (void*) android_view_RenderNode_hasOverlappingRendering }, - { "nGetClipToOutline", "(J)Z", (void*) android_view_RenderNode_getClipToOutline }, - { "nGetAlpha", "(J)F", (void*) android_view_RenderNode_getAlpha }, - { "nGetCameraDistance", "(J)F", (void*) android_view_RenderNode_getCameraDistance }, - { "nGetScaleX", "(J)F", (void*) android_view_RenderNode_getScaleX }, - { "nGetScaleY", "(J)F", (void*) android_view_RenderNode_getScaleY }, - { "nGetElevation", "(J)F", (void*) android_view_RenderNode_getElevation }, - { "nGetTranslationX", "(J)F", (void*) android_view_RenderNode_getTranslationX }, - { "nGetTranslationY", "(J)F", (void*) android_view_RenderNode_getTranslationY }, - { "nGetTranslationZ", "(J)F", (void*) android_view_RenderNode_getTranslationZ }, - { "nGetRotation", "(J)F", (void*) android_view_RenderNode_getRotation }, - { "nGetRotationX", "(J)F", (void*) android_view_RenderNode_getRotationX }, - { "nGetRotationY", "(J)F", (void*) android_view_RenderNode_getRotationY }, - { "nIsPivotExplicitlySet", "(J)Z", (void*) android_view_RenderNode_isPivotExplicitlySet }, - { "nHasIdentityMatrix", "(J)Z", (void*) android_view_RenderNode_hasIdentityMatrix }, - - { "nGetTransformMatrix", "(JJ)V", (void*) android_view_RenderNode_getTransformMatrix }, - { "nGetInverseTransformMatrix","(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix }, - - { "nGetPivotX", "(J)F", (void*) android_view_RenderNode_getPivotX }, - { "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY }, + { "nSetElevation", "!(JF)Z", (void*) android_view_RenderNode_setElevation }, + { "nSetTranslationX", "!(JF)Z", (void*) android_view_RenderNode_setTranslationX }, + { "nSetTranslationY", "!(JF)Z", (void*) android_view_RenderNode_setTranslationY }, + { "nSetTranslationZ", "!(JF)Z", (void*) android_view_RenderNode_setTranslationZ }, + { "nSetRotation", "!(JF)Z", (void*) android_view_RenderNode_setRotation }, + { "nSetRotationX", "!(JF)Z", (void*) android_view_RenderNode_setRotationX }, + { "nSetRotationY", "!(JF)Z", (void*) android_view_RenderNode_setRotationY }, + { "nSetScaleX", "!(JF)Z", (void*) android_view_RenderNode_setScaleX }, + { "nSetScaleY", "!(JF)Z", (void*) android_view_RenderNode_setScaleY }, + { "nSetPivotX", "!(JF)Z", (void*) android_view_RenderNode_setPivotX }, + { "nSetPivotY", "!(JF)Z", (void*) android_view_RenderNode_setPivotY }, + { "nSetCameraDistance", "!(JF)Z", (void*) android_view_RenderNode_setCameraDistance }, + { "nSetLeft", "!(JI)Z", (void*) android_view_RenderNode_setLeft }, + { "nSetTop", "!(JI)Z", (void*) android_view_RenderNode_setTop }, + { "nSetRight", "!(JI)Z", (void*) android_view_RenderNode_setRight }, + { "nSetBottom", "!(JI)Z", (void*) android_view_RenderNode_setBottom }, + { "nSetLeftTopRightBottom","!(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom }, + { "nOffsetLeftAndRight", "!(JI)Z", (void*) android_view_RenderNode_offsetLeftAndRight }, + { "nOffsetTopAndBottom", "!(JI)Z", (void*) android_view_RenderNode_offsetTopAndBottom }, + + { "nHasOverlappingRendering", "!(J)Z", (void*) android_view_RenderNode_hasOverlappingRendering }, + { "nGetClipToOutline", "!(J)Z", (void*) android_view_RenderNode_getClipToOutline }, + { "nGetAlpha", "!(J)F", (void*) android_view_RenderNode_getAlpha }, + { "nGetCameraDistance", "!(J)F", (void*) android_view_RenderNode_getCameraDistance }, + { "nGetScaleX", "!(J)F", (void*) android_view_RenderNode_getScaleX }, + { "nGetScaleY", "!(J)F", (void*) android_view_RenderNode_getScaleY }, + { "nGetElevation", "!(J)F", (void*) android_view_RenderNode_getElevation }, + { "nGetTranslationX", "!(J)F", (void*) android_view_RenderNode_getTranslationX }, + { "nGetTranslationY", "!(J)F", (void*) android_view_RenderNode_getTranslationY }, + { "nGetTranslationZ", "!(J)F", (void*) android_view_RenderNode_getTranslationZ }, + { "nGetRotation", "!(J)F", (void*) android_view_RenderNode_getRotation }, + { "nGetRotationX", "!(J)F", (void*) android_view_RenderNode_getRotationX }, + { "nGetRotationY", "!(J)F", (void*) android_view_RenderNode_getRotationY }, + { "nIsPivotExplicitlySet", "!(J)Z", (void*) android_view_RenderNode_isPivotExplicitlySet }, + { "nHasIdentityMatrix", "!(J)Z", (void*) android_view_RenderNode_hasIdentityMatrix }, + + { "nGetTransformMatrix", "!(JJ)V", (void*) android_view_RenderNode_getTransformMatrix }, + { "nGetInverseTransformMatrix","!(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix }, + + { "nGetPivotX", "!(J)F", (void*) android_view_RenderNode_getPivotX }, + { "nGetPivotY", "!(J)F", (void*) android_view_RenderNode_getPivotY }, { "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator }, { "nEndAllAnimators", "(J)V", (void*) android_view_RenderNode_endAllAnimators }, diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp index 90b311a..0978ebb 100644 --- a/core/jni/android_view_RenderNodeAnimator.cpp +++ b/core/jni/android_view_RenderNodeAnimator.cpp @@ -47,6 +47,15 @@ static JNIEnv* getEnv(JavaVM* vm) { return env; } +class AnimationListenerLifecycleChecker : public AnimationListener { +public: + virtual void onAnimationFinished(BaseRenderNodeAnimator* animator) { + LOG_ALWAYS_FATAL("Lifecycle failure, nStart(%p) wasn't called", animator); + } +}; + +static AnimationListenerLifecycleChecker sLifecycleChecker; + class AnimationListenerBridge : public AnimationListener { public: // This holds a strong reference to a Java WeakReference<T> object. This avoids @@ -102,6 +111,7 @@ static jlong createAnimator(JNIEnv* env, jobject clazz, jint propertyRaw, jfloat finalValue) { RenderPropertyAnimator::RenderProperty property = toRenderProperty(propertyRaw); BaseRenderNodeAnimator* animator = new RenderPropertyAnimator(property, finalValue); + animator->setListener(&sLifecycleChecker); return reinterpret_cast<jlong>( animator ); } @@ -109,6 +119,7 @@ static jlong createCanvasPropertyFloatAnimator(JNIEnv* env, jobject clazz, jlong canvasPropertyPtr, jfloat finalValue) { CanvasPropertyPrimitive* canvasProperty = reinterpret_cast<CanvasPropertyPrimitive*>(canvasPropertyPtr); BaseRenderNodeAnimator* animator = new CanvasPropertyPrimitiveAnimator(canvasProperty, finalValue); + animator->setListener(&sLifecycleChecker); return reinterpret_cast<jlong>( animator ); } @@ -119,12 +130,14 @@ static jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz, CanvasPropertyPaintAnimator::PaintField paintField = toPaintField(paintFieldRaw); BaseRenderNodeAnimator* animator = new CanvasPropertyPaintAnimator( canvasProperty, paintField, finalValue); + animator->setListener(&sLifecycleChecker); return reinterpret_cast<jlong>( animator ); } static jlong createRevealAnimator(JNIEnv* env, jobject clazz, jint centerX, jint centerY, jfloat startRadius, jfloat endRadius) { BaseRenderNodeAnimator* animator = new RevealAnimator(centerX, centerY, startRadius, endRadius); + animator->setListener(&sLifecycleChecker); return reinterpret_cast<jlong>( animator ); } @@ -161,11 +174,13 @@ static void setAllowRunningAsync(JNIEnv* env, jobject clazz, jlong animatorPtr, animator->setAllowRunningAsync(mayRunAsync); } -static void start(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) { +static void setListener(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) { + BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); + animator->setListener(new AnimationListenerBridge(env, finishListener)); +} + +static void start(JNIEnv* env, jobject clazz, jlong animatorPtr) { BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr); - if (finishListener) { - animator->setListener(new AnimationListenerBridge(env, finishListener)); - } animator->start(); } @@ -194,12 +209,16 @@ static JNINativeMethod gMethods[] = { { "nSetStartDelay", "(JJ)V", (void*) setStartDelay }, { "nSetInterpolator", "(JJ)V", (void*) setInterpolator }, { "nSetAllowRunningAsync", "(JZ)V", (void*) setAllowRunningAsync }, - { "nStart", "(JLandroid/view/RenderNodeAnimator;)V", (void*) start }, + { "nSetListener", "(JLandroid/view/RenderNodeAnimator;)V", (void*) setListener}, + { "nStart", "(J)V", (void*) start}, { "nEnd", "(J)V", (void*) end }, #endif }; int register_android_view_RenderNodeAnimator(JNIEnv* env) { +#ifdef USE_OPENGL_RENDERER + sLifecycleChecker.incStrong(0); +#endif gRenderNodeAnimatorClassInfo.clazz = FindClassOrDie(env, kClassPathName); gRenderNodeAnimatorClassInfo.clazz = MakeGlobalRefOrDie(env, gRenderNodeAnimatorClassInfo.clazz); diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 3fe50a5..7f6c50f 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -47,6 +47,11 @@ #include <ScopedUtfChars.h> +#include <AnimationContext.h> +#include <DisplayListRenderer.h> +#include <RenderNode.h> +#include <renderthread/RenderProxy.h> + // ---------------------------------------------------------------------------- namespace android { @@ -352,8 +357,70 @@ static void nativeWriteToParcel(JNIEnv* env, jclass clazz, parcel->writeStrongBinder( self != 0 ? IInterface::asBinder(self->getIGraphicBufferProducer()) : NULL); } +static jint nativeGetWidth(JNIEnv* env, jclass clazz, jlong nativeObject) { + Surface* surface = reinterpret_cast<Surface*>(nativeObject); + ANativeWindow* anw = static_cast<ANativeWindow*>(surface); + int value = 0; + anw->query(anw, NATIVE_WINDOW_WIDTH, &value); + return value; +} + +static jint nativeGetHeight(JNIEnv* env, jclass clazz, jlong nativeObject) { + Surface* surface = reinterpret_cast<Surface*>(nativeObject); + ANativeWindow* anw = static_cast<ANativeWindow*>(surface); + int value = 0; + anw->query(anw, NATIVE_WINDOW_HEIGHT, &value); + return value; +} + +namespace uirenderer { + +using namespace android::uirenderer::renderthread; + +class ContextFactory : public IContextFactory { +public: + virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { + return new AnimationContext(clock); + } +}; + +static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfacePtr) { + RenderNode* rootNode = reinterpret_cast<RenderNode*>(rootNodePtr); + sp<Surface> surface(reinterpret_cast<Surface*>(surfacePtr)); + ContextFactory factory; + RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); + proxy->loadSystemProperties(); + proxy->setSwapBehavior(kSwap_discardBuffer); + proxy->initialize(surface); + // Shadows can't be used via this interface, so just set the light source + // to all 0s. (and width & height are unused, TODO remove them) + proxy->setup(0, 0, (Vector3){0, 0, 0}, 0, 0, 0); + return (jlong) proxy; +} + +static void setSurface(JNIEnv* env, jclass clazz, jlong rendererPtr, jlong surfacePtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr); + sp<Surface> surface(reinterpret_cast<Surface*>(surfacePtr)); + proxy->updateSurface(surface); +} + +static void draw(JNIEnv* env, jclass clazz, jlong rendererPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr); + nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC); + proxy->syncAndDrawFrame(frameTimeNs, 0, 1.0f); +} + +static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr); + delete proxy; +} + +} // uirenderer + // ---------------------------------------------------------------------------- +namespace hwui = android::uirenderer; + static JNINativeMethod gSurfaceMethods[] = { {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)J", (void*)nativeCreateFromSurfaceTexture }, @@ -375,6 +442,14 @@ static JNINativeMethod gSurfaceMethods[] = { (void*)nativeReadFromParcel }, {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, + {"nativeGetWidth", "(J)I", (void*)nativeGetWidth }, + {"nativeGetHeight", "(J)I", (void*)nativeGetHeight }, + + // HWUI context + {"nHwuiCreate", "(JJ)J", (void*) hwui::create }, + {"nHwuiSetSurface", "(JJ)V", (void*) hwui::setSurface }, + {"nHwuiDraw", "(J)V", (void*) hwui::draw }, + {"nHwuiDestroy", "(J)V", (void*) hwui::destroy }, }; int register_android_view_Surface(JNIEnv* env) diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 499ff16..9b06293 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -270,14 +270,14 @@ static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject cla proxy->updateSurface(window); } -static void android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, +static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window; if (jsurface) { window = android_view_Surface_getNativeWindow(env, jsurface); } - proxy->pauseSurface(window); + return proxy->pauseSurface(window); } static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr, @@ -429,7 +429,7 @@ static JNINativeMethod gMethods[] = { { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties }, { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize }, { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, - { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface }, + { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface }, { "nSetup", "(JIIFFFFII)V", (void*) android_view_ThreadedRenderer_setup }, { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque }, { "nSyncAndDrawFrame", "(JJJF)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame }, |