#define LOG_TAG "LayerAndroid"
#define LOG_NDEBUG 1

#include "config.h"
#include "LayerAndroid.h"

#if USE(ACCELERATED_COMPOSITING)

#include "AndroidLog.h"
#include "AndroidAnimation.h"
#include "ClassTracker.h"
#include "DrawExtra.h"
#include "DumpLayer.h"
#include "FixedPositioning.h"
#include "GLUtils.h"
#include "GLWebViewState.h"
#include "ImagesManager.h"
#include "InspectorCanvas.h"
#include "LayerContent.h"
#include "MediaLayer.h"
#include "ParseCanvas.h"
#include "PictureLayerContent.h"
#include "PrerenderedInval.h"
#include "SkBitmapRef.h"
#include "SkDevice.h"
#include "SkDrawFilter.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkTypeface.h"
#include "Surface.h"
#include "TilesManager.h"

#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
#include <math.h>

#define DISABLE_LAYER_MERGE
#undef DISABLE_LAYER_MERGE

#define LAYER_MERGING_DEBUG
#undef LAYER_MERGING_DEBUG

namespace WebCore {

static int gUniqueId;

class OpacityDrawFilter : public SkDrawFilter {
public:
    OpacityDrawFilter(int opacity) : m_opacity(opacity) { }
    virtual bool filter(SkPaint* paint, Type)
    {
        paint->setAlpha(m_opacity);
        return true;
    }
private:
    int m_opacity;
};

///////////////////////////////////////////////////////////////////////////////

LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
    m_uniqueId(++gUniqueId),
    m_haveClip(false),
    m_backfaceVisibility(true),
    m_visible(true),
    m_backgroundColor(0),
    m_preserves3D(false),
    m_anchorPointZ(0),
    m_isPositionAbsolute(false),
    m_fixedPosition(0),
    m_zValue(0),
    m_content(0),
    m_imageCRC(0),
    m_scale(1),
    m_lastComputeTextureSize(0),
    m_owningLayer(owner),
    m_type(LayerAndroid::WebCoreLayer),
    m_intrinsicallyComposited(true),
    m_surface(0),
    m_replicatedLayer(0),
    m_originalLayer(0),
    m_maskLayer(0)
{
    m_dirtyRegion.setEmpty();
#ifdef DEBUG_COUNT
    ClassTracker::instance()->increment("LayerAndroid");
    ClassTracker::instance()->add(this);
#endif
}

LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
    m_uniqueId(layer.m_uniqueId),
    m_haveClip(layer.m_haveClip),
    m_backfaceVisibility(layer.m_backfaceVisibility),
    m_visible(layer.m_visible),
    m_backgroundColor(layer.m_backgroundColor),
    m_preserves3D(layer.m_preserves3D),
    m_anchorPointZ(layer.m_anchorPointZ),
    m_isPositionAbsolute(layer.m_isPositionAbsolute),
    m_fixedPosition(0),
    m_zValue(layer.m_zValue),
    m_content(layer.m_content),
    m_imageCRC(layer.m_imageCRC),
    m_scale(layer.m_scale),
    m_lastComputeTextureSize(0),
    m_owningLayer(layer.m_owningLayer),
    m_type(LayerAndroid::UILayer),
    m_intrinsicallyComposited(layer.m_intrinsicallyComposited),
    m_surface(0),
    m_replicatedLayer(0),
    m_originalLayer(0),
    m_maskLayer(0)
{
    if (m_imageCRC)
        ImagesManager::instance()->retainImage(m_imageCRC);

    SkSafeRef(m_content);

    if (layer.m_fixedPosition) {
        m_fixedPosition = layer.m_fixedPosition->copy(this);
        Layer::setShouldInheritFromRootTransform(true);
    }

    m_transform = layer.m_transform;
    m_drawTransform = layer.m_drawTransform;
    m_drawTransformUnfudged = layer.m_drawTransformUnfudged;
    m_childrenTransform = layer.m_childrenTransform;
    m_dirtyRegion = layer.m_dirtyRegion;

    m_replicatedLayerPosition = layer.m_replicatedLayerPosition;

#ifdef ABSOLUTE_POSITION
    // If we have absolute elements, we may need to reorder them if they
    // are followed by another layer that is not also absolutely positioned.
    // (as absolutely positioned elements are out of the normal flow)
    bool hasAbsoluteChildren = false;
    bool hasOnlyAbsoluteFollowers = true;

    for (int i = 0; i < layer.countChildren(); i++) {
        if (layer.getChild(i)->isPositionAbsolute()) {
            hasAbsoluteChildren = true;
            continue;
        }
        if (hasAbsoluteChildren
            && !layer.getChild(i)->isPositionAbsolute()) {
            hasOnlyAbsoluteFollowers = false;
            break;
        }
    }

    if (hasAbsoluteChildren && !hasOnlyAbsoluteFollowers) {
        Vector<LayerAndroid*> normalLayers;
        Vector<LayerAndroid*> absoluteLayers;
        for (int i = 0; i < layer.countChildren(); i++) {
            LayerAndroid* child = layer.getChild(i);
            if (child->isPositionAbsolute()
                || child->isPositionFixed())
                absoluteLayers.append(child);
            else
                normalLayers.append(child);
        }
        for (unsigned int i = 0; i < normalLayers.size(); i++)
            addChild(normalLayers[i]->copy())->unref();
        for (unsigned int i = 0; i < absoluteLayers.size(); i++)
            addChild(absoluteLayers[i]->copy())->unref();
    } else {
        for (int i = 0; i < layer.countChildren(); i++)
            addChild(layer.getChild(i)->copy())->unref();
    }
#else
    for (int i = 0; i < layer.countChildren(); i++)
        addChild(layer.getChild(i)->copy())->unref();
#endif

    KeyframesMap::const_iterator end = layer.m_animations.end();
    for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) {
        // Deep copy the key's string, to avoid cross-thread refptr use
        pair<String, int> newKey(it->first.first.threadsafeCopy(), it->first.second);
        m_animations.add(newKey, it->second);
    }

