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

Commit 428aa022 authored by Maria Yu's avatar Maria Yu Committed by Steve Kondik
Browse files

bootanimation: performance/speedup enhancements

Bootanimation: Fix the low memory device oom when run boot animation

Low memory device is easily to be oom when run boot animation. Here
we do optimize the boot animation GL Texture only one frame needed.
That is free timely and re-init it again. When in boot animation,
the fps=15, so it is ok to do the delete and re-init.

CRs-Fixed: 572325
Change-Id: I1e81c3d0f3600ac895f9bd7bd00a284f3d4b7d4c

bootanimation: Fix compilation warnings

Change-Id: Iaf7e66811f3cecf8b5b1fa690941489a7a07f7fd

bootanimation: performance/speedup enhancements (squashed from CM11)

bootanim: Don't cache textures if they're expected to use a lot of VRAM (rmcc)
https://github.com/CyanogenMod/android_frameworks_base/commit/14f9eecd3f543a25c4a2053d6155a9396a777a3a#cmds/bootanimation

bootanimation: performance enhancements (turl)
https://github.com/CyanogenMod/android_frameworks_base/commit/e6b54405aa70d7503a114d9c90ef7518abdd7133#cmds/bootanimation

bootanimation: fix usage of LOGW (intervigilium)
https://github.com/CyanogenMod/android_frameworks_base/commit/e45cf7d232490f44aecf8f2447220a8b5ace4c10#cmds/bootanimation

bootanimation: allow using RGB565 instead of ARGB8888 (tpruvot)
https://github.com/CyanogenMod/android_frameworks_base/commit/204282870a9c69b04ad5ddecd73fafbd7996cbc0#cmds/bootanimation

Change-Id: I203fa23f77d1349fb822a7662e2cd3998ba4c814

bootanimation: Do not free frame map

The frame map is reused when needSaveMem==true, resulting in a double
free and segfault.

The only side effect would seem to be failure to cleanup all resources
at exit.  That's acceptable, as the kernel will do it anyway.

Note that in 12.1, the frame map release commit was reverted by CAF in
commit I535330edb636f9457beed0849147168eaa6ae2ec, which results in the
same behavior.

Change-Id: I4ea66dccd1f5c9d784701242fba8700bce271579

bootanimation: Switch to readahead

Change-Id: I287132e311e96c0437df67c76b86bb47b8f8380e

[mikeioannina]: Adjust for cm-14.0

Change-Id: I203fa23f77d1349fb822a7662e2cd3998ba4c814
parent 98807e37
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -27,6 +27,22 @@ LOCAL_SHARED_LIBRARIES := \
    libregionalization \
    libmedia

ifeq ($(TARGET_BOOTANIMATION_PRELOAD),true)
    LOCAL_CFLAGS += -DPRELOAD_BOOTANIMATION
endif

ifeq ($(TARGET_BOOTANIMATION_TEXTURE_CACHE),true)
    LOCAL_CFLAGS += -DNO_TEXTURE_CACHE=0
endif

ifeq ($(TARGET_BOOTANIMATION_TEXTURE_CACHE),false)
    LOCAL_CFLAGS += -DNO_TEXTURE_CACHE=1
endif

ifeq ($(TARGET_BOOTANIMATION_USE_RGB565),true)
    LOCAL_CFLAGS += -DUSE_565
endif

LOCAL_MODULE:= bootanimation

LOCAL_INIT_RC := bootanim.rc
+116 −8
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <time.h>
#include <pthread.h>
#include <sys/select.h>
#include <sys/syscall.h>

#include <cutils/properties.h>

@@ -118,6 +119,57 @@ class MPlayerListener : public MediaPlayerListener
    }
};

static unsigned long getFreeMemory(void)
{
    int fd = open("/proc/meminfo", O_RDONLY);
    const char* const sums[] = { "MemFree:", "Cached:", NULL };
    const size_t sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 };
    unsigned int num = 2;

    if (fd < 0) {
        ALOGW("Unable to open /proc/meminfo");
        return -1;
    }

    char buffer[256];
    const int len = read(fd, buffer, sizeof(buffer)-1);
    close(fd);

    if (len < 0) {
        ALOGW("Unable to read /proc/meminfo");
        return -1;
    }
    buffer[len] = 0;

    size_t numFound = 0;
    unsigned long mem = 0;

    char* p = buffer;
    while (*p && numFound < num) {
        int i = 0;
        while (sums[i]) {
            if (strncmp(p, sums[i], sumsLen[i]) == 0) {
                p += sumsLen[i];
                while (*p == ' ') p++;
                char* num = p;
                while (*p >= '0' && *p <= '9') p++;
                if (*p != 0) {
                    *p = 0;
                    p++;
                    if (*p == 0) p--;
                }
                mem += atoll(num);
                numFound++;
                break;
            }
            i++;
        }
        p++;
    }

    return numFound > 0 ? mem : -1;
}

