Home | History | Annotate | Download | only in layers
      1 #define LOG_TAG "LayerAndroid"
      2 #define LOG_NDEBUG 1
      3 
      4 #include "config.h"
      5 #include "LayerAndroid.h"
      6 
      7 #if USE(ACCELERATED_COMPOSITING)
      8 
      9 #include "AndroidLog.h"
     10 #include "AndroidAnimation.h"
     11 #include "ClassTracker.h"
     12 #include "DrawExtra.h"
     13 #include "DumpLayer.h"
     14 #include "FixedPositioning.h"
     15 #include "GLUtils.h"
     16 #include "GLWebViewState.h"
     17 #include "ImagesManager.h"
     18 #include "InspectorCanvas.h"
     19 #include "LayerContent.h"
     20 #include "MediaLayer.h"
     21 #include "ParseCanvas.h"
     22 #include "PictureLayerContent.h"
     23 #include "PrerenderedInval.h"
     24 #include "SkBitmapRef.h"
     25 #include "SkDevice.h"
     26 #include "SkDrawFilter.h"
     27 #include "SkPaint.h"
     28 #include "SkPicture.h"
     29 #include "SkTypeface.h"
     30 #include "Surface.h"
     31 #include "TilesManager.h"
     32 
     33 #include <wtf/CurrentTime.h>
     34 #include <wtf/text/CString.h>
     35 #include <math.h>
     36 
     37 #define DISABLE_LAYER_MERGE
     38 #undef DISABLE_LAYER_MERGE
     39 
     40 #define LAYER_MERGING_DEBUG
     41 #undef LAYER_MERGING_DEBUG
     42 
     43 namespace WebCore {
     44 
     45 static int gUniqueId;
     46 
     47 class OpacityDrawFilter : public SkDrawFilter {
     48 public:
     49     OpacityDrawFilter(int opacity) : m_opacity(opacity) { }
     50     virtual void filter(SkPaint* paint, Type)
     51     {
     52         paint->setAlpha(m_opacity);
     53     }
     54 private:
     55     int m_opacity;
     56 };
     57 
     58 ///////////////////////////////////////////////////////////////////////////////
     59 
     60 LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
     61     m_uniqueId(++gUniqueId),
     62     m_haveClip(false),
     63     m_backfaceVisibility(true),
     64     m_visible(true),
     65     m_backgroundColor(0),
     66     m_preserves3D(false),
     67     m_anchorPointZ(0),
     68     m_isPositionAbsolute(false),
     69     m_fixedPosition(0),
     70     m_zValue(0),
     71     m_content(0),
     72     m_imageCRC(0),
     73     m_scale(1),
     74     m_lastComputeTextureSize(0),
     75     m_owningLayer(owner),
     76     m_type(LayerAndroid::WebCoreLayer),
     77     m_intrinsicallyComposited(true),
     78     m_surface(0),
     79     m_replicatedLayer(0),
     80     m_originalLayer(0),
     81     m_maskLayer(0)
     82 {
     83     m_dirtyRegion.setEmpty();
     84 #ifdef DEBUG_COUNT
     85     ClassTracker::instance()->increment("LayerAndroid");
     86     ClassTracker::instance()->add(this);
     87 #endif
     88 }
     89 
     90 LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
     91     m_uniqueId(layer.m_uniqueId),
     92     m_haveClip(layer.m_haveClip),
     93     m_backfaceVisibility(layer.m_backfaceVisibility),
     94     m_visible(layer.m_visible),
     95     m_backgroundColor(layer.m_backgroundColor),
     96     m_preserves3D(layer.m_preserves3D),
     97     m_anchorPointZ(layer.m_anchorPointZ),
     98     m_isPositionAbsolute(layer.m_isPositionAbsolute),
     99     m_fixedPosition(0),
    100     m_zValue(layer.m_zValue),
    101     m_content(layer.m_content),
    102     m_imageCRC(layer.m_imageCRC),
    103     m_scale(layer.m_scale),
    104     m_lastComputeTextureSize(0),
    105     m_owningLayer(layer.m_owningLayer),
    106     m_type(LayerAndroid::UILayer),
    107     m_intrinsicallyComposited(layer.m_intrinsicallyComposited),
    108     m_surface(0),
    109     m_replicatedLayer(0),
    110     m_originalLayer(0),
    111     m_maskLayer(0)
    112 {
    113     if (m_imageCRC)
    114         ImagesManager::instance()->retainImage(m_imageCRC);
    115 
    116     SkSafeRef(m_content);
    117 
    118     if (layer.m_fixedPosition) {
    119         m_fixedPosition = layer.m_fixedPosition->copy(this);
    120         Layer::setShouldInheritFromRootTransform(true);
    121     }
    122 
    123     m_transform = layer.m_transform;
    124     m_drawTransform = layer.m_drawTransform;
    125     m_drawTransformUnfudged = layer.m_drawTransformUnfudged;
    126     m_childrenTransform = layer.m_childrenTransform;
    127     m_dirtyRegion = layer.m_dirtyRegion;
    128 
    129     m_replicatedLayerPosition = layer.m_replicatedLayerPosition;
    130 
    131 #ifdef ABSOLUTE_POSITION
    132     // If we have absolute elements, we may need to reorder them if they
    133     // are followed by another layer that is not also absolutely positioned.
    134     // (as absolutely positioned elements are out of the normal flow)
    135     bool hasAbsoluteChildren = false;
    136     bool hasOnlyAbsoluteFollowers = true;
    137 
    138     for (int i = 0; i < layer.countChildren(); i++) {
    139         if (layer.getChild(i)->isPositionAbsolute()) {
    140             hasAbsoluteChildren = true;
    141             continue;
    142         }
    143         if (hasAbsoluteChildren
    144             && !layer.getChild(i)->isPositionAbsolute()) {
    145             hasOnlyAbsoluteFollowers = false;
    146             break;
    147         }
    148     }
    149 
    150     if (hasAbsoluteChildren && !hasOnlyAbsoluteFollowers) {
    151         Vector<LayerAndroid*> normalLayers;
    152         Vector<LayerAndroid*> absoluteLayers;
    153         for (int i = 0; i < layer.countChildren(); i++) {
    154             LayerAndroid* child = layer.getChild(i);
    155             if (child->isPositionAbsolute()
    156                 || child->isPositionFixed())
    157                 absoluteLayers.append(child);
    158             else
    159                 normalLayers.append(child);
    160         }
    161         for (unsigned int i = 0; i < normalLayers.size(); i++)
    162             addChild(normalLayers[i]->copy())->unref();
    163         for (unsigned int i = 0; i < absoluteLayers.size(); i++)
    164             addChild(absoluteLayers[i]->copy())->unref();
    165     } else {
    166         for (int i = 0; i < layer.countChildren(); i++)
    167             addChild(layer.getChild(i)->copy())->unref();
    168     }
    169 #else
    170     for (int i = 0; i < layer.countChildren(); i++)
    171         addChild(layer.getChild(i)->copy())->unref();
    172 #endif
    173 
    174     KeyframesMap::const_iterator end = layer.m_animations.end();
    175     for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) {
    176         m_animations.add(it->first, it->second);
    177     }
    178 
    179     if (layer.m_replicatedLayer) {
    180         // The replicated layer is always the first child
    181         m_replicatedLayer = getChild(0);
    182         m_replicatedLayer->setOriginalLayer(this);
    183     }
    184 
    185     if (layer.m_maskLayer)
    186         m_maskLayer = layer.m_maskLayer->copy();
    187 
    188 #ifdef DEBUG_COUNT
    189     ClassTracker::instance()->increment("LayerAndroid - recopy (UI)");
    190     ClassTracker::instance()->add(this);
    191 #endif
    192 }
    193 
    194 LayerAndroid::~LayerAndroid()
    195 {
    196     if (m_imageCRC)
    197         ImagesManager::instance()->releaseImage(m_imageCRC);
    198     if (m_fixedPosition)
    199         delete m_fixedPosition;
    200 
    201     SkSafeUnref(m_maskLayer);
    202     SkSafeUnref(m_content);
    203     // Don't unref m_surface, owned by BaseLayerAndroid
    204     m_animations.clear();
    205 #ifdef DEBUG_COUNT
    206     ClassTracker::instance()->remove(this);
    207     if (m_type == LayerAndroid::WebCoreLayer)
    208         ClassTracker::instance()->decrement("LayerAndroid");
    209     else if (m_type == LayerAndroid::UILayer)
    210         ClassTracker::instance()->decrement("LayerAndroid - recopy (UI)");
    211 #endif
    212 }
    213 
    214 bool LayerAndroid::hasText()
    215 {
    216     return m_content && m_content->hasText();
    217 }
    218 
    219 static int gDebugNbAnims = 0;
    220 
    221 bool LayerAndroid::evaluateAnimations()
    222 {
    223     double time = WTF::currentTime();
    224     gDebugNbAnims = 0;
    225     return evaluateAnimations(time);
    226 }
    227 
    228 bool LayerAndroid::hasAnimations() const
    229 {
    230     for (int i = 0; i < countChildren(); i++) {
    231         if (getChild(i)->hasAnimations())
    232             return true;
    233     }
    234     return !!m_animations.size();
    235 }
    236 
    237 bool LayerAndroid::evaluateAnimations(double time)
    238 {
    239     bool hasRunningAnimations = false;
    240     for (int i = 0; i < countChildren(); i++) {
    241         if (getChild(i)->evaluateAnimations(time))
    242             hasRunningAnimations = true;
    243     }
    244 
    245     m_hasRunningAnimations = false;
    246     int nbAnims = 0;
    247     KeyframesMap::const_iterator end = m_animations.end();
    248     for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
    249         gDebugNbAnims++;
    250         nbAnims++;
    251         LayerAndroid* currentLayer = const_cast<LayerAndroid*>(this);
    252         m_hasRunningAnimations |= (it->second)->evaluate(currentLayer, time);
    253     }
    254 
    255     return hasRunningAnimations || m_hasRunningAnimations;
    256 }
    257 
    258 void LayerAndroid::initAnimations() {
    259     // tell auto-initializing animations to start now
    260     for (int i = 0; i < countChildren(); i++)
    261         getChild(i)->initAnimations();
    262 
    263     KeyframesMap::const_iterator localBegin = m_animations.begin();
    264     KeyframesMap::const_iterator localEnd = m_animations.end();
    265     for (KeyframesMap::const_iterator localIt = localBegin; localIt != localEnd; ++localIt)
    266         (localIt->second)->suggestBeginTime(WTF::currentTime());
    267 }
    268 
    269 void LayerAndroid::addDirtyArea()
    270 {
    271     if (m_drawTransform.hasPerspective()) {
    272         state()->doFrameworkFullInval();
    273         return;
    274     }
    275 
    276     // TODO: rewrite this to handle partial invalidate, and to handle base
    277     // layer's large clip correctly
    278 
    279     IntSize layerSize(getSize().width(), getSize().height());
    280 
    281     FloatRect area =
    282         TilesManager::instance()->shader()->rectInViewCoord(m_drawTransform, layerSize);
    283     FloatRect clippingRect =
    284         TilesManager::instance()->shader()->rectInInvViewCoord(m_clippingRect);
    285     FloatRect clip =
    286         TilesManager::instance()->shader()->convertInvViewCoordToViewCoord(clippingRect);
    287 
    288     area.intersect(clip);
    289     IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());
    290 
    291     state()->addDirtyArea(dirtyArea);
    292 
    293     for (int i = 0; i < countChildren(); i++)
    294         getChild(i)->addDirtyArea();
    295 }
    296 
    297 void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim)
    298 {
    299     RefPtr<AndroidAnimation> anim = prpAnim;
    300     pair<String, int> key(anim->name(), anim->type());
    301     removeAnimationsForProperty(anim->type());
    302     m_animations.add(key, anim);
    303 }
    304 
    305 void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
    306 {
    307     KeyframesMap::const_iterator end = m_animations.end();
    308     Vector<pair<String, int> > toDelete;
    309     for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
    310         if ((it->second)->type() == property)
    311             toDelete.append(it->first);
    312     }
    313 
    314     for (unsigned int i = 0; i < toDelete.size(); i++)
    315         m_animations.remove(toDelete[i]);
    316 }
    317 
    318 void LayerAndroid::removeAnimationsForKeyframes(const String& name)
    319 {
    320     KeyframesMap::const_iterator end = m_animations.end();
    321     Vector<pair<String, int> > toDelete;
    322     for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
    323         if ((it->second)->name() == name)
    324             toDelete.append(it->first);
    325     }
    326 
    327     for (unsigned int i = 0; i < toDelete.size(); i++)
    328         m_animations.remove(toDelete[i]);
    329 }
    330 
    331 // We only use the bounding rect of the layer as mask...
    332 // FIXME: use a real mask?
    333 void LayerAndroid::setMaskLayer(LayerAndroid* layer)
    334 {
    335     SkSafeRef(layer);
    336     SkSafeUnref(m_maskLayer);
    337     m_maskLayer = layer;
    338     if (layer)
    339         m_haveClip = true;
    340 }
    341 
    342 void LayerAndroid::setBackgroundColor(SkColor color)
    343 {
    344     m_backgroundColor = color;
    345 }
    346 
    347 FloatPoint LayerAndroid::translation() const
    348 {
    349     TransformationMatrix::DecomposedType tDecomp;
    350     m_transform.decompose(tDecomp);
    351     FloatPoint p(tDecomp.translateX, tDecomp.translateY);
    352     return p;
    353 }
    354 
    355 IFrameLayerAndroid* LayerAndroid::updatePosition(SkRect viewport,
    356                                                  IFrameLayerAndroid* parentIframeLayer)
    357 {
    358     // subclasses can implement this virtual function to modify their position
    359     if (m_fixedPosition)
    360         return m_fixedPosition->updatePosition(viewport, parentIframeLayer);
    361     return parentIframeLayer;
    362 }
    363 
    364 void LayerAndroid::updateLayerPositions(SkRect viewport, IFrameLayerAndroid* parentIframeLayer)
    365 {
    366     ALOGV("updating fixed positions, using viewport %fx%f - %fx%f",
    367           viewport.fLeft, viewport.fTop,
    368           viewport.width(), viewport.height());
    369 
    370     IFrameLayerAndroid* iframeLayer = updatePosition(viewport, parentIframeLayer);
    371 
    372     int count = this->countChildren();
    373     for (int i = 0; i < count; i++)
    374         this->getChild(i)->updateLayerPositions(viewport, iframeLayer);
    375 }
    376 
    377 void LayerAndroid::updatePositions()
    378 {
    379     // apply the viewport to us
    380     if (!isPositionFixed()) {
    381         // turn our fields into a matrix.
    382         //
    383         // FIXME: this should happen in the caller, and we should remove these
    384         // fields from our subclass
    385         SkMatrix matrix;
    386         GLUtils::toSkMatrix(matrix, m_transform);
    387         this->setMatrix(matrix);
    388     }
    389 
    390     // now apply it to our children
    391     int count = this->countChildren();
    392     for (int i = 0; i < count; i++)
    393         this->getChild(i)->updatePositions();
    394 }
    395 
    396 void LayerAndroid::updateLocalTransformAndClip(const TransformationMatrix& parentMatrix,
    397                                                const FloatRect& clipping)
    398 {
    399     FloatPoint position(getPosition().x() + m_replicatedLayerPosition.x() - getScrollOffset().x(),
    400                         getPosition().y() + m_replicatedLayerPosition.y() - getScrollOffset().y());
    401     float originX = getAnchorPoint().x() * getWidth();
    402     float originY = getAnchorPoint().y() * getHeight();
    403 
    404     TransformationMatrix localMatrix;
    405 
    406     if (isPositionFixed())
    407         m_drawTransform.makeIdentity();
    408     else
    409         m_drawTransform = parentMatrix;
    410     m_drawTransform.translate3d(originX + position.x(),
    411                                 originY + position.y(),
    412                                 anchorPointZ());
    413     m_drawTransform.multiply(m_transform);
    414     m_drawTransform.translate3d(-originX,
    415                                 -originY,
    416                                 -anchorPointZ());
    417 
    418     m_drawTransformUnfudged = m_drawTransform;
    419     if (m_drawTransform.isIdentityOrTranslation()
    420         && surface() && surface()->allowTransformFudging()) {
    421         // adjust the translation coordinates of the draw transform matrix so
    422         // that layers (defined in content coordinates) will align to display/view pixels
    423 
    424         // the surface may not allow fudging if it uses the draw transform at paint time
    425         float desiredContentX = round(m_drawTransform.m41() * m_scale) / m_scale;
    426         float desiredContentY = round(m_drawTransform.m42() * m_scale) / m_scale;
    427         ALOGV("fudging translation from %f, %f to %f, %f",
    428               m_drawTransform.m41(), m_drawTransform.m42(),
    429               desiredContentX, desiredContentY);
    430         m_drawTransform.setM41(desiredContentX);
    431         m_drawTransform.setM42(desiredContentY);
    432     }
    433 
    434     m_zValue = TilesManager::instance()->shader()->zValue(m_drawTransform,
    435                                                           getSize().width(),
    436                                                           getSize().height());
    437 
    438     if (m_haveClip) {
    439         // The clipping rect calculation and intersetion will be done in content
    440         // coordinates.
    441         FloatRect rect(0, 0, getWidth(), getHeight());
    442         FloatRect clip = m_drawTransform.mapRect(rect);
    443         clip.intersect(clipping);
    444         setDrawClip(clip);
    445     } else {
    446         setDrawClip(clipping);
    447     }
    448     ALOGV("%s - %d %f %f %f %f",
    449           subclassType() == BaseLayer ? "BASE" : "nonbase",
    450           m_haveClip, m_clippingRect.x(), m_clippingRect.y(),
    451           m_clippingRect.width(), m_clippingRect.height());
    452 
    453     setVisible(m_backfaceVisibility || m_drawTransform.inverse().m33() >= 0);
    454 }
    455 
    456 void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
    457                                              const FloatRect& clipping, float opacity,
    458                                              float scale, bool forceCalculation,
    459                                              bool disableFixedElemUpdate)
    460 {
    461     m_scale = scale;
    462 
    463     opacity *= getOpacity();
    464     setDrawOpacity(opacity);
    465 
    466     // constantly recalculate the draw transform of layers that may require it (and their children)
    467     forceCalculation |= hasDynamicTransform();
    468 
    469     forceCalculation &= !(disableFixedElemUpdate && isPositionFixed());
    470     if (forceCalculation)
    471         updateLocalTransformAndClip(parentMatrix, clipping);
    472 
    473     if (!countChildren() || !m_visible)
    474         return;
    475 
    476     TransformationMatrix localMatrix = m_drawTransformUnfudged;
    477 
    478     // Flatten to 2D if the layer doesn't preserve 3D.
    479     if (!preserves3D()) {
    480         localMatrix.setM13(0);
    481         localMatrix.setM23(0);
    482         localMatrix.setM31(0);
    483         localMatrix.setM32(0);
    484         localMatrix.setM33(1);
    485         localMatrix.setM34(0);
    486         localMatrix.setM43(0);
    487     }
    488 
    489     // now apply it to our children
    490 
    491     TransformationMatrix childMatrix;
    492     childMatrix = localMatrix;
    493     childMatrix.translate3d(getScrollOffset().x(), getScrollOffset().y(), 0);
    494     if (!m_childrenTransform.isIdentity()) {
    495         childMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f);
    496         childMatrix.multiply(m_childrenTransform);
    497         childMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
    498     }
    499     for (int i = 0; i < countChildren(); i++)
    500         this->getChild(i)->updateGLPositionsAndScale(childMatrix, drawClip(),
    501                                                      opacity, scale, forceCalculation,
    502                                                      disableFixedElemUpdate);
    503 }
    504 
    505 bool LayerAndroid::visible() {
    506     // TODO: avoid climbing tree each access
    507     LayerAndroid* current = this;
    508     while (current->getParent()) {
    509         if (!current->m_visible)
    510             return false;
    511         current = static_cast<LayerAndroid*>(current->getParent());
    512     }
    513     return true;
    514 }
    515 
    516 void LayerAndroid::setContentsImage(SkBitmapRef* img)
    517 {
    518     ImageTexture* image = ImagesManager::instance()->setImage(img);
    519     ImagesManager::instance()->releaseImage(m_imageCRC);
    520     m_imageCRC = image ? image->imageCRC() : 0;
    521 }
    522 
    523 void LayerAndroid::setContent(LayerContent* content)
    524 {
    525     SkSafeRef(content);
    526     SkSafeUnref(m_content);
    527     m_content = content;
    528 }
    529 
    530 bool LayerAndroid::canUpdateWithBlit()
    531 {
    532     if (!m_content || !m_scale)
    533         return false;
    534     IntRect clip = clippedRect();
    535     IntRect dirty = m_dirtyRegion.getBounds();
    536     dirty.intersect(clip);
    537     PrerenderedInval* prerendered = m_content->prerenderForRect(dirty);
    538     if (!prerendered)
    539         return false;
    540     // Check that the scales are "close enough" to produce the same rects
    541     FloatRect screenArea = prerendered->screenArea;
    542     screenArea.scale(1 / m_scale);
    543     IntRect enclosingDocArea = enclosingIntRect(screenArea);
    544     return enclosingDocArea == prerendered->area;
    545 }
    546 
    547 bool LayerAndroid::needsTexture()
    548 {
    549     return (m_content && !m_content->isEmpty())
    550             || (m_originalLayer && m_originalLayer->needsTexture());
    551 }
    552 
    553 IntRect LayerAndroid::clippedRect() const
    554 {
    555     IntRect r(0, 0, getWidth(), getHeight());
    556     IntRect tr = m_drawTransform.mapRect(r);
    557     IntRect cr = TilesManager::instance()->shader()->clippedRectWithVisibleContentRect(tr);
    558     IntRect rect = m_drawTransform.inverse().mapRect(cr);
    559     return rect;
    560 }
    561 
    562 int LayerAndroid::nbLayers()
    563 {
    564     int nb = 0;
    565     int count = this->countChildren();
    566     for (int i = 0; i < count; i++)
    567         nb += this->getChild(i)->nbLayers();
    568     return nb+1;
    569 }
    570 
    571 int LayerAndroid::nbTexturedLayers()
    572 {
    573     int nb = 0;
    574     int count = this->countChildren();
    575     for (int i = 0; i < count; i++)
    576         nb += this->getChild(i)->nbTexturedLayers();
    577     if (needsTexture())
    578         nb++;
    579     return nb;
    580 }
    581 
    582 void LayerAndroid::showLayer(int indent)
    583 {
    584     char spaces[256];
    585     memset(spaces, 0, 256);
    586     for (int i = 0; i < indent; i++)
    587         spaces[i] = ' ';
    588 
    589     if (!indent) {
    590         ALOGD("\n\n--- LAYERS TREE ---");
    591         IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
    592         ALOGD("contentViewport(%d, %d, %d, %d)",
    593               contentViewport.x(), contentViewport.y(),
    594               contentViewport.width(), contentViewport.height());
    595     }
    596 
    597     IntRect r(0, 0, getWidth(), getHeight());
    598     IntRect tr = m_drawTransform.mapRect(r);
    599     IntRect visible = visibleContentArea();
    600     IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
    601                  m_clippingRect.width(), m_clippingRect.height());
    602     ALOGD("%s s:%x %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
    603           "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d",
    604           spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
    605           subclassType(), uniqueId(), this, m_owningLayer,
    606           needsTexture() ? "needsTexture" : "",
    607           m_imageCRC ? "hasImage" : "",
    608           tr.x(), tr.y(), tr.width(), tr.height(),
    609           visible.x(), visible.y(), visible.width(), visible.height(),
    610           clip.x(), clip.y(), clip.width(), clip.height(),
    611           contentIsScrollable() ? "SCROLLABLE" : "",
    612           isPositionFixed() ? "FIXED" : "",
    613           m_content,
    614           m_content ? m_content->width() : -1,
    615           m_content ? m_content->height() : -1,
    616           m_originalLayer, m_originalLayer ? m_originalLayer->uniqueId() : -1);
    617 
    618     int count = this->countChildren();
    619     for (int i = 0; i < count; i++)
    620         this->getChild(i)->showLayer(indent + 2);
    621 }
    622 
    623 void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree)
    624 {
    625     int count = this->countChildren();
    626     for (int i = 0; i < count; i++)
    627         this->getChild(i)->mergeInvalsInto(replacementTree);
    628 
    629     LayerAndroid* replacementLayer = replacementTree->findById(uniqueId());
    630     if (replacementLayer)
    631         replacementLayer->markAsDirty(m_dirtyRegion);
    632 }
    633 
    634 static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
    635 {
    636     return a->zValue() > b->zValue();
    637 }
    638 
    639 bool LayerAndroid::canJoinSurface(Surface* surface)
    640 {
    641 #ifdef DISABLE_LAYER_MERGE
    642     return false;
    643 #else
    644     // returns true if the layer can be merged onto the surface (group of layers)
    645     if (!surface)
    646         return false;
    647 
    648     LayerAndroid* lastLayer = surface->getFirstLayer();
    649 
    650     // isolate intrinsically composited layers
    651     if (needsIsolatedSurface() || lastLayer->needsIsolatedSurface())
    652         return false;
    653 
    654     // TODO: investigate potential for combining transformed layers
    655     if (!m_drawTransform.isIdentityOrTranslation()
    656         || !lastLayer->m_drawTransform.isIdentityOrTranslation())
    657         return false;
    658 
    659     // TODO: compare other layer properties - fixed? overscroll? transformed?
    660     return true;
    661 #endif
    662 }
    663 
    664 void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
    665 {
    666     // recurse through layers in draw order, and merge layers when able
    667 
    668     bool needNewSurface = !mergeState->currentSurface
    669         || mergeState->nonMergeNestedLevel > 0
    670         || !canJoinSurface(mergeState->currentSurface);
    671 
    672     if (needNewSurface) {
    673         mergeState->currentSurface = new Surface();
    674         mergeState->surfaceList->append(mergeState->currentSurface);
    675     }
    676 
    677 #ifdef LAYER_MERGING_DEBUG
    678     ALOGD("%*slayer %p(%d) rl %p %s surface %p lvl: %d, fixed %d, anim %d, intCom %d, haveClip %d scroll %d hasText (layer: %d surface: %d) hasContent %d size %.2f x %.2f",
    679           4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
    680           needNewSurface ? "NEW" : "joins", mergeState->currentSurface,
    681           mergeState->nonMergeNestedLevel,
    682           isPositionFixed(), m_animations.size() != 0,
    683           m_intrinsicallyComposited,
    684           m_haveClip,
    685           contentIsScrollable(), m_content ? m_content->hasText() : -1,
    686           mergeState->currentSurface ? mergeState->currentSurface->hasText() : -1,
    687           needsTexture(), getWidth(), getHeight());
    688 #endif
    689 
    690     mergeState->currentSurface->addLayer(this, m_drawTransform);
    691     m_surface = mergeState->currentSurface;
    692 
    693     if (hasDynamicTransform()) {
    694         // disable layer merging within the children of these layer types
    695         mergeState->nonMergeNestedLevel++;
    696     }
    697 
    698     // pass the surface through children in drawing order, so that they may
    699     // attach themselves (and paint on it) if possible, or ignore it and create
    700     // a new one if not
    701     int count = this->countChildren();
    702     if (count > 0) {
    703         mergeState->depth++;
    704         Vector <LayerAndroid*> sublayers;
    705         for (int i = 0; i < count; i++)
    706             sublayers.append(getChild(i));
    707 
    708         // sort for the transparency
    709         std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
    710         for (int i = 0; i < count; i++)
    711             sublayers[i]->assignSurfaces(mergeState);
    712         mergeState->depth--;
    713     }
    714 
    715     if (hasDynamicTransform()) {
    716         // re-enable joining
    717         mergeState->nonMergeNestedLevel--;
    718 
    719         // disallow layers painting after to join with this surface
    720         mergeState->currentSurface = 0;
    721     }
    722 
    723     if (needsIsolatedSurface())
    724         mergeState->currentSurface = 0;
    725 
    726 }
    727 
    728 // We call this in WebViewCore, when copying the tree of layers.
    729 // As we construct a new tree that will be passed on the UI,
    730 // we mark the webkit-side tree as having no more dirty region
    731 // (otherwise we would continuously have those dirty region UI-side)
    732 void LayerAndroid::clearDirtyRegion()
    733 {
    734     int count = this->countChildren();
    735     for (int i = 0; i < count; i++)
    736         this->getChild(i)->clearDirtyRegion();
    737 
    738     m_dirtyRegion.setEmpty();
    739 }
    740 
    741 int LayerAndroid::setHwAccelerated(bool hwAccelerated)
    742 {
    743     int flags = InvalidateNone;
    744     int count = this->countChildren();
    745     for (int i = 0; i < count; i++)
    746         flags |= this->getChild(i)->setHwAccelerated(hwAccelerated);
    747 
    748     return flags | onSetHwAccelerated(hwAccelerated);
    749 }
    750 
    751 FloatRect LayerAndroid::fullContentAreaMapped() const
    752 {
    753     FloatRect area(0,0, getWidth(), getHeight());
    754     FloatRect globalArea = m_drawTransform.mapRect(area);
    755     return globalArea;
    756 }
    757 
    758 IntRect LayerAndroid::fullContentArea() const
    759 {
    760     IntRect area(0,0, getWidth(), getHeight());
    761     return area;
    762 }
    763 
    764 IntRect LayerAndroid::visibleContentArea(bool force3dContentVisible) const
    765 {
    766     IntRect area = fullContentArea();
    767     if (subclassType() == LayerAndroid::FixedBackgroundImageLayer)
    768        return area;
    769 
    770     // If transform isn't limited to 2D space, return the entire content area.
    771     // Transforming from layers to content coordinates and back doesn't
    772     // preserve 3D.
    773     if (force3dContentVisible && GLUtils::has3dTransform(m_drawTransform))
    774             return area;
    775 
    776     // First, we get the transformed area of the layer,
    777     // in content coordinates
    778     IntRect rect = m_drawTransform.mapRect(area);
    779 
    780     // Then we apply the clipping
    781     IntRect clip(m_clippingRect);
    782     rect.intersect(clip);
    783 
    784     // Now clip with the viewport in content coordinate
    785     IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
    786     rect.intersect(contentViewport);
    787 
    788     // Finally, let's return the visible area, in layers coordinate
    789     return m_drawTransform.inverse().mapRect(rect);
    790 }
    791 
    792 bool LayerAndroid::drawCanvas(SkCanvas* canvas, bool drawChildren, PaintStyle style)
    793 {
    794     if (!m_visible)
    795         return false;
    796 
    797     bool askScreenUpdate = false;
    798 
    799     {
    800         SkAutoCanvasRestore acr(canvas, true);
    801         SkRect r;
    802         r.set(m_clippingRect.x(), m_clippingRect.y(),
    803               m_clippingRect.x() + m_clippingRect.width(),
    804               m_clippingRect.y() + m_clippingRect.height());
    805         canvas->clipRect(r);
    806         SkMatrix matrix;
    807         GLUtils::toSkMatrix(matrix, m_drawTransform);
    808         SkMatrix canvasMatrix = canvas->getTotalMatrix();
    809         matrix.postConcat(canvasMatrix);
    810         canvas->setMatrix(matrix);
    811         onDraw(canvas, m_drawOpacity, 0, style);
    812     }
    813 
    814     if (!drawChildren)
    815         return false;
    816 
    817     // When the layer is dirty, the UI thread should be notified to redraw.
    818     askScreenUpdate |= drawChildrenCanvas(canvas, style);
    819     return askScreenUpdate;
    820 }
    821 
    822 bool LayerAndroid::drawGL(bool layerTilesDisabled)
    823 {
    824     if (!layerTilesDisabled && m_imageCRC) {
    825         ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
    826         if (imageTexture)
    827             imageTexture->drawGL(this, getOpacity());
    828         ImagesManager::instance()->releaseImage(m_imageCRC);
    829     }
    830 
    831     state()->glExtras()->drawGL(this);
    832     bool askScreenUpdate = false;
    833 
    834     if (m_hasRunningAnimations)
    835         askScreenUpdate = true;
    836 
    837     return askScreenUpdate;
    838 }
    839 
    840 bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style)
    841 {
    842     bool askScreenUpdate = false;
    843     int count = this->countChildren();
    844     if (count > 0) {
    845         Vector <LayerAndroid*> sublayers;
    846         for (int i = 0; i < count; i++)
    847             sublayers.append(this->getChild(i));
    848 
    849         // now we sort for the transparency
    850         std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
    851         for (int i = 0; i < count; i++) {
    852             LayerAndroid* layer = sublayers[i];
    853             askScreenUpdate |= layer->drawCanvas(canvas, true, style);
    854         }
    855     }
    856 
    857     return askScreenUpdate;
    858 }
    859 
    860 void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style)
    861 {
    862     if (m_maskLayer && m_maskLayer->m_content) {
    863         // TODO: we should use a shader instead of doing
    864         // the masking in software
    865 
    866         if (m_originalLayer)
    867             m_originalLayer->m_content->draw(canvas);
    868         else if (m_content)
    869             m_content->draw(canvas);
    870 
    871         SkPaint maskPaint;
    872         maskPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
    873         int count = canvas->saveLayer(0, &maskPaint, SkCanvas::kHasAlphaLayer_SaveFlag);
    874         m_maskLayer->m_content->draw(canvas);
    875         canvas->restoreToCount(count);
    876 
    877     } else if (m_content)
    878         m_content->draw(canvas);
    879 
    880     if (TilesManager::instance()->getShowVisualIndicator()) {
    881         float w = getSize().width();
    882         float h = getSize().height();
    883         SkPaint paint;
    884 
    885         if (style == MergedLayers)
    886             paint.setARGB(255, 255, 255, 0);
    887         else if (style == UnmergedLayers)
    888             paint.setARGB(255, 255, 0, 0);
    889         else if (style == FlattenedLayers)
    890             paint.setARGB(255, 255, 0, 255);
    891 
    892         canvas->drawLine(0, 0, w, h, paint);
    893         canvas->drawLine(0, h, w, 0, paint);
    894 
    895         canvas->drawLine(0, 0, 0, h-1, paint);
    896         canvas->drawLine(0, h-1, w-1, h-1, paint);
    897         canvas->drawLine(w-1, h-1, w-1, 0, paint);
    898         canvas->drawLine(w-1, 0, 0, 0, paint);
    899 
    900         static SkTypeface* s_typeface = 0;
    901         if (!s_typeface)
    902             s_typeface = SkTypeface::CreateFromName("", SkTypeface::kBold);
    903         paint.setARGB(255, 0, 0, 255);
    904         paint.setTextSize(17);
    905         char str[256];
    906         snprintf(str, 256, "%d", uniqueId());
    907         paint.setTypeface(s_typeface);
    908         canvas->drawText(str, strlen(str), 2, h - 2, paint);
    909     }
    910 
    911     if (m_fixedPosition)
    912         return m_fixedPosition->contentDraw(canvas, style);
    913 }
    914 
    915 void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity,
    916                           android::DrawExtra* extra, PaintStyle style)
    917 {
    918     if (m_haveClip) {
    919         SkRect r;
    920         r.set(0, 0, getSize().width(), getSize().height());
    921         canvas->clipRect(r);
    922         return;
    923     }
    924 
    925     // only continue drawing if layer is drawable
    926     if (!m_content && !m_imageCRC)
    927         return;
    928 
    929     // we just have this save/restore for opacity...
    930     SkAutoCanvasRestore restore(canvas, true);
    931 
    932     int canvasOpacity = SkScalarRound(opacity * 255);
    933     if (canvasOpacity < 255)
    934         canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity));
    935 
    936     if (m_imageCRC) {
    937         ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
    938         m_dirtyRegion.setEmpty();
    939         if (imageTexture) {
    940             SkRect dest;
    941             dest.set(0, 0, getSize().width(), getSize().height());
    942             imageTexture->drawCanvas(canvas, dest);
    943         }
    944         ImagesManager::instance()->releaseImage(m_imageCRC);
    945     }
    946     contentDraw(canvas, style);
    947     if (extra)
    948         extra->draw(canvas, this);
    949 }
    950 
    951 void LayerAndroid::setFixedPosition(FixedPositioning* position) {
    952     if (m_fixedPosition && m_fixedPosition != position)
    953         delete m_fixedPosition;
    954     m_fixedPosition = position;
    955 }
    956 
    957 void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const
    958 {
    959     writeHexVal(file, indentLevel + 1, "layer", (int)this);
    960     writeIntVal(file, indentLevel + 1, "layerId", m_uniqueId);
    961     writeIntVal(file, indentLevel + 1, "haveClip", m_haveClip);
    962     writeIntVal(file, indentLevel + 1, "isFixed", isPositionFixed());
    963 
    964     writeFloatVal(file, indentLevel + 1, "opacity", getOpacity());
    965     writeSize(file, indentLevel + 1, "size", getSize());
    966     writePoint(file, indentLevel + 1, "position", getPosition());
    967     writePoint(file, indentLevel + 1, "anchor", getAnchorPoint());
    968 
    969     writeMatrix(file, indentLevel + 1, "drawMatrix", m_drawTransform);
    970     writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform);
    971     writeRect(file, indentLevel + 1, "clippingRect", SkRect(m_clippingRect));
    972 
    973     if (m_content) {
    974         writeIntVal(file, indentLevel + 1, "m_content.width", m_content->width());
    975         writeIntVal(file, indentLevel + 1, "m_content.height", m_content->height());
    976     }
    977 
    978     if (m_fixedPosition)
    979         return m_fixedPosition->dumpLayer(file, indentLevel);
    980 }
    981 
    982 void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
    983 {
    984     writeln(file, indentLevel, "{");
    985 
    986     dumpLayer(file, indentLevel);
    987 
    988     if (countChildren()) {
    989         writeln(file, indentLevel + 1, "children = [");
    990         for (int i = 0; i < countChildren(); i++) {
    991             if (i > 0)
    992                 writeln(file, indentLevel + 1, ", ");
    993             getChild(i)->dumpLayers(file, indentLevel + 1);
    994         }
    995         writeln(file, indentLevel + 1, "];");
    996     }
    997     writeln(file, indentLevel, "}");
    998 }
    999 
   1000 void LayerAndroid::dumpToLog() const
   1001 {
   1002     FILE* file = fopen("/data/data/com.android.browser/layertmp", "w");
   1003     dumpLayers(file, 0);
   1004     fclose(file);
   1005     file = fopen("/data/data/com.android.browser/layertmp", "r");
   1006     char buffer[512];
   1007     bzero(buffer, sizeof(buffer));
   1008     while (fgets(buffer, sizeof(buffer), file))
   1009         SkDebugf("%s", buffer);
   1010     fclose(file);
   1011 }
   1012 
   1013 LayerAndroid* LayerAndroid::findById(int match)
   1014 {
   1015     if (m_uniqueId == match)
   1016         return this;
   1017     for (int i = 0; i < countChildren(); i++) {
   1018         LayerAndroid* result = getChild(i)->findById(match);
   1019         if (result)
   1020             return result;
   1021     }
   1022     return 0;
   1023 }
   1024 
   1025 } // namespace WebCore
   1026 
   1027 #endif // USE(ACCELERATED_COMPOSITING)
   1028