Home | History | Annotate | Download | only in layers
      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 "PlatformString.h"
     29 #include "RefPtr.h"
     30 #include "SkBitmap.h"
     31 #include "SkColor.h"
     32 #include "SkRegion.h"
     33 #include "SkStream.h"
     34 #include "TransformationMatrix.h"
     35 
     36 #include <utils/threads.h>
     37 #include <wtf/HashMap.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 LayerContent;
     54 class ImageTexture;
     55 class Surface;
     56 }
     57 
     58 namespace android {
     59 class DrawExtra;
     60 void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream);
     61 WebCore::LayerAndroid* deserializeLayer(int version, SkStream* stream);
     62 void cleanupImageRefs(WebCore::LayerAndroid* layer);
     63 }
     64 
     65 using namespace android;
     66 
     67 namespace WebCore {
     68 
     69 class AndroidAnimation;
     70 class FixedPositioning;
     71 class GLWebViewState;
     72 class IFrameLayerAndroid;
     73 class LayerMergeState;
     74 class RenderLayer;
     75 class PaintedSurface;
     76 class LayerDumper;
     77 
     78 class TexturesResult {
     79 public:
     80     TexturesResult()
     81         : fixed(0)
     82         , scrollable(0)
     83         , clipped(0)
     84         , full(0)
     85     {}
     86 
     87     int fixed;
     88     int scrollable;
     89     int clipped;
     90     int full;
     91 };
     92 
     93 class TEST_EXPORT LayerAndroid : public Layer {
     94 public:
     95     typedef enum { UndefinedLayer, WebCoreLayer, UILayer } LayerType;
     96     typedef enum { StandardLayer, ScrollableLayer,
     97                    IFrameLayer, IFrameContentLayer,
     98                    FixedBackgroundLayer,
     99                    FixedBackgroundImageLayer,
    100                    ForegroundBaseLayer,
    101                    CanvasLayer, BaseLayer } SubclassType;
    102     typedef enum { InvalidateNone = 0, InvalidateLayers } InvalidateFlags;
    103 
    104     const char* subclassName() const
    105     {
    106         switch (subclassType()) {
    107             case LayerAndroid::StandardLayer:
    108                 return "StandardLayer";
    109             case LayerAndroid::ScrollableLayer:
    110                 return "ScrollableLayer";
    111             case LayerAndroid::IFrameLayer:
    112                 return "IFrameLayer";
    113             case LayerAndroid::IFrameContentLayer:
    114                 return "IFrameContentLayer";
    115             case LayerAndroid::FixedBackgroundLayer:
    116                 return "FixedBackgroundLayer";
    117             case LayerAndroid::FixedBackgroundImageLayer:
    118                 return "FixedBackgroundImageLayer";
    119             case LayerAndroid::ForegroundBaseLayer:
    120                 return "ForegroundBaseLayer";
    121             case LayerAndroid::CanvasLayer:
    122                 return "CanvasLayer";
    123             case LayerAndroid::BaseLayer:
    124                 return "BaseLayer";
    125         }
    126         return "Undefined";
    127     }
    128 
    129     LayerAndroid(RenderLayer* owner);
    130     LayerAndroid(const LayerAndroid& layer);
    131     virtual ~LayerAndroid();
    132 
    133     void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; }
    134     void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
    135     FloatPoint translation() const;
    136     IntRect clippedRect() const;
    137     bool outsideViewport();
    138 
    139     // Returns the full area of the layer mapped into global content coordinates
    140     FloatRect fullContentAreaMapped() const;
    141 
    142     IntRect fullContentArea() const;
    143     IntRect visibleContentArea(bool force3dContentVisible = false) const;
    144 
    145     virtual bool needsTexture();
    146 
    147     // Debug helper methods
    148     int nbLayers();
    149     int nbTexturedLayers();
    150     void showLayer(int indent = 0);
    151 
    152     float getScale() { return m_scale; }
    153 
    154     // draw the layer tree recursively in draw order, grouping and sorting 3d rendering contexts
    155     bool drawTreeSurfacesGL();
    156 
    157     virtual bool drawGL(bool layerTilesDisabled);
    158     virtual bool drawCanvas(SkCanvas* canvas, bool drawChildren, PaintStyle style);
    159     bool drawChildrenCanvas(SkCanvas* canvas, PaintStyle style);
    160 
    161     void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
    162                                    const FloatRect& clip, float opacity, float scale,
    163                                    bool forceCalculations, bool disableFixedElemUpdate);
    164     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
    165     float drawOpacity() { return m_drawOpacity; }
    166     bool visible();
    167     void setVisible(bool value) { m_visible = value; }
    168 
    169     bool preserves3D() { return m_preserves3D; }
    170     void setPreserves3D(bool value) { m_preserves3D = value; }
    171     void setAnchorPointZ(float z) { m_anchorPointZ = z; }
    172     float anchorPointZ() { return m_anchorPointZ; }
    173     void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = m_drawTransformUnfudged = transform; }
    174     virtual const TransformationMatrix* drawTransform() const { return &m_drawTransform; }
    175     void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
    176     void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; }
    177     const FloatRect& drawClip() { return m_clippingRect; }
    178 
    179     void setBackgroundColor(SkColor color);
    180     void setMaskLayer(LayerAndroid*);
    181     void setMasksToBounds(bool masksToBounds)
    182     {
    183         m_haveClip = masksToBounds;
    184     }
    185     bool masksToBounds() const { return m_haveClip; }
    186 
    187     LayerContent* content() { return m_content; }
    188     void setContent(LayerContent* content);
    189     // Check to see if the dirty area of this layer can be updated with a blit
    190     // from the prerender instead of needing to generate tiles from the LayerContent
    191     bool canUpdateWithBlit();
    192 
    193     void addAnimation(PassRefPtr<AndroidAnimation> anim);
    194     void removeAnimationsForProperty(AnimatedPropertyID property);
    195     void removeAnimationsForKeyframes(const String& name);
    196     bool evaluateAnimations();
    197     bool evaluateAnimations(double time);
    198     void initAnimations();
    199     bool hasAnimations() const;
    200     void addDirtyArea();
    201 
    202     void dumpLayers(LayerDumper*) const;
    203 
    204     virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
    205                                                IFrameLayerAndroid* parentIframeLayer);
    206 
    207     /** Call this to update the position attribute, so that later calls
    208         like bounds() will report the corrected position.
    209 
    210         This call is recursive, so it should be called on the root of the
    211         hierarchy.
    212      */
    213     void updatePositions();
    214 
    215     const LayerAndroid* find(int* xPtr, int* yPtr, SkPicture* root) const;
    216     const LayerAndroid* findById(int uniqueID) const
    217     {
    218         return const_cast<LayerAndroid*>(this)->findById(uniqueID);
    219     }
    220     LayerAndroid* findById(int uniqueID);
    221     LayerAndroid* getChild(int index) const
    222     {
    223         return static_cast<LayerAndroid*>(this->INHERITED::getChild(index));
    224     }
    225     int uniqueId() const { return m_uniqueId; }
    226 
    227     /** This sets a content image -- calling it means we will use
    228         the image directly when drawing the layer instead of using
    229         the content painted by WebKit.
    230         Images are handled in ImagesManager, as they can be shared
    231         between layers.
    232     */
    233     void setContentsImage(SkBitmapRef* img);
    234 
    235     virtual LayerAndroid* copy() const { return new LayerAndroid(*this); }
    236 
    237     virtual void clearDirtyRegion();
    238 
    239     virtual void contentDraw(SkCanvas* canvas, PaintStyle style);
    240 
    241     virtual bool isMedia() const { return false; }
    242     virtual bool isVideo() const { return false; }
    243     virtual bool isIFrame() const { return false; }
    244     virtual bool isIFrameContent() const { return false; }
    245     virtual bool isFixedBackground() const { return false; }
    246 
    247     bool isPositionFixed() const { return m_fixedPosition; }
    248     void setAbsolutePosition(bool isAbsolute) { m_isPositionAbsolute = isAbsolute; }
    249     bool isPositionAbsolute() { return m_isPositionAbsolute; }
    250     void setFixedPosition(FixedPositioning* position);
    251     FixedPositioning* fixedPosition() { return m_fixedPosition; }
    252 
    253     RenderLayer* owningLayer() const { return m_owningLayer; }
    254 
    255     float zValue() const { return m_zValue; }
    256 
    257     // ViewStateSerializer friends
    258     friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
    259     friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
    260     friend void android::cleanupImageRefs(LayerAndroid* layer);
    261 
    262     LayerType type() { return m_type; }
    263     virtual SubclassType subclassType() const { return LayerAndroid::StandardLayer; }
    264 
    265     float maxZoomScale() const;
    266 
    267     void copyAnimationStartTimesRecursive(LayerAndroid* oldTree);
    268 
    269 // rendering asset management
    270     SkRegion* getInvalRegion() { return &m_dirtyRegion; }
    271     void mergeInvalsInto(LayerAndroid* replacementTree);
    272 
    273     bool canJoinSurface(Surface* surface);
    274     void assignSurfaces(LayerMergeState* mergeState);
    275     Surface* surface() { return m_surface; }
    276 
    277     void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; }
    278     virtual bool needsIsolatedSurface() {
    279         return (needsTexture() && m_intrinsicallyComposited)
    280             || m_animations.size()
    281             || m_imageCRC;
    282     }
    283 
    284     int setHwAccelerated(bool hwAccelerated);
    285 
    286     void setReplicatedLayer(LayerAndroid* layer) { m_replicatedLayer = layer; }
    287     void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; }
    288     void setOriginalLayer(LayerAndroid* layer) { m_originalLayer = layer; }
    289     bool hasReplicatedLayer() { return m_replicatedLayer; }
    290     const TransformationMatrix* replicatedLayerDrawTransform() {
    291         if (m_replicatedLayer)
    292             return m_replicatedLayer->drawTransform();
    293         return 0;
    294     }
    295 
    296 protected:
    297     virtual void dumpLayer(LayerDumper*) const;
    298     /** Call this with the current viewport (scrolling, zoom) to update
    299         the position of the fixed layers.
    300 
    301         This call is recursive, so it should be called on the root of the
    302         hierarchy.
    303     */
    304     void updateLayerPositions(SkRect viewPort, IFrameLayerAndroid* parentIframeLayer = 0);
    305     virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style);
    306     virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated) { return InvalidateNone; }
    307     TransformationMatrix m_drawTransform;
    308     TransformationMatrix m_drawTransformUnfudged;
    309     int m_uniqueId;
    310 
    311 private:
    312     void updateLocalTransformAndClip(const TransformationMatrix& parentMatrix,
    313                                      const FloatRect& clip);
    314     bool hasDynamicTransform() {
    315         return contentIsScrollable() || isPositionFixed() || (m_animations.size() != 0);
    316     }
    317 
    318     // recurse through the current 3d rendering context, adding layers in the context to the vector
    319     void collect3dRenderingContext(Vector<LayerAndroid*>& layersInContext);
    320     bool drawSurfaceAndChildrenGL();
    321 
    322 #if DUMP_NAV_CACHE
    323     friend class CachedLayer::Debug; // debugging access only
    324 #endif
    325 
    326     // -------------------------------------------------------------------
    327     // Fields to be serialized
    328     // -------------------------------------------------------------------
    329 
    330     bool m_haveClip;
    331     bool m_backgroundColorSet;
    332 
    333     bool m_backfaceVisibility;
    334     bool m_visible;
    335 
    336 protected:
    337     SkColor m_backgroundColor;
    338 
    339 private:
    340 
    341     bool m_preserves3D;
    342     float m_anchorPointZ;
    343     float m_drawOpacity;
    344 
    345     bool m_isPositionAbsolute;
    346 
    347 protected:
    348     FixedPositioning* m_fixedPosition;
    349 
    350 private:
    351 
    352     typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
    353     KeyframesMap m_animations;
    354 
    355     TransformationMatrix m_transform;
    356     TransformationMatrix m_childrenTransform;
    357 
    358     // -------------------------------------------------------------------
    359     // Fields that are not serialized (generated, cached, or non-serializable)
    360     // -------------------------------------------------------------------
    361 
    362     float m_zValue;
    363 
    364     FloatRect m_clippingRect;
    365 
    366     // Note that m_content and m_imageCRC are mutually exclusive;
    367     // m_content is used when WebKit is asked to paint the layer's
    368     // content, while m_imageCRC references an image that we directly
    369     // composite, using the layer's dimensions as a destination rect.
    370     // We do this as if the layer only contains an image, directly compositing
    371     // it is a much faster method than using m_content.
    372     LayerContent* m_content;
    373 
    374 protected:
    375     unsigned m_imageCRC;
    376 
    377 private:
    378 
    379     // used to signal the framework we need a repaint
    380     bool m_hasRunningAnimations;
    381 
    382     float m_scale;
    383 
    384     // We try to not always compute the texture size, as this is quite heavy
    385     static const double s_computeTextureDelay = 0.2; // 200 ms
    386     double m_lastComputeTextureSize;
    387 
    388     RenderLayer* m_owningLayer;
    389 
    390     LayerType m_type;
    391     SubclassType m_subclassType;
    392 
    393     bool m_intrinsicallyComposited;
    394 
    395     Surface* m_surface;
    396 
    397     // link to a replicated layer (used e.g. for reflections)
    398     LayerAndroid* m_replicatedLayer;
    399     FloatPoint    m_replicatedLayerPosition;
    400     LayerAndroid* m_originalLayer;
    401     // link to a mask layer
    402     LayerAndroid* m_maskLayer;
    403 
    404     typedef Layer INHERITED;
    405 };
    406 
    407 }
    408 
    409 #else
    410 
    411 class SkPicture;
    412 
    413 namespace WebCore {
    414 
    415 class LayerAndroid {
    416 public:
    417     LayerAndroid(SkPicture* picture) :
    418         m_recordingPicture(picture), // does not assign ownership
    419         m_uniqueId(-1)
    420     {}
    421     SkPicture* picture() const { return m_recordingPicture; }
    422     int uniqueId() const { return m_uniqueId; }
    423 private:
    424     SkPicture* m_recordingPicture;
    425     int m_uniqueId;
    426 };
    427 
    428 }
    429 
    430 #endif // USE(ACCELERATED_COMPOSITING)
    431 
    432 #endif // LayerAndroid_h
    433