blob: dc180188100b115ef4ce54183d68cab1e2d6217e [file] [log] [blame]
John Recke45b1fd2014-04-15 09:50:16 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
John Recke45b1fd2014-04-15 09:50:16 -070017#include "Animator.h"
18
John Reck68bfe0a2014-06-24 15:34:58 -070019#include <inttypes.h>
John Recke45b1fd2014-04-15 09:50:16 -070020#include <set>
21
John Reck119907c2014-08-14 09:02:01 -070022#include "AnimationContext.h"
Tom Hudson2dc236b2014-10-15 15:46:42 -040023#include "Interpolator.h"
John Reck52244ff2014-05-01 21:27:37 -070024#include "RenderNode.h"
John Recke45b1fd2014-04-15 09:50:16 -070025#include "RenderProperties.h"
26
27namespace android {
28namespace uirenderer {
29
30/************************************************************
John Reckff941dc2014-05-14 16:34:14 -070031 * BaseRenderNodeAnimator
John Recke45b1fd2014-04-15 09:50:16 -070032 ************************************************************/
33
John Reckff941dc2014-05-14 16:34:14 -070034BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
Chris Craikd41c4d82015-01-05 15:51:13 -080035 : mTarget(nullptr)
Doris Liu8b083202016-02-19 21:46:06 +000036 , mStagingTarget(nullptr)
John Reck8d8af3c2014-07-01 15:23:45 -070037 , mFinalValue(finalValue)
John Reckff941dc2014-05-14 16:34:14 -070038 , mDeltaValue(0)
39 , mFromValue(0)
Chris Craikb9ce116d2015-08-20 15:14:06 -070040 , mStagingPlayState(PlayState::NotStarted)
41 , mPlayState(PlayState::NotStarted)
John Reck68bfe0a2014-06-24 15:34:58 -070042 , mHasStartValue(false)
John Recke45b1fd2014-04-15 09:50:16 -070043 , mStartTime(0)
Alan Viverettead2f8e32014-05-16 13:28:33 -070044 , mDuration(300)
Chris Craik572d9ac2014-09-12 17:40:20 -070045 , mStartDelay(0)
Doris Liuc4bb1852016-02-19 21:39:21 +000046 , mMayRunAsync(true)
47 , mPlayTime(0) {
John Recke45b1fd2014-04-15 09:50:16 -070048}
49
John Reckff941dc2014-05-14 16:34:14 -070050BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
John Reck68bfe0a2014-06-24 15:34:58 -070051}
52
53void BaseRenderNodeAnimator::checkMutable() {
54 // Should be impossible to hit as the Java-side also has guards for this
Chris Craikb9ce116d2015-08-20 15:14:06 -070055 LOG_ALWAYS_FATAL_IF(mStagingPlayState != PlayState::NotStarted,
John Reck68bfe0a2014-06-24 15:34:58 -070056 "Animator has already been started!");
John Recke45b1fd2014-04-15 09:50:16 -070057}
58
John Reckff941dc2014-05-14 16:34:14 -070059void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
John Reck68bfe0a2014-06-24 15:34:58 -070060 checkMutable();
Chris Craik51d6a3d2014-12-22 17:16:56 -080061 mInterpolator.reset(interpolator);
John Recke45b1fd2014-04-15 09:50:16 -070062}
63
John Reckff941dc2014-05-14 16:34:14 -070064void BaseRenderNodeAnimator::setStartValue(float value) {
John Reck68bfe0a2014-06-24 15:34:58 -070065 checkMutable();
66 doSetStartValue(value);
John Reckff941dc2014-05-14 16:34:14 -070067}
68
John Reck68bfe0a2014-06-24 15:34:58 -070069void BaseRenderNodeAnimator::doSetStartValue(float value) {
70 mFromValue = value;
71 mDeltaValue = (mFinalValue - mFromValue);
72 mHasStartValue = true;
John Reckff941dc2014-05-14 16:34:14 -070073}
74
Alan Viverettead2f8e32014-05-16 13:28:33 -070075void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
John Reck68bfe0a2014-06-24 15:34:58 -070076 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070077 mDuration = duration;
78}
79
80void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
John Reck68bfe0a2014-06-24 15:34:58 -070081 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070082 mStartDelay = startDelay;
83}
84
John Reck8d8af3c2014-07-01 15:23:45 -070085void BaseRenderNodeAnimator::attach(RenderNode* target) {
Doris Liu8b083202016-02-19 21:46:06 +000086 mStagingTarget = target;
John Reck8d8af3c2014-07-01 15:23:45 -070087 onAttached();
88}
89
Doris Liuc4bb1852016-02-19 21:39:21 +000090void BaseRenderNodeAnimator::start() {
91 mStagingPlayState = PlayState::Running;
92 mStagingRequests.push_back(Request::Start);
93 onStagingPlayStateChanged();
94}
95
96void BaseRenderNodeAnimator::cancel() {
97 mStagingPlayState = PlayState::Finished;
98 mStagingRequests.push_back(Request::Cancel);
99 onStagingPlayStateChanged();
100}
101
102void BaseRenderNodeAnimator::reset() {
103 mStagingPlayState = PlayState::Finished;
104 mStagingRequests.push_back(Request::Reset);
105 onStagingPlayStateChanged();
106}
107
108void BaseRenderNodeAnimator::reverse() {
109 mStagingPlayState = PlayState::Reversing;
110 mStagingRequests.push_back(Request::Reverse);
111 onStagingPlayStateChanged();
112}
113
114void BaseRenderNodeAnimator::end() {
115 mStagingPlayState = PlayState::Finished;
116 mStagingRequests.push_back(Request::End);
117 onStagingPlayStateChanged();
118}
119
120void BaseRenderNodeAnimator::resolveStagingRequest(Request request) {
121 switch (request) {
122 case Request::Start:
123 mPlayTime = (mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) ?
124 mPlayTime : 0;
125 mPlayState = PlayState::Running;
126 break;
127 case Request::Reverse:
128 mPlayTime = (mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) ?
129 mPlayTime : mDuration;
130 mPlayState = PlayState::Reversing;
131 break;
132 case Request::Reset:
133 mPlayTime = 0;
134 mPlayState = PlayState::Finished;
135 break;
136 case Request::Cancel:
137 mPlayState = PlayState::Finished;
138 break;
139 case Request::End:
140 mPlayTime = mPlayState == PlayState::Reversing ? 0 : mDuration;
141 mPlayState = PlayState::Finished;
142 break;
143 default:
144 LOG_ALWAYS_FATAL("Invalid staging request: %d", static_cast<int>(request));
145 };
146}
147
John Reck119907c2014-08-14 09:02:01 -0700148void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) {
Doris Liu8b083202016-02-19 21:46:06 +0000149 if (mStagingTarget) {
150 RenderNode* oldTarget = mTarget;
151 mTarget = mStagingTarget;
152 mStagingTarget = nullptr;
153 if (oldTarget && oldTarget != mTarget) {
154 oldTarget->onAnimatorTargetChanged(this);
155 }
156 }
157
John Reck68bfe0a2014-06-24 15:34:58 -0700158 if (!mHasStartValue) {
John Reck8d8af3c2014-07-01 15:23:45 -0700159 doSetStartValue(getValue(mTarget));
Alan Viverettead2f8e32014-05-16 13:28:33 -0700160 }
Doris Liuc4bb1852016-02-19 21:39:21 +0000161
162 if (!mStagingRequests.empty()) {
Doris Liu148f57f2016-02-19 17:19:24 -0800163 // No interpolator was set, use the default
164 if (mPlayState == PlayState::NotStarted && !mInterpolator) {
165 mInterpolator.reset(Interpolator::createDefaultInterpolator());
166 }
Doris Liuc4bb1852016-02-19 21:39:21 +0000167 // Keep track of the play state and play time before they are changed when
168 // staging requests are resolved.
169 nsecs_t currentPlayTime = mPlayTime;
170 PlayState prevFramePlayState = mPlayState;
171
172 // Resolve staging requests one by one.
173 for (Request request : mStagingRequests) {
174 resolveStagingRequest(request);
Doris Liu766431a2016-02-04 22:17:11 +0000175 }
Doris Liuc4bb1852016-02-19 21:39:21 +0000176 mStagingRequests.clear();
177
178 if (mStagingPlayState == PlayState::Finished) {
179 // Set the staging play time and end the animation
180 updatePlayTime(mPlayTime);
John Reck4d2c4722014-08-29 10:40:56 -0700181 callOnFinishedListener(context);
Doris Liuc4bb1852016-02-19 21:39:21 +0000182 } else if (mStagingPlayState == PlayState::Running
183 || mStagingPlayState == PlayState::Reversing) {
184 bool changed = currentPlayTime != mPlayTime || prevFramePlayState != mStagingPlayState;
185 if (prevFramePlayState != mStagingPlayState) {
186 transitionToRunning(context);
187 }
188 if (changed) {
189 // Now we need to seek to the stagingPlayTime (i.e. the animation progress that was
190 // requested from UI thread). It is achieved by modifying mStartTime, such that
191 // current time - mStartTime = stagingPlayTime (or mDuration -stagingPlayTime in the
192 // case of reversing)
193 nsecs_t currentFrameTime = context.frameTimeMs();
194 if (mPlayState == PlayState::Reversing) {
195 // Reverse is not supported for animations with a start delay, so here we
196 // assume no start delay.
197 mStartTime = currentFrameTime - (mDuration - mPlayTime);
198 } else {
199 // Animation should play forward
200 if (mPlayTime == 0) {
201 // If the request is to start from the beginning, include start delay.
202 mStartTime = currentFrameTime + mStartDelay;
203 } else {
204 // If the request is to seek to a non-zero play time, then we skip start
205 // delay.
206 mStartTime = currentFrameTime - mPlayTime;
207 }
208 }
209 }
John Recke45b1fd2014-04-15 09:50:16 -0700210 }
John Recke45b1fd2014-04-15 09:50:16 -0700211 }
Doris Liu8b083202016-02-19 21:46:06 +0000212 onPushStaging();
John Reck68bfe0a2014-06-24 15:34:58 -0700213}
214
John Reck119907c2014-08-14 09:02:01 -0700215void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) {
216 nsecs_t frameTimeMs = context.frameTimeMs();
217 LOG_ALWAYS_FATAL_IF(frameTimeMs <= 0, "%" PRId64 " isn't a real frame time!", frameTimeMs);
John Reck68bfe0a2014-06-24 15:34:58 -0700218 if (mStartDelay < 0 || mStartDelay > 50000) {
219 ALOGW("Your start delay is strange and confusing: %" PRId64, mStartDelay);
220 }
John Reck119907c2014-08-14 09:02:01 -0700221 mStartTime = frameTimeMs + mStartDelay;
John Reck68bfe0a2014-06-24 15:34:58 -0700222 if (mStartTime < 0) {
223 ALOGW("Ended up with a really weird start time of %" PRId64
224 " with frame time %" PRId64 " and start delay %" PRId64,
John Reck119907c2014-08-14 09:02:01 -0700225 mStartTime, frameTimeMs, mStartDelay);
John Reck68bfe0a2014-06-24 15:34:58 -0700226 // Set to 0 so that the animate() basically instantly finishes
227 mStartTime = 0;
228 }
Doris Liu952670d2016-04-12 17:43:00 -0700229 if (mDuration < 0) {
John Reck68bfe0a2014-06-24 15:34:58 -0700230 ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
231 }
232}
233
John Reck119907c2014-08-14 09:02:01 -0700234bool BaseRenderNodeAnimator::animate(AnimationContext& context) {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700235 if (mPlayState < PlayState::Running) {
John Reck68bfe0a2014-06-24 15:34:58 -0700236 return false;
237 }
Chris Craikb9ce116d2015-08-20 15:14:06 -0700238 if (mPlayState == PlayState::Finished) {
John Reck32fb6302014-07-07 09:50:32 -0700239 return true;
240 }
John Reck68bfe0a2014-06-24 15:34:58 -0700241
Doris Liu766431a2016-02-04 22:17:11 +0000242 // This should be set before setValue() so animators can query this time when setValue
243 // is called.
Doris Liuc4bb1852016-02-19 21:39:21 +0000244 nsecs_t currentPlayTime = context.frameTimeMs() - mStartTime;
245 bool finished = updatePlayTime(currentPlayTime);
246 if (finished && mPlayState != PlayState::Finished) {
247 mPlayState = PlayState::Finished;
248 callOnFinishedListener(context);
249 }
250 return finished;
251}
Doris Liu766431a2016-02-04 22:17:11 +0000252
Doris Liuc4bb1852016-02-19 21:39:21 +0000253bool BaseRenderNodeAnimator::updatePlayTime(nsecs_t playTime) {
254 mPlayTime = mPlayState == PlayState::Reversing ? mDuration - playTime : playTime;
255 onPlayTimeChanged(mPlayTime);
John Reck8d8af3c2014-07-01 15:23:45 -0700256 // If BaseRenderNodeAnimator is handling the delay (not typical), then
257 // because the staging properties reflect the final value, we always need
258 // to call setValue even if the animation isn't yet running or is still
259 // being delayed as we need to override the staging value
Doris Liuc4bb1852016-02-19 21:39:21 +0000260 if (playTime < 0) {
John Reck8d8af3c2014-07-01 15:23:45 -0700261 setValue(mTarget, mFromValue);
John Reck68bfe0a2014-06-24 15:34:58 -0700262 return false;
263 }
John Recke45b1fd2014-04-15 09:50:16 -0700264
265 float fraction = 1.0f;
Doris Liuc4bb1852016-02-19 21:39:21 +0000266 if ((mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) && mDuration > 0) {
267 fraction = mPlayTime / (float) mDuration;
John Recke45b1fd2014-04-15 09:50:16 -0700268 }
Doris Liuc4bb1852016-02-19 21:39:21 +0000269 fraction = MathUtils::clamp(fraction, 0.0f, 1.0f);
John Reck68bfe0a2014-06-24 15:34:58 -0700270
John Recke45b1fd2014-04-15 09:50:16 -0700271 fraction = mInterpolator->interpolate(fraction);
John Reck8d8af3c2014-07-01 15:23:45 -0700272 setValue(mTarget, mFromValue + (mDeltaValue * fraction));
John Recke45b1fd2014-04-15 09:50:16 -0700273
Doris Liuc4bb1852016-02-19 21:39:21 +0000274 return playTime >= mDuration;
John Recke45b1fd2014-04-15 09:50:16 -0700275}
276
Doris Liu718cd3e2016-05-17 16:50:31 -0700277nsecs_t BaseRenderNodeAnimator::getRemainingPlayTime() {
278 return mPlayState == PlayState::Reversing ? mPlayTime : mDuration - mPlayTime;
279}
280
John Recke2478d42014-09-03 16:46:05 -0700281void BaseRenderNodeAnimator::forceEndNow(AnimationContext& context) {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700282 if (mPlayState < PlayState::Finished) {
283 mPlayState = PlayState::Finished;
John Recke2478d42014-09-03 16:46:05 -0700284 callOnFinishedListener(context);
285 }
286}
287
John Reck119907c2014-08-14 09:02:01 -0700288void BaseRenderNodeAnimator::callOnFinishedListener(AnimationContext& context) {
John Reck52244ff2014-05-01 21:27:37 -0700289 if (mListener.get()) {
John Reck119907c2014-08-14 09:02:01 -0700290 context.callOnFinished(this, mListener.get());
John Reck52244ff2014-05-01 21:27:37 -0700291 }
292}
293
294/************************************************************
John Recke45b1fd2014-04-15 09:50:16 -0700295 * RenderPropertyAnimator
296 ************************************************************/
297
John Reckff941dc2014-05-14 16:34:14 -0700298struct RenderPropertyAnimator::PropertyAccessors {
299 RenderNode::DirtyPropertyMask dirtyMask;
300 GetFloatProperty getter;
301 SetFloatProperty setter;
John Reck52244ff2014-05-01 21:27:37 -0700302};
303
John Reckff941dc2014-05-14 16:34:14 -0700304// Maps RenderProperty enum to accessors
305const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = {
306 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
307 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
308 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
309 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX },
310 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY },
311 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation },
312 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX },
313 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY },
314 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX },
315 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY },
316 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ },
317 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha },
318};
319
320RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue)
321 : BaseRenderNodeAnimator(finalValue)
322 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
John Recke45b1fd2014-04-15 09:50:16 -0700323}
324
John Reck8d8af3c2014-07-01 15:23:45 -0700325void RenderPropertyAnimator::onAttached() {
John Reck68bfe0a2014-06-24 15:34:58 -0700326 if (!mHasStartValue
Doris Liu8b083202016-02-19 21:46:06 +0000327 && mStagingTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
328 setStartValue((mStagingTarget->stagingProperties().*mPropertyAccess->getter)());
John Reckff941dc2014-05-14 16:34:14 -0700329 }
John Reck8d8af3c2014-07-01 15:23:45 -0700330}
331
332void RenderPropertyAnimator::onStagingPlayStateChanged() {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700333 if (mStagingPlayState == PlayState::Running) {
Doris Liu8b083202016-02-19 21:46:06 +0000334 if (mStagingTarget) {
335 (mStagingTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
336 } else {
337 // In the case of start delay where stagingTarget has been sync'ed over and null'ed
338 // we delay the properties update to push staging.
339 mShouldUpdateStagingProperties = true;
340 }
Chris Craikb9ce116d2015-08-20 15:14:06 -0700341 } else if (mStagingPlayState == PlayState::Finished) {
John Reck32fb6302014-07-07 09:50:32 -0700342 // We're being canceled, so make sure that whatever values the UI thread
343 // is observing for us is pushed over
Doris Liu8b083202016-02-19 21:46:06 +0000344 mShouldSyncPropertyFields = true;
345 }
346}
347
348void RenderPropertyAnimator::onPushStaging() {
349 if (mShouldUpdateStagingProperties) {
350 (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
351 mShouldUpdateStagingProperties = false;
352 }
353
354 if (mShouldSyncPropertyFields) {
John Reck32fb6302014-07-07 09:50:32 -0700355 mTarget->setPropertyFieldsDirty(dirtyMask());
Doris Liu8b083202016-02-19 21:46:06 +0000356 mShouldSyncPropertyFields = false;
John Reck8d8af3c2014-07-01 15:23:45 -0700357 }
John Recke45b1fd2014-04-15 09:50:16 -0700358}
359
John Reck22184722014-06-20 07:19:30 -0700360uint32_t RenderPropertyAnimator::dirtyMask() {
361 return mPropertyAccess->dirtyMask;
362}
363
John Reckff941dc2014-05-14 16:34:14 -0700364float RenderPropertyAnimator::getValue(RenderNode* target) const {
365 return (target->properties().*mPropertyAccess->getter)();
366}
367
368void RenderPropertyAnimator::setValue(RenderNode* target, float value) {
369 (target->animatorProperties().*mPropertyAccess->setter)(value);
John Recke45b1fd2014-04-15 09:50:16 -0700370}
371
John Reck52244ff2014-05-01 21:27:37 -0700372/************************************************************
373 * CanvasPropertyPrimitiveAnimator
374 ************************************************************/
John Recke45b1fd2014-04-15 09:50:16 -0700375
John Reck52244ff2014-05-01 21:27:37 -0700376CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700377 CanvasPropertyPrimitive* property, float finalValue)
378 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700379 , mProperty(property) {
380}
381
Andreas Gampe64bb4132014-11-22 00:35:09 +0000382float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700383 return mProperty->value;
384}
385
Andreas Gampe64bb4132014-11-22 00:35:09 +0000386void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700387 mProperty->value = value;
388}
389
John Recka7c2ea22014-08-08 13:21:00 -0700390uint32_t CanvasPropertyPrimitiveAnimator::dirtyMask() {
391 return RenderNode::DISPLAY_LIST;
392}
393
John Reck52244ff2014-05-01 21:27:37 -0700394/************************************************************
395 * CanvasPropertySkPaintAnimator
396 ************************************************************/
397
398CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700399 CanvasPropertyPaint* property, PaintField field, float finalValue)
400 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700401 , mProperty(property)
402 , mField(field) {
403}
404
Andreas Gampe64bb4132014-11-22 00:35:09 +0000405float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700406 switch (mField) {
407 case STROKE_WIDTH:
408 return mProperty->value.getStrokeWidth();
409 case ALPHA:
410 return mProperty->value.getAlpha();
John Recke45b1fd2014-04-15 09:50:16 -0700411 }
John Reck52244ff2014-05-01 21:27:37 -0700412 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
413 return -1;
John Recke45b1fd2014-04-15 09:50:16 -0700414}
415
John Reck531ee702014-05-13 10:06:08 -0700416static uint8_t to_uint8(float value) {
417 int c = (int) (value + .5f);
418 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c );
419}
420
Andreas Gampe64bb4132014-11-22 00:35:09 +0000421void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700422 switch (mField) {
423 case STROKE_WIDTH:
424 mProperty->value.setStrokeWidth(value);
425 return;
426 case ALPHA:
John Reck531ee702014-05-13 10:06:08 -0700427 mProperty->value.setAlpha(to_uint8(value));
John Reck52244ff2014-05-01 21:27:37 -0700428 return;
429 }
430 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
John Recke45b1fd2014-04-15 09:50:16 -0700431}
432
John Recka7c2ea22014-08-08 13:21:00 -0700433uint32_t CanvasPropertyPaintAnimator::dirtyMask() {
434 return RenderNode::DISPLAY_LIST;
435}
436
Chris Craikaf4d04c2014-07-29 12:50:14 -0700437RevealAnimator::RevealAnimator(int centerX, int centerY,
John Reckd3de42c2014-07-15 14:29:33 -0700438 float startValue, float finalValue)
439 : BaseRenderNodeAnimator(finalValue)
440 , mCenterX(centerX)
Chris Craikaf4d04c2014-07-29 12:50:14 -0700441 , mCenterY(centerY) {
John Reckd3de42c2014-07-15 14:29:33 -0700442 setStartValue(startValue);
443}
444
445float RevealAnimator::getValue(RenderNode* target) const {
Chris Craikaf4d04c2014-07-29 12:50:14 -0700446 return target->properties().getRevealClip().getRadius();
John Reckd3de42c2014-07-15 14:29:33 -0700447}
448
449void RevealAnimator::setValue(RenderNode* target, float value) {
Chris Craikaf4d04c2014-07-29 12:50:14 -0700450 target->animatorProperties().mutableRevealClip().set(true,
John Reckd3de42c2014-07-15 14:29:33 -0700451 mCenterX, mCenterY, value);
452}
453
John Recka7c2ea22014-08-08 13:21:00 -0700454uint32_t RevealAnimator::dirtyMask() {
455 return RenderNode::GENERIC;
456}
457
John Recke45b1fd2014-04-15 09:50:16 -0700458} /* namespace uirenderer */
459} /* namespace android */