    if (layer.m_replicatedLayer) {
        // The replicated layer is always the first child
        m_replicatedLayer = getChild(0);
        m_replicatedLayer->setOriginalLayer(this);
    }

    if (layer.m_maskLayer)
        m_maskLayer = layer.m_maskLayer->copy();

#ifdef DEBUG_COUNT
    ClassTracker::instance()->increment("LayerAndroid - recopy (UI)");
    ClassTracker::instance()->add(this);
#endif
}

LayerAndroid::~LayerAndroid()
{
    if (m_imageCRC)
        ImagesManager::instance()->releaseImage(m_imageCRC);
    if (m_fixedPosition)
        delete m_fixedPosition;

    SkSafeUnref(m_maskLayer);
    SkSafeUnref(m_content);
    // Don't unref m_surface, owned by BaseLayerAndroid
    m_animations.clear();
#ifdef DEBUG_COUNT
    ClassTracker::instance()->remove(this);
    if (m_type == LayerAndroid::WebCoreLayer)
        ClassTracker::instance()->decrement("LayerAndroid");
    else if (m_type == LayerAndroid::UILayer)
        ClassTracker::instance()->decrement("LayerAndroid - recopy (UI)");
#endif
}

float LayerAndroid::maxZoomScale() const
{
    return m_content ? m_content->maxZoomScale() : 1.0f;
}

static int gDebugNbAnims = 0;

bool LayerAndroid::evaluateAnimations()
{
    double time = WTF::currentTime();
    gDebugNbAnims = 0;
    return evaluateAnimations(time);
}

bool LayerAndroid::hasAnimations() const
{
    for (int i = 0; i < countChildren(); i++) {
        if (getChild(i)->hasAnimations())
            return true;
    }
    return !!m_animations.size();
}

bool LayerAndroid::evaluateAnimations(double time)
{
    bool hasRunningAnimations = false;
    for (int i = 0; i < countChildren(); i++) {
        if (getChild(i)->evaluateAnimations(time))
            hasRunningAnimations = true;
    }

    m_hasRunningAnimations = false;
    int nbAnims = 0;
    KeyframesMap::const_iterator end = m_animations.end();
    for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
        gDebugNbAnims++;
        nbAnims++;
        LayerAndroid* currentLayer = const_cast<LayerAndroid*>(this);
        m_hasRunningAnimations |= (it->second)->evaluate(currentLayer, time);
    }

    return hasRunningAnimations || m_hasRunningAnimations;
}

