1 /* 2 * Copyright (C) 2009 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 17 #include "config.h" 18 #include "GraphicsLayerAndroid.h" 19 20 #if USE(ACCELERATED_COMPOSITING) 21 22 #include "AndroidAnimation.h" 23 #include "Animation.h" 24 #include "CString.h" 25 #include "FloatRect.h" 26 #include "GraphicsContext.h" 27 #include "Image.h" 28 #include "Length.h" 29 #include "SkLayer.h" 30 #include "PlatformBridge.h" 31 #include "PlatformGraphicsContext.h" 32 #include "RenderLayerBacking.h" 33 #include "RenderView.h" 34 #include "RotateTransformOperation.h" 35 #include "ScaleTransformOperation.h" 36 #include "SkCanvas.h" 37 #include "TransformationMatrix.h" 38 #include "TranslateTransformOperation.h" 39 40 #include <cutils/log.h> 41 #include <wtf/CurrentTime.h> 42 43 #undef LOG 44 #define LOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__) 45 #define MLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__) 46 #define TLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__) 47 48 #undef LOG 49 #define LOG(...) 50 #undef MLOG 51 #define MLOG(...) 52 #undef TLOG 53 #define TLOG(...) 54 #undef LAYER_DEBUG 55 56 using namespace std; 57 58 static bool gPaused; 59 static double gPausedDelay; 60 61 namespace WebCore { 62 63 static int gDebugGraphicsLayerAndroidInstances = 0; 64 inline int GraphicsLayerAndroid::instancesCount() 65 { 66 return gDebugGraphicsLayerAndroidInstances; 67 } 68 69 static String propertyIdToString(AnimatedPropertyID property) 70 { 71 switch (property) { 72 case AnimatedPropertyWebkitTransform: 73 return "transform"; 74 case AnimatedPropertyOpacity: 75 return "opacity"; 76 case AnimatedPropertyBackgroundColor: 77 return "backgroundColor"; 78 case AnimatedPropertyInvalid: 79 ASSERT_NOT_REACHED(); 80 } 81 ASSERT_NOT_REACHED(); 82 return ""; 83 } 84 85 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation() 86 { 87 return CompositingCoordinatesBottomUp; 88 } 89 90 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) 91 { 92 return new GraphicsLayerAndroid(client); 93 } 94 95 SkLength convertLength(Length l) { 96 SkLength length; 97 length.type = SkLength::Undefined; 98 length.value = 0; 99 if (l.type() == WebCore::Percent) { 100 length.type = SkLength::Percent; 101 length.value = l.percent(); 102 } if (l.type() == WebCore::Fixed) { 103 length.type = SkLength::Fixed; 104 length.value = l.value(); 105 } 106 return length; 107 } 108 109 GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) : 110 GraphicsLayer(client), 111 m_needsSyncChildren(false), 112 m_needsSyncMask(false), 113 m_needsRepaint(false), 114 m_needsDisplay(false), 115 m_needsNotifyClient(false), 116 m_haveContents(false), 117 m_haveImage(false), 118 m_translateX(0), 119 m_translateY(0), 120 m_currentTranslateX(0), 121 m_currentTranslateY(0), 122 m_currentPosition(0, 0) 123 { 124 m_contentLayer = new LayerAndroid(true); 125 if (m_client) { 126 RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client); 127 RenderLayer* renderLayer = backing->owningLayer(); 128 m_contentLayer->setIsRootLayer(renderLayer->isRootLayer()); 129 } 130 gDebugGraphicsLayerAndroidInstances++; 131 } 132 133 GraphicsLayerAndroid::~GraphicsLayerAndroid() 134 { 135 m_contentLayer->unref(); 136 gDebugGraphicsLayerAndroidInstances--; 137 } 138 139 void GraphicsLayerAndroid::setName(const String& name) 140 { 141 GraphicsLayer::setName(name); 142 } 143 144 NativeLayer GraphicsLayerAndroid::nativeLayer() const 145 { 146 LOG("(%x) nativeLayer", this); 147 return 0; 148 } 149 150 bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children) 151 { 152 bool childrenChanged = GraphicsLayer::setChildren(children); 153 if (childrenChanged) { 154 m_needsSyncChildren = true; 155 askForSync(); 156 } 157 158 return childrenChanged; 159 } 160 161 void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer) 162 { 163 #ifndef NDEBUG 164 const char* n = (static_cast<GraphicsLayerAndroid*>(childLayer))->m_name.latin1().data(); 165 LOG("(%x) addChild: %x (%s)", this, childLayer, n); 166 #endif 167 GraphicsLayer::addChild(childLayer); 168 m_needsSyncChildren = true; 169 askForSync(); 170 } 171 172 void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index) 173 { 174 LOG("(%x) addChild %x AtIndex %d", this, childLayer, index); 175 GraphicsLayer::addChildAtIndex(childLayer, index); 176 m_needsSyncChildren = true; 177 askForSync(); 178 } 179 180 void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling) 181 { 182 LOG("(%x) addChild %x Below %x", this, childLayer, sibling); 183 GraphicsLayer::addChildBelow(childLayer, sibling); 184 m_needsSyncChildren = true; 185 askForSync(); 186 } 187 188 void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling) 189 { 190 LOG("(%x) addChild %x Above %x", this, childLayer, sibling); 191 GraphicsLayer::addChildAbove(childLayer, sibling); 192 m_needsSyncChildren = true; 193 askForSync(); 194 } 195 196 bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) 197 { 198 LOG("(%x) replaceChild %x by %x", this, oldChild, newChild); 199 bool ret = GraphicsLayer::replaceChild(oldChild, newChild); 200 m_needsSyncChildren = true; 201 askForSync(); 202 return ret; 203 } 204 205 void GraphicsLayerAndroid::removeFromParent() 206 { 207 LOG("(%x) removeFromParent()", this); 208 if (m_parent) 209 static_cast<GraphicsLayerAndroid*>(m_parent)->needsSyncChildren(); 210 GraphicsLayer::removeFromParent(); 211 m_needsSyncChildren = true; 212 askForSync(); 213 } 214 215 void GraphicsLayerAndroid::needsSyncChildren() 216 { 217 m_needsSyncChildren = true; 218 askForSync(); 219 } 220 221 void GraphicsLayerAndroid::updateFixedPosition() 222 { 223 if (!m_client) 224 return; 225 226 RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client); 227 RenderLayer* renderLayer = backing->owningLayer(); 228 RenderView* view = static_cast<RenderView*>(renderLayer->renderer()); 229 230 // If we are a fixed position layer, just set it 231 if (view->isPositioned() && view->style()->position() == FixedPosition) { 232 SkLength left, top, right, bottom; 233 left = convertLength(view->style()->left()); 234 top = convertLength(view->style()->top()); 235 right = convertLength(view->style()->right()); 236 bottom = convertLength(view->style()->bottom()); 237 // We need to pass the size of the element to compute the final fixed 238 // position -- we can't use the layer's size as it could possibly differs. 239 // We also have to use the visible overflow and not just the size, 240 // as some child elements could be overflowing. 241 int w = view->rightVisibleOverflow() - view->leftVisibleOverflow(); 242 int h = view->bottomVisibleOverflow() - view->topVisibleOverflow(); 243 244 SkLength marginLeft, marginTop, marginRight, marginBottom; 245 marginLeft = convertLength(view->style()->marginLeft()); 246 marginTop = convertLength(view->style()->marginTop()); 247 marginRight = convertLength(view->style()->marginRight()); 248 marginBottom = convertLength(view->style()->marginBottom()); 249 250 m_contentLayer->setFixedPosition(left, top, right, bottom, 251 marginLeft, marginTop, 252 marginRight, marginBottom, 253 offsetFromRenderer().width(), 254 offsetFromRenderer().height(), 255 w, h); 256 } 257 } 258 259 void GraphicsLayerAndroid::setPosition(const FloatPoint& point) 260 { 261 m_currentPosition = point; 262 m_needsDisplay = true; 263 #ifdef LAYER_DEBUG_2 264 LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)", 265 this, point.x(), point.y(), m_currentPosition.x(), m_currentPosition.y(), 266 m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height()); 267 #endif 268 updateFixedPosition(); 269 askForSync(); 270 } 271 272 void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point) 273 { 274 GraphicsLayer::setAnchorPoint(point); 275 m_contentLayer->setAnchorPoint(point.x(), point.y()); 276 askForSync(); 277 } 278 279 void GraphicsLayerAndroid::setSize(const FloatSize& size) 280 { 281 if ((size.width() != m_size.width()) 282 || (size.height() != m_size.height())) { 283 MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height()); 284 GraphicsLayer::setSize(size); 285 m_contentLayer->setSize(size.width(), size.height()); 286 askForSync(); 287 } 288 } 289 290 void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t) 291 { 292 TransformationMatrix::DecomposedType tDecomp; 293 t.decompose(tDecomp); 294 LOG("(%x) setTransform, translate (%.2f, %.2f), mpos(%.2f,%.2f)", 295 this, tDecomp.translateX, tDecomp.translateY, 296 m_position.x(), m_position.y()); 297 298 if ((m_currentTranslateX != tDecomp.translateX) 299 || (m_currentTranslateY != tDecomp.translateY)) { 300 m_currentTranslateX = tDecomp.translateX; 301 m_currentTranslateY = tDecomp.translateY; 302 m_needsDisplay = true; 303 askForSync(); 304 } 305 } 306 307 void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t) 308 { 309 if (t == m_childrenTransform) 310 return; 311 LOG("(%x) setChildrenTransform", this); 312 313 GraphicsLayer::setChildrenTransform(t); 314 for (unsigned int i = 0; i < m_children.size(); i++) { 315 GraphicsLayer* layer = m_children[i]; 316 layer->setTransform(t); 317 if (layer->children().size()) 318 layer->setChildrenTransform(t); 319 } 320 askForSync(); 321 } 322 323 void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer) 324 { 325 if (layer == m_maskLayer) 326 return; 327 328 GraphicsLayer::setMaskLayer(layer); 329 m_needsSyncMask = true; 330 askForSync(); 331 } 332 333 void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds) 334 { 335 GraphicsLayer::setMasksToBounds(masksToBounds); 336 m_needsSyncMask = true; 337 askForSync(); 338 } 339 340 void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) 341 { 342 GraphicsLayer::setDrawsContent(drawsContent); 343 344 if (m_drawsContent) { 345 m_haveContents = true; 346 setNeedsDisplay(); 347 } 348 askForSync(); 349 } 350 351 void GraphicsLayerAndroid::setBackgroundColor(const Color& color) 352 { 353 LOG("(%x) setBackgroundColor", this); 354 GraphicsLayer::setBackgroundColor(color); 355 SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue()); 356 m_contentLayer->setBackgroundColor(c); 357 m_haveContents = true; 358 askForSync(); 359 } 360 361 void GraphicsLayerAndroid::clearBackgroundColor() 362 { 363 LOG("(%x) clearBackgroundColor", this); 364 GraphicsLayer::clearBackgroundColor(); 365 askForSync(); 366 } 367 368 void GraphicsLayerAndroid::setContentsOpaque(bool opaque) 369 { 370 LOG("(%x) setContentsOpaque (%d)", this, opaque); 371 GraphicsLayer::setContentsOpaque(opaque); 372 m_haveContents = true; 373 askForSync(); 374 } 375 376 void GraphicsLayerAndroid::setOpacity(float opacity) 377 { 378 LOG("(%x) setOpacity: %.2f", this, opacity); 379 float clampedOpacity = max(0.0f, min(opacity, 1.0f)); 380 381 if (clampedOpacity == m_opacity) 382 return; 383 384 MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this, 385 opacity, clampedOpacity, m_opacity); 386 GraphicsLayer::setOpacity(clampedOpacity); 387 m_contentLayer->setOpacity(clampedOpacity); 388 askForSync(); 389 } 390 391 bool GraphicsLayerAndroid::repaintAll() 392 { 393 LOG("(%x) repaintAll", this); 394 bool ret = false; 395 for (unsigned int i = 0; i < m_children.size(); i++) { 396 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); 397 if (layer && layer->repaintAll()) 398 ret = true; 399 } 400 int nbRects = m_invalidatedRects.size(); 401 402 for (int i = 0; !gPaused && i < nbRects; i++) { 403 FloatRect rect = m_invalidatedRects[i]; 404 if (repaint(rect)) 405 ret = true; 406 } 407 if (!gPaused) { 408 m_needsRepaint = false; 409 m_invalidatedRects.clear(); 410 } 411 return ret; 412 } 413 414 void GraphicsLayerAndroid::setNeedsDisplay() 415 { 416 LOG("(%x) setNeedsDisplay()", this); 417 FloatRect rect(0, 0, m_size.width(), m_size.height()); 418 setNeedsDisplayInRect(rect); 419 } 420 421 void GraphicsLayerAndroid::setFrame(Frame* f) 422 { 423 m_frame = f; 424 } 425 426 void GraphicsLayerAndroid::sendImmediateRepaint() 427 { 428 LOG("(%x) sendImmediateRepaint()", this); 429 GraphicsLayerAndroid* rootGraphicsLayer = this; 430 431 while (rootGraphicsLayer->parent()) 432 rootGraphicsLayer = static_cast<GraphicsLayerAndroid*>(rootGraphicsLayer->parent()); 433 434 if (rootGraphicsLayer->m_frame 435 && rootGraphicsLayer->m_frame->view()) { 436 LayerAndroid* rootLayer = new LayerAndroid(true); 437 LayerAndroid* copyLayer = new LayerAndroid(*m_contentLayer); 438 rootLayer->addChild(copyLayer); 439 copyLayer->unref(); 440 TLOG("(%x) sendImmediateRepaint, copy the layer, (%.2f,%.2f => %.2f,%.2f)", 441 this, m_contentLayer->getSize().width(), m_contentLayer->getSize().height(), 442 copyLayer->getSize().width(), copyLayer->getSize().height()); 443 PlatformBridge::setUIRootLayer(m_frame->view(), rootLayer); 444 PlatformBridge::immediateRepaint(m_frame->view()); 445 } 446 } 447 448 bool GraphicsLayerAndroid::repaint(const FloatRect& rect) 449 { 450 LOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ", 451 this, rect.x(), rect.y(), rect.width(), rect.height(), 452 gPaused, m_needsRepaint, m_haveContents); 453 454 if (!gPaused && m_haveContents && m_needsRepaint) { 455 SkAutoPictureRecord arp(m_contentLayer->recordContext(), m_size.width(), m_size.height()); 456 SkCanvas* recordingCanvas = arp.getRecordingCanvas(); 457 458 if (!recordingCanvas) 459 return false; 460 461 if ((rect.width() > 0.5) && (rect.height() > 0.5)) { 462 IntRect r((int)rect.x(), (int)rect.y(), 463 (int)rect.width(), (int)rect.height()); 464 465 PlatformGraphicsContext pgc(recordingCanvas, 0); 466 GraphicsContext gc(&pgc); 467 468 // with SkPicture, we request the entire layer's content. 469 r.setX(0); 470 r.setY(0); 471 r.setWidth(m_contentLayer->getWidth()); 472 r.setHeight(m_contentLayer->getHeight()); 473 paintGraphicsLayerContents(gc, r); 474 475 TLOG("(%x) repaint(%.2f,%.2f,%.2f,%.2f) on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!", 476 this, rect.x(), rect.y(), rect.width(), 477 rect.height(), m_size.width(), m_size.height(), 478 m_contentLayer->getPosition().fX, 479 m_contentLayer->getPosition().fY, 480 m_contentLayer->getSize().width(), 481 m_contentLayer->getSize().height()); 482 } 483 return true; 484 } 485 return false; 486 } 487 488 void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect) 489 { 490 for (unsigned int i = 0; i < m_children.size(); i++) { 491 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); 492 if (layer) { 493 FloatRect childrenRect(m_position.x() + m_translateX + rect.x(), 494 m_position.y() + m_translateY + rect.y(), 495 rect.width(), rect.height()); 496 layer->setNeedsDisplayInRect(childrenRect); 497 } 498 } 499 if (!m_haveImage && !drawsContent()) { 500 LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...", 501 this, rect.x(), rect.y(), rect.width(), rect.height()); 502 return; 503 } 504 505 const size_t maxDirtyRects = 8; 506 for (size_t i = 0; i < m_invalidatedRects.size(); ++i) { 507 if (m_invalidatedRects[i].contains(rect)) 508 return; 509 } 510 511 #ifdef LAYER_DEBUG 512 LOG("(%x) setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this, 513 m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height()); 514 #endif 515 516 if (m_invalidatedRects.size() < maxDirtyRects) 517 m_invalidatedRects.append(rect); 518 else 519 m_invalidatedRects[0].unite(rect); 520 521 m_needsRepaint = true; 522 askForSync(); 523 } 524 525 void GraphicsLayerAndroid::pauseDisplay(bool state) 526 { 527 gPaused = state; 528 if (gPaused) 529 gPausedDelay = WTF::currentTime() + 1; 530 } 531 532 bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList, 533 const IntSize& boxSize, 534 const Animation* anim, 535 const String& keyframesName, 536 double beginTime) 537 { 538 if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() != 2) 539 return false; 540 541 bool createdAnimations = false; 542 if (valueList.property() == AnimatedPropertyWebkitTransform) { 543 createdAnimations = createTransformAnimationsFromKeyframes(valueList, 544 anim, 545 keyframesName, 546 beginTime, 547 boxSize); 548 } else { 549 createdAnimations = createAnimationFromKeyframes(valueList, 550 anim, 551 keyframesName, 552 beginTime); 553 } 554 askForSync(); 555 return createdAnimations; 556 } 557 558 bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList, 559 const Animation* animation, const String& keyframesName, double beginTime) 560 { 561 bool isKeyframe = valueList.size() > 2; 562 TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)", 563 isKeyframe, keyframesName.latin1().data(), beginTime); 564 // TODO: handles keyframe animations correctly 565 566 switch (valueList.property()) { 567 case AnimatedPropertyInvalid: break; 568 case AnimatedPropertyWebkitTransform: break; 569 case AnimatedPropertyBackgroundColor: break; 570 case AnimatedPropertyOpacity: { 571 MLOG("ANIMATEDPROPERTYOPACITY"); 572 const FloatAnimationValue* startVal = 573 static_cast<const FloatAnimationValue*>(valueList.at(0)); 574 const FloatAnimationValue* endVal = 575 static_cast<const FloatAnimationValue*>(valueList.at(1)); 576 RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(startVal->value(), 577 endVal->value(), 578 animation, 579 beginTime); 580 if (keyframesName.isEmpty()) 581 anim->setName(propertyIdToString(valueList.property())); 582 else 583 anim->setName(keyframesName); 584 585 m_contentLayer->addAnimation(anim.release()); 586 needsNotifyClient(); 587 return true; 588 } break; 589 } 590 return false; 591 } 592 593 void GraphicsLayerAndroid::needsNotifyClient() 594 { 595 m_needsNotifyClient = true; 596 askForSync(); 597 } 598 599 bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, 600 const Animation* animation, 601 const String& keyframesName, 602 double beginTime, 603 const IntSize& boxSize) 604 { 605 ASSERT(valueList.property() == AnimatedPropertyWebkitTransform); 606 TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)", 607 keyframesName.latin1().data(), beginTime); 608 609 TransformOperationList functionList; 610 bool listsMatch, hasBigRotation; 611 fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation); 612 613 // If functionLists don't match we do a matrix animation, otherwise we do a component hardware animation. 614 // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation 615 // if that's not true as well. 616 617 bool isMatrixAnimation = !listsMatch; 618 size_t numAnimations = isMatrixAnimation ? 1 : functionList.size(); 619 bool isKeyframe = valueList.size() > 2; 620 621 float fromTranslateX = 0; 622 float fromTranslateY = 0; 623 float fromTranslateZ = 0; 624 float toTranslateX = 0; 625 float toTranslateY = 0; 626 float toTranslateZ = 0; 627 float fromAngle = 0; 628 float toAngle = 0; 629 float fromScaleX = 1; 630 float fromScaleY = 1; 631 float fromScaleZ = 1; 632 float toScaleX = 1; 633 float toScaleY = 1; 634 float toScaleZ = 1; 635 636 bool doTranslation = false; 637 bool doRotation = false; 638 bool doScaling = false; 639 640 TLOG("(%x) animateTransform, valueList(%d) functionList(%d) duration(%.2f)", this, 641 valueList.size(), functionList.size(), animation->duration()); 642 643 // FIXME: add support for the translate 3d operations (when 644 // we'll have an OpenGL backend) 645 646 for (unsigned int i = 0; i < valueList.size(); i++) { 647 const TransformOperations* operation = ((TransformAnimationValue*)valueList.at(i))->value(); 648 Vector<RefPtr<TransformOperation> > ops = operation->operations(); 649 TLOG("(%x) animateTransform, dealing with the %d operation, with %d ops", this, i, ops.size()); 650 for (unsigned int j = 0; j < ops.size(); j++) { 651 TransformOperation* op = ops[j].get(); 652 TLOG("(%x) animateTransform, dealing with the %d:%d operation, current op: %d (translate is %d, rotate %d, scale %d)", 653 this, i, j, op->getOperationType(), TransformOperation::TRANSLATE, TransformOperation::ROTATE, TransformOperation::SCALE); 654 if ((op->getOperationType() == TransformOperation::TRANSLATE) || 655 (op->getOperationType() == TransformOperation::TRANSLATE_3D)) { 656 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op; 657 IntSize bounds(m_size.width(), m_size.height()); 658 float x = translateOperation->x(bounds); 659 float y = translateOperation->y(bounds); 660 float z = translateOperation->z(bounds); 661 if (!i) { 662 fromTranslateX = x; 663 fromTranslateY = y; 664 fromTranslateZ = z; 665 } else { 666 toTranslateX = x; 667 toTranslateY = y; 668 toTranslateZ = z; 669 } 670 TLOG("(%x) animateTransform, the %d operation is a translation(%.2f,%.2f,%.2f)", 671 this, j, x, y, z); 672 doTranslation = true; 673 } else if (op->getOperationType() == TransformOperation::TRANSLATE_X) { 674 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op; 675 IntSize bounds(m_size.width(), m_size.height()); 676 float x = translateOperation->x(bounds); 677 if (!i) 678 fromTranslateX = x; 679 else 680 toTranslateX = x; 681 TLOG("(%x) animateTransform, the %d operation is a translation_x(%.2f)", 682 this, j, x); 683 doTranslation = true; 684 } else if (op->getOperationType() == TransformOperation::TRANSLATE_Y) { 685 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op; 686 IntSize bounds(m_size.width(), m_size.height()); 687 float y = translateOperation->y(bounds); 688 if (!i) 689 fromTranslateY = y; 690 else 691 toTranslateY = y; 692 TLOG("(%x) animateTransform, the %d operation is a translation_y(%.2f)", 693 this, j, y); 694 doTranslation = true; 695 } else if (op->getOperationType() == TransformOperation::TRANSLATE_Z) { 696 TranslateTransformOperation* translateOperation = (TranslateTransformOperation*) op; 697 IntSize bounds(m_size.width(), m_size.height()); 698 float z = translateOperation->z(bounds); 699 if (!i) 700 fromTranslateZ = z; 701 else 702 toTranslateZ = z; 703 TLOG("(%x) animateTransform, the %d operation is a translation_z(%.2f)", 704 this, j, z); 705 doTranslation = true; 706 } else if ((op->getOperationType() == TransformOperation::ROTATE) 707 || (op->getOperationType() == TransformOperation::ROTATE_X) 708 || (op->getOperationType() == TransformOperation::ROTATE_Y)) { 709 LOG("(%x) animateTransform, the %d operation is a rotation", this, j); 710 RotateTransformOperation* rotateOperation = (RotateTransformOperation*) op; 711 float angle = rotateOperation->angle(); 712 TLOG("(%x) animateTransform, the %d operation is a rotation (%d), of angle %.2f", 713 this, j, op->getOperationType(), angle); 714 715 if (!i) 716 fromAngle = angle; 717 else 718 toAngle = angle; 719 doRotation = true; 720 } else if (op->getOperationType() == TransformOperation::SCALE_X) { 721 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op; 722 if (!i) 723 fromScaleX = scaleOperation->x(); 724 else 725 toScaleX = scaleOperation->x(); 726 doScaling = true; 727 } else if (op->getOperationType() == TransformOperation::SCALE_Y) { 728 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op; 729 if (!i) 730 fromScaleY = scaleOperation->y(); 731 else 732 toScaleY = scaleOperation->y(); 733 doScaling = true; 734 } else if (op->getOperationType() == TransformOperation::SCALE_Z) { 735 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op; 736 if (!i) 737 fromScaleZ = scaleOperation->z(); 738 else 739 toScaleZ = scaleOperation->z(); 740 doScaling = true; 741 } else if (op->getOperationType() == TransformOperation::SCALE) { 742 ScaleTransformOperation* scaleOperation = (ScaleTransformOperation*) op; 743 if (!i) { 744 fromScaleX = scaleOperation->x(); 745 fromScaleY = scaleOperation->y(); 746 fromScaleZ = scaleOperation->z(); 747 } else { 748 toScaleX = scaleOperation->x(); 749 toScaleY = scaleOperation->y(); 750 toScaleZ = scaleOperation->z(); 751 } 752 doScaling = true; 753 } else { 754 TLOG("(%x) animateTransform, the %d operation is not a rotation (%d)", 755 this, j, op->getOperationType()); 756 } 757 } 758 } 759 760 RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation, beginTime); 761 762 if (keyframesName.isEmpty()) 763 anim->setName(propertyIdToString(valueList.property())); 764 else 765 anim->setName(keyframesName); 766 767 anim->setOriginalPosition(m_position); 768 769 if (doTranslation) 770 anim->setTranslation(fromTranslateX, fromTranslateY, fromTranslateZ, 771 toTranslateX, toTranslateY, toTranslateZ); 772 if (doRotation) 773 anim->setRotation(fromAngle, toAngle); 774 if (doScaling) 775 anim->setScale(fromScaleX, fromScaleY, fromScaleZ, 776 toScaleX, toScaleY, toScaleZ); 777 m_contentLayer->addAnimation(anim.release()); 778 779 needsNotifyClient(); 780 return true; 781 } 782 783 void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID) 784 { 785 TLOG("NRO removeAnimationsForProperty(%d)", anID); 786 m_contentLayer->removeAnimation(propertyIdToString(anID)); 787 askForSync(); 788 } 789 790 void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName) 791 { 792 TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data()); 793 m_contentLayer->removeAnimation(keyframesName); 794 askForSync(); 795 } 796 797 void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName) 798 { 799 TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data()); 800 } 801 802 void GraphicsLayerAndroid::suspendAnimations(double time) 803 { 804 TLOG("NRO suspendAnimations(%.2f)", time); 805 } 806 807 void GraphicsLayerAndroid::resumeAnimations() 808 { 809 TLOG("NRO resumeAnimations()"); 810 } 811 812 void GraphicsLayerAndroid::setContentsToImage(Image* image) 813 { 814 TLOG("(%x) setContentsToImage", this, image); 815 if (image) { 816 m_haveContents = true; 817 if (!m_haveImage) { 818 m_haveImage = true; 819 setNeedsDisplay(); 820 askForSync(); 821 } 822 } 823 } 824 825 PlatformLayer* GraphicsLayerAndroid::platformLayer() const 826 { 827 LOG("platformLayer"); 828 return (PlatformLayer*) m_contentLayer; 829 } 830 831 #ifndef NDEBUG 832 void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color) 833 { 834 } 835 836 void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth) 837 { 838 } 839 #endif 840 841 void GraphicsLayerAndroid::setZPosition(float position) 842 { 843 LOG("(%x) setZPosition: %.2f", this, position); 844 GraphicsLayer::setZPosition(position); 845 askForSync(); 846 } 847 848 void GraphicsLayerAndroid::askForSync() 849 { 850 if (m_client) 851 m_client->notifySyncRequired(this); 852 } 853 854 void GraphicsLayerAndroid::syncChildren() 855 { 856 if (m_needsSyncChildren) { 857 m_contentLayer->removeChildren(); 858 for (unsigned int i = 0; i < m_children.size(); i++) { 859 m_contentLayer->addChild( 860 (static_cast<GraphicsLayerAndroid*>(m_children[i]))->contentLayer()); 861 } 862 m_needsSyncChildren = false; 863 } 864 } 865 866 void GraphicsLayerAndroid::syncMask() 867 { 868 if (m_needsSyncMask) { 869 if (m_maskLayer) { 870 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_maskLayer); 871 LayerAndroid* mask = reinterpret_cast<LayerAndroid*>(layer->platformLayer()); 872 m_contentLayer->setMaskLayer(mask); 873 } else 874 m_contentLayer->setMaskLayer(0); 875 876 m_contentLayer->setMasksToBounds(m_masksToBounds); 877 m_needsSyncMask = false; 878 } 879 } 880 881 void GraphicsLayerAndroid::syncPositionState() 882 { 883 if (m_needsDisplay) { 884 m_translateX = m_currentTranslateX; 885 m_translateY = m_currentTranslateY; 886 m_position = m_currentPosition; 887 m_contentLayer->setTranslation(m_currentTranslateX, m_currentTranslateY); 888 m_contentLayer->setPosition(m_currentPosition.x(), m_currentPosition.y()); 889 m_needsDisplay = false; 890 } 891 } 892 893 void GraphicsLayerAndroid::syncCompositingState() 894 { 895 for (unsigned int i = 0; i < m_children.size(); i++) { 896 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); 897 layer->syncCompositingState(); 898 } 899 900 syncChildren(); 901 syncMask(); 902 syncPositionState(); 903 904 if (!gPaused || WTF::currentTime() >= gPausedDelay) 905 repaintAll(); 906 } 907 908 void GraphicsLayerAndroid::notifyClientAnimationStarted() 909 { 910 for (unsigned int i = 0; i < m_children.size(); i++) { 911 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); 912 layer->notifyClientAnimationStarted(); 913 } 914 915 if (m_needsNotifyClient) { 916 if (client()) 917 client()->notifyAnimationStarted(this, WTF::currentTime()); 918 m_needsNotifyClient = false; 919 } 920 } 921 922 } // namespace WebCore 923 924 #endif // USE(ACCELERATED_COMPOSITING) 925