[BlackBerry] Fix all flicker caused by empty/incomplete geometries.
[WebKit-https.git] / Source / WebKit / blackberry / Api / BackingStore_p.h
1 /*
2  * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #ifndef BackingStore_p_h
20 #define BackingStore_p_h
21
22 #include "BackingStore.h"
23 #include "Color.h"
24 #include "RenderQueue.h"
25 #include "TileIndex.h"
26 #include "TileIndexHash.h"
27 #include "Timer.h"
28 #include <BlackBerryPlatformGraphics.h>
29 #include <BlackBerryPlatformGuardedPointer.h>
30 #include <pthread.h>
31 #include <wtf/HashMap.h>
32 #include <wtf/Vector.h>
33
34 namespace WebCore {
35 class IntRect;
36 class FloatPoint;
37 class FloatRect;
38 class LayerRenderer;
39 class TransformationMatrix;
40 }
41
42 namespace BlackBerry {
43
44 namespace Platform {
45 class ViewportAccessor;
46 }
47
48 namespace WebKit {
49
50 class TileBuffer;
51 class WebPage;
52 class BackingStoreClient;
53
54 typedef WTF::HashMap<TileIndex, TileBuffer*> TileMap;
55
56 class BackingStoreGeometry {
57 public:
58     BackingStoreGeometry()
59         : m_numberOfTilesWide(0)
60         , m_numberOfTilesHigh(0)
61         , m_scale(0.0)
62     {
63     }
64
65     Platform::IntRect backingStoreRect() const;
66     Platform::IntSize backingStoreSize() const;
67
68     int numberOfTilesWide() const { return m_numberOfTilesWide; }
69     void setNumberOfTilesWide(int numberOfTilesWide) { m_numberOfTilesWide = numberOfTilesWide; }
70     int numberOfTilesHigh() const { return m_numberOfTilesHigh; }
71     void setNumberOfTilesHigh(int numberOfTilesHigh) { m_numberOfTilesHigh = numberOfTilesHigh; }
72     Platform::IntPoint backingStoreOffset() const { return m_backingStoreOffset; }
73     void setBackingStoreOffset(const Platform::IntPoint& offset) { m_backingStoreOffset = offset; }
74     Platform::IntPoint originOfTile(const TileIndex&) const;
75     TileBuffer* tileBufferAt(const TileIndex& index) const { return m_tileMap.get(index); }
76     const TileMap& tileMap() const { return m_tileMap; }
77     void setTileMap(const TileMap& tileMap) { m_tileMap = tileMap; }
78
79     double scale() const { return m_scale; }
80     void setScale(double scale) { m_scale = scale; }
81
82     bool isTileCorrespondingToBuffer(TileIndex, TileBuffer*) const;
83
84   private:
85     int m_numberOfTilesWide;
86     int m_numberOfTilesHigh;
87     double m_scale;
88     Platform::IntPoint m_backingStoreOffset;
89     TileMap m_tileMap;
90 };
91
92 class BackingStoreWindowBufferState {
93 public:
94     Platform::IntRectRegion blittedRegion() const { return m_blittedRegion; }
95     void addBlittedRegion(const Platform::IntRectRegion& region)
96     {
97         m_blittedRegion = Platform::IntRectRegion::unionRegions(m_blittedRegion, region);
98     }
99     void clearBlittedRegion(const Platform::IntRectRegion& region)
100     {
101         m_blittedRegion = Platform::IntRectRegion::subtractRegions(m_blittedRegion, region);
102     }
103     void clearBlittedRegion() { m_blittedRegion = Platform::IntRectRegion(); }
104
105     bool isRendered(const Platform::IntPoint& scrollPosition, const Platform::IntRectRegion& contents) const
106     {
107         return Platform::IntRectRegion::subtractRegions(contents, m_blittedRegion).isEmpty();
108     }
109
110   private:
111     Platform::IntRectRegion m_blittedRegion;
112 };
113
114 class BackingStorePrivate : public BlackBerry::Platform::GuardedPointerBase {
115 public:
116     enum TileMatrixDirection { Horizontal, Vertical };
117     BackingStorePrivate();
118
119     void instrumentBeginFrame();
120     void instrumentCancelFrame();
121
122     // Returns whether direct rendering is explicitly turned on or is
123     // required because the surface pool is not large enough to meet
124     // the minimum number of tiles required to scroll.
125     bool shouldDirectRenderingToWindow() const;
126
127     // Returns whether we're using the OpenGL code path for compositing the
128     // backing store tiles. This can be due to the main window using
129     // BlackBerry::Platform::Graphics::Window::GLES2Usage.
130     bool isOpenGLCompositing() const;
131
132     // Suspends all backingstore updates so that rendering to the backingstore is disabled.
133     void suspendBackingStoreUpdates();
134
135     // Resumes all backingstore updates so that rendering to the backingstore is enabled.
136     void resumeBackingStoreUpdates();
137
138     // Suspends all screen updates so that 'blitVisibleContents' is disabled.
139     void suspendScreenUpdates();
140
141     // Resumes all screen updates so that 'blitVisibleContents' is enabled.
142     void resumeScreenUpdates(BackingStore::ResumeUpdateOperation);
143
144     // Update m_suspendScreenUpdates*Thread based on a number of conditions.
145     void updateSuspendScreenUpdateState();
146
147     // The functions repaint(), slowScroll(), scroll(), scrollingStartedHelper() are
148     // called from outside WebKit and within WebKit via ChromeClientBlackBerry.
149     void repaint(const Platform::IntRect& windowRect, bool contentChanged, bool immediate);
150
151     void slowScroll(const Platform::IntSize& delta, const Platform::IntRect& windowRect, bool immediate);
152
153     void scroll(const Platform::IntSize& delta, const Platform::IntRect& scrollViewRect, const Platform::IntRect& clipRect);
154     void scrollingStartedHelper(const Platform::IntSize& delta);
155
156     bool shouldSuppressNonVisibleRegularRenderJobs() const;
157     bool shouldPerformRenderJobs() const;
158     bool shouldPerformRegularRenderJobs() const;
159     void dispatchRenderJob();
160     void renderJob();
161
162     // Set of helper methods for the scrollBackingStore() method.
163     Platform::IntRect contentsRect() const;
164     Platform::IntRect expandedContentsRect() const;
165     Platform::IntRect visibleContentsRect() const;
166     Platform::IntRect unclippedVisibleContentsRect() const;
167     bool shouldMoveLeft(const Platform::IntRect&) const;
168     bool shouldMoveRight(const Platform::IntRect&) const;
169     bool shouldMoveUp(const Platform::IntRect&) const;
170     bool shouldMoveDown(const Platform::IntRect&) const;
171     bool canMoveX(const Platform::IntRect&) const;
172     bool canMoveY(const Platform::IntRect&) const;
173     bool canMoveLeft(const Platform::IntRect&) const;
174     bool canMoveRight(const Platform::IntRect&) const;
175     bool canMoveUp(const Platform::IntRect&) const;
176     bool canMoveDown(const Platform::IntRect&) const;
177
178     Platform::IntRect backingStoreRectForScroll(int deltaX, int deltaY, const Platform::IntRect&) const;
179     void setBackingStoreRect(const Platform::IntRect&, double scale);
180     void updateTilesAfterBackingStoreRectChange();
181
182     TileIndexList indexesForBackingStoreRect(const Platform::IntRect&) const;
183     TileIndexList indexesForVisibleContentsRect(BackingStoreGeometry*) const;
184
185     TileIndex indexOfTile(const Platform::IntPoint& origin, const Platform::IntRect& backingStoreRect) const;
186     void clearAndUpdateTileOfNotRenderedRegion(const TileIndex&, TileBuffer*, const Platform::IntRectRegion&, BackingStoreGeometry*, bool update = true);
187     bool isCurrentVisibleJob(const TileIndex&, BackingStoreGeometry*) const;
188
189     // Not thread safe. Call only when threads are in sync.
190     void clearRenderedRegion(TileBuffer*, const Platform::IntRectRegion&);
191
192     // Responsible for scrolling the backing store and updating the
193     // tile matrix geometry.
194     void scrollBackingStore(int deltaX, int deltaY);
195
196     // Render the given dirty rect and invalidate the screen.
197     Platform::IntRect renderDirectToWindow(const Platform::IntRect&);
198
199     // Render the given tiles if enough back buffers are available.
200     // Return the actual set of rendered tiles.
201     // NOTE: This should only be called by RenderQueue and resumeScreenUpdates().
202     //   If you want to render to get contents to the screen, you should call
203     //   renderAndBlitImmediately() or renderAndBlitVisibleContentsImmediately().
204     TileIndexList render(const TileIndexList&);
205
206     // Called by the render queue to ensure that the queue is in a
207     // constant state before performing a render job.
208     void requestLayoutIfNeeded() const;
209
210     // Helper render methods.
211     void renderAndBlitVisibleContentsImmediately();
212     void renderAndBlitImmediately(const Platform::IntRect&);
213     void blitVisibleContents(bool force = false);
214
215     // Assumes the rect to be in window/viewport coordinates.
216     void copyPreviousContentsToBackSurfaceOfWindow();
217     void copyPreviousContentsToTileBuffer(const Platform::IntRect& excludeRect, TileBuffer* dstTileBuffer, TileBuffer* srcTileBuffer);
218     void paintDefaultBackground(const Platform::IntRect& dstRect, BlackBerry::Platform::ViewportAccessor*, bool flush);
219     void blitOnIdle();
220
221     Platform::IntRect blitTileRect(TileBuffer*, const Platform::IntRect&, const Platform::IntPoint&, const WebCore::TransformationMatrix&, BackingStoreGeometry*);
222
223 #if USE(ACCELERATED_COMPOSITING)
224     // Use instead of blitVisibleContents() if you need more control over
225     // OpenGL state. Note that contents is expressed in untransformed
226     // content coordinates.
227     // Preconditions: You have to call prepareFrame and setViewport on the LayerRenderer before
228     //                calling this.
229     void compositeContents(WebCore::LayerRenderer*, const WebCore::TransformationMatrix&, const WebCore::FloatRect& contents, bool contentsOpaque);
230
231     bool drawLayersOnCommitIfNeeded();
232     void drawAndBlendLayersForDirectRendering(const Platform::IntRect& dirtyRect);
233     // WebPage will call this when drawing layers to tell us we don't need to
234     void willDrawLayersOnCommit() { m_needsDrawLayersOnCommit = false; }
235     // WebPageCompositor uses this to cut down on excessive message sending.
236     bool isDirectRenderingAnimationMessageScheduled() { return m_isDirectRenderingAnimationMessageScheduled; }
237     void setDirectRenderingAnimationMessageScheduled() { m_isDirectRenderingAnimationMessageScheduled = true; }
238 #endif
239
240     void blitHorizontalScrollbar();
241     void blitVerticalScrollbar();
242
243     // Returns whether the tile index is currently visible or not.
244     bool isTileVisible(const TileIndex&, BackingStoreGeometry*) const;
245     bool isTileVisible(const Platform::IntPoint&) const;
246
247     // Returns a rect that is the union of all tiles that are visible.
248     TileIndexList visibleTileIndexes(BackingStoreGeometry*) const;
249
250     // Used to clip to the visible content for instance.
251     Platform::IntRect tileVisibleContentsRect(const TileIndex&, BackingStoreGeometry*) const;
252
253     // Used to clip to the contents for instance.
254     Platform::IntRect tileContentsRect(const TileIndex&, const Platform::IntRect&, BackingStoreGeometry*) const;
255
256     // This is called by WebPage once load is committed to reset the render queue.
257     void resetRenderQueue();
258
259     // This is called by WebPage once load is committed to reset all the tiles.
260     void resetTiles();
261
262     // This is called by WebPage after load is complete to update all the tiles.
263     void updateTiles(bool updateVisible, bool immediate);
264
265     // This is called during scroll and by the render queue.
266     void updateTilesForScrollOrNotRenderedRegion(bool checkLoading = true);
267
268     // Update an individual tile.
269     void updateTile(const Platform::IntPoint& tileOrigin, bool immediate);
270
271     typedef std::pair<TileIndex, Platform::IntRect> TileRect;
272     typedef WTF::Vector<TileRect> TileRectList;
273     TileRectList mapFromPixelContentsToTiles(const Platform::IntRect&, BackingStoreGeometry*) const;
274
275     void setTileMatrixNeedsUpdate() { m_tileMatrixNeedsUpdate = true; }
276     void updateTileMatrixIfNeeded();
277
278     // Called by WebPagePrivate::notifyTransformedContentsSizeChanged.
279     void contentsSizeChanged(const Platform::IntSize&);
280
281     // Called by WebPagePrivate::notifyTransformedScrollChanged.
282     void scrollChanged(const Platform::IntPoint&);
283
284     // Called by WebpagePrivate::notifyTransformChanged.
285     void transformChanged();
286
287     // Called by WebpagePrivate::actualVisibleSizeChanged.
288     void actualVisibleSizeChanged(const Platform::IntSize&);
289
290     // Called by WebPagePrivate::setScreenRotated.
291     void orientationChanged();
292
293     // Sets the geometry of the tile matrix.
294     void setGeometryOfTileMatrix(int numberOfTilesWide, int numberOfTilesHigh);
295
296     // Create the surfaces of the backing store.
297     void createSurfaces();
298
299     // Various calculations of quantities relevant to backing store.
300     int minimumNumberOfTilesWide() const;
301     int minimumNumberOfTilesHigh() const;
302     Platform::IntSize expandedContentsSize() const;
303
304     // The tile geometry methods are all static function.
305     static int tileWidth();
306     static int tileHeight();
307     static Platform::IntSize tileSize();
308
309     // This takes transformed contents coordinates.
310     bool renderContents(BlackBerry::Platform::Graphics::Buffer*, const BlackBerry::Platform::IntRect& dstRect, double scale, const BlackBerry::Platform::FloatPoint& documentScrollPosition) const;
311
312     void blitToWindow(const Platform::IntRect& dstRect, const BlackBerry::Platform::Graphics::Buffer* srcBuffer, const Platform::IntRect& srcRect, BlackBerry::Platform::Graphics::BlendMode, unsigned char globalAlpha);
313     void fillWindow(Platform::Graphics::FillPattern, const Platform::IntRect& dstRect, const Platform::IntPoint& contentsOrigin, double contentsScale);
314
315     WebCore::Color webPageBackgroundColorUserInterfaceThread() const; // use WebSettings::backgroundColor() for the WebKit thread
316     void setWebPageBackgroundColor(const WebCore::Color&);
317
318     void invalidateWindow();
319     void invalidateWindow(const Platform::IntRect& dst);
320     void clearWindow(const Platform::IntRect&, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha = 255);
321
322     bool isScrollingOrZooming() const;
323     void setScrollingOrZooming(bool scrollingOrZooming, bool shouldBlit = true);
324
325     void lockBackingStore();
326     void unlockBackingStore();
327
328     BackingStoreGeometry* frontState() const;
329     void adoptAsFrontState(BackingStoreGeometry* newFrontState);
330
331     BackingStoreWindowBufferState* windowFrontBufferState() const;
332     BackingStoreWindowBufferState* windowBackBufferState() const;
333
334     static void setCurrentBackingStoreOwner(WebPage*);
335     static WebPage* currentBackingStoreOwner() { return BackingStorePrivate::s_currentBackingStoreOwner; }
336     bool isActive() const;
337
338     // Surface abstraction, maybe BlackBerry::Platform::Graphics::Buffer could be made public instead.
339     BlackBerry::Platform::IntSize surfaceSize() const;
340     BlackBerry::Platform::Graphics::Buffer* buffer() const;
341
342     void didRenderContent(const Platform::IntRectRegion& renderedRegion);
343
344     static WebPage* s_currentBackingStoreOwner;
345
346     unsigned m_suspendScreenUpdateCounterWebKitThread;
347     unsigned m_suspendBackingStoreUpdates;
348     BackingStore::ResumeUpdateOperation m_resumeOperation;
349
350     bool m_suspendScreenUpdatesWebKitThread;
351     bool m_suspendScreenUpdatesUserInterfaceThread;
352     bool m_suspendRenderJobs;
353     bool m_suspendRegularRenderJobs;
354     bool m_tileMatrixContainsUsefulContent;
355     bool m_tileMatrixNeedsUpdate;
356     bool m_isScrollingOrZooming;
357     WebPage* m_webPage;
358     BackingStoreClient* m_client;
359     OwnPtr<RenderQueue> m_renderQueue;
360     mutable Platform::IntSize m_previousDelta;
361
362     bool m_hasBlitJobs;
363
364     WebCore::Color m_webPageBackgroundColor; // for user interface thread operations such as blitting
365
366     mutable unsigned m_frontState;
367
368     unsigned m_currentWindowBackBuffer;
369     mutable BackingStoreWindowBufferState m_windowBufferState[2];
370
371     TileMatrixDirection m_preferredTileMatrixDimension;
372
373     Platform::IntRect m_visibleTileBufferRect;
374
375     pthread_mutex_t m_mutex;
376
377 #if USE(ACCELERATED_COMPOSITING)
378     mutable bool m_needsDrawLayersOnCommit; // Not thread safe, WebKit thread only
379     bool m_isDirectRenderingAnimationMessageScheduled;
380 #endif
381
382 protected:
383     virtual ~BackingStorePrivate();
384 };
385 } // namespace WebKit
386 } // namespace BlackBerry
387
388 #endif // BackingStore_p_h