void LayerAndroid::initAnimations() {
    // tell auto-initializing animations to start now
    for (int i = 0; i < countChildren(); i++)
        getChild(i)->initAnimations();

    KeyframesMap::const_iterator localBegin = m_animations.begin();
    KeyframesMap::const_iterator localEnd = m_animations.end();
    for (KeyframesMap::const_iterator localIt = localBegin; localIt != localEnd; ++localIt)
        (localIt->second)->suggestBeginTime(WTF::currentTime());
}

void LayerAndroid::addDirtyArea()
{
    if (m_drawTransform.hasPerspective()) {
        state()->doFrameworkFullInval();
        return;
    }

    // TODO: rewrite this to handle partial invalidate, and to handle base
    // layer's large clip correctly

    IntSize layerSize(getSize().width(), getSize().height());

    FloatRect area =
        TilesManager::instance()->shader()->rectInViewCoord(m_drawTransform, layerSize);
    FloatRect clippingRect =
        TilesManager::instance()->shader()->rectInInvViewCoord(m_clippingRect);
    FloatRect clip =
        TilesManager::instance()->shader()->convertInvViewCoordToViewCoord(clippingRect);

    area.intersect(clip);
    IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());

    state()->addDirtyArea(dirtyArea);

    for (int i = 0; i < countChildren(); i++)
        getChild(i)->addDirtyArea();
}

void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim)
{
    RefPtr<AndroidAnimation> anim = prpAnim;
    pair<String, int> key(anim->nameCopy(), anim->type());
    removeAnimationsForProperty(anim->type());
    m_animations.add(key, anim);
}

void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
{
    KeyframesMap::const_iterator end = m_animations.end();
    Vector<pair<String, int> > toDelete;
    for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
        if ((it->second)->type() == property)
            toDelete.append(it->first);
    }

    for (unsigned int i = 0; i < toDelete.size(); i++)
        m_animations.remove(toDelete[i]);
}

void LayerAndroid::removeAnimationsForKeyframes(const String& name)
{
    KeyframesMap::const_iterator end = m_animations.end();
    Vector<pair<String, int> > toDelete;
    for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
        if ((it->second)->isNamed(name))
            toDelete.append(it->first);
    }

    for (unsigned int i = 0; i < toDelete.size(); i++)
        m_animations.remove(toDelete[i]);
}

// We only use the bounding rect of the layer as mask...
// FIXME: use a real mask?
void LayerAndroid::setMaskLayer(LayerAndroid* layer)
{
    SkSafeRef(layer);
    SkSafeUnref(m_maskLayer);
    m_maskLayer = layer;
    if (layer)
        m_haveClip = true;
}

void LayerAndroid::setBackgroundColor(SkColor color)
{
    m_backgroundColor = color;
}

FloatPoint LayerAndroid::translation() const
{
    TransformationMatrix::DecomposedType tDecomp;
    m_transform.decompose(tDecomp);
    FloatPoint p(tDecomp.translateX, tDecomp.translateY);
    return p;
}

IFrameLayerAndroid* LayerAndroid::updatePosition(SkRect viewport,
                                                 IFrameLayerAndroid* parentIframeLayer)
{
    // subclasses can implement this virtual function to modify their position
    if (m_fixedPosition)
        return m_fixedPosition->updatePosition(viewport, parentIframeLayer);
    return parentIframeLayer;
}

void LayerAndroid::updateLayerPositions(SkRect viewport, IFrameLayerAndroid* parentIframeLayer)
{
    ALOGV("updating fixed positions, using viewport %fx%f - %fx%f",
          viewport.fLeft, viewport.fTop,
          viewport.width(), viewport.height());

    IFrameLayerAndroid* iframeLayer = updatePosition(viewport, parentIframeLayer);

    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        this->getChild(i)->updateLayerPositions(viewport, iframeLayer);
}

void LayerAndroid::updatePositions()
{
    // apply the viewport to us
    if (!isPositionFixed()) {
        // turn our fields into a matrix.
        //
        // FIXME: this should happen in the caller, and we should remove these
        // fields from our subclass
        SkMatrix matrix;
        GLUtils::toSkMatrix(matrix, m_transform);
        this->setMatrix(matrix);
    }

    // now apply it to our children
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        this->getChild(i)->updatePositions();
}

