Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01f8f4fe authored by Jerome Gaillard's avatar Jerome Gaillard
Browse files

Add AnimatedImageDrawable to host build of libhwui

This puts Looper usages behind #ifdef __ANDROID__ as the looper is not
supported on host builds. Instead of using the looper to call the
InvokeListener, the listener is called directly for host.

Bug: 322360037
Test: build libhwui on host
Change-Id: I133fa5a7b50e9681160f0a70c23f3946b51a7cd6
parent 5ac36395
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ cc_defaults {
        "jni/android_nio_utils.cpp",
        "jni/android_util_PathParser.cpp",

        "jni/AnimatedImageDrawable.cpp",
        "jni/Bitmap.cpp",
        "jni/BitmapRegionDecoder.cpp",
        "jni/BufferUtils.cpp",
@@ -418,7 +419,6 @@ cc_defaults {
    target: {
        android: {
            srcs: [ // sources that depend on android only libraries
                "jni/AnimatedImageDrawable.cpp",
                "jni/android_graphics_TextureLayer.cpp",
                "jni/android_graphics_HardwareRenderer.cpp",
                "jni/android_graphics_HardwareBufferRenderer.cpp",
@@ -539,6 +539,7 @@ cc_defaults {
        "renderthread/RenderTask.cpp",
        "renderthread/TimeLord.cpp",
        "hwui/AnimatedImageDrawable.cpp",
        "hwui/AnimatedImageThread.cpp",
        "hwui/Bitmap.cpp",
        "hwui/BlurDrawLooper.cpp",
        "hwui/Canvas.cpp",
@@ -599,7 +600,6 @@ cc_defaults {
            local_include_dirs: ["platform/android"],

            srcs: [
                "hwui/AnimatedImageThread.cpp",
                "pipeline/skia/ATraceMemoryDump.cpp",
                "pipeline/skia/GLFunctorDrawable.cpp",
                "pipeline/skia/LayerDrawable.cpp",
+4 −10
Original line number Diff line number Diff line
@@ -15,18 +15,16 @@
 */

#include "AnimatedImageDrawable.h"
#ifdef __ANDROID__ // Layoutlib does not support AnimatedImageThread
#include "AnimatedImageThread.h"
#endif

#include <gui/TraceUtils.h>
#include "pipeline/skia/SkiaUtils.h"

#include <SkPicture.h>
#include <SkRefCnt.h>
#include <gui/TraceUtils.h>

#include <optional>

#include "AnimatedImageThread.h"
#include "pipeline/skia/SkiaUtils.h"

namespace android {

AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed,
@@ -185,10 +183,8 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
    } else if (starting) {
        // The image has animated, and now is being reset. Queue up the first
        // frame, but keep showing the current frame until the first is ready.
#ifdef __ANDROID__ // Layoutlib does not support AnimatedImageThread
        auto& thread = uirenderer::AnimatedImageThread::getInstance();
        mNextSnapshot = thread.reset(sk_ref_sp(this));
#endif
    }

    bool finalFrame = false;
@@ -214,10 +210,8 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
    }

    if (mRunning && !mNextSnapshot.valid()) {
#ifdef __ANDROID__ // Layoutlib does not support AnimatedImageThread
        auto& thread = uirenderer::AnimatedImageThread::getInstance();
        mNextSnapshot = thread.decodeNextFrame(sk_ref_sp(this));
#endif
    }

    if (!drawDirectly) {
+4 −0
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

#include "AnimatedImageThread.h"

#ifdef __ANDROID__
#include <sys/resource.h>
#endif

namespace android {
namespace uirenderer {
@@ -31,7 +33,9 @@ AnimatedImageThread& AnimatedImageThread::getInstance() {
}

AnimatedImageThread::AnimatedImageThread() {
#ifdef __ANDROID__
    setpriority(PRIO_PROCESS, 0, PRIORITY_NORMAL + PRIORITY_MORE_FAVORABLE);
#endif
}

std::future<AnimatedImageDrawable::Snapshot> AnimatedImageThread::decodeNextFrame(
+36 −0
Original line number Diff line number Diff line
@@ -25,7 +25,9 @@
#include <hwui/AnimatedImageDrawable.h>
#include <hwui/Canvas.h>
#include <hwui/ImageDecoder.h>
#ifdef __ANDROID__
#include <utils/Looper.h>
#endif

#include "ColorFilter.h"
#include "GraphicsJNI.h"
@@ -180,6 +182,23 @@ static void AnimatedImageDrawable_nSetRepeatCount(JNIEnv* env, jobject /*clazz*/
    drawable->setRepetitionCount(loopCount);
}

#ifndef __ANDROID__
struct Message {
    Message(int w) {}
};

class MessageHandler : public virtual RefBase {
protected:
    virtual ~MessageHandler() override {}

public:
    /**
     * Handles a message.
     */
    virtual void handleMessage(const Message& message) = 0;
};
#endif

class InvokeListener : public MessageHandler {
public:
    InvokeListener(JNIEnv* env, jobject javaObject) {
@@ -204,6 +223,7 @@ private:
};

class JniAnimationEndListener : public OnAnimationEndListener {
#ifdef __ANDROID__
public:
    JniAnimationEndListener(sp<Looper>&& looper, JNIEnv* env, jobject javaObject) {
        mListener = new InvokeListener(env, javaObject);
@@ -215,6 +235,17 @@ public:
private:
    sp<InvokeListener> mListener;
    sp<Looper> mLooper;
#else
public:
    JniAnimationEndListener(JNIEnv* env, jobject javaObject) {
        mListener = new InvokeListener(env, javaObject);
    }

    void onAnimationEnd() override { mListener->handleMessage(0); }

private:
    sp<InvokeListener> mListener;
#endif
};

static void AnimatedImageDrawable_nSetOnAnimationEndListener(JNIEnv* env, jobject /*clazz*/,
@@ -223,6 +254,7 @@ static void AnimatedImageDrawable_nSetOnAnimationEndListener(JNIEnv* env, jobjec
    if (!jdrawable) {
        drawable->setOnAnimationEndListener(nullptr);
    } else {
#ifdef __ANDROID__
        sp<Looper> looper = Looper::getForThread();
        if (!looper.get()) {
            doThrowISE(env,
@@ -233,6 +265,10 @@ static void AnimatedImageDrawable_nSetOnAnimationEndListener(JNIEnv* env, jobjec

        drawable->setOnAnimationEndListener(
                std::make_unique<JniAnimationEndListener>(std::move(looper), env, jdrawable));
#else
        drawable->setOnAnimationEndListener(
                std::make_unique<JniAnimationEndListener>(env, jdrawable));
#endif
    }
}