Home | History | Annotate | Download | only in nav
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "CachedPrefix.h"
     27 
     28 #include "CachedLayer.h"
     29 #include "FloatRect.h"
     30 #include "LayerAndroid.h"
     31 
     32 namespace android {
     33 
     34 #if USE(ACCELERATED_COMPOSITING)
     35 
     36 IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
     37     const IntRect& bounds) const
     38 {
     39     const LayerAndroid* aLayer = layer(root);
     40     if (!aLayer) {
     41         DBG_NAV_LOGD("no layer in root=%p uniqueId=%d", root, mUniqueId);
     42 #if DUMP_NAV_CACHE
     43         if (root)
     44             mDebug.printRootLayerAndroid(root);
     45 #endif
     46         return bounds;
     47     }
     48     FloatRect temp = bounds;
     49     // First, remove the original offset from the bounds.
     50     temp.move(-mOffset.x(), -mOffset.y());
     51 
     52     // Next, add in the new position of the layer (could be different due to a
     53     // fixed position layer).
     54     FloatPoint position = getGlobalPosition(aLayer);
     55     temp.move(position.x(), position.y());
     56 
     57     // Add in any layer translation.
     58     // FIXME: Should use bounds() and apply the entire transformation matrix.
     59     const FloatPoint& translation = aLayer->translation();
     60     temp.move(translation.x(), translation.y());
     61 
     62     SkRect clip;
     63     aLayer->bounds(&clip);
     64 
     65     // Do not try to traverse the parent chain if this is the root as the parent
     66     // will not be a LayerAndroid.
     67     if (aLayer != root) {
     68         LayerAndroid* parent = static_cast<LayerAndroid*>(aLayer->getParent());
     69         while (parent) {
     70             SkRect pClip;
     71             parent->bounds(&pClip);
     72 
     73             // Move our position into our parent's coordinate space.
     74             clip.offset(pClip.fLeft, pClip.fTop);
     75             // Clip our visible rectangle to the parent.
     76             clip.intersect(pClip);
     77 
     78             // Stop at the root.
     79             if (parent == root)
     80                 break;
     81             parent = static_cast<LayerAndroid*>(parent->getParent());
     82         }
     83     }
     84 
     85     // Intersect the result with the visible clip.
     86     temp.intersect(clip);
     87 
     88     IntRect result = enclosingIntRect(temp);
     89 
     90     DBG_NAV_LOGV("root=%p aLayer=%p [%d]"
     91         " bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g) pos=(%f,%f)"
     92         " offset=(%d,%d)"
     93         " result=(%d,%d,w=%d,h=%d)",
     94         root, aLayer, aLayer->uniqueId(),
     95         bounds.x(), bounds.y(), bounds.width(), bounds.height(),
     96         translation.x(), translation.y(), position.x(), position.y(),
     97         mOffset.x(), mOffset.y(),
     98         result.x(), result.y(), result.width(), result.height());
     99     return result;
    100 }
    101 
    102 FloatPoint CachedLayer::getGlobalPosition(const LayerAndroid* aLayer) const
    103 {
    104     SkPoint result = aLayer->getPosition();
    105     const Layer* parent = aLayer->getParent();
    106     while (parent) {
    107         result += parent->getPosition();
    108         DBG_NAV_LOGV("result=(%g,%g) parent=%p [%d]", result.fX, result.fY,
    109             parent, ((LayerAndroid*) parent)->uniqueId());
    110         parent = parent->getParent();
    111     }
    112     return result;
    113 }
    114 
    115 const LayerAndroid* CachedLayer::layer(const LayerAndroid* root) const
    116 {
    117     if (!root)
    118         return 0;
    119     return root->findById(mUniqueId);
    120 }
    121 
    122 // return bounds relative to the layer as recorded when walking the dom
    123 IntRect CachedLayer::localBounds(const LayerAndroid* root,
    124     const IntRect& bounds) const
    125 {
    126     IntRect temp = bounds;
    127     // Remove the original offset from the bounds.
    128     temp.move(-mOffset.x(), -mOffset.y());
    129 
    130 #if DEBUG_NAV_UI
    131     const LayerAndroid* aLayer = layer(root);
    132     DBG_NAV_LOGD("aLayer=%p [%d] bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)"
    133         " result=(%d,%d,w=%d,h=%d)",
    134         aLayer, aLayer ? aLayer->uniqueId() : 0,
    135         bounds.x(), bounds.y(), bounds.width(), bounds.height(),
    136         mOffset.x(), mOffset.y(),
    137         temp.x(), temp.y(), temp.width(), temp.height());
    138 #endif
    139 
    140     return temp;
    141 }
    142 
    143 SkPicture* CachedLayer::picture(const LayerAndroid* root) const
    144 {
    145     const LayerAndroid* aLayer = layer(root);
    146     if (!aLayer)
    147         return 0;
    148     DBG_NAV_LOGD("root=%p aLayer=%p [%d] picture=%p",
    149         root, aLayer, aLayer->uniqueId(), aLayer->picture());
    150     return aLayer->picture();
    151 }
    152 
    153 void CachedLayer::toLocal(const LayerAndroid* root, int* xPtr, int* yPtr) const
    154 {
    155     const LayerAndroid* aLayer = layer(root);
    156     if (!aLayer)
    157         return;
    158     DBG_NAV_LOGD("root=%p aLayer=%p [%d]", root, aLayer, aLayer->uniqueId());
    159     SkRect localBounds;
    160     aLayer->bounds(&localBounds);
    161     *xPtr -= localBounds.fLeft;
    162     *yPtr -= localBounds.fTop;
    163 }
    164 
    165 #if DUMP_NAV_CACHE
    166 
    167 CachedLayer* CachedLayer::Debug::base() const {
    168     return (CachedLayer*) ((char*) this - OFFSETOF(CachedLayer, mDebug));
    169 }
    170 
    171 void CachedLayer::Debug::print() const
    172 {
    173     CachedLayer* b = base();
    174     DUMP_NAV_LOGD("    // int mCachedNodeIndex=%d;\n", b->mCachedNodeIndex);
    175     DUMP_NAV_LOGD("    // int mOffset=(%d, %d);\n",
    176         b->mOffset.x(), b->mOffset.y());
    177     DUMP_NAV_LOGD("    // int mUniqueId=%p;\n", b->mUniqueId);
    178     DUMP_NAV_LOGD("%s\n", "");
    179 }
    180 
    181 #endif
    182 
    183 #if DUMP_NAV_CACHE
    184 
    185 int CachedLayer::Debug::spaces;
    186 
    187 void CachedLayer::Debug::printLayerAndroid(const LayerAndroid* layer)
    188 {
    189     ++spaces;
    190     SkRect bounds;
    191     layer->bounds(&bounds);
    192     DBG_NAV_LOGD("%.*s layer=%p [%d] (%g,%g,%g,%g)"
    193         " position=(%g,%g) translation=(%g,%g) anchor=(%g,%g)"
    194         " matrix=(%g,%g) childMatrix=(%g,%g) picture=%p clipped=%s"
    195         " scrollable=%s\n",
    196         spaces, "                   ", layer, layer->uniqueId(),
    197         bounds.fLeft, bounds.fTop, bounds.width(), bounds.height(),
    198         layer->getPosition().fX, layer->getPosition().fY,
    199         layer->translation().x(), layer->translation().y(),
    200         layer->getAnchorPoint().fX, layer->getAnchorPoint().fY,
    201         layer->getMatrix().getTranslateX(), layer->getMatrix().getTranslateY(),
    202         layer->getChildrenMatrix().getTranslateX(),
    203         layer->getChildrenMatrix().getTranslateY(),
    204         layer->picture(), layer->m_haveClip ? "true" : "false",
    205         layer->contentIsScrollable() ? "true" : "false");
    206     for (int i = 0; i < layer->countChildren(); i++)
    207         printLayerAndroid(layer->getChild(i));
    208     --spaces;
    209 }
    210 
    211 void CachedLayer::Debug::printRootLayerAndroid(const LayerAndroid* layer)
    212 {
    213     spaces = 0;
    214     printLayerAndroid(layer);
    215 }
    216 #endif
    217 
    218 #endif // USE(ACCELERATED_COMPOSITING)
    219 
    220 }
    221 
    222