void LayerAndroid::updateLocalTransformAndClip(const TransformationMatrix& parentMatrix,
                                               const FloatRect& clipping)
{
    FloatPoint position(getPosition().x() + m_replicatedLayerPosition.x() - getScrollOffset().x(),
                        getPosition().y() + m_replicatedLayerPosition.y() - getScrollOffset().y());

    if (isPositionFixed())
        m_drawTransform.makeIdentity();
    else
        m_drawTransform = parentMatrix;

    if (m_transform.isIdentity()) {
        m_drawTransform.translate3d(position.x(),
                                    position.y(),
                                    0);
    } else {
        float originX = getAnchorPoint().x() * getWidth();
        float originY = getAnchorPoint().y() * getHeight();
        m_drawTransform.translate3d(originX + position.x(),
                                    originY + position.y(),
                                    anchorPointZ());
        m_drawTransform.multiply(m_transform);
        m_drawTransform.translate3d(-originX,
                                    -originY,
                                    -anchorPointZ());
    }

    m_drawTransformUnfudged = m_drawTransform;
    if (m_drawTransform.isIdentityOrTranslation()
        && surface() && surface()->allowTransformFudging()) {
        // adjust the translation coordinates of the draw transform matrix so
        // that layers (defined in content coordinates) will align to display/view pixels

        // the surface may not allow fudging if it uses the draw transform at paint time
        float desiredContentX = round(m_drawTransform.m41() * m_scale) / m_scale;
        float desiredContentY = round(m_drawTransform.m42() * m_scale) / m_scale;
        ALOGV("fudging translation from %f, %f to %f, %f",
              m_drawTransform.m41(), m_drawTransform.m42(),
              desiredContentX, desiredContentY);
        m_drawTransform.setM41(desiredContentX);
        m_drawTransform.setM42(desiredContentY);
    }

    m_zValue = TilesManager::instance()->shader()->zValue(m_drawTransform,
                                                          getSize().width(),
                                                          getSize().height());

    if (m_haveClip) {
        // The clipping rect calculation and intersetion will be done in content
        // coordinates.
        FloatRect rect(0, 0, getWidth(), getHeight());
        FloatRect clip = m_drawTransform.mapRect(rect);
        clip.intersect(clipping);
        setDrawClip(clip);
    } else {
        setDrawClip(clipping);
    }
    ALOGV("%s - %d %f %f %f %f",
          subclassType() == BaseLayer ? "BASE" : "nonbase",
          m_haveClip, m_clippingRect.x(), m_clippingRect.y(),
          m_clippingRect.width(), m_clippingRect.height());

    setVisible(m_backfaceVisibility || m_drawTransform.inverse().m33() >= 0);
}

void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
                                             const FloatRect& clipping, float opacity,
                                             float scale, bool forceCalculation,
                                             bool disableFixedElemUpdate)
{
    m_scale = scale;

    opacity *= getOpacity();
    setDrawOpacity(opacity);

    // constantly recalculate the draw transform of layers that may require it (and their children)
    forceCalculation |= hasDynamicTransform();

    forceCalculation &= !(disableFixedElemUpdate && isPositionFixed());
    if (forceCalculation)
        updateLocalTransformAndClip(parentMatrix, clipping);

    if (!countChildren() || !m_visible)
        return;

    TransformationMatrix childMatrix = m_drawTransformUnfudged;
    // Flatten to 2D if the layer doesn't preserve 3D.
    if (!preserves3D()) {
        childMatrix.setM13(0);
        childMatrix.setM23(0);
        childMatrix.setM31(0);
        childMatrix.setM32(0);
        childMatrix.setM33(1);
        childMatrix.setM34(0);
        childMatrix.setM43(0);
    }

    // now apply it to our children
    childMatrix.translate3d(getScrollOffset().x(), getScrollOffset().y(), 0);
    if (!m_childrenTransform.isIdentity()) {
        childMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f);
        childMatrix.multiply(m_childrenTransform);
        childMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
    }
    for (int i = 0; i < countChildren(); i++)
        this->getChild(i)->updateGLPositionsAndScale(childMatrix, drawClip(),
                                                     opacity, scale, forceCalculation,
                                                     disableFixedElemUpdate);
}

