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