• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
adjustBounds(const LayerAndroid * root,const IntRect & bounds) const36 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 
getGlobalPosition(const LayerAndroid * aLayer) const102 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 
layer(const LayerAndroid * root) const115 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
localBounds(const LayerAndroid * root,const IntRect & bounds) const123 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 
picture(const LayerAndroid * root) const143 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 
toLocal(const LayerAndroid * root,int * xPtr,int * yPtr) const153 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 
base() const167 CachedLayer* CachedLayer::Debug::base() const {
168     return (CachedLayer*) ((char*) this - OFFSETOF(CachedLayer, mDebug));
169 }
170 
print() const171 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 
printLayerAndroid(const LayerAndroid * layer)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 
printRootLayerAndroid(const LayerAndroid * layer)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