bool LayerAndroid::visible() {
    // TODO: avoid climbing tree each access
    LayerAndroid* current = this;
    while (current->getParent()) {
        if (!current->m_visible)
            return false;
        current = static_cast<LayerAndroid*>(current->getParent());
    }
    return true;
}

void LayerAndroid::setContentsImage(SkBitmapRef* img)
{
    ImageTexture* image = ImagesManager::instance()->setImage(img);
    ImagesManager::instance()->releaseImage(m_imageCRC);
    m_imageCRC = image ? image->imageCRC() : 0;
}

void LayerAndroid::setContent(LayerContent* content)
{
    SkSafeRef(content);
    SkSafeUnref(m_content);
    m_content = content;
}

bool LayerAndroid::canUpdateWithBlit()
{
    if (!m_content || !m_scale)
        return false;
    IntRect clip = clippedRect();
    IntRect dirty = m_dirtyRegion.getBounds();
    dirty.intersect(clip);
    PrerenderedInval* prerendered = m_content->prerenderForRect(dirty);
    if (!prerendered)
        return false;
    // Check that the scales are "close enough" to produce the same rects
    FloatRect screenArea = prerendered->screenArea;
    screenArea.scale(1 / m_scale);
    IntRect enclosingDocArea = enclosingIntRect(screenArea);
    return enclosingDocArea == prerendered->area;
}

bool LayerAndroid::needsTexture()
{
    return (m_content && !m_content->isEmpty())
            || (m_originalLayer && m_originalLayer->needsTexture());
}

IntRect LayerAndroid::clippedRect() const
{
    IntRect r(0, 0, getWidth(), getHeight());
    IntRect tr = m_drawTransform.mapRect(r);
    IntRect cr = TilesManager::instance()->shader()->clippedRectWithVisibleContentRect(tr);
    IntRect rect = m_drawTransform.inverse().mapRect(cr);
    return rect;
}

int LayerAndroid::nbLayers()
{
    int nb = 0;
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        nb += this->getChild(i)->nbLayers();
    return nb+1;
}

int LayerAndroid::nbTexturedLayers()
{
    int nb = 0;
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        nb += this->getChild(i)->nbTexturedLayers();
    if (needsTexture())
        nb++;
    return nb;
}

void LayerAndroid::showLayer(int indent)
{
    char spaces[256];
    memset(spaces, 0, 256);
    for (int i = 0; i < indent; i++)
        spaces[i] = ' ';

    if (!indent) {
        ALOGD("\n\n--- LAYERS TREE ---");
        IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
        ALOGD("contentViewport(%d, %d, %d, %d)",
              contentViewport.x(), contentViewport.y(),
              contentViewport.width(), contentViewport.height());
    }

    IntRect r(0, 0, getWidth(), getHeight());
    IntRect tr = m_drawTransform.mapRect(r);
    IntRect visible = visibleContentArea();
    IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
                 m_clippingRect.width(), m_clippingRect.height());
    ALOGD("%s s:%x %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
          "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d",
          spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName(),
          subclassType(), uniqueId(), this, m_owningLayer,
          needsTexture() ? "needsTexture" : "",
          m_imageCRC ? "hasImage" : "",
          tr.x(), tr.y(), tr.width(), tr.height(),
          visible.x(), visible.y(), visible.width(), visible.height(),
          clip.x(), clip.y(), clip.width(), clip.height(),
          contentIsScrollable() ? "SCROLLABLE" : "",
          isPositionFixed() ? "FIXED" : "",
          m_content,
          m_content ? m_content->width() : -1,
          m_content ? m_content->height() : -1,
          m_originalLayer, m_originalLayer ? m_originalLayer->uniqueId() : -1);

    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        this->getChild(i)->showLayer(indent + 2);
}

void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree)
{
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        this->getChild(i)->mergeInvalsInto(replacementTree);

    LayerAndroid* replacementLayer = replacementTree->findById(uniqueId());
    if (replacementLayer)
        replacementLayer->markAsDirty(m_dirtyRegion);
}

static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
{
    return a->zValue() > b->zValue();
}

