OSDN Git Service

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