summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk5
-rw-r--r--CleanSpec.mk1
-rw-r--r--NOTICE175
-rw-r--r--Source/JavaScriptCore/wtf/HashTraits.h3
-rw-r--r--Source/JavaScriptCore/wtf/text/StringHash.h2
-rw-r--r--Source/WebCore/Android.mk112
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp6
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h4
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp2
-rw-r--r--Source/WebCore/page/FrameView.cpp5
-rw-r--r--Source/WebCore/page/Settings.cpp10
-rw-r--r--Source/WebCore/page/Settings.h8
-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.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.cpp267
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h72
-rw-r--r--Source/WebCore/platform/graphics/android/GradientAndroid.cpp63
-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.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/ZoomManager.cpp185
-rw-r--r--Source/WebCore/platform/graphics/android/ZoomManager.h118
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp648
-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)0
-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.cpp (renamed from Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp)37
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h59
-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)2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp (renamed from Source/WebCore/platform/graphics/android/LayerAndroid.cpp)108
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/LayerAndroid.h)37
-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)0
-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)84
-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)81
-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)19
-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)16
-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)28
-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)114
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h (renamed from Source/WebCore/platform/graphics/android/ShaderProgram.h)45
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp (renamed from Source/WebCore/platform/graphics/android/LayerGroup.cpp)193
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.h (renamed from Source/WebCore/platform/graphics/android/LayerGroup.h)52
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp171
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h (renamed from Source/WebCore/platform/graphics/android/TiledTexture.h)103
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp218
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h (renamed from Source/WebCore/platform/graphics/android/SurfaceCollection.h)23
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp (renamed from Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp)114
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h (renamed from Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h)9
-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)106
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h (renamed from Source/WebCore/platform/graphics/android/BaseTile.h)47
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp (renamed from Source/WebCore/platform/graphics/android/TiledTexture.cpp)345
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.h87
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilePainter.h (renamed from Source/WebCore/platform/graphics/android/TilePainter.h)6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp (renamed from Source/WebCore/platform/graphics/android/BaseTileTexture.cpp)67
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileTexture.h (renamed from Source/WebCore/platform/graphics/android/BaseTileTexture.h)33
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp (renamed from Source/WebCore/platform/graphics/android/TilesManager.cpp)83
-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)117
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h (renamed from Source/WebCore/platform/graphics/android/TransferQueue.h)33
-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/plugins/android/PluginViewAndroid.cpp5
-rw-r--r--Source/WebCore/rendering/RenderFrame.cpp16
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp4
-rw-r--r--Source/WebKit/android/AndroidLog.h25
-rw-r--r--Source/WebKit/android/RenderSkinMediaButton.cpp3
-rw-r--r--Source/WebKit/android/RenderSkinNinePatch.cpp2
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp6
-rw-r--r--Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp11
-rw-r--r--Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp64
-rw-r--r--Source/WebKit/android/jni/PictureSet.cpp38
-rw-r--r--Source/WebKit/android/jni/PictureSet.h10
-rw-r--r--Source/WebKit/android/jni/ViewStateSerializer.cpp10
-rw-r--r--Source/WebKit/android/jni/WebFrameView.cpp44
-rw-r--r--Source/WebKit/android/jni/WebSettings.cpp11
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp188
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h150
-rw-r--r--Source/WebKit/android/nav/DrawExtra.h1
-rw-r--r--Source/WebKit/android/nav/SelectText.h3
-rw-r--r--Source/WebKit/android/nav/WebView.cpp256
-rw-r--r--Source/WebKit/android/plugins/ANPSurfaceInterface.cpp14
-rw-r--r--Source/WebKit/android/plugins/PluginWidgetAndroid.cpp3
170 files changed, 6721 insertions, 5187 deletions
diff --git a/Android.mk b/Android.mk
index d01ef64..61bd467 100644
--- a/Android.mk
+++ b/Android.mk
@@ -127,6 +127,11 @@ LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) \
$(WEBCORE_PATH)/platform/animation \
$(WEBCORE_PATH)/platform/graphics \
$(WEBCORE_PATH)/platform/graphics/android \
+ $(WEBCORE_PATH)/platform/graphics/android/context \
+ $(WEBCORE_PATH)/platform/graphics/android/fonts \
+ $(WEBCORE_PATH)/platform/graphics/android/layers \
+ $(WEBCORE_PATH)/platform/graphics/android/rendering \
+ $(WEBCORE_PATH)/platform/graphics/android/utils \
$(WEBCORE_PATH)/platform/graphics/filters \
$(WEBCORE_PATH)/platform/graphics/gpu \
$(WEBCORE_PATH)/platform/graphics/network \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index fda2cf9..d2841a3 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -81,6 +81,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_int
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/NOTICE b/NOTICE
index 92c7323..fc77db5 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,57 +1,79 @@
-Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+(WebKit doesn't distribute an explicit license. This LICENSE is derived from
+license text in the source.)
+
+Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+2006, 2007 Alexander Kellett, Alexey Proskuryakov, Alex Mathews, Allan
+Sandfeld Jensen, Alp Toker, Anders Carlsson, Andrew Wellington, Antti
+Koivisto, Apple Inc., Arthur Langereis, Baron Schwartz, Bjoern Graf,
+Brent Fulgham, Cameron Zwarich, Charles Samuels, Christian Dywan,
+Collabora Ltd., Cyrus Patel, Daniel Molkentin, Dave Maclachlan, David
+Smith, Dawit Alemayehu, Dirk Mueller, Dirk Schulze, Don Gibson, Enrico
+Ros, Eric Seidel, Frederik Holljen, Frerich Raabe, Friedmann Kleint,
+George Staikos, Google Inc., Graham Dennis, Harri Porten, Henry Mason,
+Hiroyuki Ikezoe, Holger Hans Peter Freyther, IBM, James G. Speth, Jan
+Alonzo, Jean-Loup Gailly, John Reis, Jonas Witt, Jon Shier, Jonas
+Witt, Julien Chaffraix, Justin Haygood, Kevin Ollivier, Kevin Watters,
+Kimmo Kinnunen, Kouhei Sutou, Krzysztof Kowalczyk, Lars Knoll, Luca
+Bruno, Maks Orlovich, Malte Starostik, Mark Adler, Martin Jones,
+Marvin Decker, Matt Lilek, Michael Emmel, Mitz Pettel, mozilla.org,
+Netscape Communications Corporation, Nicholas Shanks, Nikolas
+Zimmermann, Nokia, Oliver Hunt, Opened Hand, Paul Johnston, Peter
+Kelly, Pioneer Research Center USA, Rich Moore, Rob Buis, Robin Dunn,
+Ronald Tschalär, Samuel Weinig, Simon Hausmann, Staikos Computing
+Services Inc., Stefan Schimanski, Symantec Corporation, The Dojo
+Foundation, The Karbon Developers, Thomas Boyer, Tim Copperfield,
+Tobias Anton, Torben Weis, Trolltech, University of Cambridge, Vaclav
+Slavik, Waldo Bastian, Xan Lopez, Zack Rusin
+
+The terms and conditions vary from file to file, but are one of:
Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. 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.
-3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- its contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS 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.
-
-Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+*OR*
Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
+modification, are permitted provided that the following conditions are
+met:
+
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
+ documentation and/or other materials provided with the
+ distribution.
+3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ its contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. OR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. 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.
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -484,55 +506,12 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -676,7 +655,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
-
+
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
@@ -986,47 +965,3 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/Source/JavaScriptCore/wtf/HashTraits.h b/Source/JavaScriptCore/wtf/HashTraits.h
index fba5afe..7deeb3a 100644
--- a/Source/JavaScriptCore/wtf/HashTraits.h
+++ b/Source/JavaScriptCore/wtf/HashTraits.h
@@ -28,6 +28,8 @@
namespace WTF {
+ class String;
+
using std::pair;
using std::make_pair;
@@ -88,6 +90,7 @@ namespace WTF {
};
template<typename P> struct HashTraits<RefPtr<P> > : SimpleClassHashTraits<RefPtr<P> > { };
+ template<> struct HashTraits<String> : SimpleClassHashTraits<String> { };
// special traits for pairs, helpful for their use in HashMap implementation
diff --git a/Source/JavaScriptCore/wtf/text/StringHash.h b/Source/JavaScriptCore/wtf/text/StringHash.h
index c47c1d8..497184d 100644
--- a/Source/JavaScriptCore/wtf/text/StringHash.h
+++ b/Source/JavaScriptCore/wtf/text/StringHash.h
@@ -179,8 +179,6 @@ namespace WTF {
}
};
- template<> struct HashTraits<String> : SimpleClassHashTraits<String> { };
-
}
using WTF::StringHash;
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index 816b163..3cf8d54 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -633,66 +633,74 @@ 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) \
@@ -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/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/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/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/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/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.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..1b0513b 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_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,21 +192,6 @@ 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)
@@ -363,7 +229,6 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib
double currentTime = WTF::currentTime();
setViewport(visibleRect, scale);
- m_zoomManager.processNewScale(currentTime, scale);
return currentTime;
}
@@ -429,43 +294,22 @@ 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)
+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);
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)",
rect.x(), rect.y(), rect.width(), rect.height(),
viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom);
@@ -481,15 +325,17 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
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 +343,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 +362,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 +400,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..6d969dd 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,50 +166,27 @@ 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();
@@ -225,9 +197,6 @@ public:
m_goingLeft = goingLeft;
}
- int expandedTileBoundsX() { return m_expandedTileBoundsX; }
- int expandedTileBoundsY() { return m_expandedTileBoundsY; }
-
float scale() { return m_scale; }
enum LayersRenderingMode {
@@ -242,10 +211,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 +221,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 +237,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
index 6007a0a..7bc69c5 100644
--- a/Source/WebCore/platform/graphics/android/GradientAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GradientAndroid.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "Gradient.h"
-#include "android_graphics.h"
#include "CSSParser.h"
#include "GraphicsContext.h"
#include "NotImplemented.h"
@@ -35,16 +34,6 @@
#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()
@@ -58,12 +47,10 @@ static U8CPU F2B(float x)
return (int)(x * 255);
}
-SkShader* Gradient::getShader(SkShader::TileMode mode)
+SkShader* Gradient::platformGradient()
{
- if (NULL == m_gradient)
- m_gradient = new PlatformGradientRec;
- else if (mode == m_gradient->m_tileMode)
- return m_gradient->m_shader;
+ if (m_gradient)
+ return m_gradient;
// need to ensure that the m_stops array is sorted. We call getColor()
// which, as a side effect, does the sort.
@@ -73,6 +60,19 @@ SkShader* Gradient::getShader(SkShader::TileMode mode)
this->getColor(0, &r, &g, &b, &a);
}
+ SkShader::TileMode mode = SkShader::kClamp_TileMode;
+ switch (m_spreadMethod) {
+ case SpreadMethodReflect:
+ mode = SkShader::kMirror_TileMode;
+ break;
+ case SpreadMethodRepeat:
+ mode = SkShader::kRepeat_TileMode;
+ break;
+ case SpreadMethodPad:
+ mode = SkShader::kClamp_TileMode;
+ break;
+ }
+
SkPoint pts[2] = { m_p0, m_p1 }; // convert to SkPoint
const size_t count = m_stops.size();
@@ -88,39 +88,28 @@ SkShader* Gradient::getShader(SkShader::TileMode mode)
++iter;
}
- SkShader* s;
- if (m_radial)
- s = SkGradientShader::CreateTwoPointRadial(pts[0],
+ if (m_radial) {
+ m_gradient = 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);
+ } else
+ m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, count, mode);
- if (NULL == s)
- s = new SkColorShader(0);
+ if (!m_gradient)
+ m_gradient = 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);
+ m_gradient->setLocalMatrix(matrix);
- return s;
+ return m_gradient;
}
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);
+ context->setFillGradient(this);
+ context->fillRect(rect);
}
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.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/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..12b53a3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp
@@ -0,0 +1,648 @@
+/*
+ * 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 SkShader* extractShader(Pattern* pat, Gradient* grad)
+{
+ if (pat)
+ return pat->platformPattern(AffineTransform());
+ else if (grad)
+ return grad->platformGradient();
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+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;
+
+ platformContext()->drawRect(rect);
+}
+
+// This is only used to draw borders.
+void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->drawLine(point1, point2);
+}
+
+void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool /* printing */)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->drawLineForText(pt, width);
+}
+
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width,
+ TextCheckingLineStyle style)
+{
+ if (paintingDisabled())
+ return;
+
+ 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;
+
+ platformContext()->drawEllipse(rect);
+}
+
+void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->strokeArc(r, startAngle, angleSpan);
+}
+
+void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points,
+ bool shouldAntialias)
+{
+ if (paintingDisabled())
+ return;
+
+ 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;
+
+ platformContext()->fillRoundedRect(rect, topLeft, topRight,
+ bottomLeft, bottomRight, color, colorSpace);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->fillRect(rect);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ 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;
+ platformContext()->setupPaintFill(paint);
+}
+
+void GraphicsContext::setupStrokePaint(SkPaint* paint)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setupPaintStroke(paint, 0);
+}
+
+bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset)
+{
+ if (paintingDisabled())
+ return false;
+ return platformContext()->setupPaintShadow(paint, offset);
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setStrokeColor(c);
+}
+
+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)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->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
+ 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;
+
+ 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;
+
+ platformContext()->clearRect(rect);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
+{
+ if (paintingDisabled())
+ return;
+
+ 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)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(0, fillGradient);
+ platformContext()->setFillShader(shader);
+}
+
+void GraphicsContext::setPlatformFillPattern(Pattern* fillPattern)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(fillPattern, 0);
+ platformContext()->setFillShader(shader);
+}
+
+void GraphicsContext::setPlatformStrokeGradient(Gradient* strokeGradient)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(0, strokeGradient);
+ platformContext()->setStrokeShader(shader);
+}
+
+void GraphicsContext::setPlatformStrokePattern(Pattern* strokePattern)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(strokePattern, 0);
+ platformContext()->setStrokeShader(shader);
+}
+
+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;
+
+ platformContext()->fillPath(pathToFill, fillRule());
+}
+
+void GraphicsContext::strokePath(const Path& pathToStroke)
+{
+ if (paintingDisabled())
+ return;
+
+ 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;
+
+ 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..a327b79 100644
--- a/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp
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/PlatformGraphicsContext.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
index 098534c..1de5ae7 100644
--- a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2006, The Android Open Source Project
+ * 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
@@ -23,29 +23,34 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "BaseLayerAndroid"
+#define LOG_NDEBUG 1
+
#include "config.h"
-#include "Node.h"
-#include "PlatformGraphicsContext.h"
-#include "SkCanvas.h"
+#include "BaseLayerAndroid.h"
+
+#include "AndroidLog.h"
+#include "GLWebViewState.h"
+#include "LayerContent.h"
namespace WebCore {
-PlatformGraphicsContext::PlatformGraphicsContext(SkCanvas* canvas)
- : mCanvas(canvas), m_deleteCanvas(false)
-{
-}
+// Note: this must match the use of ID 0 specifying the base layer in DrawExtra
+#define BASE_UNIQUE_ID 0
-PlatformGraphicsContext::PlatformGraphicsContext()
- : mCanvas(new SkCanvas), m_deleteCanvas(true)
+BaseLayerAndroid::BaseLayerAndroid(LayerContent* content)
+ : LayerAndroid((RenderLayer*)0)
+ , m_color(Color::white)
{
+ setContent(content);
+ setSize(content->width(), content->height());
+ m_uniqueId = BASE_UNIQUE_ID;
}
-PlatformGraphicsContext::~PlatformGraphicsContext()
+void BaseLayerAndroid::getLocalTransform(SkMatrix* matrix) const
{
- if (m_deleteCanvas) {
-// printf("-------------------- deleting offscreen canvas\n");
- delete mCanvas;
- }
+ // base layer doesn't use size in transform calculation
+ matrix->preConcat(getMatrix());
}
-} // WebCore
+} // 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..0ef39c8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
@@ -0,0 +1,59 @@
+/*
+ * 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; }
+
+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..996547b 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.
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 946d2a3..df3fa42 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
}
@@ -483,6 +460,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) {
@@ -679,16 +659,16 @@ 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 +690,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 +700,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 +732,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 +745,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 +753,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 +771,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;
@@ -920,10 +910,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)
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 7436676..6239418 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);
@@ -271,16 +274,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 +331,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 +361,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..1f289e6 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h
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..833aea9 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);
+ 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..26bd55d 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);
@@ -609,6 +647,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..bf43652 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)
{
@@ -69,7 +72,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
@@ -146,7 +149,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 +162,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..b2ead6a 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 {
@@ -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));
@@ -173,7 +174,8 @@ bool ImageTexture::prepareGL(GLWebViewState* state)
return false;
if (!m_texture && m_picture) {
- m_texture = new TiledTexture();
+ bool isLayerTile = true;
+ m_texture = new TileGrid(isLayerTile);
SkRegion region;
region.setRect(0, 0, m_image->width(), m_image->height());
m_texture->markAsDirty(region);
@@ -182,8 +184,8 @@ bool ImageTexture::prepareGL(GLWebViewState* state)
if (!m_texture)
return false;
- IntRect visibleArea(0, 0, m_image->width(), m_image->height());
- m_texture->prepareGL(state, 1.0, visibleArea, this);
+ IntRect unclippedArea(0, 0, m_image->width(), m_image->height());
+ m_texture->prepareGL(state, 1.0, unclippedArea, unclippedArea, this);
if (m_texture->isReady()) {
m_texture->swapTiles();
return false;
@@ -215,7 +217,7 @@ float ImageTexture::opacity()
return m_layer->drawOpacity();
}
-bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas)
+bool ImageTexture::paint(Tile* tile, SkCanvas* canvas)
{
if (!m_picture) {
ALOGV("IT %p COULDNT PAINT, NO PICTURE", this);
@@ -235,7 +237,7 @@ 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) {
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
index 91c8a29..34430f1 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(Tile* tile, SkCanvas* canvas);
virtual float opacity();
int nbTextures();
@@ -97,7 +98,7 @@ private:
SkBitmapRef* m_imageRef;
SkBitmap* m_image;
- TiledTexture* m_texture;
+ TileGrid* m_texture;
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..b5e435b 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);
@@ -80,14 +87,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 +102,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..a0d9e56 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"
@@ -423,24 +424,6 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR
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);
-}
-
// Calculate the right color value sent into the shader considering the (0,1)
// clamp and alpha blending.
Color ShaderProgram::shaderColor(Color pureColor, float opacity)
@@ -482,33 +465,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 +515,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.
@@ -639,16 +598,20 @@ 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)
+// Calculate the matrix given the geometry.
+GLfloat* ShaderProgram::getProjectionMatrix(const DrawQuadData* data)
{
- TransformationMatrix modifiedDrawMatrix = drawMatrix;
+ DrawQuadType type = data->type();
+ const TransformationMatrix* matrix = data->drawMatrix();
+ const SkRect* geometry = data->geometry();
+ if (type == Blit)
+ return m_transferProjMtx;
+ TransformationMatrix modifiedDrawMatrix;
+ if (type == LayerQuad)
+ modifiedDrawMatrix = *matrix;
// 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);
+ modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop);
+ modifiedDrawMatrix.scale3d(geometry->width(), geometry->height(), 1);
TransformationMatrix renderMatrix;
if (!m_alphaLayer)
@@ -657,26 +620,39 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
else
renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
- GLfloat projectionMatrix[16];
- GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
+ GLUtils::toGLMatrix(m_tileProjMatrix, renderMatrix);
+ return m_tileProjMatrix;
+}
+
+void ShaderProgram::drawQuad(const DrawQuadData* data)
+{
+ GLfloat* matrix = getProjectionMatrix(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,
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
index 98d45b5..b233f2b 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
@@ -30,6 +30,10 @@
namespace WebCore {
+class DrawQuadData;
+class PureColorQuadData;
+class TextureQuadData;
+
enum ShaderType {
UndefinedShader = -1,
PureColor,
@@ -45,14 +49,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 +86,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 +122,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,
@@ -170,7 +167,7 @@ public:
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
GLint createProgram(const char* vertexSource, const char* fragmentSource);
- void setProjectionMatrix(const SkRect& geometry, GLfloat* mtxPtr);
+ GLfloat* getProjectionMatrix(const DrawQuadData* data);
void setBlendingState(bool enableBlending);
void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
float opacity, GLenum textureTarget, GLenum filter,
@@ -226,6 +223,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..3ed3aad 100644
--- a/Source/WebCore/platform/graphics/android/LayerGroup.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -23,80 +23,82 @@
* 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 "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 +110,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 +135,14 @@ 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());
}
}
-IntRect LayerGroup::visibleArea()
+IntRect Surface::visibleArea()
{
if (singleLayer())
return getFirstLayer()->visibleArea();
@@ -156,78 +158,106 @@ IntRect LayerGroup::visibleArea()
return rect;
}
-void LayerGroup::prepareGL(bool layerTilesDisabled)
+IntRect Surface::unclippedArea()
{
- if (!m_dualTiledTexture) {
- ALOGV("prepareGL on LG %p, no DTT, needsTexture? %d",
- this, m_dualTiledTexture, needsTexture());
+ 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());
+}
- if (needsTexture())
- m_dualTiledTexture = new DualTiledTexture();
- else
+void Surface::prepareGL(bool layerTilesDisabled)
+{
+ bool tilesDisabled = layerTilesDisabled && !isBase();
+ if (!m_surfaceBacking) {
+ ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d",
+ this, m_surfaceBacking, needsTexture());
+
+ 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 Surf %p with SurfBack %p, %d layers",
+ this, m_surfaceBacking, m_layers.size());
- ALOGV("prepareGL on LG %p with DTT %p, %d layers",
- this, m_dualTiledTexture, m_layers.size());
- m_dualTiledTexture->prepareGL(getFirstLayer()->state(), allowZoom,
- prepareArea, this);
+ 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 LayerGroup::isReady()
+bool Surface::isReady()
{
- if (!m_dualTiledTexture)
+ if (!m_surfaceBacking)
return true;
- return m_dualTiledTexture->isReady();
+ return m_surfaceBacking->isReady();
}
-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 +269,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 LayerGroup::paint(BaseTile* tile, SkCanvas* canvas)
+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 Surface::paint(Tile* tile, 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 +318,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..27c997e 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,71 @@ 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();
- IntRect computePrepareArea();
void computeTexturesAmount(TexturesResult* result);
LayerAndroid* getFirstLayer() { return m_layers[0]; }
- bool singleLayer() { return m_layers.size() == 1; }
bool needsTexture() { return m_needsTexture; }
bool hasText() { return m_hasText; }
+ bool isBase();
+ void setBackground(Color background) { m_background = background; }
// TilePainter methods
- virtual bool paint(BaseTile* tile, SkCanvas* canvas);
+ virtual bool paint(Tile* tile, SkCanvas* canvas);
virtual float opacity();
+ virtual Color* background();
+
private:
+ IntRect computePrepareArea();
+ IntRect visibleArea();
+ IntRect unclippedArea();
+ bool singleLayer() { return m_layers.size() == 1; }
+ void updateBackground(const Color& background);
+ 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 +112,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..7c8f570
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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_frontTexture = new TileGrid(isBaseSurface);
+ m_backTexture = new TileGrid(isBaseSurface);
+ m_scale = -1;
+ m_futureScale = -1;
+ m_zooming = false;
+}
+
+SurfaceBacking::~SurfaceBacking()
+{
+ delete m_frontTexture;
+ delete m_backTexture;
+}
+
+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;
+ }
+
+ bool useExpandPrefetch = aggressiveRendering;
+ 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_frontTexture, m_backTexture);
+
+ if (!m_zooming) {
+ m_frontTexture->prepareGL(state, m_scale,
+ prepareArea, unclippedArea, painter, false, useExpandPrefetch);
+ if (aggressiveRendering) {
+ // prepare the back tiled texture to render content in low res
+ float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER;
+ m_backTexture->prepareGL(state, lowResPrefetchScale,
+ prepareArea, unclippedArea, painter, true, useExpandPrefetch);
+ m_backTexture->swapTiles();
+ }
+ } else if (m_zoomUpdateTime < WTF::currentTime()) {
+ m_backTexture->prepareGL(state, m_futureScale,
+ prepareArea, unclippedArea, painter, false, useExpandPrefetch);
+ if (m_backTexture->isReady()) {
+ // zooming completed, swap the textures and new front tiles
+ swapTileGrids();
+
+ m_frontTexture->swapTiles();
+ m_backTexture->discardTextures();
+
+ m_scale = m_futureScale;
+ m_zooming = false;
+ }
+ }
+}
+
+void SurfaceBacking::drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform,
+ bool aggressiveRendering, const Color* background)
+{
+ // draw low res prefetch page, if needed
+ if (aggressiveRendering && !m_zooming && m_frontTexture->isMissingContent())
+ m_backTexture->drawGL(visibleArea, opacity, transform);
+
+ m_frontTexture->drawGL(visibleArea, opacity, transform, background);
+}
+
+void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea)
+{
+ m_backTexture->markAsDirty(dirtyArea);
+ m_frontTexture->markAsDirty(dirtyArea);
+}
+
+void SurfaceBacking::swapTiles()
+{
+ m_backTexture->swapTiles();
+ m_frontTexture->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* 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;
+}
+
+void SurfaceBacking::swapTileGrids()
+{
+ TileGrid* temp = m_frontTexture;
+ m_frontTexture = m_backTexture;
+ m_backTexture = temp;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
index cf7c77c..b04e462 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
@@ -23,98 +23,40 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TiledTexture_h
-#define TiledTexture_h
+#ifndef SurfaceBacking_h
+#define SurfaceBacking_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;
+#include "TileGrid.h"
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);
+class LayerAndroid;
+class TexturesResult;
+class TilePainter;
- 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 {
+class SurfaceBacking : public SkRefCnt {
// TODO: investigate webkit threadsafe ref counting
public:
- DualTiledTexture();
- ~DualTiledTexture();
+ SurfaceBacking(bool isBaseSurface);
+ ~SurfaceBacking();
void prepareGL(GLWebViewState* state, bool allowZoom,
- const IntRect& prepareArea, TilePainter* painter);
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool aggressiveRendering);
void swapTiles();
- void swap();
- bool drawGL(const IntRect& visibleArea, float opacity, const TransformationMatrix* transform);
+ void drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform, bool aggressiveRendering,
+ const Color* background);
void markAsDirty(const SkRegion& dirtyArea);
- bool owns(BaseTileTexture* texture);
void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer);
void discardTextures()
{
- m_textureA->discardTextures();
- m_textureB->discardTextures();
+ m_frontTexture->discardTextures();
+ m_backTexture->discardTextures();
}
bool isReady()
{
- return !m_zooming && m_frontTexture->isReady();
+ return !m_zooming && m_frontTexture->isReady() && m_scale > 0;
}
int nbTextures(IntRect& area, float scale)
@@ -126,20 +68,19 @@ public:
}
private:
+ void swapTileGrids();
+
// 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;
+ TileGrid* m_frontTexture;
+ TileGrid* m_backTexture;
float m_scale;
float m_futureScale;
double m_zoomUpdateTime;
bool m_zooming;
- IntRect m_preZoomPrepareArea;
};
} // namespace WebCore
-#endif // TiledTexture_h
+#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..0bbaf91
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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);
+ if (m_surfaces[i]->isBase())
+ m_surfaces[i]->setBackground(getBackground());
+ }
+
+#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);
+}
+
+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;
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ needsRedraw |= m_surfaces[i]->drawGL(layerTilesDisabled);
+
+ return needsRedraw;
+}
+
+Color SurfaceCollection::getBackground()
+{
+ 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;
+}
+
+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..6450c9c 100644
--- a/Source/WebCore/platform/graphics/android/SurfaceCollection.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
@@ -26,33 +26,34 @@
#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 getBackground();
void swapTiles();
bool isReady();
void computeTexturesAmount(TexturesResult* result);
- void drawCanvas(SkCanvas* canvas, bool drawLayers);
// Recursive tree methods (animations, invals, etc)
void setIsPainting(SurfaceCollection* drawingSurfaceCollection);
@@ -62,14 +63,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..91335c7 100644
--- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -30,8 +30,7 @@
#include "SurfaceCollectionManager.h"
#include "AndroidLog.h"
-#include "BaseLayerAndroid.h"
-#include "LayerGroup.h"
+#include "private/hwui/DrawGlInfo.h"
#include "TilesManager.h"
#include "SurfaceCollection.h"
@@ -107,10 +106,6 @@ 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);
@@ -125,6 +120,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 +160,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 +193,37 @@ 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;
if (m_drawingCollection) {
bool drawingReady = didCollectionSwap || m_drawingCollection->isReady();
@@ -213,60 +239,28 @@ 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);
- }
- if (m_paintingCollection) {
- ALOGV("still have painting collection %p", m_paintingCollection);
- return true;
+ ALOGV("drawing collection %p", m_drawingCollection);
+ background = m_drawingCollection->getBackground();
+ } else if (m_paintingCollection) {
+ // Use paintingCollection background color while tiles are not done painting.
+ background = m_paintingCollection->getBackground();
}
- 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);
+ // Start doing the actual GL drawing.
+ 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);
+ 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..cc98899 100644
--- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
@@ -49,15 +49,10 @@ 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();
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..35fded1 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,45 @@ 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)
{
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);
+ 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 +244,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 +264,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 +273,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 +299,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 +379,6 @@ void BaseTile::paintBitmap(TilePainter* painter)
if (!fullRepaint) {
renderInfo.invalRect = &totalRect;
- renderInfo.measurePerf = false;
m_renderer->renderTiledContent(renderInfo);
}
}
@@ -399,15 +386,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 +421,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 +440,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 +450,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 +468,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 +481,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 +490,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) {
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h
index ab16dc9..7010301 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);
// 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,27 +132,19 @@ 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
@@ -169,9 +161,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 +188,4 @@ private:
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
-#endif // BaseTile_h
+#endif // Tile_h
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
index 039e28c..63f73aa 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
@@ -23,36 +23,51 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_TAG "TiledTexture"
+#define LOG_TAG "TileGrid"
#define LOG_NDEBUG 1
#include "config.h"
-#include "TiledTexture.h"
+#include "TileGrid.h"
#include "AndroidLog.h"
+#include "DrawQuadData.h"
+#include "GLWebViewState.h"
#include "PaintTileOperation.h"
-#include "SkCanvas.h"
-#include "SkPicture.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 {
-TiledTexture::~TiledTexture()
+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("TiledTexture");
+ ClassTracker::instance()->decrement("TileGrid");
#endif
removeTiles();
}
-bool TiledTexture::isReady()
+bool TileGrid::isReady()
{
bool tilesAllReady = true;
bool tilesVisible = false;
for (unsigned int i = 0; i < m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
+ Tile* tile = m_tiles[i];
if (tile->isTileVisible(m_area)) {
tilesVisible = true;
if (!tile->isTileReady()) {
@@ -73,7 +88,15 @@ bool TiledTexture::isReady()
|| !tilesVisible || tilesAllReady;
}
-void TiledTexture::swapTiles()
+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++)
@@ -82,7 +105,7 @@ void TiledTexture::swapTiles()
ALOGV("TT %p swapping, swaps = %d", this, swaps);
}
-IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale)
+IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale)
{
IntRect computedArea;
IntRect area(contentArea.x() * scale,
@@ -98,8 +121,8 @@ IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale)
return computedArea;
}
- int tileWidth = TilesManager::instance()->layerTileWidth();
- int tileHeight = TilesManager::instance()->layerTileHeight();
+ int tileWidth = TilesManager::tileWidth();
+ int tileHeight = TilesManager::tileHeight();
computedArea.setX(area.x() / tileWidth);
computedArea.setY(area.y() / tileHeight);
@@ -110,15 +133,16 @@ IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale)
return computedArea;
}
-void TiledTexture::prepareGL(GLWebViewState* state, float scale,
- const IntRect& prepareArea, TilePainter* painter)
+void TileGrid::prepareGL(GLWebViewState* state, float scale,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool isLowResPrefetch, bool useExpandPrefetch)
{
// 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 "
+ 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(),
@@ -129,8 +153,9 @@ void TiledTexture::prepareGL(GLWebViewState* state, float scale,
bool goingDown = m_prevTileY < m_area.y();
m_prevTileY = m_area.y();
+ TilesManager* tilesManager = TilesManager::instance();
if (scale != m_scale)
- TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, scale));
+ tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale));
m_scale = scale;
@@ -138,37 +163,74 @@ void TiledTexture::prepareGL(GLWebViewState* state, float scale,
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();
}
+ // prepare standard bounds (clearing ExpandPrefetch flag)
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);
+ 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);
+ prepareTile(m_area.x() + i, m_area.y() + j,
+ painter, state, isLowResPrefetch, false);
}
}
+
+ // prepare expanded bounds
+ if (useExpandPrefetch) {
+ 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 TiledTexture::markAsDirty(const SkRegion& invalRegion)
+void TileGrid::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)
+void TileGrid::prepareTile(int x, int y, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch)
{
- BaseTile* tile = getTile(x, y);
+ Tile* tile = getTile(x, y);
if (!tile) {
- tile = new BaseTile(true);
+ 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);
+
+ tile->setContents(x, y, m_scale, isExpandPrefetch);
// TODO: move below (which is largely the same for layers / tiled page) into
// prepareGL() function
@@ -178,22 +240,23 @@ void TiledTexture::prepareTile(int x, int y, TilePainter* painter)
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);
+ PaintTileOperation *operation = new PaintTileOperation(tile, painter,
+ state, isLowResPrefetch);
TilesManager::instance()->scheduleOperation(operation);
}
}
-BaseTile* TiledTexture::getTile(int x, int y)
+Tile* TileGrid::getTile(int x, int y)
{
for (unsigned int i = 0; i <m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
+ Tile* tile = m_tiles[i];
if (tile->x() == x && tile->y() == y)
return tile;
}
return 0;
}
-int TiledTexture::nbTextures(IntRect& area, float scale)
+int TileGrid::nbTextures(IntRect& area, float scale)
{
IntRect tileBounds = computeTilesArea(area, scale);
int numberTextures = tileBounds.width() * tileBounds.height();
@@ -201,7 +264,7 @@ int TiledTexture::nbTextures(IntRect& area, float scale)
// 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];
+ Tile* tile = m_tiles[i];
if (tile->isDirty()
&& tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX()
&& tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY())
@@ -210,24 +273,34 @@ int TiledTexture::nbTextures(IntRect& area, float scale)
return numberTextures;
}
-bool TiledTexture::drawGL(const IntRect& visibleArea, float opacity,
- const TransformationMatrix* transform)
+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 false;
+ return;
- float m_invScale = 1 / m_scale;
- const float tileWidth = TilesManager::layerTileWidth() * m_invScale;
- const float tileHeight = TilesManager::layerTileHeight() * m_invScale;
+ float invScale = 1 / m_scale;
+ const float tileWidth = TilesManager::tileWidth() * invScale;
+ const float tileHeight = TilesManager::tileHeight() * invScale;
int drawn = 0;
- bool askRedraw = false;
+
+ 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);
+ }
+
for (unsigned int i = 0; i < m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
+ Tile* tile = m_tiles[i];
- if (tile->isTileVisible(m_area)) {
- askRedraw |= !tile->isTileReady();
+ bool tileInView = tile->isTileVisible(m_area);
+ if (tileInView) {
SkRect rect;
rect.fLeft = tile->x() * tileWidth;
rect.fTop = tile->y() * tileHeight;
@@ -236,19 +309,60 @@ bool TiledTexture::drawGL(const IntRect& visibleArea, float opacity,
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);
+
+ bool forceBaseBlending = background ? background->hasAlpha() : false;
+ bool success = tile->drawGL(opacity, rect, m_scale, transform,
+ forceBaseBlending);
+ 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++;
}
+
+ if (semiOpaqueBaseSurface)
+ TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView);
}
- 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;
+ // Draw missing Regions with blend turned on
+ if (semiOpaqueBaseSurface)
+ drawMissingRegion(missingRegion, opacity, background);
+
+ ALOGV("TT %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;
+ ShaderProgram* shader = TilesManager::instance()->shader();
+ 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 TiledTexture::removeTiles()
+void TileGrid::removeTiles()
{
for (unsigned int i = 0; i < m_tiles.size(); i++) {
delete m_tiles[i];
@@ -256,152 +370,11 @@ void TiledTexture::removeTiles()
m_tiles.clear();
}
-void TiledTexture::discardTextures()
+void TileGrid::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/rendering/TileGrid.h b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
new file mode 100644
index 0000000..ffb6c7e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
@@ -0,0 +1,87 @@
+/*
+ * 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:
+ 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, bool isLowResPrefetch = false,
+ bool useExpandPrefetch = 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..d992aee 100644
--- a/Source/WebCore/platform/graphics/android/TilePainter.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h
@@ -33,16 +33,18 @@ class SkCanvas;
namespace WebCore {
-class BaseTile;
+class Tile;
+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(Tile* tile, 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..39effd7 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,7 +77,7 @@ void BaseTileTexture::discardGLTexture()
}
}
-bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
+bool TileTexture::acquire(TextureOwner* owner, bool force)
{
if (m_owner == owner)
return true;
@@ -82,7 +85,7 @@ bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
return setOwner(owner, force);
}
-bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
+bool TileTexture::setOwner(TextureOwner* owner, bool force)
{
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,38 @@ 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)
{
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.
+ forceBlending |= isLayer;
+ DrawQuadData commonData(isLayer ? LayerQuad : BaseQuad, transform, &rect,
+ opacity, forceBlending);
+ 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);
+ TextureQuadData data(commonData, m_ownTextureId, GL_TEXTURE_2D, GL_LINEAR);
+ shader->drawQuad(&data);
}
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
index 321ca31..5fe43b0 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
@@ -23,28 +23,31 @@
* 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
@@ -59,9 +62,6 @@ public:
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,12 @@ public:
Color pureColor() { return m_pureColor; }
void drawGL(bool isLayer, const SkRect& rect, float opacity,
- const TransformationMatrix* transform);
+ const TransformationMatrix* transform, bool forceBlending = 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 +96,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..e8b8cd1 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,16 +250,11 @@ 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);
@@ -274,7 +269,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return owner->backTexture();
}
- WTF::Vector<BaseTileTexture*>* availableTexturePool;
+ WTF::Vector<TileTexture*>* availableTexturePool;
if (owner->isLayerTile()) {
availableTexturePool = &m_availableTilesTextures;
} else {
@@ -289,12 +284,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 +310,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 +415,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 +433,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..ec0d9e7 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)
{
@@ -204,8 +209,9 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
// 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 +333,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 +348,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 +361,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 +384,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 +415,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);
}
@@ -422,7 +428,7 @@ void TransferQueue::updateDirtyBaseTiles()
if (usedFboForUpload) {
glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
restoreGLState();
- GLUtils::checkGlError("updateDirtyBaseTiles");
+ GLUtils::checkGlError("updateDirtyTiles");
}
m_emptyItemCount = m_transferQueueSize;
@@ -435,7 +441,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 +469,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 +481,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 +498,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 +522,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 +556,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 +574,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 +583,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;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index b864085..65ff116 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -28,14 +28,17 @@
#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 viewport[4];
GLboolean scissor[1];
@@ -44,7 +47,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 +73,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 +88,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 +117,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 +137,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 +147,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 +174,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 +195,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/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/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/WebKit/android/AndroidLog.h b/Source/WebKit/android/AndroidLog.h
index 4090ab9..3ac210f 100644
--- a/Source/WebKit/android/AndroidLog.h
+++ b/Source/WebKit/android/AndroidLog.h
@@ -26,8 +26,14 @@
#ifndef AndroidLog_h
#define AndroidLog_h
+#ifndef LOG_TAG
+#define LOG_TAG __FILE__
+#endif
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+
#ifdef ANDROID_DOM_LOGGING
-#include <utils/Log.h>
#include <stdio.h>
extern FILE* gDomTreeFile;
#define DOM_TREE_LOG_FILE "/sdcard/domTree.txt"
@@ -46,4 +52,21 @@ extern FILE* gRenderTreeFile;
#define DISPLAY_TREE_LOG_FILE "/sdcard/displayTree.txt"
#define LAYERS_TREE_LOG_FILE "/sdcard/layersTree.plist"
+#define TIME_METHOD() MethodTimer __method_timer(__func__)
+class MethodTimer {
+public:
+ MethodTimer(const char* name)
+ : m_methodName(name)
+ {
+ m_startTime = currentTimeMS();
+ }
+ virtual ~MethodTimer() {
+ double duration = currentTimeMS() - m_startTime;
+ ALOGD("%s took %.2fms", m_methodName, duration);
+ }
+private:
+ const char* m_methodName;
+ double m_startTime;
+};
+
#endif // AndroidLog_h
diff --git a/Source/WebKit/android/RenderSkinMediaButton.cpp b/Source/WebKit/android/RenderSkinMediaButton.cpp
index febf575..b3aa57d 100644
--- a/Source/WebKit/android/RenderSkinMediaButton.cpp
+++ b/Source/WebKit/android/RenderSkinMediaButton.cpp
@@ -95,6 +95,9 @@ void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonT
Decode();
}
+ if (!canvas)
+ return;
+
// If we failed to decode, do nothing. This way the browser still works,
// and webkit will still draw the label and layout space for us.
if (gDecodingFailed)
diff --git a/Source/WebKit/android/RenderSkinNinePatch.cpp b/Source/WebKit/android/RenderSkinNinePatch.cpp
index ec748f7..9ef0b4a 100644
--- a/Source/WebKit/android/RenderSkinNinePatch.cpp
+++ b/Source/WebKit/android/RenderSkinNinePatch.cpp
@@ -73,7 +73,7 @@ bool RenderSkinNinePatch::decodeAsset(AssetManager* am, const char* filename, Ni
}
asset->close();
- if (!peeker.fPatchIsValid) {
+ if (!peeker.fPatch) {
ALOGE("RenderSkinNinePatch::Patch data not valid");
return false;
}
diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 5e16152..207fe9a 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -238,11 +238,7 @@ void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, Messag
android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel);
}
-void ChromeClientAndroid::formDidBlur(const WebCore::Node* node)
-{
- android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node);
-}
-
+void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) { notImplemented(); }
bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; }
bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) {
String url = frame->document()->documentURI();
diff --git a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
index fea45de..52aeb23 100644
--- a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
@@ -264,7 +264,9 @@ public:
if (!m_poster || (!m_poster->getPixels() && !m_poster->pixelRef()))
return;
- SkCanvas* canvas = ctxt->platformContext()->mCanvas;
+ SkCanvas* canvas = ctxt->platformContext()->getCanvas();
+ if (!canvas)
+ return;
// We paint with the following rules in mind:
// - only downscale the poster, never upscale
// - maintain the natural aspect ratio of the poster
@@ -611,14 +613,9 @@ static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex,
BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(baseLayer);
if (!layerImpl)
return false;
- if (!layerImpl->countChildren())
- return false;
- LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(layerImpl->getChild(0));
- if (!compositedRoot)
- return false;
VideoLayerAndroid* videoLayer =
- static_cast<VideoLayerAndroid*>(compositedRoot->findById(videoLayerId));
+ static_cast<VideoLayerAndroid*>(layerImpl->findById(videoLayerId));
if (!videoLayer)
return false;
diff --git a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
index 77e3c32..d846daf 100644
--- a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
+++ b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
@@ -30,6 +30,7 @@
#include "UrlInterceptResponse.h"
#include "WebCoreJni.h"
+#include <ScopedLocalRef.h>
#include <utils/Log.h>
namespace android {
@@ -38,15 +39,14 @@ class JavaInputStreamWrapper {
public:
JavaInputStreamWrapper(JNIEnv* env, jobject inputStream)
: m_inputStream(env->NewGlobalRef(inputStream))
- , m_buffer(0) {
- LOG_ALWAYS_FATAL_IF(!inputStream);
- jclass inputStreamClass = env->FindClass("java/io/InputStream");
- LOG_ALWAYS_FATAL_IF(!inputStreamClass);
- m_read = env->GetMethodID(inputStreamClass, "read", "([B)I");
+ , m_buffer(NULL) {
+ LOG_ALWAYS_FATAL_IF(!m_inputStream);
+ ScopedLocalRef<jclass> inputStreamClass(env, env->FindClass("java/io/InputStream"));
+ LOG_ALWAYS_FATAL_IF(!inputStreamClass.get());
+ m_read = env->GetMethodID(inputStreamClass.get(), "read", "([B)I");
LOG_ALWAYS_FATAL_IF(!m_read);
- m_close = env->GetMethodID(inputStreamClass, "close", "()V");
+ m_close = env->GetMethodID(inputStreamClass.get(), "close", "()V");
LOG_ALWAYS_FATAL_IF(!m_close);
- env->DeleteLocalRef(inputStreamClass);
}
~JavaInputStreamWrapper() {
@@ -63,10 +63,10 @@ public:
JNIEnv* env = JSC::Bindings::getJNIEnv();
// Initialize our read buffer to the capacity of out.
if (!m_buffer) {
- m_buffer = env->NewByteArray(out->capacity());
- m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer);
+ ScopedLocalRef<jbyteArray> buffer_local(env, env->NewByteArray(out->capacity()));
+ m_buffer = static_cast<jbyteArray>(env->NewGlobalRef(buffer_local.get()));
}
- int size = (int) env->CallIntMethod(m_inputStream, m_read, m_buffer);
+ int size = env->CallIntMethod(m_inputStream, m_read, m_buffer);
if (checkException(env) || size < 0)
return;
// Copy from m_buffer to out.
@@ -82,40 +82,32 @@ private:
};
UrlInterceptResponse::UrlInterceptResponse(JNIEnv* env, jobject response) {
- jclass javaResponse = env->FindClass("android/webkit/WebResourceResponse");
- LOG_ALWAYS_FATAL_IF(!javaResponse);
- jfieldID mimeType = env->GetFieldID(javaResponse, "mMimeType",
- "Ljava/lang/String;");
+ ScopedLocalRef<jclass> javaResponse(env, env->FindClass("android/webkit/WebResourceResponse"));
+ LOG_ALWAYS_FATAL_IF(!javaResponse.get());
+ jfieldID mimeType = env->GetFieldID(javaResponse.get(), "mMimeType", "Ljava/lang/String;");
LOG_ALWAYS_FATAL_IF(!mimeType);
- jfieldID encoding = env->GetFieldID(javaResponse, "mEncoding",
- "Ljava/lang/String;");
+ jfieldID encoding = env->GetFieldID(javaResponse.get(), "mEncoding", "Ljava/lang/String;");
LOG_ALWAYS_FATAL_IF(!encoding);
- jfieldID inputStream = env->GetFieldID(javaResponse, "mInputStream",
- "Ljava/io/InputStream;");
+ jfieldID inputStream = env->GetFieldID(javaResponse.get(), "mInputStream", "Ljava/io/InputStream;");
LOG_ALWAYS_FATAL_IF(!inputStream);
- jobject stream = env->GetObjectField(response, inputStream);
- if (stream)
- m_inputStream.set(new JavaInputStreamWrapper(env, stream));
+ ScopedLocalRef<jobject> stream(env, env->GetObjectField(response, inputStream));
+ if (stream.get())
+ m_inputStream.set(new JavaInputStreamWrapper(env, stream.get()));
- jstring mimeStr = (jstring) env->GetObjectField(response, mimeType);
- jstring encodingStr = (jstring) env->GetObjectField(response, encoding);
+ ScopedLocalRef<jstring> mimeStr(env, static_cast<jstring>(env->GetObjectField(response, mimeType)));
+ ScopedLocalRef<jstring> encodingStr(env, static_cast<jstring>(env->GetObjectField(response, encoding)));
- if (mimeStr) {
- const char* s = env->GetStringUTFChars(mimeStr, NULL);
- m_mimeType.assign(s, env->GetStringUTFLength(mimeStr));
- env->ReleaseStringUTFChars(mimeStr, s);
+ if (mimeStr.get()) {
+ const char* s = env->GetStringUTFChars(mimeStr.get(), NULL);
+ m_mimeType.assign(s, env->GetStringUTFLength(mimeStr.get()));
+ env->ReleaseStringUTFChars(mimeStr.get(), s);
}
- if (encodingStr) {
- const char* s = env->GetStringUTFChars(encodingStr, NULL);
- m_encoding.assign(s, env->GetStringUTFLength(encodingStr));
- env->ReleaseStringUTFChars(encodingStr, s);
+ if (encodingStr.get()) {
+ const char* s = env->GetStringUTFChars(encodingStr.get(), NULL);
+ m_encoding.assign(s, env->GetStringUTFLength(encodingStr.get()));
+ env->ReleaseStringUTFChars(encodingStr.get(), s);
}
-
- env->DeleteLocalRef(javaResponse);
- env->DeleteLocalRef(stream);
- env->DeleteLocalRef(mimeStr);
- env->DeleteLocalRef(encodingStr);
}
UrlInterceptResponse::~UrlInterceptResponse() {
diff --git a/Source/WebKit/android/jni/PictureSet.cpp b/Source/WebKit/android/jni/PictureSet.cpp
index f3534eb..8beb0ef 100644
--- a/Source/WebKit/android/jni/PictureSet.cpp
+++ b/Source/WebKit/android/jni/PictureSet.cpp
@@ -38,6 +38,8 @@
#include "SkRegion.h"
#include "SkStream.h"
+#include "PlatformGraphicsContext.h"
+
#define MAX_DRAW_TIME 100
#define MIN_SPLITTABLE 400
#define MAX_ADDITIONAL_AREA 0.65
@@ -133,6 +135,9 @@ void PictureSet::add(const Pictures* temp)
{
Pictures pictureAndBounds = *temp;
SkSafeRef(pictureAndBounds.mPicture);
+#ifdef CONTEXT_RECORDING
+ SkSafeRef(pictureAndBounds.mGraphicsOperationCollection);
+#endif
pictureAndBounds.mWroteElapsed = false;
mPictures.append(pictureAndBounds);
}
@@ -478,13 +483,20 @@ void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool emp
working->mArea.setEmpty();
SkSafeUnref(working->mPicture);
working->mPicture = 0;
+#ifdef CONTEXT_RECORDING
+ SkSafeUnref(working->mGraphicsOperationCollection);
+ working->mGraphicsOperationCollection = 0;
+#endif
}
}
// Now we can add the new Picture to the list, with the correct area
// that need to be repainted
- Pictures pictureAndBounds = {totalArea, 0, totalArea,
- elapsed, split, false, false, empty};
+ Pictures pictureAndBounds = {totalArea, 0,
+#ifdef CONTEXT_RECORDING
+ 0,
+#endif
+ totalArea, elapsed, split, false, false, empty};
#ifdef FAST_PICTURESET
if (mPictures.size() == 0)
@@ -525,6 +537,10 @@ void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool emp
working->mArea.setEmpty();
SkSafeUnref(working->mPicture);
working->mPicture = 0;
+#ifdef CONTEXT_RECORDING
+ SkSafeUnref(working->mGraphicsOperationCollection);
+ working->mGraphicsOperationCollection = 0;
+#endif
}
}
@@ -677,6 +693,9 @@ void PictureSet::clear()
for (Pictures* working = mPictures.begin(); working != last; working++) {
working->mArea.setEmpty();
SkSafeUnref(working->mPicture);
+#ifdef CONTEXT_RECORDING
+ SkSafeUnref(working->mGraphicsOperationCollection);
+#endif
}
mPictures.clear();
#endif // FAST_PICTURESET
@@ -797,7 +816,14 @@ bool PictureSet::draw(SkCanvas* canvas)
canvas->translate(pathBounds.fLeft, pathBounds.fTop);
canvas->save();
uint32_t startTime = getThreadMsec();
+
+#ifdef CONTEXT_RECORDING
+ WebCore::PlatformGraphicsContextSkia context(canvas);
+ working->mGraphicsOperationCollection->apply(&context);
+#else
canvas->drawPicture(*working->mPicture);
+#endif
+
size_t elapsed = working->mElapsed = getThreadMsec() - startTime;
working->mWroteElapsed = true;
if (maxElapsed < elapsed && (pathBounds.width() >= MIN_SPLITTABLE ||
@@ -1060,6 +1086,14 @@ void PictureSet::setPicture(size_t i, SkPicture* p)
mPictures[i].mEmpty = emptyPicture(p);
}
+#ifdef CONTEXT_RECORDING
+void PictureSet::setGraphicsOperationCollection(size_t i, WebCore::GraphicsOperationCollection* p)
+{
+ SkSafeUnref(mPictures[i].mGraphicsOperationCollection);
+ mPictures[i].mGraphicsOperationCollection = p;
+}
+#endif
+
void PictureSet::split(PictureSet* out) const
{
dump(__FUNCTION__);
diff --git a/Source/WebKit/android/jni/PictureSet.h b/Source/WebKit/android/jni/PictureSet.h
index 1d9a14d..1e639da 100644
--- a/Source/WebKit/android/jni/PictureSet.h
+++ b/Source/WebKit/android/jni/PictureSet.h
@@ -45,7 +45,10 @@
#include <wtf/Vector.h>
#include <wtf/HashMap.h>
+#include "GraphicsOperationCollection.h"
+
// #define FAST_PICTURESET // use a hierarchy of pictures
+// #define CONTEXT_RECORDING // use the new PlatformGraphicsContextRecording
class SkCanvas;
class SkPicture;
@@ -100,6 +103,9 @@ namespace android {
const SkIRect& bounds(size_t i) const {
return mPictures[i].mArea; }
void setPicture(size_t i, SkPicture* p);
+#ifdef CONTEXT_RECORDING
+ void setGraphicsOperationCollection(size_t i, WebCore::GraphicsOperationCollection* p);
+#endif
void setDrawTimes(const PictureSet& );
size_t size() const { return mPictures.size(); }
void split(PictureSet* result) const;
@@ -119,9 +125,13 @@ namespace android {
int mBucketCountX;
int mBucketCountY;
#else
+
struct Pictures {
SkIRect mArea;
SkPicture* mPicture;
+#ifdef CONTEXT_RECORDING
+ WebCore::GraphicsOperationCollection* mGraphicsOperationCollection;
+#endif
SkIRect mUnsplit;
uint32_t mElapsed;
bool mSplit : 8;
diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp
index 2be3ecb..3fdc3e6 100644
--- a/Source/WebKit/android/jni/ViewStateSerializer.cpp
+++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp
@@ -40,6 +40,7 @@
#include "PictureLayerContent.h"
#include "PictureSet.h"
#include "ScrollableLayerAndroid.h"
+#include "SkFlattenable.h"
#include "SkPicture.h"
#include "TilesManager.h"
@@ -92,14 +93,13 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint v
SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
if (!stream)
return 0;
- BaseLayerAndroid* layer = new BaseLayerAndroid();
Color color = stream->readU32();
-#if USE(ACCELERATED_COMPOSITING)
- layer->setBackgroundColor(color);
-#endif
SkPicture* picture = new SkPicture(stream);
PictureLayerContent* content = new PictureLayerContent(picture);
- layer->setContent(content);
+
+ BaseLayerAndroid* layer = new BaseLayerAndroid(content);
+ layer->setBackgroundColor(color);
+
SkSafeUnref(content);
SkSafeUnref(picture);
int childCount = stream->readS32();
diff --git a/Source/WebKit/android/jni/WebFrameView.cpp b/Source/WebKit/android/jni/WebFrameView.cpp
index a9b90cb..10e31dc 100644
--- a/Source/WebKit/android/jni/WebFrameView.cpp
+++ b/Source/WebKit/android/jni/WebFrameView.cpp
@@ -54,45 +54,15 @@ WebFrameView::~WebFrameView() {
Release(mWebViewCore);
}
-void WebFrameView::draw(WebCore::GraphicsContext* ctx, const WebCore::IntRect& rect) {
+void WebFrameView::draw(WebCore::GraphicsContext* gc, const WebCore::IntRect& rect) {
WebCore::Frame* frame = mFrameView->frame();
- if (NULL == frame->contentRenderer()) {
- // We only do this if there is nothing else to draw.
- // If there is a renderer, it will fill the bg itself, so we don't want to
- // double-draw (slow)
- SkCanvas* canvas = ctx->platformContext()->mCanvas;
- canvas->drawColor(SK_ColorWHITE);
- } else if (frame->tree()->parent()) {
- // Note: this code was moved from FrameLoaderClientAndroid
- //
- // For subframe, create a new translated rect from the given rectangle.
- WebCore::IntRect transRect(rect);
- // In Frame::markAllMatchesForText(), it does a fake paint. So we need
- // to handle the case where platformContext() is null. However, we still
- // want to call paint, since WebKit must have called the paint for a reason.
- SkCanvas* canvas = ctx->platformContext() ? ctx->platformContext()->mCanvas : NULL;
- if (canvas) {
- const WebCore::IntRect& bounds = getBounds();
-
- // Grab the intersection of transRect and the frame's bounds.
- transRect.intersect(bounds);
- if (transRect.isEmpty())
- return;
-
- // Move the transRect into the frame's local coordinates.
- transRect.move(-bounds.x(), -bounds.y());
-
- // Translate the canvas, add a clip.
- canvas->save();
- canvas->translate(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()));
- canvas->clipRect(transRect);
- }
- mFrameView->paintContents(ctx, transRect);
- if (canvas)
- canvas->restore();
- } else {
- mFrameView->paintContents(ctx, rect);
+ if (frame->contentRenderer())
+ mFrameView->paintContents(gc, rect);
+ else {
+ // FIXME: I'm not entirely sure this ever happens or is needed
+ gc->setFillColor(WebCore::Color::white, WebCore::ColorSpaceDeviceRGB);
+ gc->fillRect(rect);
}
}
diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp
index 5ce1ccc..7ee9033 100644
--- a/Source/WebKit/android/jni/WebSettings.cpp
+++ b/Source/WebKit/android/jni/WebSettings.cpp
@@ -120,6 +120,9 @@ struct FieldIds {
mGeolocationEnabled = env->GetFieldID(clazz, "mGeolocationEnabled", "Z");
mGeolocationDatabasePath = env->GetFieldID(clazz, "mGeolocationDatabasePath", "Ljava/lang/String;");
mXSSAuditorEnabled = env->GetFieldID(clazz, "mXSSAuditorEnabled", "Z");
+#if ENABLE(LINK_PREFETCH)
+ mLinkPrefetchEnabled = env->GetFieldID(clazz, "mLinkPrefetchEnabled", "Z");
+#endif
mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz,
"mJavaScriptCanOpenWindowsAutomatically", "Z");
mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z");
@@ -253,6 +256,9 @@ struct FieldIds {
jfieldID mGeolocationEnabled;
jfieldID mGeolocationDatabasePath;
jfieldID mXSSAuditorEnabled;
+#if ENABLE(LINK_PREFETCH)
+ jfieldID mLinkPrefetchEnabled;
+#endif
#if ENABLE(DATABASE) || ENABLE(DOM_STORAGE)
jfieldID mDatabasePath;
jfieldID mDatabasePathHasBeenSet;
@@ -560,6 +566,11 @@ public:
flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled);
s->setXSSAuditorEnabled(flag);
+#if ENABLE(LINK_PREFETCH)
+ flag = env->GetBooleanField(obj, gFieldIds->mLinkPrefetchEnabled);
+ s->setLinkPrefetchEnabled(flag);
+#endif
+
size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity);
if (size > 0) {
s->setUsesPageCache(true);
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 9aaec25..a4cd94f 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -31,7 +31,6 @@
#include "AccessibilityObject.h"
#include "AndroidHitTestResult.h"
#include "Attribute.h"
-#include "BaseLayerAndroid.h"
#include "content/address_detector.h"
#include "Chrome.h"
#include "ChromeClientAndroid.h"
@@ -63,6 +62,7 @@
#include "Geolocation.h"
#include "GraphicsContext.h"
#include "GraphicsJNI.h"
+#include "GraphicsOperationCollection.h"
#include "HTMLAnchorElement.h"
#include "HTMLAreaElement.h"
#include "HTMLElement.h"
@@ -160,6 +160,8 @@ FILE* gDomTreeFile = 0;
FILE* gRenderTreeFile = 0;
#endif
+#include "BaseLayerAndroid.h"
+
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayerAndroid.h"
#include "RenderLayerCompositor.h"
@@ -309,7 +311,6 @@ struct WebViewCoreFields {
jfieldID m_viewportMaximumScale;
jfieldID m_viewportUserScalable;
jfieldID m_viewportDensityDpi;
- jfieldID m_webView;
jfieldID m_drawIsPaused;
jfieldID m_lowMemoryUsageMb;
jfieldID m_highMemoryUsageMb;
@@ -331,6 +332,7 @@ struct WebViewCore::JavaGlue {
jmethodID m_jsPrompt;
jmethodID m_jsUnload;
jmethodID m_jsInterrupt;
+ jmethodID m_getWebView;
jmethodID m_didFirstLayout;
jmethodID m_updateViewport;
jmethodID m_sendNotifyProgressFinished;
@@ -350,7 +352,6 @@ struct WebViewCore::JavaGlue {
jmethodID m_getDeviceMotionService;
jmethodID m_getDeviceOrientationService;
jmethodID m_addMessageToConsole;
- jmethodID m_formDidBlur;
jmethodID m_focusNodeChanged;
jmethodID m_getPluginClass;
jmethodID m_showFullScreenPlugin;
@@ -370,7 +371,6 @@ struct WebViewCore::JavaGlue {
jmethodID m_setWebTextViewAutoFillable;
jmethodID m_selectAt;
jmethodID m_initEditField;
- jmethodID m_updateMatchCount;
jmethodID m_chromeCanTakeFocus;
jmethodID m_chromeTakeFocus;
AutoJObject object(JNIEnv* env) {
@@ -420,7 +420,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
, m_textFieldInitDataGlue(new TextFieldInitDataGlue)
, m_mainFrame(mainframe)
, m_popupReply(0)
- , m_blurringNodePointer(0)
, m_blockTextfieldUpdates(false)
, m_focusBoundsChanged(false)
, m_skipContentDraw(false)
@@ -466,6 +465,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_jsPrompt = GetJMethod(env, clazz, "jsPrompt", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
m_javaGlue->m_jsUnload = GetJMethod(env, clazz, "jsUnload", "(Ljava/lang/String;Ljava/lang/String;)Z");
m_javaGlue->m_jsInterrupt = GetJMethod(env, clazz, "jsInterrupt", "()Z");
+ m_javaGlue->m_getWebView = GetJMethod(env, clazz, "getWebView", "()Landroid/webkit/WebView;");
m_javaGlue->m_didFirstLayout = GetJMethod(env, clazz, "didFirstLayout", "(Z)V");
m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V");
m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V");
@@ -485,7 +485,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_getDeviceMotionService = GetJMethod(env, clazz, "getDeviceMotionService", "()Landroid/webkit/DeviceMotionService;");
m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;");
m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V");
- m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V");
m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(ILandroid/webkit/WebViewCore$WebKitHitTest;)V");
m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;II)V");
@@ -507,7 +506,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V");
m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V");
m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(IIILandroid/webkit/WebViewCore$TextFieldInitData;)V");
- m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V");
m_javaGlue->m_chromeCanTakeFocus = GetJMethod(env, clazz, "chromeCanTakeFocus", "(I)Z");
m_javaGlue->m_chromeTakeFocus = GetJMethod(env, clazz, "chromeTakeFocus", "(I)V");
env->DeleteLocalRef(clazz);
@@ -788,7 +786,7 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval)
SkAutoMemoryUsageProbe mup(__FUNCTION__);
SkCanvas* recordingCanvas = arp.getRecordingCanvas();
- WebCore::PlatformGraphicsContext pgc(recordingCanvas);
+ WebCore::PlatformGraphicsContextSkia pgc(recordingCanvas);
WebCore::GraphicsContext gc(&pgc);
IntPoint origin = view->minimumScrollPosition();
WebCore::IntRect drawArea(inval.fLeft + origin.x(), inval.fTop + origin.y(),
@@ -804,6 +802,27 @@ SkPicture* WebViewCore::rebuildPicture(const SkIRect& inval)
return picture;
}
+#ifdef CONTEXT_RECORDING
+GraphicsOperationCollection* WebViewCore::rebuildGraphicsOperationCollection(const SkIRect& inval)
+{
+ WebCore::FrameView* view = m_mainFrame->view();
+ int width = view->contentsWidth();
+ int height = view->contentsHeight();
+
+ IntPoint origin = view->minimumScrollPosition();
+ WebCore::IntRect drawArea(inval.fLeft + origin.x(), inval.fTop + origin.y(),
+ inval.width(), inval.height());
+
+ AutoGraphicsOperationCollection autoPicture(drawArea);
+ view->platformWidget()->draw(autoPicture.context(), drawArea);
+
+ m_rebuildInval.op(inval, SkRegion::kUnion_Op);
+
+ SkSafeRef(autoPicture.picture());
+ return autoPicture.picture();
+}
+#endif
+
void WebViewCore::rebuildPictureSet(PictureSet* pictureSet)
{
#ifdef FAST_PICTURESET
@@ -829,6 +848,10 @@ void WebViewCore::rebuildPictureSet(PictureSet* pictureSet)
DBG_SET_LOGD("pictSet=%p [%d] {%d,%d,w=%d,h=%d}", pictureSet, index,
inval.fLeft, inval.fTop, inval.width(), inval.height());
pictureSet->setPicture(index, rebuildPicture(inval));
+#ifdef CONTEXT_RECORDING
+ pictureSet->setGraphicsOperationCollection(index,
+ rebuildGraphicsOperationCollection(inval));
+#endif
}
pictureSet->validate(__FUNCTION__);
@@ -860,10 +883,8 @@ void WebViewCore::notifyAnimationStarted()
BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region)
{
- BaseLayerAndroid* base = new BaseLayerAndroid();
-
PictureSetLayerContent* content = new PictureSetLayerContent(m_content);
- base->setContent(content);
+ BaseLayerAndroid* base = new BaseLayerAndroid(content);
SkSafeUnref(content);
m_skipContentDraw = true;
@@ -874,16 +895,25 @@ BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region)
#if USE(ACCELERATED_COMPOSITING)
// We set the background color
+ Color background = Color::white;
if (m_mainFrame && m_mainFrame->document()
&& m_mainFrame->document()->body()) {
+ bool hasCSSBackground = false;
+
Document* document = m_mainFrame->document();
RefPtr<RenderStyle> style = document->styleForElementIgnoringPendingStylesheets(document->body());
if (style->hasBackground()) {
- Color color = style->visitedDependentColor(CSSPropertyBackgroundColor);
- if (color.isValid() && color.alpha() > 0)
- base->setBackgroundColor(color);
+ background = style->visitedDependentColor(CSSPropertyBackgroundColor);
+ hasCSSBackground = true;
+ }
+
+ WebCore::FrameView* view = m_mainFrame->view();
+ if (view) {
+ Color viewBackground = view->baseBackgroundColor();
+ background = hasCSSBackground ? viewBackground.blend(background) : viewBackground;
}
}
+ base->setBackgroundColor(background);
// We update the layers
ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client());
@@ -1483,7 +1513,7 @@ VisiblePosition WebViewCore::visiblePositionForContentPoint(const IntPoint& poin
return node->renderer()->positionForPoint(result.localPoint());
}
-void WebViewCore::selectWordAt(int x, int y)
+bool WebViewCore::selectWordAt(int x, int y)
{
HitTestResult hoverResult;
moveMouse(x, y, &hoverResult);
@@ -1505,25 +1535,29 @@ void WebViewCore::selectWordAt(int x, int y)
// Matching the logic in MouseEventWithHitTestResults::targetNode()
Node* node = result.innerNode();
if (!node)
- return;
+ return false;
Element* element = node->parentElement();
if (!node->inDocument() && element && element->inDocument())
node = element;
SelectionController* sc = focusedFrame()->selection();
+ bool wordSelected = false;
if (!sc->contains(point) && (node->isContentEditable() || node->isTextNode()) && !result.isLiveLink()
&& node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true))) {
VisiblePosition pos(node->renderer()->positionForPoint(result.localPoint()));
- selectWordAroundPosition(node->document()->frame(), pos);
+ wordSelected = selectWordAroundPosition(node->document()->frame(), pos);
}
+ return wordSelected;
}
-void WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos)
+bool WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos)
{
VisibleSelection selection(pos);
selection.expandUsingGranularity(WordGranularity);
+ SelectionController* selectionController = frame->selection();
- if (frame->selection()->shouldChangeSelection(selection)) {
+ bool wordSelected = false;
+ if (selectionController->shouldChangeSelection(selection)) {
bool allWhitespaces = true;
RefPtr<Range> firstRange = selection.firstRange();
String text = firstRange.get() ? firstRange->text() : "";
@@ -1533,13 +1567,15 @@ void WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos)
break;
}
}
-
if (allWhitespaces) {
- VisibleSelection emptySelection(selection.visibleStart(), selection.visibleStart());
- frame->selection()->setSelection(emptySelection);
+ VisibleSelection emptySelection(pos);
+ selectionController->setSelection(emptySelection);
+ } else {
+ selectionController->setSelection(selection);
+ wordSelected = true;
}
- frame->selection()->setSelection(selection);
}
+ return wordSelected;
}
int WebViewCore::platformLayerIdFromNode(Node* node, LayerAndroid** outLayer)
@@ -1661,10 +1697,50 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
selectTextContainer->setCaretRect(SelectText::EndHandle, endHandle);
selectTextContainer->setText(range->text());
+ selectTextContainer->setTextRect(SelectText::StartHandle,
+ positionToTextRect(selection.start()));
+ selectTextContainer->setTextRect(SelectText::EndHandle,
+ positionToTextRect(selection.end()));
return selectTextContainer;
}
+IntRect WebViewCore::positionToTextRect(const Position& position)
+{
+ IntRect textRect;
+ InlineBox* inlineBox;
+ int offset;
+ position.getInlineBoxAndOffset(VP_DEFAULT_AFFINITY, inlineBox, offset);
+ if (inlineBox && inlineBox->isInlineTextBox()) {
+ InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox);
+ RootInlineBox* root = box->root();
+ RenderText* renderText = box->textRenderer();
+ int left = root->logicalLeft();
+ int width = root->logicalWidth();
+ int top = root->selectionTop();
+ int height = root->selectionHeight();
+
+ Node* node = position.anchorNode();
+ LayerAndroid* layer = 0;
+ int layerId = platformLayerIdFromNode(node, &layer);
+ IntPoint layerOffset;
+ layerToAbsoluteOffset(layer, layerOffset);
+
+ if (!renderText->style()->isHorizontalWritingMode()) {
+ swap(left, top);
+ swap(width, height);
+ }
+ FloatPoint origin(left, top);
+ FloatPoint absoluteOrigin = renderText->localToAbsolute(origin);
+
+ textRect.setX(absoluteOrigin.x() - layerOffset.x());
+ textRect.setWidth(width);
+ textRect.setY(absoluteOrigin.y() - layerOffset.y());
+ textRect.setHeight(height);
+ }
+ return textRect;
+}
+
IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point, WebCore::Frame* frame)
{
if (!frame) frame = focusedFrame();
@@ -3430,15 +3506,6 @@ void WebViewCore::popupReply(const int* array, int count)
}
}
-void WebViewCore::formDidBlur(const WebCore::Node* node)
-{
- // If the blur is on a text input, keep track of the node so we can
- // hide the soft keyboard when the new focus is set, if it is not a
- // text input.
- if (isTextInput(node))
- m_blurringNodePointer = reinterpret_cast<int>(node);
-}
-
// This is a slightly modified Node::nextNodeConsideringAtomicNodes() with the
// extra constraint of limiting the search to inside a containing parent
WebCore::Node* nextNodeWithinParent(WebCore::Node* parent, WebCore::Node* start)
@@ -3462,6 +3529,7 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake)
{
if (node) {
if (isTextInput(node)) {
+ bool showKeyboard = true;
initEditField(node);
WebCore::RenderTextControl* rtc = toRenderTextControl(node);
if (rtc && node->hasTagName(HTMLNames::inputTag)) {
@@ -3478,10 +3546,11 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake)
autoFill->formFieldFocused(inputElement);
}
#endif
- } else if (!fake) {
- requestKeyboard(false);
- }
+ } else
+ showKeyboard = false;
}
+ if (!fake)
+ requestKeyboard(showKeyboard);
} else if (!fake && !nodeIsPlugin(node)) {
// not a text entry field, put away the keyboard.
clearTextEntry();
@@ -3499,12 +3568,7 @@ void WebViewCore::focusNodeChanged(WebCore::Node* newFocus)
if (!javaObject.get())
return;
if (isTextInput(newFocus))
- initializeTextInput(newFocus);
- else if (m_blurringNodePointer) {
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_formDidBlur, m_blurringNodePointer);
- checkException(env);
- m_blurringNodePointer = 0;
- }
+ initializeTextInput(newFocus, true);
HitTestResult focusHitResult;
focusHitResult.setInnerNode(newFocus);
focusHitResult.setInnerNonSharedNode(newFocus);
@@ -3733,7 +3797,7 @@ WebViewCore::getWebViewJavaObject()
AutoJObject javaObject = m_javaGlue->object(env);
if (!javaObject.get())
return 0;
- return env->GetObjectField(javaObject.get(), gWebViewCoreFields.m_webView);
+ return env->CallObjectMethod(javaObject.get(), m_javaGlue->m_getWebView);
}
RenderTextControl* WebViewCore::toRenderTextControl(Node* node)
@@ -4236,19 +4300,15 @@ int WebViewCore::findTextOnPage(const WTF::String &text)
frame = frame->tree()->traverseNextWithWrap(false);
} while (frame);
m_activeMatchIndex = m_matchCount - 1; // prime first findNext
- if (!m_matchCount) // send at least one update, even if no hits
- updateMatchCount();
- else
- findNextOnPage(true);
return m_matchCount;
}
-void WebViewCore::findNextOnPage(bool forward)
+int WebViewCore::findNextOnPage(bool forward)
{
if (!m_mainFrame)
- return;
+ return -1;
if (!m_matchCount)
- return;
+ return -1;
EditorClientAndroid* client = static_cast<EditorClientAndroid*>(
m_mainFrame->editor()->client());
@@ -4295,24 +4355,12 @@ void WebViewCore::findNextOnPage(bool forward)
m_mainFrame->selection()->revealSelection(
ScrollAlignment::alignCenterIfNeeded, true);
}
- updateMatchCount();
}
// Clear selection so it doesn't display.
m_mainFrame->selection()->clear();
client->setUiGeneratedSelectionChange(false);
-}
-
-void WebViewCore::updateMatchCount() const
-{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject javaObject = m_javaGlue->object(env);
- if (!javaObject.get())
- return;
- jstring javaText = wtfStringToJstring(env, m_searchText, true);
- env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateMatchCount,
- m_activeMatchIndex, m_matchCount, javaText);
- checkException(env);
+ return m_activeMatchIndex;
}
String WebViewCore::getText(int startX, int startY, int endX, int endY)
@@ -4984,10 +5032,10 @@ static void ClearSelection(JNIEnv* env, jobject obj, jint nativeClass)
viewImpl->focusedFrame()->selection()->clear();
}
-static void SelectWordAt(JNIEnv* env, jobject obj, jint nativeClass, jint x, jint y)
+static bool SelectWordAt(JNIEnv* env, jobject obj, jint nativeClass, jint x, jint y)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- viewImpl->selectWordAt(x, y);
+ return viewImpl->selectWordAt(x, y);
}
static void SelectAll(JNIEnv* env, jobject obj, jint nativeClass)
@@ -5004,11 +5052,11 @@ static int FindAll(JNIEnv* env, jobject obj, jint nativeClass,
return viewImpl->findTextOnPage(wtfText);
}
-static void FindNext(JNIEnv* env, jobject obj, jint nativeClass,
+static int FindNext(JNIEnv* env, jobject obj, jint nativeClass,
jboolean forward)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- viewImpl->findNextOnPage(forward);
+ return viewImpl->findNextOnPage(forward);
}
// ----------------------------------------------------------------------------
@@ -5123,7 +5171,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SelectText },
{ "nativeClearTextSelection", "(I)V",
(void*) ClearSelection },
- { "nativeSelectWordAt", "(III)V",
+ { "nativeSelectWordAt", "(III)Z",
(void*) SelectWordAt },
{ "nativeSelectAll", "(I)V",
(void*) SelectAll },
@@ -5131,7 +5179,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) nativeCertTrustChanged },
{ "nativeFindAll", "(ILjava/lang/String;)I",
(void*) FindAll },
- { "nativeFindNext", "(IZ)V",
+ { "nativeFindNext", "(IZ)I",
(void*) FindNext },
};
@@ -5172,10 +5220,6 @@ int registerWebViewCore(JNIEnv* env)
"mViewportDensityDpi", "I");
ALOG_ASSERT(gWebViewCoreFields.m_viewportDensityDpi,
"Unable to find android/webkit/WebViewCore.mViewportDensityDpi");
- gWebViewCoreFields.m_webView = env->GetFieldID(widget,
- "mWebView", "Landroid/webkit/WebViewClassic;");
- ALOG_ASSERT(gWebViewCoreFields.m_webView,
- "Unable to find android/webkit/WebViewCore.mWebView");
gWebViewCoreFields.m_drawIsPaused = env->GetFieldID(widget,
"mDrawIsPaused", "Z");
ALOG_ASSERT(gWebViewCoreFields.m_drawIsPaused,
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index 6850111..5e2bafb 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -53,6 +53,7 @@
namespace WebCore {
class Color;
+ class GraphicsOperationCollection;
class FrameView;
class HTMLAnchorElement;
class HTMLElement;
@@ -85,9 +86,6 @@ class SkPicture;
class SkIRect;
namespace android {
- // TODO: This file hasn't been good about namespace. Remove this temporary
- // workaround to build
- using namespace WebCore;
enum Direction {
DIRECTION_BACKWARD = 0,
@@ -138,12 +136,6 @@ namespace android {
// Followings are called from native WebCore to Java
- /**
- * Notification that a form was blurred. Pass a message to hide the
- * keyboard if it was showing for that Node.
- * @param Node The Node that blurred.
- */
- void formDidBlur(const WebCore::Node*);
void focusNodeChanged(WebCore::Node*);
/**
@@ -174,7 +166,7 @@ namespace android {
void layersDraw();
#if USE(ACCELERATED_COMPOSITING)
- GraphicsLayerAndroid* graphicsRootLayer() const;
+ WebCore::GraphicsLayerAndroid* graphicsRootLayer() const;
#endif
/** Invalidate the view/screen, NOT the content/DOM, but expressed in
@@ -214,7 +206,7 @@ namespace android {
* Tell the java side to update the focused textfield
* @param pointer Pointer to the node for the input field.
* @param changeToPassword If true, we are changing the textfield to
- * a password field, and ignore the String
+ * a password field, and ignore the WTF::String
* @param text If changeToPassword is false, this is the new text that
* should go into the textfield.
*/
@@ -290,12 +282,13 @@ namespace android {
jobject getDeviceMotionService();
jobject getDeviceOrientationService();
- void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID, int msgLevel);
+ void addMessageToConsole(const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceID, int msgLevel);
/**
* Tell the Java side of the scrollbar mode
*/
- void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode);
+ void setScrollbarModes(WebCore::ScrollbarMode horizontalMode,
+ WebCore::ScrollbarMode verticalMode);
//
// Followings support calls from Java to native WebCore
@@ -310,7 +303,7 @@ namespace android {
// scroll the selection on screen (if necessary).
void revealSelection();
- void moveMouse(int x, int y, HitTestResult* hoveredNode = 0);
+ void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0);
// set the scroll amount that webview.java is currently showing
void setScrollOffset(bool sendScrollEvent, int dx, int dy);
@@ -326,8 +319,8 @@ namespace android {
* @return Whether keyCode was handled by this class.
*/
bool key(const WebCore::PlatformKeyboardEvent& event);
- bool chromeCanTakeFocus(FocusDirection direction);
- void chromeTakeFocus(FocusDirection direction);
+ bool chromeCanTakeFocus(WebCore::FocusDirection direction);
+ void chromeTakeFocus(WebCore::FocusDirection direction);
/**
* Handle (trackball) click event / dpad center press from Java.
@@ -339,7 +332,9 @@ namespace android {
/**
* Handle touch event
*/
- bool handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState);
+ bool handleTouchEvent(int action, WTF::Vector<int>& ids,
+ WTF::Vector<WebCore::IntPoint>& points,
+ int actionIndex, int metaState);
/**
* Handle motionUp event from the UI thread (called touchUp in the
@@ -382,11 +377,11 @@ namespace android {
* direction - The direction in which to alter the selection.
* granularity - The granularity of the selection modification.
*
- * returns - The selected HTML as a string. This is not a well formed
+ * returns - The selected HTML as a WTF::String. This is not a well formed
* HTML, rather the selection annotated with the tags of all
* intermediary elements it crosses.
*/
- String modifySelection(const int direction, const int granularity);
+ WTF::String modifySelection(const int direction, const int granularity);
/**
* Moves the selection to the given node in a given frame i.e. selects that node.
@@ -396,11 +391,11 @@ namespace android {
* frame - The frame in which to select is the node to be selected.
* node - The node to be selected.
*
- * returns - The selected HTML as a string. This is not a well formed
+ * returns - The selected HTML as a WTF::String. This is not a well formed
* HTML, rather the selection annotated with the tags of all
* intermediary elements it crosses.
*/
- String moveSelection(WebCore::Frame* frame, WebCore::Node* node);
+ WTF::String moveSelection(WebCore::Frame* frame, WebCore::Node* node);
/**
* In the currently focused textfield, replace the characters from oldStart to oldEnd
@@ -457,7 +452,7 @@ namespace android {
void sendPluginSurfaceReady();
// send onLoad event to plugins who are descendents of the given frame
- void notifyPluginsOnFrameLoad(const Frame*);
+ void notifyPluginsOnFrameLoad(const WebCore::Frame*);
// gets a rect representing the current on-screen portion of the document
void getVisibleScreen(ANPRectI&);
@@ -515,11 +510,11 @@ namespace android {
void centerFitRect(int x, int y, int width, int height);
// return a list of rects matching the touch point (x, y) with the slop
- Vector<IntRect> getTouchHighlightRects(int x, int y, int slop,
- Node** node, HitTestResult* hitTestResult);
+ WTF::Vector<WebCore::IntRect> getTouchHighlightRects(int x, int y, int slop,
+ WebCore::Node** node, WebCore::HitTestResult* hitTestResult);
// This does a sloppy hit test
AndroidHitTestResult hitTestAtPoint(int x, int y, int slop, bool doMoveMouse = false);
- static bool nodeIsClickableOrFocusable(Node* node);
+ static bool nodeIsClickableOrFocusable(WebCore::Node* node);
// Open a file chooser for selecting a file to upload
void openFileChooser(PassRefPtr<WebCore::FileChooser> );
@@ -530,13 +525,13 @@ namespace android {
bool focusBoundsChanged();
// record the inval area, and the picture size
- BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* );
+ WebCore::BaseLayerAndroid* recordContent(SkRegion* , SkIPoint* );
// This creates a new BaseLayerAndroid by copying the current m_content
// and doing a copy of the layers. The layers' content may be updated
// as we are calling layersSync().
- BaseLayerAndroid* createBaseLayer(SkRegion*);
- bool updateLayers(LayerAndroid*);
+ WebCore::BaseLayerAndroid* createBaseLayer(SkRegion*);
+ bool updateLayers(WebCore::LayerAndroid*);
void notifyAnimationStarted();
int textWrapWidth() const { return m_textWrapWidth; }
@@ -557,7 +552,7 @@ namespace android {
// find on page
void resetFindOnPage();
int findTextOnPage(const WTF::String &text);
- void findNextOnPage(bool forward);
+ int findNextOnPage(bool forward);
void updateMatchCount() const;
#if ENABLE(VIDEO)
@@ -600,14 +595,16 @@ namespace android {
*/
Vector<WebCore::VisibleSelection> getTextRanges(
int startX, int startY, int endX, int endY);
- static int platformLayerIdFromNode(Node* node, LayerAndroid** outLayer = 0);
+ static int platformLayerIdFromNode(WebCore::Node* node,
+ WebCore::LayerAndroid** outLayer = 0);
void selectText(int startX, int startY, int endX, int endY);
- void selectWordAt(int x, int y);
+ bool selectWordAt(int x, int y);
// Converts from the global content coordinates that WebView sends
// to frame-local content coordinates using the focused frame
- IntPoint convertGlobalContentToFrameContent(const IntPoint& point, WebCore::Frame* frame = 0);
- static void layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& offset);
+ WebCore::IntPoint convertGlobalContentToFrameContent(const WebCore::IntPoint& point, WebCore::Frame* frame = 0);
+ static void layerToAbsoluteOffset(const WebCore::LayerAndroid* layer,
+ WebCore::IntPoint& offset);
/**
* Returns a text position at a given coordinate.
@@ -615,7 +612,7 @@ namespace android {
WebCore::VisiblePosition visiblePositionForWindowPoint(int x, int y);
// Retrieves the current locale from system properties
- void getLocale(String& language, String& region);
+ void getLocale(String& language, WTF::String& region);
// Handles changes in system locale
void updateLocale();
@@ -645,6 +642,9 @@ namespace android {
void recordPictureSet(PictureSet* master);
SkPicture* rebuildPicture(const SkIRect& inval);
+#ifdef CONTEXT_RECORDING
+ WebCore::GraphicsOperationCollection* rebuildGraphicsOperationCollection(const SkIRect& inval);
+#endif
void rebuildPictureSet(PictureSet* );
void sendNotifyProgressFinished();
/*
@@ -660,28 +660,38 @@ namespace android {
const WebCore::QualifiedName& );
WebCore::HTMLImageElement* retrieveImageElement(int x, int y);
// below are members responsible for accessibility support
- String modifySelectionTextNavigationAxis(DOMSelection* selection, int direction, int granularity);
- String modifySelectionDomNavigationAxis(DOMSelection* selection, int direction, int granularity);
- Text* traverseNextContentTextNode(Node* fromNode, Node* toNode ,int direction);
- bool isVisible(Node* node);
- bool isHeading(Node* node);
- String formatMarkup(DOMSelection* selection);
+ WTF::String modifySelectionTextNavigationAxis(WebCore::DOMSelection* selection,
+ int direction, int granularity);
+ WTF::String modifySelectionDomNavigationAxis(WebCore::DOMSelection* selection,
+ int direction, int granularity);
+ WebCore::Text* traverseNextContentTextNode(WebCore::Node* fromNode,
+ WebCore::Node* toNode,
+ int direction);
+ bool isVisible(WebCore::Node* node);
+ bool isHeading(WebCore::Node* node);
+ WTF::String formatMarkup(WebCore::DOMSelection* selection);
void selectAt(int x, int y);
- void scrollNodeIntoView(Frame* frame, Node* node);
- bool isContentTextNode(Node* node);
- Node* getIntermediaryInputElement(Node* fromNode, Node* toNode, int direction);
- bool isContentInputElement(Node* node);
- bool isDescendantOf(Node* parent, Node* node);
- void advanceAnchorNode(DOMSelection* selection, int direction, String& markup, bool ignoreFirstNode, ExceptionCode& ec);
- Node* getNextAnchorNode(Node* anchorNode, bool skipFirstHack, int direction);
- Node* getImplicitBoundaryNode(Node* node, unsigned offset, int direction);
- jobject createTextFieldInitData(Node* node);
+ void scrollNodeIntoView(WebCore::Frame* frame, WebCore::Node* node);
+ bool isContentTextNode(WebCore::Node* node);
+ WebCore::Node* getIntermediaryInputElement(WebCore::Node* fromNode,
+ WebCore::Node* toNode,
+ int direction);
+ bool isContentInputElement(WebCore::Node* node);
+ bool isDescendantOf(WebCore::Node* parent, WebCore::Node* node);
+ void advanceAnchorNode(WebCore::DOMSelection* selection, int direction,
+ WTF::String& markup, bool ignoreFirstNode,
+ WebCore::ExceptionCode& ec);
+ WebCore::Node* getNextAnchorNode(WebCore::Node* anchorNode,
+ bool skipFirstHack, int direction);
+ WebCore::Node* getImplicitBoundaryNode(WebCore::Node* node,
+ unsigned offset, int direction);
+ jobject createTextFieldInitData(WebCore::Node* node);
/**
* Calls into java to reset the text edit field with the
* current contents and selection.
*/
- void initEditField(Node* node);
+ void initEditField(WebCore::Node* node);
/**
* If node is not a text input field or if it explicitly requests
@@ -689,55 +699,58 @@ namespace android {
* it is a text input field then initEditField is called and
* auto-fill information is requested for HTML form input fields.
*/
- void initializeTextInput(Node* node, bool fake = false);
+ void initializeTextInput(WebCore::Node* node, bool fake);
/**
* Gets the input type a Node. NONE is returned if it isn't an
* input field.
*/
- InputType getInputType(Node* node);
+ InputType getInputType(WebCore::Node* node);
/**
* If node is an input field, the spellcheck value for the
* field is returned. Otherwise true is returned.
*/
- static bool isSpellCheckEnabled(Node* node);
+ static bool isSpellCheckEnabled(WebCore::Node* node);
/**
* Returns the offsets of the selection area for both normal text
* fields and content editable fields. start and end are modified
* by this method.
*/
- static void getSelectionOffsets(Node* node, int& start, int& end);
+ static void getSelectionOffsets(WebCore::Node* node, int& start, int& end);
/**
* Gets the plain text of the specified editable text field. node
* may be content-editable or a plain text fields.
*/
- static String getInputText(Node* node);
+ static WTF::String getInputText(WebCore::Node* node);
/**
* Gets the RenderTextControl for the given node if it has one.
* If its renderer isn't a RenderTextControl, then NULL is returned.
*/
- static RenderTextControl* toRenderTextControl(Node *node);
+ static WebCore::RenderTextControl* toRenderTextControl(WebCore::Node *node);
/**
* Sets the selection for node's editable field to the offsets
* between start (inclusive) and end (exclusive).
*/
- static void setSelection(Node* node, int start, int end);
+ static void setSelection(WebCore::Node* node, int start, int end);
/**
* Returns the Position for the given offset for an editable
* field. The offset is relative to the node start.
*/
- static WebCore::Position getPositionForOffset(Node* node, int offset);
+ static WebCore::Position getPositionForOffset(WebCore::Node* node, int offset);
- VisiblePosition visiblePositionForContentPoint(int x, int y);
- VisiblePosition visiblePositionForContentPoint(const IntPoint& point);
- void selectWordAroundPosition(Frame* frame, VisiblePosition pos);
- SelectText* createSelectText(const VisibleSelection&);
- static int getMaxLength(Node* node);
- static String getFieldName(Node* node);
- static bool isAutoCompleteEnabled(Node* node);
- IntRect boundingRect(Node* node, LayerAndroid* layer);
+ WebCore::VisiblePosition visiblePositionForContentPoint(int x, int y);
+ WebCore::VisiblePosition visiblePositionForContentPoint(const WebCore::IntPoint& point);
+ bool selectWordAroundPosition(WebCore::Frame* frame,
+ WebCore::VisiblePosition pos);
+ SelectText* createSelectText(const WebCore::VisibleSelection&);
+ static int getMaxLength(WebCore::Node* node);
+ static WTF::String getFieldName(WebCore::Node* node);
+ static bool isAutoCompleteEnabled(WebCore::Node* node);
+ WebCore::IntRect boundingRect(WebCore::Node* node,
+ WebCore::LayerAndroid* layer);
+ static WebCore::IntRect positionToTextRect(const WebCore::Position& position);
// called from constructor, to add this to a global list
static void addInstance(WebViewCore*);
@@ -751,7 +764,6 @@ namespace android {
struct TextFieldInitDataGlue* m_textFieldInitDataGlue;
WebCore::Frame* m_mainFrame;
WebCoreReply* m_popupReply;
- int m_blurringNodePointer;
PictureSet m_content; // the set of pictures to draw
SkRegion m_addInval; // the accumulated inval region (not yet drawn)
SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures
@@ -773,7 +785,7 @@ namespace android {
int m_screenHeight;// height of the visible rect in document coordinates
int m_textWrapWidth;
float m_scale;
- PageGroup* m_groupForVisitedLinks;
+ WebCore::PageGroup* m_groupForVisitedLinks;
bool m_isPaused;
int m_cacheMode;
bool m_fullscreenVideoMode;
@@ -791,7 +803,7 @@ namespace android {
}
int m_screenOnCounter;
- Node* m_currentNodeDomNavigationAxis;
+ WebCore::Node* m_currentNodeDomNavigationAxis;
DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager;
#if ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebKit/android/nav/DrawExtra.h b/Source/WebKit/android/nav/DrawExtra.h
index 83e7dcd..cc94476 100644
--- a/Source/WebKit/android/nav/DrawExtra.h
+++ b/Source/WebKit/android/nav/DrawExtra.h
@@ -54,7 +54,6 @@ namespace android {
class DrawExtra {
public:
virtual ~DrawExtra() {}
- virtual void drawLegacy(SkCanvas* , LayerAndroid* , IntRect* ) {}
virtual void draw(SkCanvas*, LayerAndroid*) {}
virtual void drawGL(GLExtras*, const LayerAndroid*) {}
};
diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h
index 904b2b9..50bc82e 100644
--- a/Source/WebKit/android/nav/SelectText.h
+++ b/Source/WebKit/android/nav/SelectText.h
@@ -43,6 +43,8 @@ public:
IntRect& caretRect(HandleId id) { return m_caretRects[mapId(id)]; }
void setCaretRect(HandleId id, const IntRect& rect) { m_caretRects[mapId(id)] = rect; }
+ IntRect& textRect(HandleId id) { return m_textRects[mapId(id)]; }
+ void setTextRect(HandleId id, const IntRect& rect) { m_textRects[mapId(id)] = rect; }
int caretLayerId(HandleId id) { return m_caretLayerId[mapId(id)]; }
void setCaretLayerId(HandleId id, int layerId) { m_caretLayerId[mapId(id)] = layerId; }
@@ -56,6 +58,7 @@ private:
HandleId mapId(HandleId id);
IntRect m_caretRects[2];
+ IntRect m_textRects[2];
int m_caretLayerId[2];
bool m_baseIsFirst;
String m_text;
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index eddf0ab..a4381e6 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -30,13 +30,16 @@
#include "AndroidAnimation.h"
#include "AndroidLog.h"
#include "BaseLayerAndroid.h"
+#include "BaseRenderer.h"
#include "DrawExtra.h"
#include "Frame.h"
+#include "GLWebViewState.h"
#include "GraphicsJNI.h"
#include "HTMLInputElement.h"
#include "IntPoint.h"
#include "IntRect.h"
#include "LayerAndroid.h"
+#include "LayerContent.h"
#include "Node.h"
#include "utils/Functor.h"
#include "private/hwui/DrawGlInfo.h"
@@ -50,6 +53,7 @@
#include "SkRect.h"
#include "SkTime.h"
#include "TilesManager.h"
+#include "TransferQueue.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebViewCore.h"
@@ -124,6 +128,10 @@ struct JavaGlue {
jfieldID m_rectTop;
jmethodID m_rectWidth;
jmethodID m_rectHeight;
+ jfieldID m_quadFP1;
+ jfieldID m_quadFP2;
+ jfieldID m_quadFP3;
+ jfieldID m_quadFP4;
AutoJObject object(JNIEnv* env) {
return getRealObject(env, m_obj);
}
@@ -155,6 +163,14 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir,
m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I");
env->DeleteLocalRef(rectClass);
+ jclass quadFClass = env->FindClass("android/webkit/QuadF");
+ ALOG_ASSERT(quadFClass, "Could not find QuadF class");
+ m_javaGlue.m_quadFP1 = env->GetFieldID(quadFClass, "p1", "Landroid/graphics/PointF;");
+ m_javaGlue.m_quadFP2 = env->GetFieldID(quadFClass, "p2", "Landroid/graphics/PointF;");
+ m_javaGlue.m_quadFP3 = env->GetFieldID(quadFClass, "p3", "Landroid/graphics/PointF;");
+ m_javaGlue.m_quadFP4 = env->GetFieldID(quadFClass, "p4", "Landroid/graphics/PointF;");
+ env->DeleteLocalRef(quadFClass);
+
env->SetIntField(javaWebView, gWebViewField, (jint)this);
m_viewImpl = (WebViewCore*) viewImpl;
m_generation = 0;
@@ -235,25 +251,18 @@ void scrollRectOnScreen(const IntRect& rect)
viewInvalidate();
}
-bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
+int drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
WebCore::IntRect& webViewRect, int titleBarHeight,
- WebCore::IntRect& clip, float scale, int extras)
+ WebCore::IntRect& clip, float scale, int extras, bool shouldDraw)
{
#if USE(ACCELERATED_COMPOSITING)
if (!m_baseLayer)
- return false;
+ return 0;
if (!m_glWebViewState) {
TilesManager::instance()->setHighEndGfx(m_isHighEndGfx);
m_glWebViewState = new GLWebViewState();
- if (m_baseLayer->content()) {
- SkRegion region;
- SkIRect rect;
- rect.set(0, 0, m_baseLayer->content()->width(), m_baseLayer->content()->height());
- region.setRect(rect);
- m_baseLayer->markAsDirty(region);
- m_glWebViewState->setBaseLayer(m_baseLayer, false, true);
- }
+ m_glWebViewState->setBaseLayer(m_baseLayer, false, true);
}
DrawExtra* extra = getDrawExtra((DrawExtras) extras);
@@ -264,12 +273,12 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
// if the zoom manager is still initializing. We will be redrawn
// once the correct scale is set
if (!m_visibleRect.isFinite())
- return false;
+ return 0;
bool treesSwapped = false;
bool newTreeHasAnim = false;
- bool ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect,
+ int ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect,
webViewRect, titleBarHeight, clip, scale,
- &treesSwapped, &newTreeHasAnim);
+ &treesSwapped, &newTreeHasAnim, shouldDraw);
if (treesSwapped) {
ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
@@ -279,10 +288,9 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
checkException(env);
}
}
- if (ret)
- return !m_isDrawingPaused;
+ return m_isDrawingPaused ? 0 : ret;
#endif
- return false;
+ return 0;
}
PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool split)
@@ -295,37 +303,24 @@ PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool spli
// draw the content of the base layer first
LayerContent* content = m_baseLayer->content();
-
int sc = canvas->save(SkCanvas::kClip_SaveFlag);
canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(),
content->height()), SkRegion::kDifference_Op);
canvas->drawColor(bgColor);
canvas->restoreToCount(sc);
- content->draw(canvas);
- DrawExtra* extra = getDrawExtra(extras);
- if (extra)
- extra->draw(canvas, 0);
+ // call this to be sure we've adjusted for any scrolling or animations
+ // before we actually draw
+ m_baseLayer->updateLayerPositions(m_visibleRect);
+ m_baseLayer->updatePositions();
+
+ // We have to set the canvas' matrix on the base layer
+ // (to have fixed layers work as intended)
+ SkAutoCanvasRestore restore(canvas, true);
+ m_baseLayer->setMatrix(canvas->getTotalMatrix());
+ canvas->resetMatrix();
+ m_baseLayer->draw(canvas, getDrawExtra(extras));
-#if USE(ACCELERATED_COMPOSITING)
- LayerAndroid* compositeLayer = compositeRoot();
- if (compositeLayer) {
- // call this to be sure we've adjusted for any scrolling or animations
- // before we actually draw
- compositeLayer->updateLayerPositions(m_visibleRect);
- compositeLayer->updatePositions();
- // We have to set the canvas' matrix on the base layer
- // (to have fixed layers work as intended)
- SkAutoCanvasRestore restore(canvas, true);
- m_baseLayer->setMatrix(canvas->getTotalMatrix());
- canvas->resetMatrix();
- m_baseLayer->draw(canvas, extra);
- }
- if (extra) {
- IntRect dummy; // inval area, unused for now
- extra->drawLegacy(canvas, compositeLayer, &dummy);
- }
-#endif
return ret;
}
@@ -415,11 +410,9 @@ static const ScrollableLayerAndroid* findScrollableLayer(
int scrollableLayer(int x, int y, SkIRect* layerRect, SkIRect* bounds)
{
#if USE(ACCELERATED_COMPOSITING)
- const LayerAndroid* layerRoot = compositeRoot();
- if (!layerRoot)
+ if (!m_baseLayer)
return 0;
- const ScrollableLayerAndroid* result = findScrollableLayer(layerRoot, x, y,
- bounds);
+ const ScrollableLayerAndroid* result = findScrollableLayer(m_baseLayer, x, y, bounds);
if (result) {
result->getScrollRect(layerRect);
return result->uniqueId();
@@ -500,16 +493,6 @@ void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds)
checkException(env);
}
-LayerAndroid* compositeRoot() const
-{
- ALOG_ASSERT(!m_baseLayer || m_baseLayer->countChildren() == 1,
- "base layer can't have more than one child %s", __FUNCTION__);
- if (m_baseLayer && m_baseLayer->countChildren() == 1)
- return static_cast<LayerAndroid*>(m_baseLayer->getChild(0));
- else
- return 0;
-}
-
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
static void copyScrollPositionRecursive(const LayerAndroid* from,
LayerAndroid* root)
@@ -529,28 +512,30 @@ static void copyScrollPositionRecursive(const LayerAndroid* from,
}
#endif
-bool setBaseLayer(BaseLayerAndroid* layer, SkRegion& inval, bool showVisualIndicator,
+BaseLayerAndroid* getBaseLayer() const { return m_baseLayer; }
+
+bool setBaseLayer(BaseLayerAndroid* newBaseLayer, SkRegion& inval, bool showVisualIndicator,
bool isPictureAfterFirstLayout)
{
bool queueFull = false;
#if USE(ACCELERATED_COMPOSITING)
if (m_glWebViewState) {
- if (layer)
- layer->markAsDirty(inval);
- queueFull = m_glWebViewState->setBaseLayer(layer, showVisualIndicator,
+ // TODO: mark as inval on webkit side
+ if (newBaseLayer)
+ newBaseLayer->markAsDirty(inval);
+ queueFull = m_glWebViewState->setBaseLayer(newBaseLayer, showVisualIndicator,
isPictureAfterFirstLayout);
}
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (layer) {
- // TODO: the below tree copies are only necessary in software rendering
- LayerAndroid* newCompositeRoot = static_cast<LayerAndroid*>(layer->getChild(0));
- copyScrollPositionRecursive(compositeRoot(), newCompositeRoot);
+ if (newBaseLayer) {
+ // TODO: the below tree position copies are only necessary in software rendering
+ copyScrollPositionRecursive(m_baseLayer, newBaseLayer);
}
#endif
SkSafeUnref(m_baseLayer);
- m_baseLayer = layer;
+ m_baseLayer = newBaseLayer;
return queueFull;
}
@@ -568,8 +553,8 @@ void copyBaseContentToPicture(SkPicture* picture)
if (!m_baseLayer)
return;
LayerContent* content = m_baseLayer->content();
- m_baseLayer->drawCanvas(picture->beginRecording(content->width(), content->height(),
- SkPicture::kUsePathBoundsForClip_RecordingFlag));
+ content->draw(picture->beginRecording(content->width(), content->height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag));
picture->endRecording();
}
@@ -588,10 +573,6 @@ Functor* getFunctor() {
return m_glDrawFunctor;
}
-BaseLayerAndroid* getBaseLayer() {
- return m_baseLayer;
-}
-
void setVisibleRect(SkRect& visibleRect) {
m_visibleRect = visibleRect;
}
@@ -611,13 +592,34 @@ void setTextSelection(SelectText *selection) {
setDrawExtra(selection, DrawExtrasSelection);
}
-int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) {
+int getHandleLayerId(SelectText::HandleId handleId, SkIPoint& cursorPoint,
+ FloatQuad& textBounds) {
SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection));
if (!selectText || !m_baseLayer)
return -1;
int layerId = selectText->caretLayerId(handleId);
- cursorRect = selectText->caretRect(handleId);
- mapLayerRect(layerId, cursorRect);
+ IntRect cursorRect = selectText->caretRect(handleId);
+ IntRect textRect = selectText->textRect(handleId);
+ // Rects exclude the last pixel on right/bottom. We want only included pixels.
+ cursorPoint.set(cursorRect.x(), cursorRect.maxY() - 1);
+ textRect.setHeight(textRect.height() - 1);
+ textRect.setWidth(textRect.width() - 1);
+ textBounds = FloatQuad(textRect);
+
+ if (layerId != -1) {
+ // We need to make sure the drawTransform is up to date as this is
+ // called before a draw() or drawGL()
+ m_baseLayer->updateLayerPositions(m_visibleRect);
+ LayerAndroid* root = m_baseLayer;
+ LayerAndroid* layer = root ? root->findById(layerId) : 0;
+ if (layer && layer->drawTransform()) {
+ const TransformationMatrix* transform = layer->drawTransform();
+ // We're overloading the concept of Rect to be just the two
+ // points (bottom-left and top-right.
+ cursorPoint = transform->mapPoint(cursorPoint);
+ textBounds = transform->mapQuad(textBounds);
+ }
+ }
return layerId;
}
@@ -626,13 +628,40 @@ void mapLayerRect(int layerId, SkIRect& rect) {
// We need to make sure the drawTransform is up to date as this is
// called before a draw() or drawGL()
m_baseLayer->updateLayerPositions(m_visibleRect);
- LayerAndroid* root = compositeRoot();
- LayerAndroid* layer = root ? root->findById(layerId) : 0;
+ LayerAndroid* layer = m_baseLayer ? m_baseLayer->findById(layerId) : 0;
if (layer && layer->drawTransform())
rect = layer->drawTransform()->mapRect(rect);
}
}
+void floatQuadToQuadF(JNIEnv* env, const FloatQuad& nativeTextQuad,
+ jobject textQuad)
+{
+ jobject p1 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP1);
+ jobject p2 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP2);
+ jobject p3 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP3);
+ jobject p4 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP4);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p1(), env, p1);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p2(), env, p2);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p3(), env, p3);
+ GraphicsJNI::point_to_jpointf(nativeTextQuad.p4(), env, p4);
+ env->DeleteLocalRef(p1);
+ env->DeleteLocalRef(p2);
+ env->DeleteLocalRef(p3);
+ env->DeleteLocalRef(p4);
+}
+
+// This is called when WebView switches rendering modes in a more permanent fashion
+// such as when the layer type is set or the view is attached/detached from the window
+int setHwAccelerated(bool hwAccelerated) {
+ if (!m_glWebViewState)
+ return 0;
+ LayerAndroid* root = m_baseLayer;
+ if (root)
+ return root->setHwAccelerated(hwAccelerated);
+ return 0;
+}
+
bool m_isDrawingPaused;
private: // local state for WebView
// private to getFrameCache(); other functions operate in a different thread
@@ -661,8 +690,8 @@ private: // local state for WebView
class GLDrawFunctor : Functor {
public:
GLDrawFunctor(WebView* _wvInstance,
- bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
- WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint),
+ int (WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
+ WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint, bool),
WebCore::IntRect _viewRect, float _scale, int _extras) {
wvInstance = _wvInstance;
funcPtr = _funcPtr;
@@ -687,16 +716,15 @@ class GLDrawFunctor : Functor {
WebCore::IntRect clip(info->clipLeft, info->clipTop,
info->clipRight - info->clipLeft,
info->clipBottom - info->clipTop);
+ bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw);
TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer);
-
- bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect,
- titlebarHeight, clip, scale, extras);
- if (retVal) {
+ int returnFlags = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect,
+ titlebarHeight, clip, scale, extras, shouldDraw);
+ if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) {
IntRect finalInval;
- if (inval.isEmpty()) {
+ if (inval.isEmpty())
finalInval = webViewRect;
- retVal = true;
- } else {
+ else {
finalInval.setX(webViewRect.x() + inval.x());
finalInval.setY(webViewRect.y() + titlebarHeight + inval.y());
finalInval.setWidth(inval.width());
@@ -707,8 +735,9 @@ class GLDrawFunctor : Functor {
info->dirtyRight = finalInval.maxX();
info->dirtyBottom = finalInval.maxY();
}
- // return 1 if invalidation needed, 0 otherwise
- return retVal ? 1 : 0;
+ // return 1 if invalidation needed, 2 to request non-drawing functor callback, 0 otherwise
+ ALOGV("returnFlags are %d, shouldDraw %d", returnFlags, shouldDraw);
+ return returnFlags;
}
void updateRect(WebCore::IntRect& _viewRect) {
viewRect = _viewRect;
@@ -721,8 +750,8 @@ class GLDrawFunctor : Functor {
}
private:
WebView* wvInstance;
- bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
- WebCore::IntRect&, int, WebCore::IntRect&, float, int);
+ int (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
+ WebCore::IntRect&, int, WebCore::IntRect&, float, int, bool);
WebCore::IntRect viewRect;
WebCore::IntRect webViewRect;
jfloat scale;
@@ -815,10 +844,10 @@ static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint native
{
// only call in software rendering, initialize and evaluate animations
#if USE(ACCELERATED_COMPOSITING)
- LayerAndroid* root = ((WebView*)nativeView)->compositeRoot();
- if (root) {
- root->initAnimations();
- return root->evaluateAnimations();
+ BaseLayerAndroid* baseLayer = ((WebView*)nativeView)->getBaseLayer();
+ if (baseLayer) {
+ baseLayer->initAnimations();
+ return baseLayer->evaluateAnimations();
}
#endif
return false;
@@ -970,6 +999,7 @@ static void dumpToFile(const char text[], void* file) {
}
#endif
+// Return true to view invalidate WebView
static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jvalue)
{
WTF::String key = jstringToWtfString(env, jkey);
@@ -987,19 +1017,15 @@ static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jv
else if (key == "enable_cpu_upload_path") {
TilesManager::instance()->transferQueue()->setTextureUploadType(
value == "true" ? CpuUpload : GpuUpload);
- return true;
}
else if (key == "use_minimal_memory") {
TilesManager::instance()->setUseMinimalMemory(value == "true");
- return true;
}
else if (key == "use_double_buffering") {
TilesManager::instance()->setUseDoubleBuffering(value == "true");
- return true;
}
else if (key == "tree_updates") {
TilesManager::instance()->clearContentUpdates();
- return true;
}
return false;
}
@@ -1063,11 +1089,11 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
fclose(file);
}
#if USE(ACCELERATED_COMPOSITING)
- const LayerAndroid* rootLayer = view->compositeRoot();
- if (rootLayer) {
+ const LayerAndroid* baseLayer = view->getBaseLayer();
+ if (baseLayer) {
FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w");
if (file) {
- rootLayer->dumpLayers(file, 0);
+ baseLayer->dumpLayers(file, 0);
fclose(file);
}
}
@@ -1098,10 +1124,10 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x,
view->scrollLayer(layerId, x, y);
//TODO: the below only needed for the SW rendering path
- LayerAndroid* root = view->compositeRoot();
- if (!root)
+ LayerAndroid* baseLayer = view->getBaseLayer();
+ if (!baseLayer)
return false;
- LayerAndroid* layer = root->findById(layerId);
+ LayerAndroid* layer = baseLayer->findById(layerId);
if (!layer || !layer->contentIsScrollable())
return false;
return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
@@ -1148,13 +1174,18 @@ static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView,
}
static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView,
- jint handleIndex, jobject cursorRect)
+ jint handleIndex, jobject cursorPoint,
+ jobject textQuad)
{
WebView* webview = reinterpret_cast<WebView*>(nativeView);
- SkIRect nativeRect;
- int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, nativeRect);
- if (cursorRect)
- GraphicsJNI::irect_to_jrect(nativeRect, env, cursorRect);
+ SkIPoint nativePoint;
+ FloatQuad nativeTextQuad;
+ int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex,
+ nativePoint, nativeTextQuad);
+ if (cursorPoint)
+ GraphicsJNI::ipoint_to_jpoint(nativePoint, env, cursorPoint);
+ if (textQuad)
+ webview->floatQuadToQuadF(env, nativeTextQuad, textQuad);
return layerId;
}
@@ -1176,6 +1207,13 @@ static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView,
GraphicsJNI::irect_to_jrect(nativeRect, env, rect);
}
+static jint nativeSetHwAccelerated(JNIEnv *env, jobject obj, jint nativeView,
+ jboolean hwAccelerated)
+{
+ WebView* webview = reinterpret_cast<WebView*>(nativeView);
+ return webview->setHwAccelerated(hwAccelerated);
+}
+
/*
* JNI registration
*/
@@ -1248,12 +1286,14 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetPauseDrawing },
{ "nativeSetTextSelection", "(II)V",
(void*) nativeSetTextSelection },
- { "nativeGetHandleLayerId", "(IILandroid/graphics/Rect;)I",
+ { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I",
(void*) nativeGetHandleLayerId },
{ "nativeIsBaseFirst", "(I)Z",
(void*) nativeIsBaseFirst },
{ "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V",
(void*) nativeMapLayerRect },
+ { "nativeSetHwAccelerated", "(IZ)I",
+ (void*) nativeSetHwAccelerated },
};
int registerWebView(JNIEnv* env)
diff --git a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp
index 513d251..92dbbcd 100644
--- a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp
+++ b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp
@@ -47,7 +47,7 @@ static struct ANPSurfaceInterfaceJavaGlue {
jfieldID surfacePointer;
} gSurfaceJavaGlue;
-static inline sp<Surface> getSurface(JNIEnv* env, jobject view) {
+static inline sp<android::Surface> getSurface(JNIEnv* env, jobject view) {
if (!env || !view) {
return NULL;
}
@@ -80,7 +80,7 @@ static inline sp<Surface> getSurface(JNIEnv* env, jobject view) {
env->DeleteLocalRef(holder);
env->DeleteLocalRef(surface);
- return sp<Surface>((Surface*) surfacePointer);
+ return sp<android::Surface>((android::Surface*) surfacePointer);
}
static inline ANPBitmapFormat convertPixelFormat(PixelFormat format) {
@@ -96,9 +96,9 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec
return false;
}
- sp<Surface> surface = getSurface(env, surfaceView);
+ sp<android::Surface> surface = getSurface(env, surfaceView);
- if (!bitmap || !Surface::isValid(surface)) {
+ if (!bitmap || !android::Surface::isValid(surface)) {
return false;
}
@@ -112,7 +112,7 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec
dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
}
- Surface::SurfaceInfo info;
+ android::Surface::SurfaceInfo info;
status_t err = surface->lock(&info, &dirtyRegion);
if (err < 0) {
return false;
@@ -150,9 +150,9 @@ static void anp_unlock(JNIEnv* env, jobject surfaceView) {
return;
}
- sp<Surface> surface = getSurface(env, surfaceView);
+ sp<android::Surface> surface = getSurface(env, surfaceView);
- if (!Surface::isValid(surface)) {
+ if (!android::Surface::isValid(surface)) {
return;
}
diff --git a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
index d0af1a5..09bb24e 100644
--- a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -160,7 +160,8 @@ bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) {
if (model == kOpenGL_ANPDrawingModel && m_layer == 0) {
jobject webview = m_core->getWebViewJavaObject();
- m_layer = new WebCore::MediaLayer(webview);
+ AutoJObject webViewCore = m_core->getJavaObject();
+ m_layer = new WebCore::MediaLayer(webview, webViewCore.get());
}
else if (model != kOpenGL_ANPDrawingModel && m_layer != 0) {
m_layer->unref();