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