Home | History | Annotate | Download | only in android
      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 #ifndef GLWebViewState_h
     27 #define GLWebViewState_h
     28 
     29 #if USE(ACCELERATED_COMPOSITING)
     30 
     31 #include "Color.h"
     32 #include "DrawExtra.h"
     33 #include "GLExtras.h"
     34 #include "IntRect.h"
     35 #include "SkCanvas.h"
     36 #include "SkRect.h"
     37 #include "SkRegion.h"
     38 #include "TiledPage.h"
     39 #include "TreeManager.h"
     40 #include "ZoomManager.h"
     41 #include <utils/threads.h>
     42 
     43 // Performance measurements probe
     44 // To use it, enable the visual indicators in debug mode.
     45 // turning off the visual indicators will flush the measures.
     46 // #define MEASURES_PERF
     47 #define MAX_MEASURES_PERF 2000
     48 
     49 // Prefetch and render 1 tiles ahead of the scroll
     50 // TODO: We should either dynamically change the outer bound by detecting the
     51 // HW limit or save further in the GPU memory consumption.
     52 #define TILE_PREFETCH_DISTANCE 1
     53 
     54 // ratio of content to view required for prefetching to enable
     55 #define TILE_PREFETCH_RATIO 1.2
     56 
     57 namespace WebCore {
     58 
     59 class BaseLayerAndroid;
     60 class LayerAndroid;
     61 class ScrollableLayerAndroid;
     62 class TexturesResult;
     63 
     64 /////////////////////////////////////////////////////////////////////////////////
     65 // GL Architecture
     66 /////////////////////////////////////////////////////////////////////////////////
     67 //
     68 // To draw things, WebView use a tree of layers. The root of that tree is a
     69 // BaseLayerAndroid, which may have numerous LayerAndroid over it. The content
     70 // of those layers are SkPicture, the content of the BaseLayer is an PictureSet.
     71 //
     72 // When drawing, we therefore have one large "surface" that is the BaseLayer,
     73 // and (possibly) additional surfaces (usually smaller), which are the
     74 // LayerAndroids. The BaseLayer usually corresponds to the normal web page
     75 // content, the Layers are used for some parts such as specific divs (e.g. fixed
     76 // position divs, or elements using CSS3D transforms, or containing video,
     77 // plugins, etc.).
     78 //
     79 // *** NOTE: The GL drawing architecture only paints the BaseLayer for now.
     80 //
     81 // The rendering model is to use tiles to display the BaseLayer (as obviously a
     82 // BaseLayer's area can be arbitrarly large). The idea is to compute a set of
     83 // tiles covering the viewport's area, paint those tiles using the webview's
     84 // content (i.e. the BaseLayer's PictureSet), then display those tiles.
     85 // We check which tile we should use at every frame.
     86 //
     87 // Overview
     88 // ---------
     89 //
     90 // The tiles are grouped into a TiledPage -- basically a map of tiles covering
     91 // the BaseLayer's surface. When drawing, we ask the TiledPage to prepare()
     92 // itself then draw itself on screen. The prepare() function is the one
     93 // that schedules tiles to be painted -- i.e. the subset of tiles that intersect
     94 // with the current viewport. When they are ready, we can display
     95 // the TiledPage.
     96 //
     97 // Note that BaseLayerAndroid::drawGL() will return true to the java side if
     98 // there is a need to be called again (i.e. if we do not have up to date
     99 // textures or a transition is going on).
    100 //
    101 // Tiles are implemented as a BaseTile. It knows how to paint itself with the
    102 // PictureSet, and to display itself. A GL texture is usually associated to it.
    103 //
    104 // We also works with two TiledPages -- one to display the page at the
    105 // current scale factor, and another we use to paint the page at a different
    106 // scale factor. I.e. when we zoom, we use TiledPage A, with its tiles scaled
    107 // accordingly (and therefore possible loss of quality): this is fast as it's
    108 // purely a hardware operation. When the user is done zooming, we ask for
    109 // TiledPage B to be painted at the new scale factor, covering the
    110 // viewport's area. When B is ready, we swap it with A.
    111 //
    112 // Texture allocation
    113 // ------------------
    114 //
    115 // Obviously we cannot have every BaseTile having a GL texture -- we need to
    116 // get the GL textures from an existing pool, and reuse them.
    117 //
    118 // The way we do it is that when we call TiledPage::prepare(), we group the
    119 // tiles we need (i.e. in the viewport and dirty) into a TilesSet and call
    120 // BaseTile::reserveTexture() for each tile (which ensures there is a specific
    121 // GL textures backing the BaseTiles).
    122 //
    123 // reserveTexture() will ask the TilesManager for a texture. The allocation
    124 // mechanism goal is to (in order):
    125 // - prefers to allocate the same texture as the previous time
    126 // - prefers to allocate textures that are as far from the viewport as possible
    127 // - prefers to allocate textures that are used by different TiledPages
    128 //
    129 // Note that to compute the distance of each tile from the viewport, each time
    130 // we prepare() a TiledPage. Also during each prepare() we compute which tiles
    131 // are dirty based on the info we have received from webkit.
    132 //
    133 // BaseTile Invalidation
    134 // ------------------
    135 //
    136 // We do not want to redraw a tile if the tile is up-to-date. A tile is
    137 // considered to be dirty an in need of redrawing in the following cases
    138 //  - the tile has acquires a new texture
    139 //  - webkit invalidates all or part of the tiles contents
    140 //
    141 // To handle the case of webkit invalidation we store two ids (counters) of the
    142 // pictureSets in the tile.  The first id (A) represents the pictureSet used to
    143 // paint the tile and the second id (B) represents the pictureSet in which the
    144 // tile was invalidated by webkit. Thus, if A < B then tile is dirty.
    145 //
    146 // Since invalidates can occur faster than a full tiled page update, the tiled
    147 // page is protected by a 'lock' (m_baseLayerUpdate) that is set to true to
    148 // defer updates to the background layer, giving the foreground time to render
    149 // content instead of constantly flushing with invalidates. See
    150 // lockBaseLayerUpdate() & unlockBaseLayerUpdate().
    151 //
    152 // Painting scheduling
    153 // -------------------
    154 //
    155 // The next operation is to schedule this TilesSet to be painted
    156 // (TilesManager::schedulePaintForTilesSet()). TexturesGenerator
    157 // will get the TilesSet and ask the BaseTiles in it to be painted.
    158 //
    159 // BaseTile::paintBitmap() will paint the texture using the BaseLayer's
    160 // PictureSet (calling TiledPage::paintBaseLayerContent() which in turns
    161 // calls GLWebViewState::paintBaseLayerContent()).
    162 //
    163 // Note that TexturesGenerator is running in a separate thread, the textures
    164 // are shared using EGLImages (this is necessary to not slow down the rendering
    165 // speed -- updating GL textures in the main GL thread would slow things down).
    166 //
    167 /////////////////////////////////////////////////////////////////////////////////
    168 
    169 class GLWebViewState {
    170 public:
    171     GLWebViewState();
    172     ~GLWebViewState();
    173 
    174     ZoomManager* zoomManager() { return &m_zoomManager; }
    175     const SkIRect& futureViewport() const { return m_futureViewportTileBounds; }
    176     void setFutureViewport(const SkIRect& viewport) { m_futureViewportTileBounds = viewport; }
    177 
    178     unsigned int paintBaseLayerContent(SkCanvas* canvas);
    179     void setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval, bool showVisualIndicator,
    180                       bool isPictureAfterFirstLayout);
    181     void paintExtras();
    182 
    183     GLExtras* glExtras() { return &m_glExtras; }
    184 
    185     TiledPage* sibling(TiledPage* page);
    186     TiledPage* frontPage();
    187     TiledPage* backPage();
    188     void swapPages();
    189 
    190     // dimensions of the current base layer
    191     int baseContentWidth();
    192     int baseContentHeight();
    193 
    194     void setViewport(SkRect& viewport, float scale);
    195 
    196     // a rect containing the coordinates of all tiles in the current viewport
    197     const SkIRect& viewportTileBounds() const { return m_viewportTileBounds; }
    198     // a rect containing the viewportTileBounds before there was a scale change
    199     const SkIRect& preZoomBounds() const { return m_preZoomBounds; }
    200     void setPreZoomBounds(const SkIRect& bounds) { m_preZoomBounds = bounds; }
    201 
    202     unsigned int currentPictureCounter() const { return m_currentPictureCounter; }
    203 
    204     void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; }
    205     bool isScrolling() { return m_isScrolling; }
    206 
    207     void drawBackground(Color& backgroundColor);
    208     double setupDrawing(IntRect& viewRect, SkRect& visibleRect,
    209                         IntRect& webViewRect, int titleBarHeight,
    210                         IntRect& screenClip, float scale);
    211 
    212     bool setLayersRenderingMode(TexturesResult&);
    213     void fullInval();
    214 
    215     bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
    216                 IntRect& webViewRect, int titleBarHeight,
    217                 IntRect& clip, float scale,
    218                 bool* treesSwappedPtr, bool* newTreeHasAnimPtr);
    219 
    220 #ifdef MEASURES_PERF
    221     void dumpMeasures();
    222 #endif
    223 
    224     void resetFrameworkInval();
    225     void addDirtyArea(const IntRect& rect);
    226     void resetLayersDirtyArea();
    227 
    228     bool goingDown() { return m_goingDown; }
    229     bool goingLeft() { return m_goingLeft; }
    230     void setDirection(bool goingDown, bool goingLeft) {
    231         m_goingDown = goingDown;
    232         m_goingLeft = goingLeft;
    233     }
    234 
    235     int expandedTileBoundsX() { return m_expandedTileBoundsX; }
    236     int expandedTileBoundsY() { return m_expandedTileBoundsY; }
    237     void setHighEndGfx(bool highEnd) { m_highEndGfx = highEnd; }
    238 
    239     float scale() { return m_scale; }
    240 
    241     enum LayersRenderingMode {
    242         kAllTextures              = 0, // all layers are drawn with textures fully covering them
    243         kClippedTextures          = 1, // all layers are drawn, but their textures will be clipped
    244         kScrollableAndFixedLayers = 2, // only scrollable and fixed layers will be drawn
    245         kFixedLayers              = 3, // only fixed layers will be drawn
    246         kSingleSurfaceRendering   = 4  // no layers will be drawn on separate textures
    247                                        // -- everything is drawn on the base surface.
    248     };
    249 
    250     LayersRenderingMode layersRenderingMode() { return m_layersRenderingMode; }
    251     void scrollLayer(int layerId, int x, int y);
    252 
    253     void invalRegion(const SkRegion& region);
    254 
    255 private:
    256     void inval(const IntRect& rect);
    257 
    258     ZoomManager m_zoomManager;
    259     android::Mutex m_tiledPageLock;
    260     SkRect m_viewport;
    261     SkIRect m_viewportTileBounds;
    262     SkIRect m_futureViewportTileBounds;
    263     SkIRect m_preZoomBounds;
    264 
    265     unsigned int m_currentPictureCounter;
    266     bool m_usePageA;
    267     TiledPage* m_tiledPageA;
    268     TiledPage* m_tiledPageB;
    269     IntRect m_lastInval;
    270     IntRect m_frameworkInval;
    271     IntRect m_frameworkLayersInval;
    272 
    273 #ifdef MEASURES_PERF
    274     unsigned int m_totalTimeCounter;
    275     int m_timeCounter;
    276     double m_delayTimes[MAX_MEASURES_PERF];
    277     bool m_measurePerfs;
    278 #endif
    279     GLExtras m_glExtras;
    280 
    281     bool m_isScrolling;
    282     bool m_goingDown;
    283     bool m_goingLeft;
    284 
    285     int m_expandedTileBoundsX;
    286     int m_expandedTileBoundsY;
    287     bool m_highEndGfx;
    288 
    289     float m_scale;
    290 
    291     LayersRenderingMode m_layersRenderingMode;
    292     TreeManager m_treeManager;
    293 };
    294 
    295 } // namespace WebCore
    296 
    297 #endif // USE(ACCELERATED_COMPOSITING)
    298 #endif // GLWebViewState_h
    299