summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/Android.derived.v8bindings.mk2
-rw-r--r--Source/WebCore/Android.mk114
-rw-r--r--Source/WebCore/WebCore.exp.in1
-rw-r--r--Source/WebCore/css/CSSParser.cpp2
-rw-r--r--Source/WebCore/css/CSSPrimitiveValue.cpp3
-rw-r--r--Source/WebCore/css/CSSStyleSelector.cpp8
-rw-r--r--Source/WebCore/css/WebKitCSSKeyframesRule.cpp3
-rw-r--r--Source/WebCore/dom/Document.cpp2
-rw-r--r--Source/WebCore/dom/Node.cpp12
-rw-r--r--Source/WebCore/dom/Node.h4
-rw-r--r--Source/WebCore/dom/Range.cpp15
-rw-r--r--Source/WebCore/editing/ApplyStyleCommand.cpp6
-rw-r--r--Source/WebCore/editing/CompositeEditCommand.cpp2
-rw-r--r--Source/WebCore/fileapi/DOMFileSystemBase.cpp2
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in1
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp6
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h4
-rw-r--r--Source/WebCore/html/HTMLElement.cpp5
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp20
-rw-r--r--Source/WebCore/html/HTMLInputElement.h4
-rw-r--r--Source/WebCore/html/HTMLInputElement.idl3
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp19
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h2
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.h5
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp3
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp2
-rw-r--r--Source/WebCore/page/EventHandler.cpp8
-rw-r--r--Source/WebCore/page/FrameView.cpp5
-rw-r--r--Source/WebCore/page/Location.cpp18
-rw-r--r--Source/WebCore/page/Location.h4
-rw-r--r--Source/WebCore/page/Settings.cpp10
-rw-r--r--Source/WebCore/page/Settings.h8
-rw-r--r--Source/WebCore/platform/FileChooser.h7
-rw-r--r--Source/WebCore/platform/KURL.cpp43
-rw-r--r--Source/WebCore/platform/KURL.h4
-rw-r--r--Source/WebCore/platform/KURLGoogle.cpp17
-rw-r--r--Source/WebCore/platform/PlatformTouchEvent.h4
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.cpp18
-rw-r--r--Source/WebCore/platform/graphics/Font.h6
-rw-r--r--Source/WebCore/platform/graphics/FontPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/Gradient.cpp2
-rw-r--r--Source/WebCore/platform/graphics/Gradient.h8
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.cpp4
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h6
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp298
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.h92
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp301
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h76
-rw-r--r--Source/WebCore/platform/graphics/android/GradientAndroid.cpp127
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp1295
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp15
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/ImageAndroid.cpp74
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp102
-rw-r--r--Source/WebCore/platform/graphics/android/PerformanceMonitor.h59
-rw-r--r--Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp51
-rw-r--r--Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h57
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollection.cpp270
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp382
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.h133
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.cpp407
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.h145
-rw-r--r--Source/WebCore/platform/graphics/android/ZoomManager.cpp185
-rw-r--r--Source/WebCore/platform/graphics/android/ZoomManager.h118
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp663
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.h809
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp63
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h72
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp456
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h204
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp373
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h128
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp606
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h115
-rw-r--r--Source/WebCore/platform/graphics/android/context/android_graphics.h (renamed from Source/WebCore/platform/graphics/android/android_graphics.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/FontAndroid.cpp)10
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontCustomPlatformData.cpp (renamed from Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontCustomPlatformData.h (renamed from Source/WebCore/platform/graphics/android/FontCustomPlatformData.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontDataAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/FontDataAndroid.cpp)8
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h (renamed from Source/WebCore/platform/graphics/android/FontPlatformData.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontPlatformDataAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp)45
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/HarfbuzzSkia.cpp (renamed from Source/WebCore/platform/graphics/android/HarfbuzzSkia.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/HarfbuzzSkia.h (renamed from Source/WebCore/platform/graphics/android/HarfbuzzSkia.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/VerticalTextMap.cpp (renamed from Source/WebCore/platform/graphics/android/VerticalTextMap.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/VerticalTextMap.h (renamed from Source/WebCore/platform/graphics/android/VerticalTextMap.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/AndroidAnimation.cpp (renamed from Source/WebCore/platform/graphics/android/AndroidAnimation.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/AndroidAnimation.h (renamed from Source/WebCore/platform/graphics/android/AndroidAnimation.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp69
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h61
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp220
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasLayer.h81
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp225
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasTexture.h95
-rw-r--r--Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp (renamed from Source/WebCore/platform/graphics/android/DumpLayer.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/DumpLayer.h (renamed from Source/WebCore/platform/graphics/android/DumpLayer.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp (renamed from Source/WebCore/platform/graphics/android/FixedPositioning.cpp)1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/FixedPositioning.h (renamed from Source/WebCore/platform/graphics/android/FixedPositioning.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/IFrameLayerAndroid.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/Layer.cpp (renamed from Source/WebCore/platform/graphics/android/Layer.cpp)5
-rw-r--r--Source/WebCore/platform/graphics/android/layers/Layer.h (renamed from Source/WebCore/platform/graphics/android/Layer.h)8
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/LayerAndroid.cpp)161
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/LayerAndroid.h)43
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerContent.h (renamed from Source/WebCore/platform/graphics/android/LayerContent.h)5
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp (renamed from Source/WebCore/platform/graphics/android/MediaLayer.cpp)4
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaLayer.h (renamed from Source/WebCore/platform/graphics/android/MediaLayer.h)2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaListener.h (renamed from Source/WebCore/platform/graphics/android/MediaListener.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h (renamed from Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaTexture.cpp (renamed from Source/WebCore/platform/graphics/android/MediaTexture.cpp)40
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaTexture.h (renamed from Source/WebCore/platform/graphics/android/MediaTexture.h)3
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp (renamed from Source/WebCore/platform/graphics/android/PictureLayerContent.cpp)3
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h (renamed from Source/WebCore/platform/graphics/android/PictureLayerContent.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp (renamed from Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp)10
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h (renamed from Source/WebCore/platform/graphics/android/PictureSetLayerContent.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h)2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp)49
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/VideoLayerAndroid.h)1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp (renamed from Source/WebCore/platform/graphics/android/VideoLayerManager.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h (renamed from Source/WebCore/platform/graphics/android/VideoLayerManager.h)1
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp (renamed from Source/WebCore/platform/graphics/android/BaseRenderer.cpp)86
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h (renamed from Source/WebCore/platform/graphics/android/BaseRenderer.h)21
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h172
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp (renamed from Source/WebCore/platform/graphics/android/GLExtras.cpp)11
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLExtras.h (renamed from Source/WebCore/platform/graphics/android/GLExtras.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp (renamed from Source/WebCore/platform/graphics/android/GLUtils.cpp)91
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLUtils.h (renamed from Source/WebCore/platform/graphics/android/GLUtils.h)10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshContext.cpp (renamed from Source/WebCore/platform/graphics/android/GaneshContext.cpp)27
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshContext.h (renamed from Source/WebCore/platform/graphics/android/GaneshContext.h)6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp (renamed from Source/WebCore/platform/graphics/android/GaneshRenderer.cpp)35
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h (renamed from Source/WebCore/platform/graphics/android/GaneshRenderer.h)4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp (renamed from Source/WebCore/platform/graphics/android/ImageTexture.cpp)42
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.h (renamed from Source/WebCore/platform/graphics/android/ImageTexture.h)13
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImagesManager.cpp (renamed from Source/WebCore/platform/graphics/android/ImagesManager.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImagesManager.h (renamed from Source/WebCore/platform/graphics/android/ImagesManager.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/InspectorCanvas.cpp (renamed from Source/WebCore/platform/graphics/android/InspectorCanvas.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/InspectorCanvas.h (renamed from Source/WebCore/platform/graphics/android/InspectorCanvas.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp (renamed from Source/WebCore/platform/graphics/android/PaintTileOperation.cpp)30
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h (renamed from Source/WebCore/platform/graphics/android/PaintTileOperation.h)9
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h (renamed from Source/WebCore/platform/graphics/android/QueuedOperation.h)22
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp (renamed from Source/WebCore/platform/graphics/android/RasterRenderer.cpp)49
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h (renamed from Source/WebCore/platform/graphics/android/RasterRenderer.h)2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp (renamed from Source/WebCore/platform/graphics/android/ShaderProgram.cpp)291
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h (renamed from Source/WebCore/platform/graphics/android/ShaderProgram.h)91
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp (renamed from Source/WebCore/platform/graphics/android/LayerGroup.cpp)205
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.h (renamed from Source/WebCore/platform/graphics/android/LayerGroup.h)53
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp196
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h93
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp242
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h (renamed from Source/WebCore/platform/graphics/android/SurfaceCollection.h)24
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp (renamed from Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp)126
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h (renamed from Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h)15
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TextureInfo.cpp (renamed from Source/WebCore/platform/graphics/android/TextureInfo.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TextureInfo.h (renamed from Source/WebCore/platform/graphics/android/TextureInfo.h)1
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TextureOwner.h (renamed from Source/WebCore/platform/graphics/android/TextureOwner.h)8
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp (renamed from Source/WebCore/platform/graphics/android/TexturesGenerator.cpp)21
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h (renamed from Source/WebCore/platform/graphics/android/TexturesGenerator.h)19
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.cpp (renamed from Source/WebCore/platform/graphics/android/BaseTile.cpp)112
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h (renamed from Source/WebCore/platform/graphics/android/BaseTile.h)50
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp383
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.h89
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilePainter.h (renamed from Source/WebCore/platform/graphics/android/TilePainter.h)5
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp (renamed from Source/WebCore/platform/graphics/android/BaseTileTexture.cpp)70
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileTexture.h (renamed from Source/WebCore/platform/graphics/android/BaseTileTexture.h)38
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp (renamed from Source/WebCore/platform/graphics/android/TilesManager.cpp)101
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.h (renamed from Source/WebCore/platform/graphics/android/TilesManager.h)70
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesProfiler.cpp (renamed from Source/WebCore/platform/graphics/android/TilesProfiler.cpp)17
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesProfiler.h (renamed from Source/WebCore/platform/graphics/android/TilesProfiler.h)14
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp (renamed from Source/WebCore/platform/graphics/android/TransferQueue.cpp)121
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h (renamed from Source/WebCore/platform/graphics/android/TransferQueue.h)34
-rw-r--r--Source/WebCore/platform/graphics/android/utils/ClassTracker.cpp (renamed from Source/WebCore/platform/graphics/android/ClassTracker.cpp)0
-rw-r--r--Source/WebCore/platform/graphics/android/utils/ClassTracker.h (renamed from Source/WebCore/platform/graphics/android/ClassTracker.h)0
-rw-r--r--Source/WebCore/platform/graphics/android/utils/TestExport.h (renamed from Source/WebCore/platform/graphics/android/TestExport.h)0
-rw-r--r--Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp4
-rw-r--r--Source/WebCore/platform/qt/KURLQt.cpp1
-rw-r--r--Source/WebCore/platform/win/ClipboardWin.cpp2
-rw-r--r--Source/WebCore/plugins/android/PluginViewAndroid.cpp5
-rw-r--r--Source/WebCore/rendering/RenderBlock.cpp31
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp2
-rw-r--r--Source/WebCore/rendering/RenderBox.h2
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.cpp7
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.h3
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.cpp431
-rw-r--r--Source/WebCore/rendering/RenderFrame.cpp16
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp4
-rw-r--r--Source/WebCore/rendering/RenderObject.cpp4
-rw-r--r--Source/WebCore/rendering/RenderObject.h6
-rw-r--r--Source/WebCore/rendering/RenderReplaced.cpp8
-rw-r--r--Source/WebCore/rendering/RenderReplaced.h2
-rw-r--r--Source/WebCore/rendering/RenderWidget.cpp4
-rw-r--r--Source/WebCore/workers/WorkerLocation.cpp7
-rw-r--r--Source/WebCore/workers/WorkerLocation.h4
198 files changed, 7213 insertions, 5713 deletions
diff --git a/Source/WebCore/Android.derived.v8bindings.mk b/Source/WebCore/Android.derived.v8bindings.mk
index 546cefe..509d21e 100644
--- a/Source/WebCore/Android.derived.v8bindings.mk
+++ b/Source/WebCore/Android.derived.v8bindings.mk
@@ -31,7 +31,7 @@ js_binding_scripts := \
$(LOCAL_PATH)/bindings/scripts/generate-bindings.pl
# Add ACCELERATED_COMPOSITING=1 and ENABLE_3D_RENDERING=1 for layers support
-FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 ENABLE_DEVICE_ORIENTATION=1 ENABLE_FILE_READER=1 ENABLE_BLOB=1 ENABLE_WEB_TIMING=1
+FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 ENABLE_DEVICE_ORIENTATION=1 ENABLE_FILE_READER=1 ENABLE_BLOB=1 ENABLE_WEB_TIMING=1 ENABLE_MEDIA_CAPTURE=1
# The defines above should be identical to those for JSC.
FEATURE_DEFINES += V8_BINDING
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index 816b163..794a4a8 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -633,66 +633,73 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/StringTruncator.cpp \
platform/graphics/WidthIterator.cpp \
\
- platform/graphics/android/AndroidAnimation.cpp \
- platform/graphics/android/BaseLayerAndroid.cpp \
- platform/graphics/android/BaseRenderer.cpp \
- platform/graphics/android/BaseTile.cpp \
- platform/graphics/android/BaseTileTexture.cpp \
platform/graphics/android/BitmapAllocatorAndroid.cpp \
- platform/graphics/android/ClassTracker.cpp \
- platform/graphics/android/DumpLayer.cpp \
- platform/graphics/android/FixedPositioning.cpp \
- platform/graphics/android/FontAndroid.cpp \
- platform/graphics/android/FontCacheAndroid.cpp \
- platform/graphics/android/FontCustomPlatformData.cpp \
- platform/graphics/android/FontDataAndroid.cpp \
- platform/graphics/android/FontPlatformDataAndroid.cpp \
- platform/graphics/android/GaneshContext.cpp \
- platform/graphics/android/GaneshRenderer.cpp \
- platform/graphics/android/GLExtras.cpp \
- platform/graphics/android/GLUtils.cpp \
- platform/graphics/android/GLWebViewState.cpp \
- platform/graphics/android/GlyphMapAndroid.cpp \
- platform/graphics/android/GradientAndroid.cpp \
- platform/graphics/android/GraphicsContextAndroid.cpp \
platform/graphics/android/GraphicsLayerAndroid.cpp \
- platform/graphics/android/IFrameContentLayerAndroid.cpp \
- platform/graphics/android/IFrameLayerAndroid.cpp \
+ platform/graphics/android/GLWebViewState.cpp \
platform/graphics/android/ImageAndroid.cpp \
platform/graphics/android/ImageBufferAndroid.cpp \
platform/graphics/android/ImageSourceAndroid.cpp \
- platform/graphics/android/ImagesManager.cpp \
- platform/graphics/android/ImageTexture.cpp \
- platform/graphics/android/InspectorCanvas.cpp \
- platform/graphics/android/Layer.cpp \
- platform/graphics/android/LayerAndroid.cpp \
- platform/graphics/android/LayerGroup.cpp \
- platform/graphics/android/MediaLayer.cpp \
- platform/graphics/android/MediaTexture.cpp \
- platform/graphics/android/PaintTileOperation.cpp \
platform/graphics/android/PathAndroid.cpp \
platform/graphics/android/PatternAndroid.cpp \
- platform/graphics/android/PictureLayerContent.cpp \
- platform/graphics/android/PictureSetLayerContent.cpp \
- platform/graphics/android/PlatformGraphicsContext.cpp \
- platform/graphics/android/PerformanceMonitor.cpp \
- platform/graphics/android/RasterRenderer.cpp \
- platform/graphics/android/ScrollableLayerAndroid.cpp \
platform/graphics/android/SharedBufferStream.cpp \
- platform/graphics/android/ShaderProgram.cpp \
- platform/graphics/android/TextureInfo.cpp \
- platform/graphics/android/TexturesGenerator.cpp \
- platform/graphics/android/TilesManager.cpp \
- platform/graphics/android/TilesProfiler.cpp \
- platform/graphics/android/TiledPage.cpp \
- platform/graphics/android/TiledTexture.cpp \
- platform/graphics/android/TransferQueue.cpp \
- platform/graphics/android/SurfaceCollection.cpp \
- platform/graphics/android/SurfaceCollectionManager.cpp \
- platform/graphics/android/VerticalTextMap.cpp \
- platform/graphics/android/VideoLayerAndroid.cpp \
- platform/graphics/android/VideoLayerManager.cpp \
- platform/graphics/android/ZoomManager.cpp \
+ \
+ platform/graphics/android/context/GraphicsContextAndroid.cpp \
+ platform/graphics/android/context/GraphicsOperationCollection.cpp \
+ platform/graphics/android/context/PlatformGraphicsContext.cpp \
+ platform/graphics/android/context/PlatformGraphicsContextRecording.cpp \
+ platform/graphics/android/context/PlatformGraphicsContextSkia.cpp \
+ \
+ platform/graphics/android/fonts/FontAndroid.cpp \
+ platform/graphics/android/fonts/FontCacheAndroid.cpp \
+ platform/graphics/android/fonts/FontCustomPlatformData.cpp \
+ platform/graphics/android/fonts/FontDataAndroid.cpp \
+ platform/graphics/android/fonts/FontPlatformDataAndroid.cpp \
+ platform/graphics/android/fonts/GlyphMapAndroid.cpp \
+ platform/graphics/android/fonts/VerticalTextMap.cpp \
+ \
+ platform/graphics/android/layers/AndroidAnimation.cpp \
+ platform/graphics/android/layers/BaseLayerAndroid.cpp \
+ platform/graphics/android/layers/CanvasLayer.cpp \
+ platform/graphics/android/layers/CanvasTexture.cpp \
+ platform/graphics/android/layers/DumpLayer.cpp \
+ platform/graphics/android/layers/FixedPositioning.cpp \
+ platform/graphics/android/layers/IFrameContentLayerAndroid.cpp \
+ platform/graphics/android/layers/IFrameLayerAndroid.cpp \
+ platform/graphics/android/layers/Layer.cpp \
+ platform/graphics/android/layers/LayerAndroid.cpp \
+ platform/graphics/android/layers/MediaLayer.cpp \
+ platform/graphics/android/layers/MediaTexture.cpp \
+ platform/graphics/android/layers/PictureLayerContent.cpp \
+ platform/graphics/android/layers/PictureSetLayerContent.cpp \
+ platform/graphics/android/layers/ScrollableLayerAndroid.cpp \
+ platform/graphics/android/layers/VideoLayerAndroid.cpp \
+ platform/graphics/android/layers/VideoLayerManager.cpp \
+ \
+ platform/graphics/android/rendering/BaseRenderer.cpp \
+ platform/graphics/android/rendering/GaneshContext.cpp \
+ platform/graphics/android/rendering/GaneshRenderer.cpp \
+ platform/graphics/android/rendering/GLExtras.cpp \
+ platform/graphics/android/rendering/GLUtils.cpp \
+ platform/graphics/android/rendering/ImagesManager.cpp \
+ platform/graphics/android/rendering/ImageTexture.cpp \
+ platform/graphics/android/rendering/InspectorCanvas.cpp \
+ platform/graphics/android/rendering/PaintTileOperation.cpp \
+ platform/graphics/android/rendering/RasterRenderer.cpp \
+ platform/graphics/android/rendering/ShaderProgram.cpp \
+ platform/graphics/android/rendering/Surface.cpp \
+ platform/graphics/android/rendering/SurfaceBacking.cpp \
+ platform/graphics/android/rendering/SurfaceCollection.cpp \
+ platform/graphics/android/rendering/SurfaceCollectionManager.cpp \
+ platform/graphics/android/rendering/TextureInfo.cpp \
+ platform/graphics/android/rendering/TexturesGenerator.cpp \
+ platform/graphics/android/rendering/Tile.cpp \
+ platform/graphics/android/rendering/TileGrid.cpp \
+ platform/graphics/android/rendering/TileTexture.cpp \
+ platform/graphics/android/rendering/TilesManager.cpp \
+ platform/graphics/android/rendering/TilesProfiler.cpp \
+ platform/graphics/android/rendering/TransferQueue.cpp \
+ \
+ platform/graphics/android/utils/ClassTracker.cpp
ifeq ($(ENABLE_SVG), true)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
@@ -720,6 +727,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/skia/FloatPointSkia.cpp \
platform/graphics/skia/FloatRectSkia.cpp \
platform/graphics/skia/GlyphPageTreeNodeSkia.cpp \
+ platform/graphics/skia/GradientSkia.cpp \
platform/graphics/skia/IntPointSkia.cpp \
platform/graphics/skia/IntRectSkia.cpp \
platform/graphics/skia/NativeImageSkia.cpp \
@@ -1264,5 +1272,5 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
# For complex scripts(Arabic, Thai, Hindi...).
ifeq ($(SUPPORT_COMPLEX_SCRIPTS),true)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
- platform/graphics/android/HarfbuzzSkia.cpp
+ platform/graphics/android/fonts/HarfbuzzSkia.cpp
endif
diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in
index f110846..c6c76bf 100644
--- a/Source/WebCore/WebCore.exp.in
+++ b/Source/WebCore/WebCore.exp.in
@@ -1595,7 +1595,6 @@ __ZN7WebCore17HTMLPlugInElement11getNPObjectEv
__ZNK7WebCore14SecurityOrigin9canAccessEPKS0_
__ZNK7WebCore4KURL10protocolIsEPKc
__ZNK7WebCore4KURL7hasPathEv
-__ZNK7WebCore4KURL9prettyURLEv
#endif
#if ENABLE(ORIENTATION_EVENTS)
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index b78a6d0..06e895d 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -5383,6 +5383,8 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
// parseFillPosition advances the args next pointer.
parseFillPosition(args, centerX, centerY);
a = args->current();
+ if (!a)
+ return false;
if (centerX || centerY) {
// Comma
diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp
index 04f1089..237844e 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.cpp
+++ b/Source/WebCore/css/CSSPrimitiveValue.cpp
@@ -316,7 +316,8 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r
break;
case CSS_REMS:
applyZoomMultiplier = false;
- factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
+ if (rootStyle)
+ factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
break;
case CSS_PX:
break;
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index 0b6fd35..2424349 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -1194,7 +1194,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document)
documentStyle->setVisuallyOrdered(document->visuallyOrdered());
documentStyle->setZoom(frame ? frame->pageZoomFactor() : 1);
documentStyle->setPageScaleTransform(frame ? frame->pageScaleFactor() : 1);
-
+ documentStyle->setUserModify(document->inDesignMode() ? READ_WRITE : READ_ONLY);
+
Element* docElement = document->documentElement();
RenderObject* docElementRenderer = docElement ? docElement->renderer() : 0;
if (docElementRenderer) {
@@ -4966,6 +4967,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
applyProperty(CSSPropertyFontStyle, font->style.get());
applyProperty(CSSPropertyFontVariant, font->variant.get());
applyProperty(CSSPropertyFontWeight, font->weight.get());
+ // The previous properties can dirty our font but they don't try to read the font's
+ // properties back, which is safe. However if font-size is using the 'ex' unit, it will
+ // need query the dirtied font's x-height to get the computed size. To be safe in this
+ // case, let's just update the font now.
+ updateFont();
applyProperty(CSSPropertyFontSize, font->size.get());
m_lineHeightValue = font->lineHeight.get();
diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
index 3b41f43..497bd19 100644
--- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
+++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
@@ -66,7 +66,8 @@ void WebKitCSSKeyframesRule::setName(const String& name)
// Since the name is used in the keyframe map list in CSSStyleSelector, we need
// to recompute the style sheet to get the updated name.
- stylesheet()->styleSheetChanged();
+ if (stylesheet())
+ stylesheet()->styleSheetChanged();
}
unsigned WebKitCSSKeyframesRule::length() const
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 1b5f55b..7fc628c 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -4083,6 +4083,8 @@ void Document::setTransformSource(PassOwnPtr<TransformSource> source)
void Document::setDesignMode(InheritedBool value)
{
m_designMode = value;
+ for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree()->traverseNext(m_frame))
+ frame->document()->scheduleForcedStyleRecalc();
}
Document::InheritedBool Document::getDesignMode() const
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index 0967ef5..da4312c 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -770,7 +770,7 @@ bool Node::isContentEditable() const
bool Node::rendererIsEditable(EditableLevel editableLevel) const
{
- if (document()->inDesignMode() || (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable()))
+ if (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable())
return true;
// Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
@@ -1614,7 +1614,7 @@ SVGUseElement* Node::svgShadowHost() const
}
#endif
-Node* Node::shadowAncestorNode()
+Node* Node::shadowAncestorNode() const
{
#if ENABLE(SVG)
// SVG elements living in a shadow tree only occur when <use> created them.
@@ -1622,18 +1622,18 @@ Node* Node::shadowAncestorNode()
// but the actual shadow tree element - as main difference to the HTML forms
// shadow tree concept. (This function _could_ be made virtual - opinions?)
if (isSVGElement())
- return this;
+ return const_cast<Node*>(this);
#endif
Node* root = shadowTreeRootNode();
if (root)
return root->shadowHost();
- return this;
+ return const_cast<Node*>(this);
}
-Node* Node::shadowTreeRootNode()
+Node* Node::shadowTreeRootNode() const
{
- Node* root = this;
+ Node* root = const_cast<Node*>(this);
while (root) {
if (root->isShadowRoot() || root->isSVGShadowRoot())
return root;
diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h
index 08b1921..76355c3 100644
--- a/Source/WebCore/dom/Node.h
+++ b/Source/WebCore/dom/Node.h
@@ -218,8 +218,8 @@ public:
virtual bool isShadowBoundary() const { return false; }
virtual bool canHaveLightChildRendererWithShadow() const { return false; }
- Node* shadowAncestorNode();
- Node* shadowTreeRootNode();
+ Node* shadowAncestorNode() const;
+ Node* shadowTreeRootNode() const;
bool isInShadowTree();
// Node's parent, shadow tree host, or SVG use.
ContainerNode* parentOrHostNode() const;
diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp
index 469a94a..268687f 100644
--- a/Source/WebCore/dom/Range.cpp
+++ b/Source/WebCore/dom/Range.cpp
@@ -51,6 +51,8 @@ using namespace std;
static WTF::RefCountedLeakCounter rangeCounter("Range");
#endif
+typedef Vector<RefPtr<Node> > NodeVector;
+
inline Range::Range(PassRefPtr<Document> ownerDocument)
: m_ownerDocument(ownerDocument)
, m_start(m_ownerDocument)
@@ -662,8 +664,6 @@ static inline unsigned lengthOfContentsInNode(Node* node)
PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec)
{
- typedef Vector<RefPtr<Node> > NodeVector;
-
RefPtr<DocumentFragment> fragment;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
fragment = DocumentFragment::create(m_ownerDocument.get());
@@ -873,9 +873,14 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node
// FIXME: This assertion may fail if DOM is modified during mutation event
// FIXME: Share code with Range::processNodes
ASSERT(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->parentNode() == ancestor);
- RefPtr<Node> next;
- for (Node* child = firstChildInAncestorToProcess.get(); child; child = next.get()) {
- next = direction == ProcessContentsForward ? child->nextSibling() : child->previousSibling();
+
+ NodeVector nodes;
+ for (Node* child = firstChildInAncestorToProcess.get(); child;
+ child = (direction == ProcessContentsForward) ? child->nextSibling() : child->previousSibling())
+ nodes.append(child);
+
+ for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) {
+ Node* child = it->get();
switch (action) {
case DELETE_CONTENTS:
ancestor->removeChild(child, ec);
diff --git a/Source/WebCore/editing/ApplyStyleCommand.cpp b/Source/WebCore/editing/ApplyStyleCommand.cpp
index c9649d0..4f1bc93 100644
--- a/Source/WebCore/editing/ApplyStyleCommand.cpp
+++ b/Source/WebCore/editing/ApplyStyleCommand.cpp
@@ -1316,8 +1316,10 @@ void ApplyStyleCommand::surroundNodeRangeWithElement(PassRefPtr<Node> passedStar
RefPtr<Node> node = startNode;
while (node) {
RefPtr<Node> next = node->nextSibling();
- removeNode(node);
- appendNode(node, element);
+ if (node->isContentEditable()) {
+ removeNode(node);
+ appendNode(node, element);
+ }
if (node == endNode)
break;
node = next;
diff --git a/Source/WebCore/editing/CompositeEditCommand.cpp b/Source/WebCore/editing/CompositeEditCommand.cpp
index cf2959a..bf515d7 100644
--- a/Source/WebCore/editing/CompositeEditCommand.cpp
+++ b/Source/WebCore/editing/CompositeEditCommand.cpp
@@ -781,7 +781,7 @@ void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Positi
appendNode(topNode, blockElement);
RefPtr<Node> lastNode = topNode;
- if (start.deprecatedNode() != outerNode) {
+ if (start.deprecatedNode() != outerNode && lastNode->isElementNode()) {
Vector<RefPtr<Node> > ancestors;
// Insert each node from innerNode to outerNode (excluded) in a list.
diff --git a/Source/WebCore/fileapi/DOMFileSystemBase.cpp b/Source/WebCore/fileapi/DOMFileSystemBase.cpp
index eafb815..5a2627f 100644
--- a/Source/WebCore/fileapi/DOMFileSystemBase.cpp
+++ b/Source/WebCore/fileapi/DOMFileSystemBase.cpp
@@ -63,7 +63,7 @@ bool DOMFileSystemBase::crackFileSystemURL(const KURL& url, AsyncFileSystem::Typ
return false;
KURL originURL(ParsedURLString, url.path());
- String path = originURL.path();
+ String path = decodeURLEscapeSequences(originURL.path());
if (path.isEmpty() || path[0] != '/')
return false;
path = path.substring(1);
diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp
index 4636f20..b05e7f5 100644
--- a/Source/WebCore/html/HTMLAnchorElement.cpp
+++ b/Source/WebCore/html/HTMLAnchorElement.cpp
@@ -405,7 +405,10 @@ void HTMLAnchorElement::setPathname(const String& value)
String HTMLAnchorElement::port() const
{
- return String::number(href().port());
+ if (href().hasPort())
+ return String::number(href().port());
+
+ return "";
}
void HTMLAnchorElement::setPort(const String& value)
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 5e0fe7b..578f717 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -58,6 +58,7 @@ bgcolor
bgproperties
border
bordercolor
+capture
cellpadding
cellspacing
char
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 9f51f10..e67cbf9 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -45,6 +45,7 @@
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "RenderHTMLCanvas.h"
+#include "RenderLayer.h"
#include "Settings.h"
#include <math.h>
#include <stdio.h>
@@ -225,6 +226,11 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
return;
m_dirtyRect.unite(r);
+#if PLATFORM(ANDROID)
+ // We handle invals ourselves and don't want webkit to repaint if we
+ // have put the canvas on a layer
+ if (!ro->hasLayer())
+#endif
ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
}
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 207c384..e485835 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -128,6 +128,10 @@ public:
void makeRenderingResultsAvailable();
+#if PLATFORM(ANDROID)
+ void clearDirtyRect() { m_dirtyRect = FloatRect(); }
+#endif
+
private:
HTMLCanvasElement(const QualifiedName&, Document*);
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index b2b57a2..82e33d1 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -682,11 +682,6 @@ void HTMLElement::setContentEditable(Attribute* attr)
attr->decl()->removeProperty(CSSPropertyWordWrap, false);
attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);
attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);
- } else if (equalIgnoringCase(enabled, "inherit")) {
- addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueInherit);
- attr->decl()->removeProperty(CSSPropertyWordWrap, false);
- attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false);
- attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false);
} else if (equalIgnoringCase(enabled, "plaintext-only")) {
addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 2b262e4..36cdf51 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -1588,4 +1588,24 @@ void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
}
+#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE)
+String HTMLInputElement::capture() const
+{
+ if (!isFileUpload()) {
+ // capture has no meaning on anything other than file pickers.
+ return String();
+ }
+
+ String capture = fastGetAttribute(captureAttr).lower();
+ if (capture == "camera"
+ || capture == "camcorder"
+ || capture == "microphone"
+ || capture == "filesystem")
+ return capture;
+ // According to the HTML Media Capture specification, the invalid and
+ // missing default value is filesystem.
+ return "filesystem";
+}
+#endif
+
} // namespace
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index 2a98b13..58d86ac 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -200,6 +200,10 @@ public:
void updateCheckedRadioButtons();
bool lastChangeWasUserEdit() const;
+
+#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE)
+ String capture() const;
+#endif
protected:
HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser);
diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl
index f346e10..e1937e4 100644
--- a/Source/WebCore/html/HTMLInputElement.idl
+++ b/Source/WebCore/html/HTMLInputElement.idl
@@ -107,6 +107,9 @@ module html {
attribute [Reflect, EnabledAtRuntime] boolean webkitGrammar;
attribute [DontEnum] EventListener onwebkitspeechchange;
#endif
+#if defined(WTF_PLATFORM_ANDROID) && defined(ENABLE_MEDIA_CAPTURE) && ENABLE_MEDIA_CAPTURE
+ attribute [Reflect] DOMString capture;
+#endif
};
}
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 5cd2ddd..46e8a12 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -238,7 +238,9 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
if (controls()) {
if (!hasMediaControls()) {
- ensureMediaControls();
+ if (!createMediaControls())
+ return;
+
mediaControls()->reset();
}
mediaControls()->show();
@@ -2739,13 +2741,18 @@ bool HTMLMediaElement::hasMediaControls()
return node && node->isMediaControls();
}
-void HTMLMediaElement::ensureMediaControls()
+bool HTMLMediaElement::createMediaControls()
{
if (hasMediaControls())
- return;
+ return true;
ExceptionCode ec;
- ensureShadowRoot()->appendChild(MediaControls::create(this), ec);
+ RefPtr<MediaControls> controls = MediaControls::create(this);
+ if (!controls)
+ return false;
+
+ ensureShadowRoot()->appendChild(controls, ec);
+ return true;
}
void* HTMLMediaElement::preDispatchEventHandler(Event* event)
@@ -2753,7 +2760,9 @@ void* HTMLMediaElement::preDispatchEventHandler(Event* event)
if (event && event->type() == eventNames().webkitfullscreenchangeEvent) {
if (controls()) {
if (!hasMediaControls()) {
- ensureMediaControls();
+ if (!createMediaControls())
+ return 0;
+
mediaControls()->reset();
}
mediaControls()->show();
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 2144ea1..0b11861 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -325,7 +325,7 @@ private:
void refreshCachedTime() const;
bool hasMediaControls();
- void ensureMediaControls();
+ bool createMediaControls();
virtual void* preDispatchEventHandler(Event*);
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.h b/Source/WebCore/html/shadow/TextControlInnerElements.h
index 2340970..886fbf8 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.h
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.h
@@ -101,9 +101,8 @@ private:
virtual void detach();
virtual bool isSpinButtonElement() const { return true; }
- // FIXME: shadowAncestorNode() should be const.
- virtual bool isEnabledFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isEnabledFormControl(); }
- virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isReadOnlyFormControl(); }
+ virtual bool isEnabledFormControl() const { return static_cast<Element*>(shadowAncestorNode())->isEnabledFormControl(); }
+ virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(shadowAncestorNode())->isReadOnlyFormControl(); }
virtual void defaultEventHandler(Event*);
void startRepeatingTimer();
void stopRepeatingTimer();
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index f999fdb..670cf1f 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -993,7 +993,8 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive)
ObjectContentType FrameLoader::defaultObjectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
{
String mimeType = mimeTypeIn;
- String extension = url.path().substring(url.path().reverseFind('.') + 1);
+ String decodedPath = decodeURLEscapeSequences(url.path());
+ String extension = decodedPath.substring(decodedPath.reverseFind('.') + 1);
// We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure
if (mimeType.isEmpty())
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 91c0629..fe25a93 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -293,6 +293,8 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
}
#if ENABLE(LINK_PREFETCH)
case CachedResource::LinkResource:
+ if (!m_document->settings()->linkPrefetchEnabled())
+ return false;
break;
#endif
}
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index a737754..45450b5 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -3224,15 +3224,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// When sending a touch cancel event, use empty touches and targetTouches lists.
bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
-#if PLATFORM(ANDROID)
- AtomicString stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
- if (event.type() == TouchLongPress)
- stateName = eventNames().touchlongpressEvent;
- else if (event.type() == TouchDoubleTap)
- stateName = eventNames().touchdoubletapEvent;
-#else
const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
-#endif
const EventTargetSet& targetsForState = changedTouches[state].m_targets;
for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index f332074..8f2958c 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -1745,6 +1745,11 @@ void FrameView::scheduleRelayout()
m_frame->ownerRenderer()->setNeedsLayout(true, true);
}
+#ifdef ANDROID_FLATTEN_FRAMESET
+ if (m_frame->ownerRenderer() && m_frame->ownerElement()->hasTagName(frameTag))
+ m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
+#endif
+
int delay = m_frame->document()->minimumLayoutDelay();
if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
unscheduleRelayout();
diff --git a/Source/WebCore/page/Location.cpp b/Source/WebCore/page/Location.cpp
index 4835a83..fb68a09 100644
--- a/Source/WebCore/page/Location.cpp
+++ b/Source/WebCore/page/Location.cpp
@@ -63,8 +63,7 @@ String Location::href() const
if (!m_frame)
return String();
- const KURL& url = this->url();
- return url.hasPath() ? url.prettyURL() : url.prettyURL() + "/";
+ return url().string();
}
String Location::protocol() const
@@ -83,7 +82,7 @@ String Location::host() const
// Note: this is the IE spec. The NS spec swaps the two, it says
// "The hostname property is the concatenation of the host and port properties, separated by a colon."
const KURL& url = this->url();
- return url.port() ? url.host() + ":" + String::number(url.port()) : url.host();
+ return url.hasPort() ? url.host() + ":" + String::number(url.port()) : url.host();
}
String Location::hostname() const
@@ -100,7 +99,7 @@ String Location::port() const
return String();
const KURL& url = this->url();
- return url.port() ? String::number(url.port()) : "";
+ return url.hasPort() ? String::number(url.port()) : "";
}
String Location::pathname() const
@@ -147,15 +146,6 @@ String Location::getParameter(const String& name) const
return parameters.get(name);
}
-String Location::toString() const
-{
- if (!m_frame)
- return String();
-
- const KURL& url = this->url();
- return url.hasPath() ? url.prettyURL() : url.prettyURL() + "/";
-}
-
void Location::setHref(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow)
{
if (!m_frame)
@@ -199,7 +189,7 @@ void Location::setPort(const String& portString, DOMWindow* activeWindow, DOMWin
return;
KURL url = m_frame->document()->url();
int port = portString.toInt();
- if (port < 0 || port > 0xFFFF)
+ if (port < 0 || port > 0xFFFF || portString.isEmpty())
url.removePort();
else
url.setPort(port);
diff --git a/Source/WebCore/page/Location.h b/Source/WebCore/page/Location.h
index 1b68cee..0e89ecf 100644
--- a/Source/WebCore/page/Location.h
+++ b/Source/WebCore/page/Location.h
@@ -29,9 +29,9 @@
#ifndef Location_h
#define Location_h
-#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -71,7 +71,7 @@ public:
String hash() const;
String origin() const;
- String toString() const;
+ String toString() const { return href(); }
String getParameter(const String&) const;
diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp
index c26a0fc..f668f3e 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -149,6 +149,9 @@ Settings::Settings(Page* page)
// they can't use by. Leaving enabled for now to not change existing behavior.
, m_downloadableBinaryFontsEnabled(true)
, m_xssAuditorEnabled(false)
+#if ENABLE(LINK_PREFETCH)
+ , m_linkPrefetchEnabled(true)
+#endif
, m_acceleratedCompositingEnabled(true)
, m_acceleratedCompositingFor3DTransformsEnabled(true)
, m_acceleratedCompositingForVideoEnabled(true)
@@ -823,6 +826,13 @@ void Settings::setXSSAuditorEnabled(bool xssAuditorEnabled)
m_xssAuditorEnabled = xssAuditorEnabled;
}
+#if ENABLE(LINK_PREFETCH)
+void Settings::setLinkPrefetchEnabled(bool linkPrefetchEnabled)
+{
+ m_linkPrefetchEnabled = linkPrefetchEnabled;
+}
+#endif
+
void Settings::setAcceleratedCompositingEnabled(bool enabled)
{
if (m_acceleratedCompositingEnabled == enabled)
diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h
index 2bb222d..2cf7715 100644
--- a/Source/WebCore/page/Settings.h
+++ b/Source/WebCore/page/Settings.h
@@ -352,6 +352,11 @@ namespace WebCore {
void setXSSAuditorEnabled(bool);
bool xssAuditorEnabled() const { return m_xssAuditorEnabled; }
+#if ENABLE(LINK_PREFETCH)
+ void setLinkPrefetchEnabled(bool);
+ bool linkPrefetchEnabled() const { return m_linkPrefetchEnabled; }
+#endif
+
void setCanvasUsesAcceleratedDrawing(bool);
bool canvasUsesAcceleratedDrawing() const { return m_canvasUsesAcceleratedDrawing; }
@@ -567,6 +572,9 @@ namespace WebCore {
bool m_acceleratedDrawingEnabled : 1;
bool m_downloadableBinaryFontsEnabled : 1;
bool m_xssAuditorEnabled : 1;
+#if ENABLE(LINK_PREFETCH)
+ bool m_linkPrefetchEnabled : 1;
+#endif
bool m_acceleratedCompositingEnabled : 1;
bool m_acceleratedCompositingFor3DTransformsEnabled : 1;
bool m_acceleratedCompositingForVideoEnabled : 1;
diff --git a/Source/WebCore/platform/FileChooser.h b/Source/WebCore/platform/FileChooser.h
index ac5e0e6..6c382d1 100644
--- a/Source/WebCore/platform/FileChooser.h
+++ b/Source/WebCore/platform/FileChooser.h
@@ -50,6 +50,9 @@ public:
virtual String acceptTypes() = 0;
virtual void chooseIconForFiles(FileChooser*, const Vector<String>&) = 0;
virtual ~FileChooserClient();
+#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE)
+ virtual String capture() = 0;
+#endif
};
class FileChooser : public RefCounted<FileChooser> {
@@ -79,6 +82,10 @@ public:
// Acceptable MIME types. It's an 'accept' attribute value of the corresponding INPUT element.
String acceptTypes() const { return m_client ? m_client->acceptTypes() : String(); }
+#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE)
+ String capture() const { return m_client ? m_client->capture() : String(); }
+#endif
+
private:
FileChooser(FileChooserClient*, const Vector<String>& initialFilenames);
void initialize();
diff --git a/Source/WebCore/platform/KURL.cpp b/Source/WebCore/platform/KURL.cpp
index 88ad3d9..234d749 100644
--- a/Source/WebCore/platform/KURL.cpp
+++ b/Source/WebCore/platform/KURL.cpp
@@ -708,7 +708,7 @@ String KURL::query() const
String KURL::path() const
{
- return decodeURLEscapeSequences(m_string.substring(m_portEnd, m_pathEnd - m_portEnd));
+ return m_string.substring(m_portEnd, m_pathEnd - m_portEnd);
}
bool KURL::setProtocol(const String& s)
@@ -866,7 +866,7 @@ void KURL::setPath(const String& s)
parse(m_string.left(m_portEnd) + encodeWithURLEscapeSequences(path) + m_string.substring(m_pathEnd));
}
-String KURL::prettyURL() const
+String KURL::deprecatedString() const
{
if (!m_isValid)
return m_string;
@@ -996,7 +996,7 @@ static void appendEscapingBadChars(char*& buffer, const char* strStart, size_t l
buffer = p;
}
-static void escapeAndAppendFragment(char*& buffer, const char* strStart, size_t length)
+static void escapeAndAppendNonHierarchicalPart(char*& buffer, const char* strStart, size_t length)
{
char* p = buffer;
@@ -1137,6 +1137,23 @@ static inline bool hostPortIsEmptyButCredentialsArePresent(int hostStart, int po
return userEndChar == '@' && hostStart == portEnd;
}
+static bool isNonFileHierarchicalScheme(const char* scheme, size_t schemeLength)
+{
+ switch (schemeLength) {
+ case 2:
+ return equal("ws", 2, scheme, schemeLength);
+ case 3:
+ return equal("ftp", 3, scheme, schemeLength) || equal("wss", 3, scheme, schemeLength);
+ case 4:
+ return equal("http", 4, scheme, schemeLength);
+ case 5:
+ return equal("https", 5, scheme, schemeLength);
+ case 6:
+ return equal("gopher", 6, scheme, schemeLength);
+ }
+ return false;
+}
+
void KURL::parse(const char* url, const String* originalString)
{
if (!url || url[0] == '\0') {
@@ -1173,6 +1190,7 @@ void KURL::parse(const char* url, const String* originalString)
int portEnd;
bool hierarchical = url[schemeEnd + 1] == '/';
+ bool hasSecondSlash = hierarchical && url[schemeEnd + 2] == '/';
bool isFile = schemeEnd == 4
&& matchLetter(url[0], 'f')
@@ -1186,12 +1204,15 @@ void KURL::parse(const char* url, const String* originalString)
&& matchLetter(url[3], 'p')
&& (url[4] == ':' || (matchLetter(url[4], 's') && url[5] == ':'));
- if (hierarchical && url[schemeEnd + 2] == '/') {
+ if ((hierarchical && hasSecondSlash) || isNonFileHierarchicalScheme(url, schemeEnd)) {
// The part after the scheme is either a net_path or an abs_path whose first path segment is empty.
// Attempt to find an authority.
-
// FIXME: Authority characters may be scanned twice, and it would be nice to be faster.
- userStart += 2;
+
+ if (hierarchical)
+ userStart++;
+ if (hasSecondSlash)
+ userStart++;
userEnd = userStart;
int colonPos = 0;
@@ -1394,12 +1415,14 @@ void KURL::parse(const char* url, const String* originalString)
m_userStart = m_userEnd = m_passwordEnd = m_hostEnd = m_portEnd = p - buffer.data();
// For canonicalization, ensure we have a '/' for no path.
- // Do this only for hierarchical URL with protocol http or https.
- if (m_protocolInHTTPFamily && hierarchical && pathEnd == pathStart)
+ // Do this only for URL with protocol http or https.
+ if (m_protocolInHTTPFamily && pathEnd == pathStart)
*p++ = '/';
// add path, escaping bad characters
- if (!hierarchical || !hasSlashDotOrDotDot(url))
+ if (!hierarchical)
+ escapeAndAppendNonHierarchicalPart(p, url + pathStart, pathEnd - pathStart);
+ else if (!hasSlashDotOrDotDot(url))
appendEscapingBadChars(p, url + pathStart, pathEnd - pathStart);
else {
CharBuffer pathBuffer(pathEnd - pathStart + 1);
@@ -1425,7 +1448,7 @@ void KURL::parse(const char* url, const String* originalString)
// add fragment, escaping bad characters
if (fragmentEnd != queryEnd) {
*p++ = '#';
- escapeAndAppendFragment(p, url + fragmentStart, fragmentEnd - fragmentStart);
+ escapeAndAppendNonHierarchicalPart(p, url + fragmentStart, fragmentEnd - fragmentStart);
}
m_fragmentEnd = p - buffer.data();
diff --git a/Source/WebCore/platform/KURL.h b/Source/WebCore/platform/KURL.h
index db2dd42..192c10b 100644
--- a/Source/WebCore/platform/KURL.h
+++ b/Source/WebCore/platform/KURL.h
@@ -152,7 +152,9 @@ public:
String baseAsString() const;
- String prettyURL() const;
+ // This function is only used by location.href. It's likely we shouldn't
+ // use it for that purpose, but more study is necessary before we remove it.
+ String deprecatedString() const;
String fileSystemPath() const;
// Returns true if the current URL's protocol is the same as the null-
diff --git a/Source/WebCore/platform/KURLGoogle.cpp b/Source/WebCore/platform/KURLGoogle.cpp
index 0d11b99..54bcf16 100644
--- a/Source/WebCore/platform/KURLGoogle.cpp
+++ b/Source/WebCore/platform/KURLGoogle.cpp
@@ -593,7 +593,6 @@ String KURL::query() const
String KURL::path() const
{
- // Note: KURL.cpp unescapes here.
return m_url.componentString(m_url.m_parsed.path);
}
@@ -670,16 +669,12 @@ void KURL::setPort(unsigned short i)
{
KURLGooglePrivate::Replacements replacements;
String portStr;
- if (i) {
- portStr = String::number(i);
- replacements.SetPort(
- reinterpret_cast<const url_parse::UTF16Char*>(portStr.characters()),
- url_parse::Component(0, portStr.length()));
- } else {
- // Clear any existing port when it is set to 0.
- replacements.ClearPort();
- }
+ portStr = String::number(i);
+ replacements.SetPort(
+ reinterpret_cast<const url_parse::UTF16Char*>(portStr.characters()),
+ url_parse::Component(0, portStr.length()));
+
m_url.replaceComponents(replacements);
}
@@ -772,7 +767,7 @@ void KURL::setPath(const String& path)
// On Mac, this just seems to return the same URL, but with "/foo/bar" for
// file: URLs instead of file:///foo/bar. We don't bother with any of this,
// at least for now.
-String KURL::prettyURL() const
+String KURL::deprecatedString() const
{
if (!m_url.m_isValid)
return String();
diff --git a/Source/WebCore/platform/PlatformTouchEvent.h b/Source/WebCore/platform/PlatformTouchEvent.h
index 2ca7c99..f7524b4 100644
--- a/Source/WebCore/platform/PlatformTouchEvent.h
+++ b/Source/WebCore/platform/PlatformTouchEvent.h
@@ -52,10 +52,6 @@ enum TouchEventType {
, TouchMove
, TouchEnd
, TouchCancel
-#if PLATFORM(ANDROID)
- , TouchLongPress
- , TouchDoubleTap
-#endif
};
class PlatformTouchEvent {
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.cpp b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
index ee406c2..173cfea 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -88,7 +88,7 @@ const float scaleFactor[RenderSkinAndroid::ResolutionCount] = {
static SkCanvas* getCanvasFromInfo(const PaintInfo& info)
{
- return info.context->platformContext()->mCanvas;
+ return info.context->platformContext()->getCanvas();
}
static android::WebFrame* getWebFrame(const Node* node)
@@ -341,6 +341,8 @@ bool RenderThemeAndroid::paintMediaFullscreenButton(RenderObject* o, const Paint
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FULLSCREEN, translucent);
return false;
}
@@ -350,6 +352,8 @@ bool RenderThemeAndroid::paintMediaMuteButton(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::MUTE, translucent);
return false;
}
@@ -360,6 +364,8 @@ bool RenderThemeAndroid::paintMediaPlayButton(RenderObject* o, const PaintInfo&
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) {
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
if (btn->displayType() == MediaPlayButton)
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PLAY, translucent);
else
@@ -374,6 +380,8 @@ bool RenderThemeAndroid::paintMediaSeekBackButton(RenderObject* o, const PaintIn
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::REWIND, translucent);
return false;
}
@@ -383,6 +391,8 @@ bool RenderThemeAndroid::paintMediaSeekForwardButton(RenderObject* o, const Pain
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FORWARD, translucent);
return false;
}
@@ -392,6 +402,8 @@ bool RenderThemeAndroid::paintMediaControlsBackground(RenderObject* o, const Pai
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
RenderSkinMediaButton::BACKGROUND_SLIDER,
translucent, 0, false);
@@ -403,6 +415,8 @@ bool RenderThemeAndroid::paintMediaSliderTrack(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
RenderSkinMediaButton::SLIDER_TRACK, translucent, o);
return false;
@@ -413,6 +427,8 @@ bool RenderThemeAndroid::paintMediaSliderThumb(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
+ if (!getCanvasFromInfo(paintInfo))
+ return true;
RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
RenderSkinMediaButton::SLIDER_THUMB,
translucent, 0, false);
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index beafdc7..664c3af 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -171,7 +171,13 @@ private:
float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
+#if PLATFORM(ANDROID)
+public:
+#endif
void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
+#if PLATFORM(ANDROID)
+private:
+#endif
void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const FloatPoint&) const;
void drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
diff --git a/Source/WebCore/platform/graphics/FontPlatformData.h b/Source/WebCore/platform/graphics/FontPlatformData.h
index a32215d..36ccbb0 100644
--- a/Source/WebCore/platform/graphics/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/FontPlatformData.h
@@ -36,7 +36,7 @@
#elif (PLATFORM(EFL) || PLATFORM(GTK)) && USE(PANGO)
#include "pango/FontPlatformData.h"
#elif PLATFORM(ANDROID)
-#include "android/FontPlatformData.h"
+#include "android/fonts/FontPlatformData.h"
#else
#ifndef FontPlatformData_h
diff --git a/Source/WebCore/platform/graphics/Gradient.cpp b/Source/WebCore/platform/graphics/Gradient.cpp
index 7541646..7e3984f 100644
--- a/Source/WebCore/platform/graphics/Gradient.cpp
+++ b/Source/WebCore/platform/graphics/Gradient.cpp
@@ -221,7 +221,7 @@ void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra
setPlatformGradientSpaceTransform(gradientSpaceTransformation);
}
-#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !USE(CAIRO)
+#if !USE(SKIA) && !USE(CAIRO)
void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&)
{
}
diff --git a/Source/WebCore/platform/graphics/Gradient.h b/Source/WebCore/platform/graphics/Gradient.h
index 7595896..ec22efe 100644
--- a/Source/WebCore/platform/graphics/Gradient.h
+++ b/Source/WebCore/platform/graphics/Gradient.h
@@ -58,14 +58,9 @@ typedef QGradient* PlatformGradient;
typedef struct _cairo_pattern cairo_pattern_t;
typedef cairo_pattern_t* PlatformGradient;
#elif USE(SKIA)
-#if PLATFORM(ANDROID)
-#include "SkShader.h"
-typedef class PlatformGradientRec* PlatformGradient;
-#else
class SkShader;
typedef class SkShader* PlatformGradient;
typedef class SkShader* PlatformPattern;
-#endif
#elif PLATFORM(HAIKU)
class BGradient;
typedef BGradient* PlatformGradient;
@@ -116,9 +111,6 @@ namespace WebCore {
#if OS(WINCE) && !PLATFORM(QT)
const Vector<ColorStop, 2>& getStops() const;
#else
-#if PLATFORM(ANDROID)
- SkShader* getShader(SkShader::TileMode);
-#endif
PlatformGradient platformGradient();
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp
index e032714..d8ea160 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -662,7 +662,7 @@ CompositeOperator GraphicsContext::compositeOperation() const
return m_state.compositeOperator;
}
-#if !(USE(SKIA) && !PLATFORM(ANDROID))
+#if !USE(SKIA)
void GraphicsContext::setPlatformFillGradient(Gradient*)
{
}
@@ -688,7 +688,7 @@ void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode)
}
#endif
-#if !PLATFORM(QT) && !USE(CAIRO) && !(USE(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG)
+#if !PLATFORM(QT) && !USE(CAIRO) && !USE(SKIA) && !PLATFORM(OPENVG)
void GraphicsContext::setPlatformStrokeStyle(StrokeStyle)
{
}
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index ed43cf0..5c60e98 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -287,8 +287,6 @@ namespace WebCore {
#endif
#if PLATFORM(ANDROID)
- // initialize a paint for bitmaps
- void setupBitmapPaint(SkPaint*);
// initialize a paint for filling
void setupFillPaint(SkPaint*);
// initialize a paint for stroking
@@ -301,10 +299,6 @@ namespace WebCore {
// returns true if there is a valid (non-transparent) stroke color
bool willStroke() const;
- // may return NULL, since we lazily allocate the path. This is the path
- // that is drawn by drawPath()
- const SkPath* getCurrPath() const;
-
/** platform-specific factory method to return a bitmap graphicscontext,
called by <canvas> when we need to draw offscreen. Caller is responsible for
deleting the context. Use drawOffscreenContext() to draw the context's image
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
deleted file mode 100644
index 7e0a719..0000000
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "BaseLayerAndroid"
-#define LOG_NDEBUG 1
-
-#include "config.h"
-#include "BaseLayerAndroid.h"
-
-#include "AndroidLog.h"
-#include "ClassTracker.h"
-#include "GLUtils.h"
-#include "LayerGroup.h"
-#include "ShaderProgram.h"
-#include "SkCanvas.h"
-#include "TilesManager.h"
-#include <GLES2/gl2.h>
-
-// TODO: dynamically determine based on DPI
-#define PREFETCH_SCALE_MODIFIER 0.3
-#define PREFETCH_OPACITY 1
-#define PREFETCH_X_DIST 0
-#define PREFETCH_Y_DIST 1
-
-namespace WebCore {
-
-using namespace android;
-
-BaseLayerAndroid::BaseLayerAndroid()
-#if USE(ACCELERATED_COMPOSITING)
- : m_color(Color::white)
- , m_content(0)
- , m_scrollState(NotScrolling)
-#endif
-{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("BaseLayerAndroid");
-#endif
-}
-
-BaseLayerAndroid::~BaseLayerAndroid()
-{
- SkSafeUnref(m_content);
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("BaseLayerAndroid");
-#endif
-}
-
-void BaseLayerAndroid::setContent(LayerContent* content)
-{
- SkSafeRef(content);
- SkSafeUnref(m_content);
- m_content = content;
- // FIXME: We cannot set the size of the base layer because it will screw up
- // the matrix used. We need to fix matrix computation for the base layer
- // and then we can set the size.
- // setSize(src.width(), src.height());
-}
-
-bool BaseLayerAndroid::drawCanvas(SkCanvas* canvas)
-{
- android::Mutex::Autolock lock(m_drawLock);
- if (m_content && !m_content->isEmpty())
- m_content->draw(canvas);
- return true;
-}
-
-#if USE(ACCELERATED_COMPOSITING)
-
-void BaseLayerAndroid::prefetchBasePicture(const SkRect& viewport, float currentScale,
- TiledPage* prefetchTiledPage, bool draw)
-{
- SkIRect bounds;
- float prefetchScale = currentScale * PREFETCH_SCALE_MODIFIER;
-
- float invTileWidth = (prefetchScale)
- / TilesManager::instance()->tileWidth();
- float invTileHeight = (prefetchScale)
- / TilesManager::instance()->tileHeight();
- bool goingDown = m_state->goingDown();
- bool goingLeft = m_state->goingLeft();
-
-
- ALOGV("fetch rect %f %f %f %f, scale %f",
- viewport.fLeft,
- viewport.fTop,
- viewport.fRight,
- viewport.fBottom,
- currentScale);
-
- bounds.fLeft = static_cast<int>(floorf(viewport.fLeft * invTileWidth)) - PREFETCH_X_DIST;
- bounds.fTop = static_cast<int>(floorf(viewport.fTop * invTileHeight)) - PREFETCH_Y_DIST;
- bounds.fRight = static_cast<int>(ceilf(viewport.fRight * invTileWidth)) + PREFETCH_X_DIST;
- bounds.fBottom = static_cast<int>(ceilf(viewport.fBottom * invTileHeight)) + PREFETCH_Y_DIST;
-
- ALOGV("prefetch rect %d %d %d %d, scale %f, preparing page %p",
- bounds.fLeft, bounds.fTop,
- bounds.fRight, bounds.fBottom,
- prefetchScale,
- prefetchTiledPage);
-
- prefetchTiledPage->setScale(prefetchScale);
- prefetchTiledPage->updateTileDirtiness();
- prefetchTiledPage->prepare(goingDown, goingLeft, bounds,
- TiledPage::ExpandedBounds);
- prefetchTiledPage->swapBuffersIfReady(bounds,
- prefetchScale);
- if (draw)
- prefetchTiledPage->prepareForDrawGL(PREFETCH_OPACITY, bounds);
-}
-
-bool BaseLayerAndroid::isReady()
-{
- ZoomManager* zoomManager = m_state->zoomManager();
- if (ZoomManager::kNoScaleRequest != zoomManager->scaleRequestState()) {
- ALOGV("base layer not ready, still zooming");
- return false; // still zooming
- }
-
- if (!m_state->frontPage()->isReady(m_state->preZoomBounds())) {
- ALOGV("base layer not ready, front page not done painting");
- return false;
- }
-
- return true;
-}
-
-void BaseLayerAndroid::swapTiles()
-{
- m_state->frontPage()->swapBuffersIfReady(m_state->preZoomBounds(),
- m_state->zoomManager()->currentScale());
-
- m_state->backPage()->swapBuffersIfReady(m_state->preZoomBounds(),
- m_state->zoomManager()->currentScale());
-}
-
-void BaseLayerAndroid::setIsPainting()
-{
- ALOGV("BLA %p setIsPainting, dirty %d", this, isDirty());
- m_state->invalRegion(m_dirtyRegion);
- m_dirtyRegion.setEmpty();
-}
-
-void BaseLayerAndroid::mergeInvalsInto(BaseLayerAndroid* replacementLayer)
-{
- replacementLayer->markAsDirty(m_dirtyRegion);
-}
-
-void BaseLayerAndroid::prepareGL(const SkRect& viewport, float scale, double currentTime)
-{
- ALOGV("prepareGL BLA %p, m_state %p", this, m_state);
-
- ZoomManager* zoomManager = m_state->zoomManager();
-
- bool goingDown = m_state->goingDown();
- bool goingLeft = m_state->goingLeft();
-
- const SkIRect& viewportTileBounds = m_state->viewportTileBounds();
- ALOGV("drawBasePicture, TX: %d, TY: %d scale %.2f", viewportTileBounds.fLeft,
- viewportTileBounds.fTop, scale);
-
- // Query the resulting state from the zoom manager
- bool prepareNextTiledPage = zoomManager->needPrepareNextTiledPage();
-
- // Display the current page
- TiledPage* tiledPage = m_state->frontPage();
- TiledPage* nextTiledPage = m_state->backPage();
- tiledPage->setScale(zoomManager->currentScale());
-
- // Let's prepare the page if needed so that it will start painting
- if (prepareNextTiledPage) {
- nextTiledPage->setScale(scale);
- m_state->setFutureViewport(viewportTileBounds);
-
- nextTiledPage->updateTileDirtiness();
-
- nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds,
- TiledPage::VisibleBounds);
- // Cancel pending paints for the foreground page
- TilesManager::instance()->removePaintOperationsForPage(tiledPage, false);
- }
-
- // If we fired a request, let's check if it's ready to use
- if (zoomManager->didFireRequest()) {
- if (nextTiledPage->swapBuffersIfReady(viewportTileBounds,
- zoomManager->futureScale()))
- zoomManager->setReceivedRequest(); // transition to received request state
- }
-
- float transparency = 1;
- bool doZoomPageSwap = false;
-
- // If the page is ready, display it. We do a short transition between
- // the two pages (current one and future one with the new scale factor)
- if (zoomManager->didReceivedRequest()) {
- float nextTiledPageTransparency = 1;
- m_state->resetFrameworkInval();
- zoomManager->processTransition(currentTime, scale, &doZoomPageSwap,
- &nextTiledPageTransparency, &transparency);
- nextTiledPage->prepareForDrawGL(nextTiledPageTransparency, viewportTileBounds);
- }
-
- const SkIRect& preZoomBounds = m_state->preZoomBounds();
-
- bool zooming = ZoomManager::kNoScaleRequest != zoomManager->scaleRequestState();
-
- if (doZoomPageSwap) {
- zoomManager->setCurrentScale(scale);
- m_state->swapPages();
- }
-
- tiledPage->updateTileDirtiness();
-
- // paint what's needed unless we're zooming, since the new tiles won't
- // be relevant soon anyway
- if (!zooming)
- tiledPage->prepare(goingDown, goingLeft, preZoomBounds,
- TiledPage::ExpandedBounds);
-
- ALOGV("scrollState %d, zooming %d", m_scrollState, zooming);
-
- // prefetch in the nextTiledPage if unused by zooming (even if not scrolling
- // since we want the tiles to be ready before they're needed)
- bool usePrefetchPage = !zooming;
- nextTiledPage->setIsPrefetchPage(usePrefetchPage);
- if (usePrefetchPage) {
- // if the non-prefetch page isn't missing tiles, don't bother drawing
- // prefetch page
- bool drawPrefetchPage = tiledPage->hasMissingContent(preZoomBounds);
- prefetchBasePicture(viewport, scale, nextTiledPage, drawPrefetchPage);
- }
-
- tiledPage->prepareForDrawGL(transparency, preZoomBounds);
-}
-
-void BaseLayerAndroid::drawBasePictureInGL()
-{
- m_state->backPage()->drawGL();
- m_state->frontPage()->drawGL();
-}
-
-void BaseLayerAndroid::updateLayerPositions(const SkRect& visibleRect)
-{
- LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0));
- if (!compositedRoot)
- return;
- TransformationMatrix ident;
- compositedRoot->updateLayerPositions(visibleRect);
- FloatRect clip(0, 0, content()->width(), content()->height());
-
- // Note that this function may be called (and should still work) with no m_state in SW mode
- // TODO: is this the best thing to do in software rendering
- float scale = m_state ? m_state->scale() : 1.0f;
- compositedRoot->updateGLPositionsAndScale(ident, clip, 1, scale);
-
-#ifdef DEBUG
- compositedRoot->showLayer(0);
- ALOGV("We have %d layers, %d textured",
- compositedRoot->nbLayers(),
- compositedRoot->nbTexturedLayers());
-#endif
-}
-
-#endif // USE(ACCELERATED_COMPOSITING)
-
-void BaseLayerAndroid::drawGL(float scale)
-{
- ALOGV("drawGL BLA %p", this);
-
- // TODO: consider moving drawBackground outside of prepare (into tree manager)
- m_state->drawBackground(m_color);
- drawBasePictureInGL();
- m_state->glExtras()->drawGL(0);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
deleted file mode 100644
index 5560f58..0000000
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BaseLayerAndroid_h
-#define BaseLayerAndroid_h
-
-#include <utils/threads.h>
-
-#include "Color.h"
-#include "Layer.h"
-#include "PictureSet.h"
-#include "LayerContent.h"
-
-namespace WebCore {
-
-class TiledPage;
-
-class BaseLayerAndroid : public Layer {
-
-public:
- enum ScrollState {
- NotScrolling = 0,
- Scrolling = 1,
- ScrollingFinishPaint = 2
- };
-
- BaseLayerAndroid();
- virtual ~BaseLayerAndroid();
-
-#if USE(ACCELERATED_COMPOSITING)
- void setBackgroundColor(Color& color) { m_color = color; }
- Color getBackgroundColor() { return m_color; }
-#endif
- void setContent(LayerContent* content);
- LayerContent* content() { return m_content; }
-
- // This method will paint using the current PictureSet onto
- // the passed canvas. We used it to paint the GL tiles as well as
- // WebView::copyBaseContentToPicture(), so a lock is necessary as
- // we are running in different threads.
- virtual bool drawCanvas(SkCanvas* canvas);
-
- void updateLayerPositions(const SkRect& visibleRect);
- void prepareGL(const SkRect& visibleRect, float scale, double currentTime);
- void drawGL(float scale);
-
- // rendering asset management
- void swapTiles();
- void setIsDrawing(bool isDrawing);
- void setIsPainting();
- void mergeInvalsInto(BaseLayerAndroid* replacementLayer);
- bool isReady();
-
-private:
-#if USE(ACCELERATED_COMPOSITING)
- void prefetchBasePicture(const SkRect& viewport, float currentScale,
- TiledPage* prefetchTiledPage, bool draw);
- void drawBasePictureInGL();
-
- android::Mutex m_drawLock;
- Color m_color;
-#endif
- LayerContent* m_content;
-
- ScrollState m_scrollState;
-};
-
-} // namespace WebCore
-
-#endif // BaseLayerAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 663addb..8581a8e 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -37,19 +37,16 @@
#include "GLUtils.h"
#include "ImagesManager.h"
#include "LayerAndroid.h"
+#include "private/hwui/DrawGlInfo.h"
#include "ScrollableLayerAndroid.h"
#include "SkPath.h"
#include "TilesManager.h"
+#include "TransferQueue.h"
#include "SurfaceCollection.h"
#include "SurfaceCollectionManager.h"
#include <pthread.h>
#include <wtf/CurrentTime.h>
-#define FIRST_TILED_PAGE_ID 1
-#define SECOND_TILED_PAGE_ID 2
-
-#define FRAMERATE_CAP 0.01666 // We cap at 60 fps
-
// log warnings if scale goes outside this range
#define MIN_SCALE_WARNING 0.1
#define MAX_SCALE_WARNING 10
@@ -66,27 +63,16 @@ namespace WebCore {
using namespace android;
GLWebViewState::GLWebViewState()
- : m_zoomManager(this)
- , m_usePageA(true)
- , m_frameworkInval(0, 0, 0, 0)
- , m_frameworkLayersInval(0, 0, 0, 0)
+ : m_frameworkLayersInval(0, 0, 0, 0)
, m_isScrolling(false)
, m_isViewportScrolling(false)
, m_goingDown(true)
, m_goingLeft(false)
- , m_expandedTileBoundsX(0)
- , m_expandedTileBoundsY(0)
, m_scale(1)
, m_layersRenderingMode(kAllTextures)
- , m_surfaceCollectionManager(this)
+ , m_surfaceCollectionManager()
{
m_viewport.setEmpty();
- m_futureViewportTileBounds.setEmpty();
- m_viewportTileBounds.setEmpty();
- m_preZoomBounds.setEmpty();
-
- m_tiledPageA = new TiledPage(FIRST_TILED_PAGE_ID, this);
- m_tiledPageB = new TiledPage(SECOND_TILED_PAGE_ID, this);
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("GLWebViewState");
@@ -100,14 +86,6 @@ GLWebViewState::GLWebViewState()
GLWebViewState::~GLWebViewState()
{
- // We have to destroy the two tiled pages first as their destructor
- // may depend on the existence of this GLWebViewState and some of its
- // instance variables in order to complete.
- // Explicitely, currently we need to have the m_paintingBaseLayer around
- // in order to complete any pending paint operations (the tiled pages
- // will remove any pending operations, and wait if one is underway).
- delete m_tiledPageA;
- delete m_tiledPageB;
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("GLWebViewState");
#endif
@@ -117,19 +95,17 @@ GLWebViewState::~GLWebViewState()
bool GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndicator,
bool isPictureAfterFirstLayout)
{
- if (!layer || isPictureAfterFirstLayout) {
- // TODO: move this into SurfaceCollectionManager
- m_zoomManager.swapPages(); // reset zoom state
- m_tiledPageA->discardTextures();
- m_tiledPageB->discardTextures();
+ if (!layer || isPictureAfterFirstLayout)
m_layersRenderingMode = kAllTextures;
- }
+
+ SurfaceCollection* collection = 0;
if (layer) {
- ALOGV("new base layer %p, with child %p", layer, layer->getChild(0));
+ ALOGV("layer tree %p, with child %p", layer, layer->getChild(0));
layer->setState(this);
+ collection = new SurfaceCollection(layer);
}
bool queueFull = m_surfaceCollectionManager.updateWithSurfaceCollection(
- new SurfaceCollection(layer), isPictureAfterFirstLayout);
+ collection, isPictureAfterFirstLayout);
m_glExtras.setDrawExtra(0);
#ifdef MEASURES_PERF
@@ -145,85 +121,6 @@ bool GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndica
void GLWebViewState::scrollLayer(int layerId, int x, int y)
{
m_surfaceCollectionManager.updateScrollableLayer(layerId, x, y);
-
- // TODO: only inval the area of the scrolled layer instead of
- // doing a fullInval()
- if (m_layersRenderingMode == kSingleSurfaceRendering)
- fullInval();
-}
-
-void GLWebViewState::invalRegion(const SkRegion& region)
-{
- if (m_layersRenderingMode == kSingleSurfaceRendering) {
- // TODO: do the union of both layer trees to compute
- // the minimum inval instead of doing a fullInval()
- fullInval();
- return;
- }
- SkRegion::Iterator iterator(region);
- while (!iterator.done()) {
- SkIRect r = iterator.rect();
- IntRect ir(r.fLeft, r.fTop, r.width(), r.height());
- inval(ir);
- iterator.next();
- }
-}
-
-void GLWebViewState::inval(const IntRect& rect)
-{
- if (!rect.isEmpty()) {
- // find which tiles fall within the invalRect and mark them as dirty
- m_tiledPageA->invalidateRect(rect);
- m_tiledPageB->invalidateRect(rect);
- if (m_frameworkInval.isEmpty())
- m_frameworkInval = rect;
- else
- m_frameworkInval.unite(rect);
- ALOGV("intermediate invalRect(%d, %d, %d, %d) after unite with rect %d %d %d %d", m_frameworkInval.x(),
- m_frameworkInval.y(), m_frameworkInval.width(), m_frameworkInval.height(),
- rect.x(), rect.y(), rect.width(), rect.height());
- }
- TilesManager::instance()->getProfiler()->nextInval(rect, zoomManager()->currentScale());
-}
-
-void GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
-{
- m_surfaceCollectionManager.drawCanvas(canvas, m_layersRenderingMode == kSingleSurfaceRendering);
-}
-
-TiledPage* GLWebViewState::sibling(TiledPage* page)
-{
- return (page == m_tiledPageA) ? m_tiledPageB : m_tiledPageA;
-}
-
-TiledPage* GLWebViewState::frontPage()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- return m_usePageA ? m_tiledPageA : m_tiledPageB;
-}
-
-TiledPage* GLWebViewState::backPage()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- return m_usePageA ? m_tiledPageB : m_tiledPageA;
-}
-
-void GLWebViewState::swapPages()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- m_usePageA ^= true;
- TiledPage* oldPage = m_usePageA ? m_tiledPageB : m_tiledPageA;
- zoomManager()->swapPages();
- oldPage->discardTextures();
-}
-
-int GLWebViewState::baseContentWidth()
-{
- return m_surfaceCollectionManager.baseContentWidth();
-}
-int GLWebViewState::baseContentHeight()
-{
- return m_surfaceCollectionManager.baseContentHeight();
}
void GLWebViewState::setViewport(const SkRect& viewport, float scale)
@@ -235,20 +132,19 @@ void GLWebViewState::setViewport(const SkRect& viewport, float scale)
int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1;
int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1;
- TilesManager* manager = TilesManager::instance();
- int maxTextureCount = (viewMaxTileX + m_expandedTileBoundsX * 2) *
- (viewMaxTileY + m_expandedTileBoundsY * 2) * (manager->highEndGfx() ? 4 : 2);
+ TilesManager* tilesManager = TilesManager::instance();
+ int maxTextureCount = viewMaxTileX * viewMaxTileY * (tilesManager->highEndGfx() ? 4 : 2);
- manager->setMaxTextureCount(maxTextureCount);
- m_tiledPageA->updateBaseTileSize();
- m_tiledPageB->updateBaseTileSize();
+ tilesManager->setMaxTextureCount(maxTextureCount);
+ // TODO: investigate whether we can move this return earlier.
if ((m_viewport == viewport)
- && (zoomManager()->futureScale() == scale)) {
+ && (m_scale == scale)) {
// everything below will stay the same, early return.
m_isViewportScrolling = false;
return;
}
+ m_scale = scale;
m_goingDown = m_viewport.fTop - viewport.fTop <= 0;
m_goingLeft = m_viewport.fLeft - viewport.fLeft >= 0;
@@ -257,16 +153,9 @@ void GLWebViewState::setViewport(const SkRect& viewport, float scale)
m_isViewportScrolling = m_viewport != viewport && SkRect::Intersects(m_viewport, viewport);
m_viewport = viewport;
- ALOGV("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)",
+ ALOGV("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f )",
m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
- m_viewport.width(), m_viewport.height(), scale,
- zoomManager()->currentScale(), zoomManager()->futureScale());
-
- m_viewportTileBounds.set(
- static_cast<int>(floorf(viewport.fLeft * invTileContentWidth)),
- static_cast<int>(floorf(viewport.fTop * invTileContentHeight)),
- static_cast<int>(ceilf(viewport.fRight * invTileContentWidth)),
- static_cast<int>(ceilf(viewport.fBottom * invTileContentHeight)));
+ m_viewport.width(), m_viewport.height(), scale);
}
#ifdef MEASURES_PERF
@@ -282,14 +171,6 @@ void GLWebViewState::dumpMeasures()
}
#endif // MEASURES_PERF
-void GLWebViewState::resetFrameworkInval()
-{
- m_frameworkInval.setX(0);
- m_frameworkInval.setY(0);
- m_frameworkInval.setWidth(0);
- m_frameworkInval.setHeight(0);
-}
-
void GLWebViewState::addDirtyArea(const IntRect& rect)
{
if (rect.isEmpty())
@@ -311,29 +192,10 @@ void GLWebViewState::resetLayersDirtyArea()
m_frameworkLayersInval.setHeight(0);
}
-void GLWebViewState::drawBackground(Color& backgroundColor)
-{
- if (TilesManager::instance()->invertedScreen()) {
- float color = 1.0 - ((((float) backgroundColor.red() / 255.0) +
- ((float) backgroundColor.green() / 255.0) +
- ((float) backgroundColor.blue() / 255.0)) / 3.0);
- glClearColor(color, color, color, 1);
- } else {
- glClearColor((float)backgroundColor.red() / 255.0,
- (float)backgroundColor.green() / 255.0,
- (float)backgroundColor.blue() / 255.0, 1);
- }
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
const IntRect& webViewRect, int titleBarHeight,
const IntRect& screenClip, float scale)
{
- int left = viewRect.x();
- int top = viewRect.y();
- int width = viewRect.width();
- int height = viewRect.height();
TilesManager* tilesManager = TilesManager::instance();
// Make sure GL resources are created on the UI thread.
@@ -350,20 +212,12 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib
transferQueue->initGLResources(TilesManager::tileWidth(),
TilesManager::tileHeight());
}
- // TODO: Add the video GL resource re-initialization code here.
-
shader->setupDrawing(viewRect, visibleRect, webViewRect,
titleBarHeight, screenClip, scale);
- shader->calculateAnimationDelta();
-
- glViewport(left + shader->getAnimationDeltaX(),
- top - shader->getAnimationDeltaY(),
- width, height);
double currentTime = WTF::currentTime();
setViewport(visibleRect, scale);
- m_zoomManager.processNewScale(currentTime, scale);
return currentTime;
}
@@ -429,67 +283,57 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded)
m_layersRenderingMode = kSingleSurfaceRendering;
// update the base surface if needed
- if (m_layersRenderingMode != layersRenderingMode
- && invalBase) {
- m_tiledPageA->discardTextures();
- m_tiledPageB->discardTextures();
- fullInval();
- return true;
- }
- return false;
-}
-
-void GLWebViewState::fullInval()
-{
- // TODO -- use base layer's size.
- IntRect ir(0, 0, 1E6, 1E6);
- inval(ir);
+ // TODO: inval base layergroup when going into single surface mode
+ return (m_layersRenderingMode != layersRenderingMode && invalBase);
}
-bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
- IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale,
- bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr)
+// -rect(viewRect) is the webViewRect with inverted Y, in screen coordinate.
+// -viewport(visibleRect) is the visible area in document coordinate.
+// They are both based on webViewRect and calculated in Java side.
+//
+// -clip is the final glViewport value in screen coordinate, and it contains the
+// animation translation/scale and FBO offset.
+//
+// TODO: Try to decrease the number of parameters as some info is redundant.
+int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
+ IntRect& webViewRect, int titleBarHeight,
+ IntRect& clip, float scale,
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
+ bool shouldDraw)
{
TilesManager* tilesManager = TilesManager::instance();
- m_scale = scale;
- tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop,
- viewport.fRight, viewport.fBottom,
- scale);
+ if (shouldDraw)
+ tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop,
+ viewport.fRight, viewport.fBottom,
+ scale);
tilesManager->incDrawGLCount();
- float viewWidth = (viewport.fRight - viewport.fLeft) * TILE_PREFETCH_RATIO;
- float viewHeight = (viewport.fBottom - viewport.fTop) * TILE_PREFETCH_RATIO;
- bool noPrefetch = tilesManager->useMinimalMemory() || !tilesManager->highEndGfx();
- bool useHorzPrefetch = noPrefetch ? 0 : viewWidth < baseContentWidth();
- bool useVertPrefetch = noPrefetch ? 0 : viewHeight < baseContentHeight();
- m_expandedTileBoundsX = (useHorzPrefetch) ? TILE_PREFETCH_DISTANCE : 0;
- m_expandedTileBoundsY = (useVertPrefetch) ? TILE_PREFETCH_DISTANCE : 0;
-
- ALOGV("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)",
+ ALOGV("drawGL, rect/viewRect(%d, %d, %d, %d), viewport/visibleRect(%.2f, %.2f, %.2f, %.2f)",
rect.x(), rect.y(), rect.width(), rect.height(),
viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom);
ALOGV("drawGL, invalRect(%d, %d, %d, %d), webViewRect(%d, %d, %d, %d)"
- "clip (%d, %d, %d, %d), scale %f",
+ "clip/glViewport (%d, %d, %d, %d), scale %f titleBarHeight %d",
invalRect->x(), invalRect->y(), invalRect->width(), invalRect->height(),
webViewRect.x(), webViewRect.y(), webViewRect.width(), webViewRect.height(),
- clip.x(), clip.y(), clip.width(), clip.height(), scale);
+ clip.x(), clip.y(), clip.width(), clip.height(), scale, titleBarHeight);
resetLayersDirtyArea();
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING)
ALOGW("WARNING, scale seems corrupted before update: %e", scale);
- // Here before we draw, update the BaseTile which has updated content.
+ // Here before we draw, update the Tile which has updated content.
// Inside this function, just do GPU blits from the transfer queue into
- // the BaseTiles' texture.
- tilesManager->transferQueue()->updateDirtyBaseTiles();
+ // the Tiles' texture.
+ tilesManager->transferQueue()->updateDirtyTiles();
// Upload any pending ImageTexture
// Return true if we still have some images to upload.
// TODO: upload as many textures as possible within a certain time limit
- bool ret = ImagesManager::instance()->prepareTextures(this);
+ int returnFlags = 0;
+ if (ImagesManager::instance()->prepareTextures(this))
+ returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
ALOGW("WARNING, scale seems corrupted after update: %e", scale);
@@ -497,20 +341,17 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
}
// gather the textures we can use
- tilesManager->gatherLayerTextures();
+ tilesManager->gatherTextures();
double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale);
-
TexturesResult nbTexturesNeeded;
bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering;
m_glExtras.setViewport(viewport);
- ret |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport,
- scale, fastSwap,
- collectionsSwappedPtr, newCollectionHasAnimPtr,
- &nbTexturesNeeded);
- if (!ret)
- resetFrameworkInval();
+ returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport,
+ scale, fastSwap,
+ collectionsSwappedPtr, newCollectionHasAnimPtr,
+ &nbTexturesNeeded, shouldDraw);
int nbTexturesForImages = ImagesManager::instance()->nbTextures();
ALOGV("*** We have %d textures for images, %d full, %d clipped, total %d / %d",
@@ -519,39 +360,28 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
nbTexturesNeeded.clipped + nbTexturesForImages);
nbTexturesNeeded.full += nbTexturesForImages;
nbTexturesNeeded.clipped += nbTexturesForImages;
- ret |= setLayersRenderingMode(nbTexturesNeeded);
+
+ if (setLayersRenderingMode(nbTexturesNeeded))
+ returnFlags |= uirenderer::DrawGlInfo::kStatusDraw | uirenderer::DrawGlInfo::kStatusInvoke;
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Clean up GL textures for video layer.
tilesManager->videoLayerManager()->deleteUnusedTextures();
- ret |= tilesManager->invertedScreenSwitch();
- if (ret) {
- // ret==true && empty inval region means we've inval'd everything,
+ if (returnFlags & uirenderer::DrawGlInfo::kStatusDraw) {
+ // returnFlags & kStatusDraw && empty inval region means we've inval'd everything,
// but don't have new content. Keep redrawing full view (0,0,0,0)
// until tile generation catches up and we swap pages.
- bool fullScreenInval = m_frameworkInval.isEmpty();
-
- if (tilesManager->invertedScreenSwitch()) {
- fullScreenInval = true;
- tilesManager->setInvertedScreenSwitch(false);
- }
+ bool fullScreenInval = m_frameworkLayersInval.isEmpty();
if (!fullScreenInval) {
- FloatRect frameworkInval = tilesManager->shader()->rectInInvScreenCoord(
- m_frameworkInval);
- // Inflate the invalidate rect to avoid precision lost.
- frameworkInval.inflate(1);
- IntRect inval(frameworkInval.x(), frameworkInval.y(),
- frameworkInval.width(), frameworkInval.height());
-
- inval.unite(m_frameworkLayersInval);
+ m_frameworkLayersInval.inflate(1);
- invalRect->setX(inval.x());
- invalRect->setY(inval.y());
- invalRect->setWidth(inval.width());
- invalRect->setHeight(inval.height());
+ invalRect->setX(m_frameworkLayersInval.x());
+ invalRect->setY(m_frameworkLayersInval.y());
+ invalRect->setWidth(m_frameworkLayersInval.width());
+ invalRect->setHeight(m_frameworkLayersInval.height());
ALOGV("invalRect(%d, %d, %d, %d)", inval.x(),
inval.y(), inval.width(), inval.height());
@@ -568,13 +398,12 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
invalRect->setWidth(0);
invalRect->setHeight(0);
}
- } else {
- resetFrameworkInval();
}
- showFrameInfo(rect, *collectionsSwappedPtr);
+ if (shouldDraw)
+ showFrameInfo(rect, *collectionsSwappedPtr);
- return ret;
+ return returnFlags;
}
void GLWebViewState::showFrameInfo(const IntRect& rect, bool collectionsSwapped)
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index fcdd07c..2b28619 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -35,9 +35,7 @@
#include "SkCanvas.h"
#include "SkRect.h"
#include "SkRegion.h"
-#include "TiledPage.h"
#include "SurfaceCollectionManager.h"
-#include "ZoomManager.h"
#include <utils/threads.h>
// Performance measurements probe
@@ -51,9 +49,6 @@
// HW limit or save further in the GPU memory consumption.
#define TILE_PREFETCH_DISTANCE 1
-// ratio of content to view required for prefetching to enable
-#define TILE_PREFETCH_RATIO 1.2
-
namespace WebCore {
class BaseLayerAndroid;
@@ -98,7 +93,7 @@ class TexturesResult;
// there is a need to be called again (i.e. if we do not have up to date
// textures or a transition is going on).
//
-// Tiles are implemented as a BaseTile. It knows how to paint itself with the
+// Tiles are implemented as a Tile. It knows how to paint itself with the
// PictureSet, and to display itself. A GL texture is usually associated to it.
//
// We also works with two TiledPages -- one to display the page at the
@@ -112,13 +107,13 @@ class TexturesResult;
// Texture allocation
// ------------------
//
-// Obviously we cannot have every BaseTile having a GL texture -- we need to
+// Obviously we cannot have every Tile having a GL texture -- we need to
// get the GL textures from an existing pool, and reuse them.
//
// The way we do it is that when we call TiledPage::prepare(), we group the
// tiles we need (i.e. in the viewport and dirty) into a TilesSet and call
-// BaseTile::reserveTexture() for each tile (which ensures there is a specific
-// GL textures backing the BaseTiles).
+// Tile::reserveTexture() for each tile (which ensures there is a specific
+// GL textures backing the Tiles).
//
// reserveTexture() will ask the TilesManager for a texture. The allocation
// mechanism goal is to (in order):
@@ -130,7 +125,7 @@ class TexturesResult;
// we prepare() a TiledPage. Also during each prepare() we compute which tiles
// are dirty based on the info we have received from webkit.
//
-// BaseTile Invalidation
+// Tile Invalidation
// ------------------
//
// We do not want to redraw a tile if the tile is up-to-date. A tile is
@@ -154,9 +149,9 @@ class TexturesResult;
//
// The next operation is to schedule this TilesSet to be painted
// (TilesManager::schedulePaintForTilesSet()). TexturesGenerator
-// will get the TilesSet and ask the BaseTiles in it to be painted.
+// will get the TilesSet and ask the Tiles in it to be painted.
//
-// BaseTile::paintBitmap() will paint the texture using the BaseLayer's
+// Tile::paintBitmap() will paint the texture using the BaseLayer's
// PictureSet (calling TiledPage::paintBaseLayerContent() which in turns
// calls GLWebViewState::paintBaseLayerContent()).
//
@@ -171,62 +166,32 @@ public:
GLWebViewState();
~GLWebViewState();
- ZoomManager* zoomManager() { return &m_zoomManager; }
- const SkIRect& futureViewport() const { return m_futureViewportTileBounds; }
- void setFutureViewport(const SkIRect& viewport) { m_futureViewportTileBounds = viewport; }
-
- void paintBaseLayerContent(SkCanvas* canvas);
bool setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndicator,
bool isPictureAfterFirstLayout);
void paintExtras();
GLExtras* glExtras() { return &m_glExtras; }
- TiledPage* sibling(TiledPage* page);
- TiledPage* frontPage();
- TiledPage* backPage();
- void swapPages();
-
- // dimensions of the current base layer
- int baseContentWidth();
- int baseContentHeight();
-
- // a rect containing the coordinates of all tiles in the current viewport
- const SkIRect& viewportTileBounds() const { return m_viewportTileBounds; }
- // a rect containing the viewportTileBounds before there was a scale change
- const SkIRect& preZoomBounds() const { return m_preZoomBounds; }
- void setPreZoomBounds(const SkIRect& bounds) { m_preZoomBounds = bounds; }
-
void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; }
bool isScrolling() { return m_isScrolling || m_isViewportScrolling; }
- void drawBackground(Color& backgroundColor);
-
bool setLayersRenderingMode(TexturesResult&);
- void fullInval();
- bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
- IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale,
- bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr);
+ int drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
+ IntRect& webViewRect, int titleBarHeight,
+ IntRect& clip, float scale,
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
+ bool shouldDraw);
#ifdef MEASURES_PERF
void dumpMeasures();
#endif
- void resetFrameworkInval();
void addDirtyArea(const IntRect& rect);
void resetLayersDirtyArea();
bool goingDown() { return m_goingDown; }
bool goingLeft() { return m_goingLeft; }
- void setDirection(bool goingDown, bool goingLeft) {
- m_goingDown = goingDown;
- m_goingLeft = goingLeft;
- }
-
- int expandedTileBoundsX() { return m_expandedTileBoundsX; }
- int expandedTileBoundsY() { return m_expandedTileBoundsY; }
float scale() { return m_scale; }
@@ -242,10 +207,7 @@ public:
LayersRenderingMode layersRenderingMode() { return m_layersRenderingMode; }
void scrollLayer(int layerId, int x, int y);
- void invalRegion(const SkRegion& region);
-
private:
- void inval(const IntRect& rect);
void setViewport(const SkRect& viewport, float scale);
double setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
const IntRect& webViewRect, int titleBarHeight,
@@ -255,18 +217,7 @@ private:
float b, float a);
double m_prevDrawTime;
- ZoomManager m_zoomManager;
- android::Mutex m_tiledPageLock;
SkRect m_viewport;
- SkIRect m_viewportTileBounds;
- SkIRect m_futureViewportTileBounds;
- SkIRect m_preZoomBounds;
-
- bool m_usePageA;
- TiledPage* m_tiledPageA;
- TiledPage* m_tiledPageB;
- IntRect m_lastInval;
- IntRect m_frameworkInval;
IntRect m_frameworkLayersInval;
#ifdef MEASURES_PERF
@@ -282,9 +233,6 @@ private:
bool m_goingDown;
bool m_goingLeft;
- int m_expandedTileBoundsX;
- int m_expandedTileBoundsY;
-
float m_scale;
LayersRenderingMode m_layersRenderingMode;
diff --git a/Source/WebCore/platform/graphics/android/GradientAndroid.cpp b/Source/WebCore/platform/graphics/android/GradientAndroid.cpp
deleted file mode 100644
index 6007a0a..0000000
--- a/Source/WebCore/platform/graphics/android/GradientAndroid.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2006, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Gradient.h"
-
-#include "android_graphics.h"
-#include "CSSParser.h"
-#include "GraphicsContext.h"
-#include "NotImplemented.h"
-#include "SkCanvas.h"
-#include "SkColorShader.h"
-#include "SkGradientShader.h"
-#include "SkPaint.h"
-
-class PlatformGradientRec {
-public:
- PlatformGradientRec() : m_shader(NULL) {}
- ~PlatformGradientRec() { SkSafeUnref(m_shader); }
-
- SkShader* m_shader;
- SkShader::TileMode m_tileMode;
- int m_colorCountWhenShaderWasBuilt;
-};
-
-namespace WebCore {
-
-void Gradient::platformDestroy()
-{
- delete m_gradient;
- m_gradient = 0;
-}
-
-static U8CPU F2B(float x)
-{
- return (int)(x * 255);
-}
-
-SkShader* Gradient::getShader(SkShader::TileMode mode)
-{
- if (NULL == m_gradient)
- m_gradient = new PlatformGradientRec;
- else if (mode == m_gradient->m_tileMode)
- return m_gradient->m_shader;
-
- // need to ensure that the m_stops array is sorted. We call getColor()
- // which, as a side effect, does the sort.
- // TODO: refactor Gradient.h to formally expose a sort method
- {
- float r, g, b, a;
- this->getColor(0, &r, &g, &b, &a);
- }
-
- SkPoint pts[2] = { m_p0, m_p1 }; // convert to SkPoint
-
- const size_t count = m_stops.size();
- SkAutoMalloc storage(count * (sizeof(SkColor) + sizeof(SkScalar)));
- SkColor* colors = (SkColor*)storage.get();
- SkScalar* pos = (SkScalar*)(colors + count);
-
- Vector<ColorStop>::iterator iter = m_stops.begin();
- for (int i = 0; iter != m_stops.end(); i++) {
- pos[i] = SkFloatToScalar(iter->stop);
- colors[i] = SkColorSetARGB(F2B(iter->alpha), F2B(iter->red),
- F2B(iter->green), F2B(iter->blue));
- ++iter;
- }
-
- SkShader* s;
- if (m_radial)
- s = SkGradientShader::CreateTwoPointRadial(pts[0],
- SkFloatToScalar(m_r0),
- pts[1],
- SkFloatToScalar(m_r1),
- colors, pos, count, mode);
- else
- s = SkGradientShader::CreateLinear(pts, colors, pos, count, mode);
-
- if (NULL == s)
- s = new SkColorShader(0);
-
- // zap our previous shader, if present
- SkSafeUnref(m_gradient->m_shader);
- m_gradient->m_shader = s;
- m_gradient->m_tileMode = mode;
- SkMatrix matrix = m_gradientSpaceTransformation;
- s->setLocalMatrix(matrix);
-
- return s;
-}
-
-void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
-{
- SkPaint paint;
- // we don't care about the mode, so try to use the existing one
- SkShader::TileMode mode = m_gradient ? m_gradient->m_tileMode :
- SkShader::kClamp_TileMode;
-
- paint.setAntiAlias(true);
- paint.setShader(this->getShader(mode));
- android_gc2canvas(context)->drawRect(rect, paint);
-}
-
-
-} //namespace
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
deleted file mode 100644
index 0aa1ae6..0000000
--- a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ /dev/null
@@ -1,1295 +0,0 @@
-/*
- * Copyright 2006, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "config.h"
-#include "GraphicsContext.h"
-
-#include "AffineTransform.h"
-#include "Font.h"
-#include "Gradient.h"
-#include "NotImplemented.h"
-#include "Path.h"
-#include "Pattern.h"
-#include "PlatformGraphicsContext.h"
-#include "SkBitmapRef.h"
-#include "SkBlurDrawLooper.h"
-#include "SkBlurMaskFilter.h"
-#include "SkCanvas.h"
-#include "SkColorPriv.h"
-#include "SkCornerPathEffect.h"
-#include "SkDashPathEffect.h"
-#include "SkDevice.h"
-#include "SkGradientShader.h"
-#include "SkPaint.h"
-#include "SkString.h"
-#include "SkiaUtils.h"
-#include "TransformationMatrix.h"
-#include "android_graphics.h"
-
-using namespace std;
-
-#define GC2CANVAS(ctx) (ctx)->m_data->getPlatformGfxCtx()->mCanvas
-
-namespace WebCore {
-
-static int RoundToInt(float x)
-{
- return (int)roundf(x);
-}
-
-template <typename T> T* deepCopyPtr(const T* src)
-{
- return src ? new T(*src) : 0;
-}
-
-// Set a bitmap shader that mimics dashing by width-on, width-off.
-// Returns false if it could not succeed (e.g. there was an existing shader)
-static bool setBitmapDash(SkPaint* paint, int width) {
- if (width <= 0 || paint->getShader())
- return false;
-
- SkColor c = paint->getColor();
-
- SkBitmap bm;
- bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 1);
- bm.allocPixels();
- bm.lockPixels();
-
- // set the ON pixel
- *bm.getAddr32(0, 0) = SkPreMultiplyARGB(0xFF, SkColorGetR(c),
- SkColorGetG(c), SkColorGetB(c));
- // set the OFF pixel
- *bm.getAddr32(1, 0) = 0;
- bm.unlockPixels();
-
- SkMatrix matrix;
- matrix.setScale(SkIntToScalar(width), SK_Scalar1);
-
- SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
- SkShader::kClamp_TileMode);
- s->setLocalMatrix(matrix);
-
- paint->setShader(s)->unref();
- return true;
-}
-
-// TODO / questions
-
-// alpha: how does this interact with the alpha in Color? multiply them together?
-// mode: do I always respect this? If so, then
-// the rgb() & 0xFF000000 check will abort drawing too often
-// Is Color premultiplied or not? If it is, then I can't blindly pass it to paint.setColor()
-
-struct ShadowRec {
- SkScalar blur;
- SkScalar dx;
- SkScalar dy;
- SkColor color; // alpha>0 means valid shadow
- ShadowRec(SkScalar b = 0,
- SkScalar x = 0,
- SkScalar y = 0,
- SkColor c = 0) // by default, alpha=0, so no shadow
- : blur(b), dx(x), dy(y), color(c)
- {};
-};
-
-class GraphicsContextPlatformPrivate {
-public:
- struct State {
- SkPathEffect* pathEffect;
- float miterLimit;
- float alpha;
- float strokeThickness;
- SkPaint::Cap lineCap;
- SkPaint::Join lineJoin;
- SkXfermode::Mode mode;
- int dashRatio; // Ratio of the length of a dash to its width
- ShadowRec shadow;
- SkColor fillColor;
- SkColor strokeColor;
- bool useAA;
-
- State()
- : pathEffect(0)
- , miterLimit(4)
- , alpha(1)
- , strokeThickness(0) // Same as default in GraphicsContextPrivate.h
- , lineCap(SkPaint::kDefault_Cap)
- , lineJoin(SkPaint::kDefault_Join)
- , mode(SkXfermode::kSrcOver_Mode)
- , dashRatio(3)
- , fillColor(SK_ColorBLACK)
- , strokeColor(SK_ColorBLACK)
- , useAA(true)
- {
- }
-
- State(const State& other)
- : pathEffect(other.pathEffect)
- , miterLimit(other.miterLimit)
- , alpha(other.alpha)
- , strokeThickness(other.strokeThickness)
- , lineCap(other.lineCap)
- , lineJoin(other.lineJoin)
- , mode(other.mode)
- , dashRatio(other.dashRatio)
- , shadow(other.shadow)
- , fillColor(other.fillColor)
- , strokeColor(other.strokeColor)
- , useAA(other.useAA)
- {
- SkSafeRef(pathEffect);
- }
-
- ~State()
- {
- SkSafeUnref(pathEffect);
- }
-
- void setShadow(int radius, int dx, int dy, SkColor c)
- {
- // Cut the radius in half, to visually match the effect seen in
- // safari browser
- shadow.blur = SkScalarHalf(SkIntToScalar(radius));
- shadow.dx = SkIntToScalar(dx);
- shadow.dy = SkIntToScalar(dy);
- shadow.color = c;
- }
-
- bool setupShadowPaint(GraphicsContext* ctx, SkPaint* paint, SkPoint* offset)
- {
- paint->setAntiAlias(true);
- paint->setDither(true);
- paint->setXfermodeMode(mode);
- paint->setColor(shadow.color);
- offset->set(shadow.dx, shadow.dy);
-
- // Currently, only GraphicsContexts associated with the
- // HTMLCanvasElement have shadows ignore transforms set. This
- // allows us to distinguish between CSS and Canvas shadows which
- // have different rendering specifications.
- uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag;
- if (ctx->shadowsIgnoreTransforms()) {
- offset->fY = -offset->fY;
- flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
- }
-
- if (shadow.blur > 0) {
- paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur,
- SkBlurMaskFilter::kNormal_BlurStyle))->unref();
- }
- return SkColorGetA(shadow.color) && (shadow.blur || shadow.dx || shadow.dy);
- }
-
- SkColor applyAlpha(SkColor c) const
- {
- int s = RoundToInt(alpha * 256);
- if (s >= 256)
- return c;
- if (s < 0)
- return 0;
-
- int a = SkAlphaMul(SkColorGetA(c), s);
- return (c & 0x00FFFFFF) | (a << 24);
- }
- };
-
- GraphicsContextPlatformPrivate(GraphicsContext* gfxCtx, PlatformGraphicsContext* platformGfxCtx)
- : m_parentGfxCtx(gfxCtx)
- , m_platformGfxCtx(platformGfxCtx)
- , m_stateStack(sizeof(State))
- {
- State* state = static_cast<State*>(m_stateStack.push_back());
- new (state) State();
- m_state = state;
- }
-
- ~GraphicsContextPlatformPrivate()
- {
- // We force restores so we don't leak any subobjects owned by our
- // stack of State records.
- while (m_stateStack.count() > 0)
- this->restore();
-
- if (m_platformGfxCtx && m_platformGfxCtx->deleteUs())
- delete m_platformGfxCtx;
- }
-
- void save()
- {
- State* newState = static_cast<State*>(m_stateStack.push_back());
- new (newState) State(*m_state);
- m_state = newState;
- }
-
- void restore()
- {
- m_state->~State();
- m_stateStack.pop_back();
- m_state = static_cast<State*>(m_stateStack.back());
- }
-
- void setFillColor(const Color& c)
- {
- m_state->fillColor = c.rgb();
- }
-
- void setStrokeColor(const Color& c)
- {
- m_state->strokeColor = c.rgb();
- }
-
- void setStrokeThickness(float f)
- {
- m_state->strokeThickness = f;
- }
-
- void setupPaintCommon(SkPaint* paint) const
- {
- paint->setAntiAlias(m_state->useAA);
- paint->setDither(true);
- paint->setXfermodeMode(m_state->mode);
- if (SkColorGetA(m_state->shadow.color) > 0) {
-
- // Currently, only GraphicsContexts associated with the
- // HTMLCanvasElement have shadows ignore transforms set. This
- // allows us to distinguish between CSS and Canvas shadows which
- // have different rendering specifications.
- SkScalar dy = m_state->shadow.dy;
- uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag;
- if (m_parentGfxCtx->shadowsIgnoreTransforms()) {
- dy = -dy;
- flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
- flags |= SkBlurDrawLooper::kOverrideColor_BlurFlag;
- }
-
- SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur,
- m_state->shadow.dx,
- dy,
- m_state->shadow.color,
- flags);
- paint->setLooper(looper)->unref();
- }
- }
-
- void setupPaintFill(SkPaint* paint) const
- {
- this->setupPaintCommon(paint);
- paint->setColor(m_state->applyAlpha(m_state->fillColor));
- }
-
- void setupPaintBitmap(SkPaint* paint) const
- {
- this->setupPaintCommon(paint);
- // We only want the global alpha for bitmaps,
- // so just give applyAlpha opaque black
- paint->setColor(m_state->applyAlpha(0xFF000000));
- }
-
- // Sets up the paint for stroking. Returns true if the style is really
- // just a dash of squares (the size of the paint's stroke-width.
- bool setupPaintStroke(SkPaint* paint, SkRect* rect, bool isHLine = false)
- {
- this->setupPaintCommon(paint);
- paint->setColor(m_state->applyAlpha(m_state->strokeColor));
-
- float width = m_state->strokeThickness;
-
- // This allows dashing and dotting to work properly for hairline strokes
- // FIXME: Should we only do this for dashed and dotted strokes?
- if (!width)
- width = 1;
-
- paint->setStyle(SkPaint::kStroke_Style);
- paint->setStrokeWidth(SkFloatToScalar(width));
- paint->setStrokeCap(m_state->lineCap);
- paint->setStrokeJoin(m_state->lineJoin);
- paint->setStrokeMiter(SkFloatToScalar(m_state->miterLimit));
-
- if (rect && (RoundToInt(width) & 1))
- rect->inset(-SK_ScalarHalf, -SK_ScalarHalf);
-
- SkPathEffect* pe = m_state->pathEffect;
- if (pe) {
- paint->setPathEffect(pe);
- return false;
- }
- switch (m_parentGfxCtx->strokeStyle()) {
- case NoStroke:
- case SolidStroke:
- width = 0;
- break;
- case DashedStroke:
- width = m_state->dashRatio * width;
- break;
- // No break
- case DottedStroke:
- break;
- }
-
- if (width > 0) {
- // Return true if we're basically a dotted dash of squares
- bool justSqrs = RoundToInt(width) == RoundToInt(paint->getStrokeWidth());
-
- if (justSqrs || !isHLine || !setBitmapDash(paint, width)) {
-#if 0
- // this is slow enough that we just skip it for now
- // see http://b/issue?id=4163023
- SkScalar intervals[] = { width, width };
- pe = new SkDashPathEffect(intervals, 2, 0);
- paint->setPathEffect(pe)->unref();
-#endif
- }
- return justSqrs;
- }
- return false;
- }
-
- PlatformGraphicsContext* getPlatformGfxCtx()
- {
- return m_platformGfxCtx;
- }
-
- State* getState()
- {
- return m_state;
- }
-private:
- State* m_state;
- GraphicsContext* m_parentGfxCtx; // Back-ptr to our parent
- PlatformGraphicsContext* m_platformGfxCtx;
- SkDeque m_stateStack;
- // Not supported yet
- State& operator=(const State&);
-};
-
-static SkShader::TileMode SpreadMethod2TileMode(GradientSpreadMethod sm)
-{
- SkShader::TileMode mode = SkShader::kClamp_TileMode;
-
- switch (sm) {
- case SpreadMethodPad:
- mode = SkShader::kClamp_TileMode;
- break;
- case SpreadMethodReflect:
- mode = SkShader::kMirror_TileMode;
- break;
- case SpreadMethodRepeat:
- mode = SkShader::kRepeat_TileMode;
- break;
- }
- return mode;
-}
-
-static void extactShader(SkPaint* paint, Pattern* pat, Gradient* grad)
-{
- if (pat) {
- // platformPattern() returns a cached obj
- paint->setShader(pat->platformPattern(AffineTransform()));
- } else if (grad) {
- // grad->getShader() returns a cached obj
- GradientSpreadMethod sm = grad->spreadMethod();
- paint->setShader(grad->getShader(SpreadMethod2TileMode(sm)));
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height)
-{
- PlatformGraphicsContext* pgc = new PlatformGraphicsContext();
-
- SkBitmap bitmap;
-
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
- bitmap.allocPixels();
- bitmap.eraseColor(0);
- pgc->mCanvas->setBitmapDevice(bitmap);
-
- GraphicsContext* ctx = new GraphicsContext(pgc);
- return ctx;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-void GraphicsContext::platformInit(PlatformGraphicsContext* gc)
-{
- m_data = new GraphicsContextPlatformPrivate(this, gc);
- setPaintingDisabled(!gc || !gc->mCanvas);
-}
-
-void GraphicsContext::platformDestroy()
-{
- delete m_data;
-}
-
-void GraphicsContext::savePlatformState()
-{
- // Save our private State
- m_data->save();
- // Save our native canvas
- GC2CANVAS(this)->save();
-}
-
-void GraphicsContext::restorePlatformState()
-{
- // Restore our private State
- m_data->restore();
- // Restore our native canvas
- GC2CANVAS(this)->restore();
-}
-
-bool GraphicsContext::willFill() const
-{
- return m_data->getState()->fillColor;
-}
-
-bool GraphicsContext::willStroke() const
-{
- return m_data->getState()->strokeColor;
-}
-
-// Draws a filled rectangle with a stroked border.
-void GraphicsContext::drawRect(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- SkPaint paint;
- SkRect r(rect);
-
- if (fillColor().alpha()) {
- m_data->setupPaintFill(&paint);
- GC2CANVAS(this)->drawRect(r, paint);
- }
-
- // According to GraphicsContext.h, stroking inside drawRect always means
- // a stroke of 1 inside the rect.
- if (strokeStyle() != NoStroke && strokeColor().alpha()) {
- paint.reset();
- m_data->setupPaintStroke(&paint, &r);
- paint.setPathEffect(0); // No dashing please
- paint.setStrokeWidth(SK_Scalar1); // Always just 1.0 width
- r.inset(SK_ScalarHalf, SK_ScalarHalf); // Ensure we're "inside"
- GC2CANVAS(this)->drawRect(r, paint);
- }
-}
-
-// This is only used to draw borders.
-void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
-{
- if (paintingDisabled())
- return;
-
- StrokeStyle style = strokeStyle();
- if (style == NoStroke)
- return;
-
- SkPaint paint;
- SkCanvas* canvas = GC2CANVAS(this);
- const int idx = SkAbs32(point2.x() - point1.x());
- const int idy = SkAbs32(point2.y() - point1.y());
-
- // Special-case horizontal and vertical lines that are really just dots
- if (m_data->setupPaintStroke(&paint, 0, !idy) && (!idx || !idy)) {
- const SkScalar diameter = paint.getStrokeWidth();
- const SkScalar radius = SkScalarHalf(diameter);
- SkScalar x = SkIntToScalar(SkMin32(point1.x(), point2.x()));
- SkScalar y = SkIntToScalar(SkMin32(point1.y(), point2.y()));
- SkScalar dx, dy;
- int count;
- SkRect bounds;
-
- if (!idy) { // Horizontal
- bounds.set(x, y - radius, x + SkIntToScalar(idx), y + radius);
- x += radius;
- dx = diameter * 2;
- dy = 0;
- count = idx;
- } else { // Vertical
- bounds.set(x - radius, y, x + radius, y + SkIntToScalar(idy));
- y += radius;
- dx = 0;
- dy = diameter * 2;
- count = idy;
- }
-
- // The actual count is the number of ONs we hit alternating
- // ON(diameter), OFF(diameter), ...
- {
- SkScalar width = SkScalarDiv(SkIntToScalar(count), diameter);
- // Now compute the number of cells (ON and OFF)
- count = SkScalarRound(width);
- // Now compute the number of ONs
- count = (count + 1) >> 1;
- }
-
- SkAutoMalloc storage(count * sizeof(SkPoint));
- SkPoint* verts = (SkPoint*)storage.get();
- // Now build the array of vertices to past to drawPoints
- for (int i = 0; i < count; i++) {
- verts[i].set(x, y);
- x += dx;
- y += dy;
- }
-
- paint.setStyle(SkPaint::kFill_Style);
- paint.setPathEffect(0);
-
- // Clipping to bounds is not required for correctness, but it does
- // allow us to reject the entire array of points if we are completely
- // offscreen. This is common in a webpage for android, where most of
- // the content is clipped out. If drawPoints took an (optional) bounds
- // parameter, that might even be better, as we would *just* use it for
- // culling, and not both wacking the canvas' save/restore stack.
- canvas->save(SkCanvas::kClip_SaveFlag);
- canvas->clipRect(bounds);
- canvas->drawPoints(SkCanvas::kPoints_PointMode, count, verts, paint);
- canvas->restore();
- } else {
- SkPoint pts[2] = { point1, point2 };
- canvas->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
- }
-}
-
-static void setrectForUnderline(SkRect* r, GraphicsContext* context, const FloatPoint& point, int yOffset, float width)
-{
- float lineThickness = context->strokeThickness();
-#if 0
- if (lineThickness < 1) // Do we really need/want this?
- lineThickness = 1;
-#endif
- r->fLeft = point.x();
- r->fTop = point.y() + yOffset;
- r->fRight = r->fLeft + width;
- r->fBottom = r->fTop + lineThickness;
-}
-
-void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool)
-{
- if (paintingDisabled())
- return;
-
- SkRect r;
- setrectForUnderline(&r, this, pt, 0, width);
-
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setColor(this->strokeColor().rgb());
-
- GC2CANVAS(this)->drawRect(r, paint);
-}
-
-// TODO: Should we draw different based on TextCheckingLineStyle?
-void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, TextCheckingLineStyle)
-{
- if (paintingDisabled())
- return;
-
- SkRect r;
- setrectForUnderline(&r, this, pt, 0, width);
-
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setColor(SK_ColorRED); // Is this specified somewhere?
-
- GC2CANVAS(this)->drawRect(r, paint);
-}
-
-// This method is only used to draw the little circles used in lists.
-void GraphicsContext::drawEllipse(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- SkPaint paint;
- SkRect oval(rect);
-
- if (fillColor().rgb() & 0xFF000000) {
- m_data->setupPaintFill(&paint);
- GC2CANVAS(this)->drawOval(oval, paint);
- }
- if (strokeStyle() != NoStroke) {
- paint.reset();
- m_data->setupPaintStroke(&paint, &oval);
- GC2CANVAS(this)->drawOval(oval, paint);
- }
-}
-
-static inline int fastMod(int value, int max)
-{
- int sign = SkExtractSign(value);
-
- value = SkApplySign(value, sign);
- if (value >= max)
- value %= max;
- return SkApplySign(value, sign);
-}
-
-void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan)
-{
- if (paintingDisabled())
- return;
-
- SkPath path;
- SkPaint paint;
- SkRect oval(r);
-
- if (strokeStyle() == NoStroke) {
- m_data->setupPaintFill(&paint); // We want the fill color
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(SkFloatToScalar(this->strokeThickness()));
- } else
- m_data->setupPaintStroke(&paint, 0);
-
- // We do this before converting to scalar, so we don't overflow SkFixed
- startAngle = fastMod(startAngle, 360);
- angleSpan = fastMod(angleSpan, 360);
-
- path.addArc(oval, SkIntToScalar(-startAngle), SkIntToScalar(-angleSpan));
- GC2CANVAS(this)->drawPath(path, paint);
-}
-
-void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
-{
- if (paintingDisabled())
- return;
-
- if (numPoints <= 1)
- return;
-
- SkPaint paint;
- SkPath path;
-
- path.incReserve(numPoints);
- path.moveTo(SkFloatToScalar(points[0].x()), SkFloatToScalar(points[0].y()));
- for (size_t i = 1; i < numPoints; i++)
- path.lineTo(SkFloatToScalar(points[i].x()), SkFloatToScalar(points[i].y()));
-
- if (GC2CANVAS(this)->quickReject(path, shouldAntialias ?
- SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) {
- return;
- }
-
- if (fillColor().rgb() & 0xFF000000) {
- m_data->setupPaintFill(&paint);
- paint.setAntiAlias(shouldAntialias);
- GC2CANVAS(this)->drawPath(path, paint);
- }
-
- if (strokeStyle() != NoStroke) {
- paint.reset();
- m_data->setupPaintStroke(&paint, 0);
- paint.setAntiAlias(shouldAntialias);
- GC2CANVAS(this)->drawPath(path, paint);
- }
-}
-
-void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
- const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace)
-{
- if (paintingDisabled())
- return;
-
- SkPaint paint;
- SkPath path;
- SkScalar radii[8];
-
- radii[0] = SkIntToScalar(topLeft.width());
- radii[1] = SkIntToScalar(topLeft.height());
- radii[2] = SkIntToScalar(topRight.width());
- radii[3] = SkIntToScalar(topRight.height());
- radii[4] = SkIntToScalar(bottomRight.width());
- radii[5] = SkIntToScalar(bottomRight.height());
- radii[6] = SkIntToScalar(bottomLeft.width());
- radii[7] = SkIntToScalar(bottomLeft.height());
- path.addRoundRect(rect, radii);
-
- m_data->setupPaintFill(&paint);
- paint.setColor(color.rgb());
- GC2CANVAS(this)->drawPath(path, paint);
-}
-
-void GraphicsContext::fillRect(const FloatRect& rect)
-{
- save();
- SkPaint paint;
-
- m_data->setupPaintFill(&paint);
-
- extactShader(&paint,
- m_state.fillPattern.get(),
- m_state.fillGradient.get());
-
- GC2CANVAS(this)->drawRect(rect, paint);
- restore();
-}
-
-void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace)
-{
- if (paintingDisabled())
- return;
-
- if (color.rgb() & 0xFF000000) {
- save();
- SkPaint paint;
-
- m_data->setupPaintCommon(&paint);
- paint.setColor(color.rgb()); // Punch in the specified color
- paint.setShader(0); // In case we had one set
-
- // Sometimes we record and draw portions of the page, using clips
- // for each portion. The problem with this is that webkit, sometimes,
- // sees that we're only recording a portion, and they adjust some of
- // their rectangle coordinates accordingly (e.g.
- // RenderBoxModelObject::paintFillLayerExtended() which calls
- // rect.intersect(paintInfo.rect) and then draws the bg with that
- // rect. The result is that we end up drawing rects that are meant to
- // seam together (one for each portion), but if the rects have
- // fractional coordinates (e.g. we are zoomed by a fractional amount)
- // we will double-draw those edges, resulting in visual cracks or
- // artifacts.
-
- // The fix seems to be to just turn off antialasing for rects (this
- // entry-point in GraphicsContext seems to have been sufficient,
- // though perhaps we'll find we need to do this as well in fillRect(r)
- // as well.) Currently setupPaintCommon() enables antialiasing.
-
- // Since we never show the page rotated at a funny angle, disabling
- // antialiasing seems to have no real down-side, and it does fix the
- // bug when we're zoomed (and drawing portions that need to seam).
- paint.setAntiAlias(false);
-
- GC2CANVAS(this)->drawRect(rect, paint);
- restore();
- }
-}
-
-void GraphicsContext::clip(const FloatRect& rect)
-{
- if (paintingDisabled())
- return;
-
- GC2CANVAS(this)->clipRect(rect);
-}
-
-void GraphicsContext::clip(const Path& path)
-{
- if (paintingDisabled())
- return;
-
- GC2CANVAS(this)->clipPath(*path.platformPath(), SkRegion::kIntersect_Op, true);
-}
-
-void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
-{
- if (paintingDisabled())
- return;
-
- SkPath path;
- SkRect r(rect);
-
- path.addOval(r, SkPath::kCW_Direction);
- // Only perform the inset if we won't invert r
- if (2 * thickness < rect.width() && 2 * thickness < rect.height()) {
- // Adding one to the thickness doesn't make the border too thick as
- // it's painted over afterwards. But without this adjustment the
- // border appears a little anemic after anti-aliasing.
- r.inset(SkIntToScalar(thickness + 1), SkIntToScalar(thickness + 1));
- path.addOval(r, SkPath::kCCW_Direction);
- }
- GC2CANVAS(this)->clipPath(path, SkRegion::kIntersect_Op, true);
-}
-
-void GraphicsContext::canvasClip(const Path& path)
-{
- clip(path);
-}
-
-void GraphicsContext::clipOut(const IntRect& r)
-{
- if (paintingDisabled())
- return;
-
- GC2CANVAS(this)->clipRect(r, SkRegion::kDifference_Op);
-}
-
-#if ENABLE(SVG)
-void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule)
-{
- if (paintingDisabled())
- return;
-
- SkPath path = *pathToClip.platformPath();
- path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
- GC2CANVAS(this)->clipPath(path);
-}
-#endif
-
-void GraphicsContext::clipOut(const Path& p)
-{
- if (paintingDisabled())
- return;
-
- GC2CANVAS(this)->clipPath(*p.platformPath(), SkRegion::kDifference_Op);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if SVG_SUPPORT
-KRenderingDeviceContext* GraphicsContext::createRenderingDeviceContext()
-{
- return new KRenderingDeviceContextQuartz(platformContext());
-}
-#endif
-
-// These are the flags we need when we call saveLayer for transparency.
-// Since it does not appear that webkit intends this to also save/restore
-// the matrix or clip, I do not give those flags (for performance)
-#define TRANSPARENCY_SAVEFLAGS \
- (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | \
- SkCanvas::kFullColorLayer_SaveFlag)
-
-void GraphicsContext::beginTransparencyLayer(float opacity)
-{
- if (paintingDisabled())
- return;
-
- SkCanvas* canvas = GC2CANVAS(this);
- canvas->saveLayerAlpha(0, (int)(opacity * 255), TRANSPARENCY_SAVEFLAGS);
-}
-
-void GraphicsContext::endTransparencyLayer()
-{
- if (paintingDisabled())
- return;
-
- GC2CANVAS(this)->restore();
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-void GraphicsContext::setupBitmapPaint(SkPaint* paint)
-{
- m_data->setupPaintBitmap(paint);
-}
-
-void GraphicsContext::setupFillPaint(SkPaint* paint)
-{
- m_data->setupPaintFill(paint);
-}
-
-void GraphicsContext::setupStrokePaint(SkPaint* paint)
-{
- m_data->setupPaintStroke(paint, 0);
-}
-
-bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset)
-{
- return m_data->getState()->setupShadowPaint(this, paint, offset);
-}
-
-void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace)
-{
- m_data->setStrokeColor(c);
-}
-
-void GraphicsContext::setPlatformStrokeThickness(float f)
-{
- m_data->setStrokeThickness(f);
-}
-
-void GraphicsContext::setPlatformFillColor(const Color& c, ColorSpace)
-{
- m_data->setFillColor(c);
-}
-
-void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace)
-{
- if (paintingDisabled())
- return;
-
- if (blur <= 0)
- this->clearPlatformShadow();
-
- SkColor c;
- if (color.isValid())
- c = color.rgb();
- else
- c = SkColorSetARGB(0xFF / 3, 0, 0, 0); // "std" Apple shadow color
- m_data->getState()->setShadow(blur, size.width(), size.height(), c);
-}
-
-void GraphicsContext::clearPlatformShadow()
-{
- if (paintingDisabled())
- return;
-
- m_data->getState()->setShadow(0, 0, 0, 0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
-{
- if (paintingDisabled())
- return;
-
- unsigned rectCount = rects.size();
- if (!rectCount)
- return;
-
- SkRegion focusRingRegion;
- const SkScalar focusRingOutset = WebCoreFloatToSkScalar(0.8);
- for (unsigned i = 0; i < rectCount; i++) {
- SkIRect r = rects[i];
- r.inset(-focusRingOutset, -focusRingOutset);
- focusRingRegion.op(r, SkRegion::kUnion_Op);
- }
-
- SkPath path;
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
-
- paint.setColor(color.rgb());
- paint.setStrokeWidth(focusRingOutset * 2);
- paint.setPathEffect(new SkCornerPathEffect(focusRingOutset * 2))->unref();
- focusRingRegion.getBoundaryPath(&path);
- platformContext()->mCanvas->drawPath(path, paint);
-}
-
-void GraphicsContext::drawFocusRing(const Path&, int, int, const Color&)
-{
- // Do nothing, since we draw the focus ring independently.
-}
-
-PlatformGraphicsContext* GraphicsContext::platformContext() const
-{
- ASSERT(!paintingDisabled());
- return m_data->getPlatformGfxCtx();
-}
-
-void GraphicsContext::setMiterLimit(float limit)
-{
- m_data->getState()->miterLimit = limit;
-}
-
-void GraphicsContext::setAlpha(float alpha)
-{
- m_data->getState()->alpha = alpha;
-}
-
-void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
-{
- m_data->getState()->mode = WebCoreCompositeToSkiaComposite(op);
-}
-
-void GraphicsContext::clearRect(const FloatRect& rect)
-{
- if (paintingDisabled())
- return;
-
- SkPaint paint;
-
- m_data->setupPaintFill(&paint);
- paint.setXfermodeMode(SkXfermode::kClear_Mode);
- GC2CANVAS(this)->drawRect(rect, paint);
-}
-
-void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
-{
- if (paintingDisabled())
- return;
-
- SkPaint paint;
-
- m_data->setupPaintStroke(&paint, 0);
- paint.setStrokeWidth(SkFloatToScalar(lineWidth));
- GC2CANVAS(this)->drawRect(rect, paint);
-}
-
-void GraphicsContext::setLineCap(LineCap cap)
-{
- switch (cap) {
- case ButtCap:
- m_data->getState()->lineCap = SkPaint::kButt_Cap;
- break;
- case RoundCap:
- m_data->getState()->lineCap = SkPaint::kRound_Cap;
- break;
- case SquareCap:
- m_data->getState()->lineCap = SkPaint::kSquare_Cap;
- break;
- default:
- SkDEBUGF(("GraphicsContext::setLineCap: unknown LineCap %d\n", cap));
- break;
- }
-}
-
-#if ENABLE(SVG)
-void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
-{
- if (paintingDisabled())
- return;
-
- size_t dashLength = dashes.size();
- if (!dashLength)
- return;
-
- size_t count = !(dashLength % 2) ? dashLength : dashLength * 2;
- SkScalar* intervals = new SkScalar[count];
-
- for (unsigned int i = 0; i < count; i++)
- intervals[i] = SkFloatToScalar(dashes[i % dashLength]);
- SkPathEffect **effectPtr = &m_data->getState()->pathEffect;
- SkSafeUnref(*effectPtr);
- *effectPtr = new SkDashPathEffect(intervals, count, SkFloatToScalar(dashOffset));
-
- delete[] intervals;
-}
-#endif
-
-void GraphicsContext::setLineJoin(LineJoin join)
-{
- switch (join) {
- case MiterJoin:
- m_data->getState()->lineJoin = SkPaint::kMiter_Join;
- break;
- case RoundJoin:
- m_data->getState()->lineJoin = SkPaint::kRound_Join;
- break;
- case BevelJoin:
- m_data->getState()->lineJoin = SkPaint::kBevel_Join;
- break;
- default:
- SkDEBUGF(("GraphicsContext::setLineJoin: unknown LineJoin %d\n", join));
- break;
- }
-}
-
-void GraphicsContext::scale(const FloatSize& size)
-{
- if (paintingDisabled())
- return;
- GC2CANVAS(this)->scale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
-}
-
-void GraphicsContext::rotate(float angleInRadians)
-{
- if (paintingDisabled())
- return;
- GC2CANVAS(this)->rotate(SkFloatToScalar(angleInRadians * (180.0f / 3.14159265f)));
-}
-
-void GraphicsContext::translate(float x, float y)
-{
- if (paintingDisabled())
- return;
- GC2CANVAS(this)->translate(SkFloatToScalar(x), SkFloatToScalar(y));
-}
-
-void GraphicsContext::concatCTM(const AffineTransform& affine)
-{
- if (paintingDisabled())
- return;
- GC2CANVAS(this)->concat(affine);
-}
-
-// This is intended to round the rect to device pixels (through the CTM)
-// and then invert the result back into source space, with the hope that when
-// it is drawn (through the matrix), it will land in the "right" place (i.e.
-// on pixel boundaries).
-
-// For android, we record this geometry once and then draw it though various
-// scale factors as the user zooms, without re-recording. Thus this routine
-// should just leave the original geometry alone.
-
-// If we instead draw into bitmap tiles, we should then perform this
-// transform -> round -> inverse step.
-
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode)
-{
- return rect;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
-{
-// Appears to be PDF specific, so we ignore it
-#if 0
-if (paintingDisabled())
- return;
-
-CFURLRef urlRef = link.createCFURL();
-if (urlRef) {
- CGContextRef context = platformContext();
-
- // Get the bounding box to handle clipping.
- CGRect box = CGContextGetClipBoundingBox(context);
-
- IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height);
- IntRect rect = destRect;
- rect.intersect(intBox);
-
- CGPDFContextSetURLForRect(context, urlRef,
- CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
-
- CFRelease(urlRef);
-}
-#endif
-}
-
-void GraphicsContext::setPlatformShouldAntialias(bool useAA)
-{
- if (paintingDisabled())
- return;
- m_data->getState()->useAA = useAA;
-}
-
-AffineTransform GraphicsContext::getCTM() const
-{
- const SkMatrix& m = GC2CANVAS(this)->getTotalMatrix();
- return AffineTransform(SkScalarToDouble(m.getScaleX()), // a
- SkScalarToDouble(m.getSkewY()), // b
- SkScalarToDouble(m.getSkewX()), // c
- SkScalarToDouble(m.getScaleY()), // d
- SkScalarToDouble(m.getTranslateX()), // e
- SkScalarToDouble(m.getTranslateY())); // f
-}
-
-void GraphicsContext::setCTM(const AffineTransform& transform)
-{
- // The SkPicture mode of Skia does not support SkCanvas::setMatrix(), so we
- // can not simply use that method here. We could calculate the transform
- // required to achieve the desired matrix and use SkCanvas::concat(), but
- // there's currently no need for this.
- ASSERT_NOT_REACHED();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GraphicsContext::fillPath(const Path& pathToFill)
-{
- SkPath* path = pathToFill.platformPath();
- if (paintingDisabled() || !path)
- return;
-
- switch (this->fillRule()) {
- case RULE_NONZERO:
- path->setFillType(SkPath::kWinding_FillType);
- break;
- case RULE_EVENODD:
- path->setFillType(SkPath::kEvenOdd_FillType);
- break;
- }
-
- SkPaint paint;
- m_data->setupPaintFill(&paint);
-
- extactShader(&paint,
- m_state.fillPattern.get(),
- m_state.fillGradient.get());
-
- GC2CANVAS(this)->drawPath(*path, paint);
-}
-
-void GraphicsContext::strokePath(const Path& pathToStroke)
-{
- const SkPath* path = pathToStroke.platformPath();
- if (paintingDisabled() || !path)
- return;
-
- SkPaint paint;
- m_data->setupPaintStroke(&paint, 0);
-
- extactShader(&paint,
- m_state.strokePattern.get(),
- m_state.strokeGradient.get());
-
- GC2CANVAS(this)->drawPath(*path, paint);
-}
-
-InterpolationQuality GraphicsContext::imageInterpolationQuality() const
-{
- notImplemented();
- return InterpolationDefault;
-}
-
-void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode)
-{
-#if 0
- enum InterpolationQuality {
- InterpolationDefault,
- InterpolationNone,
- InterpolationLow,
- InterpolationMedium,
- InterpolationHigh
- };
-#endif
- // TODO: record this, so we can know when to use bitmap-filtering when we draw
- // ... not sure how meaningful this will be given our playback model.
-
- // Certainly safe to do nothing for the present.
-}
-
-void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias)
-{
- if (paintingDisabled())
- return;
-
- if (numPoints <= 1)
- return;
-
- // FIXME: IMPLEMENT!
-}
-
-void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to, bool isActive)
-{
- if (paintingDisabled())
- return;
-
- IntRect rect = (IntRect)font.selectionRectForText(run, point, h, from, to);
- if (isActive)
- fillRect(rect, backgroundColor, colorSpace);
- else {
- int x = rect.x(), y = rect.y(), w = rect.width(), h = rect.height();
- const int t = 3, t2 = t * 2;
-
- fillRect(IntRect(x, y, w, t), backgroundColor, colorSpace);
- fillRect(IntRect(x, y+h-t, w, t), backgroundColor, colorSpace);
- fillRect(IntRect(x, y+t, t, h-t2), backgroundColor, colorSpace);
- fillRect(IntRect(x+w-t, y+t, t, h-t2), backgroundColor, colorSpace);
- }
-}
-
-} // namespace WebCore
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc)
-{
- return gc->platformContext()->mCanvas;
-}
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 2f9b379..00e6918 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -25,6 +25,7 @@
#include "AndroidAnimation.h"
#include "AndroidLog.h"
#include "Animation.h"
+#include "CanvasLayer.h"
#include "FloatRect.h"
#include "FixedPositioning.h"
#include "GraphicsContext.h"
@@ -33,11 +34,12 @@
#include "Image.h"
#include "ImagesManager.h"
#include "Layer.h"
+#include "LayerAndroid.h"
#include "Length.h"
#include "MediaLayer.h"
#include "PictureLayerContent.h"
#include "PlatformBridge.h"
-#include "PlatformGraphicsContext.h"
+#include "PlatformGraphicsContextSkia.h"
#include "RenderLayerBacking.h"
#include "RenderView.h"
#include "RotateTransformOperation.h"
@@ -119,7 +121,11 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_foregroundClipLayer(0)
{
RenderLayer* renderLayer = renderLayerFromClient(m_client);
- m_contentLayer = new LayerAndroid(renderLayer);
+ if (renderLayer && renderLayer->renderer()->isCanvas()) {
+ m_contentLayer = new CanvasLayer(renderLayer,
+ static_cast<HTMLCanvasElement*>(renderLayer->renderer()->node()));
+ } else
+ m_contentLayer = new LayerAndroid(renderLayer);
m_dirtyRegion.setEmpty();
gDebugGraphicsLayerAndroidInstances++;
}
@@ -290,11 +296,10 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
GraphicsLayer::setPosition(point);
-#ifdef LAYER_DEBUG_2
ALOGV("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
this, point.x(), point.y(), m_position.x(), m_position.y(),
m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
-#endif
+
m_contentLayer->setPosition(point.x(), point.y());
askForSync();
}
@@ -709,7 +714,7 @@ bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
return false;
}
- PlatformGraphicsContext platformContext(canvas);
+ PlatformGraphicsContextSkia platformContext(canvas);
GraphicsContext graphicsContext(&platformContext);
paintGraphicsLayerContents(graphicsContext, rect);
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 27dfde2..97f974e 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -23,7 +23,6 @@
#include "Frame.h"
#include "GraphicsLayer.h"
#include "GraphicsLayerClient.h"
-#include "LayerAndroid.h"
#include "LayerContent.h"
#include "RefPtr.h"
#include "ScrollableLayerAndroid.h"
@@ -37,6 +36,7 @@ class SkRegion;
namespace WebCore {
+class LayerAndroid;
class ScrollableLayerAndroid;
class GraphicsLayerAndroid : public GraphicsLayer {
diff --git a/Source/WebCore/platform/graphics/android/ImageAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
index 8e0c112..08f72e0 100644
--- a/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
@@ -172,20 +172,7 @@ static void round_scaled(SkIRect* dst, const WebCore::FloatRect& src,
SkScalarRound(SkFloatToScalar((src.y() + src.height()) * sy)));
}
-static inline void fixPaintForBitmapsThatMaySeam(SkPaint* paint) {
- /* Bitmaps may be drawn to seem next to other images. If we are drawn
- zoomed, or at fractional coordinates, we may see cracks/edges if
- we antialias, because that will cause us to draw the same pixels
- more than once (e.g. from the left and right bitmaps that share
- an edge).
-
- Disabling antialiasing fixes this, and since so far we are never
- rotated at non-multiple-of-90 angles, this seems to do no harm
- */
- paint->setAntiAlias(false);
-}
-
-void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
+void BitmapImage::draw(GraphicsContext* gc, const FloatRect& dstRect,
const FloatRect& srcRect, ColorSpace,
CompositeOperator compositeOp)
{
@@ -222,14 +209,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
return;
}
- SkCanvas* canvas = ctxt->platformContext()->mCanvas;
- SkPaint paint;
-
- ctxt->setupBitmapPaint(&paint); // need global alpha among other things
- paint.setFilterBitmap(true);
- paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp));
- fixPaintForBitmapsThatMaySeam(&paint);
- canvas->drawBitmapRect(bitmap, &srcR, dstR, &paint);
+ gc->platformContext()->drawBitmapRect(bitmap, &srcR, dstR, compositeOp);
#ifdef TRACE_SUBSAMPLED_BITMAPS
if (bitmap.width() != image->origWidth() ||
@@ -248,26 +228,19 @@ void BitmapImage::setURL(const String& str)
///////////////////////////////////////////////////////////////////////////////
-void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect,
+void Image::drawPattern(GraphicsContext* gc, const FloatRect& srcRect,
const AffineTransform& patternTransform,
const FloatPoint& phase, ColorSpace,
CompositeOperator compositeOp, const FloatRect& destRect)
{
SkBitmapRef* image = this->nativeImageForCurrentFrame();
- if (!image) { // If it's too early we won't have an image yet.
+ if (!image || destRect.isEmpty())
return;
- }
// in case we get called with an incomplete bitmap
const SkBitmap& origBitmap = image->bitmap();
- if (origBitmap.getPixels() == NULL && origBitmap.pixelRef() == NULL) {
+ if (origBitmap.getPixels() == NULL && origBitmap.pixelRef() == NULL)
return;
- }
-
- SkRect dstR(destRect);
- if (dstR.isEmpty()) {
- return;
- }
SkIRect srcR;
// we may have to scale if the image has been subsampled (so save RAM)
@@ -278,11 +251,9 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect,
if (imageIsSubSampled) {
scaleX = (float)image->origWidth() / origBitmap.width();
scaleY = (float)image->origHeight() / origBitmap.height();
-// SkDebugf("----- subsampled %g %g\n", scaleX, scaleY);
round_scaled(&srcR, srcRect, 1 / scaleX, 1 / scaleY);
- } else {
+ } else
round(&srcR, srcRect);
- }
// now extract the proper subset of the src image
SkBitmap bitmap;
@@ -291,19 +262,6 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect,
return;
}
- SkCanvas* canvas = ctxt->platformContext()->mCanvas;
- SkPaint paint;
- ctxt->setupBitmapPaint(&paint); // need global alpha among other things
-
- SkShader* shader = SkShader::CreateBitmapShader(bitmap,
- SkShader::kRepeat_TileMode,
- SkShader::kRepeat_TileMode);
- paint.setShader(shader)->unref();
- // now paint is the only owner of shader
- paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp));
- paint.setFilterBitmap(true);
- fixPaintForBitmapsThatMaySeam(&paint);
-
SkMatrix matrix(patternTransform);
if (imageIsSubSampled) {
@@ -316,26 +274,8 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect,
float tx = phase.x() + srcRect.x() * patternTransform.a();
float ty = phase.y() + srcRect.y() * patternTransform.d();
matrix.postTranslate(SkFloatToScalar(tx), SkFloatToScalar(ty));
- shader->setLocalMatrix(matrix);
-#if 0
- SkDebugf("--- drawPattern: src [%g %g %g %g] dst [%g %g %g %g] transform [%g %g %g %g %g %g] matrix [%g %g %g %g %g %g]\n",
- srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(),
- destRect.x(), destRect.y(), destRect.width(), destRect.height(),
- patternTransform.a(), patternTransform.b(), patternTransform.c(),
- patternTransform.d(), patternTransform.e(), patternTransform.f(),
- matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
-#endif
- canvas->drawRect(dstR, paint);
-#ifdef TRACE_SUBSAMPLED_BITMAPS
- if (bitmap.width() != image->origWidth() ||
- bitmap.height() != image->origHeight()) {
- SkDebugf("--- Image::drawPattern [%d %d] orig [%d %d] dst [%g %g]\n",
- bitmap.width(), bitmap.height(),
- image->origWidth(), image->origHeight(),
- SkScalarToFloat(dstR.width()), SkScalarToFloat(dstR.height()));
- }
-#endif
+ gc->platformContext()->drawBitmapPattern(bitmap, matrix, compositeOp, destRect);
}
// missingImage, textAreaResizeCorner
diff --git a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index f148881..e56f424 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -82,7 +82,10 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
{
ASSERT(context());
- SkCanvas* canvas = context()->platformContext()->mCanvas;
+ SkCanvas* canvas = context()->platformContext()->getCanvas();
+ if (!canvas)
+ return 0;
+
SkDevice* device = canvas->getDevice();
const SkBitmap& orig = device->accessBitmap(false);
diff --git a/Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp b/Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp
deleted file mode 100644
index ed6d046..0000000
--- a/Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "PerformanceMonitor"
-#define LOG_NDEBUG 1
-
-#include "PerformanceMonitor.h"
-
-#include "AndroidLog.h"
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-PerformanceMonitor::PerformanceMonitor()
-{
-}
-
-PerformanceMonitor::~PerformanceMonitor()
-{
-}
-
-void PerformanceMonitor::start(const String &tag)
-{
- if (tag.isEmpty())
- return;
- PerfItem *item;
- if (m_tags.contains(tag))
- item = m_tags.get(tag);
- else {
- item = new PerfItem();
- m_tags.set(tag, item);
- }
- gettimeofday(&(item->start_time), NULL);
-}
-
-void PerformanceMonitor::stop(const String &tag)
-{
- if (!m_tags.contains(tag))
- return;
- PerfItem *item = m_tags.get(tag);
- struct timeval end;
- gettimeofday(&end, NULL);
- long seconds, useconds;
- seconds = end.tv_sec - item->start_time.tv_sec;
- useconds = end.tv_usec - item->start_time.tv_usec;
-
- float mtime = (seconds * 1000.0) + (useconds/1000.0);
-
- if (item->average_ms) {
- item->average_ms = (item->average_ms + mtime) / 2;
- } else
- item->average_ms = mtime;
-}
-
-float PerformanceMonitor::getAverageDuration(const String &tag)
-{
- if (tag.isEmpty() || !m_tags.contains(tag))
- return 0;
- return m_tags.get(tag)->average_ms;
-}
-
-void PerformanceMonitor::display(int limit)
-{
- bool shown = false;
- HashMap<String, PerfItem*, StringHash>::iterator end = m_tags.end();
- for (HashMap<String, PerfItem*, StringHash>::iterator it = m_tags.begin(); it != end; ++it) {
- PerfItem* item = it->second;
- if (item->average_ms > limit) {
- if (!shown) {
- ALOGD("=== DISPLAY MONITOR ====");
- shown = true;
- }
- ALOGD("item %s took longer than %d ms: %.2f", it->first.latin1().data(), limit, item->average_ms);
- }
- }
- if (shown)
- ALOGD("=== END DISPLAY MONITOR ====");
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/PerformanceMonitor.h b/Source/WebCore/platform/graphics/android/PerformanceMonitor.h
deleted file mode 100644
index 4ebbf6a..0000000
--- a/Source/WebCore/platform/graphics/android/PerformanceMonitor.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PerformanceMonitor_h
-#define PerformanceMonitor_h
-
-#include "config.h"
-
-#include <wtf/HashMap.h>
-#include <wtf/text/StringHash.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-namespace WebCore {
-
-struct PerfItem {
- PerfItem() : average_ms(0), start_time() {}
- float average_ms;
- struct timeval start_time;
-};
-
-class PerformanceMonitor {
-public:
- PerformanceMonitor();
- virtual ~PerformanceMonitor();
- void start(const String &tag);
- void stop(const String &tag);
- float getAverageDuration(const String &tag);
- void display(int limit);
-
-private:
- HashMap<String, PerfItem*, StringHash> m_tags;
-};
-
-}
-
-#endif // PerformanceMonitor_h
diff --git a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp
deleted file mode 100644
index 098534c..0000000
--- a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2006, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Node.h"
-#include "PlatformGraphicsContext.h"
-#include "SkCanvas.h"
-
-namespace WebCore {
-
-PlatformGraphicsContext::PlatformGraphicsContext(SkCanvas* canvas)
- : mCanvas(canvas), m_deleteCanvas(false)
-{
-}
-
-PlatformGraphicsContext::PlatformGraphicsContext()
- : mCanvas(new SkCanvas), m_deleteCanvas(true)
-{
-}
-
-PlatformGraphicsContext::~PlatformGraphicsContext()
-{
- if (m_deleteCanvas) {
-// printf("-------------------- deleting offscreen canvas\n");
- delete mCanvas;
- }
-}
-
-} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
deleted file mode 100644
index 80ea5d6..0000000
--- a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2006, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef platform_graphics_context_h
-#define platform_graphics_context_h
-
-#include "IntRect.h"
-#include "RenderSkinAndroid.h"
-#include "SkCanvas.h"
-#include "SkPicture.h"
-#include "SkTDArray.h"
-
-class SkCanvas;
-
-namespace WebCore {
-
- class GraphicsContext;
-
-class PlatformGraphicsContext {
-public:
- PlatformGraphicsContext();
- // Pass in a recording canvas, and an array of button information to be
- // updated.
- PlatformGraphicsContext(SkCanvas* canvas);
- ~PlatformGraphicsContext();
-
- SkCanvas* mCanvas;
-
- bool deleteUs() const { return m_deleteCanvas; }
-private:
- bool m_deleteCanvas;
-};
-
-}
-#endif
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp
deleted file mode 100644
index a4c0ac8..0000000
--- a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "SurfaceCollection"
-#define LOG_NDEBUG 1
-
-#include "config.h"
-#include "SurfaceCollection.h"
-
-#include "AndroidLog.h"
-#include "BaseLayerAndroid.h"
-#include "ClassTracker.h"
-#include "LayerAndroid.h"
-#include "LayerGroup.h"
-#include "GLWebViewState.h"
-#include "ScrollableLayerAndroid.h"
-#include "TilesManager.h"
-
-namespace WebCore {
-
-////////////////////////////////////////////////////////////////////////////////
-// TILED PAINTING / GROUPS //
-////////////////////////////////////////////////////////////////////////////////
-
-SurfaceCollection::SurfaceCollection(BaseLayerAndroid* baseLayer)
- : m_baseLayer(baseLayer)
- , m_compositedRoot(0)
-{
- if (!m_baseLayer)
- return;
-
- SkSafeRef(m_baseLayer);
- if (m_baseLayer->countChildren()) {
- m_compositedRoot = static_cast<LayerAndroid*>(m_baseLayer->getChild(0));
-
- // calculate draw transforms and z values
- SkRect visibleRect = SkRect::MakeLTRB(0, 0, 1, 1);
- m_baseLayer->updateLayerPositions(visibleRect);
-
- // allocate groups for layers, merging where possible
- ALOGV("new tree, allocating groups for tree %p", m_baseLayer);
-
- LayerMergeState layerMergeState(&m_layerGroups);
- m_compositedRoot->assignGroups(&layerMergeState);
- }
-
- // set the layergroups' and tiledpages' update count, to be drawn on painted tiles
- unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates();
- for (unsigned int i = 0; i < m_layerGroups.size(); i++)
- m_layerGroups[i]->setUpdateCount(updateCount);
- m_baseLayer->state()->frontPage()->setUpdateCount(updateCount);
- m_baseLayer->state()->backPage()->setUpdateCount(updateCount);
-
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("SurfaceCollection");
-#endif
-}
-
-SurfaceCollection::~SurfaceCollection()
-{
- SkSafeUnref(m_baseLayer);
- for (unsigned int i = 0; i < m_layerGroups.size(); i++)
- SkSafeUnref(m_layerGroups[i]);
- m_layerGroups.clear();
-
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("SurfaceCollection");
-#endif
-}
-
-void SurfaceCollection::prepareGL(const SkRect& visibleRect, float scale, double currentTime)
-{
- if (!m_baseLayer)
- return;
-
- m_baseLayer->prepareGL(visibleRect, scale, currentTime);
-
- if (m_compositedRoot) {
- m_baseLayer->updateLayerPositions(visibleRect);
- bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode()
- > GLWebViewState::kClippedTextures;
- for (unsigned int i = 0; i < m_layerGroups.size(); i++)
- m_layerGroups[i]->prepareGL(layerTilesDisabled);
- }
-}
-
-bool SurfaceCollection::drawGL(const SkRect& visibleRect, float scale)
-{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->show();
-#endif
-
- if (!m_baseLayer)
- return false;
-
- m_baseLayer->drawGL(scale);
-
- bool needsRedraw = false;
- if (m_compositedRoot) {
- m_baseLayer->updateLayerPositions(visibleRect);
- bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode()
- > GLWebViewState::kClippedTextures;
- for (unsigned int i = 0; i < m_layerGroups.size(); i++)
- needsRedraw |= m_layerGroups[i]->drawGL(layerTilesDisabled);
- }
-
- return needsRedraw;
-}
-
-void SurfaceCollection::swapTiles()
-{
- if (!m_baseLayer)
- return;
-
- m_baseLayer->swapTiles();
-
- for (unsigned int i = 0; i < m_layerGroups.size(); i++)
- m_layerGroups[i]->swapTiles();
-}
-
-bool SurfaceCollection::isReady()
-{
- if (!m_baseLayer)
- return true;
-
- if (!m_baseLayer->isReady())
- return false;
-
- if (!m_compositedRoot)
- return true;
-
- // Override layer readiness check for single surface mode
- if (m_compositedRoot->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) {
- // TODO: single surface mode should be properly double buffered
- return true;
- }
-
- for (unsigned int i = 0; i < m_layerGroups.size(); i++) {
- if (!m_layerGroups[i]->isReady()) {
- ALOGV("layer group %p isn't ready", m_layerGroups[i]);
- return false;
- }
- }
- return true;
-}
-
-void SurfaceCollection::computeTexturesAmount(TexturesResult* result)
-{
- for (unsigned int i = 0; i < m_layerGroups.size(); i++)
- m_layerGroups[i]->computeTexturesAmount(result);
-}
-
-void SurfaceCollection::drawCanvas(SkCanvas* canvas, bool drawLayers)
-{
- // TODO: move this functionality out!
- if (!m_baseLayer)
- return;
-
- m_baseLayer->drawCanvas(canvas);
-
- // draw the layers onto the same canvas (for single surface mode)
- if (drawLayers && m_compositedRoot)
- m_compositedRoot->drawCanvas(canvas, true, Layer::FlattenedLayers);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// RECURSIVE ANIMATION / INVALS / LAYERS //
-////////////////////////////////////////////////////////////////////////////////
-
-void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface)
-{
- if (!m_baseLayer)
- return;
-
- m_baseLayer->setIsPainting();
-
- if (!drawingSurface)
- return;
-
- for (unsigned int i = 0; i < m_layerGroups.size(); i++) {
- LayerGroup* newLayerGroup = m_layerGroups[i];
- if (!newLayerGroup->needsTexture())
- continue;
-
- for (unsigned int j = 0; j < drawingSurface->m_layerGroups.size(); j++) {
- LayerGroup* oldLayerGroup = drawingSurface->m_layerGroups[j];
- if (newLayerGroup->tryUpdateLayerGroup(oldLayerGroup))
- break;
- }
- }
-}
-
-void SurfaceCollection::setIsDrawing()
-{
- if (m_compositedRoot)
- m_compositedRoot->initAnimations();
-}
-
-void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface)
-{
- if (!m_baseLayer)
- return;
-
- m_baseLayer->mergeInvalsInto(replacementSurface->m_baseLayer);
-
- if (m_compositedRoot && replacementSurface->m_compositedRoot)
- m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot);
-}
-
-void SurfaceCollection::evaluateAnimations(double currentTime)
-{
- if (m_compositedRoot)
- m_compositedRoot->evaluateAnimations(currentTime);
-}
-
-bool SurfaceCollection::hasCompositedLayers()
-{
- return m_compositedRoot != 0;
-}
-
-bool SurfaceCollection::hasCompositedAnimations()
-{
- return m_compositedRoot != 0 && m_compositedRoot->hasAnimations();
-}
-
-int SurfaceCollection::baseContentWidth()
-{
- // TODO: move this functionality out!
- return m_baseLayer ? m_baseLayer->content()->width() : 0;
-}
-
-int SurfaceCollection::baseContentHeight()
-{
- // TODO: move this functionality out!
- return m_baseLayer ? m_baseLayer->content()->height() : 0;
-}
-
-void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y)
-{
- if (m_compositedRoot) {
- LayerAndroid* layer = m_compositedRoot->findById(layerId);
- if (layer && layer->contentIsScrollable())
- static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
- }
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
deleted file mode 100644
index afa2014..0000000
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "TiledPage"
-#define LOG_NDEBUG 1
-
-#include "config.h"
-#include "TiledPage.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "AndroidLog.h"
-#include "GLUtils.h"
-#include "IntRect.h"
-#include "PaintTileOperation.h"
-#include "SkPaint.h"
-#include "SkPaintFlagsDrawFilter.h"
-#include "TilesManager.h"
-
-namespace WebCore {
-
-using namespace android;
-
-TiledPage::TiledPage(int id, GLWebViewState* state)
- : m_baseTiles(0)
- , m_baseTileSize(0)
- , m_id(id)
- , m_scale(1)
- , m_invScale(1)
- , m_glWebViewState(state)
- , m_prepare(false)
- , m_isPrefetchPage(false)
- , m_willDraw(false)
-{
- m_baseTiles = new BaseTile[TilesManager::getMaxTextureAllocation() + 1];
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("TiledPage");
-#endif
-}
-
-void TiledPage::updateBaseTileSize()
-{
- // This value must be at least 1 greater than the max number of allowed
- // textures. This is because prepare() asks for a tile before it reserves
- // a texture for that tile. If all textures are currently in use by the
- // page then there will be no available tile and having the extra tile
- // ensures that this does not happen. After claiming the extra tile the call
- // to reserveTexture() will cause some other tile in the page to lose it's
- // texture and become available, thus ensuring that we always have at least
- // one tile that is available.
- int baseTileSize = TilesManager::instance()->maxTextureCount() + 1;
- if (baseTileSize > m_baseTileSize)
- m_baseTileSize = baseTileSize;
-}
-
-TiledPage::~TiledPage()
-{
- TilesManager* tilesManager = TilesManager::instance();
- // In order to delete the page we must ensure that none of its BaseTiles are
- // currently painting or scheduled to be painted by the TextureGenerator
- tilesManager->removeOperationsForPage(this);
- // Discard the transfer queue after the removal operation to make sure
- // no tiles for this page will be left in the transfer queue.
- tilesManager->transferQueue()->setPendingDiscardWithLock();
- delete[] m_baseTiles;
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("TiledPage");
-#endif
-}
-
-BaseTile* TiledPage::getBaseTile(int x, int y) const
-{
- // TODO: replace loop over array with HashMap indexing
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- if (tile.x() == x && tile.y() == y)
- return &tile;
- }
- return 0;
-}
-
-void TiledPage::discardTextures()
-{
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- tile.discardTextures();
- }
- return;
-}
-
-void TiledPage::invalidateRect(const IntRect& inval)
-{
-#ifdef DEBUG
- // Given the current scale level we need to mark the appropriate tiles as dirty
- const float invTileContentWidth = m_scale / TilesManager::tileWidth();
- const float invTileContentHeight = m_scale / TilesManager::tileHeight();
-
- const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth));
- const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight));
- const int lastDirtyTileX = static_cast<int>(ceilf(inval.maxX() * invTileContentWidth));
- const int lastDirtyTileY = static_cast<int>(ceilf(inval.maxY() * invTileContentHeight));
-
- ALOGV("Marking X %d-%d and Y %d-%d dirty",
- firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY);
-#endif
- // We defer marking the tile as dirty until the next time we need to prepare
- // to draw.
- m_invalRegion.op(inval.x(), inval.y(), inval.maxX(), inval.maxY(), SkRegion::kUnion_Op);
-}
-
-void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds)
-{
- for (int i = 0; i < tilesInRow; i++) {
- int x = firstTileX;
-
- // If we are goingLeft, we want to schedule the tiles starting from the
- // right (and to the left if not). This is because tiles are appended to
- // the list and the texture uploader goes through the set front to back.
- if (goingLeft)
- x += (tilesInRow - 1) - i;
- else
- x += i;
-
- BaseTile* currentTile = 0;
- BaseTile* availableTile = 0;
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- if (tile.x() == x && tile.y() == y) {
- currentTile = &tile;
- break;
- }
-
- if (!availableTile || (tile.drawCount() < availableTile->drawCount()))
- availableTile = &tile;
- }
-
- if (!currentTile && availableTile) {
- ALOGV("STEALING tile %d, %d (draw count %llu) for tile %d, %d",
- availableTile->x(), availableTile->y(), availableTile->drawCount(), x, y);
- availableTile->discardTextures(); // don't wait for textures to be stolen
- currentTile = availableTile;
- }
-
- if (!currentTile) {
- ALOGV("ERROR: No tile available for tile %d %d", x, y);
- }
-
- if (currentTile) {
- currentTile->setGLWebViewState(m_glWebViewState);
- currentTile->setPage(this);
-
- currentTile->setContents(x, y, m_scale);
-
- // TODO: move below (which is largely the same for layers / tiled
- // page) into prepare() function
-
- // ensure there is a texture associated with the tile and then check to
- // see if the texture is dirty and in need of repainting
- if (currentTile->isDirty() || !currentTile->frontTexture())
- currentTile->reserveTexture();
- if (currentTile->backTexture()
- && currentTile->isDirty()
- && !currentTile->isRepaintPending()) {
- PaintTileOperation *operation = new PaintTileOperation(currentTile, this);
- TilesManager::instance()->scheduleOperation(operation);
- }
- }
- }
-}
-
-void TiledPage::updateTileDirtiness()
-{
- if (!m_glWebViewState || m_invalRegion.isEmpty())
- return;
-
- for (int x = 0; x < m_baseTileSize; x++)
- m_baseTiles[x].markAsDirty(m_invalRegion);
-
- // clear the invalidated region as all tiles within that region have now
- // been marked as dirty.
- m_invalRegion.setEmpty();
-}
-
-void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds)
-{
- if (!m_glWebViewState)
- return;
-
- TilesManager::instance()->gatherTextures();
- m_scrollingDown = goingDown;
-
- int firstTileX = tileBounds.fLeft;
- int firstTileY = tileBounds.fTop;
- int nbTilesWidth = tileBounds.width();
- int nbTilesHeight = tileBounds.height();
-
- if (bounds == ExpandedBounds) {
- // prepare tiles outside of the visible bounds
- int expandX = m_glWebViewState->expandedTileBoundsX();
- int expandY = m_glWebViewState->expandedTileBoundsY();
-
- firstTileX -= expandX;
- nbTilesWidth += expandX * 2;
-
- firstTileY -= expandY;
- nbTilesHeight += expandY * 2;
- }
-
- // crop the tile bounds in each dimension to the larger of the base layer or viewport
- float maxBaseX = m_glWebViewState->baseContentWidth() * m_scale / TilesManager::tileWidth();
- float maxBaseY = m_glWebViewState->baseContentHeight() * m_scale / TilesManager::tileHeight();
- int maxX = std::max(static_cast<int>(ceilf(maxBaseX)),
- m_glWebViewState->viewportTileBounds().width());
- int maxY = std::max(static_cast<int>(ceilf(maxBaseY)),
- m_glWebViewState->viewportTileBounds().height());
-
- // adjust perimeter to not go outside cropped region
- if (firstTileX < 0) {
- nbTilesWidth += firstTileX;
- firstTileX = 0;
- }
- if (firstTileY < 0) {
- nbTilesHeight += firstTileY;
- firstTileY = 0;
- }
- nbTilesWidth = std::min(nbTilesWidth, maxX - firstTileX + 1);
- nbTilesHeight = std::min(nbTilesHeight, maxY - firstTileY + 1);
-
- // check against corrupted scale values giving bad height/width (use float to avoid overflow)
- float numTiles = static_cast<float>(nbTilesHeight) * static_cast<float>(nbTilesWidth);
- if (numTiles > TilesManager::getMaxTextureAllocation() || nbTilesHeight < 1 || nbTilesWidth < 1)
- {
- ALOGE("ERROR: We don't have enough tiles for this page!"
- " nbTilesHeight %d nbTilesWidth %d", nbTilesHeight, nbTilesWidth);
- return;
- }
- for (int i = 0; i < nbTilesHeight; i++)
- prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, tileBounds);
-
- m_prepare = true;
-}
-
-bool TiledPage::hasMissingContent(const SkIRect& tileBounds)
-{
- int neededTiles = tileBounds.width() * tileBounds.height();
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- if (tileBounds.contains(tile.x(), tile.y())) {
- if (tile.frontTexture())
- neededTiles--;
- }
- }
- return neededTiles > 0;
-}
-
-bool TiledPage::isReady(const SkIRect& tileBounds)
-{
- int neededTiles = tileBounds.width() * tileBounds.height();
- ALOGV("tiled page %p needs %d ready tiles", this, neededTiles);
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- if (tileBounds.contains(tile.x(), tile.y())) {
- if (tile.isTileReady())
- neededTiles--;
- }
- }
- ALOGV("tiled page %p still needs %d ready tiles", this, neededTiles);
- return neededTiles == 0;
-}
-
-bool TiledPage::swapBuffersIfReady(const SkIRect& tileBounds, float scale)
-{
- if (!m_glWebViewState)
- return false;
-
- if (!m_invalRegion.isEmpty() && !m_prepare)
- return false;
-
- if (m_scale != scale)
- return false;
-
- int swaps = 0;
- bool fullSwap = true;
- for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) {
- for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) {
- BaseTile* t = getBaseTile(x, y);
- if (!t || !t->isTileReady())
- fullSwap = false;
- }
- }
-
- // swap every tile on page (even if off screen)
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- if (tile.swapTexturesIfNeeded())
- swaps++;
- }
-
- ALOGV("%p greedy swapped %d textures, returning %d", this, swaps, fullSwap);
- return fullSwap;
-}
-
-void TiledPage::prepareForDrawGL(float opacity, const SkIRect& tileBounds)
-{
- m_willDraw = true;
- m_opacity = opacity;
- m_tileBounds = tileBounds;
-}
-
-void TiledPage::drawGL()
-{
- if (!m_glWebViewState || m_opacity == 0 || !m_willDraw)
- return;
-
- const float tileWidth = TilesManager::tileWidth() * m_invScale;
- const float tileHeight = TilesManager::tileHeight() * m_invScale;
-
- for (int j = 0; j < m_baseTileSize; j++) {
- BaseTile& tile = m_baseTiles[j];
- bool tileInView = m_tileBounds.contains(tile.x(), tile.y());
- if (tileInView) {
- SkRect rect;
- rect.fLeft = tile.x() * tileWidth;
- rect.fTop = tile.y() * tileHeight;
- rect.fRight = rect.fLeft + tileWidth;
- rect.fBottom = rect.fTop + tileHeight;
-
- tile.drawGL(m_opacity, rect, m_scale, 0);
- }
-
- TilesManager::instance()->getProfiler()->nextTile(tile, m_invScale, tileInView);
- }
- m_willDraw = false; // don't redraw until re-prepared
-}
-
-bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas)
-{
- static SkPaintFlagsDrawFilter prefetchFilter(SkPaint::kAllFlags,
- SkPaint::kAntiAlias_Flag);
-
- if (!m_glWebViewState)
- return false;
-
- if (isPrefetchPage())
- canvas->setDrawFilter(&prefetchFilter);
-
- m_glWebViewState->paintBaseLayerContent(canvas);
- return true;
-}
-
-TiledPage* TiledPage::sibling()
-{
- if (!m_glWebViewState)
- return 0;
- return m_glWebViewState->sibling(this);
-}
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h
deleted file mode 100644
index 5587618..0000000
--- a/Source/WebCore/platform/graphics/android/TiledPage.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TiledPage_h
-#define TiledPage_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "BaseTile.h"
-#include "SkCanvas.h"
-#include "SkRegion.h"
-
-#include "TilePainter.h"
-
-namespace WebCore {
-
-class GLWebViewState;
-class IntRect;
-
-/**
- * The TiledPage represents a map of BaseTiles covering the viewport. Each
- * GLWebViewState contains two TiledPages, one to display the page at the
- * current scale factor, and another in the background that we use to paint the
- * page at a different scale factor. For instance, when we zoom using one
- * TiledPage its tiles are scaled in hardware and therefore are subject to a
- * loss of quality. To address this when the user finishes zooming we paint the
- * background TilePage at the new scale factor. When the background TilePage is
- * ready, we swap it with the currently displaying TiledPage.
- */
-class TiledPage : public TilePainter {
-public:
- enum PrepareBounds {
- ExpandedBounds = 0,
- VisibleBounds = 1
- };
-
- TiledPage(int id, GLWebViewState* state);
- ~TiledPage();
-
- // returns the other TiledPage who shares the same GLWebViewState
- TiledPage* sibling();
-
- // prepare the page for display on the screen
- void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds);
-
- // update tiles with inval information
- void updateTileDirtiness();
-
- // returns true if the page can't draw the entire region (may still be stale)
- bool hasMissingContent(const SkIRect& tileBounds);
-
- bool isReady(const SkIRect& tileBounds);
-
- // swap 'buffers' by swapping each modified texture
- bool swapBuffersIfReady(const SkIRect& tileBounds, float scale);
- // save the opacity and bounds to be drawn in drawGL()
- void prepareForDrawGL(float opacity, const SkIRect& tileBounds);
- // draw the page on the screen
- void drawGL();
-
- // TilePainter implementation
- // used by individual tiles to generate the bitmap for their tile
- bool paint(BaseTile* tile, SkCanvas* canvas);
-
- // used by individual tiles to get the information about the current picture
- GLWebViewState* glWebViewState() { return m_glWebViewState; }
-
- float scale() const { return m_scale; }
-
- //TODO: clear all textures if this is called with a new value
- void setScale(float scale) { m_scale = scale; m_invScale = 1 / scale; }
-
- void invalidateRect(const IntRect& invalRect);
- void discardTextures();
- void updateBaseTileSize();
- bool scrollingDown() { return m_scrollingDown; }
- bool isPrefetchPage() { return m_isPrefetchPage; }
- void setIsPrefetchPage(bool isPrefetch) { m_isPrefetchPage = isPrefetch; }
-
-private:
- void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds);
-
- BaseTile* getBaseTile(int x, int y) const;
-
- // array of tiles used to compose a page. The tiles are allocated in the
- // constructor to prevent them from potentially being allocated on the stack
- BaseTile* m_baseTiles;
- // stores the number of tiles in the m_baseTiles array. This enables us to
- // quickly iterate over the array without have to check it's size
- int m_baseTileSize;
- int m_id;
- float m_scale;
- float m_invScale;
- GLWebViewState* m_glWebViewState;
-
-
- SkRegion m_invalRegion; // in content coordinates
- bool m_prepare;
- bool m_scrollingDown;
- bool m_isPrefetchPage;
-
- // info saved in prepare, used in drawGL()
- bool m_willDraw;
- SkIRect m_tileBounds;
- float m_opacity;
-};
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
-#endif // TiledPage_h
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
deleted file mode 100644
index 039e28c..0000000
--- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "TiledTexture"
-#define LOG_NDEBUG 1
-
-#include "config.h"
-#include "TiledTexture.h"
-
-#include "AndroidLog.h"
-#include "PaintTileOperation.h"
-#include "SkCanvas.h"
-#include "SkPicture.h"
-#include "TilesManager.h"
-
-#include <wtf/CurrentTime.h>
-
-namespace WebCore {
-
-TiledTexture::~TiledTexture()
-{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("TiledTexture");
-#endif
- removeTiles();
-}
-
-bool TiledTexture::isReady()
-{
- bool tilesAllReady = true;
- bool tilesVisible = false;
- for (unsigned int i = 0; i < m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
- if (tile->isTileVisible(m_area)) {
- tilesVisible = true;
- if (!tile->isTileReady()) {
- tilesAllReady = false;
- break;
- }
- }
- }
- // For now, if no textures are available, consider ourselves as ready
- // in order to unblock the zooming process.
- // FIXME: have a better system -- maybe keeping the last scale factor
- // able to fully render everything
- ALOGV("TT %p, ready %d, visible %d, texturesRemain %d",
- this, tilesAllReady, tilesVisible,
- TilesManager::instance()->layerTexturesRemain());
-
- return !TilesManager::instance()->layerTexturesRemain()
- || !tilesVisible || tilesAllReady;
-}
-
-void TiledTexture::swapTiles()
-{
- int swaps = 0;
- for (unsigned int i = 0; i < m_tiles.size(); i++)
- if (m_tiles[i]->swapTexturesIfNeeded())
- swaps++;
- ALOGV("TT %p swapping, swaps = %d", this, swaps);
-}
-
-IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale)
-{
- IntRect computedArea;
- IntRect area(contentArea.x() * scale,
- contentArea.y() * scale,
- ceilf(contentArea.width() * scale),
- ceilf(contentArea.height() * scale));
-
- ALOGV("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height());
-
- if (area.width() == 0 && area.height() == 0) {
- computedArea.setWidth(0);
- computedArea.setHeight(0);
- return computedArea;
- }
-
- int tileWidth = TilesManager::instance()->layerTileWidth();
- int tileHeight = TilesManager::instance()->layerTileHeight();
-
- computedArea.setX(area.x() / tileWidth);
- computedArea.setY(area.y() / tileHeight);
- float right = (area.x() + area.width()) / (float) tileWidth;
- float bottom = (area.y() + area.height()) / (float) tileHeight;
- computedArea.setWidth(ceilf(right) - computedArea.x());
- computedArea.setHeight(ceilf(bottom) - computedArea.y());
- return computedArea;
-}
-
-void TiledTexture::prepareGL(GLWebViewState* state, float scale,
- const IntRect& prepareArea, TilePainter* painter)
-{
- // first, how many tiles do we need
- m_area = computeTilesArea(prepareArea, scale);
- if (m_area.isEmpty())
- return;
-
- ALOGV("prepare TiledTexture %p with scale %.2f, prepareArea "
- " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
- this, scale,
- prepareArea.x(), prepareArea.y(),
- prepareArea.width(), prepareArea.height(),
- m_area.x(), m_area.y(),
- m_area.width(), m_area.height());
-
- bool goingDown = m_prevTileY < m_area.y();
- m_prevTileY = m_area.y();
-
- if (scale != m_scale)
- TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, scale));
-
- m_scale = scale;
-
- // apply dirty region to affected tiles
- if (!m_dirtyRegion.isEmpty()) {
- for (unsigned int i = 0; i < m_tiles.size(); i++)
- m_tiles[i]->markAsDirty(m_dirtyRegion);
- m_dirtyRegion.setEmpty();
- }
-
- for (int i = 0; i < m_area.width(); i++) {
- if (goingDown) {
- for (int j = 0; j < m_area.height(); j++)
- prepareTile(m_area.x() + i, m_area.y() + j, painter);
- } else {
- for (int j = m_area.height() - 1; j >= 0; j--)
- prepareTile(m_area.x() + i, m_area.y() + j, painter);
- }
- }
-}
-
-void TiledTexture::markAsDirty(const SkRegion& invalRegion)
-{
- ALOGV("TT %p markAsDirty, current region empty %d, new empty %d",
- this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty());
- m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
-}
-
-void TiledTexture::prepareTile(int x, int y, TilePainter* painter)
-{
- BaseTile* tile = getTile(x, y);
- if (!tile) {
- tile = new BaseTile(true);
- m_tiles.append(tile);
- }
-
- ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter);
- tile->setContents(x, y, m_scale);
-
- // TODO: move below (which is largely the same for layers / tiled page) into
- // prepareGL() function
-
- if (tile->isDirty() || !tile->frontTexture())
- tile->reserveTexture();
-
- if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) {
- ALOGV("painting TT %p's tile %d %d for LG %p", this, x, y, painter);
- PaintTileOperation *operation = new PaintTileOperation(tile, painter);
- TilesManager::instance()->scheduleOperation(operation);
- }
-}
-
-BaseTile* TiledTexture::getTile(int x, int y)
-{
- for (unsigned int i = 0; i <m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
- if (tile->x() == x && tile->y() == y)
- return tile;
- }
- return 0;
-}
-
-int TiledTexture::nbTextures(IntRect& area, float scale)
-{
- IntRect tileBounds = computeTilesArea(area, scale);
- int numberTextures = tileBounds.width() * tileBounds.height();
-
- // add the number of dirty tiles in the bounds, as they take up double
- // textures for double buffering
- for (unsigned int i = 0; i <m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
- if (tile->isDirty()
- && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX()
- && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY())
- numberTextures++;
- }
- return numberTextures;
-}
-
-bool TiledTexture::drawGL(const IntRect& visibleArea, float opacity,
- const TransformationMatrix* transform)
-{
- m_area = computeTilesArea(visibleArea, m_scale);
- if (m_area.width() == 0 || m_area.height() == 0)
- return false;
-
- float m_invScale = 1 / m_scale;
- const float tileWidth = TilesManager::layerTileWidth() * m_invScale;
- const float tileHeight = TilesManager::layerTileHeight() * m_invScale;
-
- int drawn = 0;
- bool askRedraw = false;
- for (unsigned int i = 0; i < m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
-
- if (tile->isTileVisible(m_area)) {
- askRedraw |= !tile->isTileReady();
- SkRect rect;
- rect.fLeft = tile->x() * tileWidth;
- rect.fTop = tile->y() * tileHeight;
- rect.fRight = rect.fLeft + tileWidth;
- rect.fBottom = rect.fTop + tileHeight;
- ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
- tile, tile->isLayerTile(), tile->x(), tile->y(),
- tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
- tile->drawGL(opacity, rect, m_scale, transform);
- if (tile->frontTexture())
- drawn++;
- }
- }
- ALOGV("TT %p drew %d tiles, redraw due to notready %d, scale %f",
- this, drawn, askRedraw, m_scale);
-
- // need to redraw if some visible tile wasn't ready
- return askRedraw;
-}
-
-void TiledTexture::removeTiles()
-{
- for (unsigned int i = 0; i < m_tiles.size(); i++) {
- delete m_tiles[i];
- }
- m_tiles.clear();
-}
-
-void TiledTexture::discardTextures()
-{
- ALOGV("TT %p discarding textures", this);
- for (unsigned int i = 0; i < m_tiles.size(); i++)
- m_tiles[i]->discardTextures();
-}
-
-bool TiledTexture::owns(BaseTileTexture* texture)
-{
- for (unsigned int i = 0; i < m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
- if (tile->frontTexture() == texture)
- return true;
- if (tile->backTexture() == texture)
- return true;
- }
- return false;
-}
-
-DualTiledTexture::DualTiledTexture()
-{
- m_textureA = new TiledTexture();
- m_textureB = new TiledTexture();
- m_frontTexture = m_textureA;
- m_backTexture = m_textureB;
- m_scale = -1;
- m_futureScale = -1;
- m_zooming = false;
-}
-
-DualTiledTexture::~DualTiledTexture()
-{
- delete m_textureA;
- delete m_textureB;
-}
-
-void DualTiledTexture::prepareGL(GLWebViewState* state, bool allowZoom,
- const IntRect& prepareArea, TilePainter* painter)
-{
- // If we are zooming, we will use the previously used area, to prevent the
- // frontTexture to try to allocate more tiles than what it has already
- if (!m_zooming)
- m_preZoomPrepareArea = prepareArea;
-
- float scale = state->scale();
- if (scale > 1 && !allowZoom)
- scale = 1;
-
- if (m_scale == -1) {
- m_scale = scale;
- m_futureScale = scale;
- }
-
- if (m_futureScale != scale) {
- m_futureScale = scale;
- m_zoomUpdateTime = WTF::currentTime() + DualTiledTexture::s_zoomUpdateDelay;
- m_zooming = true;
- }
-
- ALOGV("Prepare DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d, f %p, b %p",
- this, scale, m_scale, m_futureScale, m_zooming,
- m_frontTexture, m_backTexture);
-
- if (m_scale > 0)
- m_frontTexture->prepareGL(state, m_scale, m_preZoomPrepareArea, painter);
-
- // If we had a scheduled update
- if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) {
- m_backTexture->prepareGL(state, m_futureScale, prepareArea, painter);
- if (m_backTexture->isReady()) {
- m_backTexture->swapTiles();
- swap();
- m_zooming = false;
- }
- }
-}
-
-void DualTiledTexture::swap()
-{
- m_frontTexture = m_frontTexture == m_textureA ? m_textureB : m_textureA;
- m_backTexture = m_backTexture == m_textureA ? m_textureB : m_textureA;
- m_scale = m_futureScale;
- m_backTexture->discardTextures();
-}
-
-bool DualTiledTexture::drawGL(const IntRect& visibleArea, float opacity,
- const TransformationMatrix* transform)
-{
- bool needsRepaint = m_frontTexture->drawGL(visibleArea, opacity, transform);
- needsRepaint |= m_zooming;
- needsRepaint |= (m_scale <= 0);
- return needsRepaint;
-}
-
-void DualTiledTexture::markAsDirty(const SkRegion& dirtyArea)
-{
- m_backTexture->markAsDirty(dirtyArea);
- m_frontTexture->markAsDirty(dirtyArea);
-}
-
-void DualTiledTexture::swapTiles()
-{
- m_backTexture->swapTiles();
- m_frontTexture->swapTiles();
-}
-
-bool DualTiledTexture::owns(BaseTileTexture* texture)
-{
- bool owns = m_textureA->owns(texture);
- owns |= m_textureB->owns(texture);
- return owns;
-}
-
-void DualTiledTexture::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer)
-{
- // TODO: shouldn't use layer, as this DTT may paint multiple layers
- if (!layer)
- return;
-
- IntRect unclippedArea = layer->unclippedArea();
- IntRect clippedVisibleArea = layer->visibleArea();
-
- // get two numbers here:
- // - textures needed for a clipped area
- // - textures needed for an un-clipped area
- TiledTexture* tiledTexture = m_zooming ? m_backTexture : m_frontTexture;
- int nbTexturesUnclipped = tiledTexture->nbTextures(unclippedArea, m_scale);
- int nbTexturesClipped = tiledTexture->nbTextures(clippedVisibleArea, m_scale);
-
- // Set kFixedLayers level
- if (layer->isPositionFixed())
- result->fixed += nbTexturesClipped;
-
- // Set kScrollableAndFixedLayers level
- if (layer->contentIsScrollable()
- || layer->isPositionFixed())
- result->scrollable += nbTexturesClipped;
-
- // Set kClippedTextures level
- result->clipped += nbTexturesClipped;
-
- // Set kAllTextures level
- if (layer->contentIsScrollable())
- result->full += nbTexturesClipped;
- else
- result->full += nbTexturesUnclipped;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h
deleted file mode 100644
index cf7c77c..0000000
--- a/Source/WebCore/platform/graphics/android/TiledTexture.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TiledTexture_h
-#define TiledTexture_h
-
-#include "BaseTile.h"
-#include "BaseTileTexture.h"
-#include "ClassTracker.h"
-#include "IntRect.h"
-#include "LayerAndroid.h"
-#include "SkRefCnt.h"
-#include "SkRegion.h"
-#include "TextureOwner.h"
-#include "TilePainter.h"
-
-class SkCanvas;
-
-namespace WebCore {
-
-class TiledTexture {
-public:
- TiledTexture()
- : m_prevTileX(0)
- , m_prevTileY(0)
- , m_scale(1)
- , m_swapWhateverIsReady(false)
- {
- m_dirtyRegion.setEmpty();
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("TiledTexture");
-#endif
- }
-
- virtual ~TiledTexture();
-
- IntRect computeTilesArea(const IntRect& contentArea, float scale);
-
- void prepareGL(GLWebViewState* state, float scale,
- const IntRect& prepareArea, TilePainter* painter);
- void swapTiles();
- bool drawGL(const IntRect& visibleArea, float opacity, const TransformationMatrix* transform);
-
- void prepareTile(int x, int y, TilePainter* painter);
- void markAsDirty(const SkRegion& dirtyArea);
-
- BaseTile* getTile(int x, int y);
-
- void removeTiles();
- void discardTextures();
- bool owns(BaseTileTexture* texture);
-
- float scale() { return m_scale; }
- bool isReady();
-
- int nbTextures(IntRect& area, float scale);
-
-private:
- bool tileIsVisible(BaseTile* tile);
-
- Vector<BaseTile*> m_tiles;
-
- // tile coordinates in viewport, set in prepareGL()
- IntRect m_area;
-
- SkRegion m_dirtyRegion;
-
- int m_prevTileX;
- int m_prevTileY;
- float m_scale;
-
- bool m_swapWhateverIsReady;
-};
-
-class DualTiledTexture : public SkRefCnt {
-// TODO: investigate webkit threadsafe ref counting
-public:
- DualTiledTexture();
- ~DualTiledTexture();
- void prepareGL(GLWebViewState* state, bool allowZoom,
- const IntRect& prepareArea, TilePainter* painter);
- void swapTiles();
- void swap();
- bool drawGL(const IntRect& visibleArea, float opacity, const TransformationMatrix* transform);
- void markAsDirty(const SkRegion& dirtyArea);
- bool owns(BaseTileTexture* texture);
- void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer);
- void discardTextures()
- {
- m_textureA->discardTextures();
- m_textureB->discardTextures();
- }
- bool isReady()
- {
- return !m_zooming && m_frontTexture->isReady();
- }
-
- int nbTextures(IntRect& area, float scale)
- {
- // TODO: consider the zooming case for the backTexture
- if (!m_frontTexture)
- return 0;
- return m_frontTexture->nbTextures(area, scale);
- }
-
-private:
- // Delay before we schedule a new tile at the new scale factor
- static const double s_zoomUpdateDelay = 0.2; // 200 ms
-
- TiledTexture* m_frontTexture;
- TiledTexture* m_backTexture;
- TiledTexture* m_textureA;
- TiledTexture* m_textureB;
- float m_scale;
- float m_futureScale;
- double m_zoomUpdateTime;
- bool m_zooming;
- IntRect m_preZoomPrepareArea;
-};
-
-} // namespace WebCore
-
-#endif // TiledTexture_h
diff --git a/Source/WebCore/platform/graphics/android/ZoomManager.cpp b/Source/WebCore/platform/graphics/android/ZoomManager.cpp
deleted file mode 100644
index 35100ae..0000000
--- a/Source/WebCore/platform/graphics/android/ZoomManager.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "ZoomManager"
-#define LOG_NDEBUG 1
-
-#include "config.h"
-#include "ZoomManager.h"
-
-#include "AndroidLog.h"
-#include "GLWebViewState.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-namespace WebCore {
-
-using namespace android;
-
-ZoomManager::ZoomManager(GLWebViewState* state)
- : m_scaleRequestState(kNoScaleRequest)
- , m_currentScale(-1)
- , m_futureScale(-1)
- , m_layersScale(-1)
- , m_updateTime(-1)
- , m_transitionTime(-1)
- , m_glWebViewState(state)
-{
-}
-
-void ZoomManager::scheduleUpdate(const double& currentTime,
- const SkIRect& viewport, float scale)
-{
- // if no update time, set it
- if (updateTime() == -1) {
- m_scaleRequestState = kWillScheduleRequest;
- setUpdateTime(currentTime + s_updateInitialDelay);
- setFutureScale(scale);
- m_glWebViewState->setFutureViewport(viewport);
- return;
- }
-
- if (currentTime < updateTime())
- return;
-
- // we reached the scheduled update time, check if we can update
- if (futureScale() == scale) {
- // we are still with the previous scale, let's go
- // with the update
- m_scaleRequestState = kRequestNewScale;
- setUpdateTime(-1);
- } else {
- // we reached the update time, but the planned update was for
- // a different scale factor -- meaning the user is still probably
- // in the process of zooming. Let's push the update time a bit.
- setUpdateTime(currentTime + s_updateDelay);
- setFutureScale(scale);
- m_glWebViewState->setFutureViewport(viewport);
- }
-}
-
-double ZoomManager::zoomInTransitionTime(double currentTime)
-{
- if (m_transitionTime == -1)
- m_transitionTime = currentTime + s_zoomInTransitionDelay;
- return m_transitionTime;
-}
-
-double ZoomManager::zoomOutTransitionTime(double currentTime)
-{
- if (m_transitionTime == -1)
- m_transitionTime = currentTime + s_zoomOutTransitionDelay;
- return m_transitionTime;
-}
-
-float ZoomManager::zoomInTransparency(double currentTime)
-{
- float t = zoomInTransitionTime(currentTime) - currentTime;
- t *= s_invZoomInTransitionDelay;
- return fmin(1, fmax(0, t));
-}
-
-float ZoomManager::zoomOutTransparency(double currentTime)
-{
- float t = zoomOutTransitionTime(currentTime) - currentTime;
- t *= s_invZoomOutTransitionDelay;
- return fmin(1, fmax(0, t));
-}
-
-bool ZoomManager::swapPages()
-{
- bool reset = m_scaleRequestState != kNoScaleRequest;
- m_scaleRequestState = kNoScaleRequest;
- return reset;
-}
-
-void ZoomManager::processNewScale(double currentTime, float scale)
-{
- m_prepareNextTiledPage = false;
- m_zooming = false;
- const SkIRect& viewportTileBounds = m_glWebViewState->viewportTileBounds();
-
- if (scale == m_currentScale
- || m_glWebViewState->preZoomBounds().isEmpty())
- m_glWebViewState->setPreZoomBounds(viewportTileBounds);
-
- // If we have a different scale than the current one, we have to
- // decide what to do. The current behaviour is to delay an update,
- // so that we do not slow down zooming unnecessarily.
- if ((m_currentScale != scale
- && (m_scaleRequestState == ZoomManager::kNoScaleRequest
- || m_futureScale != scale))
- || m_scaleRequestState == ZoomManager::kWillScheduleRequest) {
-
- // schedule the new Zoom request
- scheduleUpdate(currentTime, viewportTileBounds, scale);
-
- // If it's a new request, we will have to prepare the page.
- if (m_scaleRequestState == ZoomManager::kRequestNewScale)
- m_prepareNextTiledPage = true;
- }
-
- // If the viewport has changed since we scheduled the request, we also need
- // to prepare.
- if ((m_scaleRequestState == ZoomManager::kRequestNewScale
- || m_scaleRequestState == ZoomManager::kReceivedNewScale)
- && m_glWebViewState->futureViewport() != viewportTileBounds)
- m_prepareNextTiledPage = true;
-
- // Checking if we are zooming...
- if (m_scaleRequestState != ZoomManager::kNoScaleRequest) {
- m_prepareNextTiledPage = true;
- m_zooming = true;
- }
-
- // Get the current scale; if we are zooming, we don't change the scale
- // factor immediately (see BaseLayerAndroid::drawBasePictureInGL()), but
- // we change the scaleRequestState. When the state is kReceivedNewScale
- // (see setReceivedRequest()), we can use the future scale instead of
- // the current scale to request new textures. After a transition time,
- // the scaleRequestState will be reset and the current scale will be set
- // to the future scale.
- m_layersScale = m_currentScale;
-}
-
-void ZoomManager::processTransition(double currentTime, float scale,
- bool* doSwap, float* backPageTransparency,
- float* frontPageTransparency)
-{
- if (scale < m_currentScale)
- *backPageTransparency = 1 - zoomOutTransparency(currentTime);
- else
- *frontPageTransparency = zoomInTransparency(currentTime);
-
- // The transition between the two page is finished
- if (currentTime > transitionTime(currentTime, scale)) {
- resetTransitionTime();
- *doSwap = true;
- }
-}
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/ZoomManager.h b/Source/WebCore/platform/graphics/android/ZoomManager.h
deleted file mode 100644
index dd04c5d..0000000
--- a/Source/WebCore/platform/graphics/android/ZoomManager.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2011, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ZoomManager_h
-#define ZoomManager_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "SkRect.h"
-
-namespace WebCore {
-
-class GLWebViewState;
-
-class ZoomManager {
-public:
- enum GLScaleStates {
- kNoScaleRequest = 0,
- kWillScheduleRequest = 1,
- kRequestNewScale = 2,
- kReceivedNewScale = 3
- };
- typedef int32_t GLScaleState;
-
- ZoomManager(GLWebViewState* state);
-
- void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
-
- GLScaleState scaleRequestState() const { return m_scaleRequestState; }
- void setScaleRequestState(GLScaleState state) { m_scaleRequestState = state; }
- float currentScale() const { return m_currentScale; }
- void setCurrentScale(float scale) { m_currentScale = scale; }
- float futureScale() const { return m_futureScale; }
- void setFutureScale(float scale) { m_futureScale = scale; }
- float layersScale() const { return m_layersScale; }
- double zoomInTransitionTime(double currentTime);
- double zoomOutTransitionTime(double currentTime);
- float zoomInTransparency(double currentTime);
- float zoomOutTransparency(double currentTime);
- void resetTransitionTime() { m_transitionTime = -1; }
- double updateTime() const { return m_updateTime; }
- void setUpdateTime(double value) { m_updateTime = value; }
-
- // state used by BaseLayerAndroid
- bool needPrepareNextTiledPage() { return m_prepareNextTiledPage; }
- bool zooming() { return m_zooming; }
-
- bool didFireRequest() { return m_scaleRequestState == ZoomManager::kRequestNewScale; }
- void setReceivedRequest() {
- m_scaleRequestState = ZoomManager::kReceivedNewScale;
- m_layersScale = m_futureScale;
- }
- bool didReceivedRequest() { return m_scaleRequestState == ZoomManager::kReceivedNewScale; }
-
- double transitionTime(double currentTime, float scale) {
- return (scale < m_currentScale) ? zoomOutTransitionTime(currentTime)
- : zoomInTransitionTime(currentTime);
- }
- void processTransition(double currentTime, float scale, bool* doSwap,
- float* backPageTransparency, float* frontPageTransparency);
-
- bool swapPages();
-
- void processNewScale(double currentTime, float scale);
-
-private:
- // Delay between scheduling a new page when the scale
- // factor changes (i.e. zooming in or out)
- static const double s_updateInitialDelay = 0.3; // 300 ms
- // If the scale factor continued to change and we completed
- // the original delay, we push back the update by this value
- static const double s_updateDelay = 0.1; // 100 ms
-
- // Delay for the transition between the two pages
- static const double s_zoomInTransitionDelay = 0.1; // 100 ms
- static const double s_invZoomInTransitionDelay = 10;
- static const double s_zoomOutTransitionDelay = 0.2; // 200 ms
- static const double s_invZoomOutTransitionDelay = 5;
-
- GLScaleState m_scaleRequestState;
- float m_currentScale;
- float m_futureScale;
- float m_layersScale;
- double m_updateTime;
- double m_transitionTime;
-
- bool m_prepareNextTiledPage;
- bool m_zooming;
-
- GLWebViewState* m_glWebViewState;
-};
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
-#endif // ZoomManager_h
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp
new file mode 100644
index 0000000..f2d1400
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp
@@ -0,0 +1,663 @@
+/*
+ * Copyright 2006, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "GraphicsContext.h"
+
+#include "AffineTransform.h"
+#include "Font.h"
+#include "Gradient.h"
+#include "NotImplemented.h"
+#include "Path.h"
+#include "Pattern.h"
+#include "PlatformGraphicsContext.h"
+#include "PlatformGraphicsContextSkia.h"
+#include "SkBitmapRef.h"
+#include "SkBlurDrawLooper.h"
+#include "SkBlurMaskFilter.h"
+#include "SkCanvas.h"
+#include "SkColorPriv.h"
+#include "SkCornerPathEffect.h"
+#include "SkDashPathEffect.h"
+#include "SkDevice.h"
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkiaUtils.h"
+#include "TransformationMatrix.h"
+#include "android_graphics.h"
+
+using namespace std;
+
+namespace WebCore {
+
+// This class just holds onto a PlatformContextSkia for GraphicsContext.
+class GraphicsContextPlatformPrivate {
+ WTF_MAKE_NONCOPYABLE(GraphicsContextPlatformPrivate);
+public:
+ GraphicsContextPlatformPrivate(PlatformGraphicsContext* platformContext)
+ : m_context(platformContext) { }
+
+ PlatformGraphicsContext* context() { return m_context; }
+
+private:
+ // Non-owning pointer to the PlatformContext.
+ PlatformGraphicsContext* m_context;
+};
+
+static void syncPlatformContext(GraphicsContext* gc)
+{
+ // Stroke and fill sometimes reference each other, so always
+ // sync them both to make sure our state is consistent.
+
+ PlatformGraphicsContext* pgc = gc->platformContext();
+ Gradient* grad = gc->state().fillGradient.get();
+ Pattern* pat = gc->state().fillPattern.get();
+
+ if (grad)
+ pgc->setFillShader(grad->platformGradient());
+ else if (pat)
+ pgc->setFillShader(pat->platformPattern(AffineTransform()));
+ else
+ pgc->setFillColor(gc->state().fillColor);
+
+ grad = gc->state().strokeGradient.get();
+ pat = gc->state().strokePattern.get();
+
+ if (grad)
+ pgc->setStrokeShader(grad->platformGradient());
+ else if (pat)
+ pgc->setStrokeShader(pat->platformPattern(AffineTransform()));
+ else
+ pgc->setStrokeColor(gc->state().strokeColor);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height)
+{
+ PlatformGraphicsContextSkia* pgc = new PlatformGraphicsContextSkia(new SkCanvas, true);
+
+ SkBitmap bitmap;
+
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ bitmap.allocPixels();
+ bitmap.eraseColor(0);
+ pgc->getCanvas()->setBitmapDevice(bitmap);
+
+ GraphicsContext* ctx = new GraphicsContext(pgc);
+ return ctx;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+void GraphicsContext::platformInit(PlatformGraphicsContext* gc)
+{
+ if (gc)
+ gc->setGraphicsContext(this);
+ m_data = new GraphicsContextPlatformPrivate(gc);
+ setPaintingDisabled(!gc || gc->isPaintingDisabled());
+}
+
+void GraphicsContext::platformDestroy()
+{
+ delete m_data;
+}
+
+void GraphicsContext::savePlatformState()
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->save();
+}
+
+void GraphicsContext::restorePlatformState()
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->restore();
+}
+
+bool GraphicsContext::willFill() const
+{
+ return m_state.fillColor.rgb();
+}
+
+bool GraphicsContext::willStroke() const
+{
+ return m_state.strokeColor.rgb();
+}
+
+// Draws a filled rectangle with a stroked border.
+void GraphicsContext::drawRect(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawRect(rect);
+}
+
+// This is only used to draw borders.
+void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawLine(point1, point2);
+}
+
+void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool /* printing */)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawLineForText(pt, width);
+}
+
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width,
+ TextCheckingLineStyle style)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawLineForTextChecking(pt, width, style);
+}
+
+// This method is only used to draw the little circles used in lists.
+void GraphicsContext::drawEllipse(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawEllipse(rect);
+}
+
+void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->strokeArc(r, startAngle, angleSpan);
+}
+
+void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points,
+ bool shouldAntialias)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawConvexPolygon(numPoints, points, shouldAntialias);
+}
+
+void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
+ const IntSize& bottomLeft, const IntSize& bottomRight,
+ const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->fillRoundedRect(rect, topLeft, topRight,
+ bottomLeft, bottomRight, color, colorSpace);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->fillRect(rect);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->fillRect(rect, color, colorSpace);
+}
+
+void GraphicsContext::clip(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->clip(rect);
+}
+
+void GraphicsContext::clip(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->clip(path);
+}
+
+void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->addInnerRoundedRectClip(rect, thickness);
+}
+
+void GraphicsContext::canvasClip(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->canvasClip(path);
+}
+
+void GraphicsContext::clipOut(const IntRect& r)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->clipOut(r);
+}
+
+#if ENABLE(SVG)
+void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->clipPath(pathToClip, clipRule);
+}
+#endif
+
+void GraphicsContext::clipOut(const Path& p)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->clipOut(p);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if SVG_SUPPORT
+KRenderingDeviceContext* GraphicsContext::createRenderingDeviceContext()
+{
+ return new KRenderingDeviceContextQuartz(platformContext());
+}
+#endif
+
+void GraphicsContext::beginTransparencyLayer(float opacity)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->beginTransparencyLayer(opacity);
+}
+
+void GraphicsContext::endTransparencyLayer()
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->endTransparencyLayer();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+void GraphicsContext::setupFillPaint(SkPaint* paint)
+{
+ if (paintingDisabled())
+ return;
+ syncPlatformContext(this);
+ platformContext()->setupPaintFill(paint);
+}
+
+void GraphicsContext::setupStrokePaint(SkPaint* paint)
+{
+ if (paintingDisabled())
+ return;
+ syncPlatformContext(this);
+ platformContext()->setupPaintStroke(paint, 0);
+}
+
+bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset)
+{
+ if (paintingDisabled())
+ return false;
+ syncPlatformContext(this);
+ return platformContext()->setupPaintShadow(paint, offset);
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace)
+{
+}
+
+void GraphicsContext::setPlatformStrokeThickness(float f)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setStrokeThickness(f);
+}
+
+void GraphicsContext::setPlatformStrokeStyle(StrokeStyle style)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setStrokeStyle(style);
+}
+
+void GraphicsContext::setPlatformFillColor(const Color& c, ColorSpace)
+{
+}
+
+void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ if (blur <= 0)
+ this->clearPlatformShadow();
+
+ SkColor c;
+ if (color.isValid())
+ c = color.rgb();
+ else
+ c = SkColorSetARGB(0xFF / 3, 0, 0, 0); // "std" Apple shadow color
+ platformContext()->setShadow(blur, size.width(), size.height(), c);
+}
+
+void GraphicsContext::clearPlatformShadow()
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->setShadow(0, 0, 0, 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawFocusRing(rects, width, offset, color);
+}
+
+void GraphicsContext::drawFocusRing(const Path&, int, int, const Color&)
+{
+ // Do nothing, since we draw the focus ring independently.
+}
+
+PlatformGraphicsContext* GraphicsContext::platformContext() const
+{
+ ASSERT(!paintingDisabled());
+ return m_data->context();
+}
+
+void GraphicsContext::setMiterLimit(float limit)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setMiterLimit(limit);
+}
+
+void GraphicsContext::setAlpha(float alpha)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setAlpha(alpha);
+}
+
+void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setCompositeOperation(op);
+}
+
+void GraphicsContext::clearRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->clearRect(rect);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->strokeRect(rect, lineWidth);
+}
+
+void GraphicsContext::setLineCap(LineCap cap)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setLineCap(cap);
+}
+
+#if ENABLE(SVG)
+void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->setLineDash(dashes, dashOffset);
+}
+#endif
+
+void GraphicsContext::setLineJoin(LineJoin join)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setLineJoin(join);
+}
+
+void GraphicsContext::scale(const FloatSize& size)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->scale(size);
+}
+
+void GraphicsContext::rotate(float angleInRadians)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->rotate(angleInRadians);
+}
+
+void GraphicsContext::translate(float x, float y)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->translate(x, y);
+}
+
+void GraphicsContext::concatCTM(const AffineTransform& affine)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->concatCTM(affine);
+}
+
+// This is intended to round the rect to device pixels (through the CTM)
+// and then invert the result back into source space, with the hope that when
+// it is drawn (through the matrix), it will land in the "right" place (i.e.
+// on pixel boundaries).
+
+// For android, we record this geometry once and then draw it though various
+// scale factors as the user zooms, without re-recording. Thus this routine
+// should just leave the original geometry alone.
+
+// If we instead draw into bitmap tiles, we should then perform this
+// transform -> round -> inverse step.
+
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode)
+{
+ return rect;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+// Appears to be PDF specific, so we ignore it
+}
+
+void GraphicsContext::setPlatformShouldAntialias(bool useAA)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setShouldAntialias(useAA);
+}
+
+void GraphicsContext::setPlatformFillGradient(Gradient* fillGradient)
+{
+}
+
+void GraphicsContext::setPlatformFillPattern(Pattern* fillPattern)
+{
+}
+
+void GraphicsContext::setPlatformStrokeGradient(Gradient* strokeGradient)
+{
+}
+
+void GraphicsContext::setPlatformStrokePattern(Pattern* strokePattern)
+{
+}
+
+AffineTransform GraphicsContext::getCTM() const
+{
+ if (paintingDisabled())
+ return AffineTransform();
+ const SkMatrix& m = platformContext()->getTotalMatrix();
+ return AffineTransform(SkScalarToDouble(m.getScaleX()), // a
+ SkScalarToDouble(m.getSkewY()), // b
+ SkScalarToDouble(m.getSkewX()), // c
+ SkScalarToDouble(m.getScaleY()), // d
+ SkScalarToDouble(m.getTranslateX()), // e
+ SkScalarToDouble(m.getTranslateY())); // f
+}
+
+void GraphicsContext::setCTM(const AffineTransform& transform)
+{
+ // The SkPicture mode of Skia does not support SkCanvas::setMatrix(), so we
+ // can not simply use that method here. We could calculate the transform
+ // required to achieve the desired matrix and use SkCanvas::concat(), but
+ // there's currently no need for this.
+ ASSERT_NOT_REACHED();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GraphicsContext::fillPath(const Path& pathToFill)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->fillPath(pathToFill, fillRule());
+}
+
+void GraphicsContext::strokePath(const Path& pathToStroke)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->strokePath(pathToStroke);
+}
+
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+ notImplemented();
+ return InterpolationDefault;
+}
+
+void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode)
+{
+#if 0
+ enum InterpolationQuality {
+ InterpolationDefault,
+ InterpolationNone,
+ InterpolationLow,
+ InterpolationMedium,
+ InterpolationHigh
+ };
+#endif
+ // TODO: record this, so we can know when to use bitmap-filtering when we draw
+ // ... not sure how meaningful this will be given our playback model.
+
+ // Certainly safe to do nothing for the present.
+}
+
+void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint*,
+ bool antialias)
+{
+ if (paintingDisabled())
+ return;
+
+ if (numPoints <= 1)
+ return;
+
+ // FIXME: IMPLEMENT!
+}
+
+void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run,
+ const FloatPoint& point, int h,
+ const Color& backgroundColor,
+ ColorSpace colorSpace, int from,
+ int to, bool isActive)
+{
+ if (paintingDisabled())
+ return;
+
+ syncPlatformContext(this);
+ platformContext()->drawHighlightForText(font, run, point, h, backgroundColor,
+ colorSpace, from, to, isActive);
+}
+
+} // namespace WebCore
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc)
+{
+ return gc->platformContext()->getCanvas();
+}
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
new file mode 100644
index 0000000..927ff0a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
@@ -0,0 +1,809 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsOperation_h
+#define GraphicsOperation_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "Color.h"
+#include "FloatRect.h"
+#include "GlyphBuffer.h"
+#include "Font.h"
+#include "IntRect.h"
+#include "PlatformGraphicsContext.h"
+#include "PlatformGraphicsContextSkia.h"
+#include "SkCanvas.h"
+#include "SkShader.h"
+#include "SkRefCnt.h"
+
+#include <utils/threads.h>
+#include <wtf/text/CString.h>
+
+#define TYPE_CASE(type) case type: return #type;
+
+namespace WebCore {
+
+namespace GraphicsOperation {
+
+class Operation : public SkRefCnt {
+public:
+ typedef enum { UndefinedOperation
+ // State management
+ , BeginTransparencyLayerOperation
+ , EndTransparencyLayerOperation
+ , SaveOperation
+ , RestoreOperation
+ // State setters
+ , SetAlphaOperation
+ , SetCompositeOpOperation
+ , SetFillColorOperation
+ , SetFillShaderOperation
+ , SetLineCapOperation
+ , SetLineDashOperation
+ , SetLineJoinOperation
+ , SetMiterLimitOperation
+ , SetShadowOperation
+ , SetShouldAntialiasOperation
+ , SetStrokeColorOperation
+ , SetStrokeShaderOperation
+ , SetStrokeStyleOperation
+ , SetStrokeThicknessOperation
+ // Paint setup
+ , SetupPaintFillOperation
+ , SetupPaintShadowOperation
+ , SetupPaintStrokeOperation
+ // Matrix operations
+ , ConcatCTMOperation
+ , ScaleOperation
+ , RotateOperation
+ , TranslateOperation
+ // Clipping
+ , InnerRoundedRectClipOperation
+ , ClipOperation
+ , ClipPathOperation
+ , ClipOutOperation
+ , ClearRectOperation
+ // Drawing
+ , DrawBitmapPatternOperation
+ , DrawBitmapRectOperation
+ , DrawEllipseOperation
+ , DrawLineOperation
+ , DrawLineForTextOperation
+ , DrawLineForTextCheckingOperation
+ , DrawRectOperation
+ , FillPathOperation
+ , FillRectOperation
+ , FillRoundedRectOperation
+ , StrokeArcOperation
+ , StrokePathOperation
+ , StrokeRectOperation
+ // Text
+ , DrawComplexTextOperation
+ , DrawTextOperation
+ } OperationType;
+
+ virtual void apply(PlatformGraphicsContext* context) = 0;
+ virtual ~Operation() {}
+ virtual OperationType type() { return UndefinedOperation; }
+ virtual String parameters() { return ""; }
+ String name()
+ {
+ switch (type()) {
+ TYPE_CASE(UndefinedOperation)
+ // State management
+ TYPE_CASE(BeginTransparencyLayerOperation)
+ TYPE_CASE(EndTransparencyLayerOperation)
+ TYPE_CASE(SaveOperation)
+ TYPE_CASE(RestoreOperation)
+ // State setters
+ TYPE_CASE(SetAlphaOperation)
+ TYPE_CASE(SetCompositeOpOperation)
+ TYPE_CASE(SetFillColorOperation)
+ TYPE_CASE(SetFillShaderOperation)
+ TYPE_CASE(SetLineCapOperation)
+ TYPE_CASE(SetLineDashOperation)
+ TYPE_CASE(SetLineJoinOperation)
+ TYPE_CASE(SetMiterLimitOperation)
+ TYPE_CASE(SetShadowOperation)
+ TYPE_CASE(SetShouldAntialiasOperation)
+ TYPE_CASE(SetStrokeColorOperation)
+ TYPE_CASE(SetStrokeShaderOperation)
+ TYPE_CASE(SetStrokeStyleOperation)
+ TYPE_CASE(SetStrokeThicknessOperation)
+ // Paint setup
+ TYPE_CASE(SetupPaintFillOperation)
+ TYPE_CASE(SetupPaintShadowOperation)
+ TYPE_CASE(SetupPaintStrokeOperation)
+ // Matrix operations
+ TYPE_CASE(ConcatCTMOperation)
+ TYPE_CASE(ScaleOperation)
+ TYPE_CASE(RotateOperation)
+ TYPE_CASE(TranslateOperation)
+ // Clipping
+ TYPE_CASE(InnerRoundedRectClipOperation)
+ TYPE_CASE(ClipOperation)
+ TYPE_CASE(ClipPathOperation)
+ TYPE_CASE(ClipOutOperation)
+ TYPE_CASE(ClearRectOperation)
+ // Drawing
+ TYPE_CASE(DrawBitmapPatternOperation)
+ TYPE_CASE(DrawBitmapRectOperation)
+ TYPE_CASE(DrawEllipseOperation)
+ TYPE_CASE(DrawLineOperation)
+ TYPE_CASE(DrawLineForTextOperation)
+ TYPE_CASE(DrawLineForTextCheckingOperation)
+ TYPE_CASE(DrawRectOperation)
+ TYPE_CASE(FillPathOperation)
+ TYPE_CASE(FillRectOperation)
+ TYPE_CASE(FillRoundedRectOperation)
+ TYPE_CASE(StrokeArcOperation)
+ TYPE_CASE(StrokePathOperation)
+ TYPE_CASE(StrokeRectOperation)
+ // Text
+ TYPE_CASE(DrawComplexTextOperation)
+ TYPE_CASE(DrawTextOperation)
+ }
+ return "Undefined";
+ }
+};
+
+//**************************************
+// State management
+//**************************************
+
+class BeginTransparencyLayer : public Operation {
+public:
+ BeginTransparencyLayer(const float opacity) : m_opacity(opacity) {}
+ virtual void apply(PlatformGraphicsContext* context) { context->beginTransparencyLayer(m_opacity); }
+ virtual OperationType type() { return BeginTransparencyLayerOperation; }
+private:
+ float m_opacity;
+};
+class EndTransparencyLayer : public Operation {
+public:
+ EndTransparencyLayer() {}
+ virtual void apply(PlatformGraphicsContext* context) { context->endTransparencyLayer(); }
+ virtual OperationType type() { return EndTransparencyLayerOperation; }
+};
+class Save : public Operation {
+public:
+ virtual void apply(PlatformGraphicsContext* context) { context->save(); }
+ virtual OperationType type() { return SaveOperation; }
+};
+class Restore : public Operation {
+public:
+ virtual void apply(PlatformGraphicsContext* context) { context->restore(); }
+ virtual OperationType type() { return RestoreOperation; }
+};
+
+//**************************************
+// State setters
+//**************************************
+
+class SetAlpha : public Operation {
+public:
+ SetAlpha(const float alpha) : m_alpha(alpha) {}
+ virtual void apply(PlatformGraphicsContext* context) { context->setAlpha(m_alpha); }
+ virtual OperationType type() { return SetAlphaOperation; }
+private:
+ float m_alpha;
+};
+
+class SetCompositeOperation : public Operation {
+public:
+ SetCompositeOperation(CompositeOperator op) : m_operator(op) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setCompositeOperation(m_operator);
+ }
+ virtual OperationType type() { return SetCompositeOpOperation; }
+private:
+ CompositeOperator m_operator;
+};
+
+class SetFillColor : public Operation {
+public:
+ SetFillColor(Color color) : m_color(color) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setFillColor(m_color);
+ }
+ virtual OperationType type() { return SetFillColorOperation; }
+ virtual String parameters() {
+ return String::format("r: %d g: %d b: %d a: %d",
+ m_color.red(),
+ m_color.green(),
+ m_color.blue(),
+ m_color.alpha());
+ }
+private:
+ Color m_color;
+};
+
+class SetFillShader : public Operation {
+public:
+ SetFillShader(SkShader* shader) : m_shader(shader) {
+ SkSafeRef(m_shader);
+ }
+ ~SetFillShader() { SkSafeUnref(m_shader); }
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setFillShader(m_shader);
+ }
+ virtual OperationType type() { return SetFillShaderOperation; }
+private:
+ SkShader* m_shader;
+};
+
+class SetLineCap : public Operation {
+public:
+ SetLineCap(LineCap cap) : m_cap(cap) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setLineCap(m_cap);
+ }
+ virtual OperationType type() { return SetLineCapOperation; }
+private:
+ LineCap m_cap;
+};
+
+class SetLineDash : public Operation {
+public:
+ SetLineDash(const DashArray& dashes, float dashOffset)
+ : m_dashes(dashes), m_dashOffset(dashOffset) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setLineDash(m_dashes, m_dashOffset);
+ }
+ virtual OperationType type() { return SetLineDashOperation; }
+private:
+ DashArray m_dashes;
+ float m_dashOffset;
+};
+
+class SetLineJoin : public Operation {
+public:
+ SetLineJoin(LineJoin join) : m_join(join) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setLineJoin(m_join);
+ }
+ virtual OperationType type() { return SetLineJoinOperation; }
+private:
+ LineJoin m_join;
+};
+
+class SetMiterLimit : public Operation {
+public:
+ SetMiterLimit(float limit) : m_limit(limit) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setMiterLimit(m_limit);
+ }
+ virtual OperationType type() { return SetMiterLimitOperation; }
+private:
+ float m_limit;
+};
+
+class SetShadow : public Operation {
+public:
+ SetShadow(int radius, int dx, int dy, SkColor c)
+ : m_radius(radius), m_dx(dx), m_dy(dy), m_color(c) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setShadow(m_radius, m_dx, m_dy, m_color);
+ }
+ virtual OperationType type() { return SetShadowOperation; }
+private:
+ int m_radius;
+ int m_dx;
+ int m_dy;
+ SkColor m_color;
+};
+
+class SetShouldAntialias : public Operation {
+public:
+ SetShouldAntialias(bool useAA) : m_useAA(useAA) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setShouldAntialias(m_useAA);
+ }
+ virtual OperationType type() { return SetShouldAntialiasOperation; }
+private:
+ bool m_useAA;
+};
+
+class SetStrokeColor : public Operation {
+public:
+ SetStrokeColor(const Color& c) : m_color(c) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setStrokeColor(m_color);
+ }
+ virtual OperationType type() { return SetStrokeColorOperation; }
+private:
+ Color m_color;
+};
+
+class SetStrokeShader : public Operation {
+public:
+ SetStrokeShader(SkShader* strokeShader) : m_shader(strokeShader) {
+ SkSafeRef(m_shader);
+ }
+ ~SetStrokeShader() { SkSafeUnref(m_shader); }
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setStrokeShader(m_shader);
+ }
+ virtual OperationType type() { return SetStrokeShaderOperation; }
+private:
+ SkShader* m_shader;
+};
+
+class SetStrokeStyle : public Operation {
+public:
+ SetStrokeStyle(StrokeStyle style) : m_style(style) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setStrokeStyle(m_style);
+ }
+ virtual OperationType type() { return SetStrokeStyleOperation; }
+private:
+ StrokeStyle m_style;
+};
+
+class SetStrokeThickness : public Operation {
+public:
+ SetStrokeThickness(float thickness) : m_thickness(thickness) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setStrokeThickness(m_thickness);
+ }
+ virtual OperationType type() { return SetStrokeThicknessOperation; }
+private:
+ float m_thickness;
+};
+
+//**************************************
+// Paint setup
+//**************************************
+
+class SetupPaintFill : public Operation {
+public:
+ SetupPaintFill(SkPaint* paint) : m_paint(*paint) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setupPaintFill(&m_paint);
+ }
+ virtual OperationType type() { return SetupPaintFillOperation; }
+private:
+ SkPaint m_paint;
+};
+
+class SetupPaintShadow : public Operation {
+public:
+ SetupPaintShadow(SkPaint* paint, SkPoint* offset)
+ : m_paint(*paint), m_offset(*offset) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setupPaintShadow(&m_paint, &m_offset);
+ }
+ virtual OperationType type() { return SetupPaintShadowOperation; }
+private:
+ SkPaint m_paint;
+ SkPoint m_offset;
+};
+
+class SetupPaintStroke : public Operation {
+public:
+ SetupPaintStroke(SkPaint* paint, SkRect* rect, bool isHLine)
+ : m_paint(*paint), m_rect(*rect), m_isHLine(isHLine) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->setupPaintStroke(&m_paint, &m_rect, m_isHLine);
+ }
+ virtual OperationType type() { return SetupPaintStrokeOperation; }
+private:
+ SkPaint m_paint;
+ SkRect m_rect;
+ bool m_isHLine;
+};
+
+//**************************************
+// Matrix operations
+//**************************************
+
+class ConcatCTM : public Operation {
+public:
+ ConcatCTM(const AffineTransform& affine) : m_matrix(affine) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->concatCTM(m_matrix);
+ }
+ virtual OperationType type() { return ConcatCTMOperation; }
+private:
+ AffineTransform m_matrix;
+};
+
+class Rotate : public Operation {
+public:
+ Rotate(float angleInRadians) : m_angle(angleInRadians) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->rotate(m_angle);
+ }
+ virtual OperationType type() { return RotateOperation; }
+private:
+ float m_angle;
+};
+
+class Scale : public Operation {
+public:
+ Scale(const FloatSize& size) : m_scale(size) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->scale(m_scale);
+ }
+ virtual OperationType type() { return ScaleOperation; }
+private:
+ FloatSize m_scale;
+};
+
+class Translate : public Operation {
+public:
+ Translate(float x, float y) : m_x(x), m_y(y) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->translate(m_x, m_y);
+ }
+ virtual OperationType type() { return TranslateOperation; }
+private:
+ float m_x;
+ float m_y;
+};
+
+//**************************************
+// Clipping
+//**************************************
+
+class InnerRoundedRectClip : public Operation {
+public:
+ InnerRoundedRectClip(const IntRect& rect, int thickness)
+ : m_rect(rect), m_thickness(thickness) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->addInnerRoundedRectClip(m_rect, m_thickness);
+ }
+ virtual OperationType type() { return InnerRoundedRectClipOperation; }
+private:
+ IntRect m_rect;
+ int m_thickness;
+};
+
+class Clip : public Operation {
+public:
+ Clip(const FloatRect& rect) : m_rect(rect) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->clip(m_rect);
+ }
+ virtual OperationType type() { return ClipOperation; }
+private:
+ const FloatRect m_rect;
+};
+
+class ClipPath : public Operation {
+public:
+ ClipPath(const Path& path, bool clipout = false)
+ : m_path(path), m_clipOut(clipout), m_hasWindRule(false) {}
+ void setWindRule(WindRule rule) { m_windRule = rule; m_hasWindRule = true; }
+ virtual void apply(PlatformGraphicsContext* context) {
+ if (m_hasWindRule) {
+ context->clipPath(m_path, m_windRule);
+ return;
+ }
+ if (m_clipOut)
+ context->clipOut(m_path);
+ else
+ context->clip(m_path);
+ }
+ virtual OperationType type() { return ClipPathOperation; }
+private:
+ const Path m_path;
+ bool m_clipOut;
+ WindRule m_windRule;
+ bool m_hasWindRule;
+};
+
+class ClipOut : public Operation {
+public:
+ ClipOut(const IntRect& rect) : m_rect(rect) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->clipOut(m_rect);
+ }
+ virtual OperationType type() { return ClipOutOperation; }
+private:
+ const IntRect m_rect;
+};
+
+class ClearRect : public Operation {
+public:
+ ClearRect(const FloatRect& rect) : m_rect(rect) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->clearRect(m_rect);
+ }
+ virtual OperationType type() { return ClearRectOperation; }
+private:
+ FloatRect m_rect;
+};
+
+//**************************************
+// Drawing
+//**************************************
+
+class DrawBitmapPattern : public Operation {
+public:
+ DrawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator op, const FloatRect& destRect)
+ : m_bitmap(bitmap), m_matrix(matrix), m_operator(op), m_destRect(destRect) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawBitmapPattern(m_bitmap, m_matrix, m_operator, m_destRect);
+ }
+ virtual OperationType type() { return DrawBitmapPatternOperation; }
+private:
+ // TODO: use refcounted bitmap
+ const SkBitmap m_bitmap;
+ SkMatrix m_matrix;
+ CompositeOperator m_operator;
+ FloatRect m_destRect;
+};
+
+class DrawBitmapRect : public Operation {
+public:
+ DrawBitmapRect(const SkBitmap& bitmap, const SkIRect& srcR,
+ const SkRect& dstR, CompositeOperator op)
+ : m_bitmap(bitmap), m_srcR(srcR), m_dstR(dstR), m_operator(op) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawBitmapRect(m_bitmap, &m_srcR, m_dstR, m_operator);
+ }
+ virtual OperationType type() { return DrawBitmapRectOperation; }
+ virtual String parameters() {
+ return String::format("%.2f, %.2f - %.2f x %.2f",
+ m_dstR.fLeft, m_dstR.fTop,
+ m_dstR.width(), m_dstR.height());
+ }
+private:
+ const SkBitmap& m_bitmap;
+ SkIRect m_srcR;
+ SkRect m_dstR;
+ CompositeOperator m_operator;
+};
+
+class DrawEllipse : public Operation {
+public:
+ DrawEllipse(const IntRect& rect) : m_rect(rect) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawEllipse(m_rect);
+ }
+ virtual OperationType type() { return DrawEllipseOperation; }
+private:
+ IntRect m_rect;
+};
+
+class DrawLine : public Operation {
+public:
+ DrawLine(const IntPoint& point1, const IntPoint& point2)
+ : m_point1(point1), m_point2(point2) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawLine(m_point1, m_point2);
+ }
+ virtual OperationType type() { return DrawLineOperation; }
+private:
+ IntPoint m_point1;
+ IntPoint m_point2;
+};
+
+class DrawLineForText : public Operation {
+public:
+ DrawLineForText(const FloatPoint& pt, float width)
+ : m_point(pt), m_width(width) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawLineForText(m_point, m_width);
+ }
+ virtual OperationType type() { return DrawLineForTextOperation; }
+private:
+ FloatPoint m_point;
+ float m_width;
+};
+
+class DrawLineForTextChecking : public Operation {
+public:
+ DrawLineForTextChecking(const FloatPoint& pt, float width,
+ GraphicsContext::TextCheckingLineStyle lineStyle)
+ : m_point(pt), m_width(width), m_lineStyle(lineStyle) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawLineForTextChecking(m_point, m_width, m_lineStyle);
+ }
+ virtual OperationType type() { return DrawLineForTextCheckingOperation; }
+private:
+ FloatPoint m_point;
+ float m_width;
+ GraphicsContext::TextCheckingLineStyle m_lineStyle;
+};
+
+class DrawRect : public Operation {
+public:
+ DrawRect(const IntRect& rect) : m_rect(rect) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->drawRect(m_rect);
+ }
+ virtual OperationType type() { return DrawRectOperation; }
+private:
+ IntRect m_rect;
+};
+
+class FillPath : public Operation {
+public:
+ FillPath(const Path& pathToFill, WindRule fillRule)
+ : m_path(pathToFill), m_fillRule(fillRule) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->fillPath(m_path, m_fillRule);
+ }
+ virtual OperationType type() { return FillPathOperation; }
+private:
+ Path m_path;
+ WindRule m_fillRule;
+};
+
+class FillRect : public Operation {
+public:
+ FillRect(const FloatRect& rect) : m_rect(rect), m_hasColor(false) {}
+ void setColor(Color c) { m_color = c; m_hasColor = true; }
+ virtual void apply(PlatformGraphicsContext* context) {
+ if (m_hasColor)
+ context->fillRect(m_rect, m_color);
+ else
+ context->fillRect(m_rect);
+ }
+ virtual OperationType type() { return FillRectOperation; }
+private:
+ FloatRect m_rect;
+ Color m_color;
+ bool m_hasColor;
+};
+
+class FillRoundedRect : public Operation {
+public:
+ FillRoundedRect(const IntRect& rect,
+ const IntSize& topLeft,
+ const IntSize& topRight,
+ const IntSize& bottomLeft,
+ const IntSize& bottomRight,
+ const Color& color)
+ : m_rect(rect)
+ , m_topLeft(topLeft)
+ , m_topRight(topRight)
+ , m_bottomLeft(bottomLeft)
+ , m_bottomRight(bottomRight)
+ , m_color(color)
+ {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->fillRoundedRect(m_rect, m_topLeft, m_topRight,
+ m_bottomLeft, m_bottomRight,
+ m_color);
+ }
+ virtual OperationType type() { return FillRoundedRectOperation; }
+private:
+ IntRect m_rect;
+ IntSize m_topLeft;
+ IntSize m_topRight;
+ IntSize m_bottomLeft;
+ IntSize m_bottomRight;
+ Color m_color;
+};
+
+class StrokeArc : public Operation {
+public:
+ StrokeArc(const IntRect& r, int startAngle, int angleSpan)
+ : m_rect(r)
+ , m_startAngle(startAngle)
+ , m_angleSpan(angleSpan)
+ {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->strokeArc(m_rect, m_startAngle, m_angleSpan);
+ }
+ virtual OperationType type() { return StrokeArcOperation; }
+private:
+ IntRect m_rect;
+ int m_startAngle;
+ int m_angleSpan;
+};
+
+class StrokePath : public Operation {
+public:
+ StrokePath(const Path& path) : m_path(path) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->strokePath(m_path);
+ }
+ virtual OperationType type() { return StrokePathOperation; }
+private:
+ Path m_path;
+};
+
+
+class StrokeRect : public Operation {
+public:
+ StrokeRect(const FloatRect& rect, float lineWidth)
+ : m_rect(rect), m_lineWidth(lineWidth) {}
+ virtual void apply(PlatformGraphicsContext* context) {
+ context->strokeRect(m_rect, m_lineWidth);
+ }
+ virtual OperationType type() { return StrokeRectOperation; }
+private:
+ FloatRect m_rect;
+ float m_lineWidth;
+};
+
+//**************************************
+// Text
+//**************************************
+
+class DrawComplexText : public Operation {
+public:
+ DrawComplexText(SkPicture* picture) : m_picture(picture) {
+ SkSafeRef(m_picture);
+ }
+ ~DrawComplexText() { SkSafeUnref(m_picture); }
+ virtual void apply(PlatformGraphicsContext* context) {
+ if (!context->getCanvas())
+ return;
+ context->getCanvas()->drawPicture(*m_picture);
+ }
+ virtual OperationType type() { return DrawComplexTextOperation; }
+private:
+ SkPicture* m_picture;
+};
+
+class DrawText : public Operation {
+public:
+ DrawText(const Font* font, const SimpleFontData* simpleFont,
+ const GlyphBuffer& glyphBuffer,
+ int from, int numGlyphs, const FloatPoint& point)
+ : m_font(font), m_simpleFont(simpleFont)
+ , m_glyphBuffer(glyphBuffer), m_from(from)
+ , m_numGlyphs(numGlyphs), m_point(point) {
+
+ SkPicture* picture = new SkPicture();
+ SkCanvas* canvas = picture->beginRecording(0, 0, 0);
+ PlatformGraphicsContextSkia platformContext(canvas);
+ GraphicsContext graphicsContext(&platformContext);
+ m_font->drawGlyphs(&graphicsContext, m_simpleFont,
+ m_glyphBuffer, m_from, m_numGlyphs, m_point);
+ picture->endRecording();
+ m_picture = picture;
+ }
+ ~DrawText() { SkSafeUnref(m_picture); }
+ virtual void apply(PlatformGraphicsContext* context) {
+ if (!context->getCanvas())
+ return;
+ context->getCanvas()->drawPicture(*m_picture);
+ }
+ virtual OperationType type() { return DrawTextOperation; }
+private:
+ SkPicture* m_picture;
+ const Font* m_font;
+ const SimpleFontData* m_simpleFont;
+ const GlyphBuffer m_glyphBuffer;
+ int m_from;
+ int m_numGlyphs;
+ const FloatPoint m_point;
+};
+
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // GraphicsOperation_h
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp
new file mode 100644
index 0000000..6118160
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp
@@ -0,0 +1,63 @@
+#define LOG_TAG "GraphicsOperationCollection"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "GraphicsOperationCollection.h"
+
+#include "AndroidLog.h"
+#include "GraphicsContext.h"
+#include "PlatformGraphicsContext.h"
+#include "PlatformGraphicsContextRecording.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+GraphicsOperationCollection::GraphicsOperationCollection(const IntRect& drawArea)
+ : m_drawArea(drawArea)
+{
+}
+
+GraphicsOperationCollection::~GraphicsOperationCollection()
+{
+ for (unsigned int i = 0; i < m_operations.size(); i++)
+ SkSafeUnref(m_operations[i]);
+}
+
+void GraphicsOperationCollection::apply(PlatformGraphicsContext* context)
+{
+ ALOGD("\nApply GraphicsOperationCollection %x, %d operations", this, m_operations.size());
+ for (unsigned int i = 0; i < m_operations.size(); i++) {
+ ALOGD("[%d] (%x) %s %s", i, this, m_operations[i]->name().latin1().data(),
+ m_operations[i]->parameters().latin1().data());
+ m_operations[i]->apply(context);
+ }
+}
+
+void GraphicsOperationCollection::append(GraphicsOperation::Operation* operation)
+{
+ m_operations.append(operation);
+}
+
+bool GraphicsOperationCollection::isEmpty()
+{
+ return !m_operations.size();
+}
+
+AutoGraphicsOperationCollection::AutoGraphicsOperationCollection(const IntRect& area)
+{
+ m_graphicsOperationCollection = new GraphicsOperationCollection(area);
+ m_platformGraphicsContext = new PlatformGraphicsContextRecording(m_graphicsOperationCollection);
+ m_graphicsContext = new GraphicsContext(m_platformGraphicsContext);
+}
+
+AutoGraphicsOperationCollection::~AutoGraphicsOperationCollection()
+{
+ SkSafeUnref(m_graphicsOperationCollection);
+ delete m_graphicsContext;
+ delete m_platformGraphicsContext;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h
new file mode 100644
index 0000000..9d7b530
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsOperationCollection_h
+#define GraphicsOperationCollection_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "Color.h"
+#include "GraphicsOperation.h"
+#include "IntRect.h"
+#include "SkRefCnt.h"
+
+namespace WebCore {
+
+class PlatformGraphicsContext;
+
+class GraphicsOperationCollection : public SkRefCnt {
+public:
+ GraphicsOperationCollection(const IntRect& drawArea);
+ ~GraphicsOperationCollection();
+
+ void apply(PlatformGraphicsContext* context);
+ void append(GraphicsOperation::Operation* operation);
+
+ bool isEmpty();
+
+private:
+ IntRect m_drawArea;
+ Vector<GraphicsOperation::Operation*> m_operations;
+};
+
+class AutoGraphicsOperationCollection {
+public:
+ AutoGraphicsOperationCollection(const IntRect& area);
+ ~AutoGraphicsOperationCollection();
+ GraphicsContext* context() { return m_graphicsContext; }
+ GraphicsOperationCollection* picture() { return m_graphicsOperationCollection; }
+
+private:
+ GraphicsOperationCollection* m_graphicsOperationCollection;
+ PlatformGraphicsContext* m_platformGraphicsContext;
+ GraphicsContext* m_graphicsContext;
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // GraphicsOperationCollection_h
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
new file mode 100644
index 0000000..bb5d990
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2006, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "PlatformGraphicsContext"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "PlatformGraphicsContext.h"
+
+#include "AndroidLog.h"
+#include "SkBlurDrawLooper.h"
+#include "SkBlurMaskFilter.h"
+#include "SkColorPriv.h"
+#include "SkDashPathEffect.h"
+#include "SkPaint.h"
+#include "SkShader.h"
+#include "SkiaUtils.h"
+
+namespace WebCore {
+
+//**************************************
+// Helper functions
+//**************************************
+
+static int RoundToInt(float x)
+{
+ return (int)roundf(x);
+}
+
+template <typename T> T* deepCopyPtr(const T* src)
+{
+ return src ? new T(*src) : 0;
+}
+
+// Set a bitmap shader that mimics dashing by width-on, width-off.
+// Returns false if it could not succeed (e.g. there was an existing shader)
+static bool setBitmapDash(SkPaint* paint, int width) {
+ if (width <= 0 || paint->getShader())
+ return false;
+
+ SkColor c = paint->getColor();
+
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 1);
+ bm.allocPixels();
+ bm.lockPixels();
+
+ // set the ON pixel
+ *bm.getAddr32(0, 0) = SkPreMultiplyARGB(0xFF, SkColorGetR(c),
+ SkColorGetG(c), SkColorGetB(c));
+ // set the OFF pixel
+ *bm.getAddr32(1, 0) = 0;
+ bm.unlockPixels();
+
+ SkMatrix matrix;
+ matrix.setScale(SkIntToScalar(width), SK_Scalar1);
+
+ SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
+ SkShader::kClamp_TileMode);
+ s->setLocalMatrix(matrix);
+
+ paint->setShader(s)->unref();
+ return true;
+}
+
+//**************************************
+// State implementation
+//**************************************
+
+PlatformGraphicsContext::State::State()
+ : pathEffect(0)
+ , miterLimit(4)
+ , alpha(1)
+ , strokeThickness(0) // Same as default in GraphicsContextPrivate.h
+ , lineCap(SkPaint::kDefault_Cap)
+ , lineJoin(SkPaint::kDefault_Join)
+ , mode(SkXfermode::kSrcOver_Mode)
+ , dashRatio(3)
+ , fillColor(SK_ColorBLACK)
+ , fillShader(0)
+ , strokeColor(SK_ColorBLACK)
+ , strokeShader(0)
+ , useAA(true)
+ , strokeStyle(SolidStroke)
+{
+}
+
+PlatformGraphicsContext::State::State(const State& other)
+ : pathEffect(other.pathEffect)
+ , miterLimit(other.miterLimit)
+ , alpha(other.alpha)
+ , strokeThickness(other.strokeThickness)
+ , lineCap(other.lineCap)
+ , lineJoin(other.lineJoin)
+ , mode(other.mode)
+ , dashRatio(other.dashRatio)
+ , shadow(other.shadow)
+ , fillColor(other.fillColor)
+ , fillShader(other.fillShader)
+ , strokeColor(other.strokeColor)
+ , strokeShader(other.strokeShader)
+ , useAA(other.useAA)
+ , strokeStyle(other.strokeStyle)
+{
+ SkSafeRef(pathEffect);
+ SkSafeRef(fillShader);
+ SkSafeRef(strokeShader);
+}
+
+PlatformGraphicsContext::State::~State()
+{
+ SkSafeUnref(pathEffect);
+ SkSafeUnref(fillShader);
+ SkSafeUnref(strokeShader);
+}
+
+void PlatformGraphicsContext::State::setShadow(int radius, int dx, int dy, SkColor c)
+{
+ // Cut the radius in half, to visually match the effect seen in
+ // safari browser
+ shadow.blur = SkScalarHalf(SkIntToScalar(radius));
+ shadow.dx = SkIntToScalar(dx);
+ shadow.dy = SkIntToScalar(dy);
+ shadow.color = c;
+}
+
+bool PlatformGraphicsContext::State::setupShadowPaint(SkPaint* paint, SkPoint* offset,
+ bool shadowsIgnoreTransforms)
+{
+ paint->setAntiAlias(true);
+ paint->setDither(true);
+ paint->setXfermodeMode(mode);
+ paint->setColor(shadow.color);
+ offset->set(shadow.dx, shadow.dy);
+
+ // Currently, only GraphicsContexts associated with the
+ // HTMLCanvasElement have shadows ignore transforms set. This
+ // allows us to distinguish between CSS and Canvas shadows which
+ // have different rendering specifications.
+ uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag;
+ if (shadowsIgnoreTransforms) {
+ offset->fY = -offset->fY;
+ flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
+ }
+
+ if (shadow.blur > 0) {
+ paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur,
+ SkBlurMaskFilter::kNormal_BlurStyle))->unref();
+ }
+ return SkColorGetA(shadow.color) && (shadow.blur || shadow.dx || shadow.dy);
+}
+
+SkColor PlatformGraphicsContext::State::applyAlpha(SkColor c) const
+{
+ int s = RoundToInt(alpha * 256);
+ if (s >= 256)
+ return c;
+ if (s < 0)
+ return 0;
+
+ int a = SkAlphaMul(SkColorGetA(c), s);
+ return (c & 0x00FFFFFF) | (a << 24);
+}
+
+// Returns a new State with all of this object's inherited properties copied.
+PlatformGraphicsContext::State PlatformGraphicsContext::State::cloneInheritedProperties()
+{
+ return PlatformGraphicsContext::State(*this);
+}
+
+//**************************************
+// PlatformGraphicsContext
+//**************************************
+
+PlatformGraphicsContext::PlatformGraphicsContext()
+{
+ m_stateStack.append(State());
+ m_state = &m_stateStack.last();
+}
+
+PlatformGraphicsContext::~PlatformGraphicsContext()
+{
+}
+
+//**************************************
+// State management
+//**************************************
+
+void PlatformGraphicsContext::save()
+{
+ m_stateStack.append(m_state->cloneInheritedProperties());
+ m_state = &m_stateStack.last();
+}
+
+void PlatformGraphicsContext::restore()
+{
+ m_stateStack.removeLast();
+ m_state = &m_stateStack.last();
+}
+
+//**************************************
+// State setters
+//**************************************
+
+void PlatformGraphicsContext::setAlpha(float alpha)
+{
+ m_state->alpha = alpha;
+}
+
+void PlatformGraphicsContext::setCompositeOperation(CompositeOperator op)
+{
+ m_state->mode = WebCoreCompositeToSkiaComposite(op);
+}
+
+void PlatformGraphicsContext::setFillColor(const Color& c)
+{
+ m_state->fillColor = c.rgb();
+ setFillShader(0);
+}
+
+void PlatformGraphicsContext::setFillShader(SkShader* fillShader)
+{
+ if (fillShader)
+ m_state->fillColor = Color::black;
+
+ if (fillShader != m_state->fillShader) {
+ SkSafeUnref(m_state->fillShader);
+ m_state->fillShader = fillShader;
+ SkSafeRef(m_state->fillShader);
+ }
+}
+
+void PlatformGraphicsContext::setLineCap(LineCap cap)
+{
+ switch (cap) {
+ case ButtCap:
+ m_state->lineCap = SkPaint::kButt_Cap;
+ break;
+ case RoundCap:
+ m_state->lineCap = SkPaint::kRound_Cap;
+ break;
+ case SquareCap:
+ m_state->lineCap = SkPaint::kSquare_Cap;
+ break;
+ default:
+ ALOGD("PlatformGraphicsContextSkia::setLineCap: unknown LineCap %d\n", cap);
+ break;
+ }
+}
+
+void PlatformGraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
+{
+ size_t dashLength = dashes.size();
+ if (!dashLength)
+ return;
+
+ size_t count = !(dashLength % 2) ? dashLength : dashLength * 2;
+ SkScalar* intervals = new SkScalar[count];
+
+ for (unsigned int i = 0; i < count; i++)
+ intervals[i] = SkFloatToScalar(dashes[i % dashLength]);
+ SkPathEffect **effectPtr = &m_state->pathEffect;
+ SkSafeUnref(*effectPtr);
+ *effectPtr = new SkDashPathEffect(intervals, count, SkFloatToScalar(dashOffset));
+
+ delete[] intervals;
+}
+
+void PlatformGraphicsContext::setLineJoin(LineJoin join)
+{
+ switch (join) {
+ case MiterJoin:
+ m_state->lineJoin = SkPaint::kMiter_Join;
+ break;
+ case RoundJoin:
+ m_state->lineJoin = SkPaint::kRound_Join;
+ break;
+ case BevelJoin:
+ m_state->lineJoin = SkPaint::kBevel_Join;
+ break;
+ default:
+ ALOGD("PlatformGraphicsContextSkia::setLineJoin: unknown LineJoin %d\n", join);
+ break;
+ }
+}
+
+void PlatformGraphicsContext::setMiterLimit(float limit)
+{
+ m_state->miterLimit = limit;
+}
+
+void PlatformGraphicsContext::setShadow(int radius, int dx, int dy, SkColor c)
+{
+ m_state->setShadow(radius, dx, dy, c);
+}
+
+void PlatformGraphicsContext::setShouldAntialias(bool useAA)
+{
+ m_state->useAA = useAA;
+}
+
+void PlatformGraphicsContext::setStrokeColor(const Color& c)
+{
+ m_state->strokeColor = c.rgb();
+ setStrokeShader(0);
+}
+
+void PlatformGraphicsContext::setStrokeShader(SkShader* strokeShader)
+{
+ if (strokeShader)
+ m_state->strokeColor = Color::black;
+
+ if (strokeShader != m_state->strokeShader) {
+ SkSafeUnref(m_state->strokeShader);
+ m_state->strokeShader = strokeShader;
+ SkSafeRef(m_state->strokeShader);
+ }
+}
+
+void PlatformGraphicsContext::setStrokeStyle(StrokeStyle style)
+{
+ m_state->strokeStyle = style;
+}
+
+void PlatformGraphicsContext::setStrokeThickness(float f)
+{
+ m_state->strokeThickness = f;
+}
+
+//**************************************
+// Paint setup
+//**************************************
+
+void PlatformGraphicsContext::setupPaintCommon(SkPaint* paint) const
+{
+ paint->setAntiAlias(m_state->useAA);
+ paint->setDither(true);
+ paint->setXfermodeMode(m_state->mode);
+ if (SkColorGetA(m_state->shadow.color) > 0) {
+
+ // Currently, only GraphicsContexts associated with the
+ // HTMLCanvasElement have shadows ignore transforms set. This
+ // allows us to distinguish between CSS and Canvas shadows which
+ // have different rendering specifications.
+ SkScalar dy = m_state->shadow.dy;
+ uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag;
+ if (shadowsIgnoreTransforms()) {
+ dy = -dy;
+ flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
+ flags |= SkBlurDrawLooper::kOverrideColor_BlurFlag;
+ }
+
+ SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur,
+ m_state->shadow.dx,
+ dy,
+ m_state->shadow.color,
+ flags);
+ paint->setLooper(looper)->unref();
+ }
+ paint->setFilterBitmap(true);
+}
+
+void PlatformGraphicsContext::setupPaintFill(SkPaint* paint) const
+{
+ this->setupPaintCommon(paint);
+ paint->setColor(m_state->applyAlpha(m_state->fillColor));
+ paint->setShader(m_state->fillShader);
+}
+
+bool PlatformGraphicsContext::setupPaintShadow(SkPaint* paint, SkPoint* offset) const
+{
+ return m_state->setupShadowPaint(paint, offset, shadowsIgnoreTransforms());
+}
+
+bool PlatformGraphicsContext::setupPaintStroke(SkPaint* paint, SkRect* rect,
+ bool isHLine)
+{
+ this->setupPaintCommon(paint);
+ paint->setColor(m_state->applyAlpha(m_state->strokeColor));
+ paint->setShader(m_state->strokeShader);
+
+ float width = m_state->strokeThickness;
+
+ // This allows dashing and dotting to work properly for hairline strokes
+ // FIXME: Should we only do this for dashed and dotted strokes?
+ if (!width)
+ width = 1;
+
+ paint->setStyle(SkPaint::kStroke_Style);
+ paint->setStrokeWidth(SkFloatToScalar(width));
+ paint->setStrokeCap(m_state->lineCap);
+ paint->setStrokeJoin(m_state->lineJoin);
+ paint->setStrokeMiter(SkFloatToScalar(m_state->miterLimit));
+
+ if (rect && (RoundToInt(width) & 1))
+ rect->inset(-SK_ScalarHalf, -SK_ScalarHalf);
+
+ SkPathEffect* pe = m_state->pathEffect;
+ if (pe) {
+ paint->setPathEffect(pe);
+ return false;
+ }
+ switch (m_state->strokeStyle) {
+ case NoStroke:
+ case SolidStroke:
+ width = 0;
+ break;
+ case DashedStroke:
+ width = m_state->dashRatio * width;
+ break;
+ // No break
+ case DottedStroke:
+ break;
+ }
+
+ if (width > 0) {
+ // Return true if we're basically a dotted dash of squares
+ bool justSqrs = RoundToInt(width) == RoundToInt(paint->getStrokeWidth());
+
+ if (justSqrs || !isHLine || !setBitmapDash(paint, width)) {
+#if 0
+ // this is slow enough that we just skip it for now
+ // see http://b/issue?id=4163023
+ SkScalar intervals[] = { width, width };
+ pe = new SkDashPathEffect(intervals, 2, 0);
+ paint->setPathEffect(pe)->unref();
+#endif
+ }
+ return justSqrs;
+ }
+ return false;
+}
+
+} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h
new file mode 100644
index 0000000..601de0f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2006, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef platform_graphics_context_h
+#define platform_graphics_context_h
+
+#include "IntRect.h"
+#include "GraphicsContext.h"
+#include "RenderSkinAndroid.h"
+#include "SkCanvas.h"
+#include "SkPicture.h"
+#include "SkTDArray.h"
+#include <wtf/Vector.h>
+
+class SkCanvas;
+
+namespace WebCore {
+
+class PlatformGraphicsContext {
+public:
+ PlatformGraphicsContext();
+ virtual ~PlatformGraphicsContext();
+ virtual bool isPaintingDisabled() = 0;
+ virtual SkCanvas* getCanvas() = 0;
+
+ void setGraphicsContext(GraphicsContext* gc) { m_gc = gc; }
+ virtual bool deleteUs() const { return false; }
+
+ typedef enum { PaintingContext, RecordingContext } ContextType;
+ virtual ContextType type() = 0;
+
+ // State management
+ virtual void beginTransparencyLayer(float opacity) = 0;
+ virtual void endTransparencyLayer() = 0;
+ virtual void save();
+ virtual void restore();
+
+ // State values
+ virtual void setAlpha(float alpha);
+ virtual void setCompositeOperation(CompositeOperator op);
+ virtual void setFillColor(const Color& c);
+ virtual void setFillShader(SkShader* fillShader);
+ virtual void setLineCap(LineCap cap);
+ virtual void setLineDash(const DashArray& dashes, float dashOffset);
+ virtual void setLineJoin(LineJoin join);
+ virtual void setMiterLimit(float limit);
+ virtual void setShadow(int radius, int dx, int dy, SkColor c);
+ virtual void setShouldAntialias(bool useAA);
+ virtual void setStrokeColor(const Color& c);
+ virtual void setStrokeShader(SkShader* strokeShader);
+ virtual void setStrokeStyle(StrokeStyle style);
+ virtual void setStrokeThickness(float f);
+
+ // FIXME: These setupPaint* should be private, but
+ // they are used by FontAndroid currently
+ virtual void setupPaintFill(SkPaint* paint) const;
+ virtual bool setupPaintShadow(SkPaint* paint, SkPoint* offset) const;
+ // Sets up the paint for stroking. Returns true if the style is really
+ // just a dash of squares (the size of the paint's stroke-width.
+ virtual bool setupPaintStroke(SkPaint* paint, SkRect* rect, bool isHLine = false);
+
+ // Matrix operations
+ virtual void concatCTM(const AffineTransform& affine) = 0;
+ virtual void rotate(float angleInRadians) = 0;
+ virtual void scale(const FloatSize& size) = 0;
+ virtual void translate(float x, float y) = 0;
+ virtual const SkMatrix& getTotalMatrix() = 0;
+
+ // Clipping
+ virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness) = 0;
+ virtual void canvasClip(const Path& path) = 0;
+ virtual void clip(const FloatRect& rect) = 0;
+ virtual void clip(const Path& path) = 0;
+ virtual void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias) = 0;
+ virtual void clipOut(const IntRect& r) = 0;
+ virtual void clipOut(const Path& p) = 0;
+ virtual void clipPath(const Path& pathToClip, WindRule clipRule) = 0;
+
+ // Drawing
+ virtual void clearRect(const FloatRect& rect) = 0;
+ virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator compositeOp, const FloatRect& destRect) = 0;
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, CompositeOperator op) = 0;
+ virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
+ bool shouldAntialias) = 0;
+ virtual void drawEllipse(const IntRect& rect) = 0;
+ virtual void drawFocusRing(const Vector<IntRect>& rects, int /* width */,
+ int /* offset */, const Color& color) = 0;
+ virtual void drawHighlightForText(const Font& font, const TextRun& run,
+ const FloatPoint& point, int h,
+ const Color& backgroundColor, ColorSpace colorSpace,
+ int from, int to, bool isActive) = 0;
+ virtual void drawLine(const IntPoint& point1, const IntPoint& point2) = 0;
+ virtual void drawLineForText(const FloatPoint& pt, float width) = 0;
+ virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
+ GraphicsContext::TextCheckingLineStyle) = 0;
+ virtual void drawRect(const IntRect& rect) = 0;
+ virtual void fillPath(const Path& pathToFill, WindRule fillRule) = 0;
+ virtual void fillRect(const FloatRect& rect) = 0;
+ void fillRect(const FloatRect& rect, const Color& color, ColorSpace) {
+ fillRect(rect, color);
+ }
+ virtual void fillRect(const FloatRect& rect, const Color& color) = 0;
+ void fillRoundedRect(const IntRect& rect, const IntSize& topLeft,
+ const IntSize& topRight, const IntSize& bottomLeft,
+ const IntSize& bottomRight, const Color& color,
+ ColorSpace) {
+ fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, color);
+ }
+ virtual void fillRoundedRect(const IntRect& rect, const IntSize& topLeft,
+ const IntSize& topRight, const IntSize& bottomLeft,
+ const IntSize& bottomRight, const Color& color) = 0;
+ virtual void strokeArc(const IntRect& r, int startAngle, int angleSpan) = 0;
+ virtual void strokePath(const Path& pathToStroke) = 0;
+ virtual void strokeRect(const FloatRect& rect, float lineWidth) = 0;
+
+ virtual SkCanvas* recordingCanvas() = 0;
+ virtual void endRecording(int type = 0) = 0;
+
+protected:
+
+ struct ShadowRec {
+ SkScalar blur;
+ SkScalar dx;
+ SkScalar dy;
+ SkColor color; // alpha>0 means valid shadow
+ ShadowRec(SkScalar b = 0,
+ SkScalar x = 0,
+ SkScalar y = 0,
+ SkColor c = 0) // by default, alpha=0, so no shadow
+ : blur(b), dx(x), dy(y), color(c)
+ {};
+ };
+
+ class State {
+ public:
+ SkPathEffect* pathEffect;
+ float miterLimit;
+ float alpha;
+ float strokeThickness;
+ SkPaint::Cap lineCap;
+ SkPaint::Join lineJoin;
+ SkXfermode::Mode mode;
+ int dashRatio; // Ratio of the length of a dash to its width
+ ShadowRec shadow;
+ SkColor fillColor;
+ SkShader* fillShader;
+ SkColor strokeColor;
+ SkShader* strokeShader;
+ bool useAA;
+ StrokeStyle strokeStyle;
+
+ State();
+ State(const State& other);
+ ~State();
+
+ void setShadow(int radius, int dx, int dy, SkColor c);
+ bool setupShadowPaint(SkPaint* paint, SkPoint* offset,
+ bool shadowsIgnoreTransforms);
+ SkColor applyAlpha(SkColor c) const;
+
+ State cloneInheritedProperties();
+ private:
+ // Not supported.
+ void operator=(const State&);
+
+ friend class PlatformGraphicsContextRecording;
+ friend class PlatformGraphicsContextSkia;
+ };
+
+ virtual bool shadowsIgnoreTransforms() const = 0;
+ void setupPaintCommon(SkPaint* paint) const;
+ GraphicsContext* m_gc; // Back-ptr to our parent
+
+ struct State;
+ WTF::Vector<State> m_stateStack;
+ State* m_state;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
new file mode 100644
index 0000000..d96124d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
@@ -0,0 +1,373 @@
+#define LOG_TAG "PlatformGraphicsContextRecording"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "PlatformGraphicsContextRecording.h"
+
+#include "AndroidLog.h"
+#include "Font.h"
+#include "GraphicsContext.h"
+#include "GraphicsOperationCollection.h"
+#include "GraphicsOperation.h"
+
+namespace WebCore {
+
+//**************************************
+// PlatformGraphicsContextRecording
+//**************************************
+
+PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(GraphicsOperationCollection* picture)
+ : PlatformGraphicsContext()
+ , mGraphicsOperationCollection(picture)
+ , mPicture(0)
+{
+}
+
+bool PlatformGraphicsContextRecording::isPaintingDisabled()
+{
+ return !mGraphicsOperationCollection;
+}
+
+SkCanvas* PlatformGraphicsContextRecording::recordingCanvas()
+{
+ SkSafeUnref(mPicture);
+ mPicture = new SkPicture();
+ return mPicture->beginRecording(0, 0, 0);
+}
+
+void PlatformGraphicsContextRecording::endRecording(int type)
+{
+ if (!mPicture)
+ return;
+ mPicture->endRecording();
+ GraphicsOperation::DrawComplexText* text = new GraphicsOperation::DrawComplexText(mPicture);
+ mGraphicsOperationCollection->append(text);
+ mPicture = 0;
+}
+
+
+//**************************************
+// State management
+//**************************************
+
+void PlatformGraphicsContextRecording::beginTransparencyLayer(float opacity)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::BeginTransparencyLayer(opacity));
+}
+
+void PlatformGraphicsContextRecording::endTransparencyLayer()
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::EndTransparencyLayer());
+}
+
+void PlatformGraphicsContextRecording::save()
+{
+ PlatformGraphicsContext::save();
+ mGraphicsOperationCollection->append(new GraphicsOperation::Save());
+}
+
+void PlatformGraphicsContextRecording::restore()
+{
+ PlatformGraphicsContext::restore();
+ mGraphicsOperationCollection->append(new GraphicsOperation::Restore());
+}
+
+//**************************************
+// State setters
+//**************************************
+
+void PlatformGraphicsContextRecording::setAlpha(float alpha)
+{
+ PlatformGraphicsContext::setAlpha(alpha);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetAlpha(alpha));
+}
+
+void PlatformGraphicsContextRecording::setCompositeOperation(CompositeOperator op)
+{
+ PlatformGraphicsContext::setCompositeOperation(op);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetCompositeOperation(op));
+}
+
+void PlatformGraphicsContextRecording::setFillColor(const Color& c)
+{
+ PlatformGraphicsContext::setFillColor(c);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetFillColor(c));
+}
+
+void PlatformGraphicsContextRecording::setFillShader(SkShader* fillShader)
+{
+ PlatformGraphicsContext::setFillShader(fillShader);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetFillShader(fillShader));
+}
+
+void PlatformGraphicsContextRecording::setLineCap(LineCap cap)
+{
+ PlatformGraphicsContext::setLineCap(cap);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetLineCap(cap));
+}
+
+void PlatformGraphicsContextRecording::setLineDash(const DashArray& dashes, float dashOffset)
+{
+ PlatformGraphicsContext::setLineDash(dashes, dashOffset);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetLineDash(dashes, dashOffset));
+}
+
+void PlatformGraphicsContextRecording::setLineJoin(LineJoin join)
+{
+ PlatformGraphicsContext::setLineJoin(join);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetLineJoin(join));
+}
+
+void PlatformGraphicsContextRecording::setMiterLimit(float limit)
+{
+ PlatformGraphicsContext::setMiterLimit(limit);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetMiterLimit(limit));
+}
+
+void PlatformGraphicsContextRecording::setShadow(int radius, int dx, int dy, SkColor c)
+{
+ PlatformGraphicsContext::setShadow(radius, dx, dy, c);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetShadow(radius, dx, dy, c));
+}
+
+void PlatformGraphicsContextRecording::setShouldAntialias(bool useAA)
+{
+ m_state->useAA = useAA;
+ PlatformGraphicsContext::setShouldAntialias(useAA);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetShouldAntialias(useAA));
+}
+
+void PlatformGraphicsContextRecording::setStrokeColor(const Color& c)
+{
+ PlatformGraphicsContext::setStrokeColor(c);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeColor(c));
+}
+
+void PlatformGraphicsContextRecording::setStrokeShader(SkShader* strokeShader)
+{
+ PlatformGraphicsContext::setStrokeShader(strokeShader);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeShader(strokeShader));
+}
+
+void PlatformGraphicsContextRecording::setStrokeStyle(StrokeStyle style)
+{
+ PlatformGraphicsContext::setStrokeStyle(style);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeStyle(style));
+}
+
+void PlatformGraphicsContextRecording::setStrokeThickness(float f)
+{
+ PlatformGraphicsContext::setStrokeThickness(f);
+ mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeThickness(f));
+}
+
+//**************************************
+// Matrix operations
+//**************************************
+
+void PlatformGraphicsContextRecording::concatCTM(const AffineTransform& affine)
+{
+ mCurrentMatrix.preConcat(affine);
+ mGraphicsOperationCollection->append(new GraphicsOperation::ConcatCTM(affine));
+}
+
+void PlatformGraphicsContextRecording::rotate(float angleInRadians)
+{
+ float value = angleInRadians * (180.0f / 3.14159265f);
+ mCurrentMatrix.preRotate(SkFloatToScalar(value));
+ mGraphicsOperationCollection->append(new GraphicsOperation::Rotate(angleInRadians));
+}
+
+void PlatformGraphicsContextRecording::scale(const FloatSize& size)
+{
+ mCurrentMatrix.preScale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
+ mGraphicsOperationCollection->append(new GraphicsOperation::Scale(size));
+}
+
+void PlatformGraphicsContextRecording::translate(float x, float y)
+{
+ mCurrentMatrix.preTranslate(SkFloatToScalar(x), SkFloatToScalar(y));
+ mGraphicsOperationCollection->append(new GraphicsOperation::Translate(x, y));
+}
+
+const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix()
+{
+ return mCurrentMatrix;
+}
+
+//**************************************
+// Clipping
+//**************************************
+
+void PlatformGraphicsContextRecording::addInnerRoundedRectClip(const IntRect& rect,
+ int thickness)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::InnerRoundedRectClip(rect, thickness));
+}
+
+void PlatformGraphicsContextRecording::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
+void PlatformGraphicsContextRecording::clip(const FloatRect& rect)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::Clip(rect));
+}
+
+void PlatformGraphicsContextRecording::clip(const Path& path)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::ClipPath(path));
+}
+
+void PlatformGraphicsContextRecording::clipConvexPolygon(size_t numPoints,
+ const FloatPoint*, bool antialias)
+{
+ // TODO
+}
+
+void PlatformGraphicsContextRecording::clipOut(const IntRect& r)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::ClipOut(r));
+}
+
+void PlatformGraphicsContextRecording::clipOut(const Path& path)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::ClipPath(path, true));
+}
+
+void PlatformGraphicsContextRecording::clipPath(const Path& pathToClip, WindRule clipRule)
+{
+ GraphicsOperation::ClipPath* operation = new GraphicsOperation::ClipPath(pathToClip);
+ operation->setWindRule(clipRule);
+ mGraphicsOperationCollection->append(operation);
+}
+
+void PlatformGraphicsContextRecording::clearRect(const FloatRect& rect)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::ClearRect(rect));
+}
+
+//**************************************
+// Drawing
+//**************************************
+
+void PlatformGraphicsContextRecording::drawBitmapPattern(
+ const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator compositeOp, const FloatRect& destRect)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawBitmapPattern(bitmap, matrix, compositeOp, destRect));
+}
+
+void PlatformGraphicsContextRecording::drawBitmapRect(const SkBitmap& bitmap,
+ const SkIRect* src, const SkRect& dst,
+ CompositeOperator op)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawBitmapRect(bitmap, *src, dst, op));
+}
+
+void PlatformGraphicsContextRecording::drawConvexPolygon(size_t numPoints,
+ const FloatPoint* points,
+ bool shouldAntialias)
+{
+ // TODO
+}
+
+void PlatformGraphicsContextRecording::drawEllipse(const IntRect& rect)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawEllipse(rect));
+}
+
+void PlatformGraphicsContextRecording::drawFocusRing(const Vector<IntRect>& rects,
+ int /* width */, int /* offset */,
+ const Color& color)
+{
+ // TODO
+}
+
+void PlatformGraphicsContextRecording::drawHighlightForText(
+ const Font& font, const TextRun& run, const FloatPoint& point, int h,
+ const Color& backgroundColor, ColorSpace colorSpace, int from,
+ int to, bool isActive)
+{
+ IntRect rect = (IntRect)font.selectionRectForText(run, point, h, from, to);
+ if (isActive)
+ fillRect(rect, backgroundColor);
+ else {
+ int x = rect.x(), y = rect.y(), w = rect.width(), h = rect.height();
+ const int t = 3, t2 = t * 2;
+
+ fillRect(IntRect(x, y, w, t), backgroundColor);
+ fillRect(IntRect(x, y+h-t, w, t), backgroundColor);
+ fillRect(IntRect(x, y+t, t, h-t2), backgroundColor);
+ fillRect(IntRect(x+w-t, y+t, t, h-t2), backgroundColor);
+ }
+}
+
+void PlatformGraphicsContextRecording::drawLine(const IntPoint& point1,
+ const IntPoint& point2)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawLine(point1, point2));
+}
+
+void PlatformGraphicsContextRecording::drawLineForText(const FloatPoint& pt, float width)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawLineForText(pt, width));
+}
+
+void PlatformGraphicsContextRecording::drawLineForTextChecking(const FloatPoint& pt,
+ float width, GraphicsContext::TextCheckingLineStyle lineStyle)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawLineForTextChecking(pt, width, lineStyle));
+}
+
+void PlatformGraphicsContextRecording::drawRect(const IntRect& rect)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::DrawRect(rect));
+}
+
+void PlatformGraphicsContextRecording::fillPath(const Path& pathToFill, WindRule fillRule)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::FillPath(pathToFill, fillRule));
+}
+
+void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::FillRect(rect));
+}
+
+void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect,
+ const Color& color)
+{
+ GraphicsOperation::FillRect* operation = new GraphicsOperation::FillRect(rect);
+ operation->setColor(color);
+ mGraphicsOperationCollection->append(operation);
+}
+
+void PlatformGraphicsContextRecording::fillRoundedRect(
+ const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
+ const IntSize& bottomLeft, const IntSize& bottomRight,
+ const Color& color)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::FillRoundedRect(rect, topLeft,
+ topRight, bottomLeft, bottomRight, color));
+}
+
+void PlatformGraphicsContextRecording::strokeArc(const IntRect& r, int startAngle,
+ int angleSpan)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::StrokeArc(r, startAngle, angleSpan));
+}
+
+void PlatformGraphicsContextRecording::strokePath(const Path& pathToStroke)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::StrokePath(pathToStroke));
+}
+
+void PlatformGraphicsContextRecording::strokeRect(const FloatRect& rect, float lineWidth)
+{
+ mGraphicsOperationCollection->append(new GraphicsOperation::StrokeRect(rect, lineWidth));
+}
+
+
+} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
new file mode 100644
index 0000000..ebb0075
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef platform_graphics_context_recording_h
+#define platform_graphics_context_recording_h
+
+#include "PlatformGraphicsContext.h"
+
+namespace WebCore {
+class GraphicsOperationCollection;
+
+class PlatformGraphicsContextRecording : public PlatformGraphicsContext {
+public:
+ PlatformGraphicsContextRecording(GraphicsOperationCollection* picture);
+ virtual ~PlatformGraphicsContextRecording() {}
+ virtual bool isPaintingDisabled();
+ virtual SkCanvas* getCanvas() { return 0; }
+
+ GraphicsOperationCollection* mGraphicsOperationCollection;
+ SkMatrix mCurrentMatrix;
+
+ virtual SkCanvas* recordingCanvas();
+ virtual void endRecording(int type = 0);
+
+ virtual ContextType type() { return RecordingContext; }
+
+ // State management
+ virtual void beginTransparencyLayer(float opacity);
+ virtual void endTransparencyLayer();
+ virtual void save();
+ virtual void restore();
+
+ // State values
+ virtual void setAlpha(float alpha);
+ virtual void setCompositeOperation(CompositeOperator op);
+ virtual void setFillColor(const Color& c);
+ virtual void setFillShader(SkShader* fillShader);
+ virtual void setLineCap(LineCap cap);
+ virtual void setLineDash(const DashArray& dashes, float dashOffset);
+ virtual void setLineJoin(LineJoin join);
+ virtual void setMiterLimit(float limit);
+ virtual void setShadow(int radius, int dx, int dy, SkColor c);
+ virtual void setShouldAntialias(bool useAA);
+ virtual void setStrokeColor(const Color& c);
+ virtual void setStrokeShader(SkShader* strokeShader);
+ virtual void setStrokeStyle(StrokeStyle style);
+ virtual void setStrokeThickness(float f);
+
+ // Matrix operations
+ virtual void concatCTM(const AffineTransform& affine);
+ virtual void rotate(float angleInRadians);
+ virtual void scale(const FloatSize& size);
+ virtual void translate(float x, float y);
+ virtual const SkMatrix& getTotalMatrix();
+
+ // Clipping
+ virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness);
+ virtual void canvasClip(const Path& path);
+ virtual void clip(const FloatRect& rect);
+ virtual void clip(const Path& path);
+ virtual void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+ virtual void clipOut(const IntRect& r);
+ virtual void clipOut(const Path& p);
+ virtual void clipPath(const Path& pathToClip, WindRule clipRule);
+
+ // Drawing
+ virtual void clearRect(const FloatRect& rect);
+ virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator compositeOp, const FloatRect& destRect);
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, CompositeOperator op);
+ virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
+ bool shouldAntialias);
+ virtual void drawEllipse(const IntRect& rect);
+ virtual void drawFocusRing(const Vector<IntRect>& rects, int /* width */,
+ int /* offset */, const Color& color);
+ virtual void drawHighlightForText(const Font& font, const TextRun& run,
+ const FloatPoint& point, int h,
+ const Color& backgroundColor, ColorSpace colorSpace,
+ int from, int to, bool isActive);
+ virtual void drawLine(const IntPoint& point1, const IntPoint& point2);
+ virtual void drawLineForText(const FloatPoint& pt, float width);
+ virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
+ GraphicsContext::TextCheckingLineStyle);
+ virtual void drawRect(const IntRect& rect);
+ virtual void fillPath(const Path& pathToFill, WindRule fillRule);
+ virtual void fillRect(const FloatRect& rect);
+ virtual void fillRect(const FloatRect& rect, const Color& color);
+ virtual void fillRoundedRect(const IntRect& rect, const IntSize& topLeft,
+ const IntSize& topRight, const IntSize& bottomLeft,
+ const IntSize& bottomRight, const Color& color);
+ virtual void strokeArc(const IntRect& r, int startAngle, int angleSpan);
+ virtual void strokePath(const Path& pathToStroke);
+ virtual void strokeRect(const FloatRect& rect, float lineWidth);
+
+private:
+
+ virtual bool shadowsIgnoreTransforms() const {
+ return false;
+ }
+
+ SkPicture* mPicture;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp
new file mode 100644
index 0000000..9b32726
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp
@@ -0,0 +1,606 @@
+#define LOG_TAG "PlatformGraphicsContextSkia"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "PlatformGraphicsContextSkia.h"
+
+#include "AndroidLog.h"
+#include "Font.h"
+#include "GraphicsContext.h"
+#include "SkCanvas.h"
+#include "SkCornerPathEffect.h"
+#include "SkPaint.h"
+#include "SkShader.h"
+#include "SkiaUtils.h"
+
+namespace WebCore {
+
+// These are the flags we need when we call saveLayer for transparency.
+// Since it does not appear that webkit intends this to also save/restore
+// the matrix or clip, I do not give those flags (for performance)
+#define TRANSPARENCY_SAVEFLAGS \
+ (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | \
+ SkCanvas::kFullColorLayer_SaveFlag)
+
+//**************************************
+// Helper functions
+//**************************************
+
+static void setrectForUnderline(SkRect* r, float lineThickness,
+ const FloatPoint& point, int yOffset, float width)
+{
+#if 0
+ if (lineThickness < 1) // Do we really need/want this?
+ lineThickness = 1;
+#endif
+ r->fLeft = point.x();
+ r->fTop = point.y() + yOffset;
+ r->fRight = r->fLeft + width;
+ r->fBottom = r->fTop + lineThickness;
+}
+
+static inline int fastMod(int value, int max)
+{
+ int sign = SkExtractSign(value);
+
+ value = SkApplySign(value, sign);
+ if (value >= max)
+ value %= max;
+ return SkApplySign(value, sign);
+}
+
+static inline void fixPaintForBitmapsThatMaySeam(SkPaint* paint) {
+ /* Bitmaps may be drawn to seem next to other images. If we are drawn
+ zoomed, or at fractional coordinates, we may see cracks/edges if
+ we antialias, because that will cause us to draw the same pixels
+ more than once (e.g. from the left and right bitmaps that share
+ an edge).
+
+ Disabling antialiasing fixes this, and since so far we are never
+ rotated at non-multiple-of-90 angles, this seems to do no harm
+ */
+ paint->setAntiAlias(false);
+}
+
+//**************************************
+// PlatformGraphicsContextSkia
+//**************************************
+
+PlatformGraphicsContextSkia::PlatformGraphicsContextSkia(SkCanvas* canvas,
+ bool takeCanvasOwnership)
+ : PlatformGraphicsContext()
+ , mCanvas(canvas)
+ , m_deleteCanvas(takeCanvasOwnership)
+{
+ m_gc = 0;
+}
+
+PlatformGraphicsContextSkia::~PlatformGraphicsContextSkia()
+{
+ if (m_deleteCanvas)
+ delete mCanvas;
+}
+
+bool PlatformGraphicsContextSkia::isPaintingDisabled()
+{
+ return !mCanvas;
+}
+
+//**************************************
+// State management
+//**************************************
+
+void PlatformGraphicsContextSkia::beginTransparencyLayer(float opacity)
+{
+ SkCanvas* canvas = mCanvas;
+ canvas->saveLayerAlpha(0, (int)(opacity * 255), TRANSPARENCY_SAVEFLAGS);
+}
+
+void PlatformGraphicsContextSkia::endTransparencyLayer()
+{
+ if (!mCanvas)
+ return;
+ mCanvas->restore();
+}
+
+void PlatformGraphicsContextSkia::save()
+{
+ PlatformGraphicsContext::save();
+ // Save our native canvas.
+ mCanvas->save();
+}
+
+void PlatformGraphicsContextSkia::restore()
+{
+ PlatformGraphicsContext::restore();
+ // Restore our native canvas.
+ mCanvas->restore();
+}
+
+//**************************************
+// Matrix operations
+//**************************************
+
+void PlatformGraphicsContextSkia::concatCTM(const AffineTransform& affine)
+{
+ mCanvas->concat(affine);
+}
+
+void PlatformGraphicsContextSkia::rotate(float angleInRadians)
+{
+ float value = angleInRadians * (180.0f / 3.14159265f);
+ mCanvas->rotate(SkFloatToScalar(value));
+}
+
+void PlatformGraphicsContextSkia::scale(const FloatSize& size)
+{
+ mCanvas->scale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
+}
+
+void PlatformGraphicsContextSkia::translate(float x, float y)
+{
+ mCanvas->translate(SkFloatToScalar(x), SkFloatToScalar(y));
+}
+
+const SkMatrix& PlatformGraphicsContextSkia::getTotalMatrix()
+{
+ return mCanvas->getTotalMatrix();
+}
+
+//**************************************
+// Clipping
+//**************************************
+
+void PlatformGraphicsContextSkia::addInnerRoundedRectClip(const IntRect& rect,
+ int thickness)
+{
+ SkPath path;
+ SkRect r(rect);
+
+ path.addOval(r, SkPath::kCW_Direction);
+ // Only perform the inset if we won't invert r
+ if (2 * thickness < rect.width() && 2 * thickness < rect.height()) {
+ // Adding one to the thickness doesn't make the border too thick as
+ // it's painted over afterwards. But without this adjustment the
+ // border appears a little anemic after anti-aliasing.
+ r.inset(SkIntToScalar(thickness + 1), SkIntToScalar(thickness + 1));
+ path.addOval(r, SkPath::kCCW_Direction);
+ }
+ mCanvas->clipPath(path, SkRegion::kIntersect_Op, true);
+}
+
+void PlatformGraphicsContextSkia::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
+void PlatformGraphicsContextSkia::clip(const FloatRect& rect)
+{
+ mCanvas->clipRect(rect);
+}
+
+void PlatformGraphicsContextSkia::clip(const Path& path)
+{
+ mCanvas->clipPath(*path.platformPath(), SkRegion::kIntersect_Op, true);
+}
+
+void PlatformGraphicsContextSkia::clipConvexPolygon(size_t numPoints,
+ const FloatPoint*, bool antialias)
+{
+ if (numPoints <= 1)
+ return;
+
+ // This is only used if HAVE_PATH_BASED_BORDER_RADIUS_DRAWING is defined
+ // in RenderObject.h which it isn't for us. TODO: Support that :)
+}
+
+void PlatformGraphicsContextSkia::clipOut(const IntRect& r)
+{
+ mCanvas->clipRect(r, SkRegion::kDifference_Op);
+}
+
+void PlatformGraphicsContextSkia::clipOut(const Path& path)
+{
+ mCanvas->clipPath(*path.platformPath(), SkRegion::kDifference_Op);
+}
+
+void PlatformGraphicsContextSkia::clipPath(const Path& pathToClip, WindRule clipRule)
+{
+ SkPath path = *pathToClip.platformPath();
+ path.setFillType(clipRule == RULE_EVENODD
+ ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
+ mCanvas->clipPath(path);
+}
+void PlatformGraphicsContextSkia::clearRect(const FloatRect& rect)
+{
+ SkPaint paint;
+
+ setupPaintFill(&paint);
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
+
+ mCanvas->drawRect(rect, paint);
+}
+
+//**************************************
+// Drawing
+//**************************************
+
+void PlatformGraphicsContextSkia::drawBitmapPattern(
+ const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator compositeOp, const FloatRect& destRect)
+{
+ SkShader* shader = SkShader::CreateBitmapShader(bitmap,
+ SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode);
+ shader->setLocalMatrix(matrix);
+ SkPaint paint;
+ setupPaintFill(&paint);
+ paint.setShader(shader);
+ paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp));
+ fixPaintForBitmapsThatMaySeam(&paint);
+ mCanvas->drawRect(destRect, paint);
+}
+
+void PlatformGraphicsContextSkia::drawBitmapRect(const SkBitmap& bitmap,
+ const SkIRect* src, const SkRect& dst,
+ CompositeOperator op)
+{
+ SkPaint paint;
+ setupPaintFill(&paint);
+ paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(op));
+ fixPaintForBitmapsThatMaySeam(&paint);
+
+ mCanvas->drawBitmapRect(bitmap, src, dst, &paint);
+}
+
+void PlatformGraphicsContextSkia::drawConvexPolygon(size_t numPoints,
+ const FloatPoint* points,
+ bool shouldAntialias)
+{
+ if (numPoints <= 1)
+ return;
+
+ SkPaint paint;
+ SkPath path;
+
+ path.incReserve(numPoints);
+ path.moveTo(SkFloatToScalar(points[0].x()), SkFloatToScalar(points[0].y()));
+ for (size_t i = 1; i < numPoints; i++)
+ path.lineTo(SkFloatToScalar(points[i].x()), SkFloatToScalar(points[i].y()));
+
+ if (mCanvas->quickReject(path, shouldAntialias ?
+ SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) {
+ return;
+ }
+
+ if (m_state->fillColor & 0xFF000000) {
+ setupPaintFill(&paint);
+ paint.setAntiAlias(shouldAntialias);
+ mCanvas->drawPath(path, paint);
+ }
+
+ if (m_state->strokeStyle != NoStroke) {
+ paint.reset();
+ setupPaintStroke(&paint, 0);
+ paint.setAntiAlias(shouldAntialias);
+ mCanvas->drawPath(path, paint);
+ }
+}
+
+void PlatformGraphicsContextSkia::drawEllipse(const IntRect& rect)
+{
+ SkPaint paint;
+ SkRect oval(rect);
+
+ if (m_state->fillColor & 0xFF000000) {
+ setupPaintFill(&paint);
+ mCanvas->drawOval(oval, paint);
+ }
+ if (m_state->strokeStyle != NoStroke) {
+ paint.reset();
+ setupPaintStroke(&paint, &oval);
+ mCanvas->drawOval(oval, paint);
+ }
+}
+
+void PlatformGraphicsContextSkia::drawFocusRing(const Vector<IntRect>& rects,
+ int /* width */, int /* offset */,
+ const Color& color)
+{
+ unsigned rectCount = rects.size();
+ if (!rectCount)
+ return;
+
+ SkRegion focusRingRegion;
+ const SkScalar focusRingOutset = WebCoreFloatToSkScalar(0.8);
+ for (unsigned i = 0; i < rectCount; i++) {
+ SkIRect r = rects[i];
+ r.inset(-focusRingOutset, -focusRingOutset);
+ focusRingRegion.op(r, SkRegion::kUnion_Op);
+ }
+
+ SkPath path;
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+
+ paint.setColor(color.rgb());
+ paint.setStrokeWidth(focusRingOutset * 2);
+ paint.setPathEffect(new SkCornerPathEffect(focusRingOutset * 2))->unref();
+ focusRingRegion.getBoundaryPath(&path);
+ mCanvas->drawPath(path, paint);
+}
+
+void PlatformGraphicsContextSkia::drawHighlightForText(
+ const Font& font, const TextRun& run, const FloatPoint& point, int h,
+ const Color& backgroundColor, ColorSpace colorSpace, int from,
+ int to, bool isActive)
+{
+ IntRect rect = (IntRect)font.selectionRectForText(run, point, h, from, to);
+ if (isActive)
+ fillRect(rect, backgroundColor);
+ else {
+ int x = rect.x(), y = rect.y(), w = rect.width(), h = rect.height();
+ const int t = 3, t2 = t * 2;
+
+ fillRect(IntRect(x, y, w, t), backgroundColor);
+ fillRect(IntRect(x, y+h-t, w, t), backgroundColor);
+ fillRect(IntRect(x, y+t, t, h-t2), backgroundColor);
+ fillRect(IntRect(x+w-t, y+t, t, h-t2), backgroundColor);
+ }
+}
+
+void PlatformGraphicsContextSkia::drawLine(const IntPoint& point1,
+ const IntPoint& point2)
+{
+ StrokeStyle style = m_state->strokeStyle;
+ if (style == NoStroke)
+ return;
+
+ SkPaint paint;
+ SkCanvas* canvas = mCanvas;
+ const int idx = SkAbs32(point2.x() - point1.x());
+ const int idy = SkAbs32(point2.y() - point1.y());
+
+ // Special-case horizontal and vertical lines that are really just dots
+ if (setupPaintStroke(&paint, 0, !idy) && (!idx || !idy)) {
+ const SkScalar diameter = paint.getStrokeWidth();
+ const SkScalar radius = SkScalarHalf(diameter);
+ SkScalar x = SkIntToScalar(SkMin32(point1.x(), point2.x()));
+ SkScalar y = SkIntToScalar(SkMin32(point1.y(), point2.y()));
+ SkScalar dx, dy;
+ int count;
+ SkRect bounds;
+
+ if (!idy) { // Horizontal
+ bounds.set(x, y - radius, x + SkIntToScalar(idx), y + radius);
+ x += radius;
+ dx = diameter * 2;
+ dy = 0;
+ count = idx;
+ } else { // Vertical
+ bounds.set(x - radius, y, x + radius, y + SkIntToScalar(idy));
+ y += radius;
+ dx = 0;
+ dy = diameter * 2;
+ count = idy;
+ }
+
+ // The actual count is the number of ONs we hit alternating
+ // ON(diameter), OFF(diameter), ...
+ {
+ SkScalar width = SkScalarDiv(SkIntToScalar(count), diameter);
+ // Now compute the number of cells (ON and OFF)
+ count = SkScalarRound(width);
+ // Now compute the number of ONs
+ count = (count + 1) >> 1;
+ }
+
+ SkAutoMalloc storage(count * sizeof(SkPoint));
+ SkPoint* verts = (SkPoint*)storage.get();
+ // Now build the array of vertices to past to drawPoints
+ for (int i = 0; i < count; i++) {
+ verts[i].set(x, y);
+ x += dx;
+ y += dy;
+ }
+
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setPathEffect(0);
+
+ // Clipping to bounds is not required for correctness, but it does
+ // allow us to reject the entire array of points if we are completely
+ // offscreen. This is common in a webpage for android, where most of
+ // the content is clipped out. If drawPoints took an (optional) bounds
+ // parameter, that might even be better, as we would *just* use it for
+ // culling, and not both wacking the canvas' save/restore stack.
+ canvas->save(SkCanvas::kClip_SaveFlag);
+ canvas->clipRect(bounds);
+ canvas->drawPoints(SkCanvas::kPoints_PointMode, count, verts, paint);
+ canvas->restore();
+ } else {
+ SkPoint pts[2] = { point1, point2 };
+ canvas->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
+ }
+}
+
+void PlatformGraphicsContextSkia::drawLineForText(const FloatPoint& pt, float width)
+{
+ SkRect r;
+ setrectForUnderline(&r, m_state->strokeThickness, pt, 0, width);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(m_state->strokeColor);
+
+ mCanvas->drawRect(r, paint);
+}
+
+void PlatformGraphicsContextSkia::drawLineForTextChecking(const FloatPoint& pt,
+ float width, GraphicsContext::TextCheckingLineStyle)
+{
+ // TODO: Should we draw different based on TextCheckingLineStyle?
+ SkRect r;
+ setrectForUnderline(&r, m_state->strokeThickness, pt, 0, width);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SK_ColorRED); // Is this specified somewhere?
+
+ mCanvas->drawRect(r, paint);
+}
+
+void PlatformGraphicsContextSkia::drawRect(const IntRect& rect)
+{
+ SkPaint paint;
+ SkRect r(rect);
+
+ if (m_state->fillColor & 0xFF000000) {
+ setupPaintFill(&paint);
+ mCanvas->drawRect(r, paint);
+ }
+
+ // According to GraphicsContext.h, stroking inside drawRect always means
+ // a stroke of 1 inside the rect.
+ if (m_state->strokeStyle != NoStroke && (m_state->strokeColor & 0xFF000000)) {
+ paint.reset();
+ setupPaintStroke(&paint, &r);
+ paint.setPathEffect(0); // No dashing please
+ paint.setStrokeWidth(SK_Scalar1); // Always just 1.0 width
+ r.inset(SK_ScalarHalf, SK_ScalarHalf); // Ensure we're "inside"
+ mCanvas->drawRect(r, paint);
+ }
+}
+
+void PlatformGraphicsContextSkia::fillPath(const Path& pathToFill, WindRule fillRule)
+{
+ SkPath* path = pathToFill.platformPath();
+ if (!path)
+ return;
+
+ switch (fillRule) {
+ case RULE_NONZERO:
+ path->setFillType(SkPath::kWinding_FillType);
+ break;
+ case RULE_EVENODD:
+ path->setFillType(SkPath::kEvenOdd_FillType);
+ break;
+ }
+
+ SkPaint paint;
+ setupPaintFill(&paint);
+
+ mCanvas->drawPath(*path, paint);
+}
+
+void PlatformGraphicsContextSkia::fillRect(const FloatRect& rect)
+{
+ SkPaint paint;
+ setupPaintFill(&paint);
+ mCanvas->drawRect(rect, paint);
+}
+
+void PlatformGraphicsContextSkia::fillRect(const FloatRect& rect,
+ const Color& color)
+{
+ if (color.rgb() & 0xFF000000) {
+ SkPaint paint;
+
+ setupPaintCommon(&paint);
+ paint.setColor(color.rgb()); // Punch in the specified color
+ paint.setShader(0); // In case we had one set
+
+ // Sometimes we record and draw portions of the page, using clips
+ // for each portion. The problem with this is that webkit, sometimes,
+ // sees that we're only recording a portion, and they adjust some of
+ // their rectangle coordinates accordingly (e.g.
+ // RenderBoxModelObject::paintFillLayerExtended() which calls
+ // rect.intersect(paintInfo.rect) and then draws the bg with that
+ // rect. The result is that we end up drawing rects that are meant to
+ // seam together (one for each portion), but if the rects have
+ // fractional coordinates (e.g. we are zoomed by a fractional amount)
+ // we will double-draw those edges, resulting in visual cracks or
+ // artifacts.
+
+ // The fix seems to be to just turn off antialasing for rects (this
+ // entry-point in GraphicsContext seems to have been sufficient,
+ // though perhaps we'll find we need to do this as well in fillRect(r)
+ // as well.) Currently setupPaintCommon() enables antialiasing.
+
+ // Since we never show the page rotated at a funny angle, disabling
+ // antialiasing seems to have no real down-side, and it does fix the
+ // bug when we're zoomed (and drawing portions that need to seam).
+ paint.setAntiAlias(false);
+
+ mCanvas->drawRect(rect, paint);
+ }
+}
+
+void PlatformGraphicsContextSkia::fillRoundedRect(
+ const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
+ const IntSize& bottomLeft, const IntSize& bottomRight,
+ const Color& color)
+{
+ SkPaint paint;
+ SkPath path;
+ SkScalar radii[8];
+
+ radii[0] = SkIntToScalar(topLeft.width());
+ radii[1] = SkIntToScalar(topLeft.height());
+ radii[2] = SkIntToScalar(topRight.width());
+ radii[3] = SkIntToScalar(topRight.height());
+ radii[4] = SkIntToScalar(bottomRight.width());
+ radii[5] = SkIntToScalar(bottomRight.height());
+ radii[6] = SkIntToScalar(bottomLeft.width());
+ radii[7] = SkIntToScalar(bottomLeft.height());
+ path.addRoundRect(rect, radii);
+
+ setupPaintFill(&paint);
+ paint.setColor(color.rgb());
+ mCanvas->drawPath(path, paint);
+}
+
+void PlatformGraphicsContextSkia::strokeArc(const IntRect& r, int startAngle,
+ int angleSpan)
+{
+ SkPath path;
+ SkPaint paint;
+ SkRect oval(r);
+
+ if (m_state->strokeStyle == NoStroke) {
+ setupPaintFill(&paint); // We want the fill color
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(SkFloatToScalar(m_state->strokeThickness));
+ } else
+ setupPaintStroke(&paint, 0);
+
+ // We do this before converting to scalar, so we don't overflow SkFixed
+ startAngle = fastMod(startAngle, 360);
+ angleSpan = fastMod(angleSpan, 360);
+
+ path.addArc(oval, SkIntToScalar(-startAngle), SkIntToScalar(-angleSpan));
+ mCanvas->drawPath(path, paint);
+}
+
+void PlatformGraphicsContextSkia::strokePath(const Path& pathToStroke)
+{
+ const SkPath* path = pathToStroke.platformPath();
+ if (!path)
+ return;
+
+ SkPaint paint;
+ setupPaintStroke(&paint, 0);
+
+ mCanvas->drawPath(*path, paint);
+}
+
+void PlatformGraphicsContextSkia::strokeRect(const FloatRect& rect, float lineWidth)
+{
+ SkPaint paint;
+
+ setupPaintStroke(&paint, 0);
+ paint.setStrokeWidth(SkFloatToScalar(lineWidth));
+ mCanvas->drawRect(rect, paint);
+}
+
+} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h
new file mode 100644
index 0000000..724e20b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef platform_graphics_context_skia_h
+#define platform_graphics_context_skia_h
+
+#include "PlatformGraphicsContext.h"
+
+namespace WebCore {
+
+class PlatformGraphicsContextSkia : public PlatformGraphicsContext {
+public:
+ PlatformGraphicsContextSkia(SkCanvas* canvas, bool takeCanvasOwnership = false);
+ virtual ~PlatformGraphicsContextSkia();
+ virtual bool isPaintingDisabled();
+ virtual SkCanvas* getCanvas() { return mCanvas; }
+
+ virtual ContextType type() { return PaintingContext; }
+ virtual SkCanvas* recordingCanvas() { return mCanvas; }
+ virtual void endRecording(int type = 0) {}
+
+ // FIXME: This is used by ImageBufferAndroid, which should really be
+ // managing the canvas lifecycle itself
+
+ virtual bool deleteUs() const { return m_deleteCanvas; }
+
+ // State management
+ virtual void beginTransparencyLayer(float opacity);
+ virtual void endTransparencyLayer();
+ virtual void save();
+ virtual void restore();
+
+ // Matrix operations
+ virtual void concatCTM(const AffineTransform& affine);
+ virtual void rotate(float angleInRadians);
+ virtual void scale(const FloatSize& size);
+ virtual void translate(float x, float y);
+ virtual const SkMatrix& getTotalMatrix();
+
+ // Clipping
+ virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness);
+ virtual void canvasClip(const Path& path);
+ virtual void clip(const FloatRect& rect);
+ virtual void clip(const Path& path);
+ virtual void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+ virtual void clipOut(const IntRect& r);
+ virtual void clipOut(const Path& p);
+ virtual void clipPath(const Path& pathToClip, WindRule clipRule);
+
+ // Drawing
+ virtual void clearRect(const FloatRect& rect);
+ virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator compositeOp, const FloatRect& destRect);
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, CompositeOperator op);
+ virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
+ bool shouldAntialias);
+ virtual void drawEllipse(const IntRect& rect);
+ virtual void drawFocusRing(const Vector<IntRect>& rects, int /* width */,
+ int /* offset */, const Color& color);
+ virtual void drawHighlightForText(const Font& font, const TextRun& run,
+ const FloatPoint& point, int h,
+ const Color& backgroundColor, ColorSpace colorSpace,
+ int from, int to, bool isActive);
+ virtual void drawLine(const IntPoint& point1, const IntPoint& point2);
+ virtual void drawLineForText(const FloatPoint& pt, float width);
+ virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
+ GraphicsContext::TextCheckingLineStyle);
+ virtual void drawRect(const IntRect& rect);
+ virtual void fillPath(const Path& pathToFill, WindRule fillRule);
+ virtual void fillRect(const FloatRect& rect);
+ virtual void fillRect(const FloatRect& rect, const Color& color);
+ virtual void fillRoundedRect(const IntRect& rect, const IntSize& topLeft,
+ const IntSize& topRight, const IntSize& bottomLeft,
+ const IntSize& bottomRight, const Color& color);
+ virtual void strokeArc(const IntRect& r, int startAngle, int angleSpan);
+ virtual void strokePath(const Path& pathToStroke);
+ virtual void strokeRect(const FloatRect& rect, float lineWidth);
+
+private:
+
+ // shadowsIgnoreTransforms is only true for canvas's ImageBuffer, which will
+ // have a GraphicsContext
+ virtual bool shadowsIgnoreTransforms() const {
+ return m_gc && m_gc->shadowsIgnoreTransforms();
+ }
+
+ SkCanvas* mCanvas;
+ bool m_deleteCanvas;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/android_graphics.h b/Source/WebCore/platform/graphics/android/context/android_graphics.h
index 7faa781..7faa781 100644
--- a/Source/WebCore/platform/graphics/android/android_graphics.h
+++ b/Source/WebCore/platform/graphics/android/context/android_graphics.h
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
index c8b9488..3146612 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
@@ -27,6 +27,8 @@
#include "config.h"
#include "EmojiFont.h"
+#include "GraphicsOperationCollection.h"
+#include "GraphicsOperation.h"
#include "Font.h"
#include "FontData.h"
#include "FontFallbackList.h"
@@ -196,7 +198,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs);
SkPoint* pos = storage.get();
- SkCanvas* canvas = gc->platformContext()->mCanvas;
+ SkCanvas* canvas = gc->platformContext()->recordingCanvas();
/* We need an array of [x,y,x,y,x,y,...], but webkit is giving us
point.xy + [width, height, width, height, ...], so we have to convert
@@ -254,6 +256,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
if (font->platformData().orientation() == Vertical)
canvas->restore();
}
+ gc->platformContext()->endRecording();
}
void Font::drawEmphasisMarksForComplexText(WebCore::GraphicsContext*, WebCore::TextRun const&, WTF::AtomicString const&, WebCore::FloatPoint const&, int, int) const
@@ -1054,7 +1057,8 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
if (stroke)
setupStroke(&strokePaint, gc, primaryFont());
- SkCanvas* canvas = gc->platformContext()->mCanvas;
+ SkCanvas* canvas = gc->platformContext()->recordingCanvas();
+
bool haveMultipleLayers = isCanvasMultiLayered(canvas);
TextRunWalker walker(run, point.x(), point.y(), this);
walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing());
@@ -1074,6 +1078,8 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
walker.positions(), strokePaint);
}
}
+
+ gc->platformContext()->endRecording();
}
float Font::floatWidthForComplexText(const TextRun& run,
diff --git a/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp
index 5696a46..5696a46 100644
--- a/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp
diff --git a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/android/fonts/FontCustomPlatformData.cpp
index 693386e..693386e 100644
--- a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontCustomPlatformData.cpp
diff --git a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/android/fonts/FontCustomPlatformData.h
index 47e5e71..47e5e71 100644
--- a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/fonts/FontCustomPlatformData.h
diff --git a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontDataAndroid.cpp
index c6dd174..88822df 100644
--- a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontDataAndroid.cpp
@@ -56,8 +56,12 @@ void SimpleFontData::platformInit()
m_fontMetrics.setAscent(a);
m_fontMetrics.setDescent(d);
m_fontMetrics.setXHeight(SkScalarToFloat(-skiaFontMetrics.fAscent) * 0.56f); // hack I stole from the window's port
- m_fontMetrics.setLineSpacing(a + d);
- m_fontMetrics.setLineGap(SkScalarToFloat(skiaFontMetrics.fLeading));
+ float lineGap = SkScalarToFloat(skiaFontMetrics.fLeading);
+ if (platformData().orientation() == Vertical && lineGap == 0) {
+ lineGap = skiaFontMetrics.fAvgCharWidth * 0.56f;
+ }
+ m_fontMetrics.setLineGap(lineGap);
+ m_fontMetrics.setLineSpacing(a + d + lineGap);
if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformData.h b/Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h
index 1e46971..1e46971 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontPlatformDataAndroid.cpp
index fc254c0..fc254c0 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontPlatformDataAndroid.cpp
diff --git a/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp
index a327b79..b9798e6 100644
--- a/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp
@@ -44,12 +44,12 @@ namespace WebCore {
#define NO_BREAK_SPACE_UNICHAR 0xA0
-static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, uint16_t* glyphs, unsigned bufferLength)
+static HB_Error substituteWithVerticalGlyphs(const FontPlatformData& platformData, uint16_t* glyphs, unsigned bufferLength)
{
HB_FaceRec_* hbFace = platformData.harfbuzzFace();
if (!hbFace->gsub) {
// if there is no GSUB table, treat it as not covered
- return 0Xffff;
+ return static_cast<HB_Error>(0Xffff);
}
HB_Buffer buffer;
@@ -60,13 +60,19 @@ static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, ui
HB_UShort scriptIndex;
HB_UShort featureIndex;
- HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex);
+ HB_Error error = HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex);
+ if (error) {
+ if (error != HB_Err_Not_Covered)
+ return error;
+ scriptIndex = HB_Script_Common; // Set script to common script.
+ }
+
HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'e', 'r', 't'), scriptIndex, 0xffff, &featureIndex);
HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1);
HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'r', 't', '2'), scriptIndex, 0xffff, &featureIndex);
HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1);
- int error = HB_GSUB_Apply_String(hbFace->gsub, buffer);
+ error = HB_GSUB_Apply_String(hbFace->gsub, buffer);
if (!error) {
for (unsigned i = 0; i < bufferLength; ++i)
glyphs[i] = static_cast<Glyph>(buffer->out_string[i].gindex);
@@ -74,6 +80,14 @@ static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, ui
return error;
}
+static void convertToVerticalForms(UChar* src, UChar* dest, unsigned bufferLength) {
+ for (unsigned i = 0; i < bufferLength; ++i) {
+ dest[i] = VerticalTextMap::getVerticalForm(src[i]);
+ if (!dest[i])
+ dest[i] = src[i];
+ }
+}
+
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
{
if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) {
@@ -92,11 +106,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
if (fontData->platformData().orientation() == Vertical && !fontData->hasVerticalGlyphs()) {
// Convert to vertical form if there is no vertical glyphs.
- for (unsigned i = 0; i < bufferLength; ++i) {
- vTextBuffer[i] = VerticalTextMap::getVerticalForm(buffer[i]);
- if (!vTextBuffer[i])
- vTextBuffer[i] = buffer[i];
- }
+ convertToVerticalForms(buffer, vTextBuffer, bufferLength);
textBuffer = vTextBuffer;
}
@@ -111,11 +121,22 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
for (unsigned i = 0; i < bufferLength; ++i) {
if (!Font::isCJKIdeograph(textBuffer[i])) {
lookVariants = true;
- continue;
+ break;
+ }
+ }
+ if (lookVariants) {
+ if (substituteWithVerticalGlyphs(fontData->platformData(), glyphs, bufferLength)) {
+ // Convert text to vertical forms if substituteWithVerticalGlyphs() fails to access vert tables.
+ convertToVerticalForms(buffer, vTextBuffer, bufferLength);
+ textBuffer = vTextBuffer;
+
+ unsigned count = paint.textToGlyphs(textBuffer, bufferLength << 1, glyphs);
+ if (count != length) {
+ SkDebugf("%s count != length\n", __FUNCTION__);
+ return false;
+ }
}
}
- if (lookVariants)
- substituteWithVerticalGlyphs(fontData->platformData(), glyphs, bufferLength);
}
unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero
diff --git a/Source/WebCore/platform/graphics/android/HarfbuzzSkia.cpp b/Source/WebCore/platform/graphics/android/fonts/HarfbuzzSkia.cpp
index 7c3a6b4..7c3a6b4 100644
--- a/Source/WebCore/platform/graphics/android/HarfbuzzSkia.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/HarfbuzzSkia.cpp
diff --git a/Source/WebCore/platform/graphics/android/HarfbuzzSkia.h b/Source/WebCore/platform/graphics/android/fonts/HarfbuzzSkia.h
index d26bbe2..d26bbe2 100644
--- a/Source/WebCore/platform/graphics/android/HarfbuzzSkia.h
+++ b/Source/WebCore/platform/graphics/android/fonts/HarfbuzzSkia.h
diff --git a/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp b/Source/WebCore/platform/graphics/android/fonts/VerticalTextMap.cpp
index 42aa385..42aa385 100644
--- a/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/VerticalTextMap.cpp
diff --git a/Source/WebCore/platform/graphics/android/VerticalTextMap.h b/Source/WebCore/platform/graphics/android/fonts/VerticalTextMap.h
index 2955589..2955589 100644
--- a/Source/WebCore/platform/graphics/android/VerticalTextMap.h
+++ b/Source/WebCore/platform/graphics/android/fonts/VerticalTextMap.h
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/layers/AndroidAnimation.cpp
index 0ef84b9..0ef84b9 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/AndroidAnimation.cpp
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.h b/Source/WebCore/platform/graphics/android/layers/AndroidAnimation.h
index dca769f..dca769f 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.h
+++ b/Source/WebCore/platform/graphics/android/layers/AndroidAnimation.h
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
new file mode 100644
index 0000000..ce520b4
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "BaseLayerAndroid"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "BaseLayerAndroid.h"
+
+#include "AndroidLog.h"
+#include "GLWebViewState.h"
+#include "LayerContent.h"
+
+namespace WebCore {
+
+// Note: this must match the use of ID 0 specifying the base layer in DrawExtra
+#define BASE_UNIQUE_ID 0
+
+BaseLayerAndroid::BaseLayerAndroid(LayerContent* content)
+ : LayerAndroid((RenderLayer*)0)
+ , m_color(Color::white)
+{
+ setContent(content);
+ setSize(content->width(), content->height());
+ m_uniqueId = BASE_UNIQUE_ID;
+}
+
+void BaseLayerAndroid::getLocalTransform(SkMatrix* matrix) const
+{
+ // base layer doesn't use size in transform calculation
+ matrix->preConcat(getMatrix());
+}
+
+IFrameLayerAndroid* BaseLayerAndroid::updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer)
+{
+ if (viewport.fRight > getWidth() || viewport.fBottom > getHeight()) {
+ // To handle the viewport expanding past the layer's size with HW accel,
+ // expand the size of the layer, so that tiles will cover the viewport.
+ setSize(std::max(viewport.fRight, getWidth()),
+ std::max(viewport.fBottom, getHeight()));
+ }
+
+ return LayerAndroid::updatePosition(viewport, parentIframeLayer);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
new file mode 100644
index 0000000..f4cf9f3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BaseLayerAndroid_h
+#define BaseLayerAndroid_h
+
+#include "Color.h"
+#include "LayerAndroid.h"
+
+namespace WebCore {
+
+class RenderLayerCompositor;
+
+class BaseLayerAndroid : public LayerAndroid {
+
+public:
+ BaseLayerAndroid(LayerContent* content);
+
+ virtual ~BaseLayerAndroid() {};
+
+ virtual SubclassType subclassType() { return LayerAndroid::BaseLayer; }
+ virtual bool needsTexture() { return true; }
+
+ void setBackgroundColor(Color& color) { m_color = color; }
+ Color getBackgroundColor() { return m_color; }
+
+ virtual void getLocalTransform(SkMatrix* matrix) const;
+ virtual const TransformationMatrix* drawTransform() const { return 0; }
+
+ virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer);
+private:
+ // TODO: move to SurfaceCollection.
+ Color m_color;
+};
+
+} // namespace WebCore
+
+#endif //BaseLayerAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
new file mode 100644
index 0000000..1813903
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "CanvasLayer"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "CanvasLayer.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "AndroidLog.h"
+#include "CanvasTexture.h"
+#include "DrawQuadData.h"
+#include "Image.h"
+#include "ImageBuffer.h"
+#include "RenderLayerCompositor.h"
+#include "SkBitmap.h"
+#include "SkBitmapRef.h"
+#include "SkCanvas.h"
+#include "TilesManager.h"
+
+namespace WebCore {
+
+CanvasLayer::CanvasLayer(RenderLayer* owner, HTMLCanvasElement* canvas)
+ : LayerAndroid(owner)
+ , m_canvas(canvas)
+ , m_dirtyCanvas()
+ , m_bitmap(0)
+{
+ init();
+ m_canvas->addObserver(this);
+}
+
+CanvasLayer::CanvasLayer(const CanvasLayer& layer)
+ : LayerAndroid(layer)
+ , m_canvas(0)
+ , m_bitmap(0)
+{
+ init();
+ if (!layer.m_canvas) {
+ // The canvas has already been destroyed - this shouldn't happen
+ ALOGW("Creating a CanvasLayer for a destroyed canvas!");
+ m_contentRect = IntRect();
+ m_offsetFromRenderer = IntSize();
+ m_texture->setHwAccelerated(false);
+ return;
+ }
+ // We are making a copy for the UI, sync the interesting bits
+ m_contentRect = layer.contentRect();
+ m_offsetFromRenderer = layer.offsetFromRenderer();
+ bool previousState = m_texture->hasValidTexture();
+ if (!previousState && layer.m_dirtyCanvas.isEmpty()) {
+ // We were previously in software and don't have anything new to draw,
+ // so stay in software
+ m_bitmap = layer.bitmap();
+ SkSafeRef(m_bitmap);
+ } else {
+ // Attempt to upload to a surface texture
+ if (!m_texture->uploadImageBuffer(layer.m_canvas->buffer())) {
+ // Blargh, no surface texture or ImageBuffer - fall back to software
+ m_bitmap = layer.bitmap();
+ SkSafeRef(m_bitmap);
+ // Merge the canvas invals with the layer's invals to repaint the needed
+ // tiles.
+ SkRegion::Iterator iter(layer.m_dirtyCanvas);
+ const IntPoint& offset = m_contentRect.location();
+ for (; !iter.done(); iter.next()) {
+ SkIRect diff = iter.rect();
+ diff.fLeft += offset.x();
+ diff.fRight += offset.x();
+ diff.fTop += offset.y();
+ diff.fBottom += offset.y();
+ m_dirtyRegion.op(diff, SkRegion::kUnion_Op);
+ }
+ }
+ if (previousState != m_texture->hasValidTexture()) {
+ // Need to do a full inval of the canvas content as we are mode switching
+ m_dirtyRegion.op(m_contentRect.x(), m_contentRect.y(),
+ m_contentRect.maxX(), m_contentRect.maxY(), SkRegion::kUnion_Op);
+ }
+ }
+}
+
+CanvasLayer::~CanvasLayer()
+{
+ if (m_canvas)
+ m_canvas->removeObserver(this);
+ SkSafeUnref(m_bitmap);
+}
+
+void CanvasLayer::init()
+{
+ m_texture = CanvasTexture::getCanvasTexture(this);
+}
+
+void CanvasLayer::canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect)
+{
+ if (!m_texture->hasValidTexture()) {
+ // We only need to track invals if we aren't using a SurfaceTexture.
+ // If we drop out of hwa, we will do a full inval anyway
+ SkIRect irect = SkIRect::MakeXYWH(changedRect.x(), changedRect.y(),
+ changedRect.width(), changedRect.height());
+ m_dirtyCanvas.op(irect, SkRegion::kUnion_Op);
+ }
+ owningLayer()->compositor()->scheduleLayerFlush();
+}
+
+void CanvasLayer::canvasResized(HTMLCanvasElement*)
+{
+ const IntSize& size = m_canvas->size();
+ m_dirtyCanvas.setRect(0, 0, size.width(), size.height());
+ // If we are smaller than one tile, don't bother using a surface texture
+ if (size.width() <= TilesManager::tileWidth()
+ && size.height() <= TilesManager::tileHeight())
+ m_texture->setSize(IntSize());
+ else
+ m_texture->setSize(size);
+}
+
+void CanvasLayer::canvasDestroyed(HTMLCanvasElement*)
+{
+ m_canvas = 0;
+}
+
+void CanvasLayer::clearDirtyRegion()
+{
+ LayerAndroid::clearDirtyRegion();
+ m_dirtyCanvas.setEmpty();
+ if (m_canvas)
+ m_canvas->clearDirtyRect();
+}
+
+SkBitmapRef* CanvasLayer::bitmap() const
+{
+ if (!m_canvas || !m_canvas->buffer())
+ return 0;
+ return m_canvas->copiedImage()->nativeImageForCurrentFrame();
+}
+
+IntRect CanvasLayer::contentRect() const
+{
+ if (!m_canvas
+ || !m_canvas->renderer()
+ || !m_canvas->renderer()->style()
+ || !m_canvas->inDocument()
+ || m_canvas->renderer()->style()->visibility() != VISIBLE)
+ return IntRect();
+ return m_canvas->renderBox()->contentBoxRect();
+}
+
+IntSize CanvasLayer::offsetFromRenderer() const
+{
+ return m_canvas->renderBox()->layer()->backing()->graphicsLayer()->offsetFromRenderer();
+}
+
+bool CanvasLayer::needsTexture()
+{
+ return m_bitmap || LayerAndroid::needsTexture();
+}
+
+void CanvasLayer::contentDraw(SkCanvas* canvas, PaintStyle style)
+{
+ LayerAndroid::contentDraw(canvas, style);
+ if (!m_bitmap)
+ return;
+ SkBitmap& bitmap = m_bitmap->bitmap();
+ SkRect dst = SkRect::MakeXYWH(m_contentRect.x() - m_offsetFromRenderer.width(),
+ m_contentRect.y() - m_offsetFromRenderer.height(),
+ m_contentRect.width(), m_contentRect.height());
+ canvas->drawBitmapRect(bitmap, 0, dst, 0);
+}
+
+bool CanvasLayer::drawGL(bool layerTilesDisabled)
+{
+ bool ret = LayerAndroid::drawGL(layerTilesDisabled);
+ m_texture->requireTexture();
+ if (!m_bitmap && m_texture->updateTexImage()) {
+ SkRect rect = SkRect::MakeXYWH(m_contentRect.x() - m_offsetFromRenderer.width(),
+ m_contentRect.y() - m_offsetFromRenderer.height(),
+ m_contentRect.width(), m_contentRect.height());
+ TextureQuadData data(m_texture->texture(), GL_TEXTURE_EXTERNAL_OES,
+ GL_LINEAR, LayerQuad, &m_drawTransform, &rect);
+ TilesManager::instance()->shader()->drawQuad(&data);
+ }
+ return ret;
+}
+
+LayerAndroid::InvalidateFlags CanvasLayer::onSetHwAccelerated(bool hwAccelerated)
+{
+ if (m_texture->setHwAccelerated(hwAccelerated))
+ return LayerAndroid::InvalidateLayers;
+ return LayerAndroid::InvalidateNone;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
new file mode 100644
index 0000000..532dbf2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasLayer_h
+#define CanvasLayer_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "HTMLCanvasElement.h"
+#include "ImageData.h"
+#include "LayerAndroid.h"
+#include "RenderLayer.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CanvasTexture;
+
+class CanvasLayer : public LayerAndroid, private CanvasObserver {
+public:
+ CanvasLayer(RenderLayer* owner, HTMLCanvasElement* canvas);
+ CanvasLayer(const CanvasLayer& layer);
+ virtual ~CanvasLayer();
+
+ virtual LayerAndroid* copy() const { return new CanvasLayer(*this); }
+ virtual SubclassType subclassType() { return LayerAndroid::CanvasLayer; }
+ virtual void clearDirtyRegion();
+
+ virtual bool drawGL(bool layerTilesDisabled);
+ virtual void contentDraw(SkCanvas* canvas, PaintStyle style);
+ virtual bool needsTexture();
+
+protected:
+ virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated);
+
+private:
+ virtual void canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect);
+ virtual void canvasResized(HTMLCanvasElement*);
+ virtual void canvasDestroyed(HTMLCanvasElement*);
+
+ void init();
+ SkBitmapRef* bitmap() const;
+ IntRect contentRect() const;
+ IntSize offsetFromRenderer() const;
+
+ HTMLCanvasElement* m_canvas;
+ IntRect m_contentRect;
+ IntSize m_offsetFromRenderer;
+ SkRegion m_dirtyCanvas;
+ SkBitmapRef* m_bitmap;
+ RefPtr<CanvasTexture> m_texture;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // CanvasLayer_h
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp b/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp
new file mode 100644
index 0000000..e4b2bc6
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "CanvasTexture"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "CanvasTexture.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "android_graphics.h"
+#include "AndroidLog.h"
+#include "GLUtils.h"
+#include "Image.h"
+#include "ImageBuffer.h"
+#include "SkBitmap.h"
+#include "SkBitmapRef.h"
+#include "SkDevice.h"
+#include "SkPixelRef.h"
+
+#include <android/native_window.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+
+namespace WebCore {
+
+static int s_maxTextureSize = 0;
+static HashMap<int, CanvasTexture*> s_textures;
+static android::Mutex s_texturesLock;
+
+/********************************************
+ * Called by both threads
+ ********************************************/
+
+PassRefPtr<CanvasTexture> CanvasTexture::getCanvasTexture(CanvasLayer* layer)
+{
+ android::Mutex::Autolock lock(s_texturesLock);
+ RefPtr<CanvasTexture> texture = s_textures.get(layer->uniqueId());
+ if (texture.get())
+ return texture.release();
+ return adoptRef(new CanvasTexture(layer->uniqueId()));
+}
+
+bool CanvasTexture::setHwAccelerated(bool hwAccelerated)
+{
+ android::Mutex::Autolock lock(m_surfaceLock);
+ if (m_useHwAcceleration == hwAccelerated)
+ return false;
+ m_useHwAcceleration = hwAccelerated;
+ if (!m_ANW.get())
+ return false;
+ destroySurfaceTextureLocked();
+ return true;
+}
+
+/********************************************
+ * Called by WebKit thread
+ ********************************************/
+
+void CanvasTexture::setSize(const IntSize& size)
+{
+ android::Mutex::Autolock lock(m_surfaceLock);
+ if (m_size == size)
+ return;
+ m_size = size;
+ if (m_ANW.get()) {
+ if (useSurfaceTexture()) {
+ int result = native_window_set_buffers_dimensions(m_ANW.get(),
+ m_size.width(), m_size.height());
+ GLUtils::checkSurfaceTextureError("native_window_set_buffers_dimensions", result);
+ if (result != NO_ERROR)
+ m_useHwAcceleration = false; // On error, drop out of HWA
+ }
+ if (!useSurfaceTexture())
+ destroySurfaceTextureLocked();
+ }
+}
+
+SurfaceTextureClient* CanvasTexture::nativeWindow()
+{
+ android::Mutex::Autolock lock(m_surfaceLock);
+ if (m_ANW.get())
+ return m_ANW.get();
+ if (!m_texture)
+ return 0;
+ if (!useSurfaceTexture())
+ return 0;
+ m_surfaceTexture = new android::SurfaceTexture(m_texture, false);
+ m_ANW = new android::SurfaceTextureClient(m_surfaceTexture);
+ int result = native_window_set_buffers_format(m_ANW.get(), HAL_PIXEL_FORMAT_RGBA_8888);
+ GLUtils::checkSurfaceTextureError("native_window_set_buffers_format", result);
+ if (result == NO_ERROR) {
+ result = native_window_set_buffers_dimensions(m_ANW.get(),
+ m_size.width(), m_size.height());
+ GLUtils::checkSurfaceTextureError("native_window_set_buffers_dimensions", result);
+ }
+ if (result != NO_ERROR) {
+ m_useHwAcceleration = false;
+ destroySurfaceTextureLocked();
+ return 0;
+ }
+ return m_ANW.get();
+}
+
+bool CanvasTexture::uploadImageBuffer(ImageBuffer* imageBuffer)
+{
+ m_hasValidTexture = false;
+ SurfaceTextureClient* anw = nativeWindow();
+ if (!anw)
+ return false;
+ // Size mismatch, early abort (will fall back to software)
+ if (imageBuffer->size() != m_size)
+ return false;
+ GraphicsContext* gc = imageBuffer ? imageBuffer->context() : 0;
+ if (!gc)
+ return false;
+ const SkBitmap& bitmap = android_gc2canvas(gc)->getDevice()->accessBitmap(false);
+ if (!GLUtils::updateSharedSurfaceTextureWithBitmap(anw, bitmap))
+ return false;
+ m_hasValidTexture = true;
+ return true;
+}
+
+/********************************************
+ * Called by UI thread WITH GL context
+ ********************************************/
+
+CanvasTexture::~CanvasTexture()
+{
+ if (m_layerId) {
+ s_texturesLock.lock();
+ s_textures.remove(m_layerId);
+ s_texturesLock.unlock();
+ }
+ if (m_texture)
+ GLUtils::deleteTexture(&m_texture);
+}
+
+void CanvasTexture::requireTexture()
+{
+ android::Mutex::Autolock lock(m_surfaceLock);
+ if (!m_texture)
+ glGenTextures(1, &m_texture);
+ if (!s_maxTextureSize)
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s_maxTextureSize);
+}
+
+bool CanvasTexture::updateTexImage()
+{
+ android::Mutex::Autolock lock(m_surfaceLock);
+ if (!m_surfaceTexture.get())
+ return false;
+ status_t result = m_surfaceTexture->updateTexImage();
+ if (result != OK) {
+ ALOGE("unexpected error: updateTexImage return %d", result);
+ return false;
+ }
+ return true;
+}
+
+/********************************************
+ * Called by both threads
+ ********************************************/
+
+void CanvasTexture::destroySurfaceTextureLocked()
+{
+ if (m_ANW.get()) {
+ m_ANW.clear();
+ m_surfaceTexture->abandon();
+ m_surfaceTexture.clear();
+ }
+}
+
+/********************************************
+ * Called by WebKit thread
+ ********************************************/
+
+CanvasTexture::CanvasTexture(int layerId)
+ : m_size()
+ , m_layerId(layerId)
+ , m_texture(0)
+ , m_surfaceTexture(0)
+ , m_ANW(0)
+ , m_hasValidTexture(false)
+ , m_useHwAcceleration(true)
+{
+ s_textures.add(m_layerId, this);
+}
+
+// TODO: Have a global limit as well as a way to react to low memory situations
+bool CanvasTexture::useSurfaceTexture()
+{
+ if (!m_useHwAcceleration)
+ return false;
+ if (m_size.isEmpty())
+ return false;
+ return (m_size.width() < s_maxTextureSize) && (m_size.height() < s_maxTextureSize);
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasTexture.h b/Source/WebCore/platform/graphics/android/layers/CanvasTexture.h
new file mode 100644
index 0000000..98962a0
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasTexture.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasTexture_h
+#define CanvasTexture_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "CanvasLayer.h"
+
+#include <wtf/RefPtr.h>
+#include <utils/threads.h>
+
+namespace android {
+class SurfaceTexture;
+class SurfaceTextureClient;
+}
+
+namespace WebCore {
+
+class CanvasTexture : public ThreadSafeRefCounted<CanvasTexture> {
+
+public:
+ /********************************************
+ * Called by both threads
+ ********************************************/
+ static PassRefPtr<CanvasTexture> getCanvasTexture(CanvasLayer* layer);
+ bool setHwAccelerated(bool hwAccelerated);
+
+ /********************************************
+ * Called by WebKit thread
+ ********************************************/
+ void setSize(const IntSize& size);
+ SurfaceTextureClient* nativeWindow();
+ bool uploadImageBuffer(ImageBuffer* imageBuffer);
+ bool hasValidTexture() { return m_hasValidTexture; }
+
+ /********************************************
+ * Called by UI thread WITH GL context
+ ********************************************/
+ virtual ~CanvasTexture();
+ void requireTexture();
+ GLuint texture() { requireTexture(); return m_texture; }
+ bool updateTexImage();
+
+private:
+ /********************************************
+ * Called by both threads
+ ********************************************/
+ void destroySurfaceTextureLocked();
+
+ /********************************************
+ * Called by WebKit thread
+ ********************************************/
+ CanvasTexture(int layerId);
+ bool useSurfaceTexture();
+
+ IntSize m_size;
+ int m_layerId;
+ GLuint m_texture;
+ android::Mutex m_surfaceLock;
+ sp<android::SurfaceTexture> m_surfaceTexture;
+ sp<android::SurfaceTextureClient> m_ANW;
+ bool m_hasValidTexture;
+ bool m_useHwAcceleration;
+
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // CanvasTexture_h
diff --git a/Source/WebCore/platform/graphics/android/DumpLayer.cpp b/Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp
index 5551965..5551965 100644
--- a/Source/WebCore/platform/graphics/android/DumpLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp
diff --git a/Source/WebCore/platform/graphics/android/DumpLayer.h b/Source/WebCore/platform/graphics/android/layers/DumpLayer.h
index 5b30952..5b30952 100644
--- a/Source/WebCore/platform/graphics/android/DumpLayer.h
+++ b/Source/WebCore/platform/graphics/android/layers/DumpLayer.h
diff --git a/Source/WebCore/platform/graphics/android/FixedPositioning.cpp b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp
index 989eebd..c7909c4 100644
--- a/Source/WebCore/platform/graphics/android/FixedPositioning.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp
@@ -8,6 +8,7 @@
#include "DumpLayer.h"
#include "IFrameLayerAndroid.h"
#include "TilesManager.h"
+#include "SkCanvas.h"
#if USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/FixedPositioning.h b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
index 973113b..973113b 100644
--- a/Source/WebCore/platform/graphics/android/FixedPositioning.h
+++ b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
diff --git a/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.cpp
index dadb13d..dadb13d 100644
--- a/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.cpp
diff --git a/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.h
index 64b2d06..64b2d06 100644
--- a/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.h
diff --git a/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp
index 3532542..3532542 100644
--- a/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp
diff --git a/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h
index e12188a..e12188a 100644
--- a/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h
diff --git a/Source/WebCore/platform/graphics/android/Layer.cpp b/Source/WebCore/platform/graphics/android/layers/Layer.cpp
index 7453a24..48e36fc 100644
--- a/Source/WebCore/platform/graphics/android/Layer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/Layer.cpp
@@ -1,5 +1,10 @@
+#define LOG_TAG "Layer"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "Layer.h"
+
+#include "AndroidLog.h"
#include "SkCanvas.h"
//#define DEBUG_DRAW_LAYER_BOUNDS
diff --git a/Source/WebCore/platform/graphics/android/Layer.h b/Source/WebCore/platform/graphics/android/layers/Layer.h
index e872278..d87c699 100644
--- a/Source/WebCore/platform/graphics/android/Layer.h
+++ b/Source/WebCore/platform/graphics/android/layers/Layer.h
@@ -120,7 +120,7 @@ public:
This does not include the childrenMatrix, since that is only applied
after this layer draws (but before its children draw).
*/
- void getLocalTransform(SkMatrix* matrix) const;
+ virtual void getLocalTransform(SkMatrix* matrix) const;
/** Return, in matrix, the concatenation of transforms that are applied
from this layer's root parent to the layer itself.
@@ -157,6 +157,9 @@ protected:
bool m_hasOverflowChildren;
+ // invalidation region
+ SkRegion m_dirtyRegion;
+private:
bool isAncestor(const Layer*) const;
Layer* fParent;
@@ -173,9 +176,6 @@ protected:
SkTDArray<Layer*> m_children;
- // invalidation region
- SkRegion m_dirtyRegion;
-
WebCore::GLWebViewState* m_state;
typedef SkRefCnt INHERITED;
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 946d2a3..a02759d 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -13,10 +13,10 @@
#include "DumpLayer.h"
#include "FixedPositioning.h"
#include "GLUtils.h"
+#include "GLWebViewState.h"
#include "ImagesManager.h"
#include "InspectorCanvas.h"
#include "LayerContent.h"
-#include "LayerGroup.h"
#include "MediaLayer.h"
#include "ParseCanvas.h"
#include "PictureLayerContent.h"
@@ -24,6 +24,7 @@
#include "SkDrawFilter.h"
#include "SkPaint.h"
#include "SkPicture.h"
+#include "Surface.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
@@ -33,8 +34,8 @@
#define DISABLE_LAYER_MERGE
#undef DISABLE_LAYER_MERGE
-#define LAYER_GROUPING_DEBUG
-#undef LAYER_GROUPING_DEBUG
+#define LAYER_MERGING_DEBUG
+#undef LAYER_MERGING_DEBUG
namespace WebCore {
@@ -54,6 +55,7 @@ private:
///////////////////////////////////////////////////////////////////////////////
LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
+ m_uniqueId(++gUniqueId),
m_haveClip(false),
m_backfaceVisibility(true),
m_visible(true),
@@ -62,7 +64,6 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
m_isPositionAbsolute(false),
m_fixedPosition(0),
m_zValue(0),
- m_uniqueId(++gUniqueId),
m_content(0),
m_imageCRC(0),
m_scale(1),
@@ -70,7 +71,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
m_owningLayer(owner),
m_type(LayerAndroid::WebCoreLayer),
m_intrinsicallyComposited(true),
- m_layerGroup(0)
+ m_surface(0)
{
m_backgroundColor = 0;
@@ -83,15 +84,15 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
}
LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
+ m_uniqueId(layer.m_uniqueId),
m_haveClip(layer.m_haveClip),
m_isPositionAbsolute(layer.m_isPositionAbsolute),
m_fixedPosition(0),
m_zValue(layer.m_zValue),
- m_uniqueId(layer.m_uniqueId),
m_owningLayer(layer.m_owningLayer),
m_type(LayerAndroid::UILayer),
m_intrinsicallyComposited(layer.m_intrinsicallyComposited),
- m_layerGroup(0)
+ m_surface(0)
{
m_imageCRC = layer.m_imageCRC;
if (m_imageCRC)
@@ -169,28 +170,6 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
#endif
}
-LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
- m_haveClip(false),
- m_fixedPosition(0),
- m_zValue(0),
- m_uniqueId(++gUniqueId),
- m_imageCRC(0),
- m_scale(1),
- m_lastComputeTextureSize(0),
- m_owningLayer(0),
- m_type(LayerAndroid::NavCacheLayer),
- m_intrinsicallyComposited(true),
- m_layerGroup(0)
-{
- m_backgroundColor = 0;
- m_content = new PictureLayerContent(picture);
- m_dirtyRegion.setEmpty();
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("LayerAndroid - from picture");
- ClassTracker::instance()->add(this);
-#endif
-}
-
LayerAndroid::~LayerAndroid()
{
if (m_imageCRC)
@@ -199,7 +178,7 @@ LayerAndroid::~LayerAndroid()
delete m_fixedPosition;
SkSafeUnref(m_content);
- // Don't unref m_layerGroup, owned by BaseLayerAndroid
+ // Don't unref m_surface, owned by BaseLayerAndroid
m_animations.clear();
#ifdef DEBUG_COUNT
ClassTracker::instance()->remove(this);
@@ -207,8 +186,6 @@ LayerAndroid::~LayerAndroid()
ClassTracker::instance()->decrement("LayerAndroid");
else if (m_type == LayerAndroid::UILayer)
ClassTracker::instance()->decrement("LayerAndroid - recopy (UI)");
- else if (m_type == LayerAndroid::NavCacheLayer)
- ClassTracker::instance()->decrement("LayerAndroid - from picture");
#endif
}
@@ -277,7 +254,7 @@ void LayerAndroid::addDirtyArea()
area.intersect(clip);
IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());
- m_state->addDirtyArea(dirtyArea);
+ state()->addDirtyArea(dirtyArea);
}
void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim)
@@ -434,7 +411,6 @@ void LayerAndroid::updatePositions()
void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
const FloatRect& clipping, float opacity, float scale)
{
- m_atomicSync.lock();
IntSize layerSize(getSize().width(), getSize().height());
FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY);
FloatPoint position(getPosition().fX - m_offset.x(), getPosition().fY - m_offset.y());
@@ -451,7 +427,6 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
-originY,
-anchorPointZ());
- m_atomicSync.unlock();
setDrawTransform(localMatrix);
if (m_drawTransform.isIdentityOrTranslation()) {
// adjust the translation coordinates of the draw transform matrix so
@@ -483,6 +458,9 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
} else {
setDrawClip(clipping);
}
+ ALOGV("%s - %d %f %f %f %f",
+ subclassType() == BaseLayer ? "BASE" : "nonbase",
+ m_haveClip, m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height());
if (!m_backfaceVisibility
&& m_drawTransform.inverse().m33() < 0) {
@@ -630,65 +608,21 @@ void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree)
replacementLayer->markAsDirty(m_dirtyRegion);
}
-bool LayerAndroid::updateWithTree(LayerAndroid* newTree)
-{
-// Disable fast update for now
-#if (0)
- bool needsRepaint = false;
- int count = this->countChildren();
- for (int i = 0; i < count; i++)
- needsRepaint |= this->getChild(i)->updateWithTree(newTree);
-
- if (newTree) {
- LayerAndroid* newLayer = newTree->findById(uniqueId());
- needsRepaint |= updateWithLayer(newLayer);
- }
- return needsRepaint;
-#else
- return true;
-#endif
-}
-
-// Return true to indicate to WebViewCore that the updates
-// are too complicated to be fully handled and we need a full
-// call to webkit (e.g. handle repaints)
-bool LayerAndroid::updateWithLayer(LayerAndroid* layer)
-{
- if (!layer)
- return true;
-
- android::AutoMutex lock(m_atomicSync);
- m_position = layer->m_position;
- m_anchorPoint = layer->m_anchorPoint;
- m_size = layer->m_size;
- m_opacity = layer->m_opacity;
- m_transform = layer->m_transform;
-
- if (m_imageCRC != layer->m_imageCRC)
- m_visible = false;
-
- if ((m_content != layer->m_content)
- || (m_imageCRC != layer->m_imageCRC))
- return true;
-
- return false;
-}
-
static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
{
return a->zValue() > b->zValue();
}
-bool LayerAndroid::canJoinGroup(LayerGroup* group)
+bool LayerAndroid::canJoinSurface(Surface* surface)
{
-#if DISABLE_LAYER_MERGE
+#ifdef DISABLE_LAYER_MERGE
return false;
#else
- // returns true if the layer can be merged onto the layergroup
- if (!group)
+ // returns true if the layer can be merged onto the surface (group of layers)
+ if (!surface)
return false;
- LayerAndroid* lastLayer = group->getFirstLayer();
+ LayerAndroid* lastLayer = surface->getFirstLayer();
// isolate non-tiled layers
// TODO: remove this check so that multiple tiled layers with a invisible
@@ -710,9 +644,9 @@ bool LayerAndroid::canJoinGroup(LayerGroup* group)
|| !lastLayer->m_drawTransform.isIdentityOrTranslation())
return false;
- // currently, we don't group zoomable with non-zoomable layers (unless the
- // group or the layer doesn't need a texture)
- if (group->needsTexture() && needsTexture() && m_content->hasText() != group->hasText())
+ // currently, we don't surface zoomable with non-zoomable layers (unless the
+ // surface or the layer doesn't need a texture)
+ if (surface->needsTexture() && needsTexture() && m_content->hasText() != surface->hasText())
return false;
// TODO: compare other layer properties - fixed? overscroll? transformed?
@@ -720,31 +654,31 @@ bool LayerAndroid::canJoinGroup(LayerGroup* group)
#endif
}
-void LayerAndroid::assignGroups(LayerMergeState* mergeState)
+void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
{
// recurse through layers in draw order, and merge layers when able
- bool needNewGroup = !mergeState->currentLayerGroup
+ bool needNewSurface = !mergeState->currentSurface
|| mergeState->nonMergeNestedLevel > 0
- || !canJoinGroup(mergeState->currentLayerGroup);
+ || !canJoinSurface(mergeState->currentSurface);
- if (needNewGroup) {
- mergeState->currentLayerGroup = new LayerGroup();
- mergeState->groupList->append(mergeState->currentLayerGroup);
+ if (needNewSurface) {
+ mergeState->currentSurface = new Surface();
+ mergeState->surfaceList->append(mergeState->currentSurface);
}
-#ifdef LAYER_GROUPING_DEBUG
- ALOGD("%*slayer %p(%d) rl %p %s group %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d",
+#ifdef LAYER_MERGING_DEBUG
+ ALOGD("%*slayer %p(%d) rl %p %s surface %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d",
4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
- needNewGroup ? "NEW" : "joins", mergeState->currentLayerGroup,
+ needNewSurface ? "NEW" : "joins", mergeState->currentSurface,
isPositionFixed(), m_animations.size() != 0,
m_intrinsicallyComposited,
m_haveClip,
contentIsScrollable());
#endif
- mergeState->currentLayerGroup->addLayer(this, m_drawTransform);
- m_layerGroup = mergeState->currentLayerGroup;
+ mergeState->currentSurface->addLayer(this, m_drawTransform);
+ m_surface = mergeState->currentSurface;
if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
// disable layer merging within the children of these layer types
@@ -752,7 +686,7 @@ void LayerAndroid::assignGroups(LayerMergeState* mergeState)
}
- // pass the layergroup through children in drawing order, so that they may
+ // pass the surface through children in drawing order, so that they may
// attach themselves (and paint on it) if possible, or ignore it and create
// a new one if not
int count = this->countChildren();
@@ -765,7 +699,7 @@ void LayerAndroid::assignGroups(LayerMergeState* mergeState)
// sort for the transparency
std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
for (int i = 0; i < count; i++)
- sublayers[i]->assignGroups(mergeState);
+ sublayers[i]->assignSurfaces(mergeState);
mergeState->depth--;
}
@@ -773,8 +707,8 @@ void LayerAndroid::assignGroups(LayerMergeState* mergeState)
// re-enable joining
mergeState->nonMergeNestedLevel--;
- // disallow layers painting after to join with this group
- mergeState->currentLayerGroup = 0;
+ // disallow layers painting after to join with this surface
+ mergeState->currentSurface = 0;
}
}
@@ -791,6 +725,16 @@ void LayerAndroid::clearDirtyRegion()
m_dirtyRegion.setEmpty();
}
+int LayerAndroid::setHwAccelerated(bool hwAccelerated)
+{
+ int flags = InvalidateNone;
+ int count = this->countChildren();
+ for (int i = 0; i < count; i++)
+ flags |= this->getChild(i)->setHwAccelerated(hwAccelerated);
+
+ return flags | onSetHwAccelerated(hwAccelerated);
+}
+
IntRect LayerAndroid::unclippedArea()
{
IntRect area;
@@ -867,7 +811,7 @@ bool LayerAndroid::drawGL(bool layerTilesDisabled)
ImagesManager::instance()->releaseImage(m_imageCRC);
}
- m_state->glExtras()->drawGL(this);
+ state()->glExtras()->drawGL(this);
bool askScreenUpdate = false;
m_atomicSync.lock();
@@ -920,10 +864,10 @@ void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style)
canvas->drawLine(0, 0, w, h, paint);
canvas->drawLine(0, h, w, 0, paint);
- canvas->drawLine(0, 0, 0, h, paint);
- canvas->drawLine(0, h, w, h, paint);
- canvas->drawLine(w, h, w, 0, paint);
- canvas->drawLine(w, 0, 0, 0, paint);
+ canvas->drawLine(0, 0, 0, h-1, paint);
+ canvas->drawLine(0, h-1, w-1, h-1, paint);
+ canvas->drawLine(w-1, h-1, w-1, 0, paint);
+ canvas->drawLine(w-1, 0, 0, 0, paint);
}
if (m_fixedPosition)
@@ -940,7 +884,8 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity,
return;
}
- if (masksToBounds() || !m_content)
+ // only continue drawing if layer is drawable
+ if (!m_content && !m_imageCRC)
return;
// we just have this save/restore for opacity...
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 7436676..9a803a9 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -25,6 +25,7 @@
#include "GraphicsLayerClient.h"
#include "ImageTexture.h"
#include "Layer.h"
+#include "PlatformString.h"
#include "RefPtr.h"
#include "SkBitmap.h"
#include "SkColor.h"
@@ -32,6 +33,7 @@
#include "SkStream.h"
#include "TransformationMatrix.h"
+#include <utils/threads.h>
#include <wtf/HashMap.h>
#ifndef BZERO_DEFINED
@@ -49,8 +51,8 @@ class SkPicture;
namespace WebCore {
class LayerAndroid;
class LayerContent;
-class LayerGroup;
class ImageTexture;
+class Surface;
}
namespace android {
@@ -65,13 +67,11 @@ using namespace android;
namespace WebCore {
class AndroidAnimation;
-class BaseTileTexture;
class FixedPositioning;
class GLWebViewState;
class IFrameLayerAndroid;
class LayerMergeState;
class RenderLayer;
-class TiledPage;
class PaintedSurface;
class TexturesResult {
@@ -91,9 +91,11 @@ public:
class TEST_EXPORT LayerAndroid : public Layer {
public:
- typedef enum { UndefinedLayer, WebCoreLayer, UILayer, NavCacheLayer } LayerType;
+ typedef enum { UndefinedLayer, WebCoreLayer, UILayer } LayerType;
typedef enum { StandardLayer, ScrollableLayer,
- IFrameLayer, IFrameContentLayer } SubclassType;
+ IFrameLayer, IFrameContentLayer,
+ CanvasLayer, BaseLayer } SubclassType;
+ typedef enum { InvalidateNone = 0, InvalidateLayers } InvalidateFlags;
String subclassName()
{
@@ -106,17 +108,18 @@ public:
return "IFrameLayer";
case LayerAndroid::IFrameContentLayer:
return "IFrameContentLayer";
+ case LayerAndroid::CanvasLayer:
+ return "CanvasLayer";
+ case LayerAndroid::BaseLayer:
+ return "BaseLayer";
}
return "Undefined";
}
LayerAndroid(RenderLayer* owner);
LayerAndroid(const LayerAndroid& layer);
- LayerAndroid(SkPicture*);
virtual ~LayerAndroid();
- virtual TiledPage* page() { return 0; }
-
void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; }
void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
FloatPoint translation() const;
@@ -156,7 +159,7 @@ public:
void setAnchorPointZ(float z) { m_anchorPointZ = z; }
float anchorPointZ() { return m_anchorPointZ; }
void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
- const TransformationMatrix* drawTransform() const { return &m_drawTransform; }
+ virtual const TransformationMatrix* drawTransform() const { return &m_drawTransform; }
void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; }
const FloatRect& drawClip() { return m_clippingRect; }
@@ -230,7 +233,7 @@ public:
virtual LayerAndroid* copy() const { return new LayerAndroid(*this); }
- void clearDirtyRegion();
+ virtual void clearDirtyRegion();
virtual void contentDraw(SkCanvas* canvas, PaintStyle style);
@@ -254,12 +257,6 @@ public:
friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
friend void android::cleanupImageRefs(LayerAndroid* layer);
- // Update layers using another tree. Only works for basic properties
- // such as the position, the transform. Return true if anything more
- // complex is needed.
- bool updateWithTree(LayerAndroid*);
- virtual bool updateWithLayer(LayerAndroid*);
-
LayerType type() { return m_type; }
virtual SubclassType subclassType() { return LayerAndroid::StandardLayer; }
@@ -271,16 +268,20 @@ public:
SkRegion* getInvalRegion() { return &m_dirtyRegion; }
void mergeInvalsInto(LayerAndroid* replacementTree);
- bool canJoinGroup(LayerGroup* group);
- void assignGroups(LayerMergeState* mergeState);
- LayerGroup* group() { return m_layerGroup; }
+ bool canJoinSurface(Surface* surface);
+ void assignSurfaces(LayerMergeState* mergeState);
+ Surface* surface() { return m_surface; }
void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; }
+ int setHwAccelerated(bool hwAccelerated);
+
protected:
virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style);
+ virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated) { return InvalidateNone; }
IntPoint m_offset;
TransformationMatrix m_drawTransform;
+ int m_uniqueId;
private:
#if DUMP_NAV_CACHE
@@ -324,8 +325,6 @@ private:
FloatRect m_clippingRect;
- int m_uniqueId;
-
// Note that m_content and m_imageCRC are mutually exclusive;
// m_content is used when WebKit is asked to paint the layer's
// content, while m_imageCRC references an image that we directly
@@ -356,7 +355,7 @@ private:
bool m_intrinsicallyComposited;
- LayerGroup* m_layerGroup;
+ Surface* m_surface;
typedef Layer INHERITED;
};
diff --git a/Source/WebCore/platform/graphics/android/LayerContent.h b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
index 32108ec..97bc32a 100644
--- a/Source/WebCore/platform/graphics/android/LayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
@@ -27,6 +27,7 @@
#define LayerContent_h
#include "SkRefCnt.h"
+#include <utils/threads.h>
class SkCanvas;
class SkPicture;
@@ -44,6 +45,10 @@ public:
virtual void draw(SkCanvas* canvas) = 0;
virtual void serialize(SkWStream* stream) = 0;
+
+protected:
+ // used to prevent parallel draws, as both SkPicture and PictureSet don't support them
+ android::Mutex m_drawLock;
};
} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp
index de1db17..6227ea4 100644
--- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp
@@ -28,9 +28,9 @@
namespace WebCore {
-MediaLayer::MediaLayer(jobject webViewRef) : LayerAndroid((RenderLayer*) NULL)
+MediaLayer::MediaLayer(jobject webViewRef, jobject webViewCoreRef) : LayerAndroid((RenderLayer*) NULL)
{
- m_mediaTexture = new MediaTexture(webViewRef);
+ m_mediaTexture = new MediaTexture(webViewRef, webViewCoreRef);
m_mediaTexture->incStrong(this);
m_isCopy = false;
diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.h b/Source/WebCore/platform/graphics/android/layers/MediaLayer.h
index 907c53c..2f39d74 100644
--- a/Source/WebCore/platform/graphics/android/MediaLayer.h
+++ b/Source/WebCore/platform/graphics/android/layers/MediaLayer.h
@@ -32,7 +32,7 @@ namespace WebCore {
class MediaLayer : public LayerAndroid {
public:
- MediaLayer(jobject webViewRef);
+ MediaLayer(jobject webViewRef, jobject webViewCoreRef);
MediaLayer(const MediaLayer& layer);
virtual ~MediaLayer();
diff --git a/Source/WebCore/platform/graphics/android/MediaListener.h b/Source/WebCore/platform/graphics/android/layers/MediaListener.h
index 2dfc08b..2dfc08b 100644
--- a/Source/WebCore/platform/graphics/android/MediaListener.h
+++ b/Source/WebCore/platform/graphics/android/layers/MediaListener.h
diff --git a/Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h
index 535e7ae..535e7ae 100644
--- a/Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h
diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.cpp b/Source/WebCore/platform/graphics/android/layers/MediaTexture.cpp
index 789ca03..dffe6c2 100644
--- a/Source/WebCore/platform/graphics/android/MediaTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/MediaTexture.cpp
@@ -21,6 +21,7 @@
#include "MediaTexture.h"
#include "AndroidLog.h"
+#include "DrawQuadData.h"
#include "TilesManager.h"
#include "GLUtils.h"
#include "MediaListener.h"
@@ -41,14 +42,11 @@
namespace WebCore {
-MediaTexture::MediaTexture(jobject webViewRef) : android::LightRefBase<MediaTexture>()
+MediaTexture::MediaTexture(jobject webViewRef, jobject webViewCoreRef) : android::LightRefBase<MediaTexture>()
{
- if (webViewRef) {
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- m_weakWebViewRef = env->NewWeakGlobalRef(webViewRef);
- } else {
- m_weakWebViewRef = 0;
- }
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ m_weakWebViewRef = env->NewWeakGlobalRef(webViewRef);
+ m_weakWebViewCoreRef = env->NewWeakGlobalRef(webViewCoreRef);
m_contentTexture = 0;
m_isContentInverted = false;
@@ -63,10 +61,9 @@ MediaTexture::~MediaTexture()
deleteTexture(m_videoTextures[i], true);
}
- if (m_weakWebViewRef) {
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->DeleteWeakGlobalRef(m_weakWebViewRef);
- }
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->DeleteWeakGlobalRef(m_weakWebViewRef);
+ env->DeleteWeakGlobalRef(m_weakWebViewCoreRef);
}
bool MediaTexture::isContentInverted()
@@ -98,16 +95,16 @@ void MediaTexture::initNativeWindowIfNeeded()
m_contentTexture = createTexture();
// send a message to the WebKit thread to notify the plugin that it can draw
- if (m_weakWebViewRef) {
+ if (m_weakWebViewCoreRef) {
JNIEnv* env = JSC::Bindings::getJNIEnv();
- jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef);
- if (localWebViewRef) {
- jclass wvClass = env->GetObjectClass(localWebViewRef);
+ jobject localWebViewCoreRef = env->NewLocalRef(m_weakWebViewCoreRef);
+ if (localWebViewCoreRef) {
+ jclass wvClass = env->GetObjectClass(localWebViewCoreRef);
jmethodID sendPluginDrawMsg =
env->GetMethodID(wvClass, "sendPluginDrawMsg", "()V");
- env->CallVoidMethod(localWebViewRef, sendPluginDrawMsg);
+ env->CallVoidMethod(localWebViewCoreRef, sendPluginDrawMsg);
env->DeleteLocalRef(wvClass);
- env->DeleteLocalRef(localWebViewRef);
+ env->DeleteLocalRef(localWebViewCoreRef);
}
checkException(env);
}
@@ -180,11 +177,10 @@ void MediaTexture::draw(const TransformationMatrix& contentMatrix,
PIXEL_FORMAT_RGB_888 == f ||
PIXEL_FORMAT_RGB_565 == f);
- TilesManager::instance()->shader()->drawLayerQuad(contentMatrix,
- mediaBounds,
- m_contentTexture->textureId,
- 1.0f, forceAlphaBlending,
- GL_TEXTURE_EXTERNAL_OES);
+ TextureQuadData data(m_contentTexture->textureId, GL_TEXTURE_EXTERNAL_OES,
+ GL_LINEAR, LayerQuad, &contentMatrix, &mediaBounds,
+ 1.0f, forceAlphaBlending);
+ TilesManager::instance()->shader()->drawQuad(&data);
}
ANativeWindow* MediaTexture::requestNativeWindowForVideo()
diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.h b/Source/WebCore/platform/graphics/android/layers/MediaTexture.h
index 97bb530..9ea7be2 100644
--- a/Source/WebCore/platform/graphics/android/MediaTexture.h
+++ b/Source/WebCore/platform/graphics/android/layers/MediaTexture.h
@@ -40,7 +40,7 @@ class MediaListener;
class MediaTexture : public android::LightRefBase<MediaTexture> {
public:
- MediaTexture(jobject webViewRef);
+ MediaTexture(jobject webViewRef, jobject webViewCoreRef);
~MediaTexture();
bool isContentInverted();
@@ -83,6 +83,7 @@ private:
sp<ANativeWindow> m_newWindow;
jobject m_weakWebViewRef;
+ jobject m_weakWebViewCoreRef;
android::Mutex m_mediaLock;
android::Condition m_newMediaRequestCond;
diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
index cf2e569..4398146 100644
--- a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
@@ -90,6 +90,9 @@ void PictureLayerContent::draw(SkCanvas* canvas)
if (!m_picture)
return;
+ android::Mutex::Autolock lock(m_drawLock);
+ SkRect r = SkRect::MakeWH(width(), height());
+ canvas->clipRect(r);
canvas->drawPicture(*m_picture);
}
diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
index 94bdfac..94bdfac 100644
--- a/Source/WebCore/platform/graphics/android/PictureLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp
index bc024eb..8b72b0a 100644
--- a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp
@@ -1,6 +1,7 @@
#include "config.h"
#include "PictureSetLayerContent.h"
+#include "SkCanvas.h"
#include "SkPicture.h"
namespace WebCore {
@@ -17,8 +18,13 @@ PictureSetLayerContent::~PictureSetLayerContent()
void PictureSetLayerContent::draw(SkCanvas* canvas)
{
- if (!m_pictureSet.isEmpty())
- m_pictureSet.draw(canvas);
+ if (m_pictureSet.isEmpty())
+ return;
+
+ android::Mutex::Autolock lock(m_drawLock);
+ SkRect r = SkRect::MakeWH(width(), height());
+ canvas->clipRect(r);
+ m_pictureSet.draw(canvas);
}
void PictureSetLayerContent::serialize(SkWStream* stream)
diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h
index 61fc3f4..61fc3f4 100644
--- a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.cpp
index f28c31d..f28c31d 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.cpp
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h
index 1f289e6..52f5e7e 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h
@@ -43,8 +43,6 @@ public:
virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); }
virtual SubclassType subclassType() { return LayerAndroid::ScrollableLayer; }
- virtual bool updateWithLayer(LayerAndroid*) { return true; }
-
// Scrolls to the given position in the layer.
// Returns whether or not any scrolling was required.
virtual bool scrollTo(int x, int y);
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.cpp
index 756bf28..39bbec6 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.cpp
@@ -30,6 +30,8 @@
#include "VideoLayerAndroid.h"
#include "AndroidLog.h"
+#include "DrawQuadData.h"
+#include "ShaderProgram.h"
#include "TilesManager.h"
#include <GLES2/gl2.h>
#include <gui/SurfaceTexture.h>
@@ -74,8 +76,9 @@ void VideoLayerAndroid::showPreparingAnimation(const SkRect& rect,
ShaderProgram* shader = TilesManager::instance()->shader();
VideoLayerManager* manager = TilesManager::instance()->videoLayerManager();
// Paint the video content's background.
- shader->drawLayerQuad(m_drawTransform, rect, 0, 1, true, GL_TEXTURE_2D,
- Color(128, 128, 128, 255));
+ PureColorQuadData backGroundQuadData(Color(128, 128, 128, 255), LayerQuad,
+ &m_drawTransform, &rect);
+ shader->drawQuad(&backGroundQuadData);
TransformationMatrix addReverseRotation;
TransformationMatrix addRotation = m_drawTransform;
@@ -87,14 +90,18 @@ void VideoLayerAndroid::showPreparingAnimation(const SkRect& rect,
addRotation.translate(-halfButtonSize, -halfButtonSize);
SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height());
- shader->drawLayerQuad(addRotation, size,
- manager->getSpinnerOuterTextureId(), 1, true);
+
+ TextureQuadData spinnerQuadData(manager->getSpinnerOuterTextureId(),
+ GL_TEXTURE_2D, GL_LINEAR,
+ LayerQuad, &addRotation, &size);
+ shader->drawQuad(&spinnerQuadData);
addReverseRotation.rotate(-m_rotateDegree);
addReverseRotation.translate(-halfButtonSize, -halfButtonSize);
- shader->drawLayerQuad(addReverseRotation, size,
- manager->getSpinnerInnerTextureId(), 1, true);
+ spinnerQuadData.updateTextureId(manager->getSpinnerInnerTextureId());
+ spinnerQuadData.updateDrawMatrix(&addReverseRotation);
+ shader->drawQuad(&spinnerQuadData);
m_rotateDegree += ROTATESTEP;
}
@@ -129,11 +136,13 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
// Calculate the video rect based on the aspect ratio and the element rect.
SkRect videoRect = calVideoRect(rect);
+ PureColorQuadData pureColorQuadData(Color(0, 0, 0, 255), LayerQuad,
+ &m_drawTransform, &rect);
+
if (videoRect != rect) {
// Paint the whole video element with black color when video content
// can't cover the whole area.
- shader->drawLayerQuad(m_drawTransform, rect, 0, 1, true, GL_TEXTURE_2D,
- Color(0, 0, 0, 255));
+ shader->drawQuad(&pureColorQuadData);
}
// Inner rect is for the progressing / play / pause animation.
@@ -148,7 +157,8 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
// When we are drawing the animation of the play/pause button in the
// middle of the video, we need to ask for redraw.
bool needRedraw = false;
-
+ TextureQuadData iconQuadData(0, GL_TEXTURE_2D, GL_LINEAR, LayerQuad,
+ &m_drawTransform, &innerRect);
// Draw the poster image, the progressing image or the Video depending
// on the player's state.
if (m_playerState == PREPARING) {
@@ -169,11 +179,11 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
if (scale) {
innerRect.inset(manager->getButtonSize() / 4 * scale,
manager->getButtonSize() / 4 * scale);
- shader->drawLayerQuad(m_drawTransform, innerRect,
- manager->getPlayTextureId(), scale, true);
+ iconQuadData.updateTextureId(manager->getPlayTextureId());
+ iconQuadData.updateOpacity(scale);
+ shader->drawQuad(&iconQuadData);
needRedraw = true;
}
-
} else {
GLuint textureId = manager->getTextureId(uniqueId());
GLfloat* matrix = manager->getMatrix(uniqueId());
@@ -183,10 +193,12 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
videoRect, textureId);
} else {
// Show the static poster b/c there is no screen shot available.
- shader->drawLayerQuad(m_drawTransform, rect, 0, 1, true, GL_TEXTURE_2D,
- Color(128, 128, 128, 255));
- shader->drawLayerQuad(m_drawTransform, innerRect,
- manager->getPosterTextureId(), 1, true);
+ pureColorQuadData.updateColor(Color(128, 128, 128, 255));
+ shader->drawQuad(&pureColorQuadData);
+
+ iconQuadData.updateTextureId(manager->getPosterTextureId());
+ iconQuadData.updateOpacity(1.0);
+ shader->drawQuad(&iconQuadData);
}
// Use the scale to control the fading and the sizing during animation.
@@ -194,8 +206,9 @@ bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
if (scale) {
innerRect.inset(manager->getButtonSize() / 4 * scale,
manager->getButtonSize() / 4 * scale);
- shader->drawLayerQuad(m_drawTransform, innerRect,
- manager->getPauseTextureId(), scale, true);
+ iconQuadData.updateTextureId(manager->getPauseTextureId());
+ iconQuadData.updateOpacity(scale);
+ shader->drawQuad(&iconQuadData);
needRedraw = true;
}
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h
index 29b1bdc..dd88a85 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h
@@ -30,7 +30,6 @@
#include "GLUtils.h"
#include "LayerAndroid.h"
-#include "ShaderProgram.h"
#include <jni.h>
namespace android {
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp
index 6501f98..6501f98 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
index c8e420e..6c02534 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
@@ -30,6 +30,7 @@
#include "IntRect.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
+#include <utils/threads.h>
#if USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
index 6dd16e1..8bb1755 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
@@ -40,12 +40,14 @@
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPicture.h"
+#include "SkTypeface.h"
+#include "Tile.h"
#include "TilesManager.h"
#include <wtf/text/CString.h>
#define UPDATE_COUNT_MASK 0xFF // displayed count wraps at 256
-#define UPDATE_COUNT_ALPHA_MASK 0x3F // alpha wraps at 64
+#define UPDATE_COUNT_ALPHA_MASK 0x1F // alpha wraps at 32
namespace WebCore {
@@ -70,40 +72,24 @@ void BaseRenderer::swapRendererIfNeeded(BaseRenderer*& renderer)
}
void BaseRenderer::drawTileInfo(SkCanvas* canvas,
- const TileRenderInfo& renderInfo, int updateCount)
+ const TileRenderInfo& renderInfo, int updateCount, double renderDuration)
{
+ static SkTypeface* s_typeface = 0;
+ if (!s_typeface)
+ s_typeface = SkTypeface::CreateFromName("", SkTypeface::kBold);
SkPaint paint;
+ paint.setTextSize(17);
char str[256];
- snprintf(str, 256, "(%d,%d) %.2f, tl%x p%x c%d", renderInfo.x, renderInfo.y,
- renderInfo.scale, this, renderInfo.tilePainter, updateCount);
- paint.setARGB(255, 0, 0, 0);
- canvas->drawText(str, strlen(str), 0, 10, paint);
+ snprintf(str, 256, " (%d,%d) %.2fx %d %.1fms", renderInfo.x, renderInfo.y,
+ renderInfo.scale, updateCount, renderDuration);
+ paint.setARGB(128, 255, 255, 255);
+ canvas->drawRectCoords(0, 0, renderInfo.tileSize.fWidth, 17, paint);
paint.setARGB(255, 255, 0, 0);
- canvas->drawText(str, strlen(str), 0, 11, paint);
-
- int tagCount = 0;
- const String* tags = getPerformanceTags(tagCount);
-
- float total = 0;
- for (int i = 0; i < tagCount; i++) {
- float tagDuration = m_perfMon.getAverageDuration(tags[i]);
- total += tagDuration;
- snprintf(str, 256, "%s: %.2f", tags[i].utf8().data(), tagDuration);
- paint.setARGB(255, 0, 0, 0);
- int textY = (i * 12) + 25;
- canvas->drawText(str, strlen(str), 0, textY, paint);
- paint.setARGB(255, 255, 0, 0);
- canvas->drawText(str, strlen(str), 0, textY + 1, paint);
- }
- snprintf(str, 256, "total: %.2f", total);
- paint.setARGB(255, 0, 0, 0);
- int textY = (tagCount * 12) + 30;
- canvas->drawText(str, strlen(str), 0, textY, paint);
- paint.setARGB(255, 255, 0, 0);
- canvas->drawText(str, strlen(str), 0, textY + 1, paint);
+ paint.setTypeface(s_typeface);
+ canvas->drawText(str, strlen(str), 20, 15, paint);
}
-void BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
+void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
{
const bool visualIndicator = TilesManager::instance()->getShowVisualIndicator();
const SkSize& tileSize = renderInfo.tileSize;
@@ -117,41 +103,38 @@ void BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
return;
}
- if (visualIndicator)
+ double before;
+ if (visualIndicator) {
canvas.save();
+ before = currentTimeMS();
+ }
setupPartialInval(renderInfo, &canvas);
canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height());
canvas.scale(renderInfo.scale, renderInfo.scale);
- renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas);
+ renderInfo.tilePainter->paint(&canvas);
+ if (renderInfo.baseTile && renderInfo.baseTile->backTexture())
+ checkForPureColor(renderInfo, &canvas);
+ else
+ renderInfo.isPureColor = false;
if (visualIndicator) {
+ double after = currentTimeMS();
canvas.restore();
unsigned int updateCount = renderInfo.tilePainter->getUpdateCount() & UPDATE_COUNT_MASK;
const int color = updateCount & UPDATE_COUNT_ALPHA_MASK;
// only color the invalidated area
- SkPaint invalPaint;
- invalPaint.setARGB(color, 0, 255, 0);
+ SkPaint paint;
+ paint.setARGB(color, 0, 255, 0);
if (renderInfo.invalRect)
- canvas.drawIRect(*renderInfo.invalRect, invalPaint);
+ canvas.drawIRect(*renderInfo.invalRect, paint);
else {
SkIRect rect;
rect.set(0, 0, tileSize.width(), tileSize.height());
- canvas.drawIRect(rect, invalPaint);
+ canvas.drawIRect(rect, paint);
}
- // paint the tile boundaries
- SkPaint paint;
- paint.setARGB(128, 255, 0, 0);
- paint.setStrokeWidth(3);
- canvas.drawLine(0, 0, tileSize.width(), tileSize.height(), paint);
- paint.setARGB(128, 0, 255, 0);
- canvas.drawLine(0, tileSize.height(), tileSize.width(), 0, paint);
- paint.setARGB(128, 0, 0, 255);
- canvas.drawLine(0, 0, tileSize.width(), 0, paint);
- canvas.drawLine(tileSize.width(), 0, tileSize.width(), tileSize.height(), paint);
-
if (renderInfo.invalRect) {
// if partial inval...
int x = renderInfo.invalRect->fLeft;
@@ -163,9 +146,16 @@ void BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
canvas.drawLine(x, y, x + w, y + h, paint);
canvas.drawLine(x, y + h, x + w, y, paint);
}
+ drawTileInfo(&canvas, renderInfo, updateCount, after - before);
- if (renderInfo.measurePerf)
- drawTileInfo(&canvas, renderInfo, updateCount);
+ // paint the tile boundaries
+ paint.setARGB(64, 255, 0, 0);
+ paint.setStrokeWidth(3);
+ canvas.drawLine(0, 0, tileSize.width(), tileSize.height(), paint);
+ paint.setARGB(64, 0, 255, 0);
+ canvas.drawLine(0, tileSize.height(), tileSize.width(), 0, paint);
+ paint.setARGB(128, 0, 0, 255);
+ canvas.drawLine(tileSize.width(), 0, tileSize.width(), tileSize.height(), paint);
}
renderingComplete(renderInfo, &canvas);
}
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.h b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
index 2defcc3..f225871 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
@@ -28,8 +28,9 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "PerformanceMonitor.h"
+#include "Color.h"
#include "SkRect.h"
+#include <wtf/text/StringHash.h>
class SkCanvas;
class SkDevice;
@@ -38,7 +39,7 @@ namespace WebCore {
class TextureInfo;
class TilePainter;
-class BaseTile;
+class Tile;
struct TileRenderInfo {
// coordinates of the tile
@@ -58,13 +59,13 @@ struct TileRenderInfo {
TilePainter* tilePainter;
// the base tile calling us
- BaseTile* baseTile;
+ Tile* baseTile;
// info about the texture that we are to render into
TextureInfo* textureInfo;
- // specifies whether or not to measure the rendering performance
- bool measurePerf;
+ bool isPureColor;
+ Color pureColor;
};
/**
@@ -76,7 +77,7 @@ public:
BaseRenderer(RendererType type) : m_type(type) {}
virtual ~BaseRenderer() {}
- void renderTiledContent(const TileRenderInfo& renderInfo);
+ void renderTiledContent(TileRenderInfo& renderInfo);
RendererType getType() { return m_type; }
@@ -90,14 +91,10 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
virtual void setupPartialInval(const TileRenderInfo& renderInfo, SkCanvas* canvas) {}
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
+ virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
void drawTileInfo(SkCanvas* canvas, const TileRenderInfo& renderInfo,
- int updateCount);
-
- virtual const String* getPerformanceTags(int& tagCount) = 0;
-
- // Performance tracking
- PerformanceMonitor m_perfMon;
+ int updateCount, double renderDuration);
private:
RendererType m_type;
diff --git a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
new file mode 100644
index 0000000..687808d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DrawQuadData_h
+#define DrawQuadData_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "Color.h"
+#include "SkRect.h"
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+class TransformationMatrix;
+
+enum DrawQuadType {
+ BaseQuad,
+ LayerQuad,
+ Blit // 1:1 straight pixel blit
+};
+
+// Both PureColorQuadData and TextureQuadData share the data from DrawQuadData.
+class DrawQuadData {
+public:
+ DrawQuadData(DrawQuadType type = BaseQuad,
+ const TransformationMatrix* drawMatrix = 0,
+ const SkRect* geometry = 0,
+ float opacity = 1.0f,
+ bool forceBlending = true)
+ : m_type(type)
+ , m_drawMatrix(drawMatrix)
+ , m_geometry(geometry)
+ , m_opacity(opacity)
+ , m_forceBlending(forceBlending)
+ {
+ }
+
+ DrawQuadData(const DrawQuadData& data)
+ : m_type(data.m_type)
+ , m_drawMatrix(data.m_drawMatrix)
+ , m_geometry(data.m_geometry)
+ , m_opacity(data.m_opacity)
+ , m_forceBlending(data.m_forceBlending)
+ {
+ }
+
+ virtual ~DrawQuadData() {};
+
+ DrawQuadType type() const { return m_type; }
+ const TransformationMatrix* drawMatrix() const { return m_drawMatrix; }
+ const SkRect* geometry() const { return m_geometry; }
+ float opacity() const { return m_opacity; }
+ bool forceBlending() const { return m_forceBlending; }
+
+ void updateDrawMatrix(TransformationMatrix* matrix) { m_drawMatrix = matrix; }
+ void updateGeometry(SkRect* rect) { m_geometry = rect; }
+ void updateOpacity(float opacity) { m_opacity = opacity; }
+
+ virtual bool pureColor() const { return false; }
+
+ virtual Color quadColor() const { return Color(); }
+
+ virtual int textureId() const { return 0; }
+ virtual GLint textureFilter() const { return 0; }
+ virtual GLenum textureTarget() const { return 0; }
+
+private:
+ DrawQuadType m_type;
+ const TransformationMatrix* m_drawMatrix;
+ const SkRect* m_geometry;
+ float m_opacity;
+ bool m_forceBlending;
+};
+
+class PureColorQuadData : public DrawQuadData {
+public:
+ PureColorQuadData(Color color,
+ DrawQuadType type = BaseQuad,
+ const TransformationMatrix* drawMatrix = 0,
+ const SkRect* geometry = 0,
+ float opacity = 1.0f,
+ bool forceBlending = true)
+ : DrawQuadData(type, drawMatrix, geometry, opacity, forceBlending)
+ {
+ m_quadColor = color;
+ }
+
+ PureColorQuadData(const DrawQuadData& data, Color color)
+ : DrawQuadData(data)
+ {
+ m_quadColor = color;
+ }
+
+ virtual ~PureColorQuadData() {};
+ virtual bool pureColor() const { return true; }
+ virtual Color quadColor() const { return m_quadColor; }
+ void updateColor(const Color& color) { m_quadColor = color; }
+
+private:
+ Color m_quadColor;
+};
+
+class TextureQuadData : public DrawQuadData {
+public:
+ TextureQuadData(int textureId,
+ GLenum textureTarget = GL_TEXTURE_2D,
+ GLint textureFilter = GL_LINEAR,
+ DrawQuadType type = BaseQuad,
+ const TransformationMatrix* drawMatrix = 0,
+ const SkRect* geometry = 0,
+ float opacity = 1.0f,
+ bool forceBlending = true)
+ : DrawQuadData(type, drawMatrix, geometry, opacity, forceBlending)
+ {
+ m_textureId = textureId;
+ m_textureTarget = textureTarget;
+ m_textureFilter = textureFilter;
+ }
+
+ TextureQuadData(const DrawQuadData& data,
+ int textureId,
+ GLenum textureTarget = GL_TEXTURE_2D,
+ GLint textureFilter = GL_LINEAR)
+ : DrawQuadData(data)
+ {
+ m_textureId = textureId;
+ m_textureTarget = textureTarget;
+ m_textureFilter = textureFilter;
+ }
+
+ virtual ~TextureQuadData() {};
+ virtual bool pureColor() const { return false; }
+
+ virtual int textureId() const { return m_textureId; }
+ virtual GLint textureFilter() const { return m_textureFilter; }
+ virtual GLenum textureTarget() const { return m_textureTarget; }
+
+ void updateTextureId(int newId) { m_textureId = newId; }
+
+private:
+ int m_textureId;
+ GLint m_textureFilter;
+ GLenum m_textureTarget;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // DrawQuadData_h
diff --git a/Source/WebCore/platform/graphics/android/GLExtras.cpp b/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
index 1676489..6498ecf 100644
--- a/Source/WebCore/platform/graphics/android/GLExtras.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
@@ -30,8 +30,10 @@
#include "AndroidLog.h"
#include "DrawExtra.h"
+#include "DrawQuadData.h"
#include "GLExtras.h"
#include "IntRect.h"
+#include "SkPath.h"
#include "TilesManager.h"
#include "android_graphics.h"
@@ -61,11 +63,10 @@ void GLExtras::drawRing(SkRect& srcRect, Color color, const TransformationMatrix
// double applied
Color colorWithoutAlpha(0xFF000000 | color.rgb());
float alpha = color.alpha() / (float) 255;
- if (drawMat) {
- TilesManager::instance()->shader()->drawLayerQuad(*drawMat, srcRect, 0,
- alpha, false, 0, colorWithoutAlpha);
- } else
- TilesManager::instance()->shader()->drawQuad(srcRect, 0, alpha, colorWithoutAlpha);
+
+ PureColorQuadData data(colorWithoutAlpha, drawMat ? LayerQuad : BaseQuad,
+ drawMat, &srcRect, alpha, false);
+ TilesManager::instance()->shader()->drawQuad(&data);
}
void GLExtras::drawRegion(const SkRegion& region, bool fill, bool drawBorder,
diff --git a/Source/WebCore/platform/graphics/android/GLExtras.h b/Source/WebCore/platform/graphics/android/rendering/GLExtras.h
index 59a7c3c..59a7c3c 100644
--- a/Source/WebCore/platform/graphics/android/GLExtras.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GLExtras.h
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
index ecd6bce..9435065 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
@@ -31,10 +31,14 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "ShaderProgram.h"
+#include "AndroidLog.h"
+#include "BaseRenderer.h"
+#include "TextureInfo.h"
+#include "Tile.h"
#include "TilesManager.h"
+#include "TransferQueue.h"
-#include <AndroidLog.h>
+#include <android/native_window.h>
#include <gui/SurfaceTexture.h>
#include <wtf/CurrentTime.h>
@@ -384,7 +388,7 @@ GLuint GLUtils::createSampleTexture()
return texture;
}
-GLuint GLUtils::createBaseTileGLTexture(int width, int height)
+GLuint GLUtils::createTileGLTexture(int width, int height)
{
GLuint texture;
glGenTextures(1, &texture);
@@ -412,7 +416,7 @@ GLuint GLUtils::createBaseTileGLTexture(int width, int height)
bool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
{
- // If the bitmap is the pure color, skip the transfer step, and update the BaseTile Info.
+ // If the bitmap is the pure color, skip the transfer step, and update the Tile Info.
// This check is taking < 1ms if we do full bitmap check per tile.
// TODO: use the SkPicture to determine whether or not a tile is single color.
pureColor = Color(Color::transparent);
@@ -455,25 +459,23 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap)
{
bool skipTransfer = false;
- BaseTile* tilePtr = renderInfo->baseTile;
+ Tile* tilePtr = renderInfo->baseTile;
// TODO: use pure color for partial invals as well
if (renderInfo->invalRect)
return false;
if (tilePtr) {
- BaseTileTexture* tileTexture = tilePtr->backTexture();
+ TileTexture* tileTexture = tilePtr->backTexture();
// Check the bitmap, and make everything ready here.
- Color pureColor;
- if (tileTexture && isPureColorBitmap(bitmap, pureColor)) {
+ if (tileTexture && renderInfo->isPureColor) {
// update basetile's info
// Note that we are skipping the whole TransferQueue.
renderInfo->textureInfo->m_width = bitmap.width();
renderInfo->textureInfo->m_height = bitmap.height();
renderInfo->textureInfo->m_internalFormat = GL_RGBA;
- TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo,
- pureColor);
+ TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo);
skipTransfer = true;
}
@@ -493,14 +495,14 @@ void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
return;
if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
- GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, bitmap);
+ GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
else {
if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
ALOGV("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
bitmap.width(), bitmap.height(),
requiredSize.width(), requiredSize.height());
}
- GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, bitmap);
+ GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
textureInfo->m_width = bitmap.width();
textureInfo->m_height = bitmap.height();
@@ -508,7 +510,7 @@ void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
}
}
-void GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
+void GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
{
if (!renderInfo
|| !renderInfo->textureInfo
@@ -518,6 +520,42 @@ void GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderI
TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, bitmap);
}
+bool GLUtils::updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap)
+{
+ SkAutoLockPixels alp(bitmap);
+ if (!bitmap.getPixels())
+ return false;
+ ANativeWindow_Buffer buffer;
+ if (ANativeWindow_lock(anw, &buffer, 0))
+ return false;
+ if (buffer.width < bitmap.width() || buffer.height < bitmap.height()) {
+ ALOGW("bitmap (%dx%d) too large for buffer (%dx%d)!",
+ bitmap.width(), bitmap.height(),
+ buffer.width, buffer.height);
+ ANativeWindow_unlockAndPost(anw);
+ return false;
+ }
+ uint8_t* img = (uint8_t*)buffer.bits;
+ int row;
+ int bpp = 4; // Now we only deal with RGBA8888 format.
+ bitmap.lockPixels();
+ uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
+
+ if (buffer.stride != bitmap.width())
+ // Copied line by line since we need to handle the offsets and stride.
+ for (row = 0 ; row < bitmap.height(); row ++) {
+ uint8_t* dst = &(img[buffer.stride * row * bpp]);
+ uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
+ memcpy(dst, src, bpp * bitmap.width());
+ }
+ else
+ memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
+
+ bitmap.unlockPixels();
+ ANativeWindow_unlockAndPost(anw);
+ return true;
+}
+
void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -540,16 +578,6 @@ void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GL
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
-
- // The following is a workaround -- remove when EGLImage texture upload is fixed.
- GLuint fboID;
- glGenFramebuffers(1, &fboID);
- glBindFramebuffer(GL_FRAMEBUFFER, fboID);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
- glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
- glDeleteFramebuffers(1, &fboID);
}
void GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
@@ -609,6 +637,23 @@ void GLUtils::convertToTransformationMatrix(const float* matrix, TransformationM
matrix[12], matrix[13], matrix[14], matrix[15]);
}
+void GLUtils::clearBackgroundIfOpaque(const Color* backgroundColor)
+{
+ if (!backgroundColor->hasAlpha()) {
+ if (TilesManager::instance()->invertedScreen()) {
+ float color = 1.0 - ((((float) backgroundColor->red() / 255.0) +
+ ((float) backgroundColor->green() / 255.0) +
+ ((float) backgroundColor->blue() / 255.0)) / 3.0);
+ glClearColor(color, color, color, 1);
+ } else {
+ glClearColor((float)backgroundColor->red() / 255.0,
+ (float)backgroundColor->green() / 255.0,
+ (float)backgroundColor->blue() / 255.0, 1);
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.h b/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
index e001aee..d4a2e84 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
@@ -31,8 +31,6 @@
#include "Color.h"
#include "SkBitmap.h"
#include "SkMatrix.h"
-#include "SkSize.h"
-#include "TextureInfo.h"
#include "TransformationMatrix.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -47,6 +45,8 @@ class SurfaceTexture;
namespace WebCore {
+class TileRenderInfo;
+
class GLUtils {
public:
@@ -71,7 +71,7 @@ public:
static void deleteTexture(GLuint* texture);
static GLuint createSampleColorTexture(int r, int g, int b);
static GLuint createSampleTexture();
- static GLuint createBaseTileGLTexture(int width, int height);
+ static GLuint createTileGLTexture(int width, int height);
static void createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
static void updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, const IntRect&, GLint filter = GL_LINEAR);
@@ -79,12 +79,14 @@ public:
static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
static void paintTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap);
- static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , const SkBitmap& bitmap);
+ static void updateQueueWithBitmap(const TileRenderInfo* , const SkBitmap& bitmap);
+ static bool updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap);
static void convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix);
static bool isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor);
static bool skipTransferForPureColor(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap);
+ static void clearBackgroundIfOpaque(const Color* backgroundColor);
static bool allowGLLog();
static double m_previousLogTime;
static int m_currentLogCounter;
diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.cpp b/Source/WebCore/platform/graphics/android/rendering/GaneshContext.cpp
index 620fccf..5c4b453 100644
--- a/Source/WebCore/platform/graphics/android/GaneshContext.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshContext.cpp
@@ -31,6 +31,9 @@
#include "AndroidLog.h"
#include "GLUtils.h"
+#include "TextureInfo.h"
+#include "TilesManager.h"
+#include "TransferQueue.h"
#include "android/native_window.h"
@@ -40,7 +43,7 @@ namespace WebCore {
GaneshContext::GaneshContext()
: m_grContext(0)
- , m_baseTileDeviceSurface(0)
+ , m_tileDeviceSurface(0)
, m_surfaceConfig(0)
, m_surfaceContext(EGL_NO_CONTEXT)
{
@@ -57,9 +60,8 @@ GaneshContext* GaneshContext::instance()
GrContext* GaneshContext::getGrContext()
{
- if (!m_grContext) {
- m_grContext = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL);
- }
+ if (!m_grContext)
+ m_grContext = GrContext::Create(kOpenGL_Shaders_GrEngine, 0);
return m_grContext;
}
@@ -69,7 +71,7 @@ void GaneshContext::flush()
m_grContext->flush();
}
-SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo)
+SkDevice* GaneshContext::getDeviceForTile(const TileRenderInfo& renderInfo)
{
// Ganesh should be the only code in the rendering thread that is using GL
// and setting the EGLContext. If this is not the case then we need to
@@ -85,9 +87,8 @@ SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo)
if (!m_surfaceContext) {
- if(eglGetCurrentContext() != EGL_NO_CONTEXT) {
+ if(eglGetCurrentContext() != EGL_NO_CONTEXT)
ALOGV("ERROR: should not have a context yet");
- }
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
GLUtils::checkEglError("eglGetDisplay");
@@ -146,7 +147,7 @@ SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo)
GLUtils::checkEglError("eglMakeCurrent", returnValue);
ALOGV("eglMakeCurrent");
- if (!m_baseTileDeviceSurface) {
+ if (!m_tileDeviceSurface) {
GrPlatformRenderTargetDesc renderTargetDesc;
renderTargetDesc.fWidth = TilesManager::tileWidth();
@@ -159,19 +160,19 @@ SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo)
GrContext* grContext = getGrContext();
GrRenderTarget* renderTarget = grContext->createPlatformRenderTarget(renderTargetDesc);
- m_baseTileDeviceSurface = new SkGpuDevice(grContext, renderTarget);
+ m_tileDeviceSurface = new SkGpuDevice(grContext, renderTarget);
renderTarget->unref();
- ALOGV("generated device %p", m_baseTileDeviceSurface);
+ ALOGV("generated device %p", m_tileDeviceSurface);
}
- GLUtils::checkGlError("getDeviceForBaseTile");
+ GLUtils::checkGlError("getDeviceForTile");
// We must reset the Ganesh context only after we are sure we have
// re-established our EGLContext as the current context.
- if (m_baseTileDeviceSurface && contextNeedsReset)
+ if (m_tileDeviceSurface && contextNeedsReset)
getGrContext()->resetContext();
- return m_baseTileDeviceSurface;
+ return m_tileDeviceSurface;
}
diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.h b/Source/WebCore/platform/graphics/android/rendering/GaneshContext.h
index def35e5..57e8e19 100644
--- a/Source/WebCore/platform/graphics/android/GaneshContext.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshContext.h
@@ -31,7 +31,7 @@
#include "BaseRenderer.h"
#include "GrContext.h"
#include "SkGpuDevice.h"
-#include "TilesManager.h"
+#include <EGL/egl.h>
namespace WebCore {
@@ -39,7 +39,7 @@ class GaneshContext {
public:
static GaneshContext* instance();
- SkDevice* getDeviceForBaseTile(const TileRenderInfo& renderInfo);
+ SkDevice* getDeviceForTile(const TileRenderInfo& renderInfo);
void flush();
@@ -50,7 +50,7 @@ private:
GrContext* getGrContext();
GrContext* m_grContext;
- SkGpuDevice* m_baseTileDeviceSurface;
+ SkGpuDevice* m_tileDeviceSurface;
EGLConfig m_surfaceConfig;
EGLContext m_surfaceContext;
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
index 74b008c..208adb6 100644
--- a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
@@ -36,19 +36,10 @@
#include "SkCanvas.h"
#include "SkGpuDevice.h"
#include "TilesManager.h"
+#include "TransferQueue.h"
namespace WebCore {
-static const String TAG_CREATE_FBO = "create_fbo";
-static const String TAG_DRAW_PICTURE = "draw_picture";
-static const String TAG_UPDATE_TEXTURE = "update_texture";
-#define TAG_COUNT 3
-static const String TAGS[] = {
- TAG_CREATE_FBO,
- TAG_DRAW_PICTURE,
- TAG_UPDATE_TEXTURE,
-};
-
GaneshRenderer::GaneshRenderer() : BaseRenderer(BaseRenderer::Ganesh)
{
#ifdef DEBUG_COUNT
@@ -65,9 +56,6 @@ GaneshRenderer::~GaneshRenderer()
void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- if (renderInfo.measurePerf)
- m_perfMon.start(TAG_CREATE_FBO);
-
GaneshContext* ganesh = GaneshContext::instance();
TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
@@ -84,7 +72,7 @@ void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
SkDevice* device = NULL;
if (renderInfo.tileSize.width() == TilesManager::tileWidth()
&& renderInfo.tileSize.height() == TilesManager::tileHeight()) {
- device = ganesh->getDeviceForBaseTile(renderInfo);
+ device = ganesh->getDeviceForTile(renderInfo);
} else {
// TODO support arbitrary sizes for layers
ALOGV("ERROR: expected (%d,%d) actual (%d,%d)",
@@ -92,11 +80,6 @@ void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
renderInfo.tileSize.width(), renderInfo.tileSize.height());
}
- if (renderInfo.measurePerf) {
- m_perfMon.stop(TAG_CREATE_FBO);
- m_perfMon.start(TAG_DRAW_PICTURE);
- }
-
// set the GPU device to the canvas
canvas->setDevice(device);
}
@@ -113,11 +96,6 @@ void GaneshRenderer::setupPartialInval(const TileRenderInfo& renderInfo, SkCanva
void GaneshRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- if (renderInfo.measurePerf) {
- m_perfMon.stop(TAG_DRAW_PICTURE);
- m_perfMon.start(TAG_UPDATE_TEXTURE);
- }
-
ALOGV("rendered to tile (%d,%d)", renderInfo.x, renderInfo.y);
GaneshContext::instance()->flush();
@@ -128,15 +106,6 @@ void GaneshRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanva
eglSwapBuffers(eglGetCurrentDisplay(), tileQueue->m_eglSurface);
tileQueue->addItemInTransferQueue(&renderInfo, GpuUpload, 0);
tileQueue->unlockQueue();
-
- if (renderInfo.measurePerf)
- m_perfMon.stop(TAG_UPDATE_TEXTURE);
-}
-
-const String* GaneshRenderer::getPerformanceTags(int& tagCount)
-{
- tagCount = TAG_COUNT;
- return TAGS;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.h b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
index 0e1d41e..d7eda24 100644
--- a/Source/WebCore/platform/graphics/android/GaneshRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
@@ -49,7 +49,9 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void setupPartialInval(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual const String* getPerformanceTags(int& tagCount);
+ virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) {
+ renderInfo.isPureColor = false;
+ }
};
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
index e42d075..6e4a82c 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
@@ -30,12 +30,13 @@
#include "ImageTexture.h"
#include "AndroidLog.h"
+#include "ClassTracker.h"
#include "ImagesManager.h"
#include "LayerAndroid.h"
#include "SkDevice.h"
#include "SkPicture.h"
+#include "TileGrid.h"
#include "TilesManager.h"
-#include "TiledTexture.h"
namespace WebCore {
@@ -71,7 +72,7 @@ unsigned computeCrc(uint8_t* buffer, size_t size)
ImageTexture::ImageTexture(SkBitmap* bmp, unsigned crc)
: m_image(bmp)
- , m_texture(0)
+ , m_tileGrid(0)
, m_layer(0)
, m_picture(0)
, m_crc(crc)
@@ -84,7 +85,7 @@ ImageTexture::ImageTexture(SkBitmap* bmp, unsigned crc)
// NOTE: This constructor is called on the webcore thread
- // Create a picture containing the image (needed for TiledTexture)
+ // Create a picture containing the image (needed for TileGrid)
m_picture = new SkPicture();
SkCanvas* pcanvas = m_picture->beginRecording(m_image->width(), m_image->height());
pcanvas->clear(SkColorSetARGBInline(0, 0, 0, 0));
@@ -98,7 +99,7 @@ ImageTexture::~ImageTexture()
ClassTracker::instance()->decrement("ImageTexture");
#endif
delete m_image;
- delete m_texture;
+ delete m_tileGrid;
SkSafeUnref(m_picture);
}
@@ -144,13 +145,13 @@ int ImageTexture::nbTextures()
{
if (!hasContentToShow())
return 0;
- if (!m_texture)
+ if (!m_tileGrid)
return 0;
// TODO: take in account the visible clip (need to maintain
// a list of the clients layer, etc.)
IntRect visibleArea(0, 0, m_image->width(), m_image->height());
- int nbTextures = m_texture->nbTextures(visibleArea, 1.0);
+ int nbTextures = m_tileGrid->nbTextures(visibleArea, 1.0);
ALOGV("ImageTexture %p, %d x %d needs %d textures",
this, m_image->width(), m_image->height(),
nbTextures);
@@ -172,20 +173,21 @@ bool ImageTexture::prepareGL(GLWebViewState* state)
if (!hasContentToShow())
return false;
- if (!m_texture && m_picture) {
- m_texture = new TiledTexture();
+ if (!m_tileGrid && m_picture) {
+ bool isBaseSurface = false;
+ m_tileGrid = new TileGrid(isBaseSurface);
SkRegion region;
region.setRect(0, 0, m_image->width(), m_image->height());
- m_texture->markAsDirty(region);
+ m_tileGrid->markAsDirty(region);
}
- if (!m_texture)
+ if (!m_tileGrid)
return false;
- IntRect visibleArea(0, 0, m_image->width(), m_image->height());
- m_texture->prepareGL(state, 1.0, visibleArea, this);
- if (m_texture->isReady()) {
- m_texture->swapTiles();
+ IntRect unclippedArea(0, 0, m_image->width(), m_image->height());
+ m_tileGrid->prepareGL(state, 1.0, unclippedArea, unclippedArea, this);
+ if (m_tileGrid->isReady()) {
+ m_tileGrid->swapTiles();
return false;
}
return true;
@@ -196,8 +198,6 @@ const TransformationMatrix* ImageTexture::transform()
if (!m_layer)
return 0;
- FloatPoint p(0, 0);
- p = m_layer->drawTransform()->mapPoint(p);
IntRect layerArea = m_layer->unclippedArea();
float scaleW = static_cast<float>(layerArea.width()) / static_cast<float>(m_image->width());
float scaleH = static_cast<float>(layerArea.height()) / static_cast<float>(m_image->height());
@@ -215,14 +215,14 @@ float ImageTexture::opacity()
return m_layer->drawOpacity();
}
-bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas)
+bool ImageTexture::paint(SkCanvas* canvas)
{
if (!m_picture) {
ALOGV("IT %p COULDNT PAINT, NO PICTURE", this);
return false;
}
- ALOGV("IT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), m_picture);
+ ALOGV("IT %p painting with picture %p", this, m_picture);
canvas->drawPicture(*m_picture);
return true;
@@ -235,12 +235,12 @@ void ImageTexture::drawGL(LayerAndroid* layer, float opacity)
if (!hasContentToShow())
return;
- // TiledTexture::draw() will call us back to know the
+ // TileGrid::draw() will call us back to know the
// transform and opacity, so we need to set m_layer
m_layer = layer;
- if (m_texture) {
+ if (m_tileGrid) {
IntRect visibleArea = m_layer->visibleArea();
- m_texture->drawGL(visibleArea, opacity, transform());
+ m_tileGrid->drawGL(visibleArea, opacity, transform());
}
m_layer = 0;
}
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
index 91c8a29..fccbb78 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
@@ -31,13 +31,14 @@
#include "SkBitmapRef.h"
#include "SkPicture.h"
#include "SkRefCnt.h"
-#include "LayerAndroid.h"
+#include "TilePainter.h"
namespace WebCore {
+class GLWebViewState;
class LayerAndroid;
class TexturesResult;
-class TiledTexture;
+class TileGrid;
/////////////////////////////////////////////////////////////////////////////////
// Image sharing codepath for layers
@@ -63,7 +64,7 @@ class TiledTexture;
// ImageTexture at draw time.
//
// ImageTexture recopy the original SkBitmap so that they can safely be used
-// on a different thread; it uses TiledTexture to allocate and paint the image,
+// on a different thread; it uses TileGrid to allocate and paint the image,
// so that we can share the same textures and limits as the rest of the layers.
//
/////////////////////////////////////////////////////////////////////////////////
@@ -84,8 +85,8 @@ public:
static unsigned computeCRC(const SkBitmap* bitmap);
bool equalsCRC(unsigned crc);
- // methods used by TiledTexture
- virtual bool paint(BaseTile* tile, SkCanvas* canvas);
+ // methods used by TileGrid
+ virtual bool paint(SkCanvas* canvas);
virtual float opacity();
int nbTextures();
@@ -97,7 +98,7 @@ private:
SkBitmapRef* m_imageRef;
SkBitmap* m_image;
- TiledTexture* m_texture;
+ TileGrid* m_tileGrid;
LayerAndroid* m_layer;
SkPicture* m_picture;
TransformationMatrix m_layerMatrix;
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.cpp b/Source/WebCore/platform/graphics/android/rendering/ImagesManager.cpp
index 8452503..8452503 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ImagesManager.cpp
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.h b/Source/WebCore/platform/graphics/android/rendering/ImagesManager.h
index b915a46..b915a46 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ImagesManager.h
diff --git a/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp b/Source/WebCore/platform/graphics/android/rendering/InspectorCanvas.cpp
index f9edb74..f9edb74 100644
--- a/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/InspectorCanvas.cpp
diff --git a/Source/WebCore/platform/graphics/android/InspectorCanvas.h b/Source/WebCore/platform/graphics/android/rendering/InspectorCanvas.h
index 415a579..415a579 100644
--- a/Source/WebCore/platform/graphics/android/InspectorCanvas.h
+++ b/Source/WebCore/platform/graphics/android/rendering/InspectorCanvas.h
diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp
index 1fcb765..fcd9d3b 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp
@@ -23,20 +23,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "PaintTileOperation"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "PaintTileOperation.h"
+
+#include "AndroidLog.h"
+#include "GLWebViewState.h"
#include "ImageTexture.h"
#include "ImagesManager.h"
#include "LayerAndroid.h"
-#include "TiledPage.h"
#include "TilesManager.h"
namespace WebCore {
-PaintTileOperation::PaintTileOperation(BaseTile* tile, TilePainter* painter)
- : QueuedOperation(tile->page())
- , m_tile(tile)
+PaintTileOperation::PaintTileOperation(Tile* tile, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch)
+ : m_tile(tile)
, m_painter(painter)
+ , m_state(state)
+ , m_isLowResPrefetch(isLowResPrefetch)
{
if (m_tile)
m_tile->setRepaintPending(true);
@@ -66,6 +73,8 @@ bool PaintTileOperation::operator==(const QueuedOperation* operation)
void PaintTileOperation::run()
{
+ TRACE_METHOD();
+
if (m_tile) {
m_tile->paintBitmap(m_painter);
m_tile->setRepaintPending(false);
@@ -80,14 +89,9 @@ int PaintTileOperation::priority()
int priority = 200000;
- // if scrolling, prioritize the prefetch page, otherwise deprioritize
- TiledPage* page = m_tile->page();
- if (page && page->isPrefetchPage()) {
- if (page->glWebViewState()->isScrolling())
- priority = 0;
- else
- priority = 400000;
- }
+ // prioritize low res while scrolling
+ if (m_isLowResPrefetch)
+ priority = m_state->isScrolling() ? 0 : 400000;
// prioritize higher draw count
unsigned long long currentDraw = TilesManager::instance()->getDrawGLCount();
@@ -100,7 +104,7 @@ int PaintTileOperation::priority()
// for base tiles, prioritize based on position
if (!m_tile->isLayerTile()) {
- bool goingDown = m_tile->page()->scrollingDown();
+ bool goingDown = m_state->goingDown();
priority += m_tile->x();
if (goingDown)
diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h
index 05825e2..1d376bf 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h
+++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h
@@ -26,7 +26,7 @@
#ifndef PaintTileSetOperation_h
#define PaintTileSetOperation_h
-#include "BaseTile.h"
+#include "Tile.h"
#include "QueuedOperation.h"
#include "SkRefCnt.h"
@@ -38,7 +38,8 @@ class ImageTexture;
class PaintTileOperation : public QueuedOperation {
public:
- PaintTileOperation(BaseTile* tile, TilePainter* painter);
+ PaintTileOperation(Tile* tile, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch);
virtual ~PaintTileOperation();
virtual bool operator==(const QueuedOperation* operation);
virtual void run();
@@ -48,8 +49,10 @@ public:
float scale() { return m_tile->scale(); }
private:
- BaseTile* m_tile;
+ Tile* m_tile;
TilePainter* m_painter;
+ GLWebViewState* m_state;
+ bool m_isLowResPrefetch;
};
class ScaleFilter : public OperationFilter {
diff --git a/Source/WebCore/platform/graphics/android/QueuedOperation.h b/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h
index 2f36547..f98efcd 100644
--- a/Source/WebCore/platform/graphics/android/QueuedOperation.h
+++ b/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h
@@ -28,19 +28,12 @@
namespace WebCore {
-class TiledPage;
-
class QueuedOperation {
public:
- QueuedOperation(TiledPage* page)
- : m_page(page) {}
virtual ~QueuedOperation() {}
virtual void run() = 0;
virtual bool operator==(const QueuedOperation* operation) = 0;
- virtual int priority() { return -1; }
- TiledPage* page() const { return m_page; }
-private:
- TiledPage* m_page;
+ virtual int priority() = 0;
};
class OperationFilter {
@@ -49,19 +42,6 @@ public:
virtual bool check(QueuedOperation* operation) = 0;
};
-class PageFilter : public OperationFilter {
-public:
- PageFilter(TiledPage* page) : m_page(page) {}
- virtual bool check(QueuedOperation* operation)
- {
- if (operation->page() == m_page)
- return true;
- return false;
- }
-private:
- TiledPage* m_page;
-};
-
}
#endif // QueuedOperation_h
diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
index 44f2a7d..b880eef 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
@@ -23,30 +23,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "RasterRenderer"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "RasterRenderer.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "GLUtils.h"
#include "SkBitmap.h"
#include "SkBitmapRef.h"
#include "SkCanvas.h"
#include "SkDevice.h"
+#include "Tile.h"
#include "TilesManager.h"
namespace WebCore {
-static const String TAG_CREATE_BITMAP = "create_bitmap";
-static const String TAG_DRAW_PICTURE = "draw_picture";
-static const String TAG_UPDATE_TEXTURE = "update_texture";
-#define TAG_COUNT 3
-static const String TAGS[] = {
- TAG_CREATE_BITMAP,
- TAG_DRAW_PICTURE,
- TAG_UPDATE_TEXTURE,
-};
-
SkBitmap* RasterRenderer::g_bitmap = 0;
RasterRenderer::RasterRenderer() : BaseRenderer(BaseRenderer::Raster)
@@ -72,24 +67,24 @@ RasterRenderer::~RasterRenderer()
void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- if (renderInfo.measurePerf)
- m_perfMon.start(TAG_CREATE_BITMAP);
-
if (renderInfo.baseTile->isLayerTile()) {
g_bitmap->setIsOpaque(false);
g_bitmap->eraseARGB(0, 0, 0, 0);
} else {
- g_bitmap->setIsOpaque(true);
- g_bitmap->eraseARGB(255, 255, 255, 255);
+ Color defaultBackground = Color::white;
+ Color* background = renderInfo.tilePainter->background();
+ if (!background) {
+ ALOGV("No background color for base layer!");
+ background = &defaultBackground;
+ }
+ ALOGV("setupCanvas use background on Base Layer %x", background->rgb());
+ g_bitmap->setIsOpaque(!background->hasAlpha());
+ g_bitmap->eraseARGB(background->alpha(), background->red(),
+ background->green(), background->blue());
}
SkDevice* device = new SkDevice(*g_bitmap);
- if (renderInfo.measurePerf) {
- m_perfMon.stop(TAG_CREATE_BITMAP);
- m_perfMon.start(TAG_DRAW_PICTURE);
- }
-
canvas->setDevice(device);
device->unref();
@@ -106,23 +101,13 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- if (renderInfo.measurePerf) {
- m_perfMon.stop(TAG_DRAW_PICTURE);
- m_perfMon.start(TAG_UPDATE_TEXTURE);
- }
-
const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
-
GLUtils::paintTextureWithBitmap(&renderInfo, bitmap);
-
- if (renderInfo.measurePerf)
- m_perfMon.stop(TAG_UPDATE_TEXTURE);
}
-const String* RasterRenderer::getPerformanceTags(int& tagCount)
+void RasterRenderer::checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- tagCount = TAG_COUNT;
- return TAGS;
+ renderInfo.isPureColor = GLUtils::isPureColorBitmap(*g_bitmap, renderInfo.pureColor);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.h b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
index 96b3f58..39e00f2 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
@@ -49,7 +49,7 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual const String* getPerformanceTags(int& tagCount);
+ virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas);
private:
static SkBitmap* g_bitmap;
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
index 33829e3..b1fe2f4 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
@@ -32,6 +32,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidLog.h"
+#include "DrawQuadData.h"
#include "FloatPoint3D.h"
#include "GLUtils.h"
#include "TilesManager.h"
@@ -39,6 +40,8 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#define EPSILON 0.00001f
+
namespace WebCore {
static const char gVertexShader[] =
@@ -384,7 +387,22 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR
TransformationMatrix orthoScale;
orthoScale.scale3d(orthoScaleX, orthoScaleY, 1.0);
- m_projectionMatrix = ortho * orthoScale;
+ m_visibleRectProjectionMatrix = ortho * orthoScale;
+
+ ALOGV("set m_clipProjectionMatrix, %d, %d, %d, %d",
+ screenClip.x(), screenClip.y(), screenClip.x() + screenClip.width(),
+ screenClip.y() + screenClip.height());
+
+ // In order to incorporate the animation delta X and Y, using the clip as
+ // the GL viewport can save all the trouble of re-position from webViewRect
+ // to final position.
+ GLUtils::setOrthographicMatrix(m_clipProjectionMatrix, screenClip.x(), screenClip.y(),
+ screenClip.x() + screenClip.width(),
+ screenClip.y() + screenClip.height(), -1000, 1000);
+
+ glViewport(screenClip.x(), m_targetHeight - screenClip.y() - screenClip.height() ,
+ screenClip.width(), screenClip.height());
+
m_viewport = visibleRect;
m_currentScale = scale;
@@ -401,10 +419,10 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR
TransformationMatrix viewScale;
viewScale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
- m_documentToScreenMatrix = viewScale * viewTranslate * m_projectionMatrix;
+ m_documentToScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix;
viewTranslate.scale3d(1, -1, 1);
- m_documentToInvScreenMatrix = viewScale * viewTranslate * m_projectionMatrix;
+ m_documentToInvScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix;
IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height());
m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect);
@@ -421,24 +439,10 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR
m_screenClip.setSize(IntSize(ceilf(tclip.width()), ceilf(tclip.height())));
resetBlending();
-}
-// Calculate the matrix given the geometry.
-void ShaderProgram::setProjectionMatrix(const SkRect& geometry, GLfloat* mtxPtr)
-{
- TransformationMatrix translate;
- translate.translate3d(geometry.fLeft, geometry.fTop, 0.0);
- TransformationMatrix scale;
- scale.scale3d(geometry.width(), geometry.height(), 1.0);
-
- TransformationMatrix total;
- if (!m_alphaLayer)
- total = m_projectionMatrix * m_repositionMatrix * m_webViewMatrix
- * translate * scale;
- else
- total = m_projectionMatrix * translate * scale;
-
- GLUtils::toGLMatrix(mtxPtr, total);
+ // Set up m_clipProjectionMatrix, m_currentScale and m_webViewMatrix before
+ // calling this function.
+ setupSurfaceProjectionMatrix();
}
// Calculate the right color value sent into the shader considering the (0,1)
@@ -482,33 +486,6 @@ ShaderType ShaderProgram::getTextureShaderType(GLenum textureTarget)
return type;
}
-void ShaderProgram::drawQuad(const SkRect& geometry, int textureId, float opacity,
- Color pureColor, GLenum textureTarget, GLint texFilter)
-{
- ShaderType type = UndefinedShader;
- if (!textureId) {
- pureColor = shaderColor(pureColor, opacity);
- if (pureColor.rgb() == Color::transparent && opacity < 1.0)
- return;
- type = PureColor;
- } else
- type = getTextureShaderType(textureTarget);
-
- if (type != UndefinedShader) {
- // The matrix is either for the transfer queue or the tiles
- GLfloat* finalMatrix = m_transferProjMtx;
- GLfloat projectionMatrix[16];
- if (!geometry.isEmpty()) {
- setProjectionMatrix(geometry, projectionMatrix);
- finalMatrix = projectionMatrix;
- }
- setBlendingState(opacity < 1.0);
- drawQuadInternal(type, finalMatrix, textureId, opacity, textureTarget,
- texFilter, pureColor);
- }
- GLUtils::checkGlError("drawQuad");
-}
-
// This function transform a clip rect extracted from the current layer
// into a clip rect in screen coordinates -- used by the clipping rects
FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
@@ -559,6 +536,9 @@ void ShaderProgram::clip(const FloatRect& clip)
if (clip == m_clipRect)
return;
+ ALOGV("--clipping rect %f %f, %f x %f",
+ clip.x(), clip.y(), clip.width(), clip.height());
+
// we should only call glScissor in this function, so that we can easily
// track the current clipping rect.
@@ -600,7 +580,7 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo
{
TransformationMatrix modifiedDrawMatrix = drawMatrix;
modifiedDrawMatrix.scale3d(w, h, 1);
- TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
+ TransformationMatrix renderMatrix = m_visibleRectProjectionMatrix * modifiedDrawMatrix;
FloatPoint3D point(0.5, 0.5, 0.0);
FloatPoint3D result = renderMatrix.mapPoint(point);
return result.z();
@@ -639,44 +619,81 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
-void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
- const SkRect& geometry, int textureId,
- float opacity, bool forceBlending,
- GLenum textureTarget,
- Color pureColor)
+// Put the common matrix computation at higher level to avoid redundancy.
+void ShaderProgram::setupSurfaceProjectionMatrix()
{
- TransformationMatrix modifiedDrawMatrix = drawMatrix;
- // move the drawing depending on where the texture is on the layer
- modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
- modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
+ TransformationMatrix scaleMatrix;
+ scaleMatrix.scale3d(m_currentScale, m_currentScale, 1);
+ m_surfaceProjectionMatrix = m_clipProjectionMatrix * m_webViewMatrix * scaleMatrix;
+}
+// Calculate the matrix given the geometry.
+GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data)
+{
+ DrawQuadType type = data->type();
+ if (type == Blit)
+ return m_transferProjMtx;
+
+ const TransformationMatrix* matrix = data->drawMatrix();
+ const SkRect* geometry = data->geometry();
+
+ // This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen
+ // coordinate, before applying the m_webViewMatrix.
+ // It first scale and translate the vertex array from (0,0)(1x1) to real
+ // tile position and size. Then apply the transform from the layer's.
+ // Finally scale to the currentScale to support zooming.
+ // Note the geometry contains the tile zoom scale, so visually we will see
+ // the tiles scale at a ratio as (m_currentScale/tile's scale).
+ TransformationMatrix modifiedDrawMatrix;
+ if (type == LayerQuad)
+ modifiedDrawMatrix = *matrix;
+ modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop);
+ modifiedDrawMatrix.scale3d(geometry->width(), geometry->height(), 1);
+
+ // Even when we are on a alpha layer or not, we need to respect the
+ // m_webViewMatrix, it may contain the layout offset. Normally it is
+ // identity.
TransformationMatrix renderMatrix;
- if (!m_alphaLayer)
- renderMatrix = m_projectionMatrix * m_repositionMatrix
- * m_webViewMatrix * modifiedDrawMatrix;
- else
- renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
+ renderMatrix = m_surfaceProjectionMatrix * modifiedDrawMatrix;
- GLfloat projectionMatrix[16];
- GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
+#if DEBUG_MATRIX
+ debugMatrixInfo(m_currentScale, m_clipProjectionMatrix, m_webViewMatrix,
+ modifiedDrawMatrix, matrix);
+#endif
+
+ GLUtils::toGLMatrix(m_tileProjMatrix, renderMatrix);
+ return m_tileProjMatrix;
+}
+
+void ShaderProgram::drawQuad(const DrawQuadData* data)
+{
+ GLfloat* matrix = getTileProjectionMatrix(data);
+
+ float opacity = data->opacity();
+ bool forceBlending = data->forceBlending();
bool enableBlending = forceBlending || opacity < 1.0;
- ShaderType type = UndefinedShader;
- if (!textureId) {
- pureColor = shaderColor(pureColor, opacity);
- if (pureColor.rgb() == Color::transparent && enableBlending)
+ ShaderType shaderType = UndefinedShader;
+ int textureId = 0;
+ GLint textureFilter = 0;
+ GLenum textureTarget = 0;
+
+ Color quadColor = data->quadColor();
+ if (data->pureColor()) {
+ shaderType = PureColor;
+ quadColor = shaderColor(quadColor, opacity);
+ enableBlending = enableBlending || quadColor.hasAlpha();
+ if (!quadColor.alpha() && enableBlending)
return;
- type = PureColor;
- } else
- type = getTextureShaderType(textureTarget);
-
- if (type != UndefinedShader) {
- setBlendingState(enableBlending);
- drawQuadInternal(type, projectionMatrix, textureId, opacity,
- textureTarget, GL_LINEAR, pureColor);
+ } else {
+ textureId = data->textureId();
+ textureFilter = data->textureFilter();
+ textureTarget = data->textureTarget();
+ shaderType = getTextureShaderType(textureTarget);
}
-
- GLUtils::checkGlError("drawLayerQuad");
+ setBlendingState(enableBlending);
+ drawQuadInternal(shaderType, matrix, textureId, opacity,
+ textureTarget, textureFilter, quadColor);
}
void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
@@ -685,11 +702,14 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
{
// switch to our custom yuv video rendering program
glUseProgram(m_handleArray[Video].programHandle);
-
- TransformationMatrix modifiedDrawMatrix = drawMatrix;
+ // TODO: Merge drawVideoLayerQuad into drawQuad.
+ TransformationMatrix modifiedDrawMatrix;
+ modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1);
+ modifiedDrawMatrix.multiply(drawMatrix);
modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
- TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
+ TransformationMatrix renderMatrix =
+ m_clipProjectionMatrix * m_webViewMatrix * modifiedDrawMatrix;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
@@ -711,44 +731,91 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
-void ShaderProgram::setWebViewMatrix(const float* matrix, bool alphaLayer)
+void ShaderProgram::setGLDrawInfo(const android::uirenderer::DrawGlInfo* info)
{
- GLUtils::convertToTransformationMatrix(matrix, m_webViewMatrix);
- m_alphaLayer = alphaLayer;
+ GLUtils::convertToTransformationMatrix(info->transform, m_webViewMatrix);
+ m_alphaLayer = info->isLayer;
+ m_targetHeight = info->height;
}
-void ShaderProgram::calculateAnimationDelta()
+// This function is called per tileGrid to minimize the computation overhead.
+// The ortho projection and glViewport will map 1:1, so we don't need to
+// worry about them here. Basically, if the current zoom scale / tile's scale
+// plus the webview and layer transformation ends up at scale factor 1.0,
+// then we can use point sampling.
+bool ShaderProgram::usePointSampling(float tileScale,
+ const TransformationMatrix* layerTransform)
{
- // The matrix contains the scrolling info, so this rect is starting from
- // the m_viewport.
- // So we just need to map the webview's visible rect using the matrix,
- // calculate the difference b/t transformed rect and the webViewRect,
- // then we can get the delta x , y caused by the animation.
- // Note that the Y is for reporting back to GL viewport, so it is inverted.
- // When it is alpha animation, then we rely on the framework implementation
- // such that there is no matrix applied in native webkit.
- if (!m_alphaLayer) {
- FloatRect rect(m_viewport.fLeft * m_currentScale,
- m_viewport.fTop * m_currentScale,
- m_webViewRect.width(),
- m_webViewRect.height());
- rect = m_webViewMatrix.mapRect(rect);
- m_animationDelta.setX(rect.x() - m_webViewRect.x() );
- m_animationDelta.setY(rect.y() + rect.height() - m_webViewRect.y()
- - m_webViewRect.height() - m_titleBarHeight);
-
- m_repositionMatrix.makeIdentity();
- m_repositionMatrix.translate3d(-m_webViewRect.x(), -m_webViewRect.y() - m_titleBarHeight, 0);
- m_repositionMatrix.translate3d(m_viewport.fLeft * m_currentScale, m_viewport.fTop * m_currentScale, 0);
- m_repositionMatrix.translate3d(-m_animationDelta.x(), -m_animationDelta.y(), 0);
- } else {
- m_animationDelta.setX(0);
- m_animationDelta.setY(0);
- m_repositionMatrix.makeIdentity();
+ const float testSize = 1.0;
+ FloatRect rect(0, 0, testSize, testSize);
+ TransformationMatrix matrix;
+ matrix.scale3d(m_currentScale, m_currentScale, 1);
+ if (layerTransform)
+ matrix.multiply(*layerTransform);
+ matrix.scale3d(1.0 / tileScale, 1.0 / tileScale, 1);
+
+ matrix = m_webViewMatrix * matrix;
+
+ rect = matrix.mapRect(rect);
+
+ float deltaWidth = abs(rect.width() - testSize);
+ float deltaHeight = abs(rect.height() - testSize);
+
+ if (deltaWidth < EPSILON && deltaHeight < EPSILON) {
+ ALOGV("Point sampling : deltaWidth is %f, deltaHeight is %f", deltaWidth, deltaHeight);
+ return true;
}
+ return false;
+}
+
+#if DEBUG_MATRIX
+FloatRect ShaderProgram::debugMatrixTransform(const TransformationMatrix& matrix,
+ const char* matrixName)
+{
+ FloatRect rect(0.0, 0.0, 1.0, 1.0);
+ rect = matrix.mapRect(rect);
+ ALOGV("After %s matrix:\n %f, %f rect.width() %f rect.height() %f",
+ matrixName, rect.x(), rect.y(), rect.width(), rect.height());
+ return rect;
}
-} // namespace WebCore
+void ShaderProgram::debugMatrixInfo(float currentScale,
+ const TransformationMatrix& clipProjectionMatrix,
+ const TransformationMatrix& webViewMatrix,
+ const TransformationMatrix& modifiedDrawMatrix,
+ const TransformationMatrix* layerMatrix)
+{
+ int viewport[4];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ ALOGV("viewport %d, %d, %d, %d , currentScale %f",
+ viewport[0], viewport[1], viewport[2], viewport[3], currentScale);
+ IntRect currentGLViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
+
+ TransformationMatrix scaleMatrix;
+ scaleMatrix.scale3d(currentScale, currentScale, 1.0);
+
+ if (layerMatrix)
+ debugMatrixTransform(*layerMatrix, "layerMatrix");
+
+ TransformationMatrix debugMatrix = scaleMatrix * modifiedDrawMatrix;
+ debugMatrixTransform(debugMatrix, "scaleMatrix * modifiedDrawMatrix");
+
+ debugMatrix = webViewMatrix * debugMatrix;
+ debugMatrixTransform(debugMatrix, "webViewMatrix * scaleMatrix * modifiedDrawMatrix");
+
+ debugMatrix = clipProjectionMatrix * debugMatrix;
+ FloatRect finalRect =
+ debugMatrixTransform(debugMatrix, "all Matrix");
+ // After projection, we will be in a (-1, 1) range and now we can map it back
+ // to the (x,y) -> (x+width, y+height)
+ ALOGV("final convert to screen coord x, y %f, %f width %f height %f , ",
+ (finalRect.x() + 1) / 2 * currentGLViewport.width() + currentGLViewport.x(),
+ (finalRect.y() + 1) / 2 * currentGLViewport.height() + currentGLViewport.y(),
+ finalRect.width() * currentGLViewport.width() / 2,
+ finalRect.height() * currentGLViewport.height() / 2);
+}
+#endif // DEBUG_MATRIX
+} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
index 98d45b5..cfdccda 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
@@ -24,12 +24,18 @@
#include "IntRect.h"
#include "SkRect.h"
#include "TransformationMatrix.h"
+#include "private/hwui/DrawGlInfo.h"
#include <GLES2/gl2.h>
#define MAX_CONTRAST 5
+#define DEBUG_MATRIX 0
namespace WebCore {
+class DrawQuadData;
+class PureColorQuadData;
+class TextureQuadData;
+
enum ShaderType {
UndefinedShader = -1,
PureColor,
@@ -45,14 +51,14 @@ enum ShaderType {
struct ShaderHandles {
ShaderHandles()
- : alphaHandle(-1)
- , contrastHandle(-1)
- , positionHandle(-1)
- , programHandle(-1)
- , projMtxHandle(-1)
- , pureColorHandle(-1)
- , texSamplerHandle(-1)
- , videoMtxHandle(-1)
+ : alphaHandle(-1)
+ , contrastHandle(-1)
+ , positionHandle(-1)
+ , programHandle(-1)
+ , projMtxHandle(-1)
+ , pureColorHandle(-1)
+ , texSamplerHandle(-1)
+ , videoMtxHandle(-1)
{
}
@@ -82,16 +88,16 @@ struct ShaderHandles {
struct ShaderResource {
ShaderResource()
- : program(-1)
- , vertexShader(-1)
- , fragmentShader(-1)
+ : program(-1)
+ , vertexShader(-1)
+ , fragmentShader(-1)
{
};
ShaderResource(GLuint prog, GLuint vertex, GLuint fragment)
- : program(prog)
- , vertexShader(vertex)
- , fragmentShader(fragment)
+ : program(prog)
+ , vertexShader(vertex)
+ , fragmentShader(fragment)
{
};
@@ -118,14 +124,7 @@ public:
// Surface texture in GL_TEXTURE_EXTERNAL_OES target.
// 3) textureId == 0
// No texture needed, just a pureColor quad.
- void drawQuad(const SkRect& geometry, int textureId, float opacity, Color pureColor = Color(),
- GLenum textureTarget = GL_TEXTURE_2D,
- GLint texFilter = GL_LINEAR);
- void drawLayerQuad(const TransformationMatrix& drawMatrix,
- const SkRect& geometry, int textureId, float opacity,
- bool forceBlending = false,
- GLenum textureTarget = GL_TEXTURE_2D,
- Color pureColor = Color());
+ void drawQuad(const DrawQuadData* data);
void drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
float* textureMatrix, SkRect& geometry, int textureId);
FloatRect rectInScreenCoord(const TransformationMatrix& drawMatrix,
@@ -153,24 +152,15 @@ public:
contrast = MAX_CONTRAST;
m_contrast = contrast;
}
- void setWebViewMatrix(const float* matrix, bool alphaLayer);
-
- // This delta is the delta from the layout pos and the current animation pos.
- // Basically, in terms of layout, the webview is still in the original layout
- // pos, as without animation. Such that the viewport and visible rect etc are
- // still in that pos, too, except the clipping info.
- // Our rendering approach is after applying all the matrix, webView is
- // rendered as if it was at the original layout pos, but then offset the
- // glViewport to match the animation.
- void calculateAnimationDelta();
- int getAnimationDeltaX() { return m_animationDelta.x(); }
- int getAnimationDeltaY() { return m_animationDelta.y(); }
+ void setGLDrawInfo(const android::uirenderer::DrawGlInfo* info);
+
bool needsInit() { return m_needsInit; }
+ bool usePointSampling(float tileScale, const TransformationMatrix* layerTransform);
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
GLint createProgram(const char* vertexSource, const char* fragmentSource);
- void setProjectionMatrix(const SkRect& geometry, GLfloat* mtxPtr);
+ GLfloat* getTileProjectionMatrix(const DrawQuadData* data);
void setBlendingState(bool enableBlending);
void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
float opacity, GLenum textureTarget, GLenum filter,
@@ -178,10 +168,21 @@ private:
Color shaderColor(Color pureColor, float opacity);
ShaderType getTextureShaderType(GLenum textureTarget);
void resetBlending();
+ void setupSurfaceProjectionMatrix();
+#if DEBUG_MATRIX
+ FloatRect debugMatrixTransform(const TransformationMatrix& matrix, const char* matrixName);
+ void debugMatrixInfo(float currentScale,
+ const TransformationMatrix& clipProjectionMatrix,
+ const TransformationMatrix& webViewMatrix,
+ const TransformationMatrix& modifiedDrawMatrix,
+ const TransformationMatrix* layerMatrix);
+#endif // DEBUG_MATRIX
bool m_blendingEnabled;
- TransformationMatrix m_projectionMatrix;
+ TransformationMatrix m_surfaceProjectionMatrix;
+ TransformationMatrix m_clipProjectionMatrix;
+ TransformationMatrix m_visibleRectProjectionMatrix;
GLuint m_textureBuffer[1];
TransformationMatrix m_documentToScreenMatrix;
@@ -191,28 +192,20 @@ private:
FloatRect m_clipRect;
IntRect m_screenClip;
int m_titleBarHeight;
+ // This is the layout position in screen coordinate and didn't contain the
+ // animation offset.
IntRect m_webViewRect;
FloatRect m_documentViewport;
float m_contrast;
+ // The height of the render target, either FBO or screen.
+ int m_targetHeight;
bool m_alphaLayer;
TransformationMatrix m_webViewMatrix;
float m_currentScale;
- // After the webViewTranform, we need to reposition the rect to match our viewport.
- // Basically, the webViewTransformMatrix should apply on the screen resolution.
- // So we start by doing the scale and translate to get each tile into screen coordinates.
- // After applying the webViewTransformMatrix, b/c the way it currently set up
- // for scroll and titlebar, we need to offset both of them.
- // Finally, map everything back to (-1, 1) by using the m_projectionMatrix.
- // TODO: Given that m_webViewMatrix contains most of the tranformation
- // information, we should be able to get rid of some parameter we got from
- // Java side and simplify our code.
- TransformationMatrix m_repositionMatrix;
- IntPoint m_animationDelta;
-
// Put all the uniform location (handle) info into an array, and group them
// by the shader's type, this can help to clean up the interface.
// TODO: use the type and data comparison to skip GL call if possible.
@@ -226,6 +219,8 @@ private:
// (-1,1)
GLfloat m_transferProjMtx[16];
+ GLfloat m_tileProjMatrix[16];
+
Vector<ShaderResource> m_resources;
};
diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index f360919..a9ebd1e 100644
--- a/Source/WebCore/platform/graphics/android/LayerGroup.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -23,80 +23,83 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_TAG "LayerGroup"
+#define LOG_TAG "Surface"
#define LOG_NDEBUG 1
#include "config.h"
-#include "LayerGroup.h"
+#include "Surface.h"
#include "AndroidLog.h"
+#include "BaseLayerAndroid.h"
#include "ClassTracker.h"
#include "LayerAndroid.h"
-#include "TiledTexture.h"
+#include "GLWebViewState.h"
+#include "SkCanvas.h"
+#include "SurfaceBacking.h"
#include "TilesManager.h"
-// LayerGroups with an area larger than 2048*2048 should never be unclipped
+// Surfaces with an area larger than 2048*2048 should never be unclipped
#define MAX_UNCLIPPED_AREA 4194304
namespace WebCore {
-LayerGroup::LayerGroup()
- : m_dualTiledTexture(0)
+Surface::Surface()
+ : m_surfaceBacking(0)
, m_needsTexture(false)
, m_hasText(false)
{
#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("LayerGroup");
+ ClassTracker::instance()->increment("Surface");
#endif
}
-LayerGroup::~LayerGroup()
+Surface::~Surface()
{
for (unsigned int i = 0; i < m_layers.size(); i++)
SkSafeUnref(m_layers[i]);
- if (m_dualTiledTexture)
- SkSafeUnref(m_dualTiledTexture);
+ if (m_surfaceBacking)
+ SkSafeUnref(m_surfaceBacking);
#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("LayerGroup");
+ ClassTracker::instance()->decrement("Surface");
#endif
}
-bool LayerGroup::tryUpdateLayerGroup(LayerGroup* oldLayerGroup)
+bool Surface::tryUpdateSurface(Surface* oldSurface)
{
- if (!needsTexture() || !oldLayerGroup->needsTexture())
+ if (!needsTexture() || !oldSurface->needsTexture())
return false;
- // merge layer group based on first layer ID
- if (getFirstLayer()->uniqueId() != oldLayerGroup->getFirstLayer()->uniqueId())
+ // merge surfaces based on first layer ID
+ if (getFirstLayer()->uniqueId() != oldSurface->getFirstLayer()->uniqueId())
return false;
- m_dualTiledTexture = oldLayerGroup->m_dualTiledTexture;
- SkSafeRef(m_dualTiledTexture);
+ m_surfaceBacking = oldSurface->m_surfaceBacking;
+ SkSafeRef(m_surfaceBacking);
- ALOGV("%p taking old DTT %p from group %p, nt %d",
- this, m_dualTiledTexture, oldLayerGroup, oldLayerGroup->needsTexture());
+ ALOGV("%p taking old SurfBack %p from surface %p, nt %d",
+ this, m_surfaceBacking, oldSurface, oldSurface->needsTexture());
- if (!m_dualTiledTexture) {
- // no DTT to inval, so don't worry about it.
+ if (!m_surfaceBacking) {
+ // no SurfBack to inval, so don't worry about it.
return true;
}
- if (singleLayer() && oldLayerGroup->singleLayer()) {
+ if (singleLayer() && oldSurface->singleLayer()) {
// both are single matching layers, simply apply inval
SkRegion* layerInval = getFirstLayer()->getInvalRegion();
- m_dualTiledTexture->markAsDirty(*layerInval);
+ m_surfaceBacking->markAsDirty(*layerInval);
} else {
SkRegion invalRegion;
- bool fullInval = m_layers.size() != oldLayerGroup->m_layers.size();
+ bool fullInval = m_layers.size() != oldSurface->m_layers.size();
if (!fullInval) {
for (unsigned int i = 0; i < m_layers.size(); i++) {
- if (m_layers[i]->uniqueId() != oldLayerGroup->m_layers[i]->uniqueId()) {
+ if (m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId()) {
// layer list has changed, fully invalidate
// TODO: partially invalidate based on layer size/position
fullInval = true;
break;
} else if (!m_layers[i]->getInvalRegion()->isEmpty()) {
- // merge layer inval - translate the layer's inval region into group coordinates
+ // merge layer inval - translate the layer's inval region into surface coordinates
SkPoint pos = m_layers[i]->getPosition();
m_layers[i]->getInvalRegion()->translate(pos.fX, pos.fY);
invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op);
@@ -108,12 +111,12 @@ bool LayerGroup::tryUpdateLayerGroup(LayerGroup* oldLayerGroup)
if (fullInval)
invalRegion.setRect(-1e8, -1e8, 2e8, 2e8);
- m_dualTiledTexture->markAsDirty(invalRegion);
+ m_surfaceBacking->markAsDirty(invalRegion);
}
return true;
}
-void LayerGroup::addLayer(LayerAndroid* layer, const TransformationMatrix& transform)
+void Surface::addLayer(LayerAndroid* layer, const TransformationMatrix& transform)
{
m_layers.append(layer);
SkSafeRef(layer);
@@ -133,14 +136,17 @@ void LayerGroup::addLayer(LayerAndroid* layer, const TransformationMatrix& trans
m_unclippedArea = rect;
} else
m_unclippedArea.unite(rect);
- ALOGV("LG %p adding LA %p, size %d, %d %dx%d, now LG size %d,%d %dx%d",
+ ALOGV("Surf %p adding LA %p, size %d, %d %dx%d, now Surf size %d,%d %dx%d",
this, layer, rect.x(), rect.y(), rect.width(), rect.height(),
m_unclippedArea.x(), m_unclippedArea.y(),
m_unclippedArea.width(), m_unclippedArea.height());
}
+
+ if (isBase())
+ m_background = static_cast<BaseLayerAndroid*>(layer)->getBackgroundColor();
}
-IntRect LayerGroup::visibleArea()
+IntRect Surface::visibleArea()
{
if (singleLayer())
return getFirstLayer()->visibleArea();
@@ -156,78 +162,114 @@ IntRect LayerGroup::visibleArea()
return rect;
}
-void LayerGroup::prepareGL(bool layerTilesDisabled)
+IntRect Surface::unclippedArea()
+{
+ if (singleLayer())
+ return getFirstLayer()->unclippedArea();
+ return m_unclippedArea;
+}
+
+bool Surface::useAggressiveRendering()
+{
+ // When the background is semi-opaque, 0 < alpha < 255, we had to turn off
+ // low res to avoid artifacts from double drawing.
+ // TODO: avoid double drawing for low res tiles.
+ return isBase()
+ && (!m_background.alpha()
+ || !m_background.hasAlpha());
+}
+
+void Surface::prepareGL(bool layerTilesDisabled)
{
- if (!m_dualTiledTexture) {
- ALOGV("prepareGL on LG %p, no DTT, needsTexture? %d",
- this, m_dualTiledTexture, needsTexture());
+ bool tilesDisabled = layerTilesDisabled && !isBase();
+ if (!m_surfaceBacking) {
+ ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d",
+ this, m_surfaceBacking, needsTexture());
- if (needsTexture())
- m_dualTiledTexture = new DualTiledTexture();
- else
+ if (!needsTexture())
return;
+
+ m_surfaceBacking = new SurfaceBacking(isBase());
}
- if (layerTilesDisabled) {
- m_dualTiledTexture->discardTextures();
+ if (tilesDisabled) {
+ m_surfaceBacking->discardTextures();
} else {
bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors
IntRect prepareArea = computePrepareArea();
+ IntRect fullArea = unclippedArea();
- ALOGV("prepareGL on LG %p with DTT %p, %d layers",
- this, m_dualTiledTexture, m_layers.size());
- m_dualTiledTexture->prepareGL(getFirstLayer()->state(), allowZoom,
- prepareArea, this);
+ ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers",
+ this, m_surfaceBacking, m_layers.size());
+
+ m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom,
+ prepareArea, fullArea,
+ this, useAggressiveRendering());
}
}
-bool LayerGroup::drawGL(bool layerTilesDisabled)
+bool Surface::drawGL(bool layerTilesDisabled)
{
+ bool tilesDisabled = layerTilesDisabled && !isBase();
if (!getFirstLayer()->visible())
return false;
- FloatRect drawClip = getFirstLayer()->drawClip();
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip);
- TilesManager::instance()->shader()->clip(clippingRect);
+ if (!isBase()) {
+ // TODO: why are clipping regions wrong for base layer?
+ FloatRect drawClip = getFirstLayer()->drawClip();
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip);
+ TilesManager::instance()->shader()->clip(clippingRect);
+ }
bool askRedraw = false;
- if (m_dualTiledTexture && !layerTilesDisabled) {
- ALOGV("drawGL on LG %p with DTT %p", this, m_dualTiledTexture);
+ if (m_surfaceBacking && !tilesDisabled) {
+ ALOGV("drawGL on Surf %p with SurfBack %p", this, m_surfaceBacking);
+ // TODO: why this visibleArea is different from visibleRect at zooming for base?
IntRect drawArea = visibleArea();
- askRedraw |= m_dualTiledTexture->drawGL(drawArea, opacity(), drawTransform());
+ m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(),
+ useAggressiveRendering(), background());
}
// draw member layers (draws image textures, glextras)
for (unsigned int i = 0; i < m_layers.size(); i++)
- askRedraw |= m_layers[i]->drawGL(layerTilesDisabled);
+ askRedraw |= m_layers[i]->drawGL(tilesDisabled);
return askRedraw;
}
-void LayerGroup::swapTiles()
+void Surface::swapTiles()
{
- if (!m_dualTiledTexture)
+ if (!m_surfaceBacking)
return;
- m_dualTiledTexture->swapTiles();
+ m_surfaceBacking->swapTiles();
+}
+
+bool Surface::isReady()
+{
+ if (!m_surfaceBacking)
+ return true;
+
+ return m_surfaceBacking->isReady();
}
-bool LayerGroup::isReady()
+bool Surface::isMissingContent()
{
- if (!m_dualTiledTexture)
+ if (!m_surfaceBacking)
return true;
- return m_dualTiledTexture->isReady();
+ return m_surfaceBacking->isMissingContent();
}
-IntRect LayerGroup::computePrepareArea() {
+IntRect Surface::computePrepareArea() {
IntRect area;
if (!getFirstLayer()->contentIsScrollable()
+ && !isBase()
&& getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
- area = singleLayer() ? getFirstLayer()->unclippedArea() : m_unclippedArea;
+ area = unclippedArea();
double total = ((double) area.width()) * ((double) area.height());
if (total > MAX_UNCLIPPED_AREA)
@@ -239,18 +281,36 @@ IntRect LayerGroup::computePrepareArea() {
return area;
}
-void LayerGroup::computeTexturesAmount(TexturesResult* result)
+void Surface::computeTexturesAmount(TexturesResult* result)
{
- if (!m_dualTiledTexture)
+ if (!m_surfaceBacking || isBase())
return;
- m_dualTiledTexture->computeTexturesAmount(result, getFirstLayer());
+ m_surfaceBacking->computeTexturesAmount(result, getFirstLayer());
+}
+
+bool Surface::isBase()
+{
+ // base layer surface
+ // - doesn't use layer tiles (disables blending, doesn't compute textures amount)
+ // - ignores clip rects
+ // - only prepares clippedArea
+ return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer;
}
-bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas)
+bool Surface::paint(SkCanvas* canvas)
{
if (singleLayer()) {
getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers);
+
+ // TODO: double buffer by disabling SurfaceCollection swaps and position
+ // updates until painting complete
+
+ // In single surface mode, draw layer content onto the base layer
+ if (isBase()
+ && getFirstLayer()->countChildren()
+ && getFirstLayer()->state()->layersRenderingMode() > GLWebViewState::kClippedTextures)
+ getFirstLayer()->getChild(0)->drawCanvas(canvas, true, Layer::FlattenedLayers);
} else {
SkAutoCanvasRestore acr(canvas, true);
SkMatrix matrix;
@@ -270,18 +330,25 @@ bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas)
return true;
}
-float LayerGroup::opacity()
+float Surface::opacity()
{
if (singleLayer())
- return getFirstLayer()->getOpacity();
+ return getFirstLayer()->drawOpacity();
return 1.0;
}
-const TransformationMatrix* LayerGroup::drawTransform()
+Color* Surface::background()
+{
+ if (!isBase() || !m_background.isValid())
+ return 0;
+ return &m_background;
+}
+
+const TransformationMatrix* Surface::drawTransform()
{
- // single layer groups query the layer's draw transform, while multi-layer
- // groups copy the draw transform once, during initialization
- // TODO: support fixed multi-layer groups by querying the changing drawTransform
+ // single layer surfaces query the layer's draw transform, while multi-layer
+ // surfaces copy the draw transform once, during initialization
+ // TODO: support fixed multi-layer surfaces by querying the changing drawTransform
if (singleLayer())
return getFirstLayer()->drawTransform();
diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.h b/Source/WebCore/platform/graphics/android/rendering/Surface.h
index 90001a5..0fced47 100644
--- a/Source/WebCore/platform/graphics/android/LayerGroup.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.h
@@ -23,9 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LayerGroup_h
-#define LayerGroup_h
+#ifndef Surface_h
+#define Surface_h
+#include "Color.h"
#include "IntRect.h"
#include "TilePainter.h"
#include "Vector.h"
@@ -35,62 +36,70 @@ class SkRegion;
namespace WebCore {
-class BaseTile;
-class DualTiledTexture;
-class TexturesResult;
+class Tile;
+class SurfaceBacking;
class LayerAndroid;
+class TexturesResult;
-class LayerGroup : public TilePainter {
+class Surface : public TilePainter {
public:
- LayerGroup();
- virtual ~LayerGroup();
-
- bool tryUpdateLayerGroup(LayerGroup* oldLayerGroup);
+ Surface();
+ virtual ~Surface();
+ bool tryUpdateSurface(Surface* oldSurface);
void addLayer(LayerAndroid* layer, const TransformationMatrix& transform);
- IntRect visibleArea();
void prepareGL(bool layerTilesDisabled);
bool drawGL(bool layerTilesDisabled);
void swapTiles();
bool isReady();
+ bool isMissingContent();
- IntRect computePrepareArea();
void computeTexturesAmount(TexturesResult* result);
- LayerAndroid* getFirstLayer() { return m_layers[0]; }
- bool singleLayer() { return m_layers.size() == 1; }
+ LayerAndroid* getFirstLayer() const { return m_layers[0]; }
bool needsTexture() { return m_needsTexture; }
bool hasText() { return m_hasText; }
+ bool isBase();
// TilePainter methods
- virtual bool paint(BaseTile* tile, SkCanvas* canvas);
+ virtual bool paint(SkCanvas* canvas);
virtual float opacity();
+ virtual Color* background();
+
private:
+ IntRect computePrepareArea();
+ IntRect visibleArea();
+ IntRect unclippedArea();
+ bool singleLayer() { return m_layers.size() == 1; }
+ bool useAggressiveRendering();
+
const TransformationMatrix* drawTransform();
IntRect m_unclippedArea;
TransformationMatrix m_drawTransform;
- DualTiledTexture* m_dualTiledTexture;
+ SurfaceBacking* m_surfaceBacking;
bool m_needsTexture;
bool m_hasText;
Vector<LayerAndroid*> m_layers;
+
+ Color m_background;
};
class LayerMergeState {
public:
- LayerMergeState(Vector<LayerGroup*>* const allGroups)
- : groupList(allGroups)
- , currentLayerGroup(0)
+ LayerMergeState(Vector<Surface*>* const allGroups)
+ : surfaceList(allGroups)
+ , currentSurface(0)
, nonMergeNestedLevel(-1) // start at -1 to ignore first LayerAndroid's clipping
, depth(0)
{}
// vector storing all generated layer groups
- Vector<LayerGroup*>* const groupList;
+ Vector<Surface*>* const surfaceList;
// currently merging group. if cleared, no more layers may join
- LayerGroup* currentLayerGroup;
+ Surface* currentSurface;
// records depth within non-mergeable parents (clipping, fixed, scrolling)
// and disable merging therein.
@@ -102,4 +111,4 @@ public:
} // namespace WebCore
-#endif //#define LayerGroup_h
+#endif //#define Surface_h
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
new file mode 100644
index 0000000..f43472e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "SurfaceBacking"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "SurfaceBacking.h"
+
+#include "AndroidLog.h"
+#include "Color.h"
+#include "GLWebViewState.h"
+#include "LayerAndroid.h"
+
+#define LOW_RES_PREFETCH_SCALE_MODIFIER 0.3f
+
+namespace WebCore {
+
+SurfaceBacking::SurfaceBacking(bool isBaseSurface)
+{
+ m_frontTileGrid = new TileGrid(isBaseSurface);
+ m_backTileGrid = new TileGrid(isBaseSurface);
+ m_lowResTileGrid = new TileGrid(isBaseSurface);
+ m_scale = -1;
+ m_futureScale = -1;
+ m_zooming = false;
+}
+
+SurfaceBacking::~SurfaceBacking()
+{
+ delete m_frontTileGrid;
+ delete m_backTileGrid;
+ delete m_lowResTileGrid;
+}
+
+void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool aggressiveRendering)
+{
+ float scale = state->scale();
+ if (scale > 1 && !allowZoom)
+ scale = 1;
+
+ if (m_scale == -1) {
+ m_scale = scale;
+ m_futureScale = scale;
+ }
+
+ if (m_futureScale != scale) {
+ m_futureScale = scale;
+ m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay;
+ m_zooming = true;
+
+ // release back TileGrid's TileTextures, so they can be reused immediately
+ m_backTileGrid->discardTextures();
+ }
+
+ int prepareRegionFlags = TileGrid::StandardRegion;
+ if (aggressiveRendering)
+ prepareRegionFlags |= TileGrid::ExpandedRegion;
+
+ ALOGV("Prepare SurfBack %p, scale %.2f, m_scale %.2f, futScale: %.2f, zooming: %d, f %p, b %p",
+ this, scale, m_scale, m_futureScale, m_zooming,
+ m_frontTileGrid, m_backTileGrid);
+
+ if (m_zooming && (m_zoomUpdateTime < WTF::currentTime())) {
+ // prepare the visible portions of the back tile grid at the futureScale
+ m_backTileGrid->prepareGL(state, m_futureScale,
+ prepareArea, unclippedArea, painter,
+ TileGrid::StandardRegion, false);
+
+ if (m_backTileGrid->isReady()) {
+ // zooming completed, swap the TileGrids and new front tiles
+ swapTileGrids();
+
+ m_frontTileGrid->swapTiles();
+ m_backTileGrid->discardTextures();
+ m_lowResTileGrid->discardTextures();
+
+ m_scale = m_futureScale;
+ m_zooming = false;
+
+ // clear the StandardRegion flag, to prevent preparing it twice -
+ // the new frontTileGrid has already had its StandardRegion prepared
+ prepareRegionFlags &= ~TileGrid::StandardRegion;
+ }
+ }
+
+ if (!m_zooming) {
+ if (prepareRegionFlags) {
+ // if the front grid hasn't already prepared, or needs to prepare
+ // expanded bounds do so now
+ m_frontTileGrid->prepareGL(state, m_scale,
+ prepareArea, unclippedArea, painter, prepareRegionFlags, false);
+ }
+ if (aggressiveRendering) {
+ // prepare low res content
+ float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER;
+ m_lowResTileGrid->prepareGL(state, lowResPrefetchScale,
+ prepareArea, unclippedArea, painter,
+ TileGrid::StandardRegion | TileGrid::ExpandedRegion, true);
+ m_lowResTileGrid->swapTiles();
+ }
+ }
+}
+
+void SurfaceBacking::drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform,
+ bool aggressiveRendering, const Color* background)
+{
+ // draw low res prefetch page if zooming or front texture missing content
+ if (aggressiveRendering && isMissingContent())
+ m_lowResTileGrid->drawGL(visibleArea, opacity, transform);
+
+ m_frontTileGrid->drawGL(visibleArea, opacity, transform, background);
+}
+
+void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea)
+{
+ m_backTileGrid->markAsDirty(dirtyArea);
+ m_frontTileGrid->markAsDirty(dirtyArea);
+ m_lowResTileGrid->markAsDirty(dirtyArea);
+}
+
+void SurfaceBacking::swapTiles()
+{
+ m_backTileGrid->swapTiles();
+ m_frontTileGrid->swapTiles();
+ m_lowResTileGrid->swapTiles();
+}
+
+void SurfaceBacking::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer)
+{
+ // TODO: shouldn't use layer, as this SB may paint multiple layers
+ if (!layer)
+ return;
+
+ IntRect unclippedArea = layer->unclippedArea();
+ IntRect clippedVisibleArea = layer->visibleArea();
+
+ // get two numbers here:
+ // - textures needed for a clipped area
+ // - textures needed for an un-clipped area
+ TileGrid* tileGrid = m_zooming ? m_backTileGrid : m_frontTileGrid;
+ int nbTexturesUnclipped = tileGrid->nbTextures(unclippedArea, m_scale);
+ int nbTexturesClipped = tileGrid->nbTextures(clippedVisibleArea, m_scale);
+
+ // Set kFixedLayers level
+ if (layer->isPositionFixed())
+ result->fixed += nbTexturesClipped;
+
+ // Set kScrollableAndFixedLayers level
+ if (layer->contentIsScrollable()
+ || layer->isPositionFixed())
+ result->scrollable += nbTexturesClipped;
+
+ // Set kClippedTextures level
+ result->clipped += nbTexturesClipped;
+
+ // Set kAllTextures level
+ if (layer->contentIsScrollable())
+ result->full += nbTexturesClipped;
+ else
+ result->full += nbTexturesUnclipped;
+}
+
+void SurfaceBacking::swapTileGrids()
+{
+ TileGrid* temp = m_frontTileGrid;
+ m_frontTileGrid = m_backTileGrid;
+ m_backTileGrid = temp;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
new file mode 100644
index 0000000..61e3336
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SurfaceBacking_h
+#define SurfaceBacking_h
+
+#include "SkRefCnt.h"
+#include "TileGrid.h"
+
+namespace WebCore {
+
+class LayerAndroid;
+class TexturesResult;
+class TilePainter;
+
+class SurfaceBacking : public SkRefCnt {
+// TODO: investigate webkit threadsafe ref counting
+public:
+ SurfaceBacking(bool isBaseSurface);
+ ~SurfaceBacking();
+ void prepareGL(GLWebViewState* state, bool allowZoom,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool aggressiveRendering);
+ void swapTiles();
+ void drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform, bool aggressiveRendering,
+ const Color* background);
+ void markAsDirty(const SkRegion& dirtyArea);
+ void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer);
+ void discardTextures()
+ {
+ m_frontTileGrid->discardTextures();
+ m_backTileGrid->discardTextures();
+ }
+ bool isReady()
+ {
+ return !m_zooming && m_frontTileGrid->isReady() && m_scale > 0;
+ }
+
+ bool isMissingContent()
+ {
+ return m_zooming || m_frontTileGrid->isMissingContent();
+ }
+
+ int nbTextures(IntRect& area, float scale)
+ {
+ // TODO: consider the zooming case for the backTileGrid
+ if (!m_frontTileGrid)
+ return 0;
+ return m_frontTileGrid->nbTextures(area, scale);
+ }
+
+private:
+ void swapTileGrids();
+
+ // Delay before we schedule a new tile at the new scale factor
+ static const double s_zoomUpdateDelay = 0.2; // 200 ms
+
+ TileGrid* m_frontTileGrid;
+ TileGrid* m_backTileGrid;
+ TileGrid* m_lowResTileGrid;
+
+ float m_scale;
+ float m_futureScale;
+ double m_zoomUpdateTime;
+ bool m_zooming;
+};
+
+} // namespace WebCore
+
+#endif // SurfaceBacking_h
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
new file mode 100644
index 0000000..24e196b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "SurfaceCollection"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "SurfaceCollection.h"
+
+#include "AndroidLog.h"
+#include "BaseLayerAndroid.h"
+#include "ClassTracker.h"
+#include "GLWebViewState.h"
+#include "LayerAndroid.h"
+#include "Surface.h"
+#include "ScrollableLayerAndroid.h"
+#include "TilesManager.h"
+
+namespace WebCore {
+
+////////////////////////////////////////////////////////////////////////////////
+// TILED PAINTING / SURFACES //
+////////////////////////////////////////////////////////////////////////////////
+
+SurfaceCollection::SurfaceCollection(LayerAndroid* layer)
+ : m_compositedRoot(layer)
+{
+ // layer must be non-null.
+ SkSafeRef(m_compositedRoot);
+
+ // calculate draw transforms and z values
+ SkRect visibleRect = SkRect::MakeLTRB(0, 0, 1, 1);
+ m_compositedRoot->updateLayerPositions(visibleRect);
+ // TODO: updateGLPositionsAndScale?
+
+ // allocate surfaces for layers, merging where possible
+ ALOGV("new tree, allocating surfaces for tree %p", m_baseLayer);
+
+ LayerMergeState layerMergeState(&m_surfaces);
+ m_compositedRoot->assignSurfaces(&layerMergeState);
+
+ // set the layersurfaces' update count, to be drawn on painted tiles
+ unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates();
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ m_surfaces[i]->setUpdateCount(updateCount);
+
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->increment("SurfaceCollection");
+#endif
+}
+
+SurfaceCollection::~SurfaceCollection()
+{
+ SkSafeUnref(m_compositedRoot);
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ SkSafeUnref(m_surfaces[i]);
+ m_surfaces.clear();
+
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("SurfaceCollection");
+#endif
+}
+
+void SurfaceCollection::prepareGL(const SkRect& visibleRect)
+{
+ updateLayerPositions(visibleRect);
+ bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode()
+ > GLWebViewState::kClippedTextures;
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ m_surfaces[i]->prepareGL(layerTilesDisabled);
+}
+
+static inline bool compareSurfaceZ(const Surface* a, const Surface* b)
+{
+ const LayerAndroid* la = a->getFirstLayer();
+ const LayerAndroid* lb = b->getFirstLayer();
+
+ // swap drawing order if zValue suggests it AND the layers are in the same stacking context
+ return (la->zValue() > lb->zValue()) && (la->getParent() == lb->getParent());
+}
+
+bool SurfaceCollection::drawGL(const SkRect& visibleRect)
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->show();
+#endif
+
+ bool needsRedraw = false;
+ updateLayerPositions(visibleRect);
+ bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode()
+ > GLWebViewState::kClippedTextures;
+
+ // create a duplicate vector of surfaces, sorted by z value
+ Vector <Surface*> surfaces;
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ surfaces.append(m_surfaces[i]);
+ std::stable_sort(surfaces.begin()+1, surfaces.end(), compareSurfaceZ);
+
+ // draw the sorted vector
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ needsRedraw |= surfaces[i]->drawGL(layerTilesDisabled);
+
+ return needsRedraw;
+}
+
+Color SurfaceCollection::getBackgroundColor()
+{
+ return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor();
+}
+
+void SurfaceCollection::swapTiles()
+{
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ m_surfaces[i]->swapTiles();
+}
+
+bool SurfaceCollection::isReady()
+{
+ // Override layer readiness check for single surface mode
+ if (m_compositedRoot->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) {
+ // TODO: single surface mode should be properly double buffered
+ return true;
+ }
+
+ for (unsigned int i = 0; i < m_surfaces.size(); i++) {
+ if (!m_surfaces[i]->isReady()) {
+ ALOGV("layer surface %p isn't ready", m_surfaces[i]);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SurfaceCollection::isMissingBackgroundContent()
+{
+ if (!m_compositedRoot)
+ return true;
+
+ // return true when the first surface is missing content (indicating the
+ // entire viewport isn't covered)
+ return m_surfaces[0]->isMissingContent();
+}
+
+void SurfaceCollection::computeTexturesAmount(TexturesResult* result)
+{
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ m_surfaces[i]->computeTexturesAmount(result);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RECURSIVE ANIMATION / INVALS / LAYERS //
+////////////////////////////////////////////////////////////////////////////////
+
+void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface)
+{
+ if (!drawingSurface)
+ return;
+
+ for (unsigned int i = 0; i < m_surfaces.size(); i++) {
+ Surface* newSurface = m_surfaces[i];
+ if (!newSurface->needsTexture())
+ continue;
+
+ for (unsigned int j = 0; j < drawingSurface->m_surfaces.size(); j++) {
+ Surface* oldSurface = drawingSurface->m_surfaces[j];
+ if (newSurface->tryUpdateSurface(oldSurface))
+ break;
+ }
+ }
+}
+
+void SurfaceCollection::setIsDrawing()
+{
+ m_compositedRoot->initAnimations();
+}
+
+void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface)
+{
+ m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot);
+}
+
+void SurfaceCollection::evaluateAnimations(double currentTime)
+{
+ m_compositedRoot->evaluateAnimations(currentTime);
+}
+
+bool SurfaceCollection::hasCompositedLayers()
+{
+ return m_compositedRoot->countChildren();
+}
+
+bool SurfaceCollection::hasCompositedAnimations()
+{
+ return m_compositedRoot->hasAnimations();
+}
+
+void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y)
+{
+ LayerAndroid* layer = m_compositedRoot->findById(layerId);
+ if (layer && layer->contentIsScrollable())
+ static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
+}
+
+void SurfaceCollection::updateLayerPositions(const SkRect& visibleRect)
+{
+ TransformationMatrix ident;
+ m_compositedRoot->updateLayerPositions(visibleRect);
+ FloatRect clip(0, 0, 1e10, 1e10);
+ m_compositedRoot->updateGLPositionsAndScale(
+ ident, clip, 1, m_compositedRoot->state()->scale());
+
+#ifdef DEBUG
+ m_compositedRoot->showLayer(0);
+ ALOGV("We have %d layers, %d textured",
+ m_compositedRoot->nbLayers(),
+ m_compositedRoot->nbTexturedLayers());
+#endif
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
index 921929b..7dfe140 100644
--- a/Source/WebCore/platform/graphics/android/SurfaceCollection.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
@@ -26,33 +26,35 @@
#ifndef SurfaceCollection_h
#define SurfaceCollection_h
-#include "SkRefCnt.h"
+#include "Color.h"
#include "SkRect.h"
-#include "Vector.h"
+#include "SkRefCnt.h"
+
+#include <wtf/Vector.h>
class SkCanvas;
class SkRegion;
namespace WebCore {
-class BaseLayerAndroid;
class LayerAndroid;
-class LayerGroup;
+class Surface;
class TexturesResult;
class SurfaceCollection : public SkRefCnt {
// TODO: investigate webkit threadsafe ref counting
public:
- SurfaceCollection(BaseLayerAndroid* baseLayer);
+ SurfaceCollection(LayerAndroid* compositedRoot);
virtual ~SurfaceCollection();
// Tiled painting methods (executed on groups)
- void prepareGL(const SkRect& visibleRect, float scale, double currentTime);
- bool drawGL(const SkRect& visibleRect, float scale);
+ void prepareGL(const SkRect& visibleRect);
+ bool drawGL(const SkRect& visibleRect);
+ Color getBackgroundColor();
void swapTiles();
bool isReady();
+ bool isMissingBackgroundContent();
void computeTexturesAmount(TexturesResult* result);
- void drawCanvas(SkCanvas* canvas, bool drawLayers);
// Recursive tree methods (animations, invals, etc)
void setIsPainting(SurfaceCollection* drawingSurfaceCollection);
@@ -62,14 +64,12 @@ public:
bool hasCompositedLayers();
bool hasCompositedAnimations();
- int baseContentWidth();
- int baseContentHeight();
void updateScrollableLayer(int layerId, int x, int y);
private:
- BaseLayerAndroid* m_baseLayer;
+ void updateLayerPositions(const SkRect& visibleRect);
LayerAndroid* m_compositedRoot;
- Vector<LayerGroup*> m_layerGroups;
+ WTF::Vector<Surface*> m_surfaces;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
index 633651d..52a8e44 100644
--- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -30,16 +30,14 @@
#include "SurfaceCollectionManager.h"
#include "AndroidLog.h"
-#include "BaseLayerAndroid.h"
-#include "LayerGroup.h"
+#include "private/hwui/DrawGlInfo.h"
#include "TilesManager.h"
#include "SurfaceCollection.h"
namespace WebCore {
-SurfaceCollectionManager::SurfaceCollectionManager(GLWebViewState* state)
- : m_state(state)
- , m_drawingCollection(0)
+SurfaceCollectionManager::SurfaceCollectionManager()
+ : m_drawingCollection(0)
, m_paintingCollection(0)
, m_queuedCollection(0)
, m_fastSwapMode(false)
@@ -60,8 +58,6 @@ void SurfaceCollectionManager::swap()
// swap can't be called unless painting just finished
ASSERT(m_paintingCollection);
- android::Mutex::Autolock lock(m_paintSwapLock);
-
ALOGV("SWAPPING, D %p, P %p, Q %p",
m_drawingCollection, m_paintingCollection, m_queuedCollection);
@@ -91,8 +87,6 @@ void SurfaceCollectionManager::swap()
// clear all of the content in the three collections held by the collection manager
void SurfaceCollectionManager::clearCollections()
{
- ALOGV("SurfaceCollectionManager %p removing PS from state %p", this, m_state);
-
SkSafeUnref(m_drawingCollection);
m_drawingCollection = 0;
SkSafeUnref(m_paintingCollection);
@@ -107,15 +101,9 @@ void SurfaceCollectionManager::clearCollections()
bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* newCollection,
bool brandNew)
{
- ALOGV("updateWithSurfaceCollection - %p, has children %d, has animations %d",
- newCollection, newCollection->hasCompositedLayers(),
- newCollection->hasCompositedAnimations());
-
// can't have a queued collection unless have a painting collection too
ASSERT(m_paintingCollection || !m_queuedCollection);
- android::Mutex::Autolock lock(m_paintSwapLock);
-
if (!newCollection || brandNew) {
clearCollections();
if (brandNew) {
@@ -125,6 +113,10 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne
return false;
}
+ ALOGV("updateWithSurfaceCollection - %p, has children %d, has animations %d",
+ newCollection, newCollection->hasCompositedLayers(),
+ newCollection->hasCompositedAnimations());
+
if (m_queuedCollection || m_paintingCollection) {
// currently painting, so defer this new collection
if (m_queuedCollection) {
@@ -161,25 +153,25 @@ void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y)
m_drawingCollection->updateScrollableLayer(layerId, x, y);
}
-bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
+int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
bool enterFastSwapMode,
bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
- TexturesResult* texturesResultPtr)
+ TexturesResult* texturesResultPtr, bool shouldDraw)
{
m_fastSwapMode |= enterFastSwapMode;
- ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d",
- m_drawingCollection, m_paintingCollection, m_queuedCollection, m_fastSwapMode);
+ ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d shouldDraw %d",
+ m_drawingCollection, m_paintingCollection,
+ m_queuedCollection, m_fastSwapMode, shouldDraw);
- bool ret = false;
bool didCollectionSwap = false;
if (m_paintingCollection) {
ALOGV("preparing painting collection %p", m_paintingCollection);
m_paintingCollection->evaluateAnimations(currentTime);
- m_paintingCollection->prepareGL(visibleRect, scale, currentTime);
+ m_paintingCollection->prepareGL(visibleRect);
m_paintingCollection->computeTexturesAmount(texturesResultPtr);
if (!TilesManager::instance()->useDoubleBuffering() || m_paintingCollection->isReady()) {
@@ -194,10 +186,38 @@ bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
}
} else if (m_drawingCollection) {
ALOGV("preparing drawing collection %p", m_drawingCollection);
- m_drawingCollection->prepareGL(visibleRect, scale, currentTime);
+ m_drawingCollection->prepareGL(visibleRect);
m_drawingCollection->computeTexturesAmount(texturesResultPtr);
}
+ // ask for kStatusInvoke while painting, kStatusDraw if we have content to be redrawn next frame
+ // returning 0 indicates all painting complete, no framework inval needed.
+ int returnFlags = 0;
+
+ if (m_paintingCollection)
+ returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke;
+
+ if (!shouldDraw) {
+ if (didCollectionSwap
+ || (!m_paintingCollection
+ && m_drawingCollection
+ && m_drawingCollection->isReady())) {
+ // either a swap just occurred, or there is no more work to be done: do a full draw
+ m_drawingCollection->swapTiles();
+ returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
+ } else {
+ // current collection not ready - invoke functor in process mode
+ // until either drawing or painting collection is ready
+ returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke;
+ }
+
+ return returnFlags;
+ }
+
+ // ===========================================================================
+ // Don't have a drawing collection, draw white background
+ Color background = Color::white;
+ bool drawBackground = true;
if (m_drawingCollection) {
bool drawingReady = didCollectionSwap || m_drawingCollection->isReady();
@@ -213,60 +233,32 @@ bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
m_fastSwapMode = false;
} else {
// drawing isn't ready, must redraw
- ret = true;
+ returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke;
}
m_drawingCollection->evaluateAnimations(currentTime);
+
ALOGV("drawing collection %p", m_drawingCollection);
- ret |= m_drawingCollection->drawGL(visibleRect, scale);
- } else {
- // Dont have a drawing collection, draw white background
- Color defaultBackground = Color::white;
- m_state->drawBackground(defaultBackground);
+ background = m_drawingCollection->getBackgroundColor();
+ drawBackground = m_drawingCollection->isMissingBackgroundContent();
+ } else if (m_paintingCollection) {
+ // Use paintingCollection background color while tiles are not done painting.
+ background = m_paintingCollection->getBackgroundColor();
}
- if (m_paintingCollection) {
- ALOGV("still have painting collection %p", m_paintingCollection);
- return true;
+ // Start doing the actual GL drawing.
+ if (drawBackground) {
+ ALOGV("background is %x", background.rgb());
+ // If background is opaque, we can safely and efficiently clear it here.
+ // Otherwise, we have to calculate all the missing tiles and blend the background.
+ GLUtils::clearBackgroundIfOpaque(&background);
}
- return ret;
-}
-
-// draw for base tile - called on TextureGeneration thread
-void SurfaceCollectionManager::drawCanvas(SkCanvas* canvas, bool drawLayers)
-{
- SurfaceCollection* paintingCollection = 0;
- m_paintSwapLock.lock();
- paintingCollection = m_paintingCollection ? m_paintingCollection : m_drawingCollection;
- SkSafeRef(paintingCollection);
- m_paintSwapLock.unlock();
-
- if (!paintingCollection)
- return;
-
- paintingCollection->drawCanvas(canvas, drawLayers);
+ if (m_drawingCollection && m_drawingCollection->drawGL(visibleRect))
+ returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
- SkSafeUnref(paintingCollection);
-}
-
-// TODO: refactor this functionality elsewhere
-int SurfaceCollectionManager::baseContentWidth()
-{
- if (m_paintingCollection)
- return m_paintingCollection->baseContentWidth();
- else if (m_drawingCollection)
- return m_drawingCollection->baseContentWidth();
- return 0;
-}
-
-int SurfaceCollectionManager::baseContentHeight()
-{
- if (m_paintingCollection)
- return m_paintingCollection->baseContentHeight();
- else if (m_drawingCollection)
- return m_drawingCollection->baseContentHeight();
- return 0;
+ ALOGV("returnFlags %d, m_paintingCollection %d ", returnFlags, m_paintingCollection);
+ return returnFlags;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
index 76e5e9e..125bf02 100644
--- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
@@ -41,7 +41,7 @@ class SurfaceCollection;
class TEST_EXPORT SurfaceCollectionManager {
public:
- SurfaceCollectionManager(GLWebViewState* state);
+ SurfaceCollectionManager();
~SurfaceCollectionManager();
@@ -49,24 +49,15 @@ public:
void updateScrollableLayer(int layerId, int x, int y);
- bool drawGL(double currentTime, IntRect& viewRect,
+ int drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
- TexturesResult* texturesResultPtr);
-
- void drawCanvas(SkCanvas* canvas, bool drawLayers);
-
- int baseContentWidth();
- int baseContentHeight();
+ TexturesResult* texturesResultPtr, bool shouldDraw);
private:
void swap();
void clearCollections();
- android::Mutex m_paintSwapLock;
-
- GLWebViewState* m_state;
-
SurfaceCollection* m_drawingCollection;
SurfaceCollection* m_paintingCollection;
SurfaceCollection* m_queuedCollection;
diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.cpp b/Source/WebCore/platform/graphics/android/rendering/TextureInfo.cpp
index f5c8b02..f5c8b02 100644
--- a/Source/WebCore/platform/graphics/android/TextureInfo.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TextureInfo.cpp
diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.h b/Source/WebCore/platform/graphics/android/rendering/TextureInfo.h
index 4684df2..7d182c3 100644
--- a/Source/WebCore/platform/graphics/android/TextureInfo.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TextureInfo.h
@@ -31,7 +31,6 @@
#include <jni.h>
#include <ui/GraphicBuffer.h>
#include <utils/RefBase.h>
-#include "BaseTile.h"
using android::sp;
namespace android {
diff --git a/Source/WebCore/platform/graphics/android/TextureOwner.h b/Source/WebCore/platform/graphics/android/rendering/TextureOwner.h
index 5434dbf..b12d8b7 100644
--- a/Source/WebCore/platform/graphics/android/TextureOwner.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TextureOwner.h
@@ -31,17 +31,13 @@ class Layer;
namespace WebCore {
-class TiledPage;
-class BaseTileTexture;
+class TileTexture;
class GLWebViewState;
class TextureOwner {
public:
virtual ~TextureOwner() { }
- virtual bool removeTexture(BaseTileTexture* texture) = 0;
- virtual TiledPage* page() = 0;
- virtual GLWebViewState* state() = 0;
- virtual bool samePageAs(Layer* root) { return false; }
+ virtual bool removeTexture(TileTexture* texture) = 0;
virtual bool isRepaintPending() = 0;
virtual unsigned long long drawCount() = 0;
};
diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
index 81a404f..f884e52 100644
--- a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
@@ -35,6 +35,7 @@
#include "GLUtils.h"
#include "PaintTileOperation.h"
#include "TilesManager.h"
+#include "TransferQueue.h"
namespace WebCore {
@@ -47,21 +48,6 @@ void TexturesGenerator::scheduleOperation(QueuedOperation* operation)
mRequestedOperationsCond.signal();
}
-void TexturesGenerator::removeOperationsForPage(TiledPage* page)
-{
- removeOperationsForFilter(new PageFilter(page));
-}
-
-void TexturesGenerator::removePaintOperationsForPage(TiledPage* page, bool waitForRunning)
-{
- removeOperationsForFilter(new PageFilter(page), waitForRunning);
-}
-
-void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
-{
- removeOperationsForFilter(filter, true);
-}
-
void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning)
{
if (!filter)
@@ -91,7 +77,7 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool
// The solution is use this as a flag to tell Tex Gen thread that
// UI thread is waiting now, Tex Gen thread should not wait for the
// queue any more.
- TilesManager::instance()->transferQueue()->interruptTransferQueue(true);
+ m_tilesManager->transferQueue()->interruptTransferQueue(true);
}
delete filter;
@@ -109,7 +95,6 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool
status_t TexturesGenerator::readyToRun()
{
- TilesManager::instance()->markGeneratorAsReady();
ALOGV("Thread ready to run");
return NO_ERROR;
}
@@ -180,7 +165,7 @@ bool TexturesGenerator::threadLoop()
stop = true;
if (m_waitForCompletion) {
m_waitForCompletion = false;
- TilesManager::instance()->transferQueue()->interruptTransferQueue(false);
+ m_tilesManager->transferQueue()->interruptTransferQueue(false);
mRequestedOperationsCond.signal();
}
mRequestedOperationsLock.unlock();
diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.h b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h
index 2e3b6b4..08f69ae 100644
--- a/Source/WebCore/platform/graphics/android/TexturesGenerator.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h
@@ -29,40 +29,39 @@
#if USE(ACCELERATED_COMPOSITING)
#include "QueuedOperation.h"
-#include "TiledPage.h"
#include "TilePainter.h"
+#include <wtf/Vector.h>
+
#include <utils/threads.h>
namespace WebCore {
using namespace android;
-class BaseLayerAndroid;
-class LayerAndroid;
+class TilesManager;
class TexturesGenerator : public Thread {
public:
- TexturesGenerator() : Thread(false)
+ TexturesGenerator(TilesManager* instance) : Thread(false)
, m_waitForCompletion(false)
- , m_currentOperation(0) { }
+ , m_currentOperation(0)
+ , m_tilesManager(instance) { }
virtual ~TexturesGenerator() { }
virtual status_t readyToRun();
- void removeOperationsForPage(TiledPage* page);
- void removePaintOperationsForPage(TiledPage* page, bool waitForRunning);
- void removeOperationsForFilter(OperationFilter* filter);
- void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning);
+ void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning = true);
void scheduleOperation(QueuedOperation* operation);
private:
QueuedOperation* popNext();
virtual bool threadLoop();
- Vector<QueuedOperation*> mRequestedOperations;
+ WTF::Vector<QueuedOperation*> mRequestedOperations;
android::Mutex mRequestedOperationsLock;
android::Condition mRequestedOperationsCond;
bool m_waitForCompletion;
QueuedOperation* m_currentOperation;
+ TilesManager* m_tilesManager;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
index d15feeb..f2aa9a0 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
@@ -23,11 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_TAG "BaseTile"
+#define LOG_TAG "Tile"
#define LOG_NDEBUG 1
#include "config.h"
-#include "BaseTile.h"
+#include "Tile.h"
#if USE(ACCELERATED_COMPOSITING)
@@ -35,6 +35,7 @@
#include "GLUtils.h"
#include "RasterRenderer.h"
#include "TextureInfo.h"
+#include "TileTexture.h"
#include "TilesManager.h"
// If the dirty portion of a tile exceeds this ratio, fully repaint.
@@ -46,29 +47,26 @@
namespace WebCore {
-BaseTile::BaseTile(bool isLayerTile)
- : m_glWebViewState(0)
- , m_x(-1)
+Tile::Tile(bool isLayerTile)
+ : m_x(-1)
, m_y(-1)
- , m_page(0)
, m_frontTexture(0)
, m_backTexture(0)
, m_scale(1)
, m_dirty(true)
, m_repaintPending(false)
, m_fullRepaint(true)
- , m_isTexturePainted(false)
, m_isLayerTile(isLayerTile)
, m_drawCount(0)
, m_state(Unpainted)
{
#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("BaseTile");
+ ClassTracker::instance()->increment("Tile");
#endif
m_renderer = BaseRenderer::createRenderer();
}
-BaseTile::~BaseTile()
+Tile::~Tile()
{
if (m_backTexture)
m_backTexture->release(this);
@@ -78,13 +76,13 @@ BaseTile::~BaseTile()
delete m_renderer;
#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("BaseTile");
+ ClassTracker::instance()->decrement("Tile");
#endif
}
// All the following functions must be called from the main GL thread.
-void BaseTile::setContents(int x, int y, float scale)
+void Tile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile)
{
// TODO: investigate whether below check/discard is necessary
if ((m_x != x)
@@ -99,11 +97,13 @@ void BaseTile::setContents(int x, int y, float scale)
m_y = y;
m_scale = scale;
m_drawCount = TilesManager::instance()->getDrawGLCount();
+ if (isExpandedPrefetchTile)
+ m_drawCount--; // deprioritize expanded painting region
}
-void BaseTile::reserveTexture()
+void Tile::reserveTexture()
{
- BaseTileTexture* texture = TilesManager::instance()->getAvailableTexture(this);
+ TileTexture* texture = TilesManager::instance()->getAvailableTexture(this);
android::AutoMutex lock(m_atomicSync);
if (texture && m_backTexture != texture) {
@@ -120,10 +120,10 @@ void BaseTile::reserveTexture()
}
}
-bool BaseTile::removeTexture(BaseTileTexture* texture)
+bool Tile::removeTexture(TileTexture* texture)
{
- ALOGV("%p removeTexture %p, back %p front %p... page %p",
- this, texture, m_backTexture, m_frontTexture, m_page);
+ ALOGV("%p removeTexture %p, back %p front %p",
+ this, texture, m_backTexture, m_frontTexture);
// We update atomically, so paintBitmap() can see the correct value
android::AutoMutex lock(m_atomicSync);
if (m_frontTexture == texture) {
@@ -146,7 +146,7 @@ bool BaseTile::removeTexture(BaseTileTexture* texture)
return true;
}
-void BaseTile::markAsDirty(const SkRegion& dirtyArea)
+void Tile::markAsDirty(const SkRegion& dirtyArea)
{
if (dirtyArea.isEmpty())
return;
@@ -156,17 +156,11 @@ void BaseTile::markAsDirty(const SkRegion& dirtyArea)
// Check if we actually intersect with the area
bool intersect = false;
SkRegion::Iterator cliperator(dirtyArea);
- int tileWidth = TilesManager::instance()->tileWidth();
- int tileHeight = TilesManager::instance()->tileHeight();
- if (m_isLayerTile) {
- tileWidth = TilesManager::instance()->layerTileWidth();
- tileHeight = TilesManager::instance()->layerTileHeight();
- }
SkRect realTileRect;
SkRect dirtyRect;
while (!cliperator.done()) {
dirtyRect.set(cliperator.rect());
- if (intersectWithRect(m_x, m_y, tileWidth, tileHeight,
+ if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(),
m_scale, dirtyRect, realTileRect)) {
intersect = true;
break;
@@ -186,8 +180,8 @@ void BaseTile::markAsDirty(const SkRegion& dirtyArea)
} else if (m_state != Unpainted) {
// TODO: fix it so that they can paint while deferring the markAsDirty
// call (or block updates)
- ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d, page %p",
- this, m_x, m_y, isLayerTile(), m_state, m_page);
+ ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d",
+ this, m_x, m_y, isLayerTile(), m_state);
// prefetch tiles can be marked dirty while in the process of painting,
// due to not using an update lock. force them to fail validate step.
@@ -195,51 +189,46 @@ void BaseTile::markAsDirty(const SkRegion& dirtyArea)
}
}
-bool BaseTile::isDirty()
+bool Tile::isDirty()
{
android::AutoMutex lock(m_atomicSync);
return m_dirty;
}
-bool BaseTile::isRepaintPending()
+bool Tile::isRepaintPending()
{
android::AutoMutex lock(m_atomicSync);
return m_repaintPending;
}
-void BaseTile::setRepaintPending(bool pending)
+void Tile::setRepaintPending(bool pending)
{
android::AutoMutex lock(m_atomicSync);
m_repaintPending = pending;
}
-void BaseTile::drawGL(float opacity, const SkRect& rect, float scale,
- const TransformationMatrix* transform)
+bool Tile::drawGL(float opacity, const SkRect& rect, float scale,
+ const TransformationMatrix* transform,
+ bool forceBlending, bool usePointSampling)
{
if (m_x < 0 || m_y < 0 || m_scale != scale)
- return;
+ return false;
// No need to mutex protect reads of m_backTexture as it is only written to by
// the consumer thread.
if (!m_frontTexture)
- return;
-
- // Early return if set to un-usable in purpose!
- m_atomicSync.lock();
- bool isTexturePainted = m_isTexturePainted;
- m_atomicSync.unlock();
-
- if (!isTexturePainted)
- return;
+ return false;
- m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform);
+ m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform,
+ forceBlending, usePointSampling);
+ return true;
}
-bool BaseTile::isTileReady()
+bool Tile::isTileReady()
{
// Return true if the tile's most recently drawn texture is up to date
android::AutoMutex lock(m_atomicSync);
- BaseTileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture;
+ TileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture;
if (!texture)
return false;
@@ -256,9 +245,9 @@ bool BaseTile::isTileReady()
return true;
}
-bool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
- float scale, const SkRect& dirtyRect,
- SkRect& realTileRect)
+bool Tile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
+ float scale, const SkRect& dirtyRect,
+ SkRect& realTileRect)
{
// compute the rect to corresponds to pixels
realTileRect.fLeft = x * tileWidth;
@@ -276,7 +265,7 @@ bool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
return true;
}
-bool BaseTile::isTileVisible(const IntRect& viewTileBounds)
+bool Tile::isTileVisible(const IntRect& viewTileBounds)
{
return (m_x >= viewTileBounds.x()
&& m_x < viewTileBounds.x() + viewTileBounds.width()
@@ -285,14 +274,14 @@ bool BaseTile::isTileVisible(const IntRect& viewTileBounds)
}
// This is called from the texture generation thread
-void BaseTile::paintBitmap(TilePainter* painter)
+void Tile::paintBitmap(TilePainter* painter)
{
// We acquire the values below atomically. This ensures that we are reading
// values correctly across cores. Further, once we have these values they
// can be updated by other threads without consequence.
m_atomicSync.lock();
bool dirty = m_dirty;
- BaseTileTexture* texture = m_backTexture;
+ TileTexture* texture = m_backTexture;
SkRegion dirtyArea = m_dirtyArea;
float scale = m_scale;
const int x = m_x;
@@ -311,7 +300,7 @@ void BaseTile::paintBitmap(TilePainter* painter)
m_atomicSync.unlock();
// at this point we can safely check the ownership (if the texture got
- // transferred to another BaseTile under us)
+ // transferred to another Tile under us)
if (texture->owner() != this) {
return;
}
@@ -391,7 +380,6 @@ void BaseTile::paintBitmap(TilePainter* painter)
if (!fullRepaint) {
renderInfo.invalRect = &totalRect;
- renderInfo.measurePerf = false;
m_renderer->renderTiledContent(renderInfo);
}
}
@@ -399,15 +387,12 @@ void BaseTile::paintBitmap(TilePainter* painter)
// Do a full repaint if needed
if (fullRepaint) {
renderInfo.invalRect = 0;
- renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator();
m_renderer->renderTiledContent(renderInfo);
}
m_atomicSync.lock();
if (texture == m_backTexture) {
- m_isTexturePainted = true;
-
// set the fullrepaint flags
m_fullRepaint = false;
@@ -437,7 +422,7 @@ void BaseTile::paintBitmap(TilePainter* painter)
m_atomicSync.unlock();
}
-void BaseTile::discardTextures() {
+void Tile::discardTextures() {
android::AutoMutex lock(m_atomicSync);
ALOGV("%p discarding bt %p, ft %p",
this, m_backTexture, m_frontTexture);
@@ -456,7 +441,7 @@ void BaseTile::discardTextures() {
m_state = Unpainted;
}
-void BaseTile::discardBackTexture() {
+void Tile::discardBackTexture() {
android::AutoMutex lock(m_atomicSync);
if (m_backTexture) {
m_backTexture->release(this);
@@ -466,7 +451,7 @@ void BaseTile::discardBackTexture() {
m_dirty = true;
}
-bool BaseTile::swapTexturesIfNeeded() {
+bool Tile::swapTexturesIfNeeded() {
android::AutoMutex lock(m_atomicSync);
if (m_state == ReadyToSwap) {
// discard old texture and swap the new one in its place
@@ -484,7 +469,7 @@ bool BaseTile::swapTexturesIfNeeded() {
return false;
}
-void BaseTile::backTextureTransfer() {
+void Tile::backTextureTransfer() {
android::AutoMutex lock(m_atomicSync);
if (m_state == PaintingStarted)
m_state = TransferredUnvalidated;
@@ -497,7 +482,7 @@ void BaseTile::backTextureTransfer() {
}
}
-void BaseTile::backTextureTransferFail() {
+void Tile::backTextureTransferFail() {
// transfer failed for some reason, mark dirty so it will (repaint and) be
// retransferred.
android::AutoMutex lock(m_atomicSync);
@@ -506,7 +491,7 @@ void BaseTile::backTextureTransferFail() {
// whether validatePaint is called before or after, it won't do anything
}
-void BaseTile::validatePaint() {
+void Tile::validatePaint() {
// ONLY CALL while m_atomicSync is locked (at the end of paintBitmap())
if (!m_dirty) {
@@ -527,11 +512,6 @@ void BaseTile::validatePaint() {
// paintBitmap() may have cleared m_dirty)
m_dirty = true;
}
-
- if (m_deferredDirty) {
- ALOGV("Note: deferred dirty flag set, possibly a missed paint on tile %p", this);
- m_deferredDirty = false;
- }
} else {
ALOGV("Note: paint was unsuccessful.");
m_state = Unpainted;
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h
index ab16dc9..fa06892 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef BaseTile_h
-#define BaseTile_h
+#ifndef Tile_h
+#define Tile_h
#if USE(ACCELERATED_COMPOSITING)
@@ -39,8 +39,7 @@
namespace WebCore {
class TextureInfo;
-class TiledPage;
-class BaseTileTexture;
+class TileTexture;
class GLWebViewState;
/**
@@ -59,7 +58,7 @@ class GLWebViewState;
* 5. The tile is destroyed when the user navigates to a new page.
*
*/
-class BaseTile : public TextureOwner {
+class Tile : public TextureOwner {
public:
// eventually, m_dirty might be rolled into the state machine, but note
@@ -89,20 +88,21 @@ public:
UpToDate = 5,
};
- BaseTile(bool isLayerTile = false);
- ~BaseTile();
+ Tile(bool isLayerTile = false);
+ ~Tile();
bool isLayerTile() { return m_isLayerTile; }
- void setContents(int x, int y, float scale);
- void setPage(TiledPage* page) { m_page = page; }
+ void setContents(int x, int y, float scale, bool isExpandedPrefetchTile);
void reserveTexture();
bool isTileReady();
- void drawGL(float opacity, const SkRect& rect, float scale,
- const TransformationMatrix* transform);
+ // Return false when real draw didn't happen for any reason.
+ bool drawGL(float opacity, const SkRect& rect, float scale,
+ const TransformationMatrix* transform,
+ bool forceBlending = false, bool usePointSampling = false);
// the only thread-safe function called by the background thread
void paintBitmap(TilePainter* painter);
@@ -114,15 +114,15 @@ public:
void markAsDirty(const SkRegion& dirtyArea);
bool isDirty();
- bool isRepaintPending();
+ virtual bool isRepaintPending();
void setRepaintPending(bool pending);
float scale() const { return m_scale; }
TextureState textureState() const { return m_state; }
int x() const { return m_x; }
int y() const { return m_y; }
- BaseTileTexture* frontTexture() { return m_frontTexture; }
- BaseTileTexture* backTexture() { return m_backTexture; }
+ TileTexture* frontTexture() { return m_frontTexture; }
+ TileTexture* backTexture() { return m_backTexture; }
// only used for prioritization - the higher, the more relevant the tile is
unsigned long long drawCount() { return m_drawCount; }
@@ -132,36 +132,25 @@ public:
void backTextureTransfer();
void backTextureTransferFail();
- void setGLWebViewState(GLWebViewState* state) { m_glWebViewState = state; }
-
// TextureOwner implementation
- virtual bool removeTexture(BaseTileTexture* texture);
- virtual TiledPage* page() { return m_page; }
- virtual GLWebViewState* state() { return m_glWebViewState; }
+ virtual bool removeTexture(TileTexture* texture);
private:
void validatePaint();
- GLWebViewState* m_glWebViewState;
-
int m_x;
int m_y;
- TiledPage* m_page;
-
// The remaining variables can be updated throughout the lifetime of the object
- BaseTileTexture* m_frontTexture;
- BaseTileTexture* m_backTexture;
+ TileTexture* m_frontTexture;
+ TileTexture* m_backTexture;
float m_scale;
// used to signal that the that the tile is out-of-date and needs to be
// redrawn in the backTexture
bool m_dirty;
- // currently only for debugging, to be used for tracking down dropped repaints
- bool m_deferredDirty;
-
// used to signal that a repaint is pending
bool m_repaintPending;
@@ -169,9 +158,6 @@ private:
SkRegion m_dirtyArea;
bool m_fullRepaint;
- // flag used to know if we have a texture that was painted at least once
- bool m_isTexturePainted;
-
// This mutex serves two purposes. (1) It ensures that certain operations
// happen atomically and (2) it makes sure those operations are synchronized
// across all threads and cores.
@@ -199,4 +185,4 @@ private:
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
-#endif // BaseTile_h
+#endif // Tile_h
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
new file mode 100644
index 0000000..e3aa2a9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "TileGrid"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "TileGrid.h"
+
+#include "AndroidLog.h"
+#include "DrawQuadData.h"
+#include "GLWebViewState.h"
+#include "PaintTileOperation.h"
+#include "Tile.h"
+#include "TilesManager.h"
+
+#include <wtf/CurrentTime.h>
+
+#define EXPANDED_BOUNDS_INFLATE 1
+#define EXPANDED_PREFETCH_BOUNDS_Y_INFLATE 1
+
+namespace WebCore {
+
+TileGrid::TileGrid(bool isBaseSurface)
+ : m_prevTileY(0)
+ , m_scale(1)
+ , m_isBaseSurface(isBaseSurface)
+{
+ m_dirtyRegion.setEmpty();
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->increment("TileGrid");
+#endif
+}
+
+TileGrid::~TileGrid()
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("TileGrid");
+#endif
+ removeTiles();
+}
+
+bool TileGrid::isReady()
+{
+ bool tilesAllReady = true;
+ bool tilesVisible = false;
+ for (unsigned int i = 0; i < m_tiles.size(); i++) {
+ Tile* tile = m_tiles[i];
+ if (tile->isTileVisible(m_area)) {
+ tilesVisible = true;
+ if (!tile->isTileReady()) {
+ tilesAllReady = false;
+ break;
+ }
+ }
+ }
+ // For now, if no textures are available, consider ourselves as ready
+ // in order to unblock the zooming process.
+ // FIXME: have a better system -- maybe keeping the last scale factor
+ // able to fully render everything
+ ALOGV("TG %p, ready %d, visible %d, texturesRemain %d",
+ this, tilesAllReady, tilesVisible,
+ TilesManager::instance()->layerTexturesRemain());
+
+ return !TilesManager::instance()->layerTexturesRemain()
+ || !tilesVisible || tilesAllReady;
+}
+
+bool TileGrid::isMissingContent()
+{
+ for (unsigned int i = 0; i < m_tiles.size(); i++)
+ if (m_tiles[i]->isTileVisible(m_area) && !m_tiles[i]->frontTexture())
+ return true;
+ return false;
+}
+
+void TileGrid::swapTiles()
+{
+ int swaps = 0;
+ for (unsigned int i = 0; i < m_tiles.size(); i++)
+ if (m_tiles[i]->swapTexturesIfNeeded())
+ swaps++;
+ ALOGV("TG %p swapping, swaps = %d", this, swaps);
+}
+
+IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale)
+{
+ IntRect computedArea;
+ IntRect area(contentArea.x() * scale,
+ contentArea.y() * scale,
+ ceilf(contentArea.width() * scale),
+ ceilf(contentArea.height() * scale));
+
+ ALOGV("TG %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height());
+
+ if (area.width() == 0 && area.height() == 0) {
+ computedArea.setWidth(0);
+ computedArea.setHeight(0);
+ return computedArea;
+ }
+
+ int tileWidth = TilesManager::tileWidth();
+ int tileHeight = TilesManager::tileHeight();
+
+ computedArea.setX(area.x() / tileWidth);
+ computedArea.setY(area.y() / tileHeight);
+ float right = (area.x() + area.width()) / (float) tileWidth;
+ float bottom = (area.y() + area.height()) / (float) tileHeight;
+ computedArea.setWidth(ceilf(right) - computedArea.x());
+ computedArea.setHeight(ceilf(bottom) - computedArea.y());
+ return computedArea;
+}
+
+void TileGrid::prepareGL(GLWebViewState* state, float scale,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, int regionFlags, bool isLowResPrefetch)
+{
+ // first, how many tiles do we need
+ m_area = computeTilesArea(prepareArea, scale);
+ if (m_area.isEmpty())
+ return;
+
+ ALOGV("prepare TileGrid %p with scale %.2f, prepareArea "
+ " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
+ this, scale,
+ prepareArea.x(), prepareArea.y(),
+ prepareArea.width(), prepareArea.height(),
+ m_area.x(), m_area.y(),
+ m_area.width(), m_area.height());
+
+ bool goingDown = m_prevTileY < m_area.y();
+ m_prevTileY = m_area.y();
+
+ TilesManager* tilesManager = TilesManager::instance();
+ if (scale != m_scale)
+ tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale));
+
+ m_scale = scale;
+
+ // apply dirty region to affected tiles
+ if (!m_dirtyRegion.isEmpty()) {
+ for (unsigned int i = 0; i < m_tiles.size(); i++)
+ m_tiles[i]->markAsDirty(m_dirtyRegion);
+
+ // log inval region for the base surface
+ if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) {
+ SkRegion::Iterator iterator(m_dirtyRegion);
+ while (!iterator.done()) {
+ SkIRect r = iterator.rect();
+ tilesManager->getProfiler()->nextInval(r, scale);
+ iterator.next();
+ }
+ }
+ m_dirtyRegion.setEmpty();
+ }
+
+ if (regionFlags & StandardRegion) {
+ for (int i = 0; i < m_area.width(); i++) {
+ if (goingDown) {
+ for (int j = 0; j < m_area.height(); j++)
+ prepareTile(m_area.x() + i, m_area.y() + j,
+ painter, state, isLowResPrefetch, false);
+ } else {
+ for (int j = m_area.height() - 1; j >= 0; j--)
+ prepareTile(m_area.x() + i, m_area.y() + j,
+ painter, state, isLowResPrefetch, false);
+ }
+ }
+ }
+
+ if (regionFlags & ExpandedRegion) {
+ IntRect fullArea = computeTilesArea(unclippedArea, scale);
+ IntRect expandedArea = m_area;
+
+ // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds
+ if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory())
+ expandedArea.inflate(EXPANDED_BOUNDS_INFLATE);
+
+ if (isLowResPrefetch)
+ expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE);
+
+ // clip painting area to content
+ expandedArea.intersect(fullArea);
+
+ for (int i = expandedArea.x(); i < expandedArea.maxX(); i++)
+ for (int j = expandedArea.y(); j < expandedArea.maxY(); j++)
+ if (!m_area.contains(i, j))
+ prepareTile(i, j, painter, state, isLowResPrefetch, true);
+ }
+}
+
+void TileGrid::markAsDirty(const SkRegion& invalRegion)
+{
+ ALOGV("TG %p markAsDirty, current region empty %d, new empty %d",
+ this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty());
+ m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
+}
+
+void TileGrid::prepareTile(int x, int y, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch)
+{
+ Tile* tile = getTile(x, y);
+ if (!tile) {
+ bool isLayerTile = !m_isBaseSurface;
+ tile = new Tile(isLayerTile);
+ m_tiles.append(tile);
+ }
+
+ ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter);
+
+ tile->setContents(x, y, m_scale, isExpandPrefetch);
+
+ // TODO: move below (which is largely the same for layers / tiled page) into
+ // prepareGL() function
+
+ if (tile->isDirty() || !tile->frontTexture())
+ tile->reserveTexture();
+
+ if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) {
+ ALOGV("painting TG %p's tile %d %d for LG %p", this, x, y, painter);
+ PaintTileOperation *operation = new PaintTileOperation(tile, painter,
+ state, isLowResPrefetch);
+ TilesManager::instance()->scheduleOperation(operation);
+ }
+}
+
+Tile* TileGrid::getTile(int x, int y)
+{
+ for (unsigned int i = 0; i <m_tiles.size(); i++) {
+ Tile* tile = m_tiles[i];
+ if (tile->x() == x && tile->y() == y)
+ return tile;
+ }
+ return 0;
+}
+
+int TileGrid::nbTextures(IntRect& area, float scale)
+{
+ IntRect tileBounds = computeTilesArea(area, scale);
+ int numberTextures = tileBounds.width() * tileBounds.height();
+
+ // add the number of dirty tiles in the bounds, as they take up double
+ // textures for double buffering
+ for (unsigned int i = 0; i <m_tiles.size(); i++) {
+ Tile* tile = m_tiles[i];
+ if (tile->isDirty()
+ && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX()
+ && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY())
+ numberTextures++;
+ }
+ return numberTextures;
+}
+
+void TileGrid::drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform,
+ const Color* background)
+{
+ m_area = computeTilesArea(visibleArea, m_scale);
+ if (m_area.width() == 0 || m_area.height() == 0)
+ return;
+
+ float invScale = 1.0 / m_scale;
+ const float tileWidth = TilesManager::tileWidth() * invScale;
+ const float tileHeight = TilesManager::tileHeight() * invScale;
+
+ int drawn = 0;
+
+ SkRegion missingRegion;
+ bool semiOpaqueBaseSurface =
+ background ? (background->hasAlpha() && background->alpha() > 0) : false;
+ if (semiOpaqueBaseSurface) {
+ SkIRect totalArea = SkIRect::MakeXYWH(m_area.x(), m_area.y(),
+ m_area.width(), m_area.height());
+ missingRegion = SkRegion(totalArea);
+ }
+
+ bool usePointSampling =
+ TilesManager::instance()->shader()->usePointSampling(m_scale, transform);
+
+ for (unsigned int i = 0; i < m_tiles.size(); i++) {
+ Tile* tile = m_tiles[i];
+
+ bool tileInView = tile->isTileVisible(m_area);
+ if (tileInView) {
+ SkRect rect;
+ rect.fLeft = tile->x() * tileWidth;
+ rect.fTop = tile->y() * tileHeight;
+ rect.fRight = rect.fLeft + tileWidth;
+ rect.fBottom = rect.fTop + tileHeight;
+ ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
+ tile, tile->isLayerTile(), tile->x(), tile->y(),
+ tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
+
+ bool forceBaseBlending = background ? background->hasAlpha() : false;
+ bool success = tile->drawGL(opacity, rect, m_scale, transform,
+ forceBaseBlending, usePointSampling);
+ if (semiOpaqueBaseSurface && success) {
+ // Cut the successful drawn tile area from the missing region.
+ missingRegion.op(SkIRect::MakeXYWH(tile->x(), tile->y(), 1, 1),
+ SkRegion::kDifference_Op);
+ }
+ if (tile->frontTexture())
+ drawn++;
+ }
+
+ // log tile information for base, high res tiles
+ if (m_isBaseSurface && background)
+ TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView);
+ }
+
+ // Draw missing Regions with blend turned on
+ if (semiOpaqueBaseSurface)
+ drawMissingRegion(missingRegion, opacity, background);
+
+ ALOGV("TG %p drew %d tiles, scale %f",
+ this, drawn, m_scale);
+}
+
+void TileGrid::drawMissingRegion(const SkRegion& region, float opacity,
+ const Color* background)
+{
+ SkRegion::Iterator iterator(region);
+ const float tileWidth = TilesManager::tileWidth() / m_scale;
+ const float tileHeight = TilesManager::tileHeight() / m_scale;
+ while (!iterator.done()) {
+ SkIRect r = iterator.rect();
+ SkRect rect;
+ rect.fLeft = r.x() * tileWidth;
+ rect.fTop = r.y() * tileHeight;
+ rect.fRight = rect.fLeft + tileWidth * r.width();
+ rect.fBottom = rect.fTop + tileHeight * r.height();
+ ALOGV("draw tile x y, %d %d (%d %d) opacity %f", r.x(), r.y(),
+ r.width(), r.height(), opacity);
+ // Skia is using pre-multiplied color.
+ Color postAlpha = Color(background->red() * background->alpha() / 255,
+ background->green() * background->alpha() / 255,
+ background->blue() * background->alpha() / 255,
+ background->alpha() );
+
+ PureColorQuadData backGroundData(postAlpha, BaseQuad, 0, &rect, opacity);
+ TilesManager::instance()->shader()->drawQuad(&backGroundData);
+ iterator.next();
+ }
+}
+
+void TileGrid::removeTiles()
+{
+ for (unsigned int i = 0; i < m_tiles.size(); i++) {
+ delete m_tiles[i];
+ }
+ m_tiles.clear();
+}
+
+void TileGrid::discardTextures()
+{
+ ALOGV("TG %p discarding textures", this);
+ for (unsigned int i = 0; i < m_tiles.size(); i++)
+ m_tiles[i]->discardTextures();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
new file mode 100644
index 0000000..2483e0e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TileGrid_h
+#define TileGrid_h
+
+#include "IntRect.h"
+#include "SkRegion.h"
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Color;
+class GLWebViewState;
+class Tile;
+class TilePainter;
+class TransformationMatrix;
+
+class TileGrid {
+public:
+ enum PrepareRegionFlags { EmptyRegion = 0x0, StandardRegion = 0x1, ExpandedRegion = 0x2 };
+
+ TileGrid(bool isBaseSurface);
+ virtual ~TileGrid();
+
+ static IntRect computeTilesArea(const IntRect& contentArea, float scale);
+
+ void prepareGL(GLWebViewState* state, float scale,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, int regionFlags = StandardRegion,
+ bool isLowResPrefetch = false);
+ void swapTiles();
+ void drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform, const Color* background = 0);
+
+ void prepareTile(int x, int y, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch);
+ void markAsDirty(const SkRegion& dirtyArea);
+
+ Tile* getTile(int x, int y);
+
+ void removeTiles();
+ void discardTextures();
+
+ bool isReady();
+ bool isMissingContent();
+
+ int nbTextures(IntRect& area, float scale);
+
+private:
+ void drawMissingRegion(const SkRegion& region, float opacity, const Color* tileBackground);
+ WTF::Vector<Tile*> m_tiles;
+
+ IntRect m_area;
+
+ SkRegion m_dirtyRegion;
+
+ int m_prevTileY;
+ float m_scale;
+
+ bool m_isBaseSurface;
+};
+
+} // namespace WebCore
+
+#endif // TileGrid_h
diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h
index 34e877e..53dfadc 100644
--- a/Source/WebCore/platform/graphics/android/TilePainter.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h
@@ -33,16 +33,17 @@ class SkCanvas;
namespace WebCore {
-class BaseTile;
+class Color;
class TilePainter : public SkRefCnt {
// TODO: investigate webkit threadsafe ref counting
public:
virtual ~TilePainter() { }
- virtual bool paint(BaseTile* tile, SkCanvas* canvas) = 0;
+ virtual bool paint(SkCanvas* canvas) = 0;
virtual float opacity() { return 1.0; }
enum SurfaceType { Painted, Image };
virtual SurfaceType type() { return Painted; }
+ virtual Color* background() { return 0; }
unsigned int getUpdateCount() { return m_updateCount; }
void setUpdateCount(unsigned int updateCount) { m_updateCount = updateCount; }
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp
index ec1fac2..3dceda9 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp
@@ -23,21 +23,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_TAG "BaseTileTexture"
+#define LOG_TAG "TileTexture"
#define LOG_NDEBUG 1
#include "config.h"
-#include "BaseTileTexture.h"
+#include "TileTexture.h"
#include "AndroidLog.h"
-#include "BaseTile.h"
+#include "Tile.h"
#include "ClassTracker.h"
+#include "DrawQuadData.h"
#include "GLUtils.h"
+#include "GLWebViewState.h"
+#include "TextureOwner.h"
#include "TilesManager.h"
namespace WebCore {
-BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
+TileTexture::TileTexture(uint32_t w, uint32_t h)
: m_owner(0)
, m_isPureColor(false)
{
@@ -45,24 +48,24 @@ BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
m_ownTextureId = 0;
#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("BaseTileTexture");
+ ClassTracker::instance()->increment("TileTexture");
#endif
}
-BaseTileTexture::~BaseTileTexture()
+TileTexture::~TileTexture()
{
#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("BaseTileTexture");
+ ClassTracker::instance()->decrement("TileTexture");
#endif
}
-void BaseTileTexture::requireGLTexture()
+void TileTexture::requireGLTexture()
{
if (!m_ownTextureId)
- m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height());
+ m_ownTextureId = GLUtils::createTileGLTexture(m_size.width(), m_size.height());
}
-void BaseTileTexture::discardGLTexture()
+void TileTexture::discardGLTexture()
{
if (m_ownTextureId)
GLUtils::deleteTexture(&m_ownTextureId);
@@ -74,15 +77,15 @@ void BaseTileTexture::discardGLTexture()
}
}
-bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
+bool TileTexture::acquire(TextureOwner* owner)
{
if (m_owner == owner)
return true;
- return setOwner(owner, force);
+ return setOwner(owner);
}
-bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
+bool TileTexture::setOwner(TextureOwner* owner)
{
bool proceed = true;
if (m_owner && m_owner != owner)
@@ -96,7 +99,7 @@ bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
return false;
}
-bool BaseTileTexture::release(TextureOwner* owner)
+bool TileTexture::release(TextureOwner* owner)
{
ALOGV("texture %p releasing tile %p, m_owner %p", this, owner, m_owner);
if (m_owner != owner)
@@ -106,32 +109,39 @@ bool BaseTileTexture::release(TextureOwner* owner)
return true;
}
-void BaseTileTexture::transferComplete()
+void TileTexture::transferComplete()
{
if (m_owner) {
- BaseTile* owner = static_cast<BaseTile*>(m_owner);
+ Tile* owner = static_cast<Tile*>(m_owner);
owner->backTextureTransfer();
} else
ALOGE("ERROR: owner missing after transfer of texture %p", this);
}
-void BaseTileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity,
- const TransformationMatrix* transform)
+void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity,
+ const TransformationMatrix* transform,
+ bool forceBlending, bool usePointSampling)
{
ShaderProgram* shader = TilesManager::instance()->shader();
- if (isLayer && transform) {
- if (isPureColor()) {
- shader->drawLayerQuad(*transform, rect, 0, opacity,
- true, GL_TEXTURE_2D, pureColor());
- } else {
- shader->drawLayerQuad(*transform, rect, m_ownTextureId,
- opacity, true);
- }
+
+ if (isLayer && !transform) {
+ ALOGE("ERROR: Missing tranform for layers!");
+ return;
+ }
+
+ // For base layer, we just follow the forceBlending, otherwise, blending is
+ // always turned on.
+ // TODO: Don't blend tiles if they are fully opaque.
+ bool useBlending = forceBlending || isLayer;
+ DrawQuadData commonData(isLayer ? LayerQuad : BaseQuad, transform, &rect,
+ opacity, useBlending);
+ if (isPureColor()) {
+ PureColorQuadData data(commonData, pureColor());
+ shader->drawQuad(&data);
} else {
- if (isPureColor())
- shader->drawQuad(rect, 0, opacity, pureColor());
- else
- shader->drawQuad(rect, m_ownTextureId, opacity);
+ GLint filter = usePointSampling ? GL_NEAREST : GL_LINEAR;
+ TextureQuadData data(commonData, m_ownTextureId, GL_TEXTURE_2D, filter);
+ shader->drawQuad(&data);
}
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
index 321ca31..a624c1d 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
@@ -23,45 +23,45 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef BaseTileTexture_h
-#define BaseTileTexture_h
+#ifndef TileTexture_h
+#define TileTexture_h
-#include "GLWebViewState.h"
#include "TextureInfo.h"
-#include "TextureOwner.h"
-#include "TilePainter.h"
+#include "Color.h"
+#include "SkBitmap.h"
+#include "SkRect.h"
+#include "SkSize.h"
+
#include <GLES2/gl2.h>
-#include <SkBitmap.h>
class SkCanvas;
namespace WebCore {
-class BaseTile;
+class TextureOwner;
+class Tile;
+class TransformationMatrix;
-class BaseTileTexture {
+class TileTexture {
public:
// This object is to be constructed on the consumer's thread and must have
// a width and height greater than 0.
- BaseTileTexture(uint32_t w, uint32_t h);
- virtual ~BaseTileTexture();
+ TileTexture(uint32_t w, uint32_t h);
+ virtual ~TileTexture();
// allows consumer thread to assign ownership of the texture to the tile. It
// returns false if ownership cannot be transferred because the tile is busy
- bool acquire(TextureOwner* owner, bool force = false);
+ bool acquire(TextureOwner* owner);
bool release(TextureOwner* owner);
// set the texture owner if not busy. Return false if busy, true otherwise.
- bool setOwner(TextureOwner* owner, bool force = false);
+ bool setOwner(TextureOwner* owner);
// private member accessor functions
TextureOwner* owner() { return m_owner; } // only used by the consumer thread
const SkSize& getSize() const { return m_size; }
- bool readyFor(BaseTile* baseTile);
- float scale();
-
// OpenGL ID of backing texture, 0 when not allocated
GLuint m_ownTextureId;
// these are used for dynamically (de)allocating backing graphics memory
@@ -80,13 +80,13 @@ public:
Color pureColor() { return m_pureColor; }
void drawGL(bool isLayer, const SkRect& rect, float opacity,
- const TransformationMatrix* transform);
+ const TransformationMatrix* transform, bool forceBlending = false,
+ bool usePointSampling = false);
private:
TextureInfo m_ownTextureInfo;
SkSize m_size;
- SkBitmap::Config m_config;
- // BaseTile owning the texture, only modified by UI thread
+ // Tile owning the texture, only modified by UI thread
TextureOwner* m_owner;
// When the whole tile is single color, skip the transfer queue and draw
@@ -97,4 +97,4 @@ private:
} // namespace WebCore
-#endif // BaseTileTexture_h
+#endif // TileTexture_h
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
index 37a7301..f46562a 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
@@ -32,10 +32,14 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidLog.h"
-#include "BaseTile.h"
+#include "GLWebViewState.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPaint.h"
+#include "Tile.h"
+#include "TileTexture.h"
+#include "TransferQueue.h"
+
#include <android/native_window.h>
#include <cutils/atomic.h>
#include <gui/SurfaceTexture.h>
@@ -56,8 +60,6 @@
#define MAX_TEXTURE_ALLOCATION ((6+TILE_PREFETCH_DISTANCE*2)*(5+TILE_PREFETCH_DISTANCE*2)*4)
#define TILE_WIDTH 256
#define TILE_HEIGHT 256
-#define LAYER_TILE_WIDTH 256
-#define LAYER_TILE_HEIGHT 256
#define BYTES_PER_PIXEL 4 // 8888 config
@@ -86,7 +88,6 @@ TilesManager::TilesManager()
, m_generatorReady(false)
, m_showVisualIndicator(false)
, m_invertedScreen(false)
- , m_invertedScreenSwitch(false)
, m_useMinimalMemory(true)
, m_useDoubleBuffering(true)
, m_contentUpdates(0)
@@ -101,7 +102,7 @@ TilesManager::TilesManager()
m_availableTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
m_tilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
m_availableTilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
- m_pixmapsGenerationThread = new TexturesGenerator();
+ m_pixmapsGenerationThread = new TexturesGenerator(this);
m_pixmapsGenerationThread->run("TexturesGenerator");
}
@@ -111,12 +112,12 @@ void TilesManager::allocateTiles()
ALOGV("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_maxTextureCount);
int nbTexturesAllocated = 0;
for (int i = 0; i < nbTexturesToAllocate; i++) {
- BaseTileTexture* texture = new BaseTileTexture(
+ TileTexture* texture = new TileTexture(
tileWidth(), tileHeight());
// the atomic load ensures that the texture has been fully initialized
// before we pass a pointer for other threads to operate on
- BaseTileTexture* loadedTexture =
- reinterpret_cast<BaseTileTexture*>(
+ TileTexture* loadedTexture =
+ reinterpret_cast<TileTexture*>(
android_atomic_acquire_load(reinterpret_cast<int32_t*>(&texture)));
m_textures.append(loadedTexture);
nbTexturesAllocated++;
@@ -127,12 +128,12 @@ void TilesManager::allocateTiles()
nbLayersTexturesToAllocate, m_maxLayerTextureCount);
int nbLayersTexturesAllocated = 0;
for (int i = 0; i < nbLayersTexturesToAllocate; i++) {
- BaseTileTexture* texture = new BaseTileTexture(
- layerTileWidth(), layerTileHeight());
+ TileTexture* texture = new TileTexture(
+ tileWidth(), tileHeight());
// the atomic load ensures that the texture has been fully initialized
// before we pass a pointer for other threads to operate on
- BaseTileTexture* loadedTexture =
- reinterpret_cast<BaseTileTexture*>(
+ TileTexture* loadedTexture =
+ reinterpret_cast<TileTexture*>(
android_atomic_acquire_load(reinterpret_cast<int32_t*>(&texture)));
m_tilesTextures.append(loadedTexture);
nbLayersTexturesAllocated++;
@@ -141,7 +142,7 @@ void TilesManager::allocateTiles()
nbTexturesAllocated, m_textures.size(),
m_textures.size() * TILE_WIDTH * TILE_HEIGHT * 4 / 1024 / 1024,
nbLayersTexturesAllocated, m_tilesTextures.size(),
- m_tilesTextures.size() * LAYER_TILE_WIDTH * LAYER_TILE_HEIGHT * 4 / 1024 / 1024);
+ m_tilesTextures.size() * tileWidth() * tileHeight() * 4 / 1024 / 1024);
}
void TilesManager::discardTextures(bool allTextures, bool glTextures)
@@ -163,7 +164,7 @@ void TilesManager::discardTextures(bool allTextures, bool glTextures)
}
void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount,
- WTF::Vector<BaseTileTexture*>& textures,
+ WTF::Vector<TileTexture*>& textures,
bool deallocateGLTextures)
{
const unsigned int max = textures.size();
@@ -178,14 +179,14 @@ void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount,
discardedIndex.append(i);
} else if (owner) {
// simply detach textures from owner
- static_cast<BaseTile*>(owner)->discardTextures();
+ static_cast<Tile*>(owner)->discardTextures();
}
dealloc++;
}
}
bool base = textures == m_textures;
- // Clean up the vector of BaseTileTextures and reset the max texture count.
+ // Clean up the vector of TileTextures and reset the max texture count.
if (discardedIndex.size()) {
android::Mutex::Autolock lock(m_texturesLock);
for (int i = discardedIndex.size() - 1; i >= 0; i--)
@@ -211,13 +212,13 @@ void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextur
{
*nbTextures = m_textures.size();
for (unsigned int i = 0; i < m_textures.size(); i++) {
- BaseTileTexture* texture = m_textures[i];
+ TileTexture* texture = m_textures[i];
if (texture->m_ownTextureId)
*nbAllocatedTextures += 1;
}
*nbLayerTextures = m_tilesTextures.size();
for (unsigned int i = 0; i < m_tilesTextures.size(); i++) {
- BaseTileTexture* texture = m_tilesTextures[i];
+ TileTexture* texture = m_tilesTextures[i];
if (texture->m_ownTextureId)
*nbAllocatedLayerTextures += 1;
}
@@ -228,19 +229,18 @@ void TilesManager::printTextures()
#ifdef DEBUG
ALOGV("++++++");
for (unsigned int i = 0; i < m_textures.size(); i++) {
- BaseTileTexture* texture = m_textures[i];
- BaseTile* o = 0;
+ TileTexture* texture = m_textures[i];
+ Tile* o = 0;
if (texture->owner())
- o = (BaseTile*) texture->owner();
+ o = (Tile*) texture->owner();
int x = -1;
int y = -1;
if (o) {
x = o->x();
y = o->y();
}
- ALOGV("[%d] texture %x owner: %x (%d, %d) page: %x scale: %.2f",
- i, texture,
- o, x, y, o ? o->page() : 0, o ? o->scale() : 0);
+ ALOGV("[%d] texture %x owner: %x (%d, %d) scale: %.2f",
+ i, texture, o, x, y, o ? o->scale() : 0);
}
ALOGV("------");
#endif // DEBUG
@@ -250,37 +250,26 @@ void TilesManager::gatherTextures()
{
android::Mutex::Autolock lock(m_texturesLock);
m_availableTextures = m_textures;
-}
-
-void TilesManager::gatherLayerTextures()
-{
- android::Mutex::Autolock lock(m_texturesLock);
m_availableTilesTextures = m_tilesTextures;
m_layerTexturesRemain = true;
}
-BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
+TileTexture* TilesManager::getAvailableTexture(Tile* owner)
{
android::Mutex::Autolock lock(m_texturesLock);
+ WTF::Vector<TileTexture*>* availableTexturePool;
+ if (owner->isLayerTile())
+ availableTexturePool = &m_availableTilesTextures;
+ else
+ availableTexturePool = &m_availableTextures;
+
// Sanity check that the tile does not already own a texture
if (owner->backTexture() && owner->backTexture()->owner() == owner) {
- ALOGV("same owner (%d, %d), getAvailableBackTexture(%x) => texture %x",
- owner->x(), owner->y(), owner, owner->backTexture());
- if (owner->isLayerTile())
- m_availableTilesTextures.remove(m_availableTilesTextures.find(owner->backTexture()));
- else
- m_availableTextures.remove(m_availableTextures.find(owner->backTexture()));
+ availableTexturePool->remove(availableTexturePool->find(owner->backTexture()));
return owner->backTexture();
}
- WTF::Vector<BaseTileTexture*>* availableTexturePool;
- if (owner->isLayerTile()) {
- availableTexturePool = &m_availableTilesTextures;
- } else {
- availableTexturePool = &m_availableTextures;
- }
-
// The heuristic for selecting a texture is as follows:
// 1. Skip textures currently being painted, they can't be painted while
// busy anyway
@@ -289,12 +278,12 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
// 4. Otherwise, use the least recently prepared tile, but ignoring tiles
// drawn in the last frame to avoid flickering
- BaseTileTexture* farthestTexture = 0;
+ TileTexture* farthestTexture = 0;
unsigned long long oldestDrawCount = getDrawGLCount() - 1;
const unsigned int max = availableTexturePool->size();
for (unsigned int i = 0; i < max; i++) {
- BaseTileTexture* texture = (*availableTexturePool)[i];
- BaseTile* currentOwner = static_cast<BaseTile*>(texture->owner());
+ TileTexture* texture = (*availableTexturePool)[i];
+ Tile* currentOwner = static_cast<Tile*>(texture->owner());
if (!currentOwner) {
// unused texture! take it!
farthestTexture = texture;
@@ -315,7 +304,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
}
if (farthestTexture) {
- BaseTile* previousOwner = static_cast<BaseTile*>(farthestTexture->owner());
+ Tile* previousOwner = static_cast<Tile*>(farthestTexture->owner());
if (farthestTexture->acquire(owner)) {
if (previousOwner) {
previousOwner->removeTexture(farthestTexture);
@@ -420,8 +409,9 @@ void TilesManager::setMaxLayerTextureCount(int max)
TransferQueue* TilesManager::transferQueue()
{
- // To minimize the memory usage, transfer queue can be set to minimal size
- // if required.
+ // m_queue will be created on the UI thread, although it may
+ // be accessed from the TexturesGenerator. However, that can only happen after
+ // a previous transferQueue() call due to a prepare.
if (!m_queue)
m_queue = new TransferQueue(m_useMinimalMemory);
return m_queue;
@@ -437,24 +427,11 @@ float TilesManager::tileHeight()
return TILE_HEIGHT;
}
-float TilesManager::layerTileWidth()
-{
- return LAYER_TILE_WIDTH;
-}
-
-float TilesManager::layerTileHeight()
-{
- return LAYER_TILE_HEIGHT;
-}
-
TilesManager* TilesManager::instance()
{
if (!gInstance) {
gInstance = new TilesManager();
ALOGV("instance(), new gInstance is %x", gInstance);
- ALOGV("Waiting for the generator...");
- gInstance->waitForGenerator();
- ALOGV("Generator ready!");
}
return gInstance;
}
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
index aafdfb6..92c56d3 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
@@ -28,24 +28,24 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "BaseTile.h"
-#include "BaseTileTexture.h"
-#include "ImageTexture.h"
#include "LayerAndroid.h"
#include "ShaderProgram.h"
-#include "SkBitmapRef.h"
#include "TexturesGenerator.h"
-#include "TiledPage.h"
#include "TilesProfiler.h"
-#include "TransferQueue.h"
#include "VideoLayerManager.h"
#include <utils/threads.h>
#include <wtf/HashMap.h>
namespace WebCore {
+class OperationFilter;
+class Tile;
+class TileTexture;
+class TransferQueue;
+
class TilesManager {
public:
+ // May only be called from the UI thread
static TilesManager* instance();
static GLint getMaxTextureSize();
static int getMaxTextureAllocation();
@@ -60,16 +60,6 @@ public:
m_pixmapsGenerationThread->removeOperationsForFilter(filter, waitForRunning);
}
- void removeOperationsForPage(TiledPage* page)
- {
- m_pixmapsGenerationThread->removeOperationsForPage(page);
- }
-
- void removePaintOperationsForPage(TiledPage* page, bool waitForCompletion)
- {
- m_pixmapsGenerationThread->removePaintOperationsForPage(page, waitForCompletion);
- }
-
void scheduleOperation(QueuedOperation* operation)
{
m_pixmapsGenerationThread->scheduleOperation(operation);
@@ -79,27 +69,15 @@ public:
TransferQueue* transferQueue();
VideoLayerManager* videoLayerManager() { return &m_videoLayerManager; }
- void gatherLayerTextures();
void gatherTextures();
bool layerTexturesRemain() { return m_layerTexturesRemain; }
void gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
int* nbLayerTextures, int* nbAllocatedLayerTextures);
- BaseTileTexture* getAvailableTexture(BaseTile* owner);
-
- void markGeneratorAsReady()
- {
- {
- android::Mutex::Autolock lock(m_generatorLock);
- m_generatorReady = true;
- }
- m_generatorReadyCond.signal();
- }
+ TileTexture* getAvailableTexture(Tile* owner);
void printTextures();
- void resetTextureUsage(TiledPage* page);
-
// m_highEndGfx is written/read only on UI thread, no need for a lock.
void setHighEndGfx(bool highEnd);
bool highEndGfx();
@@ -110,8 +88,6 @@ public:
void setMaxLayerTextureCount(int max);
static float tileWidth();
static float tileHeight();
- static float layerTileWidth();
- static float layerTileHeight();
void allocateTiles();
@@ -138,23 +114,11 @@ public:
return m_invertedScreen;
}
- bool invertedScreenSwitch()
- {
- return m_invertedScreenSwitch;
- }
-
void setInvertedScreen(bool invert)
{
- if (m_invertedScreen != invert)
- m_invertedScreenSwitch = true;
m_invertedScreen = invert;
}
- void setInvertedScreenSwitch(bool invertedSwitch)
- {
- m_invertedScreenSwitch = invertedSwitch;
- }
-
void setInvertedScreenContrast(float contrast)
{
m_shader.setContrast(contrast);
@@ -196,22 +160,15 @@ public:
private:
TilesManager();
- void waitForGenerator()
- {
- android::Mutex::Autolock lock(m_generatorLock);
- while (!m_generatorReady)
- m_generatorReadyCond.wait(m_generatorLock);
- }
-
void discardTexturesVector(unsigned long long sparedDrawCount,
- WTF::Vector<BaseTileTexture*>& textures,
+ WTF::Vector<TileTexture*>& textures,
bool deallocateGLTextures);
- Vector<BaseTileTexture*> m_textures;
- Vector<BaseTileTexture*> m_availableTextures;
+ WTF::Vector<TileTexture*> m_textures;
+ WTF::Vector<TileTexture*> m_availableTextures;
- Vector<BaseTileTexture*> m_tilesTextures;
- Vector<BaseTileTexture*> m_availableTilesTextures;
+ WTF::Vector<TileTexture*> m_tilesTextures;
+ WTF::Vector<TileTexture*> m_availableTilesTextures;
bool m_layerTexturesRemain;
bool m_highEndGfx;
@@ -222,7 +179,6 @@ private:
bool m_showVisualIndicator;
bool m_invertedScreen;
- bool m_invertedScreenSwitch;
bool m_useMinimalMemory;
@@ -233,8 +189,6 @@ private:
sp<TexturesGenerator> m_pixmapsGenerationThread;
android::Mutex m_texturesLock;
- android::Mutex m_generatorLock;
- android::Condition m_generatorReadyCond;
static TilesManager* gInstance;
diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp b/Source/WebCore/platform/graphics/android/rendering/TilesProfiler.cpp
index a113514..4f0c6b5 100644
--- a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesProfiler.cpp
@@ -32,6 +32,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidLog.h"
+#include "Tile.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
@@ -92,14 +93,14 @@ void TilesProfiler::nextFrame(int left, int top, int right, int bottom, float sc
scale, true, (int)(timeDelta * 1000)));
}
-void TilesProfiler::nextTile(BaseTile& tile, float scale, bool inView)
+void TilesProfiler::nextTile(Tile* tile, float scale, bool inView)
{
if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES) || (m_records.size() == 0))
return;
- bool isReady = tile.isTileReady();
- int left = tile.x() * TilesManager::tileWidth();
- int top = tile.y() * TilesManager::tileWidth();
+ bool isReady = tile->isTileReady();
+ int left = tile->x() * TilesManager::tileWidth();
+ int top = tile->y() * TilesManager::tileWidth();
int right = left + TilesManager::tileWidth();
int bottom = top + TilesManager::tileWidth();
@@ -111,20 +112,20 @@ void TilesProfiler::nextTile(BaseTile& tile, float scale, bool inView)
}
m_records.last().append(TileProfileRecord(
left, top, right, bottom,
- scale, isReady, (int)tile.drawCount()));
+ scale, isReady, (int)tile->drawCount()));
ALOGV("adding tile %d %d %d %d, scale %f", left, top, right, bottom, scale);
}
-void TilesProfiler::nextInval(const IntRect& rect, float scale)
+void TilesProfiler::nextInval(const SkIRect& rect, float scale)
{
if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES) || (m_records.size() == 0))
return;
m_records.last().append(TileProfileRecord(
rect.x(), rect.y(),
- rect.maxX(), rect.maxY(), scale, false, INVAL_CODE));
+ rect.right(), rect.bottom(), scale, false, INVAL_CODE));
ALOGV("adding inval region %d %d %d %d, scale %f", rect.x(), rect.y(),
- rect.maxX(), rect.maxY(), scale);
+ rect.right(), rect.bottom(), scale);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.h b/Source/WebCore/platform/graphics/android/rendering/TilesProfiler.h
index 286d350..b39ae2f 100644
--- a/Source/WebCore/platform/graphics/android/TilesProfiler.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesProfiler.h
@@ -28,12 +28,14 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "BaseTile.h"
#include "IntRect.h"
-#include "Vector.h"
+#include "SkRect.h"
+#include <wtf/Vector.h>
namespace WebCore {
+class Tile;
+
struct TileProfileRecord {
TileProfileRecord(int left, int top, int right, int bottom, float scale, int isReady, int level) {
this->left = left;
@@ -58,8 +60,8 @@ public:
float stop();
void clear();
void nextFrame(int left, int top, int right, int bottom, float scale);
- void nextTile(BaseTile& tile, float scale, bool inView);
- void nextInval(const IntRect& rect, float scale);
+ void nextTile(Tile* tile, float scale, bool inView);
+ void nextInval(const SkIRect& rect, float scale);
int numFrames() {
return m_records.size();
};
@@ -72,11 +74,13 @@ public:
return &m_records[frame][tile];
}
+ bool enabled() { return m_enabled; }
+
private:
bool m_enabled;
unsigned int m_goodTiles;
unsigned int m_badTiles;
- Vector<Vector<TileProfileRecord> > m_records;
+ WTF::Vector<WTF::Vector<TileProfileRecord> > m_records;
double m_time;
};
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
index ac45112..5ede167 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
@@ -32,8 +32,10 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidLog.h"
-#include "BaseTile.h"
+#include "DrawQuadData.h"
#include "GLUtils.h"
+#include "Tile.h"
+#include "TileTexture.h"
#include "TilesManager.h"
#include <android/native_window.h>
#include <gui/SurfaceTexture.h>
@@ -96,12 +98,15 @@ void TransferQueue::initGLResources(int width, int height)
android::Mutex::Autolock lock(m_transferQueueItemLocks);
if (!m_sharedSurfaceTextureId) {
glGenTextures(1, &m_sharedSurfaceTextureId);
+ sp<BufferQueue> bufferQueue(new BufferQueue(true));
m_sharedSurfaceTexture =
#if GPU_UPLOAD_WITHOUT_DRAW
new android::SurfaceTexture(m_sharedSurfaceTextureId, true,
- GL_TEXTURE_2D, false);
+ GL_TEXTURE_2D, false, bufferQueue);
#else
- new android::SurfaceTexture(m_sharedSurfaceTextureId);
+ new android::SurfaceTexture(m_sharedSurfaceTextureId, true,
+ GL_TEXTURE_EXTERNAL_OES, true,
+ bufferQueue);
#endif
m_ANW = new android::SurfaceTextureClient(m_sharedSurfaceTexture);
m_sharedSurfaceTexture->setSynchronousMode(true);
@@ -109,7 +114,7 @@ void TransferQueue::initGLResources(int width, int height)
int extraBuffersNeeded = 0;
m_ANW->query(m_ANW.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
&extraBuffersNeeded);
- m_sharedSurfaceTexture->setBufferCount(m_transferQueueSize + extraBuffersNeeded);
+ bufferQueue->setBufferCount(m_transferQueueSize + extraBuffersNeeded);
int result = native_window_set_buffers_geometry(m_ANW.get(),
width, height, HAL_PIXEL_FORMAT_RGBA_8888);
@@ -124,28 +129,28 @@ void TransferQueue::initGLResources(int width, int height)
}
// When bliting, if the item from the transfer queue is mismatching b/t the
-// BaseTile and the content, then the item is considered as obsolete, and
+// Tile and the content, then the item is considered as obsolete, and
// the content is discarded.
bool TransferQueue::checkObsolete(const TileTransferData* data)
{
- BaseTile* baseTilePtr = data->savedBaseTilePtr;
+ Tile* baseTilePtr = data->savedTilePtr;
if (!baseTilePtr) {
- ALOGV("Invalid savedBaseTilePtr , such that the tile is obsolete");
+ ALOGV("Invalid savedTilePtr , such that the tile is obsolete");
return true;
}
- BaseTileTexture* baseTileTexture = baseTilePtr->backTexture();
- if (!baseTileTexture || baseTileTexture != data->savedBaseTileTexturePtr) {
+ TileTexture* baseTileTexture = baseTilePtr->backTexture();
+ if (!baseTileTexture || baseTileTexture != data->savedTileTexturePtr) {
ALOGV("Invalid baseTileTexture %p (vs expected %p), such that the tile is obsolete",
- baseTileTexture, data->savedBaseTileTexturePtr);
+ baseTileTexture, data->savedTileTexturePtr);
return true;
}
return false;
}
-void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
- BaseTileTexture* frontTex,
+void TransferQueue::blitTileFromQueue(GLuint fboID, TileTexture* destTex,
+ TileTexture* frontTex,
GLuint srcTexId, GLenum srcTexTarget,
int index)
{
@@ -198,14 +203,14 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
ALOGV("Error: glCheckFramebufferStatus failed");
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
return;
}
// Use empty rect to set up the special matrix to draw.
SkRect rect = SkRect::MakeEmpty();
- TilesManager::instance()->shader()->drawQuad(rect, srcTexId, 1.0,
- srcTexTarget, GL_NEAREST);
+
+ TextureQuadData data(srcTexId, GL_NEAREST, srcTexTarget, Blit, 0, 0, 1.0, false);
+ TilesManager::instance()->shader()->drawQuad(&data);
// To workaround a sync issue on some platforms, we should insert the sync
// here while in the current FBO.
@@ -327,10 +332,10 @@ void TransferQueue::updatePureColorTiles()
for (unsigned int i = 0 ; i < m_pureColorTileQueue.size(); i++) {
TileTransferData* data = &m_pureColorTileQueue[i];
if (data->status == pendingBlit) {
- BaseTileTexture* destTexture = 0;
- bool obsoleteBaseTile = checkObsolete(data);
- if (!obsoleteBaseTile) {
- destTexture = data->savedBaseTilePtr->backTexture();
+ TileTexture* destTexture = 0;
+ bool obsoleteTile = checkObsolete(data);
+ if (!obsoleteTile) {
+ destTexture = data->savedTilePtr->backTexture();
destTexture->setPureColor(data->pureColor);
destTexture->transferComplete();
}
@@ -342,8 +347,8 @@ void TransferQueue::updatePureColorTiles()
m_pureColorTileQueue.clear();
}
-// Call on UI thread to copy from the shared Surface Texture to the BaseTile's texture.
-void TransferQueue::updateDirtyBaseTiles()
+// Call on UI thread to copy from the shared Surface Texture to the Tile's texture.
+void TransferQueue::updateDirtyTiles()
{
android::Mutex::Autolock lock(m_transferQueueItemLocks);
@@ -355,22 +360,22 @@ void TransferQueue::updateDirtyBaseTiles()
updatePureColorTiles();
// Start from the oldest item, we call the updateTexImage to retrive
- // the texture and blit that into each BaseTile's texture.
+ // the texture and blit that into each Tile's texture.
const int nextItemIndex = getNextTransferQueueIndex();
int index = nextItemIndex;
bool usedFboForUpload = false;
for (int k = 0; k < m_transferQueueSize ; k++) {
if (m_transferQueue[index].status == pendingBlit) {
- bool obsoleteBaseTile = checkObsolete(&m_transferQueue[index]);
+ bool obsoleteTile = checkObsolete(&m_transferQueue[index]);
// Save the needed info, update the Surf Tex, clean up the item in
// the queue. Then either move on to next item or copy the content.
- BaseTileTexture* destTexture = 0;
- BaseTileTexture* frontTexture = 0;
- if (!obsoleteBaseTile) {
- destTexture = m_transferQueue[index].savedBaseTilePtr->backTexture();
+ TileTexture* destTexture = 0;
+ TileTexture* frontTexture = 0;
+ if (!obsoleteTile) {
+ destTexture = m_transferQueue[index].savedTilePtr->backTexture();
// while destTexture is guaranteed to not be null, frontTexture
// might be (first transfer)
- frontTexture = m_transferQueue[index].savedBaseTilePtr->frontTexture();
+ frontTexture = m_transferQueue[index].savedTilePtr->frontTexture();
}
if (m_transferQueue[index].uploadType == GpuUpload) {
@@ -378,9 +383,9 @@ void TransferQueue::updateDirtyBaseTiles()
if (result != OK)
ALOGE("unexpected error: updateTexImage return %d", result);
}
- m_transferQueue[index].savedBaseTilePtr = 0;
+ m_transferQueue[index].savedTilePtr = 0;
m_transferQueue[index].status = emptyItem;
- if (obsoleteBaseTile) {
+ if (obsoleteTile) {
ALOGV("Warning: the texture is obsolete for this baseTile");
index = (index + 1) % m_transferQueueSize;
continue;
@@ -409,7 +414,7 @@ void TransferQueue::updateDirtyBaseTiles()
destTexture->transferComplete();
ALOGV("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d",
- m_transferQueue[index].savedBaseTilePtr,
+ m_transferQueue[index].savedTilePtr,
destTexture,
destTexture->m_ownTextureId);
}
@@ -420,9 +425,8 @@ void TransferQueue::updateDirtyBaseTiles()
// dynamic switch possible. Moving this out from the loop can save some
// milli-seconds.
if (usedFboForUpload) {
- glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
restoreGLState();
- GLUtils::checkGlError("updateDirtyBaseTiles");
+ GLUtils::checkGlError("updateDirtyTiles");
}
m_emptyItemCount = m_transferQueueSize;
@@ -435,7 +439,7 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
if (!tryUpdateQueueWithBitmap(renderInfo, bitmap)) {
// failed placing bitmap in queue, discard tile's texture so it will be
// re-enqueued (and repainted)
- BaseTile* tile = renderInfo->baseTile;
+ Tile* tile = renderInfo->baseTile;
if (tile)
tile->backTextureTransferFail();
}
@@ -463,33 +467,8 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
return false;
}
- ANativeWindow_Buffer buffer;
- if (ANativeWindow_lock(m_ANW.get(), &buffer, 0))
+ if (!GLUtils::updateSharedSurfaceTextureWithBitmap(m_ANW.get(), bitmap))
return false;
-
- uint8_t* img = (uint8_t*)buffer.bits;
- int row;
- int bpp = 4; // Now we only deal with RGBA8888 format.
- int width = TilesManager::instance()->tileWidth();
- int height = TilesManager::instance()->tileHeight();
- if (bitmap.width() == width && bitmap.height() == height) {
- bitmap.lockPixels();
- uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
-
- if (buffer.stride != bitmap.width())
- // Copied line by line since we need to handle the offsets and stride.
- for (row = 0 ; row < bitmap.height(); row ++) {
- uint8_t* dst = &(img[buffer.stride * row * bpp]);
- uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
- memcpy(dst, src, bpp * bitmap.width());
- }
- else
- memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
-
- bitmap.unlockPixels();
- }
-
- ANativeWindow_unlockAndPost(m_ANW.get());
}
// b) After update the Surface Texture, now udpate the transfer queue info.
@@ -500,14 +479,14 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
return true;
}
-void TransferQueue::addItemInPureColorQueue(const TileRenderInfo* renderInfo, Color color)
+void TransferQueue::addItemInPureColorQueue(const TileRenderInfo* renderInfo)
{
// The pure color tiles' queue will be read from UI thread and written in
// Tex Gen thread, thus we need to have a lock here.
android::Mutex::Autolock lock(m_transferQueueItemLocks);
TileTransferData data;
addItemCommon(renderInfo, GpuUpload, &data);
- data.pureColor = color;
+ data.pureColor = renderInfo->pureColor;
m_pureColorTileQueue.append(data);
}
@@ -517,8 +496,8 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
TextureUploadType type,
TileTransferData* data)
{
- data->savedBaseTileTexturePtr = renderInfo->baseTile->backTexture();
- data->savedBaseTilePtr = renderInfo->baseTile;
+ data->savedTileTexturePtr = renderInfo->baseTile->backTexture();
+ data->savedTilePtr = renderInfo->baseTile;
data->status = pendingBlit;
data->uploadType = type;
@@ -541,7 +520,7 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
m_transferQueueIndex = (m_transferQueueIndex + 1) % m_transferQueueSize;
int index = m_transferQueueIndex;
- if (m_transferQueue[index].savedBaseTilePtr
+ if (m_transferQueue[index].savedTilePtr
|| m_transferQueue[index].status != emptyItem) {
ALOGV("ERROR update a tile which is dirty already @ index %d", index);
}
@@ -575,7 +554,7 @@ void TransferQueue::setTextureUploadType(TextureUploadType type)
}
// Note: this need to be called within the lock and on the UI thread.
-// Only called by updateDirtyBaseTiles() and emptyQueue() for now
+// Only called by updateDirtyTiles() and emptyQueue() for now
void TransferQueue::cleanupPendingDiscard()
{
int index = getNextTransferQueueIndex();
@@ -593,8 +572,8 @@ void TransferQueue::cleanupPendingDiscard()
// since tiles in the queue may be from another webview, remove
// their textures so that they will be repainted / retransferred
- BaseTile* tile = m_transferQueue[index].savedBaseTilePtr;
- BaseTileTexture* texture = m_transferQueue[index].savedBaseTileTexturePtr;
+ Tile* tile = m_transferQueue[index].savedTilePtr;
+ TileTexture* texture = m_transferQueue[index].savedTileTexturePtr;
if (tile && texture && texture->owner() == tile) {
// since tile destruction removes textures on the UI thread, the
// texture->owner ptr guarantees the tile is valid
@@ -602,8 +581,8 @@ void TransferQueue::cleanupPendingDiscard()
ALOGV("transfer queue discarded tile %p, removed texture", tile);
}
- m_transferQueue[index].savedBaseTilePtr = 0;
- m_transferQueue[index].savedBaseTileTexturePtr = 0;
+ m_transferQueue[index].savedTilePtr = 0;
+ m_transferQueue[index].savedTileTexturePtr = 0;
m_transferQueue[index].status = emptyItem;
}
index = (index + 1) % m_transferQueueSize;
@@ -612,6 +591,7 @@ void TransferQueue::cleanupPendingDiscard()
void TransferQueue::saveGLState()
{
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, m_GLStateBeforeBlit.bufferId);
glGetIntegerv(GL_VIEWPORT, m_GLStateBeforeBlit.viewport);
glGetBooleanv(GL_SCISSOR_TEST, m_GLStateBeforeBlit.scissor);
glGetBooleanv(GL_DEPTH_TEST, m_GLStateBeforeBlit.depth);
@@ -635,6 +615,7 @@ void TransferQueue::setGLStateForCopy(int width, int height)
void TransferQueue::restoreGLState()
{
+ glBindFramebuffer(GL_FRAMEBUFFER, m_GLStateBeforeBlit.bufferId[0]);
glViewport(m_GLStateBeforeBlit.viewport[0],
m_GLStateBeforeBlit.viewport[1],
m_GLStateBeforeBlit.viewport[2],
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index b864085..d1024a4 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -28,15 +28,19 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "BaseTile.h"
-#include "BaseTileTexture.h"
+#include "GLUtils.h"
#include "ShaderProgram.h"
-#include "TiledPage.h"
-#include <EGL/eglext.h>
+#include "SkBitmap.h"
+#include <utils/StrongPointer.h>
+#include <utils/threads.h>
namespace WebCore {
+class Tile;
+class TileTexture;
+
struct GLState {
+ GLint bufferId[1];
GLint viewport[4];
GLboolean scissor[1];
GLboolean depth[1];
@@ -44,7 +48,7 @@ struct GLState {
};
-// While in the queue, the BaseTile can be re-used, the updated bitmap
+// While in the queue, the Tile can be re-used, the updated bitmap
// can be discarded. In order to track this obsolete base tiles, we save
// the Tile's Info to make the comparison.
// At the time of base tile's dtor or webview destroy, we want to discard
@@ -70,8 +74,8 @@ class TileTransferData {
public:
TileTransferData()
: status(emptyItem)
- , savedBaseTilePtr(0)
- , savedBaseTileTexturePtr(0)
+ , savedTilePtr(0)
+ , savedTileTexturePtr(0)
, uploadType(DEFAULT_UPLOAD_TYPE)
, bitmap(0)
, m_syncKHR(EGL_NO_SYNC_KHR)
@@ -85,8 +89,8 @@ public:
}
TransferItemStatus status;
- BaseTile* savedBaseTilePtr;
- BaseTileTexture* savedBaseTileTexturePtr;
+ Tile* savedTilePtr;
+ TileTexture* savedTileTexturePtr;
IntRect invalRect;
TextureUploadType uploadType;
// This is only useful in Cpu upload code path, so it will be dynamically
@@ -114,7 +118,7 @@ public:
// This will be called by the browser through nativeSetProperty
void setTextureUploadType(TextureUploadType type);
void cleanupGLResources();
- void updateDirtyBaseTiles();
+ void updateDirtyTiles();
void initGLResources(int width, int height);
@@ -134,7 +138,7 @@ public:
void lockQueue() { m_transferQueueItemLocks.lock(); }
void unlockQueue() { m_transferQueueItemLocks.unlock(); }
- void addItemInPureColorQueue(const TileRenderInfo* renderInfo, Color color);
+ void addItemInPureColorQueue(const TileRenderInfo* renderInfo);
void setPendingDiscardWithLock();
void emptyQueue();
@@ -144,7 +148,7 @@ public:
// a lock to protect its access
TileTransferData* m_transferQueue;
- sp<ANativeWindow> m_ANW;
+ android::sp<ANativeWindow> m_ANW;
// EGL wrapper around m_ANW for use by the GaneshRenderer
EGLSurface m_eglSurface;
@@ -171,8 +175,8 @@ private:
// pendingDiscard items.
void cleanupPendingDiscard();
- void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
- BaseTileTexture* frontTex,
+ void blitTileFromQueue(GLuint fboID, TileTexture* destTex,
+ TileTexture* frontTex,
GLuint srcTexId, GLenum srcTexTarget,
int index);
@@ -192,7 +196,7 @@ private:
bool m_hasGLContext;
GLState m_GLStateBeforeBlit;
- sp<android::SurfaceTexture> m_sharedSurfaceTexture;
+ android::sp<android::SurfaceTexture> m_sharedSurfaceTexture;
int m_emptyItemCount;
diff --git a/Source/WebCore/platform/graphics/android/ClassTracker.cpp b/Source/WebCore/platform/graphics/android/utils/ClassTracker.cpp
index 98e33d9..98e33d9 100644
--- a/Source/WebCore/platform/graphics/android/ClassTracker.cpp
+++ b/Source/WebCore/platform/graphics/android/utils/ClassTracker.cpp
diff --git a/Source/WebCore/platform/graphics/android/ClassTracker.h b/Source/WebCore/platform/graphics/android/utils/ClassTracker.h
index d169883..d169883 100644
--- a/Source/WebCore/platform/graphics/android/ClassTracker.h
+++ b/Source/WebCore/platform/graphics/android/utils/ClassTracker.h
diff --git a/Source/WebCore/platform/graphics/android/TestExport.h b/Source/WebCore/platform/graphics/android/utils/TestExport.h
index 15d7cc3..15d7cc3 100644
--- a/Source/WebCore/platform/graphics/android/TestExport.h
+++ b/Source/WebCore/platform/graphics/android/utils/TestExport.h
diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index dc22fca..ec04035 100644
--- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -180,9 +180,9 @@ static void ensureSessionIsInitialized(SoupSession* session)
g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
}
-void ResourceHandle::prepareForURL(const KURL &url)
+void ResourceHandle::prepareForURL(const KURL& url)
{
- GOwnPtr<SoupURI> soupURI(soup_uri_new(url.prettyURL().utf8().data()));
+ GOwnPtr<SoupURI> soupURI(soup_uri_new(url.string().utf8().data()));
if (!soupURI)
return;
soup_session_prepare_for_uri(ResourceHandle::defaultSession(), soupURI.get());
diff --git a/Source/WebCore/platform/qt/KURLQt.cpp b/Source/WebCore/platform/qt/KURLQt.cpp
index f6d2a86..674a933 100644
--- a/Source/WebCore/platform/qt/KURLQt.cpp
+++ b/Source/WebCore/platform/qt/KURLQt.cpp
@@ -50,4 +50,3 @@ String KURL::fileSystemPath() const
}
}
-
diff --git a/Source/WebCore/platform/win/ClipboardWin.cpp b/Source/WebCore/platform/win/ClipboardWin.cpp
index 0b5a3d3..2e56cbc 100644
--- a/Source/WebCore/platform/win/ClipboardWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardWin.cpp
@@ -191,7 +191,7 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share
WCHAR filePath[MAX_PATH];
if (url.isLocalFile()) {
- String localPath = url.path();
+ String localPath = decodeURLEscapeSequences(url.path());
// windows does not enjoy a leading slash on paths
if (localPath[0] == '/')
localPath = localPath.substring(1);
diff --git a/Source/WebCore/plugins/android/PluginViewAndroid.cpp b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
index 315d8a4..fdf6e03 100644
--- a/Source/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -690,7 +690,10 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
notification of its global position change.
*/
updatePluginWidget();
- m_window->setSurfaceClip(context->platformContext()->mCanvas->getTotalClip().getBounds());
+ SkCanvas* canvas = context->platformContext()->getCanvas();
+ if (!canvas)
+ return;
+ m_window->setSurfaceClip(canvas->getTotalClip().getBounds());
} else {
m_window->inval(rect, false);
context->save();
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index a90bf69..a3bd41a 100644
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -191,7 +191,7 @@ void RenderBlock::destroy()
childBox->remove();
}
}
- } else if (isInline() && parent())
+ } else if (parent())
parent()->dirtyLinesFromChangedChild(this);
}
@@ -420,14 +420,18 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render
RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
{
+ RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
for (RenderObject* curr = this; curr; curr = curr->parent()) {
if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
|| curr->isInlineBlockOrInlineTable())
return 0;
RenderBlock* currBlock = toRenderBlock(curr);
+ if (!currBlock->createsAnonymousWrapper())
+ firstChildIgnoringAnonymousWrappers = currBlock;
+
if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
- return currBlock;
+ return firstChildIgnoringAnonymousWrappers;
if (currBlock->isAnonymousColumnSpanBlock())
return 0;
@@ -443,6 +447,8 @@ RenderBlock* RenderBlock::clone() const
else {
cloneBlock = new (renderArena()) RenderBlock(node());
cloneBlock->setStyle(style());
+ if (!childrenInline() && cloneBlock->firstChild() && cloneBlock->firstChild()->isInline())
+ cloneBlock->makeChildrenNonInline();
}
cloneBlock->setChildrenInline(childrenInline());
return cloneBlock;
@@ -657,12 +663,21 @@ RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
// cross the streams and have to cope with both types of continuations mixed together).
// This function currently supports (1) and (2).
RenderBlock* columnsBlockAncestor = 0;
- if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
- && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
- if (style()->specifiesColumns())
- columnsBlockAncestor = this;
- else if (parent() && parent()->isRenderBlock())
- columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
+ if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
+ && !newChild->isFloatingOrPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
+ columnsBlockAncestor = containingColumnsBlock(false);
+ if (columnsBlockAncestor) {
+ // Make sure that none of the parent ancestors have a continuation.
+ // If yes, we do not want split the block into continuations.
+ RenderObject* curr = this;
+ while (curr && curr != columnsBlockAncestor) {
+ if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
+ columnsBlockAncestor = 0;
+ break;
+ }
+ curr = curr->parent();
+ }
+ }
}
return columnsBlockAncestor;
}
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index fb1dd2c..9c40d5b 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -3260,7 +3260,7 @@ bool RenderBox::shrinkToAvoidFloats() const
bool RenderBox::avoidsFloats() const
{
- return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot();
+ return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isDeprecatedFlexItem();
}
void RenderBox::addShadowOverflow()
diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h
index 1bee989..a5dc1b2 100644
--- a/Source/WebCore/rendering/RenderBox.h
+++ b/Source/WebCore/rendering/RenderBox.h
@@ -378,6 +378,8 @@ public:
virtual void markForPaginationRelayoutIfNeeded() { }
bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); }
+
+ bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrPositioned() && parent() && parent()->isFlexibleBox(); }
virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp
index 8056662..109d219 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp
@@ -122,6 +122,13 @@ String RenderFileUploadControl::acceptTypes()
return static_cast<HTMLInputElement*>(node())->accept();
}
+#if ENABLE(MEDIA_CAPTURE)
+String RenderFileUploadControl::capture()
+{
+ return static_cast<HTMLInputElement*>(node())->capture();
+}
+#endif
+
void RenderFileUploadControl::chooseIconForFiles(FileChooser* chooser, const Vector<String>& filenames)
{
if (Chrome* chromePointer = chrome())
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.h b/Source/WebCore/rendering/RenderFileUploadControl.h
index e9fb7f0..b57260d 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.h
+++ b/Source/WebCore/rendering/RenderFileUploadControl.h
@@ -68,6 +68,9 @@ private:
#endif
String acceptTypes();
void chooseIconForFiles(FileChooser*, const Vector<String>&);
+#if ENABLE(MEDIA_CAPTURE)
+ String capture();
+#endif
Chrome* chrome() const;
int maxFilenameWidth() const;
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp
index dc5c171..99c7e0b 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp
@@ -43,30 +43,30 @@ namespace WebCore {
class FlexBoxIterator {
public:
FlexBoxIterator(RenderFlexibleBox* parent)
+ : m_box(parent)
+ , m_lastOrdinal(1)
{
- box = parent;
- if (box->style()->boxOrient() == HORIZONTAL && !box->style()->isLeftToRightDirection())
- forward = box->style()->boxDirection() != BNORMAL;
+ if (m_box->style()->boxOrient() == HORIZONTAL && !m_box->style()->isLeftToRightDirection())
+ m_forward = m_box->style()->boxDirection() != BNORMAL;
else
- forward = box->style()->boxDirection() == BNORMAL;
- lastOrdinal = 1;
- if (!forward) {
+ m_forward = m_box->style()->boxDirection() == BNORMAL;
+ if (!m_forward) {
// No choice, since we're going backwards, we have to find out the highest ordinal up front.
- RenderBox* child = box->firstChildBox();
+ RenderBox* child = m_box->firstChildBox();
while (child) {
- if (child->style()->boxOrdinalGroup() > lastOrdinal)
- lastOrdinal = child->style()->boxOrdinalGroup();
+ if (child->style()->boxOrdinalGroup() > m_lastOrdinal)
+ m_lastOrdinal = child->style()->boxOrdinalGroup();
child = child->nextSiblingBox();
}
}
-
+
reset();
}
void reset()
{
- current = 0;
- currentOrdinal = forward ? 0 : lastOrdinal+1;
+ m_currentChild = 0;
+ m_currentOrdinal = m_forward ? 0 : m_lastOrdinal + 1;
}
RenderBox* first()
@@ -74,42 +74,42 @@ public:
reset();
return next();
}
-
+
RenderBox* next()
{
- do {
- if (!current) {
- if (forward) {
- currentOrdinal++;
- if (currentOrdinal > lastOrdinal)
+ do {
+ if (!m_currentChild) {
+ if (m_forward) {
+ ++m_currentOrdinal;
+ if (m_currentOrdinal > m_lastOrdinal)
return 0;
- current = box->firstChildBox();
+ m_currentChild = m_box->firstChildBox();
} else {
- currentOrdinal--;
- if (currentOrdinal == 0)
+ --m_currentOrdinal;
+ if (!m_currentOrdinal)
return 0;
- current = box->lastChildBox();
+ m_currentChild = m_box->lastChildBox();
}
}
else
- current = forward ? current->nextSiblingBox() : current->previousSiblingBox();
- if (current && current->style()->boxOrdinalGroup() > lastOrdinal)
- lastOrdinal = current->style()->boxOrdinalGroup();
- } while (!current || current->style()->boxOrdinalGroup() != currentOrdinal ||
- current->style()->visibility() == COLLAPSE);
- return current;
+ m_currentChild = m_forward ? m_currentChild->nextSiblingBox() : m_currentChild->previousSiblingBox();
+ if (m_currentChild && m_currentChild->style()->boxOrdinalGroup() > m_lastOrdinal)
+ m_lastOrdinal = m_currentChild->style()->boxOrdinalGroup();
+ } while (!m_currentChild || (!m_currentChild->isAnonymous()
+ && (m_currentChild->style()->boxOrdinalGroup() != m_currentOrdinal || m_currentChild->style()->visibility() == COLLAPSE)));
+ return m_currentChild;
}
private:
- RenderFlexibleBox* box;
- RenderBox* current;
- bool forward;
- unsigned int currentOrdinal;
- unsigned int lastOrdinal;
+ RenderFlexibleBox* m_box;
+ RenderBox* m_currentChild;
+ bool m_forward;
+ unsigned int m_currentOrdinal;
+ unsigned int m_lastOrdinal;
};
-
+
RenderFlexibleBox::RenderFlexibleBox(Node* node)
-:RenderBlock(node)
+ : RenderBlock(node)
{
setChildrenInline(false); // All of our children must be block-level
m_flexingChildren = m_stretchingChildren = false;
@@ -119,54 +119,48 @@ RenderFlexibleBox::~RenderFlexibleBox()
{
}
+static int marginWidthForChild(RenderBox* child)
+{
+ // A margin basically has three types: fixed, percentage, and auto (variable).
+ // Auto and percentage margins simply become 0 when computing min/max width.
+ // Fixed margins can be added in as is.
+ Length marginLeft = child->style()->marginLeft();
+ Length marginRight = child->style()->marginRight();
+ int margin = 0;
+ if (marginLeft.isFixed())
+ margin += marginLeft.value();
+ if (marginRight.isFixed())
+ margin += marginRight.value();
+ return margin;
+}
+
void RenderFlexibleBox::calcHorizontalPrefWidths()
{
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
- // positioned children don't affect the minmaxwidth
+ // Positioned children and collapsed children don't affect the min/max width.
if (child->isPositioned() || child->style()->visibility() == COLLAPSE)
continue;
- // A margin basically has three types: fixed, percentage, and auto (variable).
- // Auto and percentage margins simply become 0 when computing min/max width.
- // Fixed margins can be added in as is.
- Length ml = child->style()->marginLeft();
- Length mr = child->style()->marginRight();
- int margin = 0, marginLeft = 0, marginRight = 0;
- if (ml.isFixed())
- marginLeft += ml.value();
- if (mr.isFixed())
- marginRight += mr.value();
- margin = marginLeft + marginRight;
-
+ int margin = marginWidthForChild(child);
m_minPreferredLogicalWidth += child->minPreferredLogicalWidth() + margin;
m_maxPreferredLogicalWidth += child->maxPreferredLogicalWidth() + margin;
- }
+ }
}
void RenderFlexibleBox::calcVerticalPrefWidths()
{
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
- // Positioned children and collapsed children don't affect the min/max width
+ // Positioned children and collapsed children don't affect the min/max width.
if (child->isPositioned() || child->style()->visibility() == COLLAPSE)
continue;
- // A margin basically has three types: fixed, percentage, and auto (variable).
- // Auto/percentage margins simply become 0 when computing min/max width.
- // Fixed margins can be added in as is.
- Length ml = child->style()->marginLeft();
- Length mr = child->style()->marginRight();
- int margin = 0;
- if (ml.isFixed())
- margin += ml.value();
- if (mr.isFixed())
- margin += mr.value();
-
- int w = child->minPreferredLogicalWidth() + margin;
- m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
-
- w = child->maxPreferredLogicalWidth() + margin;
- m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
- }
+ int margin = marginWidthForChild(child);
+ int width = child->minPreferredLogicalWidth() + margin;
+ m_minPreferredLogicalWidth = max(width, m_minPreferredLogicalWidth);
+
+ width = child->maxPreferredLogicalWidth() + margin;
+ m_maxPreferredLogicalWidth = max(width, m_maxPreferredLogicalWidth);
+ }
}
void RenderFlexibleBox::computePreferredLogicalWidths()
@@ -197,7 +191,7 @@ void RenderFlexibleBox::computePreferredLogicalWidths()
m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
}
-
+
if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {
m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
@@ -222,10 +216,10 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM
int previousWidth = width();
int previousHeight = height();
-
+
computeLogicalWidth();
computeLogicalHeight();
-
+
m_overflow.clear();
if (previousWidth != width() || previousHeight != height() ||
@@ -280,7 +274,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM
setMaxMarginBeforeValues(pos, neg);
setMaxMarginAfterValues(0, 0);
}
-
+
computeOverflow(oldClientAfterEdge);
statePusher.pop();
@@ -297,15 +291,14 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM
// Repaint with our new bounds if they are different from our old bounds.
repainter.repaintAfterLayout();
-
+
setNeedsLayout(false);
}
// The first walk over our kids is to find out if we have any flexible children.
static void gatherFlexChildrenInfo(FlexBoxIterator& iterator, bool relayoutChildren, unsigned int& highestFlexGroup, unsigned int& lowestFlexGroup, bool& haveFlex)
{
- RenderBox* child = iterator.first();
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
// Check to see if this child flexes.
if (!child->isPositioned() && child->style()->boxFlex() > 0.0f) {
// We always have to lay out flexible objects again, since the flex distribution
@@ -322,7 +315,6 @@ static void gatherFlexChildrenInfo(FlexBoxIterator& iterator, bool relayoutChild
if (flexGroup > highestFlexGroup)
highestFlexGroup = flexGroup;
}
- child = iterator.next();
}
}
@@ -343,8 +335,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
bool haveFlex = false;
gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex);
- RenderBox* child;
-
RenderBlock::startDelayUpdateScrollInfo();
// We do 2 passes. The first pass is simply to lay everyone out at
@@ -354,31 +344,28 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
setHeight(yPos);
xPos = borderLeft() + paddingLeft();
-
+
// Our first pass is done without flexing. We simply lay the children
// out within the box. We have to do a layout first in order to determine
// our box's intrinsic height.
int maxAscent = 0, maxDescent = 0;
- child = iterator.first();
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
// make sure we relayout children if we need it.
if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))
child->setChildNeedsLayout(true, false);
-
- if (child->isPositioned()) {
- child = iterator.next();
+
+ if (child->isPositioned())
continue;
- }
-
+
// Compute the child's vertical margins.
child->computeBlockDirectionMargins(this);
-
+
if (!child->needsLayout())
child->markForPaginationRelayoutIfNeeded();
// Now do the layout.
child->layoutIfNeeded();
-
+
// Update our height and overflow height.
if (style()->boxAlign() == BBASELINE) {
int ascent = child->firstLineBoxBaseline();
@@ -386,38 +373,35 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
ascent = child->height() + child->marginBottom();
ascent += child->marginTop();
int descent = (child->marginTop() + child->height() + child->marginBottom()) - ascent;
-
+
// Update our maximum ascent.
maxAscent = max(maxAscent, ascent);
-
+
// Update our maximum descent.
maxDescent = max(maxDescent, descent);
-
+
// Now update our height.
setHeight(max(yPos + maxAscent + maxDescent, height()));
}
else
setHeight(max(height(), yPos + child->marginTop() + child->height() + child->marginBottom()));
-
- child = iterator.next();
}
-
+
if (!iterator.first() && hasLineIfEmpty())
setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
-
+
setHeight(height() + toAdd);
-
+
oldHeight = height();
computeLogicalHeight();
relayoutChildren = false;
if (oldHeight != height())
heightSpecified = true;
-
+
// Now that our height is actually known, we can place our boxes.
m_stretchingChildren = (style()->boxAlign() == BSTRETCH);
- child = iterator.first();
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
if (child->isPositioned()) {
child->containingBlock()->insertPositionedObject(child);
RenderLayer* childLayer = child->layer();
@@ -427,10 +411,9 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
child->setChildNeedsLayout(true, false);
}
- child = iterator.next();
continue;
}
-
+
// We need to see if this child's height has changed, since we make block elements
// fill the height of a containing box by default.
// Now do a layout.
@@ -438,18 +421,18 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
child->computeLogicalHeight();
if (oldChildHeight != child->height())
child->setChildNeedsLayout(true, false);
-
+
if (!child->needsLayout())
child->markForPaginationRelayoutIfNeeded();
child->layoutIfNeeded();
-
+
// We can place the child now, using our value of box-align.
xPos += child->marginLeft();
int childY = yPos;
switch (style()->boxAlign()) {
case BCENTER:
- childY += child->marginTop() + max(0, (contentHeight() - (child->height() + child->marginTop() + child->marginBottom()))/2);
+ childY += child->marginTop() + max(0, (contentHeight() - (child->height() + child->marginTop() + child->marginBottom())) / 2);
break;
case BBASELINE: {
int ascent = child->firstLineBoxBaseline();
@@ -468,14 +451,12 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
}
placeChild(child, xPos, childY);
-
+
xPos += child->width() + child->marginRight();
-
- child = iterator.next();
}
remainingSpace = borderLeft() + paddingLeft() + contentWidth() - xPos;
-
+
m_stretchingChildren = false;
if (m_flexingChildren)
haveFlex = false; // We're done.
@@ -500,24 +481,20 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
// forces a totalFlex recomputation).
int groupRemainingSpaceAtBeginning = groupRemainingSpace;
float totalFlex = 0.0f;
- child = iterator.first();
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i))
totalFlex += child->style()->boxFlex();
- child = iterator.next();
}
- child = iterator.first();
int spaceAvailableThisPass = groupRemainingSpace;
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
int allowedFlex = allowedChildFlex(child, expanding, i);
if (allowedFlex) {
int projectedFlex = (allowedFlex == INT_MAX) ? allowedFlex : (int)(allowedFlex * (totalFlex / child->style()->boxFlex()));
spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex);
}
- child = iterator.next();
}
- // The flex groups may not have any flexible objects this time around.
+ // The flex groups may not have any flexible objects this time around.
if (!spaceAvailableThisPass || totalFlex == 0.0f) {
// If we just couldn't grow/shrink any more, then it's time to transition to the next flex group.
groupRemainingSpace = 0;
@@ -525,8 +502,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
}
// Now distribute the space to objects.
- child = iterator.first();
- while (child && spaceAvailableThisPass && totalFlex) {
+ for (RenderBox* child = iterator.first(); child && spaceAvailableThisPass && totalFlex; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i)) {
int spaceAdd = (int)(spaceAvailableThisPass * (child->style()->boxFlex()/totalFlex));
if (spaceAdd) {
@@ -538,16 +514,14 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
spaceAvailableThisPass -= spaceAdd;
remainingSpace -= spaceAdd;
groupRemainingSpace -= spaceAdd;
-
+
totalFlex -= child->style()->boxFlex();
}
- child = iterator.next();
}
if (groupRemainingSpace == groupRemainingSpaceAtBeginning) {
- // this is not advancing, avoid getting stuck by distributing the remaining pixels
- child = iterator.first();
+ // This is not advancing, avoid getting stuck by distributing the remaining pixels.
int spaceAdd = groupRemainingSpace > 0 ? 1 : -1;
- while (child && groupRemainingSpace) {
+ for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i)) {
child->setOverrideSize(child->overrideWidth() + spaceAdd);
m_flexingChildren = true;
@@ -555,7 +529,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
remainingSpace -= spaceAdd;
groupRemainingSpace -= spaceAdd;
}
- child = iterator.next();
}
}
} while (groupRemainingSpace);
@@ -578,59 +551,47 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
if (style()->boxPack() == BJUSTIFY) {
// Determine the total number of children.
int totalChildren = 0;
- child = iterator.first();
- while (child) {
- if (child->isPositioned()) {
- child = iterator.next();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ if (child->isPositioned())
continue;
- }
- totalChildren++;
- child = iterator.next();
+ ++totalChildren;
}
// Iterate over the children and space them out according to the
// justification level.
if (totalChildren > 1) {
- totalChildren--;
+ --totalChildren;
bool firstChild = true;
- child = iterator.first();
- while (child) {
- if (child->isPositioned()) {
- child = iterator.next();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ if (child->isPositioned())
continue;
- }
if (firstChild) {
firstChild = false;
- child = iterator.next();
continue;
}
offset += remainingSpace/totalChildren;
remainingSpace -= (remainingSpace/totalChildren);
- totalChildren--;
+ --totalChildren;
- placeChild(child, child->x()+offset, child->y());
- child = iterator.next();
+ placeChild(child, child->x() + offset, child->y());
}
}
} else {
if (style()->boxPack() == BCENTER)
- offset += remainingSpace/2;
+ offset += remainingSpace / 2;
else // END for LTR, START for RTL
offset += remainingSpace;
- child = iterator.first();
- while (child) {
- if (child->isPositioned()) {
- child = iterator.next();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ if (child->isPositioned())
continue;
- }
- placeChild(child, child->x()+offset, child->y());
- child = iterator.next();
+
+ placeChild(child, child->x() + offset, child->y());
}
}
}
-
+
// So that the computeLogicalHeight in layoutBlock() knows to relayout positioned objects because of
// a height change, we revert our height back to the intrinsic height before returning.
if (heightSpecified)
@@ -655,8 +616,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
bool haveFlex = false;
gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex);
- RenderBox* child;
-
// We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of
// mainstream block layout); this is not really part of the XUL box model.
bool haveLineClamp = !style()->lineClamp().isNone();
@@ -673,12 +632,11 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
setHeight(borderTop() + paddingTop());
int minHeight = height() + toAdd;
- child = iterator.first();
- while (child) {
- // make sure we relayout children if we need it.
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ // Make sure we relayout children if we need it.
if (!haveLineClamp && (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))))
child->setChildNeedsLayout(true, false);
-
+
if (child->isPositioned()) {
child->containingBlock()->insertPositionedObject(child);
RenderLayer* childLayer = child->layer();
@@ -688,28 +646,27 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
child->setChildNeedsLayout(true, false);
}
- child = iterator.next();
continue;
- }
-
+ }
+
// Compute the child's vertical margins.
child->computeBlockDirectionMargins(this);
-
+
// Add in the child's marginTop to our height.
setHeight(height() + child->marginTop());
-
+
if (!child->needsLayout())
child->markForPaginationRelayoutIfNeeded();
// Now do a layout.
child->layoutIfNeeded();
-
+
// We can place the child now, using our value of box-align.
int childX = borderLeft() + paddingLeft();
switch (style()->boxAlign()) {
case BCENTER:
case BBASELINE: // Baseline just maps to center for vertical boxes
- childX += child->marginLeft() + max(0, (contentWidth() - (child->width() + child->marginLeft() + child->marginRight()))/2);
+ childX += child->marginLeft() + max(0, (contentWidth() - (child->width() + child->marginLeft() + child->marginRight())) / 2);
break;
case BEND:
if (!style()->isLeftToRightDirection())
@@ -724,19 +681,17 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
childX += contentWidth() - child->marginRight() - child->width();
break;
}
-
+
// Place the child.
placeChild(child, childX, height());
setHeight(height() + child->height() + child->marginBottom());
-
- child = iterator.next();
}
yPos = height();
-
+
if (!iterator.first() && hasLineIfEmpty())
setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
-
+
setHeight(height() + toAdd);
// Negative margins can cause our height to shrink below our minimal height (border/padding).
@@ -751,7 +706,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
heightSpecified = true;
remainingSpace = borderTop() + paddingTop() + contentHeight() - yPos;
-
+
if (m_flexingChildren)
haveFlex = false; // We're done.
else if (haveFlex) {
@@ -775,33 +730,28 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// forces a totalFlex recomputation).
int groupRemainingSpaceAtBeginning = groupRemainingSpace;
float totalFlex = 0.0f;
- child = iterator.first();
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i))
totalFlex += child->style()->boxFlex();
- child = iterator.next();
}
- child = iterator.first();
int spaceAvailableThisPass = groupRemainingSpace;
- while (child) {
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
int allowedFlex = allowedChildFlex(child, expanding, i);
if (allowedFlex) {
int projectedFlex = (allowedFlex == INT_MAX) ? allowedFlex : (int)(allowedFlex * (totalFlex / child->style()->boxFlex()));
spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex);
}
- child = iterator.next();
}
- // The flex groups may not have any flexible objects this time around.
+ // The flex groups may not have any flexible objects this time around.
if (!spaceAvailableThisPass || totalFlex == 0.0f) {
// If we just couldn't grow/shrink any more, then it's time to transition to the next flex group.
groupRemainingSpace = 0;
continue;
}
-
+
// Now distribute the space to objects.
- child = iterator.first();
- while (child && spaceAvailableThisPass && totalFlex) {
+ for (RenderBox* child = iterator.first(); child && spaceAvailableThisPass && totalFlex; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i)) {
int spaceAdd = (int)(spaceAvailableThisPass * (child->style()->boxFlex()/totalFlex));
if (spaceAdd) {
@@ -813,16 +763,14 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
spaceAvailableThisPass -= spaceAdd;
remainingSpace -= spaceAdd;
groupRemainingSpace -= spaceAdd;
-
+
totalFlex -= child->style()->boxFlex();
}
- child = iterator.next();
}
if (groupRemainingSpace == groupRemainingSpaceAtBeginning) {
- // this is not advancing, avoid getting stuck by distributing the remaining pixels
- child = iterator.first();
+ // This is not advancing, avoid getting stuck by distributing the remaining pixels.
int spaceAdd = groupRemainingSpace > 0 ? 1 : -1;
- while (child && groupRemainingSpace) {
+ for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) {
if (allowedChildFlex(child, expanding, i)) {
child->setOverrideSize(child->overrideHeight() + spaceAdd);
m_flexingChildren = true;
@@ -830,7 +778,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
remainingSpace -= spaceAdd;
groupRemainingSpace -= spaceAdd;
}
- child = iterator.next();
}
}
} while (groupRemainingSpace);
@@ -839,7 +786,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// We didn't find any children that could grow.
if (haveFlex && !m_flexingChildren)
haveFlex = false;
- }
+ }
} while (haveFlex);
RenderBlock::finishDelayUpdateScrollInfo();
@@ -850,54 +797,42 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (style()->boxPack() == BJUSTIFY) {
// Determine the total number of children.
int totalChildren = 0;
- child = iterator.first();
- while (child) {
- if (child->isPositioned()) {
- child = iterator.next();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ if (child->isPositioned())
continue;
- }
- totalChildren++;
- child = iterator.next();
+
+ ++totalChildren;
}
-
+
// Iterate over the children and space them out according to the
// justification level.
if (totalChildren > 1) {
- totalChildren--;
+ --totalChildren;
bool firstChild = true;
- child = iterator.first();
- while (child) {
- if (child->isPositioned()) {
- child = iterator.next();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ if (child->isPositioned())
continue;
- }
-
+
if (firstChild) {
firstChild = false;
- child = iterator.next();
continue;
}
offset += remainingSpace/totalChildren;
remainingSpace -= (remainingSpace/totalChildren);
- totalChildren--;
- placeChild(child, child->x(), child->y()+offset);
- child = iterator.next();
+ --totalChildren;
+ placeChild(child, child->x(), child->y() + offset);
}
}
} else {
if (style()->boxPack() == BCENTER)
- offset += remainingSpace/2;
+ offset += remainingSpace / 2;
else // END
offset += remainingSpace;
- child = iterator.first();
- while (child) {
- if (child->isPositioned()) {
- child = iterator.next();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ if (child->isPositioned())
continue;
- }
- placeChild(child, child->x(), child->y()+offset);
- child = iterator.next();
+ placeChild(child, child->x(), child->y() + offset);
}
}
}
@@ -905,7 +840,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// So that the computeLogicalHeight in layoutBlock() knows to relayout positioned objects because of
// a height change, we revert our height back to the intrinsic height before returning.
if (heightSpecified)
- setHeight(oldHeight);
+ setHeight(oldHeight);
}
void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutChildren)
@@ -940,16 +875,16 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC
for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow())
continue;
-
+
RenderBlock* blockChild = toRenderBlock(child);
int lineCount = blockChild->lineCount();
if (lineCount <= numVisibleLines)
continue;
-
+
int newHeight = blockChild->heightForLineCount(numVisibleLines);
if (newHeight == child->height())
continue;
-
+
child->setChildNeedsLayout(true, false);
child->setOverrideSize(newHeight);
m_flexingChildren = true;
@@ -962,11 +897,11 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC
continue;
// Get the last line
- RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount-1);
+ RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount - 1);
if (!lastLine)
continue;
- RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1);
+ RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines - 1);
if (!lastVisibleLine)
continue;
@@ -975,7 +910,7 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC
DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
const Font& font = style(numVisibleLines == 1)->font();
- // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
+ // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
int totalWidth;
InlineBox* anchorBox = lastLine->lastChild();
if (anchorBox && anchorBox->renderer()->style()->isLink())
@@ -988,7 +923,7 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC
// See if this width can be accommodated on the last visible line
RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());
RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());
-
+
// FIXME: Directions of src/destBlock could be different from our direction and from one another.
if (!srcBlock->style()->isLeftToRightDirection())
continue;
@@ -1028,57 +963,55 @@ int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsign
{
if (child->isPositioned() || child->style()->boxFlex() == 0.0f || child->style()->boxFlexGroup() != group)
return 0;
-
+
if (expanding) {
if (isHorizontal()) {
// FIXME: For now just handle fixed values.
- int maxW = INT_MAX;
- int w = child->overrideWidth() - child->borderAndPaddingWidth();
- if (!child->style()->maxWidth().isUndefined() &&
- child->style()->maxWidth().isFixed())
- maxW = child->style()->maxWidth().value();
+ int maxWidth = INT_MAX;
+ int width = child->overrideWidth() - child->borderAndPaddingWidth();
+ if (!child->style()->maxWidth().isUndefined() && child->style()->maxWidth().isFixed())
+ maxWidth = child->style()->maxWidth().value();
else if (child->style()->maxWidth().type() == Intrinsic)
- maxW = child->maxPreferredLogicalWidth();
+ maxWidth = child->maxPreferredLogicalWidth();
else if (child->style()->maxWidth().type() == MinIntrinsic)
- maxW = child->minPreferredLogicalWidth();
- if (maxW == INT_MAX)
- return maxW;
- return max(0, maxW - w);
+ maxWidth = child->minPreferredLogicalWidth();
+ if (maxWidth == INT_MAX)
+ return maxWidth;
+ return max(0, maxWidth - width);
} else {
// FIXME: For now just handle fixed values.
- int maxH = INT_MAX;
- int h = child->overrideHeight() - child->borderAndPaddingHeight();
- if (!child->style()->maxHeight().isUndefined() &&
- child->style()->maxHeight().isFixed())
- maxH = child->style()->maxHeight().value();
- if (maxH == INT_MAX)
- return maxH;
- return max(0, maxH - h);
+ int maxHeight = INT_MAX;
+ int height = child->overrideHeight() - child->borderAndPaddingHeight();
+ if (!child->style()->maxHeight().isUndefined() && child->style()->maxHeight().isFixed())
+ maxHeight = child->style()->maxHeight().value();
+ if (maxHeight == INT_MAX)
+ return maxHeight;
+ return max(0, maxHeight - height);
}
}
// FIXME: For now just handle fixed values.
if (isHorizontal()) {
- int minW = child->minPreferredLogicalWidth();
- int w = child->overrideWidth() - child->borderAndPaddingWidth();
+ int minWidth = child->minPreferredLogicalWidth();
+ int width = child->overrideWidth() - child->borderAndPaddingWidth();
if (child->style()->minWidth().isFixed())
- minW = child->style()->minWidth().value();
+ minWidth = child->style()->minWidth().value();
else if (child->style()->minWidth().type() == Intrinsic)
- minW = child->maxPreferredLogicalWidth();
+ minWidth = child->maxPreferredLogicalWidth();
else if (child->style()->minWidth().type() == MinIntrinsic)
- minW = child->minPreferredLogicalWidth();
-
- int allowedShrinkage = min(0, minW - w);
+ minWidth = child->minPreferredLogicalWidth();
+
+ int allowedShrinkage = min(0, minWidth - width);
return allowedShrinkage;
} else {
if (child->style()->minHeight().isFixed()) {
- int minH = child->style()->minHeight().value();
- int h = child->overrideHeight() - child->borderAndPaddingHeight();
- int allowedShrinkage = min(0, minH - h);
+ int minHeight = child->style()->minHeight().value();
+ int height = child->overrideHeight() - child->borderAndPaddingHeight();
+ int allowedShrinkage = min(0, minHeight - height);
return allowedShrinkage;
}
}
-
+
return 0;
}
diff --git a/Source/WebCore/rendering/RenderFrame.cpp b/Source/WebCore/rendering/RenderFrame.cpp
index 4b1444b..0ae6eda 100644
--- a/Source/WebCore/rendering/RenderFrame.cpp
+++ b/Source/WebCore/rendering/RenderFrame.cpp
@@ -64,7 +64,12 @@ void RenderFrame::layout()
{
FrameView* view = static_cast<FrameView*>(widget());
RenderView* root = view ? view->frame()->contentRenderer() : 0;
+
+ // Do not expand frames which has zero width or height
if (!width() || !height() || !root) {
+ updateWidgetPosition();
+ if (view)
+ view->layout();
setNeedsLayout(false);
return;
}
@@ -75,14 +80,17 @@ void RenderFrame::layout()
return;
}
- int layoutWidth = width();
+ // Update the dimensions to get the correct width and height
+ updateWidgetPosition();
+ if (root->preferredLogicalWidthsDirty())
+ root->computePreferredLogicalWidths();
+ // Expand the frame by setting frame height = content height
setWidth(max(view->contentsWidth() + borderAndPaddingWidth(), width()));
setHeight(max(view->contentsHeight() + borderAndPaddingHeight(), height()));
- // Trigger a layout of the FrameView which will schedule a relayout of this RenderFrame.
- if (layoutWidth < width())
- view->layout();
+ // Update one more time
+ updateWidgetPosition();
setNeedsLayout(false);
}
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 733a418..1871b57 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -628,6 +628,7 @@ bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* lis
bool fixedSibling = false;
bool positionedSibling = false;
+#if 0
// For absolute positioned elements, we need to check if they are followed
// by a composited element; if so, they also need to be composited, as the
// layer display rendering might be incorrect (absolute elements being
@@ -650,6 +651,7 @@ bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* lis
break;
}
}
+#endif
// If we find a fixed layer, let's mark all the following layers as being
// composited. The layers' surfaces will be merged if needed UI-side.
@@ -737,7 +739,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
bool willBeComposited = needsToBeComposited(layer);
-#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+#if 0 && ENABLE(COMPOSITED_FIXED_ELEMENTS)
willBeComposited |= layer->shouldComposite();
layer->setMustOverlapCompositedLayers(layer->shouldComposite());
#endif
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index 8caef04..f37753e 100644
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -2029,6 +2029,10 @@ RenderObject* RenderObject::container(RenderBoxModelObject* repaintContainer, bo
while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
if (repaintContainerSkipped && o == repaintContainer)
*repaintContainerSkipped = true;
+#if ENABLE(SVG)
+ if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it
+ break;
+#endif
o = o->parent();
}
}
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index 005c453..f5fe562 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -312,6 +312,7 @@ public:
inline bool isBeforeContent() const;
inline bool isAfterContent() const;
+ inline bool isBeforeOrAfterContent() const;
static inline bool isBeforeContent(const RenderObject* obj) { return obj && obj->isBeforeContent(); }
static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); }
@@ -917,6 +918,11 @@ inline bool RenderObject::isAfterContent() const
return true;
}
+inline bool RenderObject::isBeforeOrAfterContent() const
+{
+ return isBeforeContent() || isAfterContent();
+}
+
inline void RenderObject::setNeedsLayout(bool b, bool markParents)
{
bool alreadyNeededLayout = m_needsLayout;
diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp
index c27d336..09a7944 100644
--- a/Source/WebCore/rendering/RenderReplaced.cpp
+++ b/Source/WebCore/rendering/RenderReplaced.cpp
@@ -57,6 +57,14 @@ RenderReplaced::~RenderReplaced()
{
}
+void RenderReplaced::destroy()
+{
+ if (!documentBeingDestroyed() && parent())
+ parent()->dirtyLinesFromChangedChild(this);
+
+ RenderBox::destroy();
+}
+
void RenderReplaced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBox::styleDidChange(diff, oldStyle);
diff --git a/Source/WebCore/rendering/RenderReplaced.h b/Source/WebCore/rendering/RenderReplaced.h
index d6ebba6..29fc71c 100644
--- a/Source/WebCore/rendering/RenderReplaced.h
+++ b/Source/WebCore/rendering/RenderReplaced.h
@@ -32,6 +32,8 @@ public:
RenderReplaced(Node*, const IntSize& intrinsicSize);
virtual ~RenderReplaced();
+ virtual void destroy();
+
protected:
virtual void layout();
diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp
index 894d689..97444cd 100644
--- a/Source/WebCore/rendering/RenderWidget.cpp
+++ b/Source/WebCore/rendering/RenderWidget.cpp
@@ -125,6 +125,10 @@ void RenderWidget::destroy()
document()->axObjectCache()->childrenChanged(this->parent());
document()->axObjectCache()->remove(this);
}
+
+ if (!documentBeingDestroyed() && parent())
+ parent()->dirtyLinesFromChangedChild(this);
+
remove();
if (m_hasCounterNodeMap)
diff --git a/Source/WebCore/workers/WorkerLocation.cpp b/Source/WebCore/workers/WorkerLocation.cpp
index b934abd..319a528 100644
--- a/Source/WebCore/workers/WorkerLocation.cpp
+++ b/Source/WebCore/workers/WorkerLocation.cpp
@@ -36,7 +36,7 @@ namespace WebCore {
String WorkerLocation::href() const
{
- return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/";
+ return m_url.string();
}
String WorkerLocation::protocol() const
@@ -74,11 +74,6 @@ String WorkerLocation::hash() const
return m_url.fragmentIdentifier().isEmpty() ? "" : "#" + m_url.fragmentIdentifier();
}
-String WorkerLocation::toString() const
-{
- return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/";
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/workers/WorkerLocation.h b/Source/WebCore/workers/WorkerLocation.h
index 5200e35..692c0e3 100644
--- a/Source/WebCore/workers/WorkerLocation.h
+++ b/Source/WebCore/workers/WorkerLocation.h
@@ -30,10 +30,10 @@
#if ENABLE(WORKERS)
#include "KURL.h"
-#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -57,7 +57,7 @@ namespace WebCore {
String search() const;
String hash() const;
- String toString() const;
+ String toString() const { return href(); }
private:
WorkerLocation(const KURL& url) : m_url(url) { }