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