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 #define LOG_TAG "GraphicsLayerAndroid"
18 #define LOG_NDEBUG 1
19
20 #include "config.h"
21 #include "GraphicsLayerAndroid.h"
22
23 #if USE(ACCELERATED_COMPOSITING)
24
25 #include "AndroidAnimation.h"
26 #include "AndroidLog.h"
27 #include "Animation.h"
28 #include "BaseLayerAndroid.h"
29 #include "CachedImage.h"
30 #include "CanvasLayer.h"
31 #include "FixedBackgroundLayerAndroid.h"
32 #include "FixedPositioning.h"
33 #include "FloatRect.h"
34 #include "GraphicsContext.h"
35 #include "IFrameContentLayerAndroid.h"
36 #include "IFrameLayerAndroid.h"
37 #include "Image.h"
38 #include "ImagesManager.h"
39 #include "Layer.h"
40 #include "LayerAndroid.h"
41 #include "Length.h"
42 #include "MediaLayer.h"
43 #include "PictureLayerContent.h"
44 #include "PicturePileLayerContent.h"
45 #include "PlatformBridge.h"
46 #include "PlatformGraphicsContextSkia.h"
47 #include "RenderLayerBacking.h"
48 #include "RenderView.h"
49 #include "RotateTransformOperation.h"
50 #include "ScaleTransformOperation.h"
51 #include "ScrollableLayerAndroid.h"
52 #include "SkCanvas.h"
53 #include "SkRegion.h"
54 #include "StyleCachedImage.h"
55 #include "TransformationMatrix.h"
56 #include "TranslateTransformOperation.h"
57
58 #include <wtf/CurrentTime.h>
59 #include <wtf/text/CString.h>
60
61 using namespace std;
62
63 static bool gPaused;
64 static double gPausedDelay;
65
66 namespace WebCore {
67
68 static int gDebugGraphicsLayerAndroidInstances = 0;
instancesCount()69 inline int GraphicsLayerAndroid::instancesCount()
70 {
71 return gDebugGraphicsLayerAndroidInstances;
72 }
73
propertyIdToString(AnimatedPropertyID property)74 static String propertyIdToString(AnimatedPropertyID property)
75 {
76 switch (property) {
77 case AnimatedPropertyWebkitTransform:
78 return "transform";
79 case AnimatedPropertyOpacity:
80 return "opacity";
81 case AnimatedPropertyBackgroundColor:
82 return "backgroundColor";
83 case AnimatedPropertyInvalid:
84 ASSERT_NOT_REACHED();
85 }
86 ASSERT_NOT_REACHED();
87 return "";
88 }
89
create(GraphicsLayerClient * client)90 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
91 {
92 return new GraphicsLayerAndroid(client);
93 }
94
renderLayerFromClient(GraphicsLayerClient * client)95 static RenderLayer* renderLayerFromClient(GraphicsLayerClient* client)
96 {
97 return client ? client->owningLayer() : 0;
98 }
99
GraphicsLayerAndroid(GraphicsLayerClient * client)100 GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
101 GraphicsLayer(client),
102 m_needsSyncChildren(false),
103 m_needsSyncMask(false),
104 m_needsRepaint(false),
105 m_needsNotifyClient(false),
106 m_haveContents(false),
107 m_newImage(false),
108 m_image(0),
109 m_fixedBackgroundLayer(0),
110 m_foregroundLayer(0),
111 m_foregroundClipLayer(0)
112 {
113 RenderLayer* renderLayer = renderLayerFromClient(m_client);
114 if (renderLayer && renderLayer->renderer()->isCanvas()) {
115 m_contentLayer = new CanvasLayer(renderLayer,
116 static_cast<HTMLCanvasElement*>(renderLayer->renderer()->node()));
117 } else
118 m_contentLayer = new LayerAndroid(renderLayer);
119 gDebugGraphicsLayerAndroidInstances++;
120 }
121
~GraphicsLayerAndroid()122 GraphicsLayerAndroid::~GraphicsLayerAndroid()
123 {
124 if (m_image)
125 m_image->deref();
126
127 SkSafeUnref(m_contentLayer);
128 SkSafeUnref(m_fixedBackgroundLayer);
129 SkSafeUnref(m_foregroundLayer);
130 SkSafeUnref(m_foregroundClipLayer);
131 gDebugGraphicsLayerAndroidInstances--;
132 }
133
setName(const String & name)134 void GraphicsLayerAndroid::setName(const String& name)
135 {
136 GraphicsLayer::setName(name);
137 }
138
nativeLayer() const139 NativeLayer GraphicsLayerAndroid::nativeLayer() const
140 {
141 ALOGV("(%x) nativeLayer", this);
142 return 0;
143 }
144
setChildren(const Vector<GraphicsLayer * > & children)145 bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children)
146 {
147 bool childrenChanged = GraphicsLayer::setChildren(children);
148 if (childrenChanged) {
149 m_needsSyncChildren = true;
150 askForSync();
151 }
152
153 return childrenChanged;
154 }
155
addChild(GraphicsLayer * childLayer)156 void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
157 {
158 #ifndef NDEBUG
159 const String& name = childLayer->name();
160 ALOGV("(%x) addChild: %x (%s)", this, childLayer, name.ascii().data());
161 #endif
162 GraphicsLayer::addChild(childLayer);
163 m_needsSyncChildren = true;
164 askForSync();
165 }
166
addChildAtIndex(GraphicsLayer * childLayer,int index)167 void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
168 {
169 ALOGV("(%x) addChild %x AtIndex %d", this, childLayer, index);
170 GraphicsLayer::addChildAtIndex(childLayer, index);
171 m_needsSyncChildren = true;
172 askForSync();
173 }
174
addChildBelow(GraphicsLayer * childLayer,GraphicsLayer * sibling)175 void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
176 {
177 ALOGV("(%x) addChild %x Below %x", this, childLayer, sibling);
178 GraphicsLayer::addChildBelow(childLayer, sibling);
179 m_needsSyncChildren = true;
180 askForSync();
181 }
182
addChildAbove(GraphicsLayer * childLayer,GraphicsLayer * sibling)183 void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
184 {
185 ALOGV("(%x) addChild %x Above %x", this, childLayer, sibling);
186 GraphicsLayer::addChildAbove(childLayer, sibling);
187 m_needsSyncChildren = true;
188 askForSync();
189 }
190
replaceChild(GraphicsLayer * oldChild,GraphicsLayer * newChild)191 bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
192 {
193 ALOGV("(%x) replaceChild %x by %x", this, oldChild, newChild);
194 bool ret = GraphicsLayer::replaceChild(oldChild, newChild);
195 if (ret) {
196 m_needsSyncChildren = true;
197 askForSync();
198 }
199 return ret;
200 }
201
setReplicatedLayer(GraphicsLayer * layer)202 void GraphicsLayerAndroid::setReplicatedLayer(GraphicsLayer* layer)
203 {
204 GraphicsLayer::setReplicatedLayer(layer);
205 if (m_replicatedLayer) {
206 GraphicsLayerAndroid* graphicsLayer = static_cast<GraphicsLayerAndroid*>(m_replicatedLayer);
207 if (graphicsLayer->m_contentLayer)
208 graphicsLayer->m_contentLayer->setReplicatedLayer(m_contentLayer);
209 if (maskLayer()) {
210 GraphicsLayerAndroid* maskLayer = static_cast<GraphicsLayerAndroid*>(GraphicsLayer::maskLayer());
211 m_contentLayer->setMaskLayer(maskLayer->m_contentLayer);
212 }
213 m_contentLayer->setReplicatedLayerPosition(replicatedLayerPosition());
214 askForSync();
215 }
216 }
217
removeFromParent()218 void GraphicsLayerAndroid::removeFromParent()
219 {
220 ALOGV("(%x) removeFromParent()", this);
221 GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
222 GraphicsLayer::removeFromParent();
223 // Update the parent's children.
224 if (parent) {
225 parent->m_needsSyncChildren = true;
226 askForSync();
227 }
228 }
229
updatePositionedLayers()230 void GraphicsLayerAndroid::updatePositionedLayers()
231 {
232 RenderLayer* renderLayer = renderLayerFromClient(m_client);
233 if (!renderLayer)
234 return;
235 RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
236
237 if (!view)
238 return;
239
240 // We will need the Iframe flag in the LayerAndroid tree for fixed position
241 if (view->isRenderIFrame() && !m_contentLayer->isIFrame()) {
242 LayerAndroid* layer = new IFrameLayerAndroid(*m_contentLayer);
243 m_contentLayer->unref();
244 m_contentLayer = layer;
245 }
246
247 // If we are a fixed position layer, just set it
248 if (view->isPositioned() && view->style()->position() == FixedPosition) {
249 m_contentLayer->setAbsolutePosition(false);
250 // We need to get the passed CSS properties for the element
251 SkLength left, top, right, bottom;
252 left = SkLength::convertLength(view->style()->left());
253 top = SkLength::convertLength(view->style()->top());
254 right = SkLength::convertLength(view->style()->right());
255 bottom = SkLength::convertLength(view->style()->bottom());
256
257 // We also need to get the margin...
258 SkLength marginLeft, marginTop, marginRight, marginBottom;
259 marginLeft = SkLength::convertLength(view->style()->marginLeft());
260 marginTop = SkLength::convertLength(view->style()->marginTop());
261 marginRight = SkLength::convertLength(view->style()->marginRight());
262 marginBottom = SkLength::convertLength(view->style()->marginBottom());
263
264 // In order to compute the fixed element's position, we need the width
265 // and height of the element when bottom or right is defined.
266 // And here we should use the non-overflowed value, that means, the
267 // overflowed content (e.g. outset shadow) will not be counted into the
268 // width and height.
269 int w = view->width();
270 int h = view->height();
271
272 int paintingOffsetX = - offsetFromRenderer().width();
273 int paintingOffsetY = - offsetFromRenderer().height();
274
275 SkRect viewRect;
276 viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h);
277 IntPoint renderLayerPos(position().x(), position().y());
278
279 FixedPositioning* fixedPosition = m_contentLayer->fixedPosition();
280 if (!fixedPosition) {
281 fixedPosition = new FixedPositioning();
282 m_contentLayer->setFixedPosition(fixedPosition);
283 }
284
285 fixedPosition->setFixedPosition(left, top, right, bottom,
286 marginLeft, marginTop,
287 marginRight, marginBottom,
288 renderLayerPos,
289 viewRect);
290 } else if (view->isPositioned() && view->style()->position() == AbsolutePosition) {
291 m_contentLayer->setAbsolutePosition(true);
292 } else {
293 m_contentLayer->setFixedPosition(0);
294 m_contentLayer->setAbsolutePosition(false);
295 }
296 }
297
setPosition(const FloatPoint & point)298 void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
299 {
300 if (point == m_position)
301 return;
302
303 GraphicsLayer::setPosition(point);
304
305 ALOGV("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
306 this, point.x(), point.y(), m_position.x(), m_position.y(),
307 m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
308
309 m_contentLayer->setPosition(point.x(), point.y());
310 askForSync();
311 }
312
setPreserves3D(bool preserves3D)313 void GraphicsLayerAndroid::setPreserves3D(bool preserves3D)
314 {
315 if (preserves3D == m_preserves3D)
316 return;
317
318 GraphicsLayer::setPreserves3D(preserves3D);
319 m_contentLayer->setPreserves3D(preserves3D);
320 askForSync();
321 }
322
setAnchorPoint(const FloatPoint3D & point)323 void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
324 {
325 if (point == m_anchorPoint)
326 return;
327 GraphicsLayer::setAnchorPoint(point);
328 m_contentLayer->setAnchorPoint(point.x(), point.y());
329 m_contentLayer->setAnchorPointZ(point.z());
330 askForSync();
331 }
332
setSize(const FloatSize & size)333 void GraphicsLayerAndroid::setSize(const FloatSize& size)
334 {
335 if (size == m_size)
336 return;
337 ALOGV("(%x) layer %d setSize (%.2f,%.2f)", this,
338 m_contentLayer->uniqueId(), size.width(), size.height());
339 GraphicsLayer::setSize(size);
340
341 // If it is a media layer the size may have changed as a result of the media
342 // element (e.g. plugin) gaining focus. Therefore, we must sync the size of
343 // the focus' outline so that our UI thread can draw accordingly.
344 RenderLayer* layer = renderLayerFromClient(m_client);
345 if (layer && m_contentLayer->isMedia()) {
346 RenderBox* box = layer->renderBox();
347 int outline = box->view()->maximalOutlineSize();
348 static_cast<MediaLayer*>(m_contentLayer)->setOutlineSize(outline);
349 ALOGV("Media Outline: %d %p %p %p", outline, m_client, layer, box);
350 ALOGV("Media Size: %g,%g", size.width(), size.height());
351 }
352
353 m_contentLayer->setSize(size.width(), size.height());
354 setNeedsDisplay();
355 askForSync();
356 }
357
setBackfaceVisibility(bool b)358 void GraphicsLayerAndroid::setBackfaceVisibility(bool b)
359 {
360 if (b == m_backfaceVisibility)
361 return;
362
363 GraphicsLayer::setBackfaceVisibility(b);
364 m_contentLayer->setBackfaceVisibility(b);
365 askForSync();
366 }
367
setTransform(const TransformationMatrix & t)368 void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
369 {
370 if (t == m_transform)
371 return;
372
373 GraphicsLayer::setTransform(t);
374 m_contentLayer->setTransform(t);
375 askForSync();
376 }
377
setChildrenTransform(const TransformationMatrix & t)378 void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
379 {
380 if (t == m_childrenTransform)
381 return;
382 ALOGV("(%x) setChildrenTransform", this);
383
384 GraphicsLayer::setChildrenTransform(t);
385 m_contentLayer->setChildrenTransform(t);
386 for (unsigned int i = 0; i < m_children.size(); i++) {
387 GraphicsLayer* layer = m_children[i];
388 layer->setTransform(t);
389 if (layer->children().size())
390 layer->setChildrenTransform(t);
391 }
392 askForSync();
393 }
394
setMaskLayer(GraphicsLayer * layer)395 void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
396 {
397 if (layer == m_maskLayer)
398 return;
399
400 GraphicsLayer::setMaskLayer(layer);
401 m_needsSyncMask = true;
402 askForSync();
403 }
404
setMasksToBounds(bool masksToBounds)405 void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
406 {
407 if (masksToBounds == m_masksToBounds)
408 return;
409 GraphicsLayer::setMasksToBounds(masksToBounds);
410 m_needsSyncMask = true;
411 askForSync();
412 }
413
setDrawsContent(bool drawsContent)414 void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
415 {
416 if (drawsContent == m_drawsContent)
417 return;
418 GraphicsLayer::setDrawsContent(drawsContent);
419 m_contentLayer->setVisible(drawsContent);
420 if (m_drawsContent) {
421 m_haveContents = true;
422 setNeedsDisplay();
423 }
424 askForSync();
425 }
426
setBackgroundColor(const Color & color)427 void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
428 {
429 if (color == m_backgroundColor && m_backgroundColorSet)
430 return;
431 ALOGV("(%x) setBackgroundColor", this);
432 GraphicsLayer::setBackgroundColor(color);
433 SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
434 m_contentLayer->setBackgroundColor(c);
435 m_haveContents = true;
436 askForSync();
437 }
438
clearBackgroundColor()439 void GraphicsLayerAndroid::clearBackgroundColor()
440 {
441 if (!m_backgroundColorSet)
442 return;
443
444 ALOGV("(%x) clearBackgroundColor", this);
445 GraphicsLayer::clearBackgroundColor();
446 askForSync();
447 }
448
setContentsOpaque(bool opaque)449 void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
450 {
451 if (opaque == m_contentsOpaque)
452 return;
453 ALOGV("(%x) setContentsOpaque (%d)", this, opaque);
454 GraphicsLayer::setContentsOpaque(opaque);
455 m_haveContents = true;
456 askForSync();
457 }
458
setOpacity(float opacity)459 void GraphicsLayerAndroid::setOpacity(float opacity)
460 {
461 ALOGV("(%x) setOpacity: %.2f", this, opacity);
462 float clampedOpacity = max(0.0f, min(opacity, 1.0f));
463
464 if (clampedOpacity == m_opacity)
465 return;
466
467 ALOGV("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
468 opacity, clampedOpacity, m_opacity);
469 GraphicsLayer::setOpacity(clampedOpacity);
470 m_contentLayer->setOpacity(clampedOpacity);
471 askForSync();
472 }
473
setNeedsDisplay()474 void GraphicsLayerAndroid::setNeedsDisplay()
475 {
476 ALOGV("(%x) setNeedsDisplay()", this);
477 FloatRect rect(0, 0, m_size.width(), m_size.height());
478 setNeedsDisplayInRect(rect);
479 }
480
481 // Helper to set and clear the painting phase as well as auto restore the
482 // original phase.
483 class PaintingPhase {
484 public:
PaintingPhase(GraphicsLayer * layer)485 PaintingPhase(GraphicsLayer* layer)
486 : m_layer(layer)
487 , m_originalPhase(layer->paintingPhase()) {}
488
~PaintingPhase()489 ~PaintingPhase()
490 {
491 m_layer->setPaintingPhase(m_originalPhase);
492 }
493
set(GraphicsLayerPaintingPhase phase)494 void set(GraphicsLayerPaintingPhase phase)
495 {
496 m_layer->setPaintingPhase(phase);
497 }
498
clear(GraphicsLayerPaintingPhase phase)499 void clear(GraphicsLayerPaintingPhase phase)
500 {
501 m_layer->setPaintingPhase(
502 (GraphicsLayerPaintingPhase) (m_originalPhase & ~phase));
503 }
504 private:
505 GraphicsLayer* m_layer;
506 GraphicsLayerPaintingPhase m_originalPhase;
507 };
508
updateScrollingLayers()509 void GraphicsLayerAndroid::updateScrollingLayers()
510 {
511 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
512 RenderLayer* layer = renderLayerFromClient(m_client);
513 if (!layer || !m_haveContents)
514 return;
515 bool hasOverflowScroll = m_foregroundLayer || m_contentLayer->contentIsScrollable();
516 bool layerNeedsOverflow = layer->hasOverflowScroll();
517 bool iframeNeedsOverflow = layer->isRootLayer() &&
518 layer->renderer()->frame()->ownerRenderer() &&
519 layer->renderer()->frame()->view()->hasOverflowScroll();
520
521 if (hasOverflowScroll && (layerNeedsOverflow || iframeNeedsOverflow)) {
522 // Already has overflow layers.
523 return;
524 }
525 if (!hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow) {
526 // Does not need overflow layers.
527 return;
528 }
529 if (layerNeedsOverflow || iframeNeedsOverflow) {
530 ASSERT(!hasOverflowScroll);
531 if (layerNeedsOverflow) {
532 ASSERT(!m_foregroundLayer && !m_foregroundClipLayer);
533 m_foregroundLayer = new ScrollableLayerAndroid(layer);
534 m_foregroundLayer->setIntrinsicallyComposited(true);
535
536 m_foregroundClipLayer = new LayerAndroid(layer);
537 m_foregroundClipLayer->setMasksToBounds(true);
538 m_foregroundClipLayer->addChild(m_foregroundLayer);
539 m_contentLayer->addChild(m_foregroundClipLayer);
540 m_contentLayer->setHasOverflowChildren(true);
541 } else {
542 ASSERT(iframeNeedsOverflow && !m_contentLayer->contentIsScrollable());
543 // No need to copy the children as they will be removed and synced.
544 m_contentLayer->removeChildren();
545 // Replace the content layer with a scrollable layer.
546 LayerAndroid* layer = new IFrameContentLayerAndroid(*m_contentLayer);
547 m_contentLayer->unref();
548 m_contentLayer = layer;
549 if (m_parent) {
550 // The content layer has changed so the parent needs to sync
551 // children.
552 static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
553 }
554 }
555 // Need to rebuild our children based on the new structure.
556 m_needsSyncChildren = true;
557 } else if (!m_contentLayer->isFixedBackground()) {
558 ASSERT(hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow);
559 ASSERT(m_contentLayer);
560 // Remove the foreground layers.
561 if (m_foregroundLayer) {
562 m_foregroundLayer->unref();
563 m_foregroundLayer = 0;
564 m_foregroundClipLayer->unref();
565 m_foregroundClipLayer = 0;
566 }
567 // No need to copy over children.
568 m_contentLayer->removeChildren();
569 LayerAndroid* layer = new LayerAndroid(*m_contentLayer);
570 m_contentLayer->unref();
571 m_contentLayer = layer;
572 if (m_parent) {
573 // The content layer has changed so the parent needs to sync
574 // children.
575 static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
576 }
577 // Children are all re-parented.
578 m_needsSyncChildren = true;
579 }
580 #endif
581 }
582
updateFixedBackgroundLayers()583 void GraphicsLayerAndroid::updateFixedBackgroundLayers() {
584 RenderLayer* renderLayer = renderLayerFromClient(m_client);
585 if (!renderLayer)
586 return;
587 RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
588 if (!view)
589 return;
590 if (view->isBody()) // body element is already handled
591 return;
592 if (!view->style()->hasFixedBackgroundImage())
593 return;
594 if (view->isRenderIFrame()) // not supported
595 return;
596
597 Image* image = FixedBackgroundImageLayerAndroid::GetCachedImage(view->style());
598 if (!image)
599 return;
600
601 if (image->width() == 1 && image->height() == 1)
602 return;
603
604 SkSafeUnref(m_foregroundClipLayer);
605 SkSafeUnref(m_fixedBackgroundLayer);
606 SkSafeUnref(m_foregroundLayer);
607
608 // we will have:
609 // m_contentLayer
610 // \- m_foregroundClipLayer
611 // \- m_fixedBackgroundLayer
612 // \- m_foregroundLayer
613
614 // use the background image and create a layer for it
615 // the layer will be fixed positioned.
616
617 m_fixedBackgroundLayer = new FixedBackgroundImageLayerAndroid(view->style(),
618 view->width(),
619 view->height());
620
621 Color color = view->style()->visitedDependentColor(CSSPropertyBackgroundColor);
622 SkColor skiaColor = SkColorSetARGB(color.alpha(),
623 color.red(),
624 color.green(),
625 color.blue());
626 m_fixedBackgroundLayer->setBackgroundColor(skiaColor);
627
628 // We need to clip the background image to the bounds of the original element
629 m_foregroundClipLayer = new LayerAndroid(renderLayer);
630 m_foregroundClipLayer->setMasksToBounds(true);
631 m_foregroundClipLayer->addChild(m_fixedBackgroundLayer);
632
633 // We then want to display the content above the image background; webkit
634 // allow to paint background and foreground separately. For now, we'll create
635 // two layers; the one containing the background will be painted *without* the
636 // background image (but with the decorations, e.g. border)
637 m_foregroundLayer = new LayerAndroid(renderLayer);
638 m_foregroundLayer->setIntrinsicallyComposited(true);
639
640 // Finally, let's assemble all the layers under a FixedBackgroundLayerAndroid layer
641 if (!m_contentLayer->isFixedBackground()) {
642 m_contentLayer->removeChildren();
643 LayerAndroid* layer = new FixedBackgroundLayerAndroid(*m_contentLayer);
644 m_contentLayer->unref();
645 m_contentLayer = layer;
646 }
647
648 if (m_parent) {
649 // The content layer has changed so the parent needs to sync
650 // children.
651 static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
652 }
653 // Children are all re-parented.
654 m_needsSyncChildren = true;
655
656 setNeedsDisplay();
657 askForSync();
658 }
659
updateScrollOffset()660 void GraphicsLayerAndroid::updateScrollOffset() {
661 RenderLayer* layer = renderLayerFromClient(m_client);
662 if (!layer || !(m_foregroundLayer || m_contentLayer->contentIsScrollable()))
663 return;
664 if (m_foregroundLayer) {
665 IntSize scroll = layer->scrolledContentOffset();
666 m_foregroundLayer->setScrollOffset(IntPoint(scroll.width(), scroll.height()));
667 } else if (m_contentLayer->isIFrameContent()) {
668 IntPoint p(layer->renderer()->frame()->view()->scrollX(),
669 layer->renderer()->frame()->view()->scrollY());
670 static_cast<IFrameContentLayerAndroid*>(m_contentLayer)->setIFrameScrollOffset(p);
671 }
672 askForSync();
673 }
674
setScrollLimits(ScrollableLayerAndroid * scrollableLayer,RenderLayer * renderLayer)675 static void setScrollLimits(ScrollableLayerAndroid* scrollableLayer, RenderLayer* renderLayer)
676 {
677 RenderBox* box = renderLayer->renderBox();
678 scrollableLayer->setScrollLimits(0, 0,
679 renderLayer->scrollWidth() - box->clientWidth(),
680 renderLayer->scrollHeight() - box->clientHeight());
681 }
682
repaint()683 bool GraphicsLayerAndroid::repaint()
684 {
685 ALOGV("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
686 this, gPaused, m_needsRepaint, m_haveContents);
687
688 if (!gPaused && m_haveContents && m_needsRepaint && !m_image) {
689 // with SkPicture, we request the entire layer's content.
690 IntRect layerBounds(0, 0, m_size.width(), m_size.height());
691
692 RenderLayer* layer = renderLayerFromClient(m_client);
693 if (!layer)
694 return false;
695 if (m_foregroundLayer && !m_contentLayer->isFixedBackground()) {
696 PaintingPhase phase(this);
697 // Paint the background into a separate context.
698 phase.set(GraphicsLayerPaintBackground);
699 if (!paintContext(m_contentLayer, m_contentLayerContent))
700 return false;
701
702 // Construct the foreground layer and draw.
703 RenderBox* box = layer->renderBox();
704 int outline = box->view()->maximalOutlineSize();
705 IntRect contentsRect(0, 0,
706 box->borderLeft() + box->borderRight() + layer->scrollWidth()
707 + layer->verticalScrollbarWidth(),
708 box->borderTop() + box->borderBottom() + layer->scrollHeight()
709 + layer->horizontalScrollbarHeight());
710 contentsRect.inflate(outline);
711 // Update the foreground layer size.
712 m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height());
713 // Paint everything else into the main recording canvas.
714 phase.clear(GraphicsLayerPaintBackground);
715
716 // Invalidate the entire layer for now, as webkit will only send the
717 // setNeedsDisplayInRect() for the visible (clipped) scrollable area,
718 // offsetting the invals by the scroll position would not be enough.
719 // TODO: have webkit send us invals even for non visible area
720 m_foregroundLayerContent.invalidate(IntRect(0, 0, contentsRect.width(), contentsRect.height()));
721
722 // Paint at 0,0.
723 IntSize scroll = layer->scrolledContentOffset();
724 layer->scrollToOffset(0, 0);
725 // At this point, it doesn't matter if painting failed.
726 (void) paintContext(m_foregroundLayer, m_foregroundLayerContent);
727 layer->scrollToOffset(scroll.width(), scroll.height());
728
729 // Construct the clip layer for masking the contents.
730 IntRect clip = layer->renderer()->absoluteBoundingBoxRect();
731 // absoluteBoundingBoxRect does not include the outline so we need
732 // to offset the position.
733 int x = box->borderLeft() + outline;
734 int y = box->borderTop() + outline;
735 int width = clip.width() - box->borderLeft() - box->borderRight();
736 int height = clip.height() - box->borderTop() - box->borderBottom();
737 m_foregroundClipLayer->setPosition(x, y);
738 m_foregroundClipLayer->setSize(width, height);
739
740 int rtlOffset = 0; // LTR uses no offset.
741 if (!layer->renderer()->style()->isLeftToRightDirection())
742 rtlOffset = layer->scrollWidth() - width; // Scroll all the way right.
743 m_foregroundLayer->setScrollOffset(IntPoint(scroll.width() + rtlOffset,
744 scroll.height()));
745 // Need to offset the foreground layer by the clip layer in order
746 // for the contents to be in the correct position.
747 m_foregroundLayer->setPosition(-x, -y);
748 // Set the scrollable bounds of the layer.
749 setScrollLimits(static_cast<ScrollableLayerAndroid*>(m_foregroundLayer), layer);
750
751 m_foregroundLayer->markAsDirty(m_foregroundLayerContent.dirtyRegion());
752 m_foregroundLayerContent.dirtyRegion().setEmpty();
753 } else if (m_contentLayer->isFixedBackground()) {
754 SkPicture* picture = new SkPicture();
755 SkCanvas* canvas = picture->beginRecording(layerBounds.width(),
756 layerBounds.height(), 0);
757 if (canvas) {
758 PaintingPhase phase(this);
759 PlatformGraphicsContextSkia platformContext(canvas);
760 GraphicsContext graphicsContext(&platformContext);
761
762 // Paint the background (without the fixed image)...
763 phase.set(GraphicsLayerPaintBackgroundDecorations);
764 paintGraphicsLayerContents(graphicsContext, layerBounds);
765 phase.clear(GraphicsLayerPaintBackgroundDecorations);
766
767 // Paint the foreground...
768 phase.set(GraphicsLayerPaintForeground);
769 paintGraphicsLayerContents(graphicsContext, layerBounds);
770 picture->endRecording();
771
772 // Now set the content for that layer.
773 PictureLayerContent* layerContent = new PictureLayerContent(picture);
774 m_foregroundLayer->setContent(layerContent);
775 SkSafeUnref(layerContent);
776 }
777 SkSafeUnref(picture);
778
779 m_foregroundLayer->setSize(layerBounds.width(), layerBounds.height());
780 m_foregroundClipLayer->setPosition(layerBounds.x(), layerBounds.y());
781 m_foregroundClipLayer->setSize(layerBounds.width(), layerBounds.height());
782 } else {
783
784 // If we are replicated, paint the mask
785 if (isReplicated()) {
786 GraphicsLayerAndroid* replicatedLayer = static_cast<GraphicsLayerAndroid*>(replicaLayer());
787 if (replicatedLayer->maskLayer()) {
788 GraphicsLayerAndroid* mask = static_cast<GraphicsLayerAndroid*>(replicatedLayer->maskLayer());
789 mask->paintContext(mask->m_contentLayer, mask->m_contentLayerContent);
790 }
791 }
792
793 // If there is no contents clip, we can draw everything into one
794 // picture.
795 bool painting = paintContext(m_contentLayer, m_contentLayerContent);
796 if (!painting)
797 return false;
798 // Check for a scrollable iframe and report the scrolling
799 // limits based on the view size.
800 if (m_contentLayer->isIFrameContent()) {
801 FrameView* view = layer->renderer()->frame()->view();
802 setScrollLimits(static_cast<ScrollableLayerAndroid*>(m_contentLayer), layer);
803 ALOGV("setScrollLimits(%.2f, %.2f, w: %d h: %d) layer %d, frame scroll position is %d, %d",
804 m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight(),
805 m_contentLayer->uniqueId(), view->scrollX(), view->scrollY());
806 }
807 }
808
809 ALOGV("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
810 this, m_size.width(), m_size.height(),
811 m_contentLayer->getPosition().fX,
812 m_contentLayer->getPosition().fY,
813 m_contentLayer->getSize().width(),
814 m_contentLayer->getSize().height());
815
816 m_contentLayer->markAsDirty(m_contentLayerContent.dirtyRegion());
817 m_contentLayerContent.dirtyRegion().setEmpty();
818 m_needsRepaint = false;
819
820 return true;
821 }
822 if (m_needsRepaint && m_image && m_newImage) {
823 // We need to tell the GL thread that we will need to repaint the
824 // texture. Only do so if we effectively have a new image!
825 m_contentLayer->markAsDirty(m_contentLayerContent.dirtyRegion());
826 m_contentLayerContent.dirtyRegion().setEmpty();
827 m_newImage = false;
828 m_needsRepaint = false;
829 return true;
830 }
831 return false;
832 }
833
paintContents(GraphicsContext * gc,IntRect & dirty)834 void GraphicsLayerAndroid::paintContents(GraphicsContext* gc, IntRect& dirty)
835 {
836 paintGraphicsLayerContents(*gc, dirty);
837 }
838
paintContext(LayerAndroid * layer,PicturePile & picture)839 bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
840 PicturePile& picture)
841 {
842 if (!layer)
843 return false;
844
845 TRACE_METHOD();
846
847 picture.setSize(IntSize(layer->getWidth(), layer->getHeight()));
848
849 // TODO: add content checks (text, opacity, etc.)
850 picture.updatePicturesIfNeeded(this);
851
852 // store the newly painted content in the layer if it's not empty
853 PicturePileLayerContent* content = new PicturePileLayerContent(picture);
854 layer->setContent(content->isEmpty() ? 0 : content);
855 SkSafeUnref(content);
856
857 return true;
858 }
859
setNeedsDisplayInRect(const FloatRect & rect)860 void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
861 {
862 // rect is in the render object coordinates
863
864 if (!m_image && !drawsContent()) {
865 ALOGV("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
866 this, rect.x(), rect.y(), rect.width(), rect.height());
867 return;
868 }
869
870 m_contentLayerContent.invalidate(enclosingIntRect(rect));
871 if (m_foregroundLayer)
872 m_foregroundLayerContent.invalidate(enclosingIntRect(rect));
873
874 m_needsRepaint = true;
875 askForSync();
876 }
877
pauseDisplay(bool state)878 void GraphicsLayerAndroid::pauseDisplay(bool state)
879 {
880 gPaused = state;
881 if (gPaused)
882 gPausedDelay = WTF::currentTime() + 1;
883 }
884
addAnimation(const KeyframeValueList & valueList,const IntSize & boxSize,const Animation * anim,const String & keyframesName,double beginTime)885 bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList,
886 const IntSize& boxSize,
887 const Animation* anim,
888 const String& keyframesName,
889 double beginTime)
890 {
891 if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
892 return false;
893
894 bool createdAnimations = false;
895 if (valueList.property() == AnimatedPropertyWebkitTransform) {
896 createdAnimations = createTransformAnimationsFromKeyframes(valueList,
897 anim,
898 keyframesName,
899 beginTime,
900 boxSize);
901 } else {
902 createdAnimations = createAnimationFromKeyframes(valueList,
903 anim,
904 keyframesName,
905 beginTime);
906 }
907 if (createdAnimations)
908 askForSync();
909 return createdAnimations;
910 }
911
createAnimationFromKeyframes(const KeyframeValueList & valueList,const Animation * animation,const String & keyframesName,double beginTime)912 bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList,
913 const Animation* animation, const String& keyframesName, double beginTime)
914 {
915 bool isKeyframe = valueList.size() > 2;
916 ALOGV("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
917 isKeyframe, keyframesName.ascii().data(), beginTime);
918
919 switch (valueList.property()) {
920 case AnimatedPropertyInvalid: break;
921 case AnimatedPropertyWebkitTransform: break;
922 case AnimatedPropertyBackgroundColor: break;
923 case AnimatedPropertyOpacity: {
924 ALOGV("ANIMATEDPROPERTYOPACITY");
925
926 KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity);
927 for (unsigned int i = 0; i < valueList.size(); i++) {
928 FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i);
929 RefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
930 FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(),
931 originalValue->value(),
932 timingFunction);
933 operationsList->insert(value);
934 }
935
936 RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(animation,
937 operationsList,
938 beginTime);
939 if (keyframesName.isEmpty())
940 anim->setName(propertyIdToString(valueList.property()));
941 else
942 anim->setName(keyframesName);
943
944 m_contentLayer->addAnimation(anim.release());
945 needsNotifyClient();
946 return true;
947 } break;
948 }
949 return false;
950 }
951
needsNotifyClient()952 void GraphicsLayerAndroid::needsNotifyClient()
953 {
954 m_needsNotifyClient = true;
955 askForSync();
956 }
957
createTransformAnimationsFromKeyframes(const KeyframeValueList & valueList,const Animation * animation,const String & keyframesName,double beginTime,const IntSize & boxSize)958 bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList,
959 const Animation* animation,
960 const String& keyframesName,
961 double beginTime,
962 const IntSize& boxSize)
963 {
964 ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
965 ALOGV("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
966 keyframesName.ascii().data(), beginTime);
967
968 KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform);
969 for (unsigned int i = 0; i < valueList.size(); i++) {
970 TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i);
971 RefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
972 TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(),
973 originalValue->value(),
974 timingFunction);
975 operationsList->insert(value);
976 }
977
978 RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation,
979 operationsList,
980 beginTime);
981
982 if (keyframesName.isEmpty())
983 anim->setName(propertyIdToString(valueList.property()));
984 else
985 anim->setName(keyframesName);
986
987
988 m_contentLayer->addAnimation(anim.release());
989
990 needsNotifyClient();
991 return true;
992 }
993
removeAnimationsForProperty(AnimatedPropertyID anID)994 void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
995 {
996 ALOGV("NRO removeAnimationsForProperty(%d)", anID);
997 m_contentLayer->removeAnimationsForProperty(anID);
998 askForSync();
999 }
1000
removeAnimationsForKeyframes(const String & keyframesName)1001 void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
1002 {
1003 ALOGV("NRO removeAnimationsForKeyframes(%s)", keyframesName.ascii().data());
1004 m_contentLayer->removeAnimationsForKeyframes(keyframesName);
1005 askForSync();
1006 }
1007
pauseAnimation(const String & keyframesName)1008 void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName)
1009 {
1010 ALOGV("NRO pauseAnimation(%s)", keyframesName.ascii().data());
1011 }
1012
suspendAnimations(double time)1013 void GraphicsLayerAndroid::suspendAnimations(double time)
1014 {
1015 ALOGV("NRO suspendAnimations(%.2f)", time);
1016 }
1017
resumeAnimations()1018 void GraphicsLayerAndroid::resumeAnimations()
1019 {
1020 ALOGV("NRO resumeAnimations()");
1021 }
1022
setContentsToImage(Image * image)1023 void GraphicsLayerAndroid::setContentsToImage(Image* image)
1024 {
1025 ALOGV("(%x) setContentsToImage", this, image);
1026 if (image && image != m_image) {
1027 image->ref();
1028 if (m_image)
1029 m_image->deref();
1030 m_image = image;
1031
1032 SkBitmapRef* bitmap = image->nativeImageForCurrentFrame();
1033 m_contentLayer->setContentsImage(bitmap);
1034
1035 m_haveContents = true;
1036 m_newImage = true;
1037 }
1038 if (!image && m_image) {
1039 m_contentLayer->setContentsImage(0);
1040 m_image->deref();
1041 m_image = 0;
1042 }
1043
1044 setNeedsDisplay();
1045 askForSync();
1046 }
1047
setContentsToMedia(PlatformLayer * mediaLayer)1048 void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
1049 {
1050 // Only fullscreen video on Android, so media doesn't get it's own layer.
1051 // We might still have other layers though.
1052 if (m_contentLayer != mediaLayer && mediaLayer) {
1053
1054 // TODO add a copy method to LayerAndroid to sync everything
1055 // copy data from the original content layer to the new one
1056 mediaLayer->setPosition(m_contentLayer->getPosition().fX,
1057 m_contentLayer->getPosition().fY);
1058 mediaLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight());
1059 mediaLayer->setDrawTransform(*m_contentLayer->drawTransform());
1060
1061 mediaLayer->ref();
1062 m_contentLayer->unref();
1063 m_contentLayer = mediaLayer;
1064
1065 // If the parent exists then notify it to re-sync it's children
1066 if (m_parent) {
1067 GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
1068 parent->m_needsSyncChildren = true;
1069 }
1070 m_needsSyncChildren = true;
1071
1072 setNeedsDisplay();
1073 askForSync();
1074 }
1075 }
1076
platformLayer() const1077 PlatformLayer* GraphicsLayerAndroid::platformLayer() const
1078 {
1079 ALOGV("platformLayer");
1080 return m_contentLayer;
1081 }
1082
1083 #ifndef NDEBUG
setDebugBackgroundColor(const Color & color)1084 void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color)
1085 {
1086 }
1087
setDebugBorder(const Color & color,float borderWidth)1088 void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth)
1089 {
1090 }
1091 #endif
1092
setZPosition(float position)1093 void GraphicsLayerAndroid::setZPosition(float position)
1094 {
1095 if (position == m_zPosition)
1096 return;
1097 ALOGV("(%x) setZPosition: %.2f", this, position);
1098 GraphicsLayer::setZPosition(position);
1099 askForSync();
1100 }
1101
askForSync()1102 void GraphicsLayerAndroid::askForSync()
1103 {
1104 if (!m_client)
1105 return;
1106
1107 if (m_client)
1108 m_client->notifySyncRequired(this);
1109 }
1110
syncChildren()1111 void GraphicsLayerAndroid::syncChildren()
1112 {
1113 if (m_needsSyncChildren || isReplicated()) {
1114 m_contentLayer->removeChildren();
1115 LayerAndroid* layer = m_contentLayer;
1116
1117 if (isReplicated()) {
1118 GraphicsLayerAndroid* replicatedLayer = static_cast<GraphicsLayerAndroid*>(replicaLayer());
1119 m_contentLayer->addChild(replicatedLayer->m_contentLayer);
1120 }
1121
1122 if (m_contentLayer->isFixedBackground()) {
1123 m_contentLayer->addChild(m_foregroundClipLayer);
1124 m_contentLayer->addChild(m_foregroundLayer);
1125 layer = m_foregroundLayer;
1126 layer->removeChildren();
1127 } else if (m_foregroundClipLayer) {
1128 m_contentLayer->addChild(m_foregroundClipLayer);
1129 // Use the scrollable content layer as the parent of the children so
1130 // that they move with the content.
1131 layer = m_foregroundLayer;
1132 layer->removeChildren();
1133 }
1134
1135 for (unsigned int i = 0; i < m_children.size(); i++)
1136 layer->addChild(m_children[i]->platformLayer());
1137 }
1138 m_needsSyncChildren = false;
1139 }
1140
syncMask()1141 void GraphicsLayerAndroid::syncMask()
1142 {
1143 if (m_needsSyncMask) {
1144 if (m_maskLayer) {
1145 LayerAndroid* mask = m_maskLayer->platformLayer();
1146 m_contentLayer->setMaskLayer(mask);
1147 } else
1148 m_contentLayer->setMaskLayer(0);
1149
1150 m_contentLayer->setMasksToBounds(m_masksToBounds);
1151 m_needsSyncMask = false;
1152 }
1153 }
1154
gatherRootLayers(Vector<const RenderLayer * > & list)1155 void GraphicsLayerAndroid::gatherRootLayers(Vector<const RenderLayer*>& list)
1156 {
1157 RenderLayer* renderLayer = renderLayerFromClient(m_client);
1158 if (renderLayer) {
1159 const RenderLayer* rootLayer = renderLayer->root();
1160 bool found = false;
1161 for (unsigned int i = 0; i < list.size(); i++) {
1162 const RenderLayer* current = list[i];
1163 if (current == rootLayer) {
1164 found = true;
1165 break;
1166 }
1167 }
1168 if (!found)
1169 list.append(rootLayer);
1170 }
1171
1172 for (unsigned int i = 0; i < m_children.size(); i++) {
1173 GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]);
1174 layer->gatherRootLayers(list);
1175 }
1176 }
1177
syncCompositingStateForThisLayerOnly()1178 void GraphicsLayerAndroid::syncCompositingStateForThisLayerOnly()
1179 {
1180 if (m_contentLayer) {
1181 RenderLayer* renderLayer = renderLayerFromClient(m_client);
1182 int intrinsicallyComposited = renderLayer ? renderLayer->intrinsicallyComposited() : true;
1183 m_contentLayer->setIntrinsicallyComposited(intrinsicallyComposited);
1184 }
1185
1186 updateScrollingLayers();
1187 updateFixedBackgroundLayers();
1188 updatePositionedLayers();
1189 syncChildren();
1190 syncMask();
1191
1192 if (!gPaused || WTF::currentTime() >= gPausedDelay)
1193 repaint();
1194 }
1195
syncCompositingState()1196 void GraphicsLayerAndroid::syncCompositingState()
1197 {
1198 for (unsigned int i = 0; i < m_children.size(); i++)
1199 m_children[i]->syncCompositingState();
1200
1201 syncCompositingStateForThisLayerOnly();
1202 }
1203
notifyClientAnimationStarted()1204 void GraphicsLayerAndroid::notifyClientAnimationStarted()
1205 {
1206 for (unsigned int i = 0; i < m_children.size(); i++)
1207 static_cast<GraphicsLayerAndroid*>(m_children[i])->notifyClientAnimationStarted();
1208
1209 if (m_needsNotifyClient) {
1210 if (client())
1211 client()->notifyAnimationStarted(this, WTF::currentTime());
1212 m_needsNotifyClient = false;
1213 }
1214 }
1215
1216 } // namespace WebCore
1217
1218 #endif // USE(ACCELERATED_COMPOSITING)
1219