bool LayerAndroid::canJoinSurface(Surface* surface)
{
#ifdef DISABLE_LAYER_MERGE
    return false;
#else
    // returns true if the layer can be merged onto the surface (group of layers)
    if (!surface)
        return false;

    LayerAndroid* lastLayer = surface->getFirstLayer();

    // isolate intrinsically composited layers
    if (needsIsolatedSurface() || lastLayer->needsIsolatedSurface())
        return false;

    // TODO: investigate potential for combining transformed layers
    if (!m_drawTransform.isIdentityOrTranslation()
        || !lastLayer->m_drawTransform.isIdentityOrTranslation())
        return false;

    // TODO: compare other layer properties - fixed? overscroll? transformed?
    return true;
#endif
}

void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
{
    // recurse through layers in draw order, and merge layers when able

    bool needNewSurface = !mergeState->currentSurface
        || mergeState->nonMergeNestedLevel > 0
        || !canJoinSurface(mergeState->currentSurface);

    if (needNewSurface) {
        mergeState->currentSurface = new Surface();
        mergeState->surfaceList->append(mergeState->currentSurface);
    }

#ifdef LAYER_MERGING_DEBUG
    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",
          4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
          needNewSurface ? "NEW" : "joins", mergeState->currentSurface,
          mergeState->nonMergeNestedLevel,
          isPositionFixed(), m_animations.size() != 0,
          m_intrinsicallyComposited,
          m_haveClip,
          contentIsScrollable(), m_content ? m_content->hasText() : -1,
          mergeState->currentSurface ? mergeState->currentSurface->hasText() : -1,
          needsTexture(), getWidth(), getHeight());
#endif

    mergeState->currentSurface->addLayer(this, m_drawTransform);
    m_surface = mergeState->currentSurface;

    if (hasDynamicTransform()) {
        // disable layer merging within the children of these layer types
        mergeState->nonMergeNestedLevel++;
    }

    // pass the surface through children in drawing order, so that they may
    // attach themselves (and paint on it) if possible, or ignore it and create
    // a new one if not
    int count = this->countChildren();
    if (count > 0) {
        mergeState->depth++;
        Vector <LayerAndroid*> sublayers;
        for (int i = 0; i < count; i++)
            sublayers.append(getChild(i));

        // sort for the transparency
        std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
        for (int i = 0; i < count; i++)
            sublayers[i]->assignSurfaces(mergeState);
        mergeState->depth--;
    }

    if (hasDynamicTransform()) {
        // re-enable joining
        mergeState->nonMergeNestedLevel--;

        // disallow layers painting after to join with this surface
        mergeState->currentSurface = 0;
    }

    if (needsIsolatedSurface())
        mergeState->currentSurface = 0;

}

// We call this in WebViewCore, when copying the tree of layers.
// As we construct a new tree that will be passed on the UI,
// we mark the webkit-side tree as having no more dirty region
// (otherwise we would continuously have those dirty region UI-side)
void LayerAndroid::clearDirtyRegion()
{
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        this->getChild(i)->clearDirtyRegion();

    m_dirtyRegion.setEmpty();
}

int LayerAndroid::setHwAccelerated(bool hwAccelerated)
{
    int flags = InvalidateNone;
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        flags |= this->getChild(i)->setHwAccelerated(hwAccelerated);

    return flags | onSetHwAccelerated(hwAccelerated);
}

FloatRect LayerAndroid::fullContentAreaMapped() const
{
    FloatRect area(0,0, getWidth(), getHeight());
    FloatRect globalArea = m_drawTransform.mapRect(area);
    return globalArea;
}

IntRect LayerAndroid::fullContentArea() const
{
    IntRect area(0,0, getWidth(), getHeight());
    return area;
}

IntRect LayerAndroid::visibleContentArea(bool force3dContentVisible) const
{
    IntRect area = fullContentArea();
    if (subclassType() == LayerAndroid::FixedBackgroundImageLayer)
       return area;

    // If transform isn't limited to 2D space, return the entire content area.
    // Transforming from layers to content coordinates and back doesn't
    // preserve 3D.
    if (force3dContentVisible && GLUtils::has3dTransform(m_drawTransform))
            return area;

    // First, we get the transformed area of the layer,
    // in content coordinates
    IntRect rect = m_drawTransform.mapRect(area);

    // Then we apply the clipping
    IntRect clip(m_clippingRect);
    rect.intersect(clip);

    // Now clip with the viewport in content coordinate
    IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
    rect.intersect(contentViewport);

    // Finally, let's return the visible area, in layers coordinate
    return m_drawTransform.inverse().mapRect(rect);
}

