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