12d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger/*
22d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * Copyright (C) 2018 The Android Open Source Project
32d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger *
42d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * Licensed under the Apache License, Version 2.0 (the "License");
52d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * you may not use this file except in compliance with the License.
62d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * You may obtain a copy of the License at
72d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger *
82d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger *      http://www.apache.org/licenses/LICENSE-2.0
92d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger *
102d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * Unless required by applicable law or agreed to in writing, software
112d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * distributed under the License is distributed on an "AS IS" BASIS,
122d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * See the License for the specific language governing permissions and
142d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger * limitations under the License.
152d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger */
162d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
172d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger#include "AnimatedImageDrawable.h"
185b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III#include "AnimatedImageThread.h"
192d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
202d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger#include "utils/TraceUtils.h"
212d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
222d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger#include <SkPicture.h>
232d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger#include <SkRefCnt.h>
242d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger#include <SkTLazy.h>
252d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
262d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenbergernamespace android {
272d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
28eb3b38e22cb29c6a7fccb7031263f50663cc76d0Leon Scroggins IIIAnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
29eb3b38e22cb29c6a7fccb7031263f50663cc76d0Leon Scroggins III        : mSkAnimatedImage(std::move(animatedImage)), mBytesUsed(bytesUsed) {
304afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    mTimeToShowNextSnapshot = ms2ns(mSkAnimatedImage->currentFrameDuration());
315b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III}
322d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
332d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenbergervoid AnimatedImageDrawable::syncProperties() {
345e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    mProperties = mStagingProperties;
352d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
362d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
37057c91a20dda36776b7f0bfc60bfce4331d83ab5Leon Scroggins IIIbool AnimatedImageDrawable::start() {
385b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (mRunning) {
39057c91a20dda36776b7f0bfc60bfce4331d83ab5Leon Scroggins III        return false;
40057c91a20dda36776b7f0bfc60bfce4331d83ab5Leon Scroggins III    }
412d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
42d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    mStarting = true;
431996dbb19cd43d0ffa034cafe460fe27342e584eLeon Scroggins III
445b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    mRunning = true;
455b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    return true;
462d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
472d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
48beaf5d919fa7986b96968d2282458aca9dc05b13Leon Scroggins IIIbool AnimatedImageDrawable::stop() {
49beaf5d919fa7986b96968d2282458aca9dc05b13Leon Scroggins III    bool wasRunning = mRunning;
505b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    mRunning = false;
51beaf5d919fa7986b96968d2282458aca9dc05b13Leon Scroggins III    return wasRunning;
522d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
532d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
542d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenbergerbool AnimatedImageDrawable::isRunning() {
555b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    return mRunning;
562d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
572d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
585b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins IIIbool AnimatedImageDrawable::nextSnapshotReady() const {
595b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    return mNextSnapshot.valid() &&
605b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III           mNextSnapshot.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
612d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
622d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
635b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III// Only called on the RenderThread while UI thread is locked.
644afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins IIIbool AnimatedImageDrawable::isDirty(nsecs_t* outDelay) {
654afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    *outDelay = 0;
664afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    const nsecs_t currentTime = systemTime(CLOCK_MONOTONIC);
674afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    const nsecs_t lastWallTime = mLastWallTime;
682d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
695b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    mLastWallTime = currentTime;
705b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (!mRunning) {
715b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        return false;
722d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger    }
732d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
745b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    std::unique_lock lock{mSwapLock};
754afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    mCurrentTime += currentTime - lastWallTime;
765b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
775b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (!mNextSnapshot.valid()) {
785b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // Need to trigger onDraw in order to start decoding the next frame.
794afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        *outDelay = mTimeToShowNextSnapshot - mCurrentTime;
804afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        return true;
814afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    }
824afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III
834afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    if (mTimeToShowNextSnapshot > mCurrentTime) {
844afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        *outDelay = mTimeToShowNextSnapshot - mCurrentTime;
854afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    } else if (nextSnapshotReady()) {
864afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        // We have not yet updated mTimeToShowNextSnapshot. Read frame duration
874afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        // directly from mSkAnimatedImage.
884afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        lock.unlock();
894afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        std::unique_lock imageLock{mImageLock};
904afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        *outDelay = ms2ns(mSkAnimatedImage->currentFrameDuration());
915b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        return true;
924afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    } else {
934afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        // The next snapshot has not yet been decoded, but we've already passed
944afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        // time to draw it. There's not a good way to know when decoding will
954afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        // finish, so request an update immediately.
964afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        *outDelay = 0;
975b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
985b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
994afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    return false;
1002d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
1012d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
1025b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III// Only called on the AnimatedImageThread.
1035b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins IIIAnimatedImageDrawable::Snapshot AnimatedImageDrawable::decodeNextFrame() {
1045b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    Snapshot snap;
1055b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    {
1065b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mImageLock};
1074afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        snap.mDurationMS = mSkAnimatedImage->decodeNextFrame();
1085b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot());
1095b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
1105b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1115b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    return snap;
1125b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III}
1135b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1145b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III// Only called on the AnimatedImageThread.
1155b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins IIIAnimatedImageDrawable::Snapshot AnimatedImageDrawable::reset() {
1165b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    Snapshot snap;
1175b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    {
1185b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mImageLock};
1195b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        mSkAnimatedImage->reset();
1205b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot());
1214afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        snap.mDurationMS = mSkAnimatedImage->currentFrameDuration();
1225b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
1235b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1245b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    return snap;
1255b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III}
1265b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1275b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III// Only called on the RenderThread.
1282d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenbergervoid AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
1292d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger    SkTLazy<SkPaint> lazyPaint;
1305e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    SkAutoCanvasRestore acr(canvas, false);
1315e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    if (mProperties.mAlpha != SK_AlphaOPAQUE || mProperties.mColorFilter.get()) {
1322d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        lazyPaint.init();
1335e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        lazyPaint.get()->setAlpha(mProperties.mAlpha);
1345e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        lazyPaint.get()->setColorFilter(mProperties.mColorFilter);
1352d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        lazyPaint.get()->setFilterQuality(kLow_SkFilterQuality);
1362d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger    }
1375e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    if (mProperties.mMirrored) {
1385e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        canvas->save();
1395e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
1405e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        canvas->scale(-1, 1);
1415e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    }
1422d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
143d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    const bool starting = mStarting;
144d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    mStarting = false;
145d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III
146d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    const bool drawDirectly = !mSnapshot.mPic;
147d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    if (drawDirectly) {
1485b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // The image is not animating, and never was. Draw directly from
1495b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // mSkAnimatedImage.
1502d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        if (lazyPaint.isValid()) {
1512d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger            canvas->saveLayer(mSkAnimatedImage->getBounds(), lazyPaint.get());
1522d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        }
1535b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1545b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mImageLock};
1552d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        mSkAnimatedImage->draw(canvas);
156d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        if (!mRunning) {
157d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            return;
158d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        }
159d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    } else if (starting) {
160d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        // The image has animated, and now is being reset. Queue up the first
161d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        // frame, but keep showing the current frame until the first is ready.
1625b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        auto& thread = uirenderer::AnimatedImageThread::getInstance();
1635b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        mNextSnapshot = thread.reset(sk_ref_sp(this));
1645b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
1655b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1665b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    bool finalFrame = false;
1675b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (mRunning && nextSnapshotReady()) {
1685b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mSwapLock};
1695b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        if (mCurrentTime >= mTimeToShowNextSnapshot) {
1705b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III            mSnapshot = mNextSnapshot.get();
1714afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            const nsecs_t timeToShowCurrentSnap = mTimeToShowNextSnapshot;
1724afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            if (mSnapshot.mDurationMS == SkAnimatedImage::kFinished) {
1735b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                finalFrame = true;
1745b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                mRunning = false;
1755b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III            } else {
1764afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III                mTimeToShowNextSnapshot += ms2ns(mSnapshot.mDurationMS);
1775b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                if (mCurrentTime >= mTimeToShowNextSnapshot) {
1785b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                    // This would mean showing the current frame very briefly. It's
1795b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                    // possible that not being displayed for a time resulted in
1805b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                    // mCurrentTime being far ahead. Prevent showing many frames
1815b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                    // rapidly by going back to the beginning of this frame time.
1825b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                    mCurrentTime = timeToShowCurrentSnap;
1835b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III                }
1845b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III            }
1855b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        }
1865b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
1875b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1885b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (mRunning && !mNextSnapshot.valid()) {
1895b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        auto& thread = uirenderer::AnimatedImageThread::getInstance();
1905b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        mNextSnapshot = thread.decodeNextFrame(sk_ref_sp(this));
1915b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
1925b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
193d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    if (!drawDirectly) {
1945b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // No other thread will modify mCurrentSnap so this should be safe to
1955b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // use without locking.
1965b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        canvas->drawPicture(mSnapshot.mPic, nullptr, lazyPaint.getMaybeNull());
1975b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
1985b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
1995b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (finalFrame) {
2005b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        if (mEndListener) {
2015b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III            mEndListener->onAnimationEnd();
2025b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        }
2035b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
2042d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
2052d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
2064afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins IIIint AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
2072d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger    SkAutoCanvasRestore acr(canvas, false);
2085e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    if (mStagingProperties.mAlpha != SK_AlphaOPAQUE || mStagingProperties.mColorFilter.get()) {
2092d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        SkPaint paint;
2105e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        paint.setAlpha(mStagingProperties.mAlpha);
2115e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        paint.setColorFilter(mStagingProperties.mColorFilter);
2122d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger        canvas->saveLayer(mSkAnimatedImage->getBounds(), &paint);
2132d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger    }
2145e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    if (mStagingProperties.mMirrored) {
2155e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        canvas->save();
2165e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
2175e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III        canvas->scale(-1, 1);
2185e8447f74dd371bd6e3079c126eff1d5c3df2e4bLeon Scroggins III    }
2195b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
220d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    if (!mRunning) {
221d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        // Continue drawing the current frame, and return 0 to indicate no need
222d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        // to redraw.
2235b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mImageLock};
2245b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        canvas->drawDrawable(mSkAnimatedImage.get());
2254afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        return 0;
2265b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
2275b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
228d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    if (mStarting) {
229d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        mStarting = false;
2304afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        int durationMS = 0;
231d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        {
232d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            std::unique_lock lock{mImageLock};
233d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            mSkAnimatedImage->reset();
2344afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            durationMS = mSkAnimatedImage->currentFrameDuration();
235d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        }
236d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        {
237d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            std::unique_lock lock{mSwapLock};
2384afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            mLastWallTime = 0;
2394afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            // The current time will be added later, below.
2404afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            mTimeToShowNextSnapshot = ms2ns(durationMS);
241d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        }
242d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III    }
243d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III
2445b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    bool update = false;
2455b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    {
2464afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        const nsecs_t currentTime = systemTime(CLOCK_MONOTONIC);
2475b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mSwapLock};
2485b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // mLastWallTime starts off at 0. If it is still 0, just update it to
2495b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        // the current time and avoid updating
2504afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        if (mLastWallTime == 0) {
2515b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III            mCurrentTime = currentTime;
252d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            // mTimeToShowNextSnapshot is already set to the duration of the
253d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            // first frame.
254d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            mTimeToShowNextSnapshot += currentTime;
2554afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        } else if (mRunning) {
256d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            mCurrentTime += currentTime - mLastWallTime;
257d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            update = mCurrentTime >= mTimeToShowNextSnapshot;
2585b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        }
2595b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        mLastWallTime = currentTime;
2605b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
2615b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
2624afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    int durationMS = 0;
2635b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    {
2645b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        std::unique_lock lock{mImageLock};
2655b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        if (update) {
2664afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            durationMS = mSkAnimatedImage->decodeNextFrame();
2675b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        }
2685b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
2695b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        canvas->drawDrawable(mSkAnimatedImage.get());
2705b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
2715b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III
2725b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    std::unique_lock lock{mSwapLock};
2735b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    if (update) {
2744afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        if (durationMS == SkAnimatedImage::kFinished) {
2755b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III            mRunning = false;
2764afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III            return SkAnimatedImage::kFinished;
277d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        }
278d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III
2794afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        const nsecs_t timeToShowCurrentSnapshot = mTimeToShowNextSnapshot;
2804afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III        mTimeToShowNextSnapshot += ms2ns(durationMS);
281d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III        if (mCurrentTime >= mTimeToShowNextSnapshot) {
282d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            // As in onDraw, prevent speedy catch-up behavior.
283d935157f48525d5fe7cc107c2d7aed99564b60bdLeon Scroggins III            mCurrentTime = timeToShowCurrentSnapshot;
2845b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III        }
2855b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III    }
2864afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III
2874afdd1caa4ff5f0890c3f4d73c6d475f9e06cefdLeon Scroggins III    return ns2ms(mTimeToShowNextSnapshot - mCurrentTime);
2882d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger}
2892d14213849d6df70d0fa80319ab4ffc08743a683Derek Sollenberger
2905b7f426ff04820f81877ccb696bf6245dede89e7Leon Scroggins III}  // namespace android
291