bool LayerAndroid::drawCanvas(SkCanvas* canvas, bool drawChildren, PaintStyle style)
{
    if (!m_visible)
        return false;

    bool askScreenUpdate = false;

    {
        SkAutoCanvasRestore acr(canvas, true);
        SkRect r;
        r.set(m_clippingRect.x(), m_clippingRect.y(),
              m_clippingRect.x() + m_clippingRect.width(),
              m_clippingRect.y() + m_clippingRect.height());
        if (canvas->clipRect(r)) {
            SkMatrix matrix;
            GLUtils::toSkMatrix(matrix, m_drawTransform);
            SkMatrix canvasMatrix = canvas->getTotalMatrix();
            matrix.postConcat(canvasMatrix);
            canvas->setMatrix(matrix);
            onDraw(canvas, m_drawOpacity, 0, style);
        }
    }

    if (!drawChildren)
        return false;

    // When the layer is dirty, the UI thread should be notified to redraw.
    askScreenUpdate |= drawChildrenCanvas(canvas, style);
    return askScreenUpdate;
}

void LayerAndroid::collect3dRenderingContext(Vector<LayerAndroid*>& layersInContext)
{
    layersInContext.append(this);
    if (preserves3D()) {
        int count = countChildren();
        for (int i = 0; i < count; i++)
            getChild(i)->collect3dRenderingContext(layersInContext);
    }
}

bool LayerAndroid::drawSurfaceAndChildrenGL()
{
    bool askScreenUpdate = false;
    if (surface()->getFirstLayer() == this)
        askScreenUpdate |= surface()->drawGL(false);

    // return early, since children will be painted directly by drawTreeSurfacesGL
    if (preserves3D())
        return askScreenUpdate;

    int count = countChildren();
    Vector <LayerAndroid*> sublayers;
    for (int i = 0; i < count; i++)
        sublayers.append(getChild(i));

    std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
    for (int i = 0; i < count; i++)
        askScreenUpdate |= sublayers[i]->drawTreeSurfacesGL();

    return askScreenUpdate;
}

bool LayerAndroid::drawTreeSurfacesGL()
{
    bool askScreenUpdate = false;
    if (preserves3D()) {
        // hit a preserve-3d layer, so render the entire 3D rendering context in z order
        Vector<LayerAndroid*> contextLayers;
        collect3dRenderingContext(contextLayers);
        std::stable_sort(contextLayers.begin(), contextLayers.end(), compareLayerZ);

        for (unsigned int i = 0; i < contextLayers.size(); i++)
            askScreenUpdate |= contextLayers[i]->drawSurfaceAndChildrenGL();
    } else
        askScreenUpdate |= drawSurfaceAndChildrenGL();

    return askScreenUpdate;
}

bool LayerAndroid::drawGL(bool layerTilesDisabled)
{
    if (!layerTilesDisabled && m_imageCRC) {
        ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
        if (imageTexture)
            imageTexture->drawGL(this, getOpacity());
        ImagesManager::instance()->releaseImage(m_imageCRC);
    }

    state()->glExtras()->drawGL(this);
    bool askScreenUpdate = false;

    if (m_hasRunningAnimations)
        askScreenUpdate = true;

    return askScreenUpdate;
}

bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style)
{
    bool askScreenUpdate = false;
    int count = this->countChildren();
    if (count > 0) {
        Vector <LayerAndroid*> sublayers;
        for (int i = 0; i < count; i++)
            sublayers.append(this->getChild(i));

        // now we sort for the transparency
        std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
        for (int i = 0; i < count; i++) {
            LayerAndroid* layer = sublayers[i];
            askScreenUpdate |= layer->drawCanvas(canvas, true, style);
        }
    }

    return askScreenUpdate;
}

