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

Commit 50a2f36f authored by Huihong Luo's avatar Huihong Luo
Browse files

Preload zip before waiting for surface flinger

This saves about 200 msec by preloading media zip file before waiting
for surface flinger becomes ready.

Android Auto results:
BootAnimation: BootAnimationPreloadTiming start time: 8261ms
BootAnimation: BootAnimationPreloadStopTiming start time: 8508ms

Bug: 62056504

Test: adb logcat -s BootAnimation
Change-Id: Iaedf774983a66c2838452c45a04b3a1f4c728f17
parent dbc97088
Loading
Loading
Loading
Loading
+55 −14
Original line number Diff line number Diff line
@@ -110,13 +110,30 @@ BootAnimation::BootAnimation(sp<Callbacks> callbacks)
    } else {
        mShuttingDown = true;
    }
    ALOGD("%sAnimationStartTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
            elapsedRealtime());
}

BootAnimation::~BootAnimation() {
    if (mAnimation != nullptr) {
        releaseAnimation(mAnimation);
        mAnimation = nullptr;
    }
    ALOGD("%sAnimationStopTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
            elapsedRealtime());
}

void BootAnimation::onFirstRef() {
    status_t err = mSession->linkToComposerDeath(this);
    SLOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
    if (err == NO_ERROR) {
        run("BootAnimation", PRIORITY_DISPLAY);
        // Load the animation content -- this can be slow (eg 200ms)
        // called before waitForSurfaceFlinger() in main() to avoid wait
        ALOGD("%sAnimationPreloadTiming start time: %" PRId64 "ms",
                mShuttingDown ? "Shutdown" : "Boot", elapsedRealtime());
        preloadAnimation();
        ALOGD("%sAnimationPreloadStopTiming start time: %" PRId64 "ms",
                mShuttingDown ? "Shutdown" : "Boot", elapsedRealtime());
    }
}

@@ -306,6 +323,20 @@ status_t BootAnimation::readyToRun() {
    mFlingerSurface = s;
    mTargetInset = -1;

    return NO_ERROR;
}

bool BootAnimation::preloadAnimation() {
    findBootAnimationFile();
    if (!mZipFileName.isEmpty()) {
        mAnimation = loadAnimation(mZipFileName);
        return (mAnimation != nullptr);
    }

    return false;
}

void BootAnimation::findBootAnimationFile() {
    // If the device has encryption turned on or is in process
    // of being encrypted we show the encrypted boot animation.
    char decrypt[PROPERTY_VALUE_MAX];
@@ -320,7 +351,7 @@ status_t BootAnimation::readyToRun() {
        for (const char* f : encryptedBootFiles) {
            if (access(f, R_OK) == 0) {
                mZipFileName = f;
                return NO_ERROR;
                return;
            }
        }
    }
@@ -332,10 +363,9 @@ status_t BootAnimation::readyToRun() {
    for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
        if (access(f, R_OK) == 0) {
            mZipFileName = f;
            return NO_ERROR;
            return;
        }
    }
    return NO_ERROR;
}

bool BootAnimation::threadLoop()
@@ -790,8 +820,6 @@ bool BootAnimation::preloadZip(Animation& animation)
        }
    }

    mCallbacks->init(animation.parts);

    zip->endIteration(cookie);

    return true;
@@ -799,13 +827,25 @@ bool BootAnimation::preloadZip(Animation& animation)

bool BootAnimation::movie()
{
    Animation* animation = loadAnimation(mZipFileName);
    if (animation == NULL)
    if (mAnimation == nullptr) {
        mAnimation = loadAnimation(mZipFileName);
    }

    if (mAnimation == nullptr)
        return false;

    // mCallbacks->init() may get called recursively,
    // this loop is needed to get the same results
    for (const Animation::Part& part : mAnimation->parts) {
        if (part.animation != nullptr) {
            mCallbacks->init(part.animation->parts);
        }
    }
    mCallbacks->init(mAnimation->parts);

    bool anyPartHasClock = false;
    for (size_t i=0; i < animation->parts.size(); i++) {
        if(validClock(animation->parts[i])) {
    for (size_t i=0; i < mAnimation->parts.size(); i++) {
        if(validClock(mAnimation->parts[i])) {
            anyPartHasClock = true;
            break;
        }
@@ -846,7 +886,7 @@ bool BootAnimation::movie()
    bool clockFontInitialized = false;
    if (mClockEnabled) {
        clockFontInitialized =
            (initFont(&animation->clockFont, CLOCK_FONT_ASSET) == NO_ERROR);
            (initFont(&mAnimation->clockFont, CLOCK_FONT_ASSET) == NO_ERROR);
        mClockEnabled = clockFontInitialized;
    }

@@ -855,7 +895,7 @@ bool BootAnimation::movie()
        mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
    }

    playAnimation(*animation);
    playAnimation(*mAnimation);

    if (mTimeCheckThread != nullptr) {
        mTimeCheckThread->requestExit();
@@ -863,10 +903,11 @@ bool BootAnimation::movie()
    }

    if (clockFontInitialized) {
        glDeleteTextures(1, &animation->clockFont.texture.name);
        glDeleteTextures(1, &mAnimation->clockFont.texture.name);
    }

    releaseAnimation(animation);
    releaseAnimation(mAnimation);
    mAnimation = nullptr;

    return false;
}
+4 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ public:
    };

    explicit BootAnimation(sp<Callbacks> callbacks);
    virtual ~BootAnimation();

    sp<SurfaceComposerClient> session() const;

@@ -155,6 +156,8 @@ private:
    void releaseAnimation(Animation*) const;
    bool parseAnimationDesc(Animation&);
    bool preloadZip(Animation &animation);
    void findBootAnimationFile();
    bool preloadAnimation();

    void checkExit();

@@ -182,6 +185,7 @@ private:
    SortedVector<String8> mLoadedFiles;
    sp<TimeCheckThread> mTimeCheckThread = nullptr;
    sp<Callbacks> mCallbacks;
    Animation* mAnimation = nullptr;
};

// ---------------------------------------------------------------------------
+5 −3
Original line number Diff line number Diff line
@@ -44,14 +44,16 @@ int main()
        sp<ProcessState> proc(ProcessState::self());
        ProcessState::self()->startThreadPool();

        // create the boot animation object (may take up to 200ms for 2MB zip)
        sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());

        waitForSurfaceFlinger();

        // create the boot animation object
        sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());
        boot->run("BootAnimation", PRIORITY_DISPLAY);

        ALOGV("Boot animation set up. Joining pool.");

        IPCThreadState::self()->joinThreadPool();
    }
    ALOGV("Boot animation exit");
    return 0;
}