• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LayerAndroid_h
18 #define LayerAndroid_h
19 
20 #if USE(ACCELERATED_COMPOSITING)
21 
22 #include "FloatPoint.h"
23 #include "FloatPoint3D.h"
24 #include "FloatRect.h"
25 #include "GraphicsLayerClient.h"
26 #include "ImageTexture.h"
27 #include "Layer.h"
28 #include "RefPtr.h"
29 #include "SkBitmap.h"
30 #include "SkColor.h"
31 #include "SkRegion.h"
32 #include "SkStream.h"
33 #include "TextureOwner.h"
34 #include "TransformationMatrix.h"
35 
36 #include <wtf/HashMap.h>
37 #include <wtf/text/StringHash.h>
38 
39 #ifndef BZERO_DEFINED
40 #define BZERO_DEFINED
41 // http://www.opengroup.org/onlinepubs/000095399/functions/bzero.html
42 // For maximum portability, it is recommended to replace the function call to bzero() as follows:
43 #define bzero(b, len) (memset((b), '\0', (len)), (void) 0)
44 #endif
45 
46 class SkBitmapRef;
47 class SkCanvas;
48 class SkMatrix;
49 class SkPicture;
50 
51 namespace WebCore {
52 class LayerAndroid;
53 class ImageTexture;
54 }
55 
56 namespace android {
57 class DrawExtra;
58 void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream);
59 WebCore::LayerAndroid* deserializeLayer(SkStream* stream);
60 void cleanupImageRefs(WebCore::LayerAndroid* layer);
61 }
62 
63 using namespace android;
64 
65 struct SkLength {
66     enum SkLengthType { Undefined, Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
67     SkLengthType type;
68     SkScalar value;
SkLengthSkLength69     SkLength()
70     {
71         type = Undefined;
72         value = 0;
73     }
definedSkLength74     bool defined() const
75     {
76         if (type == Undefined)
77             return false;
78         return true;
79     }
calcFloatValueSkLength80     float calcFloatValue(float max) const
81     {
82         switch (type) {
83         case Percent:
84             return (max * value) / 100.0f;
85         case Fixed:
86             return value;
87         default:
88             return value;
89         }
90     }
91 };
92 
93 namespace WebCore {
94 
95 class AndroidAnimation;
96 class BaseTileTexture;
97 class LayerAndroidFindState;
98 class RenderLayer;
99 class TiledPage;
100 class PaintedSurface;
101 
102 class LayerAndroid : public Layer {
103 public:
104     enum LayerType { UndefinedLayer, WebCoreLayer, UILayer, NavCacheLayer };
105     LayerAndroid(RenderLayer* owner);
106     LayerAndroid(const LayerAndroid& layer);
107     LayerAndroid(SkPicture*);
108     virtual ~LayerAndroid();
109 
page()110     virtual TiledPage* page() { return 0; }
state()111     virtual GLWebViewState* state() { return m_state; }
112 
setBackfaceVisibility(bool value)113     void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; }
setTransform(const TransformationMatrix & matrix)114     void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
115     FloatPoint translation() const;
116     // Returns a rect describing the bounds of the layer with the local
117     // transformation applied, expressed relative to the parent layer.
118     // FIXME: Currently we use only the translation component of the local
119     // transformation.
120     SkRect bounds() const;
121     IntRect clippedRect() const;
122     bool outsideViewport();
123 
124     virtual bool needsTexture();
125     void removeTexture(PaintedSurface*);
126 
127     // Debug helper methods
128     int nbLayers();
129     int nbTexturedLayers();
130     void showLayer(int indent);
131 
getScale()132     float getScale() { return m_scale; }
133 
134     // draw layer and its children via Z, pre-order traversal
135     virtual bool drawGL(GLWebViewState*, SkMatrix&);
136     bool drawChildrenGL(GLWebViewState*, SkMatrix&);
137 
138     // prepare layer and its children via reverse-Z, post-order traversal
139     void prepare(GLWebViewState*);
140 
141     void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
142                                    const FloatRect& clip, float opacity, float scale);
setDrawOpacity(float opacity)143     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
drawOpacity()144     float drawOpacity() { return m_drawOpacity; }
setVisible(bool value)145     void setVisible(bool value) { m_visible = value; }
146 
preserves3D()147     bool preserves3D() { return m_preserves3D; }
setPreserves3D(bool value)148     void setPreserves3D(bool value) { m_preserves3D = value; }
setAnchorPointZ(float z)149     void setAnchorPointZ(float z) { m_anchorPointZ = z; }
anchorPointZ()150     float anchorPointZ() { return m_anchorPointZ; }
setDrawTransform(const TransformationMatrix & transform)151     void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
drawTransform()152     const TransformationMatrix* drawTransform() const { return &m_drawTransform; }
setChildrenTransform(const TransformationMatrix & t)153     void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
setDrawClip(const FloatRect & rect)154     void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; }
drawClip()155     const FloatRect& drawClip() { return m_clippingRect; }
156 
setFixedPosition(SkLength left,SkLength top,SkLength right,SkLength bottom,SkLength marginLeft,SkLength marginTop,SkLength marginRight,SkLength marginBottom,const IntPoint & renderLayerPos,SkRect viewRect)157     void setFixedPosition(SkLength left, // CSS left property
158                           SkLength top, // CSS top property
159                           SkLength right, // CSS right property
160                           SkLength bottom, // CSS bottom property
161                           SkLength marginLeft, // CSS margin-left property
162                           SkLength marginTop, // CSS margin-top property
163                           SkLength marginRight, // CSS margin-right property
164                           SkLength marginBottom, // CSS margin-bottom property
165                           const IntPoint& renderLayerPos, // For undefined fixed position
166                           SkRect viewRect) { // view rect, can be smaller than the layer's
167         m_fixedLeft = left;
168         m_fixedTop = top;
169         m_fixedRight = right;
170         m_fixedBottom = bottom;
171         m_fixedMarginLeft = marginLeft;
172         m_fixedMarginTop = marginTop;
173         m_fixedMarginRight = marginRight;
174         m_fixedMarginBottom = marginBottom;
175         m_fixedRect = viewRect;
176         m_isFixed = true;
177         m_renderLayerPos = renderLayerPos;
178         setShouldInheritFromRootTransform(true);
179     }
180 
181     void setBackgroundColor(SkColor color);
182     void setMaskLayer(LayerAndroid*);
setMasksToBounds(bool masksToBounds)183     void setMasksToBounds(bool masksToBounds)
184     {
185         m_haveClip = masksToBounds;
186     }
masksToBounds()187     bool masksToBounds() const { return m_haveClip; }
188 
189     SkPicture* recordContext();
190 
191     void addAnimation(PassRefPtr<AndroidAnimation> anim);
192     void removeAnimationsForProperty(AnimatedPropertyID property);
193     void removeAnimationsForKeyframes(const String& name);
194     bool evaluateAnimations();
195     bool evaluateAnimations(double time);
196     bool hasAnimations() const;
197     void addDirtyArea(GLWebViewState*);
198 
picture()199     SkPicture* picture() const { return m_recordingPicture; }
200 
201     // Given a rect in global space, subtracts from it the bounds of this layer
202     // and of all of its children. Returns the bounding rectangle of the result,
203     // in global space.
204     SkRect subtractLayers(const SkRect&) const;
205 
206     void dumpLayers(FILE*, int indentLevel) const;
207     void dumpToLog() const;
208 
209     /** Call this with the current viewport (scrolling, zoom) to update
210         the position of the fixed layers.
211 
212         This call is recursive, so it should be called on the root of the
213         hierarchy.
214     */
215     void updateFixedLayersPositions(SkRect viewPort, LayerAndroid* parentIframeLayer = 0);
216 
217     /** Call this to update the position attribute, so that later calls
218         like bounds() will report the corrected position.
219 
220         This call is recursive, so it should be called on the root of the
221         hierarchy.
222      */
223     void updatePositions();
224 
225     void clipArea(SkTDArray<SkRect>* region) const;
226     const LayerAndroid* find(int* xPtr, int* yPtr, SkPicture* root) const;
findById(int uniqueID)227     const LayerAndroid* findById(int uniqueID) const
228     {
229         return const_cast<LayerAndroid*>(this)->findById(uniqueID);
230     }
231     LayerAndroid* findById(int uniqueID);
getChild(int index)232     LayerAndroid* getChild(int index) const
233     {
234         return static_cast<LayerAndroid*>(this->INHERITED::getChild(index));
235     }
236     void setExtra(DrawExtra* extra); // does not assign ownership
uniqueId()237     int uniqueId() const { return m_uniqueId; }
isFixed()238     bool isFixed() { return m_isFixed; }
239 
240     /** This sets a content image -- calling it means we will use
241         the image directly when drawing the layer instead of using
242         the content painted by WebKit.
243         Images are handled in TilesManager, as they can be shared
244         between layers.
245     */
246     void setContentsImage(SkBitmapRef* img);
247 
248     void bounds(SkRect*) const;
249 
copy()250     virtual LayerAndroid* copy() const { return new LayerAndroid(*this); }
251 
needsRepaint()252     void needsRepaint() { m_pictureUsed++; }
pictureUsed()253     unsigned int pictureUsed() { return m_pictureUsed; }
254 
255     void markAsDirty(const SkRegion& dirtyArea);
256     void clearDirtyRegion();
dirtyRegion()257     const SkRegion& dirtyRegion() { return m_dirtyRegion; }
258 
259     void contentDraw(SkCanvas*);
260     void extraDraw(SkCanvas*);
261 
isMedia()262     virtual bool isMedia() const { return false; }
isVideo()263     virtual bool isVideo() const { return false; }
264 
owningLayer()265     RenderLayer* owningLayer() const { return m_owningLayer; }
266 
setIsIframe(bool isIframe)267     void setIsIframe(bool isIframe) { m_isIframe = isIframe; }
zValue()268     float zValue() const { return m_zValue; }
269 
270     // ViewStateSerializer friends
271     friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
272     friend LayerAndroid* android::deserializeLayer(SkStream* stream);
273     friend void android::cleanupImageRefs(LayerAndroid* layer);
274 
texture()275     PaintedSurface* texture() { return m_texture; }
276     void assignTextureTo(LayerAndroid* newTree);
277     void createTexture();
278 
279     // Update layers using another tree. Only works for basic properties
280     // such as the position, the transform. Return true if anything more
281     // complex is needed.
282     bool updateWithTree(LayerAndroid*);
283     virtual bool updateWithLayer(LayerAndroid*);
284 
imageRef()285     SkBitmapRef* imageRef() { return m_imageRef; }
imageTexture()286     ImageTexture* imageTexture() { return m_imageTexture; }
type()287     int type() { return m_type; }
288 
289 protected:
290     virtual void onDraw(SkCanvas*, SkScalar opacity);
291 
292     TransformationMatrix m_drawTransform;
293 
294 private:
295     class FindState;
296 #if DUMP_NAV_CACHE
297     friend class CachedLayer::Debug; // debugging access only
298 #endif
299 
300     void findInner(FindState&) const;
301     bool prepareContext(bool force = false);
302     void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const;
303 
304     // -------------------------------------------------------------------
305     // Fields to be serialized
306     // -------------------------------------------------------------------
307 
308     bool m_haveClip;
309     bool m_isFixed;
310     bool m_backgroundColorSet;
311     bool m_isIframe;
312 
313     SkLength m_fixedLeft;
314     SkLength m_fixedTop;
315     SkLength m_fixedRight;
316     SkLength m_fixedBottom;
317     SkLength m_fixedMarginLeft;
318     SkLength m_fixedMarginTop;
319     SkLength m_fixedMarginRight;
320     SkLength m_fixedMarginBottom;
321     SkRect m_fixedRect;
322 
323     // When fixed element is undefined or auto, the render layer's position
324     // is needed for offset computation
325     IntPoint m_renderLayerPos;
326 
327     bool m_backfaceVisibility;
328     bool m_visible;
329 
330     SkColor m_backgroundColor;
331 
332     bool m_preserves3D;
333     float m_anchorPointZ;
334     float m_drawOpacity;
335 
336     // Note that m_recordingPicture and m_imageRef are mutually exclusive;
337     // m_recordingPicture is used when WebKit is asked to paint the layer's
338     // content, while m_imageRef contains an image that we directly
339     // composite, using the layer's dimensions as a destination rect.
340     // We do this as if the layer only contains an image, directly compositing
341     // it is a much faster method than using m_recordingPicture.
342     SkPicture* m_recordingPicture;
343 
344     typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
345     KeyframesMap m_animations;
346 
347     TransformationMatrix m_transform;
348     TransformationMatrix m_childrenTransform;
349 
350     // -------------------------------------------------------------------
351     // Fields that are not serialized (generated, cached, or non-serializable)
352     // -------------------------------------------------------------------
353 
354     SkPoint m_iframeOffset;
355 
356     float m_zValue;
357 
358     FloatRect m_clippingRect;
359 
360     SkPicture* m_extra;
361     int m_uniqueId;
362 
363     PaintedSurface* m_texture;
364     SkBitmapRef* m_imageRef;
365     ImageTexture* m_imageTexture;
366 
367     // used to signal that the tile is out-of-date and needs to be redrawn
368     bool m_dirty;
369     unsigned int m_pictureUsed;
370 
371     // dirty regions
372     SkRegion m_dirtyRegion;
373 
374     // used to signal the framework we need a repaint
375     bool m_hasRunningAnimations;
376 
377     // painting request sent
378     bool m_requestSent;
379 
380     float m_scale;
381 
382     // We try to not always compute the texture size, as this is quite heavy
383     static const double s_computeTextureDelay = 0.2; // 200 ms
384     double m_lastComputeTextureSize;
385 
386     // This mutex serves two purposes. (1) It ensures that certain operations
387     // happen atomically and (2) it makes sure those operations are synchronized
388     // across all threads and cores.
389     android::Mutex m_atomicSync;
390 
391     RenderLayer* m_owningLayer;
392 
393     GLWebViewState* m_state;
394     int m_type;
395     typedef Layer INHERITED;
396 };
397 
398 }
399 
400 #else
401 
402 class SkPicture;
403 
404 namespace WebCore {
405 
406 class LayerAndroid {
407 public:
LayerAndroid(SkPicture * picture)408     LayerAndroid(SkPicture* picture) :
409         m_recordingPicture(picture), // does not assign ownership
410         m_uniqueId(-1)
411     {}
picture()412     SkPicture* picture() const { return m_recordingPicture; }
uniqueId()413     int uniqueId() const { return m_uniqueId; }
414 private:
415     SkPicture* m_recordingPicture;
416     int m_uniqueId;
417 };
418 
419 }
420 
421 #endif // USE(ACCELERATED_COMPOSITING)
422 
423 #endif // LayerAndroid_h
424