BootAnimation::BootAnimation() : Thread(false), mClockEnabled(true) {
    mSession = new SurfaceComposerClient();
}
@@ -217,16 +269,15 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame)
    if (codec != NULL) {
        codec->setDitherImage(false);
        codec->decode(&stream, &bitmap,
                #ifdef USE_565
                kRGB_565_SkColorType,
                #else
                kN32_SkColorType,
                #endif
                SkImageDecoder::kDecodePixels_Mode);
        delete codec;
    }

    // FileMap memory is never released until application exit.
    // Release it now as the texture is already loaded and the memory used for
    // the packed resource can be released.
    delete frame.map;

    // ensure we can call getPixels(). No need to call unlock, since the
    // bitmap will go out of scope when we return from this method.
    bitmap.lockPixels();
@@ -482,6 +533,33 @@ status_t BootAnimation::readyToRun() {
    else if (access(getAnimationFileName(IMG_SYS), R_OK) == 0) {
        mZipFileName = getAnimationFileName(IMG_SYS);
    }

#ifdef PRELOAD_BOOTANIMATION
    // Preload the bootanimation zip on memory, so we don't stutter
    // when showing the animation
    FILE* fd;
    if (encryptedAnimation && access(getAnimationFileName(IMG_ENC), R_OK) == 0)
        fd = fopen(getAnimationFileName(IMG_ENC), "r");
    else if (access(getAnimationFileName(IMG_OEM), R_OK) == 0)
        fd = fopen(getAnimationFileName(IMG_OEM), "r");
    else if (access(getAnimationFileName(IMG_SYS), R_OK) == 0)
        fd = fopen(getAnimationFileName(IMG_SYS), "r");
    else
        return NO_ERROR;

    if (fd != NULL) {
        // Since including fcntl.h doesn't give us the wrapper, use the syscall.
        // 32 bits takes LO/HI offset (we don't care about endianness of 0).
#if defined(__aarch64__) || defined(__x86_64__)
        if (syscall(__NR_readahead, fd, 0, INT_MAX))
#else
        if (syscall(__NR_readahead, fd, 0, 0, INT_MAX))
#endif
            ALOGW("Unable to cache the animation");
        fclose(fd);
    }
#endif

    return NO_ERROR;
}

@@ -882,8 +960,34 @@ bool BootAnimation::playAnimation(const Animation& animation)
    for (size_t i=0 ; i<pcount ; i++) {
        const Animation::Part& part(animation.parts[i]);
        const size_t fcount = part.frames.size();

        // can be 1, 0, or not set
        #ifdef NO_TEXTURE_CACHE
        const int noTextureCache = NO_TEXTURE_CACHE;
        #else
        const int noTextureCache =
                ((animation.width * animation.height * fcount) > 48 * 1024 * 1024) ? 1 : 0;
        #endif

        glBindTexture(GL_TEXTURE_2D, 0);

        // Calculate if we need to save memory by disabling texture cache
        // If free memory is less than the max texture size, cache will be disabled
        GLint mMaxTextureSize;
        bool needSaveMem = false;
        GLuint mTextureid;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
        ALOGD("Free memory: %ld, max texture size: %d", getFreeMemory(), mMaxTextureSize);
        if (getFreeMemory() < mMaxTextureSize * mMaxTextureSize * fcount / 1024 ||
                noTextureCache) {
            ALOGD("Disabled bootanimation texture cache, FPS drops might occur.");
            needSaveMem = true;
            glGenTextures(1, &mTextureid);
            glBindTexture(GL_TEXTURE_2D, mTextureid);
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        }

        // Handle animation package
        if (part.animation != NULL) {
            playAnimation(*part.animation);
@@ -912,10 +1016,10 @@ bool BootAnimation::playAnimation(const Animation& animation)
                const Animation::Frame& frame(part.frames[j]);
                nsecs_t lastFrame = systemTime();

                if (r > 0) {
                if (r > 0 && !needSaveMem) {
                    glBindTexture(GL_TEXTURE_2D, frame.tid);
                } else {
                    if (part.count != 1) {
                    if (!needSaveMem && part.count != 1) {
                        glGenTextures(1, &frame.tid);
                        glBindTexture(GL_TEXTURE_2D, frame.tid);
                        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -972,12 +1076,16 @@ bool BootAnimation::playAnimation(const Animation& animation)
        }

        // free the textures for this part
        if (part.count != 1) {
        if (!needSaveMem && part.count != 1) {
            for (size_t j=0 ; j<fcount ; j++) {
                const Animation::Frame& frame(part.frames[j]);
                glDeleteTextures(1, &frame.tid);
            }
        }

        if (needSaveMem) {
            glDeleteTextures(1, &mTextureid);
        }
    }

    property_get("persist.sys.silent", value, "null");