1/*
2 * Copyright (C) 2009, 2010, 2011, 2012, 2013 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
34namespace WebCore {
35class IntRect;
36class FloatPoint;
37class FloatRect;
38class LayerRenderer;
39class TransformationMatrix;
40}
41
42namespace BlackBerry {
43
44namespace Platform {
45class ViewportAccessor;
46}
47
48namespace WebKit {
49
50class TileBuffer;
51class WebPage;
52class BackingStoreClient;
53
54typedef WTF::HashMap<TileIndex, TileBuffer*> TileMap;
55
56class BackingStoreGeometry {
57public:
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
84private:
85    int m_numberOfTilesWide;
86    int m_numberOfTilesHigh;
87    double m_scale;
88    Platform::IntPoint m_backingStoreOffset;
89    TileMap m_tileMap;
90};
91
92class BackingStorePrivate : public BlackBerry::Platform::GuardedPointerBase {
93public:
94    enum TileMatrixDirection { Horizontal, Vertical };
95    BackingStorePrivate();
96
97    void instrumentBeginFrame();
98    void instrumentCancelFrame();
99
100    // Returns whether we're using the OpenGL code path for compositing the
101    // backing store tiles. This can be due to the main window using
102    // BlackBerry::Platform::Graphics::Window::GLES2Usage.
103    bool isOpenGLCompositing() const;
104
105    // Suspends all backingstore updates so that rendering to the backingstore is disabled.
106    void suspendBackingStoreUpdates();
107
108    // Resumes all backingstore updates so that rendering to the backingstore is enabled.
109    void resumeBackingStoreUpdates();
110
111    // Suspends all backingstore geometry updates.
112    void suspendGeometryUpdates();
113
114    // Resumes all backingstore geometry updates.
115    void resumeGeometryUpdates();
116
117    // Suspends all screen updates so that 'blitVisibleContents' is disabled.
118    void suspendScreenUpdates();
119
120    // Resumes all screen updates so that 'blitVisibleContents' is enabled.
121    void resumeScreenUpdates(BackingStore::ResumeUpdateOperation);
122
123    // Update m_suspendScreenUpdates*Thread based on a number of conditions.
124    void updateSuspendScreenUpdateState(bool* hasSyncedToUserInterfaceThread = 0);
125
126    // The functions repaint(), slowScroll(), scroll(), scrollingStartedHelper() are
127    // called from outside WebKit and within WebKit via ChromeClientBlackBerry.
128    void repaint(const Platform::IntRect& windowRect, bool contentChanged, bool immediate);
129
130    void slowScroll(const Platform::IntSize& delta, const Platform::IntRect& windowRect, bool immediate);
131
132    void scroll(const Platform::IntSize& delta, const Platform::IntRect& scrollViewRect, const Platform::IntRect& clipRect);
133    void scrollingStartedHelper(const Platform::IntSize& delta);
134
135    bool shouldSuppressNonVisibleRegularRenderJobs() const;
136    bool shouldPerformRenderJobs() const;
137    bool shouldPerformRegularRenderJobs() const;
138    void dispatchRenderJob();
139    void renderJob();
140
141    // Various calculations of quantities relevant to backing store.
142    Platform::IntSize expandedContentsSize() const;
143    Platform::IntRect expandedContentsRect() const;
144    Platform::IntRect visibleContentsRect() const;
145
146    void setBackingStoreRect(const Platform::IntRect&, double scale);
147    void updateTilesAfterBackingStoreRectChange();
148
149    TileIndexList indexesForBackingStoreRect(const Platform::IntRect&) const;
150    TileIndexList indexesForVisibleContentsRect(BackingStoreGeometry*) const;
151
152    TileIndex indexOfTile(const Platform::IntPoint& origin, const Platform::IntRect& backingStoreRect) const;
153    void clearAndUpdateTileOfNotRenderedRegion(const TileIndex&, TileBuffer*, const Platform::IntRectRegion&, BackingStoreGeometry*, bool update = true);
154    bool isCurrentVisibleJob(const TileIndex&, BackingStoreGeometry*) const;
155
156    // Not thread safe. Call only when threads are in sync.
157    void clearRenderedRegion(TileBuffer*, const Platform::IntRectRegion&);
158
159    // Responsible for scrolling the backing store and updating the
160    // tile matrix geometry.
161    Platform::IntRect nonOverscrolled(const Platform::IntRect& viewportRect, const Platform::IntRect& contentsRect);
162    Platform::IntRect enclosingTileRect(const Platform::IntRect& pixelContentsRect);
163    Platform::IntRect desiredBackingStoreRect(const Platform::IntRect& pixelViewportRect, const Platform::IntRect& maximumReasonableRect, int deltaX, int deltaY);
164    void mergeDesiredBackingStoreRect(const Platform::IntRect& desiredRect, const Platform::IntRect& pixelViewportForDesiredRect);
165    Platform::IntRect largestTileRectForDesiredRect(const Platform::IntRect& minimumRect, const Platform::IntRect& desiredRect);
166    void scrollBackingStore(int deltaX, int deltaY);
167
168    // Render the given tiles if enough back buffers are available.
169    // Return the actual set of rendered tiles.
170    // NOTE: This should only be called by RenderQueue and resumeScreenUpdates().
171    //   If you want to render to get contents to the screen, you should call
172    //   renderAndBlitImmediately() or renderAndBlitVisibleContentsImmediately().
173    TileIndexList render(const TileIndexList&);
174
175    // Called by the render queue to ensure that the queue is in a
176    // constant state before performing a render job.
177    void requestLayoutIfNeeded() const;
178
179    // Helper render methods.
180    void renderAndBlitVisibleContentsImmediately();
181    void renderAndBlitImmediately(const Platform::IntRect&);
182    void blitVisibleContents(bool force = false);
183    void blitOnIdle();
184
185    Platform::IntRect blitTileRect(TileBuffer*, const Platform::IntRect&, const Platform::IntPoint&, const WebCore::TransformationMatrix&, BackingStoreGeometry*);
186
187#if USE(ACCELERATED_COMPOSITING)
188    // Use instead of blitVisibleContents() if you need more control over
189    // OpenGL state. Note that contents is expressed in untransformed
190    // content coordinates.
191    // Preconditions: You have to call prepareFrame and setViewport on the LayerRenderer before
192    //                calling this.
193    void compositeContents(WebCore::LayerRenderer*, const WebCore::TransformationMatrix&, const WebCore::FloatRect& contents, bool contentsOpaque);
194
195    bool drawLayersOnCommitIfNeeded();
196    // WebPage will call this when drawing layers to tell us we don't need to
197    void willDrawLayersOnCommit() { m_needsDrawLayersOnCommit = false; }
198#endif
199
200    void blitHorizontalScrollbar();
201    void blitVerticalScrollbar();
202
203    // Returns whether the tile index is currently visible or not.
204    bool isTileVisible(const TileIndex&, BackingStoreGeometry*) const;
205    bool isTileVisible(const Platform::IntPoint&) const;
206
207    // Returns a rect that is the union of all tiles that are visible.
208    TileIndexList visibleTileIndexes(BackingStoreGeometry*) const;
209
210    // Used to clip to the visible content for instance.
211    Platform::IntRect tileVisibleContentsRect(const TileIndex&, BackingStoreGeometry*) const;
212
213    // Used to clip to the contents for instance.
214    Platform::IntRect tileContentsRect(const TileIndex&, const Platform::IntRect&, BackingStoreGeometry*) const;
215
216    // This is called by WebPage once load is committed to reset the render queue.
217    void resetRenderQueue();
218
219    // This is called by WebPage once load is committed to reset all the tiles.
220    void resetTiles();
221
222    // This is called by WebPage after load is complete to update all the tiles.
223    void updateTiles(bool updateVisible, bool immediate);
224
225    // This is called during scroll and by the render queue.
226    void updateTilesForScrollOrNotRenderedRegion(bool checkLoading = true);
227
228    // Update an individual tile.
229    void updateTile(const Platform::IntPoint& tileOrigin, bool immediate);
230
231    typedef std::pair<TileIndex, Platform::IntRect> TileRect;
232    typedef WTF::Vector<TileRect> TileRectList;
233    TileRectList mapFromPixelContentsToTiles(const Platform::IntRect&, BackingStoreGeometry*) const;
234
235    void setTileMatrixNeedsUpdate() { m_tileMatrixNeedsUpdate = true; }
236    void updateTileMatrixIfNeeded();
237
238    // Called by WebPagePrivate::notifyTransformedContentsSizeChanged.
239    void contentsSizeChanged(const Platform::IntSize&);
240
241    // Called by WebPagePrivate::notifyTransformedScrollChanged.
242    void scrollChanged(const Platform::IntPoint&);
243
244    // Called by WebpagePrivate::notifyTransformChanged.
245    void transformChanged();
246
247    // Called by WebpagePrivate::actualVisibleSizeChanged.
248    void actualVisibleSizeChanged(const Platform::IntSize&);
249
250    // Called by WebPagePrivate::setScreenRotated.
251    void orientationChanged();
252
253    // Sets the geometry of the tile matrix.
254    void setGeometryOfTileMatrix(int numberOfTilesWide, int numberOfTilesHigh);
255
256    // Create the surfaces of the backing store.
257    void createSurfaces();
258
259    // The tile geometry methods are all static function.
260    static int tileWidth();
261    static int tileHeight();
262    static Platform::IntSize tileSize();
263
264    // This takes transformed contents coordinates.
265    enum LayersToRender { RenderRootLayer, RenderAllLayers };
266    bool renderContents(BlackBerry::Platform::Graphics::Buffer*, const BlackBerry::Platform::IntRect& dstRect, double scale, const BlackBerry::Platform::FloatPoint& documentScrollPosition, LayersToRender) const;
267
268    void blitToWindow(const Platform::IntRect& dstRect, const BlackBerry::Platform::Graphics::Buffer* srcBuffer, const Platform::IntRect& srcRect, BlackBerry::Platform::Graphics::BlendMode, unsigned char globalAlpha);
269
270    WebCore::Color webPageBackgroundColorUserInterfaceThread() const; // use WebSettings::backgroundColor() for the WebKit thread
271    void setWebPageBackgroundColor(const WebCore::Color&);
272
273    bool isScrollingOrZooming() const;
274    void setScrollingOrZooming(bool scrollingOrZooming, bool shouldBlit = true);
275
276    BackingStoreGeometry* frontState() const;
277    void adoptAsFrontState(BackingStoreGeometry* newFrontState);
278
279    static void setCurrentBackingStoreOwner(WebPage*);
280    static WebPage* currentBackingStoreOwner() { return BackingStorePrivate::s_currentBackingStoreOwner; }
281    bool isActive() const;
282
283    // Surface abstraction, maybe BlackBerry::Platform::Graphics::Buffer could be made public instead.
284    BlackBerry::Platform::IntSize surfaceSize() const;
285    BlackBerry::Platform::Graphics::Buffer* buffer() const;
286
287    void didRenderContent(const Platform::IntRectRegion& renderedRegion);
288
289    static WebPage* s_currentBackingStoreOwner;
290
291    unsigned m_suspendScreenUpdateCounterWebKitThread;
292    unsigned m_suspendBackingStoreUpdates;
293    unsigned m_suspendGeometryUpdates;
294    BackingStore::ResumeUpdateOperation m_resumeOperation;
295
296    bool m_suspendScreenUpdatesWebKitThread;
297    bool m_suspendScreenUpdatesUserInterfaceThread;
298    bool m_suspendRenderJobs;
299    bool m_suspendRegularRenderJobs;
300    bool m_tileMatrixContainsUsefulContent;
301    bool m_tileMatrixNeedsUpdate;
302    bool m_isScrollingOrZooming;
303    WebPage* m_webPage;
304    BackingStoreClient* m_client;
305    OwnPtr<RenderQueue> m_renderQueue;
306
307    bool m_hasBlitJobs;
308
309    WebCore::Color m_webPageBackgroundColor; // for user interface thread operations such as blitting
310
311    mutable unsigned m_frontState;
312
313    Platform::IntRect m_desiredBackingStoreRect;
314    Platform::IntPoint m_desiredBackingStoreRectViewportLocation;
315    double m_desiredBackingStoreRectScale;
316
317#if USE(ACCELERATED_COMPOSITING)
318    mutable bool m_needsDrawLayersOnCommit; // Not thread safe, WebKit thread only
319#endif
320
321protected:
322    virtual ~BackingStorePrivate();
323};
324} // namespace WebKit
325} // namespace BlackBerry
326
327#endif // BackingStore_p_h
328