OSDN Git Service

Merge "Don't prepare offscreen tiles" into ics-mr1
[android-x86/external-webkit.git] / Source / WebCore / platform / graphics / android / GraphicsLayerAndroid.cpp
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 "FloatRect.h"
25 #include "GraphicsContext.h"
26 #include "Image.h"
27 #include "ImagesManager.h"
28 #include "Layer.h"
29 #include "Length.h"
30 #include "MediaLayer.h"
31 #include "PlatformBridge.h"
32 #include "PlatformGraphicsContext.h"
33 #include "RenderLayerBacking.h"
34 #include "RenderView.h"
35 #include "RotateTransformOperation.h"
36 #include "ScaleTransformOperation.h"
37 #include "ScrollableLayerAndroid.h"
38 #include "SkCanvas.h"
39 #include "SkRegion.h"
40 #include "TransformationMatrix.h"
41 #include "TranslateTransformOperation.h"
42
43 #include <cutils/log.h>
44 #include <wtf/CurrentTime.h>
45 #include <wtf/text/CString.h>
46
47 #undef LOG
48 #define LOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
49 #define MLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
50 #define TLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
51
52 #undef LOG
53 #define LOG(...)
54 #undef MLOG
55 #define MLOG(...)
56 #undef TLOG
57 #define TLOG(...)
58 #undef LAYER_DEBUG
59
60 using namespace std;
61
62 static bool gPaused;
63 static double gPausedDelay;
64
65 namespace WebCore {
66
67 static int gDebugGraphicsLayerAndroidInstances = 0;
68 inline int GraphicsLayerAndroid::instancesCount()
69 {
70     return gDebugGraphicsLayerAndroidInstances;
71 }
72
73 static String propertyIdToString(AnimatedPropertyID property)
74 {
75     switch (property) {
76     case AnimatedPropertyWebkitTransform:
77         return "transform";
78     case AnimatedPropertyOpacity:
79         return "opacity";
80     case AnimatedPropertyBackgroundColor:
81         return "backgroundColor";
82     case AnimatedPropertyInvalid:
83         ASSERT_NOT_REACHED();
84     }
85     ASSERT_NOT_REACHED();
86     return "";
87 }
88
89 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
90 {
91     return new GraphicsLayerAndroid(client);
92 }
93
94 SkLength convertLength(Length len)
95 {
96     SkLength length;
97     length.type = SkLength::Undefined;
98     length.value = 0;
99     if (len.type() == WebCore::Percent) {
100         length.type = SkLength::Percent;
101         length.value = len.percent();
102     }
103     if (len.type() == WebCore::Fixed) {
104         length.type = SkLength::Fixed;
105         length.value = len.value();
106     }
107     return length;
108 }
109
110 static RenderLayer* renderLayerFromClient(GraphicsLayerClient* client)
111 {
112     return client ? client->owningLayer() : 0;
113 }
114
115 GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
116     GraphicsLayer(client),
117     m_needsSyncChildren(false),
118     m_needsSyncMask(false),
119     m_needsRepaint(false),
120     m_needsNotifyClient(false),
121     m_haveContents(false),
122     m_haveImage(false),
123     m_newImage(false),
124     m_foregroundLayer(0),
125     m_foregroundClipLayer(0)
126 {
127     RenderLayer* renderLayer = renderLayerFromClient(m_client);
128     m_contentLayer = new LayerAndroid(renderLayer);
129     m_dirtyRegion.setEmpty();
130     gDebugGraphicsLayerAndroidInstances++;
131 }
132
133 GraphicsLayerAndroid::~GraphicsLayerAndroid()
134 {
135     m_contentLayer->unref();
136     SkSafeUnref(m_foregroundLayer);
137     SkSafeUnref(m_foregroundClipLayer);
138     gDebugGraphicsLayerAndroidInstances--;
139 }
140
141 void GraphicsLayerAndroid::setName(const String& name)
142 {
143     GraphicsLayer::setName(name);
144 }
145
146 NativeLayer GraphicsLayerAndroid::nativeLayer() const
147 {
148     LOG("(%x) nativeLayer", this);
149     return 0;
150 }
151
152 bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children)
153 {
154     bool childrenChanged = GraphicsLayer::setChildren(children);
155     if (childrenChanged) {
156         m_needsSyncChildren = true;
157         askForSync();
158     }
159
160     return childrenChanged;
161 }
162
163 void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
164 {
165 #ifndef NDEBUG
166     const String& name = childLayer->name();
167     LOG("(%x) addChild: %x (%s)", this, childLayer, name.latin1().data());
168 #endif
169     GraphicsLayer::addChild(childLayer);
170     m_needsSyncChildren = true;
171     askForSync();
172 }
173
174 void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
175 {
176     LOG("(%x) addChild %x AtIndex %d", this, childLayer, index);
177     GraphicsLayer::addChildAtIndex(childLayer, index);
178     m_needsSyncChildren = true;
179     askForSync();
180 }
181
182 void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
183 {
184     LOG("(%x) addChild %x Below %x", this, childLayer, sibling);
185     GraphicsLayer::addChildBelow(childLayer, sibling);
186     m_needsSyncChildren = true;
187     askForSync();
188 }
189
190 void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
191 {
192     LOG("(%x) addChild %x Above %x", this, childLayer, sibling);
193     GraphicsLayer::addChildAbove(childLayer, sibling);
194     m_needsSyncChildren = true;
195     askForSync();
196 }
197
198 bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
199 {
200     LOG("(%x) replaceChild %x by %x", this, oldChild, newChild);
201     bool ret = GraphicsLayer::replaceChild(oldChild, newChild);
202     if (ret) {
203         m_needsSyncChildren = true;
204         askForSync();
205     }
206     return ret;
207 }
208
209 void GraphicsLayerAndroid::removeFromParent()
210 {
211     LOG("(%x) removeFromParent()", this);
212     GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
213     GraphicsLayer::removeFromParent();
214     // Update the parent's children.
215     if (parent) {
216         parent->m_needsSyncChildren = true;
217         askForSync();
218     }
219 }
220
221 void GraphicsLayerAndroid::updateFixedPosition()
222 {
223     RenderLayer* renderLayer = renderLayerFromClient(m_client);
224     if (!renderLayer)
225         return;
226     RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
227
228     if (!view)
229         return;
230
231     // We will need the Iframe flag in the LayerAndroid tree for fixed position
232     if (view->isRenderIFrame())
233         m_contentLayer->setIsIframe(true);
234     // If we are a fixed position layer, just set it
235     if (view->isPositioned() && view->style()->position() == FixedPosition) {
236         // We need to get the passed CSS properties for the element
237         SkLength left, top, right, bottom;
238         left = convertLength(view->style()->left());
239         top = convertLength(view->style()->top());
240         right = convertLength(view->style()->right());
241         bottom = convertLength(view->style()->bottom());
242
243         // We also need to get the margin...
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         // In order to compute the fixed element's position, we need the width
251         // and height of the element when bottom or right is defined.
252         // And here we should use the non-overflowed value, that means, the
253         // overflowed content (e.g. outset shadow) will not be counted into the
254         // width and height.
255         int w = view->width();
256         int h = view->height();
257
258         int paintingOffsetX = - offsetFromRenderer().width();
259         int paintingOffsetY = - offsetFromRenderer().height();
260
261         SkRect viewRect;
262         viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h);
263         IntPoint renderLayerPos(renderLayer->x(), renderLayer->y());
264         m_contentLayer->setFixedPosition(left, top, right, bottom,
265                                          marginLeft, marginTop,
266                                          marginRight, marginBottom,
267                                          renderLayerPos,
268                                          viewRect);
269     }
270 }
271
272 void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
273 {
274     if (point == m_position)
275         return;
276
277     GraphicsLayer::setPosition(point);
278
279 #ifdef LAYER_DEBUG_2
280     LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
281         this, point.x(), point.y(), m_position.x(), m_position.y(),
282         m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
283 #endif
284     m_contentLayer->setPosition(point.x(), point.y());
285     askForSync();
286 }
287
288 void GraphicsLayerAndroid::setPreserves3D(bool preserves3D)
289 {
290     if (preserves3D == m_preserves3D)
291         return;
292
293     GraphicsLayer::setPreserves3D(preserves3D);
294     m_contentLayer->setPreserves3D(preserves3D);
295     askForSync();
296 }
297
298 void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point)
299 {
300     if (point == m_anchorPoint)
301         return;
302     GraphicsLayer::setAnchorPoint(point);
303     m_contentLayer->setAnchorPoint(point.x(), point.y());
304     m_contentLayer->setAnchorPointZ(point.z());
305     askForSync();
306 }
307
308 void GraphicsLayerAndroid::setSize(const FloatSize& size)
309 {
310     if (size == m_size)
311         return;
312     MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
313     GraphicsLayer::setSize(size);
314
315     // If it is a media layer the size may have changed as a result of the media
316     // element (e.g. plugin) gaining focus. Therefore, we must sync the size of
317     // the focus' outline so that our UI thread can draw accordingly.
318     RenderLayer* layer = renderLayerFromClient(m_client);
319     if (layer && m_contentLayer->isMedia()) {
320         RenderBox* box = layer->renderBox();
321         int outline = box->view()->maximalOutlineSize();
322         static_cast<MediaLayer*>(m_contentLayer)->setOutlineSize(outline);
323         LOG("Media Outline: %d %p %p %p", outline, m_client, layer, box);
324         LOG("Media Size: %g,%g", size.width(), size.height());
325     }
326
327     m_contentLayer->setSize(size.width(), size.height());
328     setNeedsDisplay();
329     askForSync();
330 }
331
332 void GraphicsLayerAndroid::setBackfaceVisibility(bool b)
333 {
334     if (b == m_backfaceVisibility)
335         return;
336
337     GraphicsLayer::setBackfaceVisibility(b);
338     m_contentLayer->setBackfaceVisibility(b);
339     askForSync();
340 }
341
342 void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t)
343 {
344     if (t == m_transform)
345         return;
346
347     GraphicsLayer::setTransform(t);
348     m_contentLayer->setTransform(t);
349     askForSync();
350 }
351
352 void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
353 {
354     if (t == m_childrenTransform)
355        return;
356     LOG("(%x) setChildrenTransform", this);
357
358     GraphicsLayer::setChildrenTransform(t);
359     m_contentLayer->setChildrenTransform(t);
360     for (unsigned int i = 0; i < m_children.size(); i++) {
361         GraphicsLayer* layer = m_children[i];
362         layer->setTransform(t);
363         if (layer->children().size())
364             layer->setChildrenTransform(t);
365     }
366     askForSync();
367 }
368
369 void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer)
370 {
371     if (layer == m_maskLayer)
372         return;
373
374     GraphicsLayer::setMaskLayer(layer);
375     m_needsSyncMask = true;
376     askForSync();
377 }
378
379 void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds)
380 {
381     if (masksToBounds == m_masksToBounds)
382         return;
383     GraphicsLayer::setMasksToBounds(masksToBounds);
384     m_needsSyncMask = true;
385     askForSync();
386 }
387
388 void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
389 {
390     if (drawsContent == m_drawsContent)
391         return;
392     GraphicsLayer::setDrawsContent(drawsContent);
393     m_contentLayer->setVisible(drawsContent);
394     if (m_drawsContent) {
395         m_haveContents = true;
396         setNeedsDisplay();
397     }
398     askForSync();
399 }
400
401 void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
402 {
403     if (color == m_backgroundColor && m_backgroundColorSet)
404         return;
405     LOG("(%x) setBackgroundColor", this);
406     GraphicsLayer::setBackgroundColor(color);
407     SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
408     m_contentLayer->setBackgroundColor(c);
409     m_haveContents = true;
410     askForSync();
411 }
412
413 void GraphicsLayerAndroid::clearBackgroundColor()
414 {
415     if (!m_backgroundColorSet)
416         return;
417
418     LOG("(%x) clearBackgroundColor", this);
419     GraphicsLayer::clearBackgroundColor();
420     askForSync();
421 }
422
423 void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
424 {
425     if (opaque == m_contentsOpaque)
426         return;
427     LOG("(%x) setContentsOpaque (%d)", this, opaque);
428     GraphicsLayer::setContentsOpaque(opaque);
429     m_haveContents = true;
430     askForSync();
431 }
432
433 void GraphicsLayerAndroid::setOpacity(float opacity)
434 {
435     LOG("(%x) setOpacity: %.2f", this, opacity);
436     float clampedOpacity = max(0.0f, min(opacity, 1.0f));
437
438     if (clampedOpacity == m_opacity)
439         return;
440
441     MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
442         opacity, clampedOpacity, m_opacity);
443     GraphicsLayer::setOpacity(clampedOpacity);
444     m_contentLayer->setOpacity(clampedOpacity);
445     askForSync();
446 }
447
448 void GraphicsLayerAndroid::setNeedsDisplay()
449 {
450     LOG("(%x) setNeedsDisplay()", this);
451     FloatRect rect(0, 0, m_size.width(), m_size.height());
452     setNeedsDisplayInRect(rect);
453 }
454
455 // Helper to set and clear the painting phase as well as auto restore the
456 // original phase.
457 class PaintingPhase {
458 public:
459     PaintingPhase(GraphicsLayer* layer)
460         : m_layer(layer)
461         , m_originalPhase(layer->paintingPhase()) {}
462
463     ~PaintingPhase()
464     {
465         m_layer->setPaintingPhase(m_originalPhase);
466     }
467
468     void set(GraphicsLayerPaintingPhase phase)
469     {
470         m_layer->setPaintingPhase(phase);
471     }
472
473     void clear(GraphicsLayerPaintingPhase phase)
474     {
475         m_layer->setPaintingPhase(
476                 (GraphicsLayerPaintingPhase) (m_originalPhase & ~phase));
477     }
478 private:
479     GraphicsLayer* m_layer;
480     GraphicsLayerPaintingPhase m_originalPhase;
481 };
482
483 void GraphicsLayerAndroid::updateScrollingLayers()
484 {
485 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
486     RenderLayer* layer = renderLayerFromClient(m_client);
487     if (!layer || !m_haveContents)
488         return;
489     bool hasOverflowScroll = m_foregroundLayer || m_contentLayer->contentIsScrollable();
490     bool layerNeedsOverflow = layer->hasOverflowScroll();
491     bool iframeNeedsOverflow = layer->isRootLayer() &&
492         layer->renderer()->frame()->ownerRenderer() &&
493         layer->renderer()->frame()->view()->hasOverflowScroll();
494
495     if (hasOverflowScroll && (layerNeedsOverflow || iframeNeedsOverflow)) {
496         // Already has overflow layers.
497         return;
498     }
499     if (!hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow) {
500         // Does not need overflow layers.
501         return;
502     }
503     if (layerNeedsOverflow || iframeNeedsOverflow) {
504         ASSERT(!hasOverflowScroll);
505         if (layerNeedsOverflow) {
506             ASSERT(!m_foregroundLayer && !m_foregroundClipLayer);
507             m_foregroundLayer = new ScrollableLayerAndroid(layer);
508             m_foregroundClipLayer = new LayerAndroid(layer);
509             m_foregroundClipLayer->setMasksToBounds(true);
510             m_foregroundClipLayer->addChild(m_foregroundLayer);
511             m_contentLayer->addChild(m_foregroundClipLayer);
512             m_contentLayer->setHasOverflowChildren(true);
513         } else {
514             ASSERT(iframeNeedsOverflow && !m_contentLayer->contentIsScrollable());
515             // No need to copy the children as they will be removed and synced.
516             m_contentLayer->removeChildren();
517             // Replace the content layer with a scrollable layer.
518             LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer);
519             m_contentLayer->unref();
520             m_contentLayer = layer;
521             if (m_parent) {
522                 // The content layer has changed so the parent needs to sync
523                 // children.
524                 static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
525             }
526         }
527         // Need to rebuild our children based on the new structure.
528         m_needsSyncChildren = true;
529     } else {
530         ASSERT(hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow);
531         ASSERT(m_contentLayer);
532         // Remove the foreground layers.
533         if (m_foregroundLayer) {
534             m_foregroundLayer->unref();
535             m_foregroundLayer = 0;
536             m_foregroundClipLayer->unref();
537             m_foregroundClipLayer = 0;
538         }
539         // No need to copy over children.
540         m_contentLayer->removeChildren();
541         LayerAndroid* layer = new LayerAndroid(*m_contentLayer);
542         m_contentLayer->unref();
543         m_contentLayer = layer;
544         if (m_parent) {
545             // The content layer has changed so the parent needs to sync
546             // children.
547             static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
548         }
549         // Children are all re-parented.
550         m_needsSyncChildren = true;
551     }
552 #endif
553 }
554
555 bool GraphicsLayerAndroid::repaint()
556 {
557     LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
558         this, gPaused, m_needsRepaint, m_haveContents);
559
560     if (!gPaused && m_haveContents && m_needsRepaint && !m_haveImage) {
561         // with SkPicture, we request the entire layer's content.
562         IntRect layerBounds(0, 0, m_size.width(), m_size.height());
563
564         RenderLayer* layer = renderLayerFromClient(m_client);
565         if (!layer)
566             return false;
567         if (m_foregroundLayer) {
568             PaintingPhase phase(this);
569             // Paint the background into a separate context.
570             phase.set(GraphicsLayerPaintBackground);
571             if (!paintContext(m_contentLayer->recordContext(), layerBounds))
572                 return false;
573             m_contentLayer->checkTextPresence();
574
575             // Construct the foreground layer and draw.
576             RenderBox* box = layer->renderBox();
577             int outline = box->view()->maximalOutlineSize();
578             IntRect contentsRect(0, 0,
579                                  box->borderLeft() + box->borderRight() + layer->scrollWidth(),
580                                  box->borderTop() + box->borderBottom() + layer->scrollHeight());
581             contentsRect.inflate(outline);
582             // Update the foreground layer size.
583             m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height());
584             // Paint everything else into the main recording canvas.
585             phase.clear(GraphicsLayerPaintBackground);
586
587             // Paint at 0,0.
588             IntSize scroll = layer->scrolledContentOffset();
589             layer->scrollToOffset(0, 0);
590             // At this point, it doesn't matter if painting failed.
591             (void) paintContext(m_foregroundLayer->recordContext(), contentsRect);
592             m_foregroundLayer->checkTextPresence();
593             layer->scrollToOffset(scroll.width(), scroll.height());
594
595             // Construct the clip layer for masking the contents.
596             IntRect clip = layer->renderer()->absoluteBoundingBoxRect();
597             // absoluteBoundingBoxRect does not include the outline so we need
598             // to offset the position.
599             int x = box->borderLeft() + outline;
600             int y = box->borderTop() + outline;
601             int width = clip.width() - box->borderLeft() - box->borderRight();
602             int height = clip.height() - box->borderTop() - box->borderBottom();
603             m_foregroundClipLayer->setPosition(x, y);
604             m_foregroundClipLayer->setSize(width, height);
605
606             // Need to offset the foreground layer by the clip layer in order
607             // for the contents to be in the correct position.
608             m_foregroundLayer->setPosition(-x, -y);
609             // Set the scrollable bounds of the layer.
610             m_foregroundLayer->setScrollLimits(-x, -y, m_size.width(), m_size.height());
611             m_foregroundLayer->markAsDirty(m_dirtyRegion);
612             m_foregroundLayer->needsRepaint();
613         } else {
614             // If there is no contents clip, we can draw everything into one
615             // picture.
616             if (!paintContext(m_contentLayer->recordContext(), layerBounds))
617                 return false;
618             m_contentLayer->checkTextPresence();
619             // Check for a scrollable iframe and report the scrolling
620             // limits based on the view size.
621             if (m_contentLayer->contentIsScrollable()) {
622                 FrameView* view = layer->renderer()->frame()->view();
623                 static_cast<ScrollableLayerAndroid*>(m_contentLayer)->setScrollLimits(
624                     m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight());
625             }
626         }
627
628         LOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
629             this, m_size.width(), m_size.height(),
630             m_contentLayer->getPosition().fX,
631             m_contentLayer->getPosition().fY,
632             m_contentLayer->getSize().width(),
633             m_contentLayer->getSize().height());
634
635         m_contentLayer->markAsDirty(m_dirtyRegion);
636         m_dirtyRegion.setEmpty();
637         m_contentLayer->needsRepaint();
638         m_needsRepaint = false;
639
640         return true;
641     }
642     if (m_needsRepaint && m_haveImage && m_newImage) {
643         // We need to tell the GL thread that we will need to repaint the
644         // texture. Only do so if we effectively have a new image!
645         m_contentLayer->markAsDirty(m_dirtyRegion);
646         m_dirtyRegion.setEmpty();
647         m_contentLayer->needsRepaint();
648         m_newImage = false;
649         m_needsRepaint = false;
650         return true;
651     }
652     return false;
653 }
654
655 bool GraphicsLayerAndroid::paintContext(SkPicture* context,
656                                         const IntRect& rect)
657 {
658     SkAutoPictureRecord arp(context, rect.width(), rect.height());
659     SkCanvas* canvas = arp.getRecordingCanvas();
660
661     if (!canvas)
662         return false;
663
664     PlatformGraphicsContext platformContext(canvas);
665     GraphicsContext graphicsContext(&platformContext);
666
667     paintGraphicsLayerContents(graphicsContext, rect);
668     return true;
669 }
670
671 void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
672 {
673     // rect is in the render object coordinates
674
675     if (!m_haveImage && !drawsContent()) {
676         LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
677             this, rect.x(), rect.y(), rect.width(), rect.height());
678         return;
679     }
680
681     SkRegion region;
682     region.setRect(rect.x(), rect.y(),
683                    rect.x() + rect.width(),
684                    rect.y() + rect.height());
685     m_dirtyRegion.op(region, SkRegion::kUnion_Op);
686
687     m_needsRepaint = true;
688     askForSync();
689 }
690
691 void GraphicsLayerAndroid::pauseDisplay(bool state)
692 {
693     gPaused = state;
694     if (gPaused)
695         gPausedDelay = WTF::currentTime() + 1;
696 }
697
698 bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList,
699                                         const IntSize& boxSize,
700                                         const Animation* anim,
701                                         const String& keyframesName,
702                                         double beginTime)
703 {
704     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
705         return false;
706
707     bool createdAnimations = false;
708     if (valueList.property() == AnimatedPropertyWebkitTransform) {
709         createdAnimations = createTransformAnimationsFromKeyframes(valueList,
710                                                                    anim,
711                                                                    keyframesName,
712                                                                    beginTime,
713                                                                    boxSize);
714     } else {
715         createdAnimations = createAnimationFromKeyframes(valueList,
716                                                          anim,
717                                                          keyframesName,
718                                                          beginTime);
719     }
720     if (createdAnimations)
721         askForSync();
722     return createdAnimations;
723 }
724
725 bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList,
726      const Animation* animation, const String& keyframesName, double beginTime)
727 {
728     bool isKeyframe = valueList.size() > 2;
729     TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
730         isKeyframe, keyframesName.latin1().data(), beginTime);
731
732     switch (valueList.property()) {
733     case AnimatedPropertyInvalid: break;
734     case AnimatedPropertyWebkitTransform: break;
735     case AnimatedPropertyBackgroundColor: break;
736     case AnimatedPropertyOpacity: {
737         MLOG("ANIMATEDPROPERTYOPACITY");
738
739         KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity);
740         for (unsigned int i = 0; i < valueList.size(); i++) {
741             FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i);
742             PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
743             FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(),
744                                                                  originalValue->value(),
745                                                                  timingFunction);
746             operationsList->insert(value);
747         }
748
749         RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(animation,
750                                                                                operationsList,
751                                                                                beginTime);
752         if (keyframesName.isEmpty())
753             anim->setName(propertyIdToString(valueList.property()));
754         else
755             anim->setName(keyframesName);
756
757         m_contentLayer->addAnimation(anim.release());
758         needsNotifyClient();
759         return true;
760     } break;
761     }
762     return false;
763 }
764
765 void GraphicsLayerAndroid::needsNotifyClient()
766 {
767     m_needsNotifyClient = true;
768     askForSync();
769 }
770
771 bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList,
772                                                                   const Animation* animation,
773                                                                   const String& keyframesName,
774                                                                   double beginTime,
775                                                                   const IntSize& boxSize)
776 {
777     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
778     TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
779         keyframesName.latin1().data(), beginTime);
780
781     KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform);
782     for (unsigned int i = 0; i < valueList.size(); i++) {
783         TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i);
784         PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
785         TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(),
786                                                                      originalValue->value(),
787                                                                      timingFunction);
788         operationsList->insert(value);
789     }
790
791     RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation,
792                                                                                operationsList,
793                                                                                beginTime);
794
795     if (keyframesName.isEmpty())
796         anim->setName(propertyIdToString(valueList.property()));
797     else
798         anim->setName(keyframesName);
799
800
801     m_contentLayer->addAnimation(anim.release());
802
803     needsNotifyClient();
804     return true;
805 }
806
807 void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
808 {
809     TLOG("NRO removeAnimationsForProperty(%d)", anID);
810     m_contentLayer->removeAnimationsForProperty(anID);
811     askForSync();
812 }
813
814 void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
815 {
816     TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
817     m_contentLayer->removeAnimationsForKeyframes(keyframesName);
818     askForSync();
819 }
820
821 void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName)
822 {
823     TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data());
824 }
825
826 void GraphicsLayerAndroid::suspendAnimations(double time)
827 {
828     TLOG("NRO suspendAnimations(%.2f)", time);
829 }
830
831 void GraphicsLayerAndroid::resumeAnimations()
832 {
833     TLOG("NRO resumeAnimations()");
834 }
835
836 void GraphicsLayerAndroid::setContentsToImage(Image* image)
837 {
838     TLOG("(%x) setContentsToImage", this, image);
839     if (image) {
840         m_haveContents = true;
841         m_haveImage = true;
842         m_newImage = true;
843         m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
844     }
845     if (m_haveImage && !image)
846         m_contentLayer->setContentsImage(0);
847
848     setNeedsDisplay();
849     askForSync();
850 }
851
852 void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
853 {
854     // Only fullscreen video on Android, so media doesn't get it's own layer.
855     // We might still have other layers though.
856     if (m_contentLayer != mediaLayer && mediaLayer) {
857
858         // TODO add a copy method to LayerAndroid to sync everything
859         // copy data from the original content layer to the new one
860         mediaLayer->setPosition(m_contentLayer->getPosition().fX,
861                                 m_contentLayer->getPosition().fY);
862         mediaLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight());
863         mediaLayer->setDrawTransform(*m_contentLayer->drawTransform());
864
865         mediaLayer->ref();
866         m_contentLayer->unref();
867         m_contentLayer = mediaLayer;
868
869         // If the parent exists then notify it to re-sync it's children
870         if (m_parent) {
871             GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
872             parent->m_needsSyncChildren = true;
873         }
874         m_needsSyncChildren = true;
875
876         setNeedsDisplay();
877         askForSync();
878     }
879 }
880
881 PlatformLayer* GraphicsLayerAndroid::platformLayer() const
882 {
883     LOG("platformLayer");
884     return m_contentLayer;
885 }
886
887 #ifndef NDEBUG
888 void GraphicsLayerAndroid::setDebugBackgroundColor(const Color& color)
889 {
890 }
891
892 void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth)
893 {
894 }
895 #endif
896
897 void GraphicsLayerAndroid::setZPosition(float position)
898 {
899     if (position == m_zPosition)
900         return;
901     LOG("(%x) setZPosition: %.2f", this, position);
902     GraphicsLayer::setZPosition(position);
903     askForSync();
904 }
905
906 void GraphicsLayerAndroid::askForSync()
907 {
908     if (!m_client)
909         return;
910
911     if (m_client)
912         m_client->notifySyncRequired(this);
913 }
914
915 void GraphicsLayerAndroid::syncChildren()
916 {
917     if (m_needsSyncChildren) {
918         m_contentLayer->removeChildren();
919         LayerAndroid* layer = m_contentLayer;
920         if (m_foregroundClipLayer) {
921             m_contentLayer->addChild(m_foregroundClipLayer);
922             // Use the scrollable content layer as the parent of the children so
923             // that they move with the content.
924             layer = m_foregroundLayer;
925             layer->removeChildren();
926         }
927         for (unsigned int i = 0; i < m_children.size(); i++)
928             layer->addChild(m_children[i]->platformLayer());
929         m_needsSyncChildren = false;
930     }
931 }
932
933 void GraphicsLayerAndroid::syncMask()
934 {
935     if (m_needsSyncMask) {
936         if (m_maskLayer) {
937             LayerAndroid* mask = m_maskLayer->platformLayer();
938             m_contentLayer->setMaskLayer(mask);
939         } else
940             m_contentLayer->setMaskLayer(0);
941
942         m_contentLayer->setMasksToBounds(m_masksToBounds);
943         m_needsSyncMask = false;
944     }
945 }
946
947 void GraphicsLayerAndroid::syncCompositingState()
948 {
949     for (unsigned int i = 0; i < m_children.size(); i++)
950         m_children[i]->syncCompositingState();
951
952     updateScrollingLayers();
953     updateFixedPosition();
954     syncChildren();
955     syncMask();
956
957     if (!gPaused || WTF::currentTime() >= gPausedDelay)
958         repaint();
959 }
960
961 void GraphicsLayerAndroid::notifyClientAnimationStarted()
962 {
963     for (unsigned int i = 0; i < m_children.size(); i++)
964         static_cast<GraphicsLayerAndroid*>(m_children[i])->notifyClientAnimationStarted();
965
966     if (m_needsNotifyClient) {
967         if (client())
968             client()->notifyAnimationStarted(this, WTF::currentTime());
969         m_needsNotifyClient = false;
970     }
971 }
972
973 } // namespace WebCore
974
975 #endif // USE(ACCELERATED_COMPOSITING)