2bcdf6fbdf
Bug: skbug.com/10154 Test: CtsGraphicsTestCases The API is being moved to a new file and renamed. Use the new API. Remove an unncessary FIXME and comment in Movie.cpp. The hardcoded 6 is fine, and the ownership is obvious now that we use smart pointers. Change-Id: I79657626ccbd5fe2616d546c617d591928064106
163 lines
5.7 KiB
C++
163 lines
5.7 KiB
C++
#include "CreateJavaOutputStreamAdaptor.h"
|
|
#include "FrontBufferedStream.h"
|
|
#include "GraphicsJNI.h"
|
|
#include <nativehelper/ScopedLocalRef.h>
|
|
#include "Movie.h"
|
|
#include "SkStream.h"
|
|
#include "SkUtils.h"
|
|
#include "Utils.h"
|
|
|
|
#include <androidfw/Asset.h>
|
|
#include <androidfw/ResourceTypes.h>
|
|
#include <hwui/Canvas.h>
|
|
#include <hwui/Paint.h>
|
|
#include <netinet/in.h>
|
|
|
|
static jclass gMovie_class;
|
|
static jmethodID gMovie_constructorMethodID;
|
|
static jfieldID gMovie_nativeInstanceID;
|
|
|
|
jobject create_jmovie(JNIEnv* env, Movie* moov) {
|
|
if (NULL == moov) {
|
|
return NULL;
|
|
}
|
|
return env->NewObject(gMovie_class, gMovie_constructorMethodID,
|
|
static_cast<jlong>(reinterpret_cast<uintptr_t>(moov)));
|
|
}
|
|
|
|
static Movie* J2Movie(JNIEnv* env, jobject movie) {
|
|
SkASSERT(env);
|
|
SkASSERT(movie);
|
|
SkASSERT(env->IsInstanceOf(movie, gMovie_class));
|
|
Movie* m = (Movie*)env->GetLongField(movie, gMovie_nativeInstanceID);
|
|
SkASSERT(m);
|
|
return m;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
static jint movie_width(JNIEnv* env, jobject movie) {
|
|
NPE_CHECK_RETURN_ZERO(env, movie);
|
|
return static_cast<jint>(J2Movie(env, movie)->width());
|
|
}
|
|
|
|
static jint movie_height(JNIEnv* env, jobject movie) {
|
|
NPE_CHECK_RETURN_ZERO(env, movie);
|
|
return static_cast<jint>(J2Movie(env, movie)->height());
|
|
}
|
|
|
|
static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
|
|
NPE_CHECK_RETURN_ZERO(env, movie);
|
|
return J2Movie(env, movie)->isOpaque() ? JNI_TRUE : JNI_FALSE;
|
|
}
|
|
|
|
static jint movie_duration(JNIEnv* env, jobject movie) {
|
|
NPE_CHECK_RETURN_ZERO(env, movie);
|
|
return static_cast<jint>(J2Movie(env, movie)->duration());
|
|
}
|
|
|
|
static jboolean movie_setTime(JNIEnv* env, jobject movie, jint ms) {
|
|
NPE_CHECK_RETURN_ZERO(env, movie);
|
|
return J2Movie(env, movie)->setTime(ms) ? JNI_TRUE : JNI_FALSE;
|
|
}
|
|
|
|
static void movie_draw(JNIEnv* env, jobject movie, jlong canvasHandle,
|
|
jfloat fx, jfloat fy, jlong paintHandle) {
|
|
NPE_CHECK_RETURN_VOID(env, movie);
|
|
|
|
android::Canvas* c = reinterpret_cast<android::Canvas*>(canvasHandle);
|
|
const android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
|
|
|
|
// Canvas should never be NULL. However paint is an optional parameter and
|
|
// therefore may be NULL.
|
|
SkASSERT(c != NULL);
|
|
|
|
Movie* m = J2Movie(env, movie);
|
|
const SkBitmap& b = m->bitmap();
|
|
sk_sp<android::Bitmap> wrapper = android::Bitmap::createFrom(b.info(), *b.pixelRef());
|
|
c->drawBitmap(*wrapper, fx, fy, p);
|
|
}
|
|
|
|
static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
|
|
android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
|
|
if (asset == NULL) return NULL;
|
|
android::AssetStreamAdaptor stream(asset);
|
|
Movie* moov = Movie::DecodeStream(&stream);
|
|
return create_jmovie(env, moov);
|
|
}
|
|
|
|
static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
|
|
|
|
NPE_CHECK_RETURN_ZERO(env, istream);
|
|
|
|
jbyteArray byteArray = env->NewByteArray(16*1024);
|
|
ScopedLocalRef<jbyteArray> scoper(env, byteArray);
|
|
SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray);
|
|
if (NULL == strm) {
|
|
return 0;
|
|
}
|
|
|
|
// Need to buffer enough input to be able to rewind as much as might be read by a decoder
|
|
// trying to determine the stream's format. The only decoder for movies is GIF, which
|
|
// will only read 6.
|
|
std::unique_ptr<SkStreamRewindable> bufferedStream(
|
|
android::skia::FrontBufferedStream::Make(std::unique_ptr<SkStream>(strm), 6));
|
|
SkASSERT(bufferedStream.get() != NULL);
|
|
|
|
Movie* moov = Movie::DecodeStream(bufferedStream.get());
|
|
return create_jmovie(env, moov);
|
|
}
|
|
|
|
static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
|
|
jbyteArray byteArray,
|
|
jint offset, jint length) {
|
|
|
|
NPE_CHECK_RETURN_ZERO(env, byteArray);
|
|
|
|
int totalLength = env->GetArrayLength(byteArray);
|
|
if ((offset | length) < 0 || offset + length > totalLength) {
|
|
doThrowAIOOBE(env);
|
|
return 0;
|
|
}
|
|
|
|
AutoJavaByteArray ar(env, byteArray);
|
|
Movie* moov = Movie::DecodeMemory(ar.ptr() + offset, length);
|
|
return create_jmovie(env, moov);
|
|
}
|
|
|
|
static void movie_destructor(JNIEnv* env, jobject, jlong movieHandle) {
|
|
Movie* movie = (Movie*) movieHandle;
|
|
delete movie;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static const JNINativeMethod gMethods[] = {
|
|
{ "width", "()I", (void*)movie_width },
|
|
{ "height", "()I", (void*)movie_height },
|
|
{ "isOpaque", "()Z", (void*)movie_isOpaque },
|
|
{ "duration", "()I", (void*)movie_duration },
|
|
{ "setTime", "(I)Z", (void*)movie_setTime },
|
|
{ "nDraw", "(JFFJ)V",
|
|
(void*)movie_draw },
|
|
{ "nativeDecodeAsset", "(J)Landroid/graphics/Movie;",
|
|
(void*)movie_decodeAsset },
|
|
{ "nativeDecodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;",
|
|
(void*)movie_decodeStream },
|
|
{ "nativeDestructor","(J)V", (void*)movie_destructor },
|
|
{ "decodeByteArray", "([BII)Landroid/graphics/Movie;",
|
|
(void*)movie_decodeByteArray },
|
|
};
|
|
|
|
int register_android_graphics_Movie(JNIEnv* env)
|
|
{
|
|
gMovie_class = android::FindClassOrDie(env, "android/graphics/Movie");
|
|
gMovie_class = android::MakeGlobalRefOrDie(env, gMovie_class);
|
|
|
|
gMovie_constructorMethodID = android::GetMethodIDOrDie(env, gMovie_class, "<init>", "(J)V");
|
|
|
|
gMovie_nativeInstanceID = android::GetFieldIDOrDie(env, gMovie_class, "mNativeMovie", "J");
|
|
|
|
return android::RegisterMethodsOrDie(env, "android/graphics/Movie", gMethods, NELEM(gMethods));
|
|
}
|