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