blob: 262b55323cca56537d9d4ccda63550c8e8700f24 [file] [log] [blame]
Leon Scroggins III671cce22018-01-14 16:52:17 -05001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "GraphicsJNI.h"
18#include "ImageDecoder.h"
19#include "core_jni_helpers.h"
20
Derek Sollenberger2d142132018-01-22 10:25:26 -050021#include <hwui/AnimatedImageDrawable.h>
Leon Scroggins III671cce22018-01-14 16:52:17 -050022#include <hwui/Canvas.h>
23#include <SkAndroidCodec.h>
24#include <SkAnimatedImage.h>
25#include <SkColorFilter.h>
26#include <SkPicture.h>
27#include <SkPictureRecorder.h>
28
29using namespace android;
30
Leon Scroggins III671cce22018-01-14 16:52:17 -050031
32// Note: jpostProcess holds a handle to the ImageDecoder.
33static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
34 jlong nativeImageDecoder, jobject jpostProcess,
35 jint width, jint height, jobject jsubset) {
36 if (nativeImageDecoder == 0) {
37 doThrowIOE(env, "Cannot create AnimatedImageDrawable from null!");
38 return 0;
39 }
40
41 auto* imageDecoder = reinterpret_cast<ImageDecoder*>(nativeImageDecoder);
42 auto info = imageDecoder->mCodec->getInfo();
43 const SkISize scaledSize = SkISize::Make(width, height);
44 SkIRect subset;
45 if (jsubset) {
46 GraphicsJNI::jrect_to_irect(env, jsubset, &subset);
47 } else {
48 subset = SkIRect::MakeWH(width, height);
49 }
50
51 sk_sp<SkPicture> picture;
52 if (jpostProcess) {
53 SkRect bounds = SkRect::MakeWH(subset.width(), subset.height());
54
55 SkPictureRecorder recorder;
56 SkCanvas* skcanvas = recorder.beginRecording(bounds);
57 std::unique_ptr<Canvas> canvas(Canvas::create_canvas(skcanvas));
Leon Scroggins IIIe5de9aa2018-01-10 20:56:51 -050058 postProcessAndRelease(env, jpostProcess, std::move(canvas));
Leon Scroggins III671cce22018-01-14 16:52:17 -050059 if (env->ExceptionCheck()) {
60 return 0;
61 }
62 picture = recorder.finishRecordingAsPicture();
63 }
64
Derek Sollenberger2d142132018-01-22 10:25:26 -050065
66 sk_sp<SkAnimatedImage> animatedImg = SkAnimatedImage::Make(std::move(imageDecoder->mCodec),
67 scaledSize, subset,
68 std::move(picture));
69 if (!animatedImg) {
Leon Scroggins III671cce22018-01-14 16:52:17 -050070 doThrowIOE(env, "Failed to create drawable");
71 return 0;
72 }
Leon Scroggins III671cce22018-01-14 16:52:17 -050073
Derek Sollenberger2d142132018-01-22 10:25:26 -050074 sk_sp<AnimatedImageDrawable> drawable(new AnimatedImageDrawable(animatedImg));
Leon Scroggins III671cce22018-01-14 16:52:17 -050075 return reinterpret_cast<jlong>(drawable.release());
76}
77
78static void AnimatedImageDrawable_destruct(AnimatedImageDrawable* drawable) {
Derek Sollenberger2d142132018-01-22 10:25:26 -050079 SkSafeUnref(drawable);
Leon Scroggins III671cce22018-01-14 16:52:17 -050080}
81
82static jlong AnimatedImageDrawable_nGetNativeFinalizer(JNIEnv* /*env*/, jobject /*clazz*/) {
83 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&AnimatedImageDrawable_destruct));
84}
85
86static jlong AnimatedImageDrawable_nDraw(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
Derek Sollenberger2d142132018-01-22 10:25:26 -050087 jlong canvasPtr) {
Leon Scroggins III671cce22018-01-14 16:52:17 -050088 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
Leon Scroggins III671cce22018-01-14 16:52:17 -050089 auto* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Derek Sollenberger2d142132018-01-22 10:25:26 -050090 return (jlong) canvas->drawAnimatedImage(drawable);
Leon Scroggins III671cce22018-01-14 16:52:17 -050091}
92
93static void AnimatedImageDrawable_nSetAlpha(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
94 jint alpha) {
95 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
Derek Sollenberger2d142132018-01-22 10:25:26 -050096 drawable->setStagingAlpha(alpha);
Leon Scroggins III671cce22018-01-14 16:52:17 -050097}
98
99static jlong AnimatedImageDrawable_nGetAlpha(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
100 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
Derek Sollenberger2d142132018-01-22 10:25:26 -0500101 return drawable->getStagingAlpha();
Leon Scroggins III671cce22018-01-14 16:52:17 -0500102}
103
104static void AnimatedImageDrawable_nSetColorFilter(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
105 jlong nativeFilter) {
106 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
107 auto* filter = reinterpret_cast<SkColorFilter*>(nativeFilter);
Derek Sollenberger2d142132018-01-22 10:25:26 -0500108 drawable->setStagingColorFilter(sk_ref_sp(filter));
Leon Scroggins III671cce22018-01-14 16:52:17 -0500109}
110
111static jboolean AnimatedImageDrawable_nIsRunning(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
112 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
Derek Sollenberger2d142132018-01-22 10:25:26 -0500113 return drawable->isRunning();
Leon Scroggins III671cce22018-01-14 16:52:17 -0500114}
115
Leon Scroggins III057c91a2018-01-24 13:02:16 -0500116static jboolean AnimatedImageDrawable_nStart(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
Leon Scroggins III671cce22018-01-14 16:52:17 -0500117 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
Leon Scroggins III057c91a2018-01-24 13:02:16 -0500118 return drawable->start();
Leon Scroggins III671cce22018-01-14 16:52:17 -0500119}
120
121static void AnimatedImageDrawable_nStop(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
122 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
Derek Sollenberger2d142132018-01-22 10:25:26 -0500123 drawable->stop();
Leon Scroggins III671cce22018-01-14 16:52:17 -0500124}
125
126static long AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
127 auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
128 // FIXME: Report the size of the internal SkBitmap etc.
129 return sizeof(drawable);
130}
131
132static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
133 { "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate },
134 { "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer },
Derek Sollenberger2d142132018-01-22 10:25:26 -0500135 { "nDraw", "(JJ)J", (void*) AnimatedImageDrawable_nDraw },
Leon Scroggins III671cce22018-01-14 16:52:17 -0500136 { "nSetAlpha", "(JI)V", (void*) AnimatedImageDrawable_nSetAlpha },
137 { "nGetAlpha", "(J)I", (void*) AnimatedImageDrawable_nGetAlpha },
138 { "nSetColorFilter", "(JJ)V", (void*) AnimatedImageDrawable_nSetColorFilter },
139 { "nIsRunning", "(J)Z", (void*) AnimatedImageDrawable_nIsRunning },
Leon Scroggins III057c91a2018-01-24 13:02:16 -0500140 { "nStart", "(J)Z", (void*) AnimatedImageDrawable_nStart },
Leon Scroggins III671cce22018-01-14 16:52:17 -0500141 { "nStop", "(J)V", (void*) AnimatedImageDrawable_nStop },
142 { "nNativeByteSize", "(J)J", (void*) AnimatedImageDrawable_nNativeByteSize },
143};
144
145int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
146 return android::RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedImageDrawable",
147 gAnimatedImageDrawableMethods, NELEM(gAnimatedImageDrawableMethods));
148}
149