void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style)
{
    if (m_maskLayer && m_maskLayer->m_content) {
        // TODO: we should use a shader instead of doing
        // the masking in software

        if (m_originalLayer)
            m_originalLayer->m_content->draw(canvas);
        else if (m_content)
            m_content->draw(canvas);

        SkPaint maskPaint;
        maskPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
        int count = canvas->saveLayer(0, &maskPaint, SkCanvas::kHasAlphaLayer_SaveFlag);
        m_maskLayer->m_content->draw(canvas);
        canvas->restoreToCount(count);

    } else if (m_content)
        m_content->draw(canvas);

    if (TilesManager::instance()->getShowVisualIndicator()) {
        float w = getSize().width();
        float h = getSize().height();
        SkPaint paint;

        if (style == MergedLayers)
            paint.setARGB(255, 255, 255, 0);
        else if (style == UnmergedLayers)
            paint.setARGB(255, 255, 0, 0);
        else if (style == FlattenedLayers)
            paint.setARGB(255, 255, 0, 255);

        canvas->drawLine(0, 0, w, h, paint);
        canvas->drawLine(0, h, w, 0, paint);

        canvas->drawLine(0, 0, 0, h-1, paint);
        canvas->drawLine(0, h-1, w-1, h-1, paint);
        canvas->drawLine(w-1, h-1, w-1, 0, paint);
        canvas->drawLine(w-1, 0, 0, 0, paint);

        static SkTypeface* s_typeface = 0;
        if (!s_typeface)
            s_typeface = SkTypeface::CreateFromName("", SkTypeface::kBold);
        paint.setARGB(255, 0, 0, 255);
        paint.setTextSize(17);
        char str[256];
        snprintf(str, 256, "%d", uniqueId());
        paint.setTypeface(s_typeface);
        canvas->drawText(str, strlen(str), 2, h - 2, paint);
    }

    if (m_fixedPosition)
        return m_fixedPosition->contentDraw(canvas, style);
}

void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity,
                          android::DrawExtra* extra, PaintStyle style)
{
    if (m_haveClip) {
        SkRect r;
        r.set(0, 0, getSize().width(), getSize().height());
        canvas->clipRect(r);
        return;
    }

    // only continue drawing if layer is drawable
    if (!m_content && !m_imageCRC)
        return;

    // we just have this save/restore for opacity...
    SkAutoCanvasRestore restore(canvas, true);

    int canvasOpacity = SkScalarRound(opacity * 255);
    if (canvasOpacity < 255)
        canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity));

    if (m_imageCRC) {
        ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
        m_dirtyRegion.setEmpty();
        if (imageTexture) {
            SkRect dest;
            dest.set(0, 0, getSize().width(), getSize().height());
            imageTexture->drawCanvas(canvas, dest);
        }
        ImagesManager::instance()->releaseImage(m_imageCRC);
    }
    contentDraw(canvas, style);
    if (extra)
        extra->draw(canvas, this);
}

void LayerAndroid::setFixedPosition(FixedPositioning* position) {
    if (m_fixedPosition && m_fixedPosition != position)
        delete m_fixedPosition;
    m_fixedPosition = position;
}

void LayerAndroid::dumpLayer(LayerDumper* dumper) const
{
    dumper->writeIntVal("layerId", m_uniqueId);
    dumper->writeIntVal("haveClip", m_haveClip);
    dumper->writeIntVal("isFixed", isPositionFixed());

    dumper->writeFloatVal("opacity", getOpacity());
    dumper->writeSize("size", getSize());
    dumper->writePoint("position", getPosition());
    dumper->writePoint("anchor", getAnchorPoint());

    dumper->writeMatrix("drawMatrix", m_drawTransform);
    dumper->writeMatrix("transformMatrix", m_transform);
    dumper->writeRect("clippingRect", SkRect(m_clippingRect));

    if (m_content) {
        dumper->writeIntVal("m_content.width", m_content->width());
        dumper->writeIntVal("m_content.height", m_content->height());
    }

    if (m_fixedPosition)
        m_fixedPosition->dumpLayer(dumper);
}

void LayerAndroid::dumpLayers(LayerDumper* dumper) const
{
    dumper->beginLayer(subclassName(), this);
    dumpLayer(dumper);

    dumper->beginChildren(countChildren());
    if (countChildren()) {
        for (int i = 0; i < countChildren(); i++)
            getChild(i)->dumpLayers(dumper);
    }
    dumper->endChildren();
    dumper->endLayer();
}

LayerAndroid* LayerAndroid::findById(int match)
{
    if (m_uniqueId == match)
        return this;
    for (int i = 0; i < countChildren(); i++) {
        LayerAndroid* result = getChild(i)->findById(match);
        if (result)
            return result;
    }
    return 0;
}

} // namespace WebCore

#endif // USE(ACCELERATED_COMPOSITING)
