summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/Android.derived.jscbindings.mk752
-rw-r--r--Source/WebCore/Android.derived.v8bindings.mk1
-rw-r--r--Source/WebCore/Android.jscbindings.mk240
-rw-r--r--Source/WebCore/Android.mk23
-rw-r--r--Source/WebCore/Android.v8bindings.mk1
-rw-r--r--Source/WebCore/DerivedSources.cpp1
-rw-r--r--Source/WebCore/bindings/js/JSBindingsAllInOne.cpp1
-rw-r--r--Source/WebCore/bindings/js/JSDOMWindowCustom.cpp6
-rw-r--r--Source/WebCore/bindings/js/JSFloat64ArrayCustom.cpp61
-rw-r--r--Source/WebCore/bindings/v8/V8DOMWindowShell.cpp12
-rw-r--r--Source/WebCore/bindings/v8/V8Proxy.cpp34
-rw-r--r--Source/WebCore/bindings/v8/V8Proxy.h8
-rw-r--r--Source/WebCore/bindings/v8/custom/V8Float64ArrayCustom.cpp61
-rw-r--r--Source/WebCore/bridge/jni/JavaMethodJobject.cpp8
-rw-r--r--Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp43
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaValueV8.h13
-rw-r--r--Source/WebCore/css/AndroidCSSPropertyNames.in11
-rw-r--r--Source/WebCore/css/CSSComputedStyleDeclaration.cpp35
-rw-r--r--Source/WebCore/css/CSSImportRule.cpp22
-rw-r--r--Source/WebCore/css/CSSImportRule.h8
-rw-r--r--Source/WebCore/css/CSSMutableStyleDeclaration.cpp14
-rw-r--r--Source/WebCore/css/CSSParser.cpp85
-rw-r--r--Source/WebCore/css/CSSPropertyNames.in1
-rw-r--r--Source/WebCore/css/CSSStyleDeclaration.cpp1
-rw-r--r--Source/WebCore/css/CSSStyleSelector.cpp132
-rw-r--r--Source/WebCore/css/CSSValueKeywords.in4
-rw-r--r--Source/WebCore/css/StyleBase.cpp33
-rw-r--r--Source/WebCore/css/StyleBase.h12
-rw-r--r--Source/WebCore/css/mediaControlsAndroid.css5
-rw-r--r--Source/WebCore/dom/DOMTextContentWalker.cpp95
-rw-r--r--Source/WebCore/dom/DOMTextContentWalker.h60
-rw-r--r--Source/WebCore/dom/Document.cpp19
-rw-r--r--Source/WebCore/dom/Node.cpp33
-rw-r--r--Source/WebCore/dom/Node.h12
-rw-r--r--Source/WebCore/dom/ProcessingInstruction.cpp22
-rw-r--r--Source/WebCore/dom/ProcessingInstruction.h8
-rw-r--r--Source/WebCore/dom/Text.cpp2
-rw-r--r--Source/WebCore/editing/InsertIntoTextNodeCommand.cpp10
-rw-r--r--Source/WebCore/editing/SelectionController.cpp8
-rw-r--r--Source/WebCore/editing/TextIterator.cpp71
-rw-r--r--Source/WebCore/editing/TextIterator.h22
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp6
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h16
-rw-r--r--Source/WebCore/html/HTMLDocument.cpp22
-rw-r--r--Source/WebCore/html/HTMLDocument.h8
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp22
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h8
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h4
-rw-r--r--Source/WebCore/html/canvas/ArrayBufferView.h1
-rw-r--r--Source/WebCore/html/canvas/Float64Array.cpp62
-rw-r--r--Source/WebCore/html/canvas/Float64Array.h75
-rw-r--r--Source/WebCore/html/canvas/Float64Array.idl48
-rw-r--r--Source/WebCore/html/parser/HTMLDocumentParser.cpp14
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp19
-rw-r--r--Source/WebCore/loader/archive/android/WebArchiveAndroid.cpp61
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp2
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.h6
-rw-r--r--Source/WebCore/loader/icon/IconDatabase.cpp26
-rw-r--r--Source/WebCore/page/DOMWindow.cpp16
-rw-r--r--Source/WebCore/page/DOMWindow.idl1
-rw-r--r--Source/WebCore/page/EventHandler.cpp6
-rw-r--r--Source/WebCore/page/Frame.cpp4
-rw-r--r--Source/WebCore/page/FrameView.cpp24
-rw-r--r--Source/WebCore/page/Settings.cpp16
-rw-r--r--Source/WebCore/page/Settings.h17
-rw-r--r--Source/WebCore/platform/Arena.cpp12
-rw-r--r--Source/WebCore/platform/Arena.h4
-rw-r--r--Source/WebCore/platform/NotImplemented.h16
-rw-r--r--Source/WebCore/platform/ScrollView.cpp59
-rw-r--r--Source/WebCore/platform/ScrollView.h16
-rw-r--r--Source/WebCore/platform/android/KeyEventAndroid.cpp4
-rw-r--r--Source/WebCore/platform/android/PopupMenuAndroid.cpp3
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.cpp257
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.h10
-rw-r--r--Source/WebCore/platform/android/ScrollViewAndroid.cpp30
-rw-r--r--Source/WebCore/platform/android/SharedTimerAndroid.cpp2
-rw-r--r--Source/WebCore/platform/android/TemporaryLinkStubs.cpp19
-rw-r--r--Source/WebCore/platform/android/WidgetAndroid.cpp9
-rw-r--r--Source/WebCore/platform/graphics/Color.h9
-rw-r--r--Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp38
-rw-r--r--Source/WebCore/platform/graphics/GlyphPageTreeNode.h5
-rw-r--r--Source/WebCore/platform/graphics/Gradient.h8
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.cpp6
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h10
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.cpp45
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp369
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.h60
-rw-r--r--Source/WebCore/platform/graphics/android/BaseRenderer.cpp117
-rw-r--r--Source/WebCore/platform/graphics/android/BaseRenderer.h17
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp306
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.h37
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp203
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h81
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasLayer.cpp218
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasLayer.h (renamed from Source/WebCore/platform/graphics/android/TilesTracker.h)88
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasTexture.cpp225
-rw-r--r--Source/WebCore/platform/graphics/android/CanvasTexture.h95
-rw-r--r--Source/WebCore/platform/graphics/android/ClassTracker.cpp43
-rw-r--r--Source/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp217
-rw-r--r--Source/WebCore/platform/graphics/android/DumpLayer.cpp83
-rw-r--r--Source/WebCore/platform/graphics/android/DumpLayer.h67
-rw-r--r--Source/WebCore/platform/graphics/android/FixedPositioning.cpp105
-rw-r--r--Source/WebCore/platform/graphics/android/FixedPositioning.h128
-rw-r--r--Source/WebCore/platform/graphics/android/FontAndroid.cpp134
-rw-r--r--Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/FontDataAndroid.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/FontPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp50
-rw-r--r--Source/WebCore/platform/graphics/android/GLExtras.cpp127
-rw-r--r--Source/WebCore/platform/graphics/android/GLExtras.h32
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.cpp342
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.h18
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp454
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h78
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshContext.cpp150
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshContext.h12
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshRenderer.cpp97
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshRenderer.h4
-rw-r--r--Source/WebCore/platform/graphics/android/GradientAndroid.cpp64
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp990
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp227
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h9
-rw-r--r--Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp42
-rw-r--r--Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h78
-rw-r--r--Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp40
-rw-r--r--Source/WebCore/platform/graphics/android/IFrameLayerAndroid.h (renamed from Source/WebCore/platform/graphics/android/DoubleBufferedTexture.h)72
-rw-r--r--Source/WebCore/platform/graphics/android/ImageAndroid.cpp76
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.cpp59
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.h9
-rw-r--r--Source/WebCore/platform/graphics/android/ImagesManager.cpp23
-rw-r--r--Source/WebCore/platform/graphics/android/ImagesManager.h2
-rw-r--r--Source/WebCore/platform/graphics/android/InspectorCanvas.cpp133
-rw-r--r--Source/WebCore/platform/graphics/android/InspectorCanvas.h102
-rw-r--r--Source/WebCore/platform/graphics/android/Layer.cpp15
-rw-r--r--Source/WebCore/platform/graphics/android/Layer.h32
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp1049
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h220
-rw-r--r--Source/WebCore/platform/graphics/android/LayerContent.h56
-rw-r--r--Source/WebCore/platform/graphics/android/LayerGroup.cpp345
-rw-r--r--Source/WebCore/platform/graphics/android/LayerGroup.h115
-rw-r--r--Source/WebCore/platform/graphics/android/MediaLayer.cpp39
-rw-r--r--Source/WebCore/platform/graphics/android/MediaLayer.h4
-rw-r--r--Source/WebCore/platform/graphics/android/MediaListener.h15
-rw-r--r--Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h1
-rw-r--r--Source/WebCore/platform/graphics/android/MediaTexture.cpp61
-rw-r--r--Source/WebCore/platform/graphics/android/MediaTexture.h3
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.cpp42
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.h31
-rw-r--r--Source/WebCore/platform/graphics/android/PaintedSurface.cpp224
-rw-r--r--Source/WebCore/platform/graphics/android/PaintedSurface.h94
-rw-r--r--Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp104
-rw-r--r--Source/WebCore/platform/graphics/android/PictureLayerContent.cpp106
-rw-r--r--Source/WebCore/platform/graphics/android/PictureLayerContent.h (renamed from Source/WebCore/platform/graphics/android/PerformanceMonitor.h)46
-rw-r--r--Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp41
-rw-r--r--Source/WebCore/platform/graphics/android/PictureSetLayerContent.h (renamed from Source/WebCore/platform/graphics/android/DeleteTextureOperation.h)48
-rw-r--r--Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp1011
-rw-r--r--Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h112
-rw-r--r--Source/WebCore/platform/graphics/android/QueuedOperation.h40
-rw-r--r--Source/WebCore/platform/graphics/android/RasterRenderer.cpp76
-rw-r--r--Source/WebCore/platform/graphics/android/RasterRenderer.h2
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp36
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h12
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.cpp517
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.h177
-rw-r--r--Source/WebCore/platform/graphics/android/SharedTexture.cpp248
-rw-r--r--Source/WebCore/platform/graphics/android/SharedTexture.h118
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollection.cpp218
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollection.h75
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp245
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h (renamed from Source/WebCore/platform/graphics/android/TreeManager.h)41
-rw-r--r--Source/WebCore/platform/graphics/android/TextureInfo.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/TextureInfo.h23
-rw-r--r--Source/WebCore/platform/graphics/android/TextureOwner.h3
-rw-r--r--Source/WebCore/platform/graphics/android/TexturesGenerator.cpp52
-rw-r--r--Source/WebCore/platform/graphics/android/TexturesGenerator.h17
-rw-r--r--Source/WebCore/platform/graphics/android/TilePainter.h28
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp413
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.h141
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.cpp421
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.h82
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp244
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h107
-rw-r--r--Source/WebCore/platform/graphics/android/TilesProfiler.cpp49
-rw-r--r--Source/WebCore/platform/graphics/android/TilesProfiler.h6
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp371
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.h43
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.cpp331
-rw-r--r--Source/WebCore/platform/graphics/android/VerticalTextMap.cpp37
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp240
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.h20
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerManager.cpp187
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerManager.h46
-rw-r--r--Source/WebCore/platform/graphics/android/ZoomManager.cpp201
-rw-r--r--Source/WebCore/platform/graphics/android/ZoomManager.h118
-rw-r--r--Source/WebCore/platform/graphics/android/android_graphics.cpp160
-rw-r--r--Source/WebCore/platform/graphics/android/android_graphics.h44
-rw-r--r--Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp4
-rw-r--r--Source/WebCore/platform/network/android/ResourceLoaderAndroid.h1
-rw-r--r--Source/WebCore/platform/network/android/ResourceRequestAndroid.cpp7
-rw-r--r--Source/WebCore/platform/text/android/HyphenationAndroid.cpp2
-rw-r--r--Source/WebCore/plugins/PluginView.cpp3
-rw-r--r--Source/WebCore/plugins/PluginView.h2
-rw-r--r--Source/WebCore/plugins/android/PluginViewAndroid.cpp7
-rw-r--r--Source/WebCore/rendering/InlineTextBox.cpp5
-rw-r--r--Source/WebCore/rendering/RenderArena.cpp7
-rw-r--r--Source/WebCore/rendering/RenderArena.h4
-rw-r--r--Source/WebCore/rendering/RenderBlockLineLayout.cpp4
-rw-r--r--Source/WebCore/rendering/RenderFrame.cpp16
-rw-r--r--Source/WebCore/rendering/RenderHTMLCanvas.cpp7
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp21
-rw-r--r--Source/WebCore/rendering/RenderLayer.h9
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp132
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.h2
-rw-r--r--Source/WebCore/rendering/RenderText.cpp76
-rw-r--r--Source/WebCore/rendering/RenderText.h4
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.h39
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.cpp34
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.h11
-rw-r--r--Source/WebCore/storage/AbstractDatabase.h4
-rw-r--r--Source/WebCore/storage/DatabaseTask.cpp16
-rw-r--r--Source/WebCore/storage/DatabaseTask.h10
-rw-r--r--Source/WebCore/storage/SQLTransaction.cpp2
-rw-r--r--Source/WebCore/storage/SQLTransaction.h2
-rw-r--r--Source/WebCore/svg/SVGFontFaceUriElement.h16
-rw-r--r--Source/WebCore/workers/WorkerContext.idl1
-rw-r--r--Source/WebCore/xml/XSLImportRule.h16
229 files changed, 8387 insertions, 10067 deletions
diff --git a/Source/WebCore/Android.derived.jscbindings.mk b/Source/WebCore/Android.derived.jscbindings.mk
deleted file mode 100644
index d859b15..0000000
--- a/Source/WebCore/Android.derived.jscbindings.mk
+++ /dev/null
@@ -1,752 +0,0 @@
-
-##
-## Copyright 2009, 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.
-##
-
-# lookup tables for old-style JavaScript bindings
-create_hash_table := $(LOCAL_PATH)/../JavaScriptCore/create_hash_table
-
-GEN := $(addprefix $(intermediates)/, \
- bindings/js/JSDOMWindowBase.lut.h \
- )
-$(GEN): PRIVATE_CUSTOM_TOOL = perl $(create_hash_table) $< > $@
-$(GEN): $(intermediates)/bindings/js/%.lut.h: $(LOCAL_PATH)/bindings/js/%.cpp $(create_hash_table)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-
-GEN := $(intermediates)/bindings/js/JSHTMLInputElementBaseTable.cpp
-$(GEN): PRIVATE_CUSTOM_TOOL = perl $(create_hash_table) $< > $@
-$(GEN): $(intermediates)/bindings/js/%Table.cpp: $(LOCAL_PATH)/bindings/js/%.cpp $(create_hash_table)
- $(transform-generated-source)
-$(intermediates)/bindings/js/JSHTMLInputElementBase.o : $(GEN)
-
-# lookup tables for old-style JavaScript bindings
-js_binding_scripts := $(addprefix $(LOCAL_PATH)/,\
- bindings/scripts/CodeGenerator.pm \
- bindings/scripts/IDLParser.pm \
- bindings/scripts/IDLStructure.pm \
- bindings/scripts/generate-bindings.pl \
- )
-
-FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 ENABLE_DEVICE_ORIENTATION=1 ENABLE_FILE_READER=1 ENABLE_BLOB=1 ENABLE_WEB_TIMING=1
-
-ifeq ($(ENABLE_SVG), true)
- FEATURE_DEFINES += ENABLE_SVG=1
-endif
-
-# CSS
-GEN := \
- $(intermediates)/css/JSCSSCharsetRule.h \
- $(intermediates)/css/JSCSSFontFaceRule.h \
- $(intermediates)/css/JSCSSImportRule.h \
- $(intermediates)/css/JSCSSMediaRule.h \
- $(intermediates)/css/JSCSSPageRule.h \
- $(intermediates)/css/JSCSSPrimitiveValue.h \
- $(intermediates)/css/JSCSSRule.h \
- $(intermediates)/css/JSCSSRuleList.h \
- $(intermediates)/css/JSCSSStyleDeclaration.h \
- $(intermediates)/css/JSCSSStyleRule.h \
- $(intermediates)/css/JSCSSStyleSheet.h \
- $(intermediates)/css/JSCSSValue.h \
- $(intermediates)/css/JSCSSValueList.h \
- $(intermediates)/css/JSCounter.h \
- $(intermediates)/css/JSMediaList.h \
- $(intermediates)/css/JSMediaQueryList.h \
- $(intermediates)/css/JSRGBColor.h \
- $(intermediates)/css/JSRect.h \
- $(intermediates)/css/JSStyleMedia.h \
- $(intermediates)/css/JSStyleSheet.h \
- $(intermediates)/css/JSStyleSheetList.h \
- $(intermediates)/css/JSWebKitCSSKeyframeRule.h \
- $(intermediates)/css/JSWebKitCSSKeyframesRule.h \
- $(intermediates)/css/JSWebKitCSSMatrix.h \
- $(intermediates)/css/JSWebKitCSSTransformValue.h
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/css/JS%.h : $(LOCAL_PATH)/css/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/css/%.cpp : $(intermediates)/css/%.h
-
-# DOM
-GEN := \
- $(intermediates)/dom/JSAttr.h \
- $(intermediates)/dom/JSBeforeLoadEvent.h \
- $(intermediates)/dom/JSCDATASection.h \
- $(intermediates)/dom/JSCharacterData.h \
- $(intermediates)/dom/JSClientRect.h \
- $(intermediates)/dom/JSClientRectList.h \
- $(intermediates)/dom/JSClipboard.h \
- $(intermediates)/dom/JSComment.h \
- $(intermediates)/dom/JSCustomEvent.h \
- $(intermediates)/dom/JSCompositionEvent.h \
- $(intermediates)/dom/JSDOMCoreException.h \
- $(intermediates)/dom/JSDOMImplementation.h \
- $(intermediates)/dom/JSDOMStringList.h \
- $(intermediates)/dom/JSDOMStringMap.h \
- $(intermediates)/dom/JSDataTransferItems.h \
- $(intermediates)/dom/JSDeviceMotionEvent.h \
- $(intermediates)/dom/JSDeviceOrientationEvent.h \
- $(intermediates)/dom/JSDocument.h \
- $(intermediates)/dom/JSDocumentFragment.h \
- $(intermediates)/dom/JSDocumentType.h \
- $(intermediates)/dom/JSElement.h \
- $(intermediates)/dom/JSEntity.h \
- $(intermediates)/dom/JSEntityReference.h \
- $(intermediates)/dom/JSErrorEvent.h \
- $(intermediates)/dom/JSEvent.h \
- $(intermediates)/dom/JSEventException.h \
- $(intermediates)/dom/JSHashChangeEvent.h \
- $(intermediates)/dom/JSKeyboardEvent.h \
- $(intermediates)/dom/JSMessageChannel.h \
- $(intermediates)/dom/JSMessageEvent.h \
- $(intermediates)/dom/JSMessagePort.h \
- $(intermediates)/dom/JSMouseEvent.h \
- $(intermediates)/dom/JSMutationEvent.h \
- $(intermediates)/dom/JSNamedNodeMap.h \
- $(intermediates)/dom/JSNode.h \
- $(intermediates)/dom/JSNodeFilter.h \
- $(intermediates)/dom/JSNodeIterator.h \
- $(intermediates)/dom/JSNodeList.h \
- $(intermediates)/dom/JSNotation.h \
- $(intermediates)/dom/JSOverflowEvent.h \
- $(intermediates)/dom/JSPageTransitionEvent.h \
- $(intermediates)/dom/JSPopStateEvent.h \
- $(intermediates)/dom/JSProcessingInstruction.h \
- $(intermediates)/dom/JSProgressEvent.h \
- $(intermediates)/dom/JSRange.h \
- $(intermediates)/dom/JSRangeException.h \
- $(intermediates)/dom/JSText.h \
- $(intermediates)/dom/JSTextEvent.h \
- $(intermediates)/dom/JSTouch.h \
- $(intermediates)/dom/JSTouchEvent.h \
- $(intermediates)/dom/JSTouchList.h \
- $(intermediates)/dom/JSTreeWalker.h \
- $(intermediates)/dom/JSUIEvent.h \
- $(intermediates)/dom/JSWebKitAnimationEvent.h \
- $(intermediates)/dom/JSWebKitTransitionEvent.h \
- $(intermediates)/dom/JSWheelEvent.h
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/dom/JS%.h : $(LOCAL_PATH)/dom/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/dom/%.cpp : $(intermediates)/dom/%.h
-
-# Fileapi
-GEN := \
- $(intermediates)/fileapi/JSBlob.h \
- $(intermediates)/fileapi/JSDOMFileSystem.h \
- $(intermediates)/fileapi/JSDOMFileSystemSync.h \
- $(intermediates)/fileapi/JSDirectoryEntry.h \
- $(intermediates)/fileapi/JSDirectoryEntrySync.h \
- $(intermediates)/fileapi/JSDirectoryReader.h \
- $(intermediates)/fileapi/JSDirectoryReaderSync.h \
- $(intermediates)/fileapi/JSEntriesCallback.h \
- $(intermediates)/fileapi/JSEntry.h \
- $(intermediates)/fileapi/JSEntryArray.h \
- $(intermediates)/fileapi/JSEntryArraySync.h \
- $(intermediates)/fileapi/JSEntryCallback.h \
- $(intermediates)/fileapi/JSEntrySync.h \
- $(intermediates)/fileapi/JSErrorCallback.h \
- $(intermediates)/fileapi/JSFile.h \
- $(intermediates)/fileapi/JSFileCallback.h \
- $(intermediates)/fileapi/JSFileEntry.h \
- $(intermediates)/fileapi/JSFileEntrySync.h \
- $(intermediates)/fileapi/JSFileError.h \
- $(intermediates)/fileapi/JSFileException.h \
- $(intermediates)/fileapi/JSFileList.h \
- $(intermediates)/fileapi/JSFileReader.h \
- $(intermediates)/fileapi/JSFileReaderSync.h \
- $(intermediates)/fileapi/JSFileSystemCallback.h \
- $(intermediates)/fileapi/JSFileWriter.h \
- $(intermediates)/fileapi/JSFileWriterCallback.h \
- $(intermediates)/fileapi/JSMetadata.h \
- $(intermediates)/fileapi/JSMetadataCallback.h \
- $(intermediates)/fileapi/JSWebKitBlobBuilder.h \
- $(intermediates)/fileapi/JSWebKitFlags.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --include fileapi --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/fileapi/JS%.h : $(LOCAL_PATH)/fileapi/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/fileapi/%.cpp : $(intermediates)/fileapi/%.h
-
-# HTML
-GEN := \
- $(intermediates)/html/JSDOMFormData.h \
- $(intermediates)/html/JSDOMSettableTokenList.h \
- $(intermediates)/html/JSDOMTokenList.h \
- $(intermediates)/html/JSDOMURL.h \
- $(intermediates)/html/JSDataGridColumn.h \
- $(intermediates)/html/JSDataGridColumnList.h \
- $(intermediates)/html/JSHTMLAllCollection.h \
- $(intermediates)/html/JSHTMLAnchorElement.h \
- $(intermediates)/html/JSHTMLAppletElement.h \
- $(intermediates)/html/JSHTMLAreaElement.h \
- $(intermediates)/html/JSHTMLAudioElement.h \
- $(intermediates)/html/JSHTMLBRElement.h \
- $(intermediates)/html/JSHTMLBaseElement.h \
- $(intermediates)/html/JSHTMLBaseFontElement.h \
- $(intermediates)/html/JSHTMLBlockquoteElement.h \
- $(intermediates)/html/JSHTMLBodyElement.h \
- $(intermediates)/html/JSHTMLButtonElement.h \
- $(intermediates)/html/JSHTMLCanvasElement.h \
- $(intermediates)/html/JSHTMLCollection.h \
- $(intermediates)/html/JSHTMLDataGridElement.h \
- $(intermediates)/html/JSHTMLDataGridCellElement.h \
- $(intermediates)/html/JSHTMLDataGridColElement.h \
- $(intermediates)/html/JSHTMLDataGridRowElement.h \
- $(intermediates)/html/JSHTMLDataListElement.h \
- $(intermediates)/html/JSHTMLDetailsElement.h \
- $(intermediates)/html/JSHTMLDListElement.h \
- $(intermediates)/html/JSHTMLDirectoryElement.h \
- $(intermediates)/html/JSHTMLDivElement.h \
- $(intermediates)/html/JSHTMLDocument.h \
- $(intermediates)/html/JSHTMLElement.h \
- $(intermediates)/html/JSHTMLEmbedElement.h \
- $(intermediates)/html/JSHTMLFieldSetElement.h \
- $(intermediates)/html/JSHTMLFontElement.h \
- $(intermediates)/html/JSHTMLFormElement.h \
- $(intermediates)/html/JSHTMLFrameElement.h \
- $(intermediates)/html/JSHTMLFrameSetElement.h \
- $(intermediates)/html/JSHTMLHRElement.h \
- $(intermediates)/html/JSHTMLHeadElement.h \
- $(intermediates)/html/JSHTMLHeadingElement.h \
- $(intermediates)/html/JSHTMLHtmlElement.h \
- $(intermediates)/html/JSHTMLIFrameElement.h \
- $(intermediates)/html/JSHTMLImageElement.h \
- $(intermediates)/html/JSHTMLInputElement.h \
- $(intermediates)/html/JSHTMLIsIndexElement.h \
- $(intermediates)/html/JSHTMLKeygenElement.h \
- $(intermediates)/html/JSHTMLLIElement.h \
- $(intermediates)/html/JSHTMLLabelElement.h \
- $(intermediates)/html/JSHTMLLegendElement.h \
- $(intermediates)/html/JSHTMLLinkElement.h \
- $(intermediates)/html/JSHTMLMapElement.h \
- $(intermediates)/html/JSHTMLMarqueeElement.h \
- $(intermediates)/html/JSHTMLMediaElement.h \
- $(intermediates)/html/JSHTMLMenuElement.h \
- $(intermediates)/html/JSHTMLMetaElement.h \
- $(intermediates)/html/JSHTMLMeterElement.h \
- $(intermediates)/html/JSHTMLModElement.h \
- $(intermediates)/html/JSHTMLOListElement.h \
- $(intermediates)/html/JSHTMLObjectElement.h \
- $(intermediates)/html/JSHTMLOptGroupElement.h \
- $(intermediates)/html/JSHTMLOptionElement.h \
- $(intermediates)/html/JSHTMLOptionsCollection.h \
- $(intermediates)/html/JSHTMLOutputElement.h \
- $(intermediates)/html/JSHTMLParagraphElement.h \
- $(intermediates)/html/JSHTMLParamElement.h \
- $(intermediates)/html/JSHTMLPreElement.h \
- $(intermediates)/html/JSHTMLProgressElement.h \
- $(intermediates)/html/JSHTMLQuoteElement.h \
- $(intermediates)/html/JSHTMLScriptElement.h \
- $(intermediates)/html/JSHTMLSelectElement.h \
- $(intermediates)/html/JSHTMLSourceElement.h \
- $(intermediates)/html/JSHTMLStyleElement.h \
- $(intermediates)/html/JSHTMLTableCaptionElement.h \
- $(intermediates)/html/JSHTMLTableCellElement.h \
- $(intermediates)/html/JSHTMLTableColElement.h \
- $(intermediates)/html/JSHTMLTableElement.h \
- $(intermediates)/html/JSHTMLTableRowElement.h \
- $(intermediates)/html/JSHTMLTableSectionElement.h \
- $(intermediates)/html/JSHTMLTextAreaElement.h \
- $(intermediates)/html/JSHTMLTitleElement.h \
- $(intermediates)/html/JSHTMLUListElement.h \
- $(intermediates)/html/JSHTMLVideoElement.h \
- $(intermediates)/html/JSImageData.h \
- $(intermediates)/html/JSMediaError.h \
- $(intermediates)/html/JSTextMetrics.h \
- $(intermediates)/html/JSTimeRanges.h \
- $(intermediates)/html/JSValidityState.h \
- $(intermediates)/html/JSVoidCallback.h
-
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/html/JS%.h : $(LOCAL_PATH)/html/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/html/%.cpp : $(intermediates)/html/%.h
-
-# Canvas
-GEN := \
- $(intermediates)/html/canvas/JSArrayBuffer.h \
- $(intermediates)/html/canvas/JSArrayBufferView.h \
- $(intermediates)/html/canvas/JSCanvasGradient.h \
- $(intermediates)/html/canvas/JSCanvasPattern.h \
- $(intermediates)/html/canvas/JSCanvasRenderingContext.h \
- $(intermediates)/html/canvas/JSCanvasRenderingContext2D.h \
- $(intermediates)/html/canvas/JSDataView.h \
- $(intermediates)/html/canvas/JSFloat32Array.h \
- $(intermediates)/html/canvas/JSInt8Array.h \
- $(intermediates)/html/canvas/JSInt16Array.h \
- $(intermediates)/html/canvas/JSInt32Array.h \
- $(intermediates)/html/canvas/JSOESTextureFloat.h \
- $(intermediates)/html/canvas/JSOESVertexArrayObject.h \
- $(intermediates)/html/canvas/JSUint8Array.h \
- $(intermediates)/html/canvas/JSUint16Array.h \
- $(intermediates)/html/canvas/JSUint32Array.h \
- $(intermediates)/html/canvas/JSWebGLActiveInfo.h \
- $(intermediates)/html/canvas/JSWebGLBuffer.h \
- $(intermediates)/html/canvas/JSWebGLFramebuffer.h \
- $(intermediates)/html/canvas/JSWebGLProgram.h \
- $(intermediates)/html/canvas/JSWebGLRenderbuffer.h \
- $(intermediates)/html/canvas/JSWebGLRenderingContext.h \
- $(intermediates)/html/canvas/JSWebGLShader.h \
- $(intermediates)/html/canvas/JSWebGLTexture.h \
- $(intermediates)/html/canvas/JSWebGLUniformLocation.h \
- $(intermediates)/html/canvas/JSWebGLVertexArrayObjectOES.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/html/canvas/JS%.h : $(LOCAL_PATH)/html/canvas/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/html/canvas/%.cpp : $(intermediates)/html/canvas/%.h
-
-# Appcache
-GEN := \
- $(intermediates)/loader/appcache/JSDOMApplicationCache.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/loader/appcache/JS%.h : $(LOCAL_PATH)/loader/appcache/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/loader/appcache/%.cpp : $(intermediates)/loader/appcache/%.h
-
-# page
-GEN := \
- $(intermediates)/page/JSBarInfo.h \
- $(intermediates)/page/JSConnection.h \
- $(intermediates)/page/JSConsole.h \
- $(intermediates)/page/JSCoordinates.h \
- $(intermediates)/page/JSCrypto.h \
- $(intermediates)/page/JSDOMSelection.h \
- $(intermediates)/page/JSDOMWindow.h \
- $(intermediates)/page/JSEventSource.h \
- $(intermediates)/page/JSGeolocation.h \
- $(intermediates)/page/JSGeoposition.h \
- $(intermediates)/page/JSHistory.h \
- $(intermediates)/page/JSLocation.h \
- $(intermediates)/page/JSMemoryInfo.h \
- $(intermediates)/page/JSNavigator.h \
- $(intermediates)/page/JSNavigatorUserMediaError.h \
- $(intermediates)/page/JSNavigatorUserMediaErrorCallback.h \
- $(intermediates)/page/JSNavigatorUserMediaSuccessCallback.h \
- $(intermediates)/page/JSPerformance.h \
- $(intermediates)/page/JSPerformanceNavigation.h \
- $(intermediates)/page/JSPerformanceTiming.h \
- $(intermediates)/page/JSPositionError.h \
- $(intermediates)/page/JSScreen.h \
- $(intermediates)/page/JSSpeechInputEvent.h \
- $(intermediates)/page/JSWebKitAnimation.h \
- $(intermediates)/page/JSWebKitAnimationList.h \
- $(intermediates)/page/JSWebKitPoint.h \
- $(intermediates)/page/JSWorkerNavigator.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/page/JS%.h : $(LOCAL_PATH)/page/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/page/%.cpp : $(intermediates)/page/%.h
-
-GEN := \
- $(intermediates)/plugins/JSDOMMimeType.h \
- $(intermediates)/plugins/JSDOMMimeTypeArray.h \
- $(intermediates)/plugins/JSDOMPlugin.h \
- $(intermediates)/plugins/JSDOMPluginArray.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/plugins/JS%.h : $(LOCAL_PATH)/plugins/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/plugins/%.cpp : $(intermediates)/plugins/%.h
-
-# Database
-GEN := \
- $(intermediates)/storage/JSDatabase.h \
- $(intermediates)/storage/JSDatabaseCallback.h \
- $(intermediates)/storage/JSDatabaseSync.h \
- $(intermediates)/storage/JSSQLError.h \
- $(intermediates)/storage/JSSQLException.h \
- $(intermediates)/storage/JSSQLResultSet.h \
- $(intermediates)/storage/JSSQLResultSetRowList.h \
- $(intermediates)/storage/JSSQLStatementCallback.h \
- $(intermediates)/storage/JSSQLStatementErrorCallback.h \
- $(intermediates)/storage/JSSQLTransaction.h \
- $(intermediates)/storage/JSSQLTransactionCallback.h \
- $(intermediates)/storage/JSSQLTransactionSync.h \
- $(intermediates)/storage/JSSQLTransactionSyncCallback.h \
- $(intermediates)/storage/JSSQLTransactionErrorCallback.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --include storage --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/storage/JS%.h : $(LOCAL_PATH)/storage/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/storage/%.cpp : $(intermediates)/storage/%.h
-
-# DOM Storage
-GEN := \
- $(intermediates)/storage/JSStorage.h \
- $(intermediates)/storage/JSStorageEvent.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/storage/JS%.h : $(LOCAL_PATH)/storage/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/storage/%.cpp : $(intermediates)/storage/%.h
-
-# Indexed Database
-GEN := \
- $(intermediates)/storage/JSIDBAny.h \
- $(intermediates)/storage/JSIDBCursor.h \
- $(intermediates)/storage/JSIDBCursorWithValue.h \
- $(intermediates)/storage/JSIDBDatabaseError.h \
- $(intermediates)/storage/JSIDBDatabaseException.h \
- $(intermediates)/storage/JSIDBDatabase.h \
- $(intermediates)/storage/JSIDBFactory.h \
- $(intermediates)/storage/JSIDBIndex.h \
- $(intermediates)/storage/JSIDBKey.h \
- $(intermediates)/storage/JSIDBKeyRange.h \
- $(intermediates)/storage/JSIDBObjectStore.h \
- $(intermediates)/storage/JSIDBRequest.h \
- $(intermediates)/storage/JSIDBTransaction.h \
- $(intermediates)/storage/JSIDBVersionChangeEvent.h \
- $(intermediates)/storage/JSIDBVersionChangeRequest.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --include storage --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/storage/JS%.h : $(LOCAL_PATH)/storage/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/storage/%.cpp : $(intermediates)/storage/%.h
-
-# SVG
-ifeq ($(ENABLE_SVG), true)
-GEN := \
- $(intermediates)/svg/JSSVGAElement.h \
- $(intermediates)/svg/JSSVGAltGlyphElement.h \
- $(intermediates)/svg/JSSVGAngle.h \
- $(intermediates)/svg/JSSVGAnimateColorElement.h \
- $(intermediates)/svg/JSSVGAnimateElement.h \
- $(intermediates)/svg/JSSVGAnimateTransformElement.h \
- $(intermediates)/svg/JSSVGAnimatedAngle.h \
- $(intermediates)/svg/JSSVGAnimatedBoolean.h \
- $(intermediates)/svg/JSSVGAnimatedEnumeration.h \
- $(intermediates)/svg/JSSVGAnimatedInteger.h \
- $(intermediates)/svg/JSSVGAnimatedLength.h \
- $(intermediates)/svg/JSSVGAnimatedLengthList.h \
- $(intermediates)/svg/JSSVGAnimatedNumber.h \
- $(intermediates)/svg/JSSVGAnimatedNumberList.h \
- $(intermediates)/svg/JSSVGAnimatedPreserveAspectRatio.h \
- $(intermediates)/svg/JSSVGAnimatedRect.h \
- $(intermediates)/svg/JSSVGAnimatedString.h \
- $(intermediates)/svg/JSSVGAnimatedTransformList.h \
- $(intermediates)/svg/JSSVGAnimationElement.h \
- $(intermediates)/svg/JSSVGCircleElement.h \
- $(intermediates)/svg/JSSVGClipPathElement.h \
- $(intermediates)/svg/JSSVGColor.h \
- $(intermediates)/svg/JSSVGComponentTransferFunctionElement.h \
- $(intermediates)/svg/JSSVGCursorElement.h \
- $(intermediates)/svg/JSSVGDefsElement.h \
- $(intermediates)/svg/JSSVGDescElement.h \
- $(intermediates)/svg/JSSVGDocument.h \
- $(intermediates)/svg/JSSVGElement.h \
- $(intermediates)/svg/JSSVGElementInstance.h \
- $(intermediates)/svg/JSSVGElementInstanceList.h \
- $(intermediates)/svg/JSSVGEllipseElement.h \
- $(intermediates)/svg/JSSVGException.h \
- $(intermediates)/svg/JSSVGFEBlendElement.h \
- $(intermediates)/svg/JSSVGFEColorMatrixElement.h \
- $(intermediates)/svg/JSSVGFEComponentTransferElement.h \
- $(intermediates)/svg/JSSVGFECompositeElement.h \
- $(intermediates)/svg/JSSVGFEConvolveMatrixElement.h \
- $(intermediates)/svg/JSSVGFEDiffuseLightingElement.h \
- $(intermediates)/svg/JSSVGFEDisplacementMapElement.h \
- $(intermediates)/svg/JSSVGFEDistantLightElement.h \
- $(intermediates)/svg/JSSVGFEFloodElement.h \
- $(intermediates)/svg/JSSVGFEFuncAElement.h \
- $(intermediates)/svg/JSSVGFEFuncBElement.h \
- $(intermediates)/svg/JSSVGFEFuncGElement.h \
- $(intermediates)/svg/JSSVGFEFuncRElement.h \
- $(intermediates)/svg/JSSVGFEGaussianBlurElement.h \
- $(intermediates)/svg/JSSVGFEImageElement.h \
- $(intermediates)/svg/JSSVGFEMergeElement.h \
- $(intermediates)/svg/JSSVGFEMergeNodeElement.h \
- $(intermediates)/svg/JSSVGFEOffsetElement.h \
- $(intermediates)/svg/JSSVGFEPointLightElement.h \
- $(intermediates)/svg/JSSVGFESpecularLightingElement.h \
- $(intermediates)/svg/JSSVGFESpotLightElement.h \
- $(intermediates)/svg/JSSVGFETileElement.h \
- $(intermediates)/svg/JSSVGFETurbulenceElement.h \
- $(intermediates)/svg/JSSVGFilterElement.h \
- $(intermediates)/svg/JSSVGFontElement.h \
- $(intermediates)/svg/JSSVGFontFaceElement.h \
- $(intermediates)/svg/JSSVGFontFaceFormatElement.h \
- $(intermediates)/svg/JSSVGFontFaceNameElement.h \
- $(intermediates)/svg/JSSVGFontFaceSrcElement.h \
- $(intermediates)/svg/JSSVGFontFaceUriElement.h \
- $(intermediates)/svg/JSSVGForeignObjectElement.h \
- $(intermediates)/svg/JSSVGGElement.h \
- $(intermediates)/svg/JSSVGGlyphElement.h \
- $(intermediates)/svg/JSSVGGradientElement.h \
- $(intermediates)/svg/JSSVGHKernElement.h \
- $(intermediates)/svg/JSSVGImageElement.h \
- $(intermediates)/svg/JSSVGLength.h \
- $(intermediates)/svg/JSSVGLengthList.h \
- $(intermediates)/svg/JSSVGLineElement.h \
- $(intermediates)/svg/JSSVGLinearGradientElement.h \
- $(intermediates)/svg/JSSVGMarkerElement.h \
- $(intermediates)/svg/JSSVGMaskElement.h \
- $(intermediates)/svg/JSSVGMatrix.h \
- $(intermediates)/svg/JSSVGMetadataElement.h \
- $(intermediates)/svg/JSSVGMissingGlyphElement.h \
- $(intermediates)/svg/JSSVGNumber.h \
- $(intermediates)/svg/JSSVGNumberList.h \
- $(intermediates)/svg/JSSVGPaint.h \
- $(intermediates)/svg/JSSVGPathElement.h \
- $(intermediates)/svg/JSSVGPathSeg.h \
- $(intermediates)/svg/JSSVGPathSegArcAbs.h \
- $(intermediates)/svg/JSSVGPathSegArcRel.h \
- $(intermediates)/svg/JSSVGPathSegClosePath.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoCubicAbs.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoCubicRel.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoCubicSmoothAbs.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoCubicSmoothRel.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoQuadraticAbs.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoQuadraticRel.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoQuadraticSmoothAbs.h \
- $(intermediates)/svg/JSSVGPathSegCurvetoQuadraticSmoothRel.h \
- $(intermediates)/svg/JSSVGPathSegLinetoAbs.h \
- $(intermediates)/svg/JSSVGPathSegLinetoHorizontalAbs.h \
- $(intermediates)/svg/JSSVGPathSegLinetoHorizontalRel.h \
- $(intermediates)/svg/JSSVGPathSegLinetoRel.h \
- $(intermediates)/svg/JSSVGPathSegLinetoVerticalAbs.h \
- $(intermediates)/svg/JSSVGPathSegLinetoVerticalRel.h \
- $(intermediates)/svg/JSSVGPathSegList.h \
- $(intermediates)/svg/JSSVGPathSegMovetoAbs.h \
- $(intermediates)/svg/JSSVGPathSegMovetoRel.h \
- $(intermediates)/svg/JSSVGPatternElement.h \
- $(intermediates)/svg/JSSVGPoint.h \
- $(intermediates)/svg/JSSVGPointList.h \
- $(intermediates)/svg/JSSVGPolygonElement.h \
- $(intermediates)/svg/JSSVGPolylineElement.h \
- $(intermediates)/svg/JSSVGPreserveAspectRatio.h \
- $(intermediates)/svg/JSSVGRadialGradientElement.h \
- $(intermediates)/svg/JSSVGRect.h \
- $(intermediates)/svg/JSSVGRectElement.h \
- $(intermediates)/svg/JSSVGRenderingIntent.h \
- $(intermediates)/svg/JSSVGSVGElement.h \
- $(intermediates)/svg/JSSVGScriptElement.h \
- $(intermediates)/svg/JSSVGSetElement.h \
- $(intermediates)/svg/JSSVGStopElement.h \
- $(intermediates)/svg/JSSVGStringList.h \
- $(intermediates)/svg/JSSVGStyleElement.h \
- $(intermediates)/svg/JSSVGSwitchElement.h \
- $(intermediates)/svg/JSSVGSymbolElement.h \
- $(intermediates)/svg/JSSVGTRefElement.h \
- $(intermediates)/svg/JSSVGTSpanElement.h \
- $(intermediates)/svg/JSSVGTextContentElement.h \
- $(intermediates)/svg/JSSVGTextElement.h \
- $(intermediates)/svg/JSSVGTextPathElement.h \
- $(intermediates)/svg/JSSVGTextPositioningElement.h \
- $(intermediates)/svg/JSSVGTitleElement.h \
- $(intermediates)/svg/JSSVGTransform.h \
- $(intermediates)/svg/JSSVGTransformList.h \
- $(intermediates)/svg/JSSVGUnitTypes.h \
- $(intermediates)/svg/JSSVGUseElement.h \
- $(intermediates)/svg/JSSVGViewElement.h \
- $(intermediates)/svg/JSSVGVKernElement.h \
- $(intermediates)/svg/JSSVGZoomEvent.h
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include external/webkit/Source/WebCore/dom --include external/webkit/Source/WebCore/html --include external/webkit/Source/WebCore/svg --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/svg/JS%.h : $(LOCAL_PATH)/svg/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/svg/%.cpp : $(intermediates)/svg/%.h
-endif
-
-# Workers
-GEN := \
- $(intermediates)/workers/JSAbstractWorker.h \
- $(intermediates)/workers/JSDedicatedWorkerContext.h \
- $(intermediates)/workers/JSSharedWorker.h \
- $(intermediates)/workers/JSSharedWorkerContext.h \
- $(intermediates)/workers/JSWorker.h \
- $(intermediates)/workers/JSWorkerContext.h \
- $(intermediates)/workers/JSWorkerLocation.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/workers/JS%.h : $(LOCAL_PATH)/workers/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/workers/%.cpp : $(intermediates)/workers/%.h
-
-# XML
-GEN := \
- $(intermediates)/xml/JSDOMParser.h \
- $(intermediates)/xml/JSXMLHttpRequest.h \
- $(intermediates)/xml/JSXMLHttpRequestException.h \
- $(intermediates)/xml/JSXMLHttpRequestProgressEvent.h \
- $(intermediates)/xml/JSXMLHttpRequestUpload.h \
- $(intermediates)/xml/JSXMLSerializer.h \
- $(intermediates)/xml/JSXPathException.h \
- $(intermediates)/xml/JSXPathExpression.h \
- $(intermediates)/xml/JSXPathEvaluator.h \
- $(intermediates)/xml/JSXPathNSResolver.h \
- $(intermediates)/xml/JSXPathResult.h \
- $(intermediates)/xml/JSXSLTProcessor.h
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/xml/JS%.h : $(LOCAL_PATH)/xml/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/xml/%.cpp : $(intermediates)/xml/%.h
-#end
-
-# Inspector
-# These headers are required even when Inspector is disabled.
-# Note that Inspector.idl should not be processed using the JS generator.
-GEN := \
- $(intermediates)/inspector/JSScriptProfile.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/inspector/JS%.h : $(LOCAL_PATH)/inspector/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/inspector/%.cpp : $(intermediates)/inspector/%.h
-
-# WebAudio
-# These headers are required even when WebAudio is disabled
-GEN := \
- $(intermediates)/webaudio/JSAudioContext.h \
- $(intermediates)/webaudio/JSAudioPannerNode.h
-
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
-$(GEN): $(intermediates)/webaudio/JS%.h : $(LOCAL_PATH)/webaudio/%.idl $(js_binding_scripts)
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
-
-# We also need the .cpp files, which are generated as side effects of the
-# above rules. Specifying this explicitly makes -j2 work.
-$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/webaudio/%.cpp : $(intermediates)/webaudio/%.h
-
-# HTML tag and attribute names
-
-GEN:= $(intermediates)/HTMLNames.cpp $(intermediates)/HTMLNames.h $(intermediates)/HTMLElementFactory.cpp $(intermediates)/HTMLElementFactory.h $(intermediates)/JSHTMLElementWrapperFactory.cpp $(intermediates)/JSHTMLElementWrapperFactory.h
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(PRIVATE_PATH)/html/HTMLTagNames.in --attrs $(PRIVATE_PATH)/html/HTMLAttributeNames.in --extraDefines "$(FEATURE_DEFINES)" --factory --wrapperFactory --output $(dir $@)
-$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(LOCAL_PATH)/html/HTMLTagNames.in $(LOCAL_PATH)/html/HTMLAttributeNames.in
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-# SVG tag and attribute names
-
-# Note that if SVG is not used, we still need the headers and SVGNames.cpp as
-# the HTML5 parser still requires these. The factory .cpp files are also
-# generated in this case, but since these are not needed, they are excluded
-# from GEN so that they don't get compiled.
-ifeq ($(ENABLE_SVG), true)
-GEN:= $(intermediates)/SVGNames.cpp $(intermediates)/SVGNames.h $(intermediates)/SVGElementFactory.cpp $(intermediates)/SVGElementFactory.h $(intermediates)/JSSVGElementWrapperFactory.cpp $(intermediates)/JSSVGElementWrapperFactory.h
-else
-GEN:= $(intermediates)/SVGNames.h $(intermediates)/SVGNames.cpp $(intermediates)/SVGElementFactory.h $(intermediates)/JSSVGElementWrapperFactory.h
-endif
-SVG_FLAGS:=ENABLE_SVG_ANIMATION=1 ENABLE_SVG_AS_IMAGE=1 ENABLE_SVG_FILTERS=1 ENABLE_SVG_FONTS=1 ENABLE_SVG_FOREIGN_OBJECT=1 ENABLE_SVG_USE=1
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(PRIVATE_PATH)/svg/svgtags.in --attrs $(PRIVATE_PATH)/svg/svgattrs.in --extraDefines "$(SVG_FLAGS)" --factory --wrapperFactory --output $(dir $@)
-$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(LOCAL_PATH)/svg/svgtags.in $(LOCAL_PATH)/svg/svgattrs.in
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-# MathML tag and attribute names
-
-# Note that MathML is never used but we still need the headers and
-# MathMLames.cpp as the HTML5 parser still requires these. The factory
-# .cpp files are also generated in this case, but since these are not
-# needed, they are excluded from GEN so that they don't get compiled.
-GEN:= $(intermediates)/MathMLNames.h $(intermediates)/MathMLNames.cpp $(intermediates)/MathMLElementFactory.h $(intermediates)/JSMathMLElementWrapperFactory.h
-$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(PRIVATE_PATH)/mathml/mathtags.in --attrs $(PRIVATE_PATH)/mathml/mathattrs.in --factory --wrapperFactory --output $(dir $@)
-$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(LOCAL_PATH)/mathml/mathtags.in $(LOCAL_PATH)/mathml/mathattrs.in
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
diff --git a/Source/WebCore/Android.derived.v8bindings.mk b/Source/WebCore/Android.derived.v8bindings.mk
index 992cc40..546cefe 100644
--- a/Source/WebCore/Android.derived.v8bindings.mk
+++ b/Source/WebCore/Android.derived.v8bindings.mk
@@ -301,6 +301,7 @@ GEN := \
$(intermediates)/bindings/V8CanvasRenderingContext2D.h \
$(intermediates)/bindings/V8DataView.h \
$(intermediates)/bindings/V8Float32Array.h \
+ $(intermediates)/bindings/V8Float64Array.h \
$(intermediates)/bindings/V8Int8Array.h \
$(intermediates)/bindings/V8Int16Array.h \
$(intermediates)/bindings/V8Int32Array.h \
diff --git a/Source/WebCore/Android.jscbindings.mk b/Source/WebCore/Android.jscbindings.mk
deleted file mode 100644
index bdd6d92..0000000
--- a/Source/WebCore/Android.jscbindings.mk
+++ /dev/null
@@ -1,240 +0,0 @@
-##
-## Copyright 2009, 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.
-##
-
-BINDING_C_INCLUDES := \
- $(LOCAL_PATH)/bindings/js \
- $(LOCAL_PATH)/bindings/js/specialization \
- $(LOCAL_PATH)/bridge \
- $(LOCAL_PATH)/bridge/c \
- $(LOCAL_PATH)/bridge/jni \
- $(LOCAL_PATH)/bridge/jni/jsc \
- $(LOCAL_PATH)/bridge/jsc \
- \
- $(JAVASCRIPTCORE_PATH)/API \
- $(JAVASCRIPTCORE_PATH)/assembler \
- $(JAVASCRIPTCORE_PATH)/bytecode \
- $(JAVASCRIPTCORE_PATH)/bytecompiler \
- $(JAVASCRIPTCORE_PATH)/debugger \
- $(JAVASCRIPTCORE_PATH)/parser \
- $(JAVASCRIPTCORE_PATH)/jit \
- $(JAVASCRIPTCORE_PATH)/interpreter \
- $(JAVASCRIPTCORE_PATH)/profiler \
- $(JAVASCRIPTCORE_PATH)/runtime \
- $(JAVASCRIPTCORE_PATH)/yarr \
- $(JAVASCRIPTCORE_PATH)/ForwardingHeaders \
- \
- $(WEBCORE_INTERMEDIATES_PATH)/bindings/js \
- $(WEBCORE_INTERMEDIATES_PATH)/dom \
- $(WEBCORE_INTERMEDIATES_PATH)/fileapi \
- $(WEBCORE_INTERMEDIATES_PATH)/html/canvas \
- $(WEBCORE_INTERMEDIATES_PATH)/inspector \
- $(WEBCORE_INTERMEDIATES_PATH)/loader/appcache \
- $(WEBCORE_INTERMEDIATES_PATH)/page \
- $(WEBCORE_INTERMEDIATES_PATH)/plugins \
- $(WEBCORE_INTERMEDIATES_PATH)/storage \
- $(WEBCORE_INTERMEDIATES_PATH)/svg \
- $(WEBCORE_INTERMEDIATES_PATH)/webaudio \
- $(WEBCORE_INTERMEDIATES_PATH)/workers \
- $(WEBCORE_INTERMEDIATES_PATH)/xml
-
-LOCAL_SRC_FILES += \
- bindings/js/CallbackFunction.cpp \
- bindings/js/DOMObjectHashTableMap.cpp \
- bindings/js/DOMWrapperWorld.cpp \
- bindings/js/GCController.cpp \
- bindings/js/IDBBindingUtilities.cpp \
- bindings/js/JSArrayBufferCustom.cpp \
- bindings/js/JSAttrCustom.cpp \
- bindings/js/JSAudioBufferSourceNodeCustom.cpp \
- bindings/js/JSAudioConstructor.cpp \
- bindings/js/JSCDATASectionCustom.cpp \
- bindings/js/JSCSSFontFaceRuleCustom.cpp \
- bindings/js/JSCSSImportRuleCustom.cpp \
- bindings/js/JSCSSMediaRuleCustom.cpp \
- bindings/js/JSCSSPageRuleCustom.cpp \
- bindings/js/JSCSSRuleCustom.cpp \
- bindings/js/JSCSSRuleListCustom.cpp \
- bindings/js/JSCSSStyleDeclarationCustom.cpp \
- bindings/js/JSCSSStyleRuleCustom.cpp \
- bindings/js/JSCSSValueCustom.cpp \
- bindings/js/JSCallbackData.cpp \
- bindings/js/JSCanvasRenderingContext2DCustom.cpp \
- bindings/js/JSCanvasRenderingContextCustom.cpp \
- bindings/js/JSClipboardCustom.cpp \
- bindings/js/JSConsoleCustom.cpp \
- bindings/js/JSConvolverNodeCustom.cpp \
- bindings/js/JSCoordinatesCustom.cpp \
- bindings/js/JSCustomApplicationInstalledCallback.cpp \
- bindings/js/JSCustomPositionCallback.cpp \
- bindings/js/JSCustomPositionErrorCallback.cpp \
- bindings/js/JSCustomSQLStatementErrorCallback.cpp \
- bindings/js/JSCustomVoidCallback.cpp \
- bindings/js/JSDOMApplicationCacheCustom.cpp \
- bindings/js/JSDOMBinding.cpp \
- bindings/js/JSDOMFormDataCustom.cpp \
- bindings/js/JSDOMGlobalObject.cpp \
- bindings/js/JSDOMImplementationCustom.cpp \
- bindings/js/JSDOMMimeTypeArrayCustom.cpp \
- bindings/js/JSDOMPluginArrayCustom.cpp \
- bindings/js/JSDOMPluginCustom.cpp \
- bindings/js/JSDOMStringMapCustom.cpp \
- bindings/js/JSDOMWindowBase.cpp \
- bindings/js/JSDOMWindowCustom.cpp \
- bindings/js/JSDOMWindowShell.cpp \
- bindings/js/JSDOMWrapper.cpp \
- bindings/js/JSDataGridColumnListCustom.cpp \
- bindings/js/JSDataGridDataSource.cpp \
- bindings/js/JSDataViewCustom.cpp \
- bindings/js/JSDedicatedWorkerContextCustom.cpp \
- bindings/js/JSDesktopNotificationsCustom.cpp \
- bindings/js/JSDeviceMotionEventCustom.cpp \
- bindings/js/JSDeviceOrientationEventCustom.cpp \
- bindings/js/JSDirectoryEntrySyncCustom.cpp \
- bindings/js/JSDocumentCustom.cpp \
- bindings/js/JSElementCustom.cpp \
- bindings/js/JSEntrySyncCustom.cpp \
- bindings/js/JSErrorHandler.cpp \
- bindings/js/JSEventCustom.cpp \
- bindings/js/JSEventListener.cpp \
- bindings/js/JSEventTarget.cpp \
- bindings/js/JSExceptionBase.cpp \
- bindings/js/JSFloat32ArrayCustom.cpp \
- bindings/js/JSFileReaderCustom.cpp \
- bindings/js/JSGeolocationCustom.cpp \
- bindings/js/JSHTMLAllCollectionCustom.cpp \
- bindings/js/JSHTMLAppletElementCustom.cpp \
- bindings/js/JSHTMLCanvasElementCustom.cpp \
- bindings/js/JSHTMLCollectionCustom.cpp \
- bindings/js/JSHTMLDataGridElementCustom.cpp \
- bindings/js/JSHTMLDocumentCustom.cpp \
- bindings/js/JSHTMLElementCustom.cpp \
- bindings/js/JSHTMLEmbedElementCustom.cpp \
- bindings/js/JSHTMLFormElementCustom.cpp \
- bindings/js/JSHTMLFrameElementCustom.cpp \
- bindings/js/JSHTMLFrameSetElementCustom.cpp \
- bindings/js/JSHTMLInputElementCustom.cpp \
- bindings/js/JSHTMLLinkElementCustom.cpp \
- bindings/js/JSHTMLObjectElementCustom.cpp \
- bindings/js/JSHTMLOptionsCollectionCustom.cpp \
- bindings/js/JSHTMLOutputElementCustom.cpp \
- bindings/js/JSHTMLSelectElementCustom.cpp \
- bindings/js/JSHTMLStyleElementCustom.cpp \
- bindings/js/JSHistoryCustom.cpp \
- bindings/js/JSIDBAnyCustom.cpp \
- bindings/js/JSIDBKeyCustom.cpp \
- bindings/js/JSImageConstructor.cpp \
- bindings/js/JSImageDataCustom.cpp \
- bindings/js/JSInt16ArrayCustom.cpp \
- bindings/js/JSInt32ArrayCustom.cpp \
- bindings/js/JSInt8ArrayCustom.cpp \
- bindings/js/JSJavaScriptAudioNodeCustom.cpp \
- bindings/js/JSLazyEventListener.cpp \
- bindings/js/JSLocationCustom.cpp \
- bindings/js/JSMainThreadExecState.cpp \
- bindings/js/JSMemoryInfoCustom.cpp \
- bindings/js/JSMessageChannelCustom.cpp \
- bindings/js/JSMessageEventCustom.cpp \
- bindings/js/JSMessagePortCustom.cpp \
- bindings/js/JSNamedNodeMapCustom.cpp \
- bindings/js/JSNavigatorCustom.cpp \
- bindings/js/JSNodeCustom.cpp \
- bindings/js/JSNodeFilterCondition.cpp \
- bindings/js/JSNodeFilterCustom.cpp \
- bindings/js/JSNodeIteratorCustom.cpp \
- bindings/js/JSNodeListCustom.cpp \
- bindings/js/JSOptionConstructor.cpp \
- bindings/js/JSPluginElementFunctions.cpp \
- bindings/js/JSProcessingInstructionCustom.cpp \
- bindings/js/JSSQLResultSetRowListCustom.cpp \
- bindings/js/JSSQLTransactionCustom.cpp \
- bindings/js/JSSQLTransactionSyncCustom.cpp \
- bindings/js/JSSVGElementInstanceCustom.cpp \
- bindings/js/JSSVGLengthCustom.cpp \
- bindings/js/JSSVGPathSegCustom.cpp \
- bindings/js/JSSharedWorkerCustom.cpp \
- bindings/js/JSStorageCustom.cpp \
- bindings/js/JSStyleSheetCustom.cpp \
- bindings/js/JSStyleSheetListCustom.cpp \
- bindings/js/JSTextCustom.cpp \
- bindings/js/JSTouchCustom.cpp \
- bindings/js/JSTouchListCustom.cpp \
- bindings/js/JSTreeWalkerCustom.cpp \
- bindings/js/JSUint16ArrayCustom.cpp \
- bindings/js/JSUint32ArrayCustom.cpp \
- bindings/js/JSUint8ArrayCustom.cpp \
- bindings/js/JSWebKitAnimationCustom.cpp \
- bindings/js/JSWebKitAnimationListCustom.cpp \
- bindings/js/JSWebKitCSSKeyframeRuleCustom.cpp \
- bindings/js/JSWebKitCSSKeyframesRuleCustom.cpp \
- bindings/js/JSWebKitCSSMatrixCustom.cpp \
- bindings/js/JSWebKitPointCustom.cpp \
- bindings/js/JSWorkerContextBase.cpp \
- bindings/js/JSWorkerContextCustom.cpp \
- bindings/js/JSWorkerCustom.cpp \
- bindings/js/JSXMLHttpRequestCustom.cpp \
- bindings/js/JSXMLHttpRequestUploadCustom.cpp \
- bindings/js/JSXSLTProcessorCustom.cpp \
- bindings/js/ScheduledAction.cpp \
- bindings/js/ScriptCachedFrameData.cpp \
- bindings/js/ScriptCallStackFactory.cpp \
- bindings/js/ScriptController.cpp \
- bindings/js/ScriptControllerAndroid.cpp \
- bindings/js/ScriptEventListener.cpp \
- bindings/js/ScriptFunctionCall.cpp \
- bindings/js/ScriptObject.cpp \
- bindings/js/ScriptProfile.cpp \
- bindings/js/ScriptState.cpp \
- bindings/js/ScriptValue.cpp \
- bindings/js/SerializedScriptValue.cpp \
- bindings/js/WorkerScriptController.cpp \
- \
- bindings/ScriptControllerBase.cpp \
- \
- bridge/IdentifierRep.cpp \
- bridge/NP_jsobject.cpp \
- bridge/c/CRuntimeObject.cpp \
- bridge/c/c_class.cpp \
- bridge/c/c_instance.cpp \
- bridge/c/c_runtime.cpp \
- bridge/c/c_utility.cpp \
- bridge/jni/JNIUtility.cpp \
- bridge/jni/JavaMethodJobject.cpp \
- bridge/jni/JobjectWrapper.cpp \
- bridge/jni/jsc/JNIUtilityPrivate.cpp \
- bridge/jni/jsc/JavaArrayJSC.cpp \
- bridge/jni/jsc/JavaClassJSC.cpp \
- bridge/jni/jsc/JavaFieldJSC.cpp \
- bridge/jni/jsc/JavaInstanceJSC.cpp \
- bridge/jni/jsc/JavaRuntimeObject.cpp \
- bridge/jsc/BridgeJSC.cpp \
- bridge/npruntime.cpp \
- bridge/runtime_array.cpp \
- bridge/runtime_method.cpp \
- bridge/runtime_object.cpp \
- bridge/runtime_root.cpp
-
-# For XPath.
-LOCAL_SRC_FILES += \
- bindings/js/JSCustomXPathNSResolver.cpp
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index 6542931..6ddf965 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -124,6 +124,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
dom/DOMImplementation.cpp \
dom/DOMStringList.cpp \
dom/DOMStringMap.cpp \
+ dom/DOMTextContentWalker.cpp \
dom/DatasetDOMStringMap.cpp \
dom/DecodedDataDocumentParser.cpp \
dom/DeviceMotionController.cpp \
@@ -378,6 +379,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/canvas/CanvasStyle.cpp \
html/canvas/DataView.cpp \
html/canvas/Float32Array.cpp \
+ html/canvas/Float64Array.cpp \
html/canvas/Int16Array.cpp \
html/canvas/Int32Array.cpp \
html/canvas/Int8Array.cpp \
@@ -637,8 +639,11 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/BaseTile.cpp \
platform/graphics/android/BaseTileTexture.cpp \
platform/graphics/android/BitmapAllocatorAndroid.cpp \
+ platform/graphics/android/CanvasLayer.cpp \
+ platform/graphics/android/CanvasTexture.cpp \
platform/graphics/android/ClassTracker.cpp \
- platform/graphics/android/DoubleBufferedTexture.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 \
@@ -653,39 +658,40 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
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/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/PaintedSurface.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/SharedTexture.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/TreeManager.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/android_graphics.cpp \
ifeq ($(ENABLE_SVG), true)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
@@ -811,6 +817,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
plugins/DOMPluginArray.cpp \
plugins/PluginData.cpp \
plugins/PluginDatabase.cpp \
+ plugins/PluginDebug.cpp \
plugins/PluginMainThreadScheduler.cpp \
plugins/PluginPackage.cpp \
plugins/PluginStream.cpp \
diff --git a/Source/WebCore/Android.v8bindings.mk b/Source/WebCore/Android.v8bindings.mk
index 283a212..7858ef3 100644
--- a/Source/WebCore/Android.v8bindings.mk
+++ b/Source/WebCore/Android.v8bindings.mk
@@ -130,6 +130,7 @@ LOCAL_SRC_FILES += \
bindings/v8/custom/V8EventSourceConstructor.cpp \
bindings/v8/custom/V8FileReaderCustom.cpp \
bindings/v8/custom/V8Float32ArrayCustom.cpp \
+ bindings/v8/custom/V8Float64ArrayCustom.cpp \
bindings/v8/custom/V8GeolocationCustom.cpp \
bindings/v8/custom/V8HistoryCustom.cpp \
bindings/v8/custom/V8HTMLAllCollectionCustom.cpp \
diff --git a/Source/WebCore/DerivedSources.cpp b/Source/WebCore/DerivedSources.cpp
index 3bba78c..45a425c 100644
--- a/Source/WebCore/DerivedSources.cpp
+++ b/Source/WebCore/DerivedSources.cpp
@@ -130,6 +130,7 @@
#include "JSFileWriterSync.cpp"
#include "JSWebKitFlags.cpp"
#include "JSFloat32Array.cpp"
+#include "JSFloat64Array.cpp"
#include "JSGeolocation.cpp"
#include "JSGeoposition.cpp"
#include "JSHashChangeEvent.cpp"
diff --git a/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp b/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
index a457ce8..82367b2 100644
--- a/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
+++ b/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
@@ -81,6 +81,7 @@
#include "JSEventTarget.cpp"
#include "JSExceptionBase.cpp"
#include "JSFloat32ArrayCustom.cpp"
+#include "JSFloat64ArrayCustom.cpp"
#include "JSGeolocationCustom.cpp"
#include "JSHTMLAllCollectionCustom.cpp"
#include "JSHTMLAppletElementCustom.cpp"
diff --git a/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp b/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
index 4bde9e5..938be96 100644
--- a/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -31,6 +31,7 @@
#include "JSEventListener.h"
#include "JSEventSource.h"
#include "JSFloat32Array.h"
+#include "JSFloat64Array.h"
#include "JSHTMLCollection.h"
#include "JSHistory.h"
#include "JSImageConstructor.h"
@@ -569,6 +570,11 @@ JSValue JSDOMWindow::float32Array(ExecState* exec) const
return getDOMConstructor<JSFloat32ArrayConstructor>(exec, this);
}
+JSValue JSDOMWindow::float64Array(ExecState* exec) const
+{
+ return getDOMConstructor<JSFloat64ArrayConstructor>(exec, this);
+}
+
JSValue JSDOMWindow::dataView(ExecState* exec) const
{
return getDOMConstructor<JSDataViewConstructor>(exec, this);
diff --git a/Source/WebCore/bindings/js/JSFloat64ArrayCustom.cpp b/Source/WebCore/bindings/js/JSFloat64ArrayCustom.cpp
new file mode 100644
index 0000000..446b0ec
--- /dev/null
+++ b/Source/WebCore/bindings/js/JSFloat64ArrayCustom.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * 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 "JSFloat64Array.h"
+
+#include "Float64Array.h"
+#include "JSArrayBufferViewHelper.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSFloat64Array::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value)
+{
+ impl()->set(index, value.toNumber(exec));
+}
+
+JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, Float64Array* object)
+{
+ return toJSArrayBufferView<JSFloat64Array>(exec, globalObject, object);
+}
+
+JSC::JSValue JSFloat64Array::set(JSC::ExecState* exec)
+{
+ return setWebGLArrayHelper(exec, impl(), toFloat64Array);
+}
+
+EncodedJSValue JSC_HOST_CALL JSFloat64ArrayConstructor::constructJSFloat64Array(ExecState* exec)
+{
+ JSFloat64ArrayConstructor* jsConstructor = static_cast<JSFloat64ArrayConstructor*>(exec->callee());
+ RefPtr<Float64Array> array = constructArrayBufferView<Float64Array, double>(exec);
+ if (!array.get())
+ // Exception has already been thrown.
+ return JSValue::encode(JSValue());
+ return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), array.get())));
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
index e025008..c3a0cbb 100644
--- a/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
+++ b/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
@@ -76,10 +76,6 @@
#include <wtf/UnusedParam.h>
#include <wtf/text/CString.h>
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#endif
-
namespace WebCore {
static void handleFatalErrorInV8()
@@ -283,10 +279,6 @@ bool V8DOMWindowShell::initContextIfNeeded()
if (!m_context.IsEmpty())
return false;
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::JavaScriptInitTimeCounter);
-#endif
-
// Create a handle scope for all local handles.
v8::HandleScope handleScope;
@@ -352,10 +344,6 @@ bool V8DOMWindowShell::initContextIfNeeded()
// we do isolated worlds the WebCore way.
m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::JavaScriptInitTimeCounter, __FUNCTION__);
-#endif
-
return true;
}
diff --git a/Source/WebCore/bindings/v8/V8Proxy.cpp b/Source/WebCore/bindings/v8/V8Proxy.cpp
index ca57fa8..d90cf1c 100644
--- a/Source/WebCore/bindings/v8/V8Proxy.cpp
+++ b/Source/WebCore/bindings/v8/V8Proxy.cpp
@@ -83,14 +83,6 @@
#include <wtf/UnusedParam.h>
#include <wtf/text/StringConcatenate.h>
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#endif
-
-#if PLATFORM(ANDROID)
-#include <wtf/text/CString.h>
-#endif
-
namespace WebCore {
// Static list of registered extensions
@@ -209,16 +201,6 @@ V8Proxy::~V8Proxy()
}
v8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition0& scriptStartPosition, v8::ScriptData* scriptData)
-#ifdef ANDROID_INSTRUMENT
-{
- android::TimeCounter::start(android::TimeCounter::JavaScriptParseTimeCounter);
- v8::Handle<v8::Script> script = compileScriptInternal(code, fileName, scriptStartPosition, scriptData);
- android::TimeCounter::record(android::TimeCounter::JavaScriptParseTimeCounter, __FUNCTION__);
- return script;
-}
-
-v8::Handle<v8::Script> V8Proxy::compileScriptInternal(v8::Handle<v8::String> code, const String& fileName, const TextPosition0& scriptStartPosition, v8::ScriptData* scriptData)
-#endif
{
const uint16_t* fileNameString = fromWebCoreString(fileName);
v8::Handle<v8::String> name = v8::String::New(fileNameString, fileName.length());
@@ -398,16 +380,6 @@ v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* nod
}
v8::Local<v8::Value> V8Proxy::runScript(v8::Handle<v8::Script> script, bool isInlineCode)
-#ifdef ANDROID_INSTRUMENT
-{
- android::TimeCounter::start(android::TimeCounter::JavaScriptExecuteTimeCounter);
- v8::Local<v8::Value> result = runScriptInternal(script, isInlineCode);
- android::TimeCounter::record(android::TimeCounter::JavaScriptExecuteTimeCounter, __FUNCTION__);
- return result;
-}
-
-v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, bool isInlineCode)
-#endif
{
if (script.IsEmpty())
return notHandledByInterceptor();
@@ -472,9 +444,6 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b
v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::JavaScriptExecuteTimeCounter);
-#endif
V8GCController::checkMemoryUsage();
v8::Local<v8::Value> result;
{
@@ -521,9 +490,6 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
if (v8::V8::IsDead())
handleFatalErrorInV8();
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::JavaScriptExecuteTimeCounter, __FUNCTION__);
-#endif
return result;
}
diff --git a/Source/WebCore/bindings/v8/V8Proxy.h b/Source/WebCore/bindings/v8/V8Proxy.h
index fc52b19..777815b 100644
--- a/Source/WebCore/bindings/v8/V8Proxy.h
+++ b/Source/WebCore/bindings/v8/V8Proxy.h
@@ -171,10 +171,6 @@ namespace WebCore {
// Run an already compiled script.
v8::Local<v8::Value> runScript(v8::Handle<v8::Script>, bool isInlineCode);
-#ifdef ANDROID_INSTRUMENT
- v8::Local<v8::Value> runScriptInternal(v8::Handle<v8::Script> script, bool inline_code);
-#endif
-
// Call the function with the given receiver and arguments.
v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
@@ -244,10 +240,6 @@ namespace WebCore {
static v8::Handle<v8::Script> compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition0& scriptStartPosition, v8::ScriptData* = 0);
-#ifdef ANDROID_INSTRUMENT
- static v8::Handle<v8::Script> compileScriptInternal(v8::Handle<v8::String> code, const String& fileName, int baseLine, v8::ScriptData* scriptData);
-#endif
-
// If the exception code is different from zero, a DOM exception is
// schedule to be thrown.
static void setDOMException(int exceptionCode);
diff --git a/Source/WebCore/bindings/v8/custom/V8Float64ArrayCustom.cpp b/Source/WebCore/bindings/v8/custom/V8Float64ArrayCustom.cpp
new file mode 100644
index 0000000..429e962
--- /dev/null
+++ b/Source/WebCore/bindings/v8/custom/V8Float64ArrayCustom.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * 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 "Float64Array.h"
+
+#include "ArrayBuffer.h"
+#include "V8ArrayBuffer.h"
+#include "V8ArrayBufferViewCustom.h"
+#include "V8Binding.h"
+#include "V8Float64Array.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8Float64Array::constructorCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.Float64Array.Contructor");
+
+ return constructWebGLArray<Float64Array, double>(args, &info, v8::kExternalDoubleArray);
+}
+
+v8::Handle<v8::Value> V8Float64Array::setCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.Float64Array.set()");
+ return setWebGLArrayHelper<Float64Array, V8Float64Array>(args);
+}
+
+v8::Handle<v8::Value> toV8(Float64Array* impl)
+{
+ if (!impl)
+ return v8::Null();
+ v8::Handle<v8::Object> wrapper = V8Float64Array::wrap(impl);
+ if (!wrapper.IsEmpty())
+ wrapper->SetIndexedPropertiesToExternalArrayData(impl->baseAddress(), v8::kExternalDoubleArray, impl->length());
+ return wrapper;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bridge/jni/JavaMethodJobject.cpp b/Source/WebCore/bridge/jni/JavaMethodJobject.cpp
index 01a0b5b..f93e197 100644
--- a/Source/WebCore/bridge/jni/JavaMethodJobject.cpp
+++ b/Source/WebCore/bridge/jni/JavaMethodJobject.cpp
@@ -131,9 +131,9 @@ const char* JavaMethodJobject::signature() const
else {
signatureBuilder.append(signatureFromJavaType(type));
if (type == JavaTypeObject
-#if USE(V8)
+// ANDROID
|| type == JavaTypeString
-#endif
+// ANDROID
) {
appendClassName(signatureBuilder, javaClassName.data());
signatureBuilder.append(';');
@@ -148,9 +148,9 @@ const char* JavaMethodJobject::signature() const
else {
signatureBuilder.append(signatureFromJavaType(m_returnType));
if (m_returnType == JavaTypeObject
-#if USE(V8)
+// ANDROID
|| m_returnType == JavaTypeString
-#endif
+// ANDROID
) {
appendClassName(signatureBuilder, returnType);
signatureBuilder.append(';');
diff --git a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
index 42efaac..15b4bda 100644
--- a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
+++ b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
@@ -72,11 +72,16 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
break;
}
- jsize length = 0;
- if (NPVARIANT_IS_INT32(npvLength))
- length = static_cast<jsize>(NPVARIANT_TO_INT32(npvLength));
- else if (NPVARIANT_IS_DOUBLE(npvLength))
- length = static_cast<jsize>(NPVARIANT_TO_DOUBLE(npvLength));
+ // Convert to null if the length property is not a number.
+ if (!NPVARIANT_IS_INT32(npvLength) && !NPVARIANT_IS_DOUBLE(npvLength))
+ break;
+
+ // Convert to null if the length property is out of bounds.
+ double doubleLength = NPVARIANT_IS_INT32(npvLength) ? NPVARIANT_TO_INT32(npvLength) : NPVARIANT_TO_DOUBLE(npvLength);
+ if (doubleLength < 0.0 || doubleLength > INT32_MAX)
+ break;
+
+ jsize length = static_cast<jsize>(doubleLength);
if (!strcmp(javaClassName.data(), "[Ljava.lang.String;")) {
// Match JSC behavior by only allowing Object arrays if they are Strings.
@@ -85,7 +90,7 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
for (jsize i = 0; i < length; i++) {
NPVariant npvValue;
_NPN_GetProperty(0, object, _NPN_GetIntIdentifier(i), &npvValue);
- if(NPVARIANT_IS_STRING(npvValue)) {
+ if (NPVARIANT_IS_STRING(npvValue)) {
NPString str = NPVARIANT_TO_STRING(npvValue);
env->SetObjectArrayElement(static_cast<jobjectArray>(javaArray), i, env->NewStringUTF(str.UTF8Characters));
}
@@ -100,11 +105,10 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
NPVariant npvValue;
_NPN_GetProperty(0, object, _NPN_GetIntIdentifier(i), &npvValue);
jbyte bVal = 0;
- if (NPVARIANT_IS_INT32(npvValue)) {
+ if (NPVARIANT_IS_INT32(npvValue))
bVal = static_cast<jbyte>(NPVARIANT_TO_INT32(npvValue));
- } else if (NPVARIANT_IS_DOUBLE(npvValue)) {
+ else if (NPVARIANT_IS_DOUBLE(npvValue))
bVal = static_cast<jbyte>(NPVARIANT_TO_DOUBLE(npvValue));
- }
env->SetByteArrayRegion(static_cast<jbyteArray>(javaArray), i, 1, &bVal);
}
} else if (!strcmp(javaClassName.data(), "[C")) {
@@ -115,12 +119,8 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
NPVariant npvValue;
_NPN_GetProperty(0, object, _NPN_GetIntIdentifier(i), &npvValue);
jchar cVal = 0;
- if (NPVARIANT_IS_INT32(npvValue)) {
+ if (NPVARIANT_IS_INT32(npvValue))
cVal = static_cast<jchar>(NPVARIANT_TO_INT32(npvValue));
- } else if (NPVARIANT_IS_STRING(npvValue)) {
- NPString str = NPVARIANT_TO_STRING(npvValue);
- cVal = str.UTF8Characters[0];
- }
env->SetCharArrayRegion(static_cast<jcharArray>(javaArray), i, 1, &cVal);
}
} else if (!strcmp(javaClassName.data(), "[D")) {
@@ -155,11 +155,10 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
NPVariant npvValue;
_NPN_GetProperty(0, object, _NPN_GetIntIdentifier(i), &npvValue);
jint iVal = 0;
- if (NPVARIANT_IS_INT32(npvValue)) {
+ if (NPVARIANT_IS_INT32(npvValue))
iVal = NPVARIANT_TO_INT32(npvValue);
- } else if (NPVARIANT_IS_DOUBLE(npvValue)) {
+ else if (NPVARIANT_IS_DOUBLE(npvValue))
iVal = static_cast<jint>(NPVARIANT_TO_DOUBLE(npvValue));
- }
env->SetIntArrayRegion(static_cast<jintArray>(javaArray), i, 1, &iVal);
}
} else if (!strcmp(javaClassName.data(), "[J")) {
@@ -170,11 +169,10 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
NPVariant npvValue;
_NPN_GetProperty(0, object, _NPN_GetIntIdentifier(i), &npvValue);
jlong jVal = 0;
- if (NPVARIANT_IS_INT32(npvValue)) {
+ if (NPVARIANT_IS_INT32(npvValue))
jVal = static_cast<jlong>(NPVARIANT_TO_INT32(npvValue));
- } else if (NPVARIANT_IS_DOUBLE(npvValue)) {
+ else if (NPVARIANT_IS_DOUBLE(npvValue))
jVal = static_cast<jlong>(NPVARIANT_TO_DOUBLE(npvValue));
- }
env->SetLongArrayRegion(static_cast<jlongArray>(javaArray), i, 1, &jVal);
}
} else if (!strcmp(javaClassName.data(), "[S")) {
@@ -185,11 +183,10 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
NPVariant npvValue;
_NPN_GetProperty(0, object, _NPN_GetIntIdentifier(i), &npvValue);
jshort sVal = 0;
- if (NPVARIANT_IS_INT32(npvValue)) {
+ if (NPVARIANT_IS_INT32(npvValue))
sVal = static_cast<jshort>(NPVARIANT_TO_INT32(npvValue));
- } else if (NPVARIANT_IS_DOUBLE(npvValue)) {
+ else if (NPVARIANT_IS_DOUBLE(npvValue))
sVal = static_cast<jshort>(NPVARIANT_TO_DOUBLE(npvValue));
- }
env->SetShortArrayRegion(static_cast<jshortArray>(javaArray), i, 1, &sVal);
}
} else if (!strcmp(javaClassName.data(), "[Z")) {
diff --git a/Source/WebCore/bridge/jni/v8/JavaValueV8.h b/Source/WebCore/bridge/jni/v8/JavaValueV8.h
index 3e1c623..c6ff315 100644
--- a/Source/WebCore/bridge/jni/v8/JavaValueV8.h
+++ b/Source/WebCore/bridge/jni/v8/JavaValueV8.h
@@ -49,7 +49,18 @@ class JavaInstance;
// currently used only with V8.
// See https://bugs.webkit.org/show_bug.cgi?id=57023.
struct JavaValue {
- JavaValue() : m_type(JavaTypeInvalid) {}
+// ANDROID
+ JavaValue()
+ : m_type(JavaTypeInvalid)
+ , m_booleanValue(false)
+ , m_byteValue(0)
+ , m_charValue(0)
+ , m_shortValue(0)
+ , m_intValue(0)
+ , m_longValue(0)
+ , m_floatValue(0.0)
+ , m_doubleValue(0.0) {}
+// ANDROID
JavaType m_type;
// We don't use a union because we want to be able to ref-count some of the
diff --git a/Source/WebCore/css/AndroidCSSPropertyNames.in b/Source/WebCore/css/AndroidCSSPropertyNames.in
index ef67d6b..be751da 100644
--- a/Source/WebCore/css/AndroidCSSPropertyNames.in
+++ b/Source/WebCore/css/AndroidCSSPropertyNames.in
@@ -21,14 +21,5 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
--webkit-ring
--webkit-ring-fill-color
--webkit-ring-inner-width
--webkit-ring-outer-width
--webkit-ring-outset
--webkit-ring-pressed-inner-color
--webkit-ring-pressed-outer-color
--webkit-ring-radius
--webkit-ring-selected-inner-color
--webkit-ring-selected-outer-color
+
-webkit-tap-highlight-color
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
index 4c0571d..4922109 100644
--- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -291,18 +291,6 @@ static const int computedProperties[] = {
CSSPropertyWebkitSvgShadow,
CSSPropertyVectorEffect
#endif
-#ifdef ANDROID_CSS_RING
- ,
- CSSPropertyWebkitRingFillColor,
- CSSPropertyWebkitRingInnerWidth,
- CSSPropertyWebkitRingOuterWidth,
- CSSPropertyWebkitRingOutset,
- CSSPropertyWebkitRingPressedInnerColor,
- CSSPropertyWebkitRingPressedOuterColor,
- CSSPropertyWebkitRingRadius,
- CSSPropertyWebkitRingSelectedInnerColor,
- CSSPropertyWebkitRingSelectedOuterColor
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
,
CSSPropertyWebkitTapHighlightColor
@@ -1818,29 +1806,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyWebkitTransformOriginZ:
case CSSPropertyWebkitTransition:
break;
-#ifdef ANDROID_CSS_RING
- case CSSPropertyWebkitRing:
- // shorthand property currently not supported see bug 13658
- break;
- case CSSPropertyWebkitRingFillColor:
- return primitiveValueCache->createColorValue(style->ringFillColor().rgb());
- case CSSPropertyWebkitRingInnerWidth:
- return primitiveValueCache->createValue(style->ringInnerWidth());
- case CSSPropertyWebkitRingOuterWidth:
- return primitiveValueCache->createValue(style->ringOuterWidth());
- case CSSPropertyWebkitRingOutset:
- return primitiveValueCache->createValue(style->ringOutset());
- case CSSPropertyWebkitRingPressedInnerColor:
- return primitiveValueCache->createColorValue(style->ringPressedInnerColor().rgb());
- case CSSPropertyWebkitRingPressedOuterColor:
- return primitiveValueCache->createColorValue(style->ringPressedOuterColor().rgb());
- case CSSPropertyWebkitRingRadius:
- return primitiveValueCache->createValue(style->ringRadius());
- case CSSPropertyWebkitRingSelectedInnerColor:
- return primitiveValueCache->createColorValue(style->ringSelectedInnerColor().rgb());
- case CSSPropertyWebkitRingSelectedOuterColor:
- return primitiveValueCache->createColorValue(style->ringSelectedOuterColor().rgb());
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
case CSSPropertyWebkitTapHighlightColor:
return primitiveValueCache->createColorValue(style->tapHighlightColor().rgb());
diff --git a/Source/WebCore/css/CSSImportRule.cpp b/Source/WebCore/css/CSSImportRule.cpp
index 09e313e..81ade39 100644
--- a/Source/WebCore/css/CSSImportRule.cpp
+++ b/Source/WebCore/css/CSSImportRule.cpp
@@ -170,26 +170,4 @@ void CSSImportRule::addSubresourceStyleURLs(ListHashSet<KURL>& urls)
addSubresourceURL(urls, m_styleSheet->baseURL());
}
-#ifdef ANDROID_INSTRUMENT
-void* CSSImportRule::operator new(size_t size)
-{
- return StyleBase::operator new(size);
-}
-
-void* CSSImportRule::operator new[](size_t size)
-{
- return StyleBase::operator new[](size);
-}
-
-void CSSImportRule::operator delete(void* p, size_t size)
-{
- StyleBase::operator delete(p, size);
-}
-
-void CSSImportRule::operator delete[](void* p, size_t size)
-{
- StyleBase::operator delete[](p, size);
-}
-#endif
-
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSImportRule.h b/Source/WebCore/css/CSSImportRule.h
index 3f44f5b..ad4e97d 100644
--- a/Source/WebCore/css/CSSImportRule.h
+++ b/Source/WebCore/css/CSSImportRule.h
@@ -66,14 +66,6 @@ private:
// from CachedResourceClient
virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*);
-#ifdef ANDROID_INSTRUMENT
- // Overridden to resolve the ambiguous
- void* operator new(size_t size);
- void* operator new[](size_t size);
- void operator delete(void* p, size_t size);
- void operator delete[](void* p, size_t size);
-#endif
-
String m_strHref;
RefPtr<MediaList> m_lstMedia;
RefPtr<CSSStyleSheet> m_styleSheet;
diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
index ba3332d..ece418a 100644
--- a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -261,20 +261,6 @@ String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const
return value->cssText();
}
#endif
-#ifdef ANDROID_CSS_RING
- case CSSPropertyWebkitRing: {
- const int properties[9] = { CSSPropertyWebkitRingFillColor,
- CSSPropertyWebkitRingInnerWidth,
- CSSPropertyWebkitRingOuterWidth,
- CSSPropertyWebkitRingOutset,
- CSSPropertyWebkitRingPressedInnerColor,
- CSSPropertyWebkitRingPressedOuterColor,
- CSSPropertyWebkitRingRadius,
- CSSPropertyWebkitRingSelectedInnerColor,
- CSSPropertyWebkitRingSelectedOuterColor };
- return getLayeredShorthandValue(properties, 9);
- }
-#endif
}
return String();
}
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 831e438..b78a6d0 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -92,10 +92,6 @@ extern int cssyyparse(void* parser);
using namespace std;
using namespace WTF;
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#endif
-
namespace WebCore {
static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
@@ -230,9 +226,6 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int startLineNumber, StyleRuleRangeMap* ruleRangeMap)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
setStyleSheet(sheet);
m_defaultNamespace = starAtom; // Reset the default namespace.
m_ruleRangeMap = ruleRangeMap;
@@ -247,37 +240,22 @@ void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int start
m_ruleRangeMap = 0;
m_currentRuleData = 0;
m_rule = 0;
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
}
PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
setStyleSheet(sheet);
m_allowNamespaceDeclarations = false;
setupParser("@-webkit-rule{", string, "} ");
cssyyparse(this);
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
return m_rule.release();
}
PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
setStyleSheet(sheet);
setupParser("@-webkit-keyframe-rule{ ", string, "} ");
cssyyparse(this);
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
return m_keyframe.release();
}
@@ -440,9 +418,6 @@ bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int property
bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
@@ -464,9 +439,6 @@ bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int property
clearProperties();
}
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
return ok;
}
@@ -499,9 +471,6 @@ bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict)
bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String& string)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
@@ -509,9 +478,6 @@ bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String
cssyyparse(this);
m_rule = 0;
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
return (m_numParsedProperties && m_parsedProperties[0]->m_id == CSSPropertyColor);
}
@@ -533,9 +499,6 @@ bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document*
void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorList& selectorList)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc);
setStyleSheet(dummyStyleSheet.get());
@@ -549,18 +512,10 @@ void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorLi
// The style sheet will be deleted right away, so it won't outlive the document.
ASSERT(dummyStyleSheet->hasOneRef());
-
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
}
bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const String& string, RefPtr<CSSStyleSourceData>* styleSourceData)
{
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
-
// Length of the "@-webkit-decls{" prefix.
static const unsigned prefixLength = 15;
@@ -599,9 +554,6 @@ bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const
m_currentRuleData = 0;
m_inStyleRuleOrDeclaration = false;
}
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
return ok;
}
@@ -610,9 +562,6 @@ bool CSSParser::parseMediaQuery(MediaList* queries, const String& string)
if (string.isEmpty())
return true;
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter);
-#endif
ASSERT(!m_mediaQuery);
// can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
@@ -626,9 +575,6 @@ bool CSSParser::parseMediaQuery(MediaList* queries, const String& string)
queries->appendMediaQuery(m_mediaQuery.release());
}
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CSSParseTimeCounter, __FUNCTION__);
-#endif
return ok;
}
@@ -2016,7 +1962,6 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyTextOverline:
case CSSPropertyTextUnderline:
return false;
-
#if ENABLE(WCSS)
case CSSPropertyWapInputFormat:
validPrimitive = true;
@@ -2063,36 +2008,6 @@ bool CSSParser::parseValue(int propId, bool important)
return parseLineBoxContain(important);
break;
-#ifdef ANDROID_CSS_RING
- case CSSPropertyWebkitRing:
- {
- const int properties[9] = { CSSPropertyWebkitRingFillColor,
- CSSPropertyWebkitRingInnerWidth,
- CSSPropertyWebkitRingOuterWidth,
- CSSPropertyWebkitRingOutset,
- CSSPropertyWebkitRingPressedInnerColor,
- CSSPropertyWebkitRingPressedOuterColor,
- CSSPropertyWebkitRingRadius,
- CSSPropertyWebkitRingSelectedInnerColor,
- CSSPropertyWebkitRingSelectedOuterColor };
- return parseShorthand(propId, properties, 9, important);
- }
- case CSSPropertyWebkitRingFillColor:
- case CSSPropertyWebkitRingPressedInnerColor:
- case CSSPropertyWebkitRingPressedOuterColor:
- case CSSPropertyWebkitRingSelectedInnerColor:
- case CSSPropertyWebkitRingSelectedOuterColor:
- parsedValue = parseColor();
- if (parsedValue)
- m_valueList->next();
- break;
- case CSSPropertyWebkitRingInnerWidth:
- case CSSPropertyWebkitRingOuterWidth:
- case CSSPropertyWebkitRingOutset:
- case CSSPropertyWebkitRingRadius:
- validPrimitive = validUnit(value, FLength | FNonNeg, m_strict);
- break;
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
case CSSPropertyWebkitTapHighlightColor:
parsedValue = parseColor();
diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in
index a62d2f3..395b7cf 100644
--- a/Source/WebCore/css/CSSPropertyNames.in
+++ b/Source/WebCore/css/CSSPropertyNames.in
@@ -306,3 +306,4 @@ z-index
-webkit-user-drag
-webkit-user-modify
-webkit-user-select
+-webkit-overflow-scrolling
diff --git a/Source/WebCore/css/CSSStyleDeclaration.cpp b/Source/WebCore/css/CSSStyleDeclaration.cpp
index 1c465e5..d4acc2a 100644
--- a/Source/WebCore/css/CSSStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSStyleDeclaration.cpp
@@ -27,6 +27,7 @@
#include "CSSPropertyNames.h"
#include "CSSRule.h"
#include <wtf/ASCIICType.h>
+#include <wtf/text/CString.h>
using namespace WTF;
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index b79f2dc..0b6fd35 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -6054,138 +6054,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
ASSERT_NOT_REACHED();
return;
-#ifdef ANDROID_CSS_RING
- case CSSPropertyWebkitRing:
- if (valueType != CSSValue::CSS_INHERIT || !m_parentNode) return;
- m_style->setRingFillColor(m_parentStyle->ringFillColor());
- m_style->setRingInnerWidth(m_parentStyle->ringInnerWidth());
- m_style->setRingOuterWidth(m_parentStyle->ringOuterWidth());
- m_style->setRingOutset(m_parentStyle->ringOutset());
- m_style->setRingPressedInnerColor(m_parentStyle->ringPressedInnerColor());
- m_style->setRingPressedOuterColor(m_parentStyle->ringPressedOuterColor());
- m_style->setRingRadius(m_parentStyle->ringRadius());
- m_style->setRingSelectedInnerColor(m_parentStyle->ringSelectedInnerColor());
- m_style->setRingSelectedOuterColor(m_parentStyle->ringSelectedOuterColor());
- return;
- case CSSPropertyWebkitRingFillColor: {
- HANDLE_INHERIT_AND_INITIAL(ringFillColor, RingFillColor);
- if (!primitiveValue)
- break;
- Color col = getColorFromPrimitiveValue(primitiveValue).blendWithWhite();
- m_style->setRingFillColor(col);
- return;
- }
- case CSSPropertyWebkitRingInnerWidth: {
- HANDLE_INHERIT_AND_INITIAL(ringInnerWidth, RingInnerWidth)
- if (!primitiveValue)
- break;
- Length l;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type)) {
- // width can be specified with fractional px
- // scale by 16 here (and unscale in android_graphics) to keep
- // 4 bits of fraction
- RefPtr<CSSPrimitiveValue> scaledValue = CSSPrimitiveValue::create(
- primitiveValue->getFloatValue() * 16,
- (CSSPrimitiveValue::UnitTypes) type);
- l = Length(scaledValue->computeLengthIntForLength(style(),
- m_rootElementStyle, zoomFactor), Fixed);
- scaledValue.release();
- } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- l = Length(primitiveValue->getDoubleValue(), Percent);
- else
- return;
- m_style->setRingInnerWidth(l);
- return;
- }
- case CSSPropertyWebkitRingOuterWidth: {
- HANDLE_INHERIT_AND_INITIAL(ringOuterWidth, RingOuterWidth)
- if (!primitiveValue)
- break;
- Length l;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type)) {
- // width can be specified with fractional px
- // scale by 16 here (and unscale in android_graphics) to keep
- // 4 bits of fraction
- RefPtr<CSSPrimitiveValue> scaledValue = CSSPrimitiveValue::create(
- primitiveValue->getFloatValue() * 16,
- (CSSPrimitiveValue::UnitTypes) type);
- l = Length(scaledValue->computeLengthIntForLength(style(),
- m_rootElementStyle, zoomFactor), Fixed);
- scaledValue.release();
- } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- l = Length(primitiveValue->getDoubleValue(), Percent);
- else
- return;
- m_style->setRingOuterWidth(l);
- return;
- }
- case CSSPropertyWebkitRingOutset: {
- HANDLE_INHERIT_AND_INITIAL(ringOutset, RingOutset)
- if (!primitiveValue)
- break;
- Length l;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type))
- l = Length(primitiveValue->computeLengthIntForLength(style(),
- m_rootElementStyle, zoomFactor), Fixed);
- else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- l = Length(primitiveValue->getDoubleValue(), Percent);
- else
- return;
- m_style->setRingOutset(l);
- return;
- }
- case CSSPropertyWebkitRingPressedInnerColor: {
- HANDLE_INHERIT_AND_INITIAL(ringPressedInnerColor, RingPressedInnerColor);
- if (!primitiveValue)
- break;
- Color col = getColorFromPrimitiveValue(primitiveValue).blendWithWhite();
- m_style->setRingPressedInnerColor(col);
- return;
- }
- case CSSPropertyWebkitRingPressedOuterColor: {
- HANDLE_INHERIT_AND_INITIAL(ringPressedOuterColor, RingPressedOuterColor);
- if (!primitiveValue)
- break;
- Color col = getColorFromPrimitiveValue(primitiveValue).blendWithWhite();
- m_style->setRingPressedOuterColor(col);
- return;
- }
- case CSSPropertyWebkitRingRadius: {
- HANDLE_INHERIT_AND_INITIAL(ringRadius, RingRadius)
- if (!primitiveValue)
- break;
- Length l;
- int type = primitiveValue->primitiveType();
- if (CSSPrimitiveValue::isUnitTypeLength(type))
- l = Length(primitiveValue->computeLengthIntForLength(style(),
- m_rootElementStyle, zoomFactor), Fixed);
- else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- l = Length(primitiveValue->getDoubleValue(), Percent);
- else
- return;
- m_style->setRingRadius(l);
- return;
- }
- case CSSPropertyWebkitRingSelectedInnerColor: {
- HANDLE_INHERIT_AND_INITIAL(ringSelectedInnerColor, RingSelectedInnerColor);
- if (!primitiveValue)
- break;
- Color col = getColorFromPrimitiveValue(primitiveValue).blendWithWhite();
- m_style->setRingSelectedInnerColor(col);
- return;
- }
- case CSSPropertyWebkitRingSelectedOuterColor: {
- HANDLE_INHERIT_AND_INITIAL(ringSelectedOuterColor, RingSelectedOuterColor);
- if (!primitiveValue)
- break;
- Color col = getColorFromPrimitiveValue(primitiveValue).blendWithWhite();
- m_style->setRingSelectedOuterColor(col);
- return;
- }
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
case CSSPropertyWebkitTapHighlightColor: {
HANDLE_INHERIT_AND_INITIAL(tapHighlightColor, TapHighlightColor);
diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in
index 6dac06f..5b6e5b0 100644
--- a/Source/WebCore/css/CSSValueKeywords.in
+++ b/Source/WebCore/css/CSSValueKeywords.in
@@ -756,6 +756,10 @@ windowed
manual
# auto
+# -webkit-overflow-scrolling
+# auto
+touch
+
# -webkit-writing-mode
# SVG compatibility
lr
diff --git a/Source/WebCore/css/StyleBase.cpp b/Source/WebCore/css/StyleBase.cpp
index 5d9d79d..93dbda0 100644
--- a/Source/WebCore/css/StyleBase.cpp
+++ b/Source/WebCore/css/StyleBase.cpp
@@ -65,37 +65,4 @@ KURL StyleBase::baseURL() const
return sheet->ownerNode()->document()->baseURL();
}
-#ifdef ANDROID_INSTRUMENT
-static size_t styleSize = 0;
-
-void* StyleBase::operator new(size_t size)
-{
- styleSize += size;
- return ::operator new(size);
-}
-
-void* StyleBase::operator new[](size_t size)
-{
- styleSize += size;
- return ::operator new[](size);
-}
-
-void StyleBase::operator delete(void* p, size_t size)
-{
- styleSize -= size;
- ::operator delete(p);
-}
-
-void StyleBase::operator delete[](void* p, size_t size)
-{
- styleSize -= size;
- ::operator delete[](p);
-}
-
-size_t StyleBase::reportStyleSize()
-{
- return styleSize;
-}
-#endif
-
}
diff --git a/Source/WebCore/css/StyleBase.h b/Source/WebCore/css/StyleBase.h
index 94efa01..63c671e 100644
--- a/Source/WebCore/css/StyleBase.h
+++ b/Source/WebCore/css/StyleBase.h
@@ -72,18 +72,6 @@ namespace WebCore {
StyleSheet* stylesheet();
-#ifdef ANDROID_INSTRUMENT
- // Overridden to prevent the normal new from being called.
- void* operator new(size_t size);
- void* operator new[](size_t size);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void* p, size_t size);
- void operator delete[](void* p, size_t size);
-
- static size_t reportStyleSize();
-#endif
-
protected:
StyleBase(StyleBase* parent)
: m_parent(parent)
diff --git a/Source/WebCore/css/mediaControlsAndroid.css b/Source/WebCore/css/mediaControlsAndroid.css
index 77f8b08..614c92f 100644
--- a/Source/WebCore/css/mediaControlsAndroid.css
+++ b/Source/WebCore/css/mediaControlsAndroid.css
@@ -49,10 +49,7 @@ video:-webkit-full-page-media::-webkit-media-controls-panel {
}
audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button {
- -webkit-appearance: media-mute-button;
- display: -webkit-box;
- width: 48px;
- height: 48px;
+ display: none;
}
audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
diff --git a/Source/WebCore/dom/DOMTextContentWalker.cpp b/Source/WebCore/dom/DOMTextContentWalker.cpp
new file mode 100644
index 0000000..5e77db1
--- /dev/null
+++ b/Source/WebCore/dom/DOMTextContentWalker.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#include "config.h"
+#include "DOMTextContentWalker.h"
+
+#if OS(ANDROID)
+
+#include "Range.h"
+#include "TextIterator.h"
+#include "VisiblePosition.h"
+#include "VisibleSelection.h"
+#include "visible_units.h"
+
+namespace WebCore {
+
+static PassRefPtr<Range> getRange(const Position& start, const Position& end)
+{
+ return VisibleSelection(start.parentAnchoredEquivalent(), end.parentAnchoredEquivalent(), DOWNSTREAM).firstRange();
+}
+
+DOMTextContentWalker::DOMTextContentWalker(const VisiblePosition& position, unsigned maxLength)
+ : m_hitOffsetInContent(0)
+{
+ const unsigned halfMaxLength = maxLength / 2;
+ RefPtr<Range> forwardRange = makeRange(position, endOfDocument(position));
+ if (!forwardRange)
+ return;
+ CharacterIterator forwardChar(forwardRange.get(), TextIteratorStopsOnFormControls);
+ forwardChar.advance(maxLength - halfMaxLength);
+
+ // No forward contents, started inside form control.
+ if (getRange(position.deepEquivalent(), forwardChar.range()->startPosition())->text().length() == 0)
+ return;
+
+ RefPtr<Range> backwardsRange = makeRange(startOfDocument(position), position);
+ if (!backwardsRange)
+ return;
+ BackwardsCharacterIterator backwardsChar(backwardsRange.get(), TextIteratorStopsOnFormControls);
+ backwardsChar.advance(halfMaxLength);
+
+ m_hitOffsetInContent = getRange(backwardsChar.range()->endPosition(), position.deepEquivalent())->text().length();
+ m_contentRange = getRange(backwardsChar.range()->endPosition(), forwardChar.range()->startPosition());
+}
+
+PassRefPtr<Range> DOMTextContentWalker::contentOffsetsToRange(unsigned startInContent, unsigned endInContent)
+{
+ if (startInContent >= endInContent || endInContent > content().length())
+ return 0;
+
+ CharacterIterator iterator(m_contentRange.get());
+ iterator.advance(startInContent);
+
+ Position start = iterator.range()->startPosition();
+ iterator.advance(endInContent - startInContent);
+ Position end = iterator.range()->startPosition();
+ return getRange(start, end);
+}
+
+String DOMTextContentWalker::content() const
+{
+ if (m_contentRange)
+ return m_contentRange->text();
+ return String();
+}
+
+unsigned DOMTextContentWalker::hitOffsetInContent() const
+{
+ return m_hitOffsetInContent;
+}
+
+} // namespace WebCore
+
+#endif // OS(ANDROID)
diff --git a/Source/WebCore/dom/DOMTextContentWalker.h b/Source/WebCore/dom/DOMTextContentWalker.h
new file mode 100644
index 0000000..0d4259b
--- /dev/null
+++ b/Source/WebCore/dom/DOMTextContentWalker.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#ifndef DOMTextContentWalker_h
+#define DOMTextContentWalker_h
+
+#if OS(ANDROID)
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Range;
+class VisiblePosition;
+
+// Explore the DOM tree to find the text contents up to a limit
+// around a position in a given text node.
+class DOMTextContentWalker {
+ WTF_MAKE_NONCOPYABLE(DOMTextContentWalker);
+public:
+ DOMTextContentWalker(const VisiblePosition& position, unsigned maxLength);
+
+ String content() const;
+ unsigned hitOffsetInContent() const;
+
+ // Convert start/end positions in the content text string into a text range.
+ PassRefPtr<Range> contentOffsetsToRange(unsigned startInContent, unsigned endInContent);
+
+private:
+ RefPtr<Range> m_contentRange;
+ size_t m_hitOffsetInContent;
+};
+
+} // namespace WebCore
+
+#endif // OS(ANDROID)
+
+#endif // DOMTextContentWalker_h
+
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 6e21dc3..1b5f55b 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -189,15 +189,6 @@
#include "Settings.h"
#endif
-#ifdef ANDROID_RESET_SELECTION
-#include "CacheBuilder.h"
-#include "HTMLTextAreaElement.h"
-#endif
-
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#endif
-
#if ENABLE(TOUCH_EVENTS)
#if USE(V8)
#include "RuntimeEnabledFeatures.h"
@@ -1475,10 +1466,6 @@ void Document::recalcStyle(StyleChange change)
frameView->beginDeferredRepaints();
}
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::CalculateStyleTimeCounter);
-#endif
-
ASSERT(!renderer() || renderArena());
if (!renderer() || !renderArena())
goto bail_out;
@@ -1500,10 +1487,6 @@ void Document::recalcStyle(StyleChange change)
if (change >= Inherit || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
n->recalcStyle(change);
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::CalculateStyleTimeCounter, __FUNCTION__);
-#endif
-
#if USE(ACCELERATED_COMPOSITING)
if (view()) {
bool layoutPending = view()->layoutPending() || renderer()->needsLayout();
@@ -2729,8 +2712,8 @@ void Document::processArguments(const String& features, void* data, ArgumentsCal
#ifdef ANDROID_META_SUPPORT
if (frame())
frame()->settings()->setMetadataSettings(keyString, valueString);
-#endif
if (callback && data)
+#endif
callback(keyString, valueString, this, data);
}
}
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index 1fd4b92..0967ef5 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -2498,39 +2498,6 @@ Node* Node::enclosingLinkEventParentOrSelf()
return 0;
}
-#ifdef ANDROID_INSTRUMENT
-static size_t nodeSize = 0;
-
-void* Node::operator new(size_t size)
-{
- nodeSize += size;
- return ::operator new(size);
-}
-
-void* Node::operator new[](size_t size)
-{
- nodeSize += size;
- return ::operator new[](size);
-}
-
-void Node::operator delete(void* p, size_t size)
-{
- nodeSize -= size;
- ::operator delete(p);
-}
-
-void Node::operator delete[](void* p, size_t size)
-{
- nodeSize -= size;
- ::operator delete[](p);
-}
-
-size_t Node::reportDOMNodesSize()
-{
- return nodeSize;
-}
-#endif
-
// --------
ScriptExecutionContext* Node::scriptExecutionContext() const
diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h
index 1fe30ad..08b1921 100644
--- a/Source/WebCore/dom/Node.h
+++ b/Source/WebCore/dom/Node.h
@@ -528,18 +528,6 @@ public:
unsigned short compareDocumentPosition(Node*);
-#ifdef ANDROID_INSTRUMENT
- // Overridden to prevent the normal new from being called.
- void* operator new(size_t size);
- void* operator new[](size_t size);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void* p, size_t size);
- void operator delete[](void* p, size_t size);
-
- static size_t reportDOMNodesSize();
-#endif
-
virtual Node* toNode() { return this; }
virtual InputElement* toInputElement();
diff --git a/Source/WebCore/dom/ProcessingInstruction.cpp b/Source/WebCore/dom/ProcessingInstruction.cpp
index 7135644..30111d8 100644
--- a/Source/WebCore/dom/ProcessingInstruction.cpp
+++ b/Source/WebCore/dom/ProcessingInstruction.cpp
@@ -297,26 +297,4 @@ void ProcessingInstruction::finishParsingChildren()
ContainerNode::finishParsingChildren();
}
-#ifdef ANDROID_INSTRUMENT
-void* ProcessingInstruction::operator new(size_t size)
-{
- return Node::operator new(size);
-}
-
-void* ProcessingInstruction::operator new[](size_t size)
-{
- return Node::operator new[](size);
-}
-
-void ProcessingInstruction::operator delete(void* p, size_t size)
-{
- Node::operator delete(p, size);
-}
-
-void ProcessingInstruction::operator delete[](void* p, size_t size)
-{
- Node::operator delete[](p, size);
-}
-#endif
-
} // namespace
diff --git a/Source/WebCore/dom/ProcessingInstruction.h b/Source/WebCore/dom/ProcessingInstruction.h
index fd98566..1be8710 100644
--- a/Source/WebCore/dom/ProcessingInstruction.h
+++ b/Source/WebCore/dom/ProcessingInstruction.h
@@ -56,14 +56,6 @@ public:
private:
ProcessingInstruction(Document*, const String& target, const String& data);
-#ifdef ANDROID_INSTRUMENT
- // Overridden to resolve the ambiguous
- void* operator new(size_t size);
- void* operator new[](size_t size);
- void operator delete(void* p, size_t size);
- void operator delete[](void* p, size_t size);
-#endif
-
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual String nodeValue() const;
diff --git a/Source/WebCore/dom/Text.cpp b/Source/WebCore/dom/Text.cpp
index 906e421..c4ea0a6 100644
--- a/Source/WebCore/dom/Text.cpp
+++ b/Source/WebCore/dom/Text.cpp
@@ -31,6 +31,8 @@
#include "SVGNames.h"
#endif
+#include <wtf/text/CString.h>
+
#if ENABLE(WML)
#include "WMLDocument.h"
#include "WMLVariables.h"
diff --git a/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp b/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
index b1a455b..bd6fb60 100644
--- a/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
+++ b/Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
@@ -28,6 +28,8 @@
#include "AXObjectCache.h"
#include "Text.h"
+#include "RenderText.h"
+#include "Settings.h"
namespace WebCore {
@@ -46,7 +48,13 @@ void InsertIntoTextNodeCommand::doApply()
{
if (!m_node->rendererIsEditable())
return;
-
+
+ if (document()->settings() && document()->settings()->passwordEchoEnabled()) {
+ RenderText* renderText = toRenderText(m_node->renderer());
+ if (renderText && renderText->isSecure())
+ renderText->momentarilyRevealLastTypedCharacter(m_offset + m_text.length() - 1);
+ }
+
ExceptionCode ec;
m_node->insertData(m_offset, m_text, ec);
diff --git a/Source/WebCore/editing/SelectionController.cpp b/Source/WebCore/editing/SelectionController.cpp
index c5a33d3..acae6bf 100644
--- a/Source/WebCore/editing/SelectionController.cpp
+++ b/Source/WebCore/editing/SelectionController.cpp
@@ -1217,10 +1217,6 @@ void SelectionController::invalidateCaretRect()
void SelectionController::paintCaret(GraphicsContext* context, int tx, int ty, const IntRect& clipRect)
{
-#ifdef ANDROID_ALLOW_TURNING_OFF_CARET
- if (m_frame && !android::WebViewCore::getWebViewCore(m_frame->view())->shouldPaintCaret())
- return;
-#endif
#if ENABLE(TEXT_CARET)
if (!m_caretVisible)
return;
@@ -1592,6 +1588,10 @@ void SelectionController::updateAppearance()
// We need to update style in case the node containing the selection is made display:none.
m_frame->document()->updateStyleIfNeeded();
+#if PLATFORM(ANDROID)
+ return;
+#endif
+
RenderView* view = m_frame->contentRenderer();
if (!view)
return;
diff --git a/Source/WebCore/editing/TextIterator.cpp b/Source/WebCore/editing/TextIterator.cpp
index c3be277..3aa68af 100644
--- a/Source/WebCore/editing/TextIterator.cpp
+++ b/Source/WebCore/editing/TextIterator.cpp
@@ -239,6 +239,20 @@ static void setUpFullyClippedStack(BitStack& stack, Node* node)
ASSERT(stack.size() == 1 + depthCrossingShadowBoundaries(node));
}
+#if OS(ANDROID)
+static bool checkFormControlElement(Node* startNode)
+{
+ Node* node = startNode;
+ while (node) {
+ if (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement())
+ return true;
+ node = node->parentNode();
+ }
+ return false;
+}
+#endif
+
+
// --------
TextIterator::TextIterator()
@@ -258,6 +272,10 @@ TextIterator::TextIterator()
, m_handledFirstLetter(false)
, m_ignoresStyleVisibility(false)
, m_emitsObjectReplacementCharacters(false)
+#if OS(ANDROID)
+ , m_stopsOnFormControls(false)
+ , m_shouldStop(false)
+#endif
{
}
@@ -277,6 +295,10 @@ TextIterator::TextIterator(const Range* r, TextIteratorBehavior behavior)
, m_handledFirstLetter(false)
, m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility)
, m_emitsObjectReplacementCharacters(behavior & TextIteratorEmitsObjectReplacementCharacters)
+#if OS(ANDROID)
+ , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls)
+ , m_shouldStop(false)
+#endif
{
if (!r)
return;
@@ -334,8 +356,21 @@ TextIterator::~TextIterator()
{
}
+bool TextIterator::atEnd() const
+{
+#if OS(ANDROID)
+ return !m_positionNode || m_shouldStop;
+#else
+ return !m_positionNode;
+#endif
+}
+
void TextIterator::advance()
{
+#if OS(ANDROID)
+ if (m_shouldStop)
+ return;
+#endif
// reset the run information
m_positionNode = 0;
m_textLength = 0;
@@ -368,6 +403,10 @@ void TextIterator::advance()
}
while (m_node && m_node != m_pastEndNode) {
+#if OS(ANDROID)
+ if (!m_shouldStop && m_stopsOnFormControls && checkFormControlElement(m_node))
+ m_shouldStop = true;
+#endif
// if the range ends at offset 0 of an element, represent the
// position, but not the content, of that element e.g. if the
// node is a blockflow element, emit a newline that
@@ -1034,6 +1073,10 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator()
: m_behavior(TextIteratorDefaultBehavior)
, m_node(0)
, m_positionNode(0)
+#if OS(ANDROID)
+ , m_stopsOnFormControls(false)
+ , m_shouldStop(false)
+#endif
{
}
@@ -1041,8 +1084,16 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
: m_behavior(behavior)
, m_node(0)
, m_positionNode(0)
+#if OS(ANDROID)
+ , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls)
+ , m_shouldStop(false)
+#endif
{
+#if OS(ANDROID)
+ ASSERT(m_behavior == TextIteratorDefaultBehavior || m_behavior == TextIteratorStopsOnFormControls);
+#else
ASSERT(m_behavior == TextIteratorDefaultBehavior);
+#endif
if (!r)
return;
@@ -1091,10 +1142,30 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
advance();
}
+bool SimplifiedBackwardsTextIterator::atEnd() const
+{
+#if OS(ANDROID)
+ return !m_positionNode || m_shouldStop;
+#else
+ return !m_positionNode;
+#endif
+}
+
void SimplifiedBackwardsTextIterator::advance()
{
ASSERT(m_positionNode);
+#if OS(ANDROID)
+ if (m_shouldStop)
+ return;
+
+ // Prevent changing the iterator position if a form control element was found and advance should stop on it.
+ if (m_stopsOnFormControls && checkFormControlElement(m_node)) {
+ m_shouldStop = true;
+ return;
+ }
+#endif
+
m_positionNode = 0;
m_textLength = 0;
diff --git a/Source/WebCore/editing/TextIterator.h b/Source/WebCore/editing/TextIterator.h
index 9fe4ceb..c4fc264 100644
--- a/Source/WebCore/editing/TextIterator.h
+++ b/Source/WebCore/editing/TextIterator.h
@@ -42,7 +42,10 @@ enum TextIteratorBehavior {
TextIteratorEntersTextControls = 1 << 1,
TextIteratorEmitsTextsWithoutTranscoding = 1 << 2,
TextIteratorIgnoresStyleVisibility = 1 << 3,
- TextIteratorEmitsObjectReplacementCharacters = 1 << 4
+ TextIteratorEmitsObjectReplacementCharacters = 1 << 4,
+#if OS(ANDROID)
+ TextIteratorStopsOnFormControls = 1 << 6
+#endif
};
// FIXME: Can't really answer this question correctly without knowing the white-space mode.
@@ -88,7 +91,7 @@ public:
~TextIterator();
explicit TextIterator(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior);
- bool atEnd() const { return !m_positionNode; }
+ bool atEnd() const;
void advance();
int length() const { return m_textLength; }
@@ -182,6 +185,12 @@ private:
bool m_ignoresStyleVisibility;
// Used when emitting the special 0xFFFC character is required.
bool m_emitsObjectReplacementCharacters;
+#if OS(ANDROID)
+ // Used when the iteration should stop if form controls are reached.
+ bool m_stopsOnFormControls;
+ // Used when m_stopsOnFormControls is set to determine if the iterator should keep advancing.
+ bool m_shouldStop;
+#endif
};
// Iterates through the DOM range, returning all the text, and 0-length boundaries
@@ -192,7 +201,7 @@ public:
SimplifiedBackwardsTextIterator();
explicit SimplifiedBackwardsTextIterator(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior);
- bool atEnd() const { return !m_positionNode; }
+ bool atEnd() const;
void advance();
int length() const { return m_textLength; }
@@ -240,6 +249,13 @@ private:
// Whether m_node has advanced beyond the iteration range (i.e. m_startNode).
bool m_havePassedStartNode;
+
+#if OS(ANDROID)
+ // Used when the iteration should stop if form controls are reached.
+ bool m_stopsOnFormControls;
+ // Used when m_stopsOnFormControls is set to determine if the iterator should keep advancing.
+ bool m_shouldStop;
+#endif
};
// Builds on the text iterator, adding a character position so we can walk one
diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp
index 60f5b4a..4636f20 100644
--- a/Source/WebCore/html/HTMLAnchorElement.cpp
+++ b/Source/WebCore/html/HTMLAnchorElement.cpp
@@ -531,7 +531,11 @@ bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
bool isEnterKeyKeydownEvent(Event* event)
{
+#if OS(ANDROID)
+ return event->type() == eventNames().keyupEvent && event->isKeyboardEvent() && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter";
+#else
return event->type() == eventNames().keydownEvent && event->isKeyboardEvent() && static_cast<KeyboardEvent*>(event)->keyIdentifier() == "Enter";
+#endif
}
bool isMiddleMouseButtonEvent(Event* event)
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 9eab209..e485835 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -128,20 +128,8 @@ public:
void makeRenderingResultsAvailable();
-#ifdef ANDROID_INSTRUMENT
- void* operator new(size_t size) {
- return HTMLElement::operator new(size);
- }
- void* operator new[](size_t size) {
- return HTMLElement::operator new[](size);
- }
-
- void operator delete(void* p, size_t size) {
- HTMLElement::operator delete(p, size);
- }
- void operator delete[](void* p, size_t size) {
- HTMLElement::operator delete[](p, size);
- }
+#if PLATFORM(ANDROID)
+ void clearDirtyRect() { m_dirtyRect = FloatRect(); }
#endif
private:
diff --git a/Source/WebCore/html/HTMLDocument.cpp b/Source/WebCore/html/HTMLDocument.cpp
index dd41514..a1be93d 100644
--- a/Source/WebCore/html/HTMLDocument.cpp
+++ b/Source/WebCore/html/HTMLDocument.cpp
@@ -438,26 +438,4 @@ bool HTMLDocument::isFrameSet() const
return bodyElement && bodyElement->hasTagName(framesetTag);
}
-#ifdef ANDROID_INSTRUMENT
-void* HTMLDocument::operator new(size_t size)
-{
- return Node::operator new(size);
-}
-
-void* HTMLDocument::operator new[](size_t size)
-{
- return Node::operator new[](size);
-}
-
-void HTMLDocument::operator delete(void* p, size_t size)
-{
- Node::operator delete(p, size);
-}
-
-void HTMLDocument::operator delete[](void* p, size_t size)
-{
- Node::operator delete[](p, size);
-}
-#endif
-
}
diff --git a/Source/WebCore/html/HTMLDocument.h b/Source/WebCore/html/HTMLDocument.h
index 3310b71..d39f392 100644
--- a/Source/WebCore/html/HTMLDocument.h
+++ b/Source/WebCore/html/HTMLDocument.h
@@ -82,14 +82,6 @@ public:
protected:
HTMLDocument(Frame*, const KURL&);
-#ifdef ANDROID_INSTRUMENT
- // Overridden to resolve the ambiguous
- void* operator new(size_t size);
- void* operator new[](size_t size);
- void operator delete(void* p, size_t size);
- void operator delete[](void* p, size_t size);
-#endif
-
private:
virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index 7cbf38b..4673109 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -504,28 +504,6 @@ void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
styleSheet->addSubresourceStyleURLs(urls);
}
-#ifdef ANDROID_INSTRUMENT
-void* HTMLLinkElement::operator new(size_t size)
-{
- return Node::operator new(size);
-}
-
-void* HTMLLinkElement::operator new[](size_t size)
-{
- return Node::operator new[](size);
-}
-
-void HTMLLinkElement::operator delete(void* p, size_t size)
-{
- Node::operator delete(p, size);
-}
-
-void HTMLLinkElement::operator delete[](void* p, size_t size)
-{
- Node::operator delete[](p, size);
-}
-#endif
-
void HTMLLinkElement::addPendingSheet(PendingSheetType type)
{
if (type <= m_pendingSheetType)
diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h
index f602d38..1a6eba9 100644
--- a/Source/WebCore/html/HTMLLinkElement.h
+++ b/Source/WebCore/html/HTMLLinkElement.h
@@ -120,14 +120,6 @@ private:
void addPendingSheet(PendingSheetType);
void removePendingSheet();
-#ifdef ANDROID_INSTRUMENT
- // Overridden to resolve the ambiguous
- void* operator new(size_t size);
- void* operator new[](size_t size);
- void operator delete(void* p, size_t size);
- void operator delete[](void* p, size_t size);
-#endif
-
private:
HTMLLinkElement(const QualifiedName&, Document*, bool createdByParser);
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 023e8d2..5cd2ddd 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -178,6 +178,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
, m_completelyLoaded(false)
#if PLATFORM(ANDROID)
, m_lastTouch(0)
+ , m_userGestureInitiated(false)
#endif
{
LOG(Media, "HTMLMediaElement::HTMLMediaElement");
@@ -187,8 +188,8 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
// Enable the Media Element to listen to all the touch events
document->addListenerTypeIfNeeded(eventNames().touchstartEvent);
+ m_restrictions |= RequireUserGestureForRateChangeRestriction;
#endif
-
}
HTMLMediaElement::~HTMLMediaElement()
@@ -515,6 +516,9 @@ void HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
ec = INVALID_STATE_ERR;
else {
m_loadInitiatedByUserGesture = isUserGesture;
+#if PLATFORM(ANDROID)
+ m_userGestureInitiated |= isUserGesture;
+#endif
prepareForLoad();
loadInternal();
}
@@ -1417,9 +1421,19 @@ void HTMLMediaElement::play(bool isUserGesture)
{
LOG(Media, "HTMLMediaElement::play(isUserGesture : %s)", boolString(isUserGesture));
- if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture
+#if PLATFORM(ANDROID)
+ && !m_userGestureInitiated
+#endif
+ )
return;
+#if PLATFORM(ANDROID)
+ // B/c we set the restriction to require gesture for rate change for
+ // Android, when we don't early return, we can safely set this to true.
+ m_userGestureInitiated = true;
+#endif
+
Document* doc = document();
Settings* settings = doc->settings();
if (settings && settings->needsSiteSpecificQuirks() && m_dispatchingCanPlayEvent && !m_loadInitiatedByUserGesture) {
@@ -1466,9 +1480,17 @@ void HTMLMediaElement::pause(bool isUserGesture)
{
LOG(Media, "HTMLMediaElement::pause(isUserGesture : %s)", boolString(isUserGesture));
- if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture
+#if PLATFORM(ANDROID)
+ && !m_userGestureInitiated
+#endif
+ )
return;
-
+#if PLATFORM(ANDROID)
+ // B/c we set the restriction to require gesture for rate change for
+ // Android, when we don't early return, we can safely set this to true.
+ m_userGestureInitiated = true;
+#endif
pauseInternal();
}
@@ -2402,6 +2424,15 @@ void HTMLMediaElement::defaultEventHandler(Event* event)
}
#endif
+#if PLATFORM(ANDROID)
+ // It is really hard to hit the play/pause button on mobile devices.
+ // This allows user to click the video area to toggle play/pause state.
+ if (event->type() == eventNames().clickEvent
+ && !hasEventListeners(eventNames().clickEvent)) {
+ m_userGestureInitiated = processingUserGesture();
+ togglePlayState();
+ }
+#endif
HTMLElement::defaultEventHandler(event);
#endif
}
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 987cf87..2144ea1 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -420,6 +420,10 @@ private:
#if PLATFORM(ANDROID)
double m_lastTouch;
+ // When user gesture invoke load, play or pause, this turns to be true.
+ // After this becomes true, we ignore the user gesture requirement for play
+ // and pause.
+ bool m_userGestureInitiated;
#endif
};
diff --git a/Source/WebCore/html/canvas/ArrayBufferView.h b/Source/WebCore/html/canvas/ArrayBufferView.h
index 701abbc..d06fc8d 100644
--- a/Source/WebCore/html/canvas/ArrayBufferView.h
+++ b/Source/WebCore/html/canvas/ArrayBufferView.h
@@ -46,6 +46,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
virtual bool isIntArray() const { return false; }
virtual bool isUnsignedIntArray() const { return false; }
virtual bool isFloatArray() const { return false; }
+ virtual bool isDoubleArray() const { return false; }
virtual bool isDataView() const { return false; }
PassRefPtr<ArrayBuffer> buffer() const
diff --git a/Source/WebCore/html/canvas/Float64Array.cpp b/Source/WebCore/html/canvas/Float64Array.cpp
new file mode 100644
index 0000000..2dcb373
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float64Array.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * 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 "Float64Array.h"
+
+namespace WebCore {
+
+PassRefPtr<Float64Array> Float64Array::create(unsigned length)
+{
+ return TypedArrayBase<double>::create<Float64Array>(length);
+}
+
+PassRefPtr<Float64Array> Float64Array::create(const double* array, unsigned length)
+{
+ return TypedArrayBase<double>::create<Float64Array>(array, length);
+}
+
+PassRefPtr<Float64Array> Float64Array::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<double>::create<Float64Array>(buffer, byteOffset, length);
+}
+
+Float64Array::Float64Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : TypedArrayBase<double>(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Float64Array> Float64Array::subarray(int start) const
+{
+ return subarray(start, length());
+}
+
+PassRefPtr<Float64Array> Float64Array::subarray(int start, int end) const
+{
+ return subarrayImpl<Float64Array>(start, end);
+}
+
+}
diff --git a/Source/WebCore/html/canvas/Float64Array.h b/Source/WebCore/html/canvas/Float64Array.h
new file mode 100644
index 0000000..f45a21c
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float64Array.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * 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 Float64Array_h
+#define Float64Array_h
+
+#include "TypedArrayBase.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+class Float64Array : public TypedArrayBase<double> {
+public:
+ static PassRefPtr<Float64Array> create(unsigned length);
+ static PassRefPtr<Float64Array> create(const double* array, unsigned length);
+ static PassRefPtr<Float64Array> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
+
+ using TypedArrayBase<double>::set;
+
+ void set(unsigned index, double value)
+ {
+ if (index >= TypedArrayBase<double>::m_length)
+ return;
+ TypedArrayBase<double>::data()[index] = static_cast<double>(value);
+ }
+
+ // Invoked by the indexed getter. Does not perform range checks; caller
+ // is responsible for doing so and returning undefined as necessary.
+ double item(unsigned index) const
+ {
+ ASSERT(index < TypedArrayBase<double>::m_length);
+ double result = TypedArrayBase<double>::data()[index];
+ return result;
+ }
+
+ PassRefPtr<Float64Array> subarray(int start) const;
+ PassRefPtr<Float64Array> subarray(int start, int end) const;
+
+private:
+ Float64Array(PassRefPtr<ArrayBuffer>,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<double>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isDoubleArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Float64Array_h
diff --git a/Source/WebCore/html/canvas/Float64Array.idl b/Source/WebCore/html/canvas/Float64Array.idl
new file mode 100644
index 0000000..6057253
--- /dev/null
+++ b/Source/WebCore/html/canvas/Float64Array.idl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * 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.
+ */
+
+module html {
+ interface [
+ CanBeConstructed,
+ CustomConstructFunction,
+ V8CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Float64Array : ArrayBufferView {
+ const unsigned int BYTES_PER_ELEMENT = 8;
+
+ readonly attribute unsigned long length;
+ Float64Array subarray(in long start, in [Optional] long end);
+
+ // void set(in Float64Array array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/parser/HTMLDocumentParser.cpp b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
index 8f95cc5..46dddf0 100644
--- a/Source/WebCore/html/parser/HTMLDocumentParser.cpp
+++ b/Source/WebCore/html/parser/HTMLDocumentParser.cpp
@@ -41,10 +41,6 @@
#include "NestingLevelIncrementer.h"
#include "Settings.h"
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#endif
-
namespace WebCore {
using namespace HTMLNames;
@@ -318,10 +314,6 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
if (isStopped())
return;
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::start(android::TimeCounter::ParsingTimeCounter);
-#endif
-
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
RefPtr<HTMLDocumentParser> protect(this);
@@ -369,18 +361,12 @@ void HTMLDocumentParser::append(const SegmentedString& source)
// We've gotten data off the network in a nested write.
// We don't want to consume any more of the input stream now. Do
// not worry. We'll consume this data in a less-nested write().
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::ParsingTimeCounter, __FUNCTION__);
-#endif
return;
}
pumpTokenizerIfPossible(AllowYield);
endIfDelayed();
-#ifdef ANDROID_INSTRUMENT
- android::TimeCounter::record(android::TimeCounter::ParsingTimeCounter, __FUNCTION__);
-#endif
}
void HTMLDocumentParser::end()
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 85b1541..f999fdb 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -119,11 +119,6 @@
#include "ArchiveFactory.h"
#endif
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#include "RenderArena.h"
-#endif
-
namespace WebCore {
using namespace HTMLNames;
@@ -1114,11 +1109,7 @@ void FrameLoader::handleFallbackContent()
}
void FrameLoader::provisionalLoadStarted()
-{
-#ifdef ANDROID_INSTRUMENT
- if (!m_frame->tree()->parent())
- android::TimeCounter::reset();
-#endif
+{
if (m_stateMachine.firstLayoutDone())
m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
m_frame->navigationScheduler()->cancel(true);
@@ -2308,7 +2299,7 @@ void FrameLoader::finishedLoadingDocument(DocumentLoader* loader)
if (m_stateMachine.creatingInitialEmptyDocument())
return;
#endif
-
+
#if !ENABLE(WEB_ARCHIVE)
m_client->finishedLoading(loader);
#else
@@ -2499,12 +2490,6 @@ void FrameLoader::checkLoadCompleteForThisFrame()
if (Page* page = m_frame->page())
page->progress()->progressCompleted(m_frame);
-
-#ifdef ANDROID_INSTRUMENT
- if (!m_frame->tree()->parent() && m_frame->document()->renderArena())
- android::TimeCounter::report(m_URL, cache()->getLiveSize(), cache()->getDeadSize(),
- m_frame->document()->renderArena()->reportPoolSize());
-#endif
return;
}
diff --git a/Source/WebCore/loader/archive/android/WebArchiveAndroid.cpp b/Source/WebCore/loader/archive/android/WebArchiveAndroid.cpp
index 55d7cec..5f60163 100644
--- a/Source/WebCore/loader/archive/android/WebArchiveAndroid.cpp
+++ b/Source/WebCore/loader/archive/android/WebArchiveAndroid.cpp
@@ -36,6 +36,7 @@
#include <libxml/tree.h>
#include <libxml/xmlstring.h>
#include <libxml/xmlwriter.h>
+#include <utils/Log.h>
#include <wtf/text/CString.h>
namespace WebCore {
@@ -117,7 +118,7 @@ static bool loadArchiveResourceField(xmlNodePtr resourceNode, const xmlChar* fie
}
}
if (!base64Data) {
- LOGD("loadArchiveResourceField: Failed to load field.");
+ ALOGD("loadArchiveResourceField: Failed to load field.");
return false;
}
@@ -125,7 +126,7 @@ static bool loadArchiveResourceField(xmlNodePtr resourceNode, const xmlChar* fie
const int result = base64Decode(base64Data, base64Size, *outputData);
if (!result) {
- LOGD("loadArchiveResourceField: Failed to decode field.");
+ ALOGD("loadArchiveResourceField: Failed to decode field.");
return false;
}
@@ -165,37 +166,37 @@ static KURL loadArchiveResourceFieldURL(xmlNodePtr resourceNode, const xmlChar*
static PassRefPtr<ArchiveResource> loadArchiveResource(xmlNodePtr resourceNode)
{
if (!xmlStrEqual(resourceNode->name, archiveResourceTag)) {
- LOGD("loadArchiveResource: Malformed resource.");
+ ALOGD("loadArchiveResource: Malformed resource.");
return 0;
}
KURL url = loadArchiveResourceFieldURL(resourceNode, urlFieldTag);
if (url.isNull()) {
- LOGD("loadArchiveResource: Failed to load resource.");
+ ALOGD("loadArchiveResource: Failed to load resource.");
return 0;
}
String mimeType = loadArchiveResourceFieldString(resourceNode, mimeFieldTag);
if (mimeType.isNull()) {
- LOGD("loadArchiveResource: Failed to load resource.");
+ ALOGD("loadArchiveResource: Failed to load resource.");
return 0;
}
String textEncoding = loadArchiveResourceFieldString(resourceNode, encodingFieldTag);
if (textEncoding.isNull()) {
- LOGD("loadArchiveResource: Failed to load resource.");
+ ALOGD("loadArchiveResource: Failed to load resource.");
return 0;
}
String frameName = loadArchiveResourceFieldString(resourceNode, frameFieldTag);
if (frameName.isNull()) {
- LOGD("loadArchiveResource: Failed to load resource.");
+ ALOGD("loadArchiveResource: Failed to load resource.");
return 0;
}
PassRefPtr<SharedBuffer> data = loadArchiveResourceFieldBuffer(resourceNode, dataFieldTag);
if (!data) {
- LOGD("loadArchiveResource: Failed to load resource.");
+ ALOGD("loadArchiveResource: Failed to load resource.");
return 0;
}
@@ -211,7 +212,7 @@ static PassRefPtr<WebArchiveAndroid> loadArchive(xmlNodePtr archiveNode)
Vector<PassRefPtr<Archive> > subframes;
if (!xmlStrEqual(archiveNode->name, archiveTag)) {
- LOGD("loadArchive: Malformed archive.");
+ ALOGD("loadArchive: Malformed archive.");
return 0;
}
@@ -227,7 +228,7 @@ static PassRefPtr<WebArchiveAndroid> loadArchive(xmlNodePtr archiveNode)
}
}
if (!mainResource) {
- LOGD("loadArchive: Failed to load main resource.");
+ ALOGD("loadArchive: Failed to load main resource.");
return 0;
}
@@ -240,7 +241,7 @@ static PassRefPtr<WebArchiveAndroid> loadArchive(xmlNodePtr archiveNode)
resourceNode = resourceNode->next) {
PassRefPtr<ArchiveResource> subresource = loadArchiveResource(resourceNode);
if (!subresource) {
- LOGD("loadArchive: Failed to load subresource.");
+ ALOGD("loadArchive: Failed to load subresource.");
break;
}
subresources.append(subresource);
@@ -258,7 +259,7 @@ static PassRefPtr<WebArchiveAndroid> loadArchive(xmlNodePtr archiveNode)
resourceNode = resourceNode->next) {
PassRefPtr<WebArchiveAndroid> subframe = loadArchive(resourceNode);
if (!subframe) {
- LOGD("loadArchive: Failed to load subframe.");
+ ALOGD("loadArchive: Failed to load subframe.");
break;
}
subframes.append(subframe);
@@ -290,20 +291,20 @@ PassRefPtr<WebArchiveAndroid> WebArchiveAndroid::create(SharedBuffer* buffer)
xmlDocPtr doc = xmlReadMemory(buffer->data(), buffer->size(), noBaseUrl, defaultEncoding, noParserOptions);
if (!doc) {
- LOGD("create: Failed to parse document.");
+ ALOGD("create: Failed to parse document.");
return createArchiveForError();
}
xmlNodePtr root = xmlDocGetRootElement(doc);
if (!root) {
- LOGD("create: Empty document.");
+ ALOGD("create: Empty document.");
xmlFreeDoc(doc);
return createArchiveForError();
}
RefPtr<WebArchiveAndroid> archive = loadArchive(root);
if (!archive) {
- LOGD("create: Failed to load archive.");
+ ALOGD("create: Failed to load archive.");
xmlFreeDoc(doc);
return createArchiveForError();
}
@@ -316,7 +317,7 @@ static bool saveArchiveResourceField(xmlTextWriterPtr writer, const xmlChar* tag
{
int result = xmlTextWriterStartElement(writer, tag);
if (result < 0) {
- LOGD("saveArchiveResourceField: Failed to start element.");
+ ALOGD("saveArchiveResourceField: Failed to start element.");
return false;
}
@@ -324,20 +325,20 @@ static bool saveArchiveResourceField(xmlTextWriterPtr writer, const xmlChar* tag
Vector<char> base64Data;
base64Encode(data, size, base64Data, false);
if (base64Data.isEmpty()) {
- LOGD("saveArchiveResourceField: Failed to base64 encode data.");
+ ALOGD("saveArchiveResourceField: Failed to base64 encode data.");
return false;
}
result = xmlTextWriterWriteRawLen(writer, BAD_CAST base64Data.data(), base64Data.size());
if (result < 0) {
- LOGD("saveArchiveResourceField: Failed to write data.");
+ ALOGD("saveArchiveResourceField: Failed to write data.");
return false;
}
}
result = xmlTextWriterEndElement(writer);
if (result < 0) {
- LOGD("saveArchiveResourceField: Failed to end element.");
+ ALOGD("saveArchiveResourceField: Failed to end element.");
return false;
}
@@ -360,7 +361,7 @@ static bool saveArchiveResource(xmlTextWriterPtr writer, PassRefPtr<ArchiveResou
{
int result = xmlTextWriterStartElement(writer, archiveResourceTag);
if (result < 0) {
- LOGD("saveArchiveResource: Failed to start element.");
+ ALOGD("saveArchiveResource: Failed to start element.");
return false;
}
@@ -373,7 +374,7 @@ static bool saveArchiveResource(xmlTextWriterPtr writer, PassRefPtr<ArchiveResou
result = xmlTextWriterEndElement(writer);
if (result < 0) {
- LOGD("saveArchiveResource: Failed to end element.");
+ ALOGD("saveArchiveResource: Failed to end element.");
return false;
}
@@ -384,13 +385,13 @@ static bool saveArchive(xmlTextWriterPtr writer, PassRefPtr<Archive> archive)
{
int result = xmlTextWriterStartElement(writer, archiveTag);
if (result < 0) {
- LOGD("saveArchive: Failed to start element.");
+ ALOGD("saveArchive: Failed to start element.");
return false;
}
result = xmlTextWriterStartElement(writer, mainResourceTag);
if (result < 0) {
- LOGD("saveArchive: Failed to start element.");
+ ALOGD("saveArchive: Failed to start element.");
return false;
}
@@ -399,13 +400,13 @@ static bool saveArchive(xmlTextWriterPtr writer, PassRefPtr<Archive> archive)
result = xmlTextWriterEndElement(writer);
if (result < 0) {
- LOGD("saveArchive: Failed to end element.");
+ ALOGD("saveArchive: Failed to end element.");
return false;
}
result = xmlTextWriterStartElement(writer, subresourcesTag);
if (result < 0) {
- LOGD("saveArchive: Failed to start element.");
+ ALOGD("saveArchive: Failed to start element.");
return false;
}
@@ -418,13 +419,13 @@ static bool saveArchive(xmlTextWriterPtr writer, PassRefPtr<Archive> archive)
result = xmlTextWriterEndElement(writer);
if (result < 0) {
- LOGD("saveArchive: Failed to end element.");
+ ALOGD("saveArchive: Failed to end element.");
return false;
}
result = xmlTextWriterStartElement(writer, subframesTag);
if (result < 0) {
- LOGD("saveArchive: Failed to start element.");
+ ALOGD("saveArchive: Failed to start element.");
return false;
}
@@ -437,7 +438,7 @@ static bool saveArchive(xmlTextWriterPtr writer, PassRefPtr<Archive> archive)
result = xmlTextWriterEndElement(writer);
if (result < 0) {
- LOGD("saveArchive: Failed to end element.");
+ ALOGD("saveArchive: Failed to end element.");
return true;
}
@@ -452,7 +453,7 @@ bool WebArchiveAndroid::saveWebArchive(xmlTextWriterPtr writer)
int result = xmlTextWriterStartDocument(writer, defaultXmlVersion, defaultEncoding, defaultStandalone);
if (result < 0) {
- LOGD("saveWebArchive: Failed to start document.");
+ ALOGD("saveWebArchive: Failed to start document.");
return false;
}
@@ -461,7 +462,7 @@ bool WebArchiveAndroid::saveWebArchive(xmlTextWriterPtr writer)
result = xmlTextWriterEndDocument(writer);
if (result< 0) {
- LOGD("saveWebArchive: Failed to end document.");
+ ALOGD("saveWebArchive: Failed to end document.");
return false;
}
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/loader/cache/MemoryCache.h b/Source/WebCore/loader/cache/MemoryCache.h
index a092eac..c9b91f9 100644
--- a/Source/WebCore/loader/cache/MemoryCache.h
+++ b/Source/WebCore/loader/cache/MemoryCache.h
@@ -171,12 +171,6 @@ public:
void removeResourcesWithOrigin(SecurityOrigin*);
void getOriginsWithCache(SecurityOriginSet& origins);
-#ifdef ANDROID_INSTRUMENT
- unsigned getLiveSize() { return m_liveSize; }
- unsigned getDeadSize() { return m_deadSize; }
-#endif
-
-
private:
MemoryCache();
~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
diff --git a/Source/WebCore/loader/icon/IconDatabase.cpp b/Source/WebCore/loader/icon/IconDatabase.cpp
index 3cefea7..2bb22ec 100644
--- a/Source/WebCore/loader/icon/IconDatabase.cpp
+++ b/Source/WebCore/loader/icon/IconDatabase.cpp
@@ -73,7 +73,7 @@ static const int updateTimerDelay = 5;
static bool checkIntegrityOnOpen = false;
-#ifndef NDEBUG
+#if !LOG_DISABLED || !ERROR_DISABLED
static String urlForLogging(const String& url)
{
static unsigned urlTruncationLength = 120;
@@ -967,7 +967,7 @@ void* IconDatabase::iconDatabaseSyncThread()
LOG(IconDatabase, "(THREAD) IconDatabase sync thread started");
-#ifndef NDEBUG
+#if !LOG_DISABLED
double startTime = currentTime();
#endif
@@ -993,7 +993,7 @@ void* IconDatabase::iconDatabaseSyncThread()
if (shouldStopThreadActivity())
return syncThreadMainLoop();
-#ifndef NDEBUG
+#if !LOG_DISABLED
double timeStamp = currentTime();
LOG(IconDatabase, "(THREAD) Open took %.4f seconds", timeStamp - startTime);
#endif
@@ -1002,7 +1002,7 @@ void* IconDatabase::iconDatabaseSyncThread()
if (shouldStopThreadActivity())
return syncThreadMainLoop();
-#ifndef NDEBUG
+#if !LOG_DISABLED
double newStamp = currentTime();
LOG(IconDatabase, "(THREAD) performOpenInitialization() took %.4f seconds, now %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime);
timeStamp = newStamp;
@@ -1025,7 +1025,7 @@ void* IconDatabase::iconDatabaseSyncThread()
if (shouldStopThreadActivity())
return syncThreadMainLoop();
-#ifndef NDEBUG
+#if !LOG_DISABLED
newStamp = currentTime();
LOG(IconDatabase, "(THREAD) performImport() took %.4f seconds, now %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime);
timeStamp = newStamp;
@@ -1042,7 +1042,7 @@ void* IconDatabase::iconDatabaseSyncThread()
if (shouldStopThreadActivity())
return syncThreadMainLoop();
-#ifndef NDEBUG
+#if !LOG_DISABLED
newStamp = currentTime();
LOG(IconDatabase, "(THREAD) performURLImport() took %.4f seconds. Entering main loop %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime);
#endif
@@ -1358,7 +1358,7 @@ void* IconDatabase::syncThreadMainLoop()
while (!m_threadTerminationRequested) {
m_syncLock.unlock();
-#ifndef NDEBUG
+#if !LOG_DISABLED
double timeStamp = currentTime();
#endif
LOG(IconDatabase, "(THREAD) Main work loop starting");
@@ -1391,7 +1391,7 @@ void* IconDatabase::syncThreadMainLoop()
// has asked to delay pruning
static bool prunedUnretainedIcons = false;
if (didWrite && !m_privateBrowsingEnabled && !prunedUnretainedIcons && !databaseCleanupCounter) {
-#ifndef NDEBUG
+#if !LOG_DISABLED
double time = currentTime();
#endif
LOG(IconDatabase, "(THREAD) Starting pruneUnretainedIcons()");
@@ -1410,7 +1410,7 @@ void* IconDatabase::syncThreadMainLoop()
break;
}
-#ifndef NDEBUG
+#if !LOG_DISABLED
double newstamp = currentTime();
LOG(IconDatabase, "(THREAD) Main work loop ran for %.4f seconds, %s requested to terminate", newstamp - timeStamp, shouldStopThreadActivity() ? "was" : "was not");
#endif
@@ -1458,7 +1458,7 @@ bool IconDatabase::readFromDatabase()
{
ASSERT_ICON_SYNC_THREAD();
-#ifndef NDEBUG
+#if !LOG_DISABLED
double timeStamp = currentTime();
#endif
@@ -1567,7 +1567,7 @@ bool IconDatabase::writeToDatabase()
{
ASSERT_ICON_SYNC_THREAD();
-#ifndef NDEBUG
+#if !LOG_DISABLED
double timeStamp = currentTime();
#endif
@@ -1772,7 +1772,7 @@ void* IconDatabase::cleanupSyncThread()
{
ASSERT_ICON_SYNC_THREAD();
-#ifndef NDEBUG
+#if !LOG_DISABLED
double timeStamp = currentTime();
#endif
@@ -1792,7 +1792,7 @@ void* IconDatabase::cleanupSyncThread()
deleteAllPreparedStatements();
m_syncDB.close();
-#ifndef NDEBUG
+#if !LOG_DISABLED
LOG(IconDatabase, "(THREAD) Final closure took %.4f seconds", currentTime() - timeStamp);
#endif
diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp
index c7f162a..ee2206b 100644
--- a/Source/WebCore/page/DOMWindow.cpp
+++ b/Source/WebCore/page/DOMWindow.cpp
@@ -1095,11 +1095,7 @@ int DOMWindow::innerHeight() const
if (!view)
return 0;
-#if PLATFORM(ANDROID)
- return static_cast<int>(view->actualHeight() / m_frame->pageZoomFactor());
-#else
return static_cast<int>(view->height() / m_frame->pageZoomFactor());
-#endif
}
int DOMWindow::innerWidth() const
@@ -1111,11 +1107,7 @@ int DOMWindow::innerWidth() const
if (!view)
return 0;
-#if PLATFORM(ANDROID)
- return static_cast<int>(view->actualWidth() / m_frame->pageZoomFactor());
-#else
return static_cast<int>(view->width() / m_frame->pageZoomFactor());
-#endif
}
int DOMWindow::screenX() const
@@ -1153,11 +1145,7 @@ int DOMWindow::scrollX() const
m_frame->document()->updateLayoutIgnorePendingStylesheets();
-#if PLATFORM(ANDROID)
- return static_cast<int>(view->actualScrollX() / m_frame->pageZoomFactor());
-#else
return static_cast<int>(view->scrollX() / m_frame->pageZoomFactor());
-#endif
}
int DOMWindow::scrollY() const
@@ -1171,11 +1159,7 @@ int DOMWindow::scrollY() const
m_frame->document()->updateLayoutIgnorePendingStylesheets();
-#if PLATFORM(ANDROID)
- return static_cast<int>(view->actualScrollY() / m_frame->pageZoomFactor());
-#else
return static_cast<int>(view->scrollY() / m_frame->pageZoomFactor());
-#endif
}
bool DOMWindow::closed() const
diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl
index 9f7313c..d5d3413 100644
--- a/Source/WebCore/page/DOMWindow.idl
+++ b/Source/WebCore/page/DOMWindow.idl
@@ -510,6 +510,7 @@ module window {
attribute [JSCCustomGetter] Int32ArrayConstructor Int32Array; // Usable with new operator
attribute [JSCCustomGetter] Uint32ArrayConstructor Uint32Array; // Usable with new operator
attribute [JSCCustomGetter] Float32ArrayConstructor Float32Array; // Usable with new operator
+ attribute [JSCCustomGetter] Float64ArrayConstructor Float64Array; // Usable with new operator
attribute [JSCCustomGetter] DataViewConstructor DataView; // Usable with new operator
attribute [JSCCustomGetter,Conditional=WEB_AUDIO,EnabledAtRuntime] AudioContextConstructor webkitAudioContext; // Usable with new operator
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index e77809c..a737754 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -2415,16 +2415,10 @@ static Node* eventTargetNodeForDocument(Document* doc)
if (!doc)
return 0;
Node* node = doc->focusedNode();
-#if defined(ANDROID_PLUGINS)
- if (!node && doc->frame() && doc->frame()->view())
- node = android::WebViewCore::getWebViewCore(doc->frame()->view())
- ->cursorNodeIsPlugin();
-#else
if (!node && doc->isPluginDocument()) {
PluginDocument* pluginDocument = static_cast<PluginDocument*>(doc);
node = pluginDocument->pluginNode();
}
-#endif
if (!node && doc->isHTMLDocument())
node = doc->body();
if (!node)
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
index 8a1ad69..049f08b 100644
--- a/Source/WebCore/page/Frame.cpp
+++ b/Source/WebCore/page/Frame.cpp
@@ -113,10 +113,6 @@
#include "WMLNames.h"
#endif
-#if PLATFORM(ANDROID)
-#include "WebViewCore.h"
-#endif
-
using namespace std;
namespace WebCore {
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 49a7d0c..8f2958c 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -62,11 +62,6 @@
#include "TextResourceDecoder.h"
#include <wtf/CurrentTime.h>
-#ifdef ANDROID_INSTRUMENT
-#include "FrameTree.h"
-#include "TimeCounter.h"
-#endif
-
#if USE(ACCELERATED_COMPOSITING)
#include "RenderLayerCompositor.h"
#endif
@@ -872,11 +867,6 @@ void FrameView::layout(bool allowSubtree)
return;
}
-#ifdef ANDROID_INSTRUMENT
- if (!m_frame->tree() || !m_frame->tree()->parent())
- android::TimeCounter::start(android::TimeCounter::LayoutTimeCounter);
-#endif
-
m_nestedLayoutCount++;
if (!m_layoutRoot) {
@@ -1014,10 +1004,6 @@ void FrameView::layout(bool allowSubtree)
updateDashboardRegions();
#endif
-#ifdef ANDROID_INSTRUMENT
- if (!m_frame->tree()->parent())
- android::TimeCounter::record(android::TimeCounter::LayoutTimeCounter, __FUNCTION__);
-#endif
ASSERT(!root->needsLayout());
updateCanBlitOnScrollRecursively();
@@ -1752,11 +1738,6 @@ void FrameView::scheduleRelayout()
if (!m_frame->document()->shouldScheduleLayout())
return;
-#ifdef ANDROID_FLATTEN_FRAMESET
- if (m_frame->ownerRenderer())
- m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
-#endif
-
// When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
// Also invalidate parent frame starting from the owner element of this frame.
if (m_frame->settings() && m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
@@ -1764,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 e2312a9..f668f3e 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -98,6 +98,7 @@ Settings::Settings(Page* page)
#ifdef ANDROID_LAYOUT
, m_layoutAlgorithm(kLayoutFitColumnToScreen)
#endif
+ , m_passwordEchoDurationInSeconds(1)
, m_isSpatialNavigationEnabled(false)
, m_isJavaEnabled(false)
, m_loadsImagesAutomatically(false)
@@ -148,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)
@@ -192,6 +196,11 @@ Settings::Settings(Page* page)
#ifdef ANDROID_PLUGINS
, m_pluginsOnDemand(false)
#endif
+#if OS(SYMBIAN)
+ , m_passwordEchoEnabled(true)
+#else
+ , m_passwordEchoEnabled(false)
+#endif
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -817,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 31a5ad9..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; }
@@ -458,6 +463,12 @@ namespace WebCore {
void setShouldInjectUserScriptsInInitialEmptyDocument(bool flag) { m_shouldInjectUserScriptsInInitialEmptyDocument = flag; }
bool shouldInjectUserScriptsInInitialEmptyDocument() { return m_shouldInjectUserScriptsInInitialEmptyDocument; }
+ void setPasswordEchoEnabled(bool flag) { m_passwordEchoEnabled = flag; }
+ bool passwordEchoEnabled() const { return m_passwordEchoEnabled; }
+
+ void setPasswordEchoDurationInSeconds(double durationInSeconds) { m_passwordEchoDurationInSeconds = durationInSeconds; }
+ double passwordEchoDurationInSeconds() const { return m_passwordEchoDurationInSeconds; }
+
#if ENABLE(WEB_AUTOFILL)
void setAutoFillEnabled(bool flag) { m_autoFillEnabled = flag; }
bool autoFillEnabled() { return m_autoFillEnabled; }
@@ -511,6 +522,8 @@ namespace WebCore {
#ifdef ANDROID_LAYOUT
LayoutAlgorithm m_layoutAlgorithm;
#endif
+ double m_passwordEchoDurationInSeconds;
+
bool m_isSpatialNavigationEnabled : 1;
bool m_isJavaEnabled : 1;
bool m_loadsImagesAutomatically : 1;
@@ -559,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;
@@ -617,6 +633,7 @@ namespace WebCore {
#ifdef ANDROID_PLUGINS
bool m_pluginsOnDemand : 1;
#endif
+ bool m_passwordEchoEnabled : 1;
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
diff --git a/Source/WebCore/platform/Arena.cpp b/Source/WebCore/platform/Arena.cpp
index 231e1b6..33980ed 100644
--- a/Source/WebCore/platform/Arena.cpp
+++ b/Source/WebCore/platform/Arena.cpp
@@ -255,16 +255,4 @@ void FinishArenaPool(ArenaPool *pool)
FreeArenaList(pool, &pool->first, true);
}
-#ifdef ANDROID_INSTRUMENT
-size_t ReportPoolSize(const ArenaPool* pool)
-{
- size_t total = 0;
- for (const Arena *a = &pool->first; a; a = a->next)
- total += (a->limit - a->base);
- for (const Arena *fa = arena_freelist; fa; fa = fa->next )
- total += (fa->limit - fa->base);
- return total;
-}
-#endif
-
}
diff --git a/Source/WebCore/platform/Arena.h b/Source/WebCore/platform/Arena.h
index e937955..06e09f2 100644
--- a/Source/WebCore/platform/Arena.h
+++ b/Source/WebCore/platform/Arena.h
@@ -134,10 +134,6 @@ void* ArenaAllocate(ArenaPool *pool, unsigned int nb);
fastFree(a); \
(a) = 0;
-#ifdef ANDROID_INSTRUMENT
-size_t ReportPoolSize(const ArenaPool* pool);
-#endif
-
}
#endif
diff --git a/Source/WebCore/platform/NotImplemented.h b/Source/WebCore/platform/NotImplemented.h
index a71e99c..e9758b0 100644
--- a/Source/WebCore/platform/NotImplemented.h
+++ b/Source/WebCore/platform/NotImplemented.h
@@ -38,21 +38,7 @@
#define supressNotImplementedWarning() false
#endif
-#if OS(ANDROID)
-
-#include <cutils/log.h>
-#ifndef LOG_TAG
-#define LOG_TAG "WebCore"
-#endif
-#define notImplemented() do { \
- static bool havePrinted = false; \
- if (!havePrinted && !supressNotImplementedWarning()) { \
- LOGV("%s: notImplemented", __PRETTY_FUNCTION__); \
- havePrinted = true; \
- } \
- } while (0)
-
-#elif defined(NDEBUG)
+#if defined(NDEBUG)
#define notImplemented() ((void)0)
#else
diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp
index e79f049..140c8e5 100644
--- a/Source/WebCore/platform/ScrollView.cpp
+++ b/Source/WebCore/platform/ScrollView.cpp
@@ -27,6 +27,13 @@
#include "ScrollView.h"
#include "AXObjectCache.h"
+#if PLATFORM(ANDROID)
+#include "FrameView.h"
+#include "GraphicsLayerAndroid.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#include "RenderView.h"
+#endif
#include "GraphicsContext.h"
#include "GraphicsLayer.h"
#include "HostWindow.h"
@@ -301,32 +308,12 @@ void ScrollView::setContentsSize(const IntSize& newSize)
}
#if PLATFORM(ANDROID)
-int ScrollView::actualWidth() const
-{
- if (platformWidget())
- return platformActualWidth();
- return width();
-}
-
-int ScrollView::actualHeight() const
-{
- if (platformWidget())
- return platformActualHeight();
- return height();
-}
-
-int ScrollView::actualScrollX() const
-{
- if (platformWidget())
- return platformActualScrollX();
- return scrollX();
-}
-
-int ScrollView::actualScrollY() const
-{
- if (platformWidget())
- return platformActualScrollY();
- return scrollY();
+FrameView* ScrollView::frameView() {
+ if (this->isFrameView()) {
+ FrameView* frameView = reinterpret_cast<FrameView*>(this);
+ return frameView;
+ }
+ return 0;
}
#endif
@@ -386,6 +373,26 @@ void ScrollView::scrollTo(const IntSize& newOffset)
return;
m_scrollOffset = newOffset;
+#if PLATFORM(ANDROID)
+ if (parent()) {
+ FrameView* frameView = this->frameView();
+ // IFrames are composited on a layer, we do not need to repaint them
+ // when scrolling
+ if (frameView) {
+ RenderView* renderer = frameView->frame()->contentRenderer();
+ if (renderer) {
+ RenderLayer* layer = renderer->layer();
+ if (layer->backing()) {
+ GraphicsLayerAndroid* backing = static_cast<GraphicsLayerAndroid*>(
+ layer->backing()->graphicsLayer());
+ backing->updateScrollOffset();
+ }
+ }
+ return;
+ }
+ }
+#endif
+
if (scrollbarsSuppressed())
return;
diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h
index 558aee2..e58d025 100644
--- a/Source/WebCore/platform/ScrollView.h
+++ b/Source/WebCore/platform/ScrollView.h
@@ -53,6 +53,10 @@ namespace WebCore {
class HostWindow;
class Scrollbar;
+#if PLATFORM(ANDROID)
+class FrameView;
+#endif
+
class ScrollView : public Widget, public ScrollableArea {
public:
~ScrollView();
@@ -168,10 +172,7 @@ public:
virtual void setContentsSize(const IntSize&);
#if PLATFORM(ANDROID)
- int actualWidth() const;
- int actualHeight() const;
- int actualScrollX() const;
- int actualScrollY() const;
+ FrameView* frameView();
#endif
// Functions for querying the current scrolled position (both as a point, a size, or as individual X and Y values).
@@ -400,13 +401,6 @@ private:
void platformSetScrollOrigin(const IntPoint&, bool updatePositionAtAll, bool updatePositionSynchronously);
-#if PLATFORM(ANDROID)
- int platformActualWidth() const;
- int platformActualHeight() const;
- int platformActualScrollX() const;
- int platformActualScrollY() const;
-#endif
-
#if PLATFORM(MAC) && defined __OBJC__
public:
NSView* documentView() const;
diff --git a/Source/WebCore/platform/android/KeyEventAndroid.cpp b/Source/WebCore/platform/android/KeyEventAndroid.cpp
index eaf34a9..dd1f37d 100644
--- a/Source/WebCore/platform/android/KeyEventAndroid.cpp
+++ b/Source/WebCore/platform/android/KeyEventAndroid.cpp
@@ -33,7 +33,7 @@
#include "NotImplemented.h"
#include "WindowsKeyboardCodes.h"
-#include <ui/KeycodeLabels.h>
+#include <androidfw/KeycodeLabels.h>
namespace WebCore {
@@ -191,7 +191,7 @@ static String keyIdentifierForAndroidKeyCode(int keyCode)
return "U+00007F";
default:
char upper[16];
- sprintf(upper, "U+%06X", windowsKeyCodeForKeyEvent(keyCode));
+ sprintf(upper, "U+%04X", windowsKeyCodeForKeyEvent(keyCode));
return String(upper);
}
}
diff --git a/Source/WebCore/platform/android/PopupMenuAndroid.cpp b/Source/WebCore/platform/android/PopupMenuAndroid.cpp
index f4c351f..a5758bb 100644
--- a/Source/WebCore/platform/android/PopupMenuAndroid.cpp
+++ b/Source/WebCore/platform/android/PopupMenuAndroid.cpp
@@ -25,10 +25,13 @@
#include "config.h"
#include "PopupMenuAndroid.h"
+#include "IntRect.h"
#include "PopupMenuClient.h"
#include "SkTDArray.h"
#include "WebViewCore.h"
+using namespace WebCore;
+
class PopupReply : public android::WebCoreReply {
public:
PopupReply(const IntRect& rect, android::WebViewCore* view, ListPopupMenuClient* client)
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.cpp b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
index 93c99a4..ee406c2 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -38,10 +38,8 @@
#include "RenderMediaControls.h"
#endif
#include "RenderSkinAndroid.h"
-#include "RenderSkinButton.h"
-#include "RenderSkinCombo.h"
#include "RenderSkinMediaButton.h"
-#include "RenderSkinRadio.h"
+#include "RoundedIntRect.h"
#include "SkCanvas.h"
#include "UserAgentStyleSheets.h"
#include "WebCoreFrameBridge.h"
@@ -63,6 +61,31 @@ const int listboxPadding = 5;
const RGBA32 selectionColor = makeRGB(181, 224, 136);
+// Colors copied from the holo resources
+const RGBA32 defaultBgColor = makeRGBA(204, 204, 204, 197);
+const RGBA32 defaultBgBright = makeRGBA(213, 213, 213, 221);
+const RGBA32 defaultBgDark = makeRGBA(92, 92, 92, 160);
+const RGBA32 defaultBgMedium = makeRGBA(132, 132, 132, 111);
+const RGBA32 defaultFgColor = makeRGBA(101, 101, 101, 225);
+const RGBA32 defaultCheckColor = makeRGBA(154, 204, 2, 255);
+
+const RGBA32 disabledBgColor = makeRGBA(205, 205, 205, 107);
+const RGBA32 disabledBgBright = makeRGBA(213, 213, 213, 133);
+const RGBA32 disabledBgDark = makeRGBA(92, 92, 92, 96);
+const RGBA32 disabledBgMedium = makeRGBA(132, 132, 132, 111);
+const RGBA32 disabledFgColor = makeRGBA(148, 148, 148, 137);
+
+const int paddingButton = 2;
+const int cornerButton = 2;
+
+// scale factors for various resolutions
+const float scaleFactor[RenderSkinAndroid::ResolutionCount] = {
+ 1.0f, // medium res
+ 1.5f, // high res
+ 2.0f // extra high res
+};
+
+
static SkCanvas* getCanvasFromInfo(const PaintInfo& info)
{
return info.context->platformContext()->mCanvas;
@@ -158,6 +181,16 @@ Color RenderThemeAndroid::platformInactiveListBoxSelectionForegroundColor() cons
return Color(Color::transparent);
}
+Color RenderThemeAndroid::platformActiveTextSearchHighlightColor() const
+{
+ return Color(0x00, 0x99, 0xcc, 0x99); // HOLO_DARK
+}
+
+Color RenderThemeAndroid::platformInactiveTextSearchHighlightColor() const
+{
+ return Color(0x33, 0xb5, 0xe5, 0x66); // HOLO_LIGHT
+}
+
int RenderThemeAndroid::baselinePosition(const RenderObject* obj) const
{
// From the description of this function in RenderTheme.h:
@@ -166,7 +199,7 @@ int RenderThemeAndroid::baselinePosition(const RenderObject* obj) const
// controls that need to do this.
//
// Our checkboxes and radio buttons need to be offset to line up properly.
- return RenderTheme::baselinePosition(obj) - 2;
+ return RenderTheme::baselinePosition(obj) - 8;
}
void RenderThemeAndroid::addIntrinsicMargins(RenderStyle* style) const
@@ -174,10 +207,10 @@ void RenderThemeAndroid::addIntrinsicMargins(RenderStyle* style) const
// Cut out the intrinsic margins completely if we end up using a small font size
if (style->fontSize() < 11)
return;
-
+
// Intrinsic margin value.
const int m = 2;
-
+
// FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
if (style->width().isIntrinsicOrAuto()) {
if (style->marginLeft().quirk())
@@ -210,22 +243,11 @@ bool RenderThemeAndroid::supportsFocus(ControlPart appearance)
void RenderThemeAndroid::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, WebCore::Element*) const
{
- // Code is taken from RenderThemeSafari.cpp
- // It makes sure we have enough space for the button text.
- const int paddingHoriz = 12;
- const int paddingVert = 8;
- style->setPaddingLeft(Length(paddingHoriz, Fixed));
- style->setPaddingRight(Length(paddingHoriz, Fixed));
- style->setPaddingTop(Length(paddingVert, Fixed));
- style->setPaddingBottom(Length(paddingVert, Fixed));
-
- // Set a min-height so that we can't get smaller than the mini button.
- style->setMinHeight(Length(15, Fixed));
}
bool RenderThemeAndroid::paintCheckbox(RenderObject* obj, const PaintInfo& info, const IntRect& rect)
{
- RenderSkinRadio::Draw(getCanvasFromInfo(info), obj->node(), rect, true);
+ paintRadio(obj, info, rect);
return false;
}
@@ -237,16 +259,50 @@ bool RenderThemeAndroid::paintButton(RenderObject* obj, const PaintInfo& info, c
if (formControlElement) {
android::WebFrame* webFrame = getWebFrame(node);
if (webFrame) {
- RenderSkinAndroid* skins = webFrame->renderSkins();
- if (skins) {
- RenderSkinAndroid::State state = RenderSkinAndroid::kNormal;
- if (!formControlElement->isEnabledFormControl())
- state = RenderSkinAndroid::kDisabled;
- skins->renderSkinButton()->draw(getCanvasFromInfo(info), rect, state);
+ GraphicsContext *context = info.context;
+ IntRect innerrect = IntRect(rect.x() + paddingButton, rect.y() + paddingButton,
+ rect.width() - 2 * paddingButton, rect.height() - 2 * paddingButton);
+ IntSize cornerrect = IntSize(cornerButton, cornerButton);
+ Color bg, bright, dark, medium;
+ if (formControlElement->isEnabledFormControl()) {
+ bg = Color(defaultBgColor);
+ bright = Color(defaultBgBright);
+ dark = Color(defaultBgDark);
+ medium = Color(defaultBgMedium);
+ } else {
+ bg = Color(disabledBgColor);
+ bright = Color(disabledBgBright);
+ dark = Color(disabledBgDark);
+ medium = Color(disabledBgMedium);
}
+ context->save();
+ context->clip(
+ IntRect(innerrect.x(), innerrect.y(), innerrect.width(), 1));
+ context->fillRoundedRect(innerrect, cornerrect, cornerrect,
+ cornerrect, cornerrect, bright, context->fillColorSpace());
+ context->restore();
+ context->save();
+ context->clip(IntRect(innerrect.x(), innerrect.y() + innerrect.height() - 1,
+ innerrect.width(), 1));
+ context->fillRoundedRect(innerrect, cornerrect, cornerrect,
+ cornerrect, cornerrect, dark, context->fillColorSpace());
+ context->restore();
+ context->save();
+ context->clip(IntRect(innerrect.x(), innerrect.y() + 1, innerrect.width(),
+ innerrect.height() - 2));
+ context->fillRoundedRect(innerrect, cornerrect, cornerrect,
+ cornerrect, cornerrect, bg, context->fillColorSpace());
+ context->restore();
+ context->setStrokeColor(medium, context->strokeColorSpace());
+ context->setStrokeThickness(1.0f);
+ context->drawLine(IntPoint(innerrect.x(), innerrect.y() + cornerButton),
+ IntPoint(innerrect.x(), innerrect.y() + innerrect.height() - cornerButton));
+ context->drawLine(IntPoint(innerrect.x() + innerrect.width(), innerrect.y() + cornerButton),
+ IntPoint(innerrect.x() + innerrect.width(), innerrect.y() + innerrect.height() - cornerButton));
}
}
+
// We always return false so we do not request to be redrawn.
return false;
}
@@ -336,7 +392,9 @@ bool RenderThemeAndroid::paintMediaControlsBackground(RenderObject* o, const Pai
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::BACKGROUND_SLIDER, translucent);
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
+ RenderSkinMediaButton::BACKGROUND_SLIDER,
+ translucent, 0, false);
return false;
}
@@ -355,7 +413,9 @@ bool RenderThemeAndroid::paintMediaSliderThumb(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::SLIDER_THUMB, translucent);
+ RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
+ RenderSkinMediaButton::SLIDER_THUMB,
+ translucent, 0, false);
return false;
}
@@ -373,7 +433,49 @@ void RenderThemeAndroid::adjustSliderThumbSize(RenderObject* o) const
bool RenderThemeAndroid::paintRadio(RenderObject* obj, const PaintInfo& info, const IntRect& rect)
{
- RenderSkinRadio::Draw(getCanvasFromInfo(info), obj->node(), rect, false);
+ Node* node = obj->node();
+ Element* element = static_cast<Element*>(node);
+ if (element) {
+ InputElement* input = element->toInputElement();
+ GraphicsContext* context = info.context;
+ if (!element->isEnabledFormControl()) {
+ context->setAlpha(0.5f);
+ }
+ const IntRect inner = IntRect(rect.x() - 2, rect.y() - 2, rect.width() - 4, rect.height() - 4);
+ context->setFillColor(Color(defaultBgBright), context->fillColorSpace());
+ context->setStrokeColor(Color(defaultBgBright), context->strokeColorSpace());
+ context->setStrokeThickness(1.0f);
+ if (input->isCheckbox()) {
+ context->drawRect(inner);
+ } else {
+ context->drawEllipse(inner);
+ }
+ context->setStrokeColor(Color(defaultFgColor), context->strokeColorSpace());
+ if (input->isCheckbox()) {
+ context->drawRect(IntRect(inner.x() + 2, inner.y() + 2, inner.width() -4, inner.height() - 4));
+ } else {
+ context->drawEllipse(IntRect(inner.x() + 2, inner.y() + 2, inner.width() -4, inner.height() - 4));
+ }
+ if (input->isChecked()) {
+ context->setFillColor(Color(defaultCheckColor), context->fillColorSpace());
+ context->setStrokeColor(Color(defaultCheckColor), context->strokeColorSpace());
+ if (input->isCheckbox()) {
+ const float w2 = ((float) rect.width() / 2);
+ const float cx = ((float) rect.x());
+ const float cy = ((float) rect.y());
+ context->save();
+ // magic numbers due to weird scale in context
+ context->translate(cx + w2 / 2.2f, cy + w2 / 1.2f);
+ context->rotate(3.93f); // 225 degrees
+ context->drawRect(IntRect(0, 0, rect.width() / 4, 2));
+ context->rotate(1.57f); // 90 degrees
+ context->drawRect(IntRect(0, 0, rect.width() / 2, 2));
+ context->restore();
+ } else {
+ context->drawEllipse(IntRect(inner.x() + 5, inner.y() + 5, inner.width() - 10, inner.height() - 10));
+ }
+ }
+ }
return false;
}
@@ -396,7 +498,7 @@ void RenderThemeAndroid::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* st
bool RenderThemeAndroid::paintTextField(RenderObject*, const PaintInfo&, const IntRect&)
{
- return true;
+ return true;
}
void RenderThemeAndroid::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle* style, WebCore::Element*) const
@@ -418,25 +520,29 @@ void RenderThemeAndroid::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*
bool RenderThemeAndroid::paintSearchField(RenderObject*, const PaintInfo&, const IntRect&)
{
- return true;
+ return true;
}
static void adjustMenuListStyleCommon(RenderStyle* style)
{
// Added to make room for our arrow and make the touch target less cramped.
- style->setPaddingLeft(Length(RenderSkinCombo::padding(), Fixed));
- style->setPaddingTop(Length(RenderSkinCombo::padding(), Fixed));
- style->setPaddingBottom(Length(RenderSkinCombo::padding(), Fixed));
- style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed));
- style->setMinHeight(Length(RenderSkinCombo::minHeight(), Fixed));
+ const int padding = (int)(scaleFactor[RenderSkinAndroid::DrawableResolution()] + 0.5f);
+ style->setPaddingLeft(Length(padding,Fixed));
+ style->setPaddingTop(Length(padding, Fixed));
+ style->setPaddingBottom(Length(padding, Fixed));
+ // allocate height as arrow size
+ int arrow = std::max(18, style->fontMetrics().height() + 2 * padding);
+ style->setPaddingRight(Length(arrow, Fixed));
+ style->setMinHeight(Length(arrow, Fixed));
+ style->setHeight(Length(arrow, Fixed));
}
-void RenderThemeAndroid::adjustListboxStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+void RenderThemeAndroid::adjustListboxStyle(CSSStyleSelector*, RenderStyle* style, Element* e) const
{
adjustMenuListButtonStyle(0, style, 0);
}
-void RenderThemeAndroid::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element* e) const
+void RenderThemeAndroid::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
adjustMenuListStyleCommon(style);
addIntrinsicMargins(style);
@@ -446,11 +552,55 @@ bool RenderThemeAndroid::paintCombo(RenderObject* obj, const PaintInfo& info, c
{
if (obj->style() && !obj->style()->visitedDependentColor(CSSPropertyBackgroundColor).alpha())
return true;
- return RenderSkinCombo::Draw(getCanvasFromInfo(info), obj->node(), rect.x(), rect.y(), rect.width(), rect.height());
+ Node* node = obj->node();
+ Element* element = static_cast<Element*>(node);
+ if (element) {
+ InputElement* input = element->toInputElement();
+ GraphicsContext* context = info.context;
+ if (!element->isEnabledFormControl()) {
+ context->setAlpha(0.5f);
+ }
+ IntRect bounds = IntRect(rect.x(), rect.y(), rect.width(), rect.height());
+ // paint bg color
+ RenderStyle* style = obj->style();
+ context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor),
+ context->fillColorSpace());
+ context->fillRect(FloatRect(bounds));
+ // copied form the original RenderSkinCombo:
+ // If this is an appearance where RenderTheme::paint returns true
+ // without doing anything, this means that
+ // RenderBox::PaintBoxDecorationWithSize will end up painting the
+ // border, so we shouldn't paint a border here.
+ if (style->appearance() != MenulistButtonPart &&
+ style->appearance() != ListboxPart &&
+ style->appearance() != TextFieldPart &&
+ style->appearance() != TextAreaPart) {
+ const int arrowSize = bounds.height();
+ // dropdown button bg
+ context->setFillColor(Color(defaultBgColor), context->fillColorSpace());
+ context->fillRect(FloatRect(bounds.maxX() - arrowSize + 0.5f, bounds.y() + .5f,
+ arrowSize - 1, bounds.height() - 1));
+ // outline
+ context->setStrokeThickness(1.0f);
+ context->setStrokeColor(Color(defaultBgDark), context->strokeColorSpace());
+ context->strokeRect(bounds, 1.0f);
+ // arrow
+ context->setFillColor(Color(defaultFgColor), context->fillColorSpace());
+ Path tri = Path();
+ tri.clear();
+ const float aw = arrowSize - 10;
+ FloatPoint br = FloatPoint(bounds.maxX() - 4, bounds.maxY() - 4);
+ tri.moveTo(br);
+ tri.addLineTo(FloatPoint(br.x() - aw, br.y()));
+ tri.addLineTo(FloatPoint(br.x(), br.y() - aw));
+ context->fillPath(tri);
+ }
+ }
+ return false;
}
-bool RenderThemeAndroid::paintMenuList(RenderObject* obj, const PaintInfo& info, const IntRect& rect)
-{
+bool RenderThemeAndroid::paintMenuList(RenderObject* obj, const PaintInfo& info, const IntRect& rect)
+{
return paintCombo(obj, info, rect);
}
@@ -461,13 +611,13 @@ void RenderThemeAndroid::adjustMenuListButtonStyle(CSSStyleSelector*,
const float baseFontSize = 11.0f;
const int baseBorderRadius = 5;
float fontScale = style->fontSize() / baseFontSize;
-
+
style->resetPadding();
style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up?
const int minHeight = 15;
style->setMinHeight(Length(minHeight, Fixed));
-
+
style->setLineHeight(RenderStyle::initialLineHeight());
// Found these padding numbers by trial and error.
const int padding = 4;
@@ -476,26 +626,23 @@ void RenderThemeAndroid::adjustMenuListButtonStyle(CSSStyleSelector*,
adjustMenuListStyleCommon(style);
}
-bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const PaintInfo& info, const IntRect& rect)
+bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const PaintInfo& info, const IntRect& rect)
{
return paintCombo(obj, info, rect);
}
+Color RenderThemeAndroid::platformFocusRingColor() const
+{
+ static Color focusRingColor(0x33, 0xB5, 0xE5, 0x66);
+ return focusRingColor;
+}
+
bool RenderThemeAndroid::supportsFocusRing(const RenderStyle* style) const
{
- return style->opacity() > 0
- && style->hasAppearance()
- && style->appearance() != TextFieldPart
- && style->appearance() != SearchFieldPart
- && style->appearance() != TextAreaPart
- && style->appearance() != CheckboxPart
- && style->appearance() != RadioPart
- && style->appearance() != PushButtonPart
- && style->appearance() != SquareButtonPart
- && style->appearance() != ButtonPart
- && style->appearance() != ButtonBevelPart
- && style->appearance() != MenulistPart
- && style->appearance() != MenulistButtonPart;
+ // Draw the focus ring ourselves unless it is a text area (webkit does borders better)
+ if (!style || !style->hasAppearance())
+ return true;
+ return style->appearance() != TextFieldPart && style->appearance() != TextAreaPart;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.h b/Source/WebCore/platform/android/RenderThemeAndroid.h
index e3922a1..ed4d07f 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.h
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.h
@@ -31,10 +31,6 @@
namespace WebCore {
-class RenderSkinButton;
-class RenderSkinRadio;
-class RenderSkinCombo;
-
struct ThemeData {
ThemeData()
: m_part(0)
@@ -52,7 +48,7 @@ public:
~RenderThemeAndroid();
virtual bool stateChanged(RenderObject*, ControlState) const;
-
+
virtual bool supportsFocusRing(const RenderStyle*) const;
// A method asking if the theme's controls actually care about redrawing when hovered.
virtual bool supportsHover(const RenderStyle* style) const { return style->affectedByHoverRules(); }
@@ -64,12 +60,16 @@ public:
virtual Color platformActiveSelectionForegroundColor() const;
virtual Color platformInactiveSelectionForegroundColor() const;
virtual Color platformTextSearchHighlightColor() const;
+ virtual Color platformFocusRingColor() const;
virtual Color platformActiveListBoxSelectionBackgroundColor() const;
virtual Color platformInactiveListBoxSelectionBackgroundColor() const;
virtual Color platformActiveListBoxSelectionForegroundColor() const;
virtual Color platformInactiveListBoxSelectionForegroundColor() const;
+ virtual Color platformActiveTextSearchHighlightColor() const;
+ virtual Color platformInactiveTextSearchHighlightColor() const;
+
virtual void systemFont(int, WebCore::FontDescription&) const {}
virtual int minimumMenuListSize(RenderStyle*) const { return 0; }
diff --git a/Source/WebCore/platform/android/ScrollViewAndroid.cpp b/Source/WebCore/platform/android/ScrollViewAndroid.cpp
index f29e998..ecaa2b5 100644
--- a/Source/WebCore/platform/android/ScrollViewAndroid.cpp
+++ b/Source/WebCore/platform/android/ScrollViewAndroid.cpp
@@ -68,38 +68,8 @@ IntSize ScrollView::platformContentsSize() const
return m_contentsSize;
}
-int ScrollView::platformActualWidth() const
-{
- if (parent())
- return width();
- return platformWidget()->visibleWidth();
-}
-
-int ScrollView::platformActualHeight() const
-{
- if (parent())
- return height();
- return platformWidget()->visibleHeight();
-}
-
-int ScrollView::platformActualScrollX() const
-{
- if (parent())
- return scrollX();
- return platformWidget()->visibleX();
-}
-
-int ScrollView::platformActualScrollY() const
-{
- if (parent())
- return scrollY();
- return platformWidget()->visibleY();
-}
-
void ScrollView::platformSetScrollPosition(const WebCore::IntPoint& pt)
{
- if (parent()) // don't attempt to scroll subframes; they're fully visible
- return;
PlatformBridge::setScrollPosition(this, m_scrollOrigin.x() + pt.x(),
m_scrollOrigin.y() + pt.y());
}
diff --git a/Source/WebCore/platform/android/SharedTimerAndroid.cpp b/Source/WebCore/platform/android/SharedTimerAndroid.cpp
index e4f3b36..a3f3db5 100644
--- a/Source/WebCore/platform/android/SharedTimerAndroid.cpp
+++ b/Source/WebCore/platform/android/SharedTimerAndroid.cpp
@@ -51,7 +51,7 @@ void setSharedTimerFireTime(double fireTime)
{
long long timeInMs = static_cast<long long>((fireTime - WTF::currentTime()) * 1000);
- LOGV("setSharedTimerFireTime: in %ld millisec", timeInMs);
+ ALOGV("setSharedTimerFireTime: in %ld millisec", timeInMs);
if (JavaSharedClient::GetTimerClient())
JavaSharedClient::GetTimerClient()->setSharedTimer(timeInMs);
}
diff --git a/Source/WebCore/platform/android/TemporaryLinkStubs.cpp b/Source/WebCore/platform/android/TemporaryLinkStubs.cpp
index ca9f24d..7df3e8c 100644
--- a/Source/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/Source/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -80,13 +80,6 @@
#include <wtf/MainThread.h>
#include <wtf/text/CString.h>
-#if USE(JSC)
-#include "API/JSClassRef.h"
-#include "JNIUtilityPrivate.h"
-#include "JavaScriptCallFrame.h"
-#include "ScriptDebugServer.h"
-#endif
-
using namespace WebCore;
/********************************************************/
@@ -394,18 +387,6 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&)
}
-#if USE(JSC)
-namespace JSC { namespace Bindings {
-bool dispatchJNICall(ExecState*, const void* targetAppletView, jobject obj, bool isStatic, JavaType returnType,
- jmethodID methodID, jvalue* args, jvalue& result, const char* callingURL, JSValue& exceptionDescription)
-{
- notImplemented();
- return false;
-}
-
-} } // namespace Bindings
-#endif
-
char* dirname(const char*)
{
notImplemented();
diff --git a/Source/WebCore/platform/android/WidgetAndroid.cpp b/Source/WebCore/platform/android/WidgetAndroid.cpp
index 10326f9..0f7758d 100644
--- a/Source/WebCore/platform/android/WidgetAndroid.cpp
+++ b/Source/WebCore/platform/android/WidgetAndroid.cpp
@@ -49,9 +49,7 @@ Widget::~Widget()
IntRect Widget::frameRect() const
{
- if (!platformWidget())
- return m_frame;
- return platformWidget()->getBounds();
+ return m_frame;
}
void Widget::setFocus(bool focused)
@@ -95,11 +93,6 @@ void Widget::hide()
void Widget::setFrameRect(const IntRect& rect)
{
m_frame = rect;
- // platformWidget() is 0 when called from Scrollbar
- if (!platformWidget())
- return;
- platformWidget()->setLocation(rect.x(), rect.y());
- platformWidget()->setSize(rect.width(), rect.height());
}
void Widget::setIsSelected(bool isSelected)
diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h
index 02ec005..0fb355b 100644
--- a/Source/WebCore/platform/graphics/Color.h
+++ b/Source/WebCore/platform/graphics/Color.h
@@ -162,15 +162,8 @@ public:
static const RGBA32 lightGray = 0xFFC0C0C0;
static const RGBA32 transparent = 0x00000000;
-#ifdef ANDROID_CSS_RING
- static const RGBA32 ringFill = 0x666699FF;
- static const RGBA32 ringPressedInner = 0x006699FF;
- static const RGBA32 ringPressedOuter = 0x336699FF;
- static const RGBA32 ringSelectedInner = 0xAA6699FF;
- static const RGBA32 ringSelectedOuter = 0x336699FF;
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
- static const RGBA32 tap = 0x4D1A1A1A;
+ static const RGBA32 tap = 0x6633B5E5;
#endif
private:
diff --git a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index 951cf56..126b3b4 100644
--- a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -47,12 +47,19 @@ GlyphPageTreeNode* GlyphPageTreeNode::pageZeroRoot = 0;
GlyphPageTreeNode* GlyphPageTreeNode::getRoot(unsigned pageNumber)
{
+#if !PLATFORM(ANDROID)
static bool initialized;
if (!initialized) {
initialized = true;
roots = new HashMap<int, GlyphPageTreeNode*>;
pageZeroRoot = new GlyphPageTreeNode;
}
+#else
+ if (!roots)
+ roots = new HashMap<int, GlyphPageTreeNode*>;
+ if (!pageZeroRoot)
+ pageZeroRoot = new GlyphPageTreeNode;
+#endif
GlyphPageTreeNode* node = pageNumber ? roots->get(pageNumber) : pageZeroRoot;
if (!node) {
@@ -68,6 +75,29 @@ GlyphPageTreeNode* GlyphPageTreeNode::getRoot(unsigned pageNumber)
return node;
}
+#if PLATFORM(ANDROID)
+void GlyphPageTreeNode::resetRoots()
+{
+ if (roots) {
+ HashMap<int, GlyphPageTreeNode*>::iterator end = roots->end();
+ for (HashMap<int, GlyphPageTreeNode*>::iterator it = roots->begin(); it != end; ++it)
+ it->second->resetChildren();
+ }
+ if (pageZeroRoot) {
+ pageZeroRoot->resetChildren();
+ }
+}
+
+void GlyphPageTreeNode::resetChildren()
+{
+ HashMap<const FontData*, GlyphPageTreeNode*>::const_iterator end = m_children.end();
+ for (HashMap<const FontData*, GlyphPageTreeNode*>::const_iterator it = m_children.begin(); it != end; ++it) {
+ pruneTreeFontData(static_cast<const SimpleFontData*>(it->first));
+ pruneTreeCustomFontData(it->first);
+ }
+}
+#endif
+
size_t GlyphPageTreeNode::treeGlyphPageCount()
{
size_t count = 0;
@@ -347,7 +377,11 @@ GlyphPageTreeNode* GlyphPageTreeNode::getChild(const FontData* fontData, unsigne
void GlyphPageTreeNode::pruneCustomFontData(const FontData* fontData)
{
+#if !PLATFORM(ANDROID)
if (!fontData || !m_customFontCount)
+#else
+ if (!fontData || !m_customFontCount || fontData == (SimpleFontData*)-1)
+#endif
return;
// Prune any branch that contains this FontData.
@@ -371,7 +405,11 @@ void GlyphPageTreeNode::pruneCustomFontData(const FontData* fontData)
void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, unsigned level)
{
ASSERT(fontData);
+#if !PLATFORM(ANDROID)
if (!fontData)
+#else
+ if (!fontData || fontData == (SimpleFontData*)-1)
+#endif
return;
// Prune any branch that contains this FontData.
diff --git a/Source/WebCore/platform/graphics/GlyphPageTreeNode.h b/Source/WebCore/platform/graphics/GlyphPageTreeNode.h
index b68c0ed..72a62ea 100644
--- a/Source/WebCore/platform/graphics/GlyphPageTreeNode.h
+++ b/Source/WebCore/platform/graphics/GlyphPageTreeNode.h
@@ -196,6 +196,11 @@ public:
void pruneCustomFontData(const FontData*);
void pruneFontData(const SimpleFontData*, unsigned level = 0);
+#if PLATFORM(ANDROID)
+ static void resetRoots();
+ void resetChildren();
+#endif
+
GlyphPageTreeNode* parent() const { return m_parent; }
GlyphPageTreeNode* getChild(const FontData*, unsigned pageNumber);
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 65cc6df..d8ea160 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -432,6 +432,7 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F
bidiRuns.deleteRuns();
}
+#if !PLATFORM(ANDROID)
void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to)
{
if (paintingDisabled())
@@ -439,6 +440,7 @@ void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run,
fillRect(font.selectionRectForText(run, point, h, from, to), backgroundColor, colorSpace);
}
+#endif
void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op, bool useLowQualityScale)
{
@@ -660,7 +662,7 @@ CompositeOperator GraphicsContext::compositeOperation() const
return m_state.compositeOperator;
}
-#if !(USE(SKIA) && !PLATFORM(ANDROID))
+#if !USE(SKIA)
void GraphicsContext::setPlatformFillGradient(Gradient*)
{
}
@@ -686,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 2b41c2e..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
@@ -382,7 +376,11 @@ namespace WebCore {
void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1);
void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1);
void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
+#if PLATFORM(ANDROID)
+ void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1, bool isActive = true);
+#else
void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
+#endif
enum RoundingMode {
RoundAllSides,
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
index 6b22359..0ef84b9 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
@@ -14,39 +14,22 @@
* limitations under the License.
*/
+#define LOG_TAG "AndroidAnimation"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "AndroidAnimation.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "Animation.h"
#include "GraphicsLayerAndroid.h"
-
#include "Timer.h"
#include "TimingFunction.h"
#include "TranslateTransformOperation.h"
#include "UnitBezier.h"
-#include <wtf/CurrentTime.h>
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-
namespace WebCore {
static int gUniqueId;
@@ -251,10 +234,10 @@ void AndroidOpacityAnimation::applyForProgress(LayerAndroid* layer, float progre
FloatAnimationValue* fromValue = (FloatAnimationValue*) m_operations->at(from);
FloatAnimationValue* toValue = (FloatAnimationValue*) m_operations->at(to);
- XLOG("[layer %d] opacity fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
- layer->uniqueId(),
- fromValue, fromValue->keyTime(),
- toValue, toValue->keyTime(), progress);
+ ALOGV("[layer %d] opacity fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
+ layer->uniqueId(),
+ fromValue, fromValue->keyTime(),
+ toValue, toValue->keyTime(), progress);
// We now have the correct two values to work with, let's compute the
// progress value
@@ -293,10 +276,10 @@ void AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float prog
TransformAnimationValue* fromValue = (TransformAnimationValue*) m_operations->at(from);
TransformAnimationValue* toValue = (TransformAnimationValue*) m_operations->at(to);
- XLOG("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
- layer->uniqueId(),
- fromValue, fromValue->keyTime(),
- toValue, toValue->keyTime(), progress);
+ ALOGV("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
+ layer->uniqueId(),
+ fromValue, fromValue->keyTime(),
+ toValue, toValue->keyTime(), progress);
// We now have the correct two values to work with, let's compute the
// progress value
@@ -304,8 +287,8 @@ void AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float prog
const TimingFunction* timingFunction = fromValue->timingFunction();
float p = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(),
progress, timingFunction);
- XLOG("progress %.2f => %.2f from: %.2f to: %.2f", progress, p, fromValue->keyTime(),
- toValue->keyTime());
+ ALOGV("progress %.2f => %.2f from: %.2f to: %.2f", progress, p, fromValue->keyTime(),
+ toValue->keyTime());
progress = p;
// With both values and the progress, we also need to check out that
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 9c7716c..7bb632f 100644
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010, 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,368 +23,35 @@
* 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"
-#if USE(ACCELERATED_COMPOSITING)
-#include "ClassTracker.h"
-#include "GLUtils.h"
-#include "ShaderProgram.h"
-#include "SkCanvas.h"
-#include "TilesManager.h"
-#include <GLES2/gl2.h>
-#include <wtf/CurrentTime.h>
-#endif // USE(ACCELERATED_COMPOSITING)
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseLayerAndroid", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseLayerAndroid", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-// 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
+#include "AndroidLog.h"
+#include "GLWebViewState.h"
+#include "LayerContent.h"
namespace WebCore {
-using namespace android;
-
-BaseLayerAndroid::BaseLayerAndroid()
-#if USE(ACCELERATED_COMPOSITING)
- : m_color(Color::white)
- , m_scrollState(NotScrolling)
-#endif
-{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("BaseLayerAndroid");
-#endif
-}
-
-BaseLayerAndroid::~BaseLayerAndroid()
-{
- m_content.clear();
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("BaseLayerAndroid");
-#endif
-}
-void BaseLayerAndroid::setContent(const PictureSet& src)
-{
-#if USE(ACCELERATED_COMPOSITING)
- // FIXME: We lock here because we do not want
- // to paint and change the m_content concurrently.
- // We should instead refactor PictureSet to use
- // an atomic refcounting scheme and use atomic operations
- // to swap PictureSets.
- android::Mutex::Autolock lock(m_drawLock);
-#endif
- m_content.set(src);
- // 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());
-}
+// Note: this must match the use of ID 0 specifying the base layer in DrawExtra
+#define BASE_UNIQUE_ID 0
-bool BaseLayerAndroid::drawCanvas(SkCanvas* canvas)
+BaseLayerAndroid::BaseLayerAndroid(LayerContent* content)
+ : LayerAndroid((RenderLayer*)0)
+ , m_color(Color::white)
{
-#if USE(ACCELERATED_COMPOSITING)
- android::Mutex::Autolock lock(m_drawLock);
-#endif
- if (!m_content.isEmpty())
- m_content.draw(canvas);
- return true;
+ setContent(content);
+ setSize(content->width(), content->height());
+ m_uniqueId = BASE_UNIQUE_ID;
}
-#if USE(ACCELERATED_COMPOSITING)
-
-void BaseLayerAndroid::prefetchBasePicture(SkRect& viewport, float currentScale,
- TiledPage* prefetchTiledPage, bool draw)
+void BaseLayerAndroid::getLocalTransform(SkMatrix* matrix) const
{
- 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();
-
-
- XLOG("fetch rect %f %f %f %f, scale %f",
- viewport.fLeft,
- viewport.fTop,
- viewport.fRight,
- viewport.fBottom,
- scale);
-
- 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;
-
- XLOG("prefetch rect %d %d %d %d, scale %f, preparing page %p",
- bounds.fLeft, bounds.fTop,
- bounds.fRight, bounds.fBottom,
- scale * PREFETCH_SCALE,
- prefetchTiledPage);
-
- prefetchTiledPage->setScale(prefetchScale);
- prefetchTiledPage->updateTileDirtiness(bounds);
- 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()) {
- XLOG("base layer not ready, still zooming");
- return false; // still zooming
- }
-
- if (!m_state->frontPage()->isReady(m_state->preZoomBounds())) {
- XLOG("base layer not ready, front page not done painting");
- return false;
- }
-
- LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0));
- if (compositedRoot) {
- XLOG("base layer is ready, how about children?");
- return compositedRoot->isReady();
- }
-
- return true;
-}
-
-void BaseLayerAndroid::swapTiles()
-{
- if (countChildren())
- getChild(0)->swapTiles(); // TODO: move to parent impl
-
- m_state->frontPage()->swapBuffersIfReady(m_state->preZoomBounds(),
- m_state->zoomManager()->currentScale());
-
- m_state->backPage()->swapBuffersIfReady(m_state->preZoomBounds(),
- m_state->zoomManager()->currentScale());
-}
-
-void BaseLayerAndroid::setIsDrawing(bool isDrawing)
-{
- if (countChildren())
- getChild(0)->setIsDrawing(isDrawing); // TODO: move to parent impl
-}
-
-void BaseLayerAndroid::setIsPainting(Layer* drawingTree)
-{
- XLOG("BLA %p painting, dirty %d", this, isDirty());
- if (drawingTree)
- drawingTree = drawingTree->getChild(0);
-
- if (countChildren())
- getChild(0)->setIsPainting(drawingTree); // TODO: move to parent impl
-
- m_state->invalRegion(m_dirtyRegion);
- m_dirtyRegion.setEmpty();
-}
-
-void BaseLayerAndroid::mergeInvalsInto(Layer* replacementTree)
-{
- XLOG("merging invals (empty=%d) from BLA %p to %p", m_dirtyRegion.isEmpty(), this, replacementTree);
- if (countChildren() && replacementTree->countChildren())
- getChild(0)->mergeInvalsInto(replacementTree->getChild(0));
-
- replacementTree->markAsDirty(m_dirtyRegion);
-}
-
-bool BaseLayerAndroid::prepareBasePictureInGL(SkRect& viewport, float scale,
- double currentTime)
-{
- ZoomManager* zoomManager = m_state->zoomManager();
-
- bool goingDown = m_state->goingDown();
- bool goingLeft = m_state->goingLeft();
-
- const SkIRect& viewportTileBounds = m_state->viewportTileBounds();
- XLOG("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);
-
- // ignore dirtiness return value since while zooming we repaint regardless
- nextTiledPage->updateTileDirtiness(viewportTileBounds);
-
- 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();
- }
-
- bool needsRedraw = zooming;
-
- // if applied invals mark tiles dirty, need to redraw
- needsRedraw |= tiledPage->updateTileDirtiness(preZoomBounds);
-
- // 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);
-
- XLOG("scrolling %d, zooming %d, needsRedraw %d",
- scrolling, zooming, needsRedraw);
-
- // 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);
-
- return needsRedraw;
-}
-
-void BaseLayerAndroid::drawBasePictureInGL()
-{
- m_state->backPage()->drawGL();
- m_state->frontPage()->drawGL();
-}
-
-#endif // USE(ACCELERATED_COMPOSITING)
-
-void BaseLayerAndroid::updateLayerPositions(SkRect& visibleRect)
-{
- LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0));
- TransformationMatrix ident;
- compositedRoot->updateFixedLayersPositions(visibleRect);
- FloatRect clip(0, 0, content()->width(), content()->height());
- compositedRoot->updateGLPositionsAndScale(
- ident, clip, 1, m_state->zoomManager()->layersScale());
-
-#ifdef DEBUG
- compositedRoot->showLayer(0);
- XLOG("We have %d layers, %d textured",
- compositedRoot->nbLayers(),
- compositedRoot->nbTexturedLayers());
-#endif
-}
-
-bool BaseLayerAndroid::prepare(double currentTime, IntRect& viewRect,
- SkRect& visibleRect, float scale)
-{
- XLOG("preparing BLA %p", this);
-
- // base layer is simply drawn in prepare, since there is always a base layer it doesn't matter
- bool needsRedraw = prepareBasePictureInGL(visibleRect, scale, currentTime);
-
- LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0));
- if (compositedRoot) {
- updateLayerPositions(visibleRect);
-
- XLOG("preparing BLA %p, root %p", this, compositedRoot);
- compositedRoot->prepare();
- }
-
- return needsRedraw;
-}
-
-bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
- float scale)
-{
- XLOG("drawing BLA %p", this);
-
- // TODO: consider moving drawBackground outside of prepare (into tree manager)
- m_state->drawBackground(m_color);
- drawBasePictureInGL();
-
- bool needsRedraw = false;
-
-#if USE(ACCELERATED_COMPOSITING)
-
- LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0));
- if (compositedRoot) {
- updateLayerPositions(visibleRect);
- // For now, we render layers only if the rendering mode
- // is kAllTextures or kClippedTextures
- if (compositedRoot->drawGL()) {
- if (TilesManager::instance()->layerTexturesRemain()) {
- // only try redrawing for layers if layer textures remain,
- // otherwise we'll repaint without getting anything done
- needsRedraw = true;
- }
- }
- }
-
-#endif // USE(ACCELERATED_COMPOSITING)
-#ifdef DEBUG
- ClassTracker::instance()->show();
-#endif
- return needsRedraw;
+ // base layer doesn't use size in transform calculation
+ matrix->preConcat(getMatrix());
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
index c5ce52f..0ef39c8 100644
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010, 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
@@ -27,65 +27,33 @@
#define BaseLayerAndroid_h
#include "Color.h"
-#include "GLWebViewState.h"
-#include "IntRect.h"
-#include "Layer.h"
-#include "PictureSet.h"
-#include "SkPicture.h"
+#include "LayerAndroid.h"
namespace WebCore {
-class BaseLayerAndroid : public Layer {
+class RenderLayerCompositor;
+
+class BaseLayerAndroid : public LayerAndroid {
public:
- enum ScrollState {
- NotScrolling = 0,
- Scrolling = 1,
- ScrollingFinishPaint = 2
- };
+ BaseLayerAndroid(LayerContent* content);
+
+ virtual ~BaseLayerAndroid() {};
- BaseLayerAndroid();
- virtual ~BaseLayerAndroid();
+ virtual SubclassType subclassType() { return LayerAndroid::BaseLayer; }
+ virtual bool needsTexture() { return true; }
-#if USE(ACCELERATED_COMPOSITING)
void setBackgroundColor(Color& color) { m_color = color; }
Color getBackgroundColor() { return m_color; }
-#endif
- void setContent(const android::PictureSet& src);
- android::PictureSet* 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(SkRect& visibleRect);
- bool prepare(double currentTime, IntRect& viewRect,
- SkRect& visibleRect, float scale);
- bool drawGL(IntRect& viewRect, SkRect& visibleRect, float scale);
- // rendering asset management
- void swapTiles();
- void setIsDrawing(bool isDrawing);
- void setIsPainting(Layer* drawingTree);
- void mergeInvalsInto(Layer* replacementTree);
- bool isReady();
+ virtual void getLocalTransform(SkMatrix* matrix) const;
+ virtual const TransformationMatrix* drawTransform() const { return 0; }
private:
-#if USE(ACCELERATED_COMPOSITING)
- void prefetchBasePicture(SkRect& viewport, float currentScale,
- TiledPage* prefetchTiledPage, bool draw);
- bool prepareBasePictureInGL(SkRect& viewport, float scale, double currentTime);
- void drawBasePictureInGL();
-
- android::Mutex m_drawLock;
+ // TODO: move to SurfaceCollection.
Color m_color;
-#endif
- android::PictureSet m_content;
-
- ScrollState m_scrollState;
};
} // namespace WebCore
-#endif // BaseLayerAndroid_h
+#endif //BaseLayerAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
index 57baee8..fba62b7 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
@@ -23,12 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "BaseRenderer"
+#define LOG_NDEBUG 1
#include "config.h"
#include "BaseRenderer.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "GaneshRenderer.h"
#include "GLUtils.h"
#include "RasterRenderer.h"
@@ -37,24 +40,13 @@
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPicture.h"
+#include "SkTypeface.h"
#include "TilesManager.h"
#include <wtf/text/CString.h>
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseRenderer", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+#define UPDATE_COUNT_MASK 0xFF // displayed count wraps at 256
+#define UPDATE_COUNT_ALPHA_MASK 0x1F // alpha wraps at 32
namespace WebCore {
@@ -79,40 +71,24 @@ void BaseRenderer::swapRendererIfNeeded(BaseRenderer*& renderer)
}
void BaseRenderer::drawTileInfo(SkCanvas* canvas,
- const TileRenderInfo& renderInfo, int pictureCount)
+ 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, pictureCount);
- paint.setARGB(255, 0, 0, 0);
- canvas->drawText(str, strlen(str), 0, 10, 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);
+ 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, textY + 1, paint);
+ paint.setTypeface(s_typeface);
+ canvas->drawText(str, strlen(str), 20, 15, paint);
}
-int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
+void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
{
const bool visualIndicator = TilesManager::instance()->getShowVisualIndicator();
const SkSize& tileSize = renderInfo.tileSize;
@@ -121,45 +97,66 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
setupCanvas(renderInfo, &canvas);
if (!canvas.getDevice()) {
- XLOG("Error: No Device");
- return 0;
+ // TODO: consider ALOGE
+ ALOGV("Error: No Device");
+ 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);
- unsigned int pictureCount = 0;
- renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas, &pictureCount);
+ 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();
- const int color = 20 + (pictureCount % 100);
+ 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);
- canvas.drawIRect(*renderInfo.invalRect, invalPaint);
+ SkPaint paint;
+ paint.setARGB(color, 0, 255, 0);
+ if (renderInfo.invalRect)
+ canvas.drawIRect(*renderInfo.invalRect, paint);
+ else {
+ SkIRect rect;
+ rect.set(0, 0, tileSize.width(), tileSize.height());
+ canvas.drawIRect(rect, paint);
+ }
+
+ if (renderInfo.invalRect) {
+ // if partial inval...
+ int x = renderInfo.invalRect->fLeft;
+ int y = renderInfo.invalRect->fTop;
+ int w = renderInfo.invalRect->width();
+ int h = renderInfo.invalRect->height();
+
+ paint.setARGB(128, 255, 255, 0);
+ canvas.drawLine(x, y, x + w, y + h, paint);
+ canvas.drawLine(x, y + h, x + w, y, paint);
+ }
+ drawTileInfo(&canvas, renderInfo, updateCount, after - before);
// paint the tile boundaries
- SkPaint paint;
- paint.setARGB(128, 255, 0, 0);
+ paint.setARGB(64, 255, 0, 0);
paint.setStrokeWidth(3);
canvas.drawLine(0, 0, tileSize.width(), tileSize.height(), paint);
- paint.setARGB(128, 0, 255, 0);
+ paint.setARGB(64, 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.measurePerf)
- drawTileInfo(&canvas, renderInfo, pictureCount);
}
- renderInfo.textureInfo->m_pictureCount = pictureCount;
renderingComplete(renderInfo, &canvas);
- return pictureCount;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.h b/Source/WebCore/platform/graphics/android/BaseRenderer.h
index 7780db1..ef1e4c2 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.h
+++ b/Source/WebCore/platform/graphics/android/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;
@@ -63,8 +64,8 @@ struct TileRenderInfo {
// 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() {}
- int 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 pictureCount);
-
- 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/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index 27bd482..ddaf181 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -23,51 +23,38 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "BaseTile"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "BaseTile.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "GLUtils.h"
#include "RasterRenderer.h"
#include "TextureInfo.h"
#include "TilesManager.h"
-#include <cutils/atomic.h>
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+// If the dirty portion of a tile exceeds this ratio, fully repaint.
+// Lower values give fewer partial repaints, thus fewer front-to-back
+// texture copies (cost will vary by device). It's a tradeoff between
+// the rasterization cost and the FBO texture recopy cost when using
+// GPU for the transfer queue.
+#define MAX_INVAL_AREA 0.6
namespace WebCore {
BaseTile::BaseTile(bool isLayerTile)
- : m_glWebViewState(0)
- , m_painter(0)
- , m_x(-1)
+ : 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_lastDirtyPicture(0)
+ , m_fullRepaint(true)
, m_isTexturePainted(false)
, m_isLayerTile(isLayerTile)
, m_drawCount(0)
@@ -76,20 +63,6 @@ BaseTile::BaseTile(bool isLayerTile)
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("BaseTile");
#endif
- m_currentDirtyAreaIndex = 0;
-
- // For EglImage Mode, the internal buffer should be 2.
- // For Surface Texture mode, we only need one.
- if (TilesManager::instance()->getSharedTextureMode() == EglImageMode)
- m_maxBufferNumber = 2;
- else
- m_maxBufferNumber = 1;
-
- m_dirtyArea = new SkRegion[m_maxBufferNumber];
- m_fullRepaint = new bool[m_maxBufferNumber];
- for (int i = 0; i < m_maxBufferNumber; i++)
- m_fullRepaint[i] = true;
-
m_renderer = BaseRenderer::createRenderer();
}
@@ -101,8 +74,6 @@ BaseTile::~BaseTile()
m_frontTexture->release(this);
delete m_renderer;
- delete[] m_dirtyArea;
- delete[] m_fullRepaint;
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("BaseTile");
@@ -111,10 +82,10 @@ BaseTile::~BaseTile()
// All the following functions must be called from the main GL thread.
-void BaseTile::setContents(TilePainter* painter, int x, int y, float scale)
+void BaseTile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile)
{
- if ((m_painter != painter)
- || (m_x != x)
+ // TODO: investigate whether below check/discard is necessary
+ if ((m_x != x)
|| (m_y != y)
|| (m_scale != scale)) {
// neither texture is relevant
@@ -122,11 +93,12 @@ void BaseTile::setContents(TilePainter* painter, int x, int y, float scale)
}
android::AutoMutex lock(m_atomicSync);
- m_painter = painter;
m_x = x;
m_y = y;
m_scale = scale;
m_drawCount = TilesManager::instance()->getDrawGLCount();
+ if (isExpandedPrefetchTile)
+ m_drawCount--; // deprioritize expanded painting region
}
void BaseTile::reserveTexture()
@@ -135,14 +107,14 @@ void BaseTile::reserveTexture()
android::AutoMutex lock(m_atomicSync);
if (texture && m_backTexture != texture) {
- XLOG("tile %p reserving texture %p, back was %p (front %p)",
- this, texture, m_backTexture, m_frontTexture);
+ ALOGV("tile %p reserving texture %p, back was %p (front %p)",
+ this, texture, m_backTexture, m_frontTexture);
m_state = Unpainted;
m_backTexture = texture;
}
if (m_state == UpToDate) {
- XLOG("moving tile %p to unpainted, since it reserved while up to date", this);
+ ALOGV("moving tile %p to unpainted, since it reserved while up to date", this);
m_dirty = true;
m_state = Unpainted;
}
@@ -150,13 +122,13 @@ void BaseTile::reserveTexture()
bool BaseTile::removeTexture(BaseTileTexture* texture)
{
- XLOG("%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... page %p",
+ this, texture, m_backTexture, m_frontTexture, m_page);
// We update atomically, so paintBitmap() can see the correct value
android::AutoMutex lock(m_atomicSync);
if (m_frontTexture == texture) {
if (m_state == UpToDate) {
- XLOG("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture);
+ ALOGV("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture);
m_state = Unpainted;
}
@@ -174,30 +146,21 @@ bool BaseTile::removeTexture(BaseTileTexture* texture)
return true;
}
-void BaseTile::markAsDirty(int unsigned pictureCount,
- const SkRegion& dirtyArea)
+void BaseTile::markAsDirty(const SkRegion& dirtyArea)
{
if (dirtyArea.isEmpty())
return;
android::AutoMutex lock(m_atomicSync);
- m_lastDirtyPicture = pictureCount;
- for (int i = 0; i < m_maxBufferNumber; i++)
- m_dirtyArea[i].op(dirtyArea, SkRegion::kUnion_Op);
+ m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op);
// 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;
@@ -217,7 +180,7 @@ void BaseTile::markAsDirty(int unsigned pictureCount,
} else if (m_state != Unpainted) {
// TODO: fix it so that they can paint while deferring the markAsDirty
// call (or block updates)
- XLOG("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d, page %p",
+ 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);
// prefetch tiles can be marked dirty while in the process of painting,
@@ -244,15 +207,16 @@ void BaseTile::setRepaintPending(bool pending)
m_repaintPending = pending;
}
-void BaseTile::draw(float transparency, SkRect& rect, float scale)
+bool BaseTile::drawGL(float opacity, const SkRect& rect, float scale,
+ const TransformationMatrix* transform)
{
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;
+ return false;
// Early return if set to un-usable in purpose!
m_atomicSync.lock();
@@ -260,27 +224,10 @@ void BaseTile::draw(float transparency, SkRect& rect, float scale)
m_atomicSync.unlock();
if (!isTexturePainted)
- return;
-
- TextureInfo* textureInfo = m_frontTexture->consumerLock();
- if (!textureInfo) {
- m_frontTexture->consumerRelease();
- return;
- }
-
- if (m_frontTexture->readyFor(this)) {
- if (isLayerTile() && m_painter && m_painter->transform())
- TilesManager::instance()->shader()->drawLayerQuad(*m_painter->transform(),
- rect, m_frontTexture->m_ownTextureId,
- transparency, true);
- else
- TilesManager::instance()->shader()->drawQuad(rect, m_frontTexture->m_ownTextureId,
- transparency);
- } else {
- XLOG("tile %p at %d, %d not readyfor (at draw),", this, m_x, m_y);
- }
+ return false;
- m_frontTexture->consumerRelease();
+ m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform);
+ return true;
}
bool BaseTile::isTileReady()
@@ -301,16 +248,7 @@ bool BaseTile::isTileReady()
if (m_state != ReadyToSwap && m_state != UpToDate)
return false;
- texture->consumerLock();
- bool ready = texture->readyFor(this);
- texture->consumerRelease();
-
- if (ready)
- return true;
-
- XLOG("tile %p at %d, %d not readyfor (at isTileReady)", this, m_x, m_y);
-
- return false;
+ return true;
}
bool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
@@ -342,7 +280,7 @@ bool BaseTile::isTileVisible(const IntRect& viewTileBounds)
}
// This is called from the texture generation thread
-void BaseTile::paintBitmap()
+void BaseTile::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
@@ -350,38 +288,31 @@ void BaseTile::paintBitmap()
m_atomicSync.lock();
bool dirty = m_dirty;
BaseTileTexture* texture = m_backTexture;
- SkRegion dirtyArea = m_dirtyArea[m_currentDirtyAreaIndex];
+ SkRegion dirtyArea = m_dirtyArea;
float scale = m_scale;
const int x = m_x;
const int y = m_y;
- TilePainter* painter = m_painter;
if (!dirty || !texture) {
m_atomicSync.unlock();
return;
}
if (m_state != Unpainted) {
- XLOG("Warning: started painting tile %p, but was at state %d, ft %p bt %p",
+ ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p",
this, m_state, m_frontTexture, m_backTexture);
}
m_state = PaintingStarted;
-
- texture->producerAcquireContext();
- TextureInfo* textureInfo = texture->producerLock();
+ TextureInfo* textureInfo = texture->getTextureInfo();
m_atomicSync.unlock();
// at this point we can safely check the ownership (if the texture got
// transferred to another BaseTile under us)
if (texture->owner() != this) {
- texture->producerRelease();
return;
}
- unsigned int pictureCount = 0;
-
// swap out the renderer if necessary
BaseRenderer::swapRendererIfNeeded(m_renderer);
-
// setup the common renderInfo fields;
TileRenderInfo renderInfo;
renderInfo.x = x;
@@ -399,82 +330,79 @@ void BaseTile::paintBitmap()
bool fullRepaint = false;
- if (m_fullRepaint[m_currentDirtyAreaIndex]
+ if (m_fullRepaint
|| textureInfo->m_width != tileWidth
|| textureInfo->m_height != tileHeight) {
fullRepaint = true;
}
- bool surfaceTextureMode = textureInfo->getSharedTextureMode() == SurfaceTextureMode;
-
- if (surfaceTextureMode)
- fullRepaint = true;
-
- while (!fullRepaint && !cliperator.done()) {
- SkRect realTileRect;
- SkRect dirtyRect;
- dirtyRect.set(cliperator.rect());
- bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
- scale, dirtyRect, realTileRect);
-
- // With SurfaceTexture, just repaint the entire tile if we intersect
- // TODO: Implement the partial invalidate in Surface Texture Mode
- if (intersect && surfaceTextureMode) {
- fullRepaint = true;
- break;
- }
-
- if (intersect && !surfaceTextureMode) {
- // initialize finalRealRect to the rounded values of realTileRect
- SkIRect finalRealRect;
- realTileRect.roundOut(&finalRealRect);
-
- // stash the int values of the current width and height
- const int iWidth = finalRealRect.width();
- const int iHeight = finalRealRect.height();
-
- if (iWidth == tileWidth || iHeight == tileHeight) {
- fullRepaint = true;
- break;
+ // For now, only do full repaint
+ fullRepaint = true;
+
+ if (!fullRepaint) {
+ // compute the partial inval area
+ SkIRect totalRect;
+ totalRect.set(0, 0, 0, 0);
+ float tileSurface = tileWidth * tileHeight;
+ float tileSurfaceCap = MAX_INVAL_AREA * tileSurface;
+
+ // We join all the invals in the same tile for now
+ while (!fullRepaint && !cliperator.done()) {
+ SkRect realTileRect;
+ SkRect dirtyRect;
+ dirtyRect.set(cliperator.rect());
+ bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
+ scale, dirtyRect, realTileRect);
+ if (intersect) {
+ // initialize finalRealRect to the rounded values of realTileRect
+ SkIRect finalRealRect;
+ realTileRect.roundOut(&finalRealRect);
+
+ // stash the int values of the current width and height
+ const int iWidth = finalRealRect.width();
+ const int iHeight = finalRealRect.height();
+
+ if (iWidth == tileWidth || iHeight == tileHeight) {
+ fullRepaint = true;
+ break;
+ }
+
+ // translate the rect into tile space coordinates
+ finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
+ finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
+ finalRealRect.fRight = finalRealRect.fLeft + iWidth;
+ finalRealRect.fBottom = finalRealRect.fTop + iHeight;
+ totalRect.join(finalRealRect);
+ float repaintSurface = totalRect.width() * totalRect.height();
+
+ if (repaintSurface > tileSurfaceCap) {
+ fullRepaint = true;
+ break;
+ }
}
- // translate the rect into tile space coordinates
- finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
- finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
- finalRealRect.fRight = finalRealRect.fLeft + iWidth;
- finalRealRect.fBottom = finalRealRect.fTop + iHeight;
-
- renderInfo.invalRect = &finalRealRect;
- renderInfo.measurePerf = false;
-
- pictureCount = m_renderer->renderTiledContent(renderInfo);
+ cliperator.next();
}
- cliperator.next();
+ if (!fullRepaint) {
+ renderInfo.invalRect = &totalRect;
+ m_renderer->renderTiledContent(renderInfo);
+ }
}
// Do a full repaint if needed
if (fullRepaint) {
- SkIRect rect;
- rect.set(0, 0, tileWidth, tileHeight);
-
- renderInfo.invalRect = &rect;
- renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator();
-
- pictureCount = m_renderer->renderTiledContent(renderInfo);
+ renderInfo.invalRect = 0;
+ m_renderer->renderTiledContent(renderInfo);
}
m_atomicSync.lock();
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- texture->setTile(textureInfo, x, y, scale, painter, pictureCount);
-#endif
- texture->producerReleaseAndSwap();
if (texture == m_backTexture) {
m_isTexturePainted = true;
// set the fullrepaint flags
- m_fullRepaint[m_currentDirtyAreaIndex] = false;
+ m_fullRepaint = false;
// The various checks to see if we are still dirty...
@@ -484,27 +412,19 @@ void BaseTile::paintBitmap()
m_dirty = true;
if (fullRepaint)
- m_dirtyArea[m_currentDirtyAreaIndex].setEmpty();
+ m_dirtyArea.setEmpty();
else
- m_dirtyArea[m_currentDirtyAreaIndex].op(dirtyArea, SkRegion::kDifference_Op);
+ m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op);
- if (!m_dirtyArea[m_currentDirtyAreaIndex].isEmpty())
+ if (!m_dirtyArea.isEmpty())
m_dirty = true;
- // Now we can swap the dirty areas
- // TODO: For surface texture in Async mode, the index will be updated
- // according to the current buffer just dequeued.
- m_currentDirtyAreaIndex = (m_currentDirtyAreaIndex+1) % m_maxBufferNumber;
-
- if (!m_dirtyArea[m_currentDirtyAreaIndex].isEmpty())
- m_dirty = true;
-
- XLOG("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
+ ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
validatePaint();
} else {
- XLOG("tile %p no longer owns texture %p, m_state %d. ft %p bt %p",
- this, texture, m_state, m_frontTexture, m_backTexture);
+ ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p",
+ this, texture, m_state, m_frontTexture, m_backTexture);
}
m_atomicSync.unlock();
@@ -512,8 +432,8 @@ void BaseTile::paintBitmap()
void BaseTile::discardTextures() {
android::AutoMutex lock(m_atomicSync);
- XLOG("%p discarding bt %p, ft %p",
- this, m_backTexture, m_frontTexture);
+ ALOGV("%p discarding bt %p, ft %p",
+ this, m_backTexture, m_frontTexture);
if (m_frontTexture) {
m_frontTexture->release(this);
m_frontTexture = 0;
@@ -522,10 +442,9 @@ void BaseTile::discardTextures() {
m_backTexture->release(this);
m_backTexture = 0;
}
- for (int i = 0; i < m_maxBufferNumber; i++) {
- m_dirtyArea[i].setEmpty();
- m_fullRepaint[i] = true;
- }
+ m_dirtyArea.setEmpty();
+ m_fullRepaint = true;
+
m_dirty = true;
m_state = Unpainted;
}
@@ -550,8 +469,8 @@ bool BaseTile::swapTexturesIfNeeded() {
m_frontTexture = m_backTexture;
m_backTexture = 0;
m_state = UpToDate;
- XLOG("display texture for %p at %d, %d front is now %p, back is %p",
- this, m_x, m_y, m_frontTexture, m_backTexture);
+ ALOGV("display texture for %p at %d, %d front is now %p, back is %p",
+ this, m_x, m_y, m_frontTexture, m_backTexture);
return true;
}
@@ -566,8 +485,8 @@ void BaseTile::backTextureTransfer() {
m_state = ReadyToSwap;
else {
// shouldn't have transferred a tile in any other state, log
- XLOG("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d",
- this, m_x, m_y, m_state);
+ ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d",
+ this, m_x, m_y, m_state);
}
}
@@ -589,10 +508,13 @@ void BaseTile::validatePaint() {
// when both have happened, mark as 'ReadyToSwap'
if (m_state == PaintingStarted)
m_state = ValidatedUntransferred;
- else if (m_state == TransferredUnvalidated)
+ else if (m_state == TransferredUnvalidated) {
+ // When the backTexture has been marked pureColor, we will skip the
+ // transfer and marked as ReadyToSwap, in this case, we don't want
+ // to reset m_dirty bit to true.
m_state = ReadyToSwap;
- else {
- XLOG("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d",
+ } else {
+ ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d",
this, m_x, m_y, m_state);
// failed transferring, in which case mark dirty (since
// paintBitmap() may have cleared m_dirty)
@@ -600,11 +522,11 @@ void BaseTile::validatePaint() {
}
if (m_deferredDirty) {
- XLOG("Note: deferred dirty flag set, possibly a missed paint on tile %p", this);
+ ALOGV("Note: deferred dirty flag set, possibly a missed paint on tile %p", this);
m_deferredDirty = false;
}
} else {
- XLOG("Note: paint was unsuccessful.");
+ ALOGV("Note: paint was unsuccessful.");
m_state = Unpainted;
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h
index 685ca43..93ec287 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.h
+++ b/Source/WebCore/platform/graphics/android/BaseTile.h
@@ -39,7 +39,6 @@
namespace WebCore {
class TextureInfo;
-class TiledPage;
class BaseTileTexture;
class GLWebViewState;
@@ -54,7 +53,7 @@ class GLWebViewState;
* the BaseLayer's most recent PictureSet to a bitmap which is then uploaded
* to the GPU.
* 3. After the bitmap is uploaded to the GPU the main GL thread then uses the
- * tile's draw() function to display the tile to the screen.
+ * tile's drawGL() function to display the tile to the screen.
* 4. Steps 2-3 are repeated as necessary.
* 5. The tile is destroyed when the user navigates to a new page.
*
@@ -94,27 +93,27 @@ public:
bool isLayerTile() { return m_isLayerTile; }
- void setContents(TilePainter* painter, 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 draw(float transparency, SkRect& rect, float scale);
+ // Return false when real draw didn't happen for any reason.
+ bool drawGL(float opacity, const SkRect& rect, float scale,
+ const TransformationMatrix* transform);
// the only thread-safe function called by the background thread
- void paintBitmap();
+ void paintBitmap(TilePainter* painter);
bool intersectWithRect(int x, int y, int tileWidth, int tileHeight,
float scale, const SkRect& dirtyRect,
SkRect& realTileRect);
bool isTileVisible(const IntRect& viewTileBounds);
- void markAsDirty(const unsigned int pictureCount,
- const SkRegion& dirtyArea);
+ 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; }
@@ -132,25 +131,15 @@ 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; }
- TilePainter* painter() { return m_painter; }
private:
void validatePaint();
- GLWebViewState* m_glWebViewState;
-
- TilePainter* m_painter;
int m_x;
int m_y;
- TiledPage* m_page;
-
// The remaining variables can be updated throughout the lifetime of the object
BaseTileTexture* m_frontTexture;
@@ -166,16 +155,10 @@ private:
// used to signal that a repaint is pending
bool m_repaintPending;
- // stores the id of the latest picture from webkit that caused this tile to
- // become dirty. A tile is no longer dirty when it has been painted with a
- // picture that is newer than this value.
- unsigned int m_lastDirtyPicture;
// store the dirty region
- SkRegion* m_dirtyArea;
- bool* m_fullRepaint;
- int m_maxBufferNumber;
- int m_currentDirtyAreaIndex;
+ SkRegion m_dirtyArea;
+ bool m_fullRepaint;
// flag used to know if we have a texture that was painted at least once
bool m_isTexturePainted;
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
index caaf116..f7f9370 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
@@ -23,47 +23,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "BaseTileTexture"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "BaseTileTexture.h"
+#include "AndroidLog.h"
#include "BaseTile.h"
#include "ClassTracker.h"
-#include "DeleteTextureOperation.h"
#include "GLUtils.h"
#include "TilesManager.h"
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTileTexture", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTileTexture", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
- : DoubleBufferedTexture(eglGetCurrentContext(),
- TilesManager::instance()->getSharedTextureMode())
- , m_owner(0)
- , m_busy(false)
+ : m_owner(0)
+ , m_isPureColor(false)
{
m_size.set(w, h);
m_ownTextureId = 0;
- // Make sure they are created on the UI thread.
- TilesManager::instance()->transferQueue()->initSharedSurfaceTextures(w, h);
-
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("BaseTileTexture");
#endif
@@ -71,10 +51,6 @@ BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
BaseTileTexture::~BaseTileTexture()
{
- if (m_sharedTextureMode == EglImageMode) {
- SharedTexture* textures[3] = { m_textureA, m_textureB, 0 };
- destroyTextures(textures);
- }
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("BaseTileTexture");
#endif
@@ -98,71 +74,6 @@ void BaseTileTexture::discardGLTexture()
}
}
-void BaseTileTexture::destroyTextures(SharedTexture** textures)
-{
- int x = 0;
- while (textures[x]) {
- // We need to delete the source texture and EGLImage in the texture
- // generation thread. In theory we should be able to delete the EGLImage
- // from either thread, but it currently throws an error if not deleted
- // in the same EGLContext from which it was created.
- textures[x]->lock();
- DeleteTextureOperation* operation = new DeleteTextureOperation(
- textures[x]->getSourceTextureId(), textures[x]->getEGLImage());
- textures[x]->unlock();
- TilesManager::instance()->scheduleOperation(operation);
- x++;
- }
-}
-
-TextureInfo* BaseTileTexture::producerLock()
-{
- m_busyLock.lock();
- m_busy = true;
- m_busyLock.unlock();
- return DoubleBufferedTexture::producerLock();
-}
-
-void BaseTileTexture::producerRelease()
-{
- DoubleBufferedTexture::producerRelease();
- setNotBusy();
-}
-
-void BaseTileTexture::producerReleaseAndSwap()
-{
- DoubleBufferedTexture::producerReleaseAndSwap();
- setNotBusy();
-}
-
-void BaseTileTexture::setNotBusy()
-{
- android::Mutex::Autolock lock(m_busyLock);
- m_busy = false;
- m_busyCond.signal();
-}
-
-bool BaseTileTexture::busy()
-{
- android::Mutex::Autolock lock(m_busyLock);
- return m_busy;
-}
-
-void BaseTileTexture::producerUpdate(TextureInfo* textureInfo, const SkBitmap& bitmap)
-{
- // no need to upload a texture since the bitmap is empty
- if (!bitmap.width() && !bitmap.height()) {
- producerRelease();
- return;
- }
-
- // After the tiled layer checked in, this is not called anyway.
- // TODO: cleanup the old code path for layer painting
- // GLUtils::paintTextureWithBitmap(info, m_size, bitmap, 0, 0);
-
- producerReleaseAndSwap();
-}
-
bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
{
if (m_owner == owner)
@@ -173,39 +84,21 @@ bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
{
- // if the writable texture is busy (i.e. currently being written to) then we
- // can't change the owner out from underneath that texture
- m_busyLock.lock();
- while (m_busy && force)
- m_busyCond.wait(m_busyLock);
- bool busy = m_busy;
- m_busyLock.unlock();
-
- if (!busy) {
- // if we are not busy we can try to remove the texture from the layer;
- // LayerAndroid::removeTexture() is protected by the same lock as
- // LayerAndroid::paintBitmapGL(), so either we execute removeTexture()
- // first and paintBitmapGL() will bail out, or we execute it after,
- // and paintBitmapGL() will mark the texture as busy before
- // relinquishing the lock. LayerAndroid::removeTexture() will call
- // BaseTileTexture::release(), which will then do nothing
- // if the texture is busy and we then don't return true.
- bool proceed = true;
- if (m_owner && m_owner != owner)
- proceed = m_owner->removeTexture(this);
+ bool proceed = true;
+ if (m_owner && m_owner != owner)
+ proceed = m_owner->removeTexture(this);
- if (proceed) {
- m_owner = owner;
- return true;
- }
+ if (proceed) {
+ m_owner = owner;
+ return true;
}
+
return false;
}
bool BaseTileTexture::release(TextureOwner* owner)
{
- android::Mutex::Autolock lock(m_busyLock);
- XLOG("texture %p releasing tile %p, m_owner %p, m_busy %d", this, owner, m_owner, m_busy);
+ ALOGV("texture %p releasing tile %p, m_owner %p", this, owner, m_owner);
if (m_owner != owner)
return false;
@@ -213,61 +106,33 @@ bool BaseTileTexture::release(TextureOwner* owner)
return true;
}
-void BaseTileTexture::setTile(TextureInfo* info, int x, int y,
- float scale, TilePainter* painter,
- unsigned int pictureCount)
-{
- TextureTileInfo* textureInfo = m_texturesInfo.get(getWriteableTexture());
- if (!textureInfo) {
- textureInfo = new TextureTileInfo();
- }
- textureInfo->m_x = x;
- textureInfo->m_y = y;
- textureInfo->m_scale = scale;
- textureInfo->m_painter = painter;
- textureInfo->m_picture = pictureCount;
- m_texturesInfo.set(getWriteableTexture(), textureInfo);
-}
-
-float BaseTileTexture::scale()
+void BaseTileTexture::transferComplete()
{
- TextureTileInfo* textureInfo = &m_ownTextureTileInfo;
- return textureInfo->m_scale;
-}
-
-// This function + TilesManager::addItemInTransferQueue() is replacing the
-// setTile().
-void BaseTileTexture::setOwnTextureTileInfoFromQueue(const TextureTileInfo* info)
-{
- m_ownTextureTileInfo.m_x = info->m_x;
- m_ownTextureTileInfo.m_y = info->m_y;
- m_ownTextureTileInfo.m_scale = info->m_scale;
- m_ownTextureTileInfo.m_painter = info->m_painter;
- m_ownTextureTileInfo.m_picture = info->m_picture;
- m_ownTextureTileInfo.m_inverted = TilesManager::instance()->invertedScreen();
if (m_owner) {
BaseTile* owner = static_cast<BaseTile*>(m_owner);
owner->backTextureTransfer();
- }
-
+ } else
+ ALOGE("ERROR: owner missing after transfer of texture %p", this);
}
-bool BaseTileTexture::readyFor(BaseTile* baseTile)
+void BaseTileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity,
+ const TransformationMatrix* transform)
{
- const TextureTileInfo* info = &m_ownTextureTileInfo;
- if (info &&
- (info->m_x == baseTile->x()) &&
- (info->m_y == baseTile->y()) &&
- (info->m_scale == baseTile->scale()) &&
- (info->m_painter == baseTile->painter()) &&
- (info->m_inverted == TilesManager::instance()->invertedScreen()))
- return true;
-
- XLOG("texture %p readyFor return false for tile x, y (%d %d) texId %d ,"
- " BaseTileTexture %p, BaseTile is %p, SCALE %f, painter %p, inv %d",
- this, baseTile->x(), baseTile->y(), m_ownTextureId, this, baseTile,
- baseTile->scale(), baseTile->painter(), TilesManager::instance()->invertedScreen());
- return false;
+ 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);
+ }
+ } else {
+ if (isPureColor())
+ shader->drawQuad(rect, 0, opacity, pureColor());
+ else
+ shader->drawQuad(rect, m_ownTextureId, opacity);
+ }
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index cd8e78b..d8737b3 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -26,10 +26,11 @@
#ifndef BaseTileTexture_h
#define BaseTileTexture_h
-#include "DoubleBufferedTexture.h"
#include "GLWebViewState.h"
+#include "TextureInfo.h"
#include "TextureOwner.h"
#include "TilePainter.h"
+#include <GLES2/gl2.h>
#include <SkBitmap.h>
class SkCanvas;
@@ -38,101 +39,57 @@ namespace WebCore {
class BaseTile;
-class TextureTileInfo {
-public:
- TextureTileInfo()
- : m_x(-1)
- , m_y(-1)
- , m_layerId(-1)
- , m_scale(0)
- , m_texture(0)
- , m_painter(0)
- , m_picture(0)
- , m_inverted(false)
- {
- }
- int m_x;
- int m_y;
- int m_layerId;
- float m_scale;
- TextureInfo* m_texture;
- TilePainter* m_painter;
- unsigned int m_picture;
- bool m_inverted;
-};
-
-// DoubleBufferedTexture using a SkBitmap as backing mechanism
-class BaseTileTexture : public DoubleBufferedTexture {
+class BaseTileTexture {
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();
- // these functions override their parent
- virtual TextureInfo* producerLock();
- virtual void producerRelease();
- virtual void producerReleaseAndSwap();
-
- // updates the texture with current bitmap and releases (and if needed also
- // swaps) the texture.
- virtual void producerUpdate(TextureInfo* textureInfo, const SkBitmap& bitmap);
-
// allows consumer thread to assign ownership of the texture to the tile. It
// returns false if ownership cannot be transferred because the tile is busy
bool acquire(TextureOwner* owner, bool force = false);
bool release(TextureOwner* owner);
- // removes Tile->Texture, and Texture->Tile links to fully discard the texture
- void releaseAndRemoveFromTile();
-
// set the texture owner if not busy. Return false if busy, true otherwise.
bool setOwner(TextureOwner* owner, bool force = false);
// private member accessor functions
TextureOwner* owner() { return m_owner; } // only used by the consumer thread
- bool busy();
- void setNotBusy();
-
const SkSize& getSize() const { return m_size; }
- void setTile(TextureInfo* info, int x, int y, float scale,
- TilePainter* painter, unsigned int pictureCount);
- 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
void requireGLTexture();
void discardGLTexture();
- void setOwnTextureTileInfoFromQueue(const TextureTileInfo* info);
+ void transferComplete();
-protected:
- HashMap<SharedTexture*, TextureTileInfo*> m_texturesInfo;
+ TextureInfo* getTextureInfo() { return &m_ownTextureInfo; }
-private:
- void destroyTextures(SharedTexture** textures);
- TextureTileInfo m_ownTextureTileInfo;
+ // Make sure the following pureColor getter/setter are only read/written
+ // in UI thread. Therefore no need for a lock.
+ void setPure(bool pure) { m_isPureColor = pure; }
+ bool isPureColor() {return m_isPureColor; }
+ void setPureColor(const Color& color) { m_pureColor = color; setPure(true); }
+ Color pureColor() { return m_pureColor; }
+ void drawGL(bool isLayer, const SkRect& rect, float opacity,
+ const TransformationMatrix* transform);
+private:
+ TextureInfo m_ownTextureInfo;
SkSize m_size;
SkBitmap::Config m_config;
// BaseTile owning the texture, only modified by UI thread
TextureOwner* m_owner;
- // This values signals that the texture is currently in use by the consumer.
- // This allows us to prevent the owner of the texture from changing while the
- // consumer is holding a lock on the texture.
- bool m_busy;
- // We mutex protect the reads/writes of m_busy to ensure that we are reading
- // the most up-to-date value even across processors in an SMP system.
- android::Mutex m_busyLock;
- // We use this condition variable to signal that the texture
- // is not busy anymore
- android::Condition m_busyCond;
+ // When the whole tile is single color, skip the transfer queue and draw
+ // it directly through shader.
+ bool m_isPureColor;
+ Color m_pureColor;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/CanvasLayer.cpp b/Source/WebCore/platform/graphics/android/CanvasLayer.cpp
new file mode 100644
index 0000000..5409fef
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/CanvasLayer.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 "CanvasLayer"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "CanvasLayer.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "AndroidLog.h"
+#include "CanvasTexture.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());
+ TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, rect,
+ m_texture->texture(), 1, true, GL_TEXTURE_EXTERNAL_OES);
+ }
+ 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/TilesTracker.h b/Source/WebCore/platform/graphics/android/CanvasLayer.h
index 202d072..532dbf2 100644
--- a/Source/WebCore/platform/graphics/android/TilesTracker.h
+++ b/Source/WebCore/platform/graphics/android/CanvasLayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, 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,63 +23,59 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TilesTracker_h
-#define TilesTracker_h
+#ifndef CanvasLayer_h
+#define CanvasLayer_h
#if USE(ACCELERATED_COMPOSITING)
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
+#include "HTMLCanvasElement.h"
+#include "ImageData.h"
+#include "LayerAndroid.h"
+#include "RenderLayer.h"
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesTracker", __VA_ARGS__)
+#include <wtf/RefPtr.h>
namespace WebCore {
-class TilesTracker {
+class CanvasTexture;
+
+class CanvasLayer : public LayerAndroid, private CanvasObserver {
public:
- TilesTracker() {
- clear();
- }
-
- void track(bool ready, bool haveTexture) {
- m_nbTextures++;
- if (ready)
- m_nbTexturesReady++;
- else
- m_nbTexturesNotReady++;
- if (haveTexture)
- m_nbTexturesUsed++;
- }
-
- void clear() {
- m_nbLayers = 0;
- m_nbVisibleLayers = 0;
- m_nbTextures = 0;
- m_nbTexturesReady = 0;
- m_nbTexturesNotReady = 0;
- m_nbTexturesUsed = 0;
- }
-
- void trackLayer() { m_nbLayers++; }
- void trackVisibleLayer() { m_nbVisibleLayers++; }
-
- void showTrackTextures() {
- XLOG("We had %d/%d layers needing %d textures, we had %d, %d were ready, %d were not",
- m_nbLayers, m_nbVisibleLayers, m_nbTextures, m_nbTexturesUsed, m_nbTexturesReady, m_nbTexturesNotReady);
- }
+ 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:
- int m_nbLayers;
- int m_nbVisibleLayers;
- int m_nbTextures;
- int m_nbTexturesReady;
- int m_nbTexturesNotReady;
- int m_nbTexturesUsed;
+ 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 // TilesTracker_h
+
+#endif // CanvasLayer_h
diff --git a/Source/WebCore/platform/graphics/android/CanvasTexture.cpp b/Source/WebCore/platform/graphics/android/CanvasTexture.cpp
new file mode 100644
index 0000000..e4b2bc6
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/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/CanvasTexture.h b/Source/WebCore/platform/graphics/android/CanvasTexture.h
new file mode 100644
index 0000000..98962a0
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/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/ClassTracker.cpp b/Source/WebCore/platform/graphics/android/ClassTracker.cpp
index eb810a8..98e33d9 100644
--- a/Source/WebCore/platform/graphics/android/ClassTracker.cpp
+++ b/Source/WebCore/platform/graphics/android/ClassTracker.cpp
@@ -23,19 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "ClassTracker"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "ClassTracker.h"
+#include "AndroidLog.h"
#include "LayerAndroid.h"
#include "TilesManager.h"
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ClassTracker", __VA_ARGS__)
-
#define DEBUG_LAYERS
#undef DEBUG_LAYERS
@@ -85,12 +84,12 @@ void ClassTracker::remove(LayerAndroid* layer)
void ClassTracker::show()
{
android::Mutex::Autolock lock(m_lock);
- XLOG("*** Tracking %d classes ***", m_classes.size());
+ ALOGD("*** Tracking %d classes ***", m_classes.size());
for (HashMap<String, int>::iterator iter = m_classes.begin(); iter != m_classes.end(); ++iter) {
- XLOG("class %s has %d instances",
- iter->first.latin1().data(), iter->second);
+ ALOGD("class %s has %d instances",
+ iter->first.latin1().data(), iter->second);
}
- XLOG("*** %d Layers ***", m_layers.size());
+ ALOGD("*** %d Layers ***", m_layers.size());
int nbTextures = 0;
int nbAllocatedTextures = 0;
int nbLayerTextures = 0;
@@ -98,23 +97,23 @@ void ClassTracker::show()
float textureSize = 256 * 256 * 4 / 1024.0 / 1024.0;
TilesManager::instance()->gatherTexturesNumbers(&nbTextures, &nbAllocatedTextures,
&nbLayerTextures, &nbAllocatedLayerTextures);
- XLOG("*** textures: %d/%d (%.2f Mb), layer textures: %d/%d (%.2f Mb) : total used %.2f Mb",
- nbAllocatedTextures, nbTextures,
- nbAllocatedTextures * textureSize,
- nbAllocatedLayerTextures, nbLayerTextures,
- nbAllocatedLayerTextures * textureSize,
- (nbAllocatedTextures + nbAllocatedLayerTextures) * textureSize);
+ ALOGD("*** textures: %d/%d (%.2f Mb), layer textures: %d/%d (%.2f Mb) : total used %.2f Mb",
+ nbAllocatedTextures, nbTextures,
+ nbAllocatedTextures * textureSize,
+ nbAllocatedLayerTextures, nbLayerTextures,
+ nbAllocatedLayerTextures * textureSize,
+ (nbAllocatedTextures + nbAllocatedLayerTextures) * textureSize);
#ifdef DEBUG_LAYERS
for (unsigned int i = 0; i < m_layers.size(); i++) {
LayerAndroid* layer = m_layers[i];
- XLOG("[%d/%d] layer %x (%.2f, %.2f) of type %d, refcount(%d) has texture %x has image ref %x (%x) root: %x parent: %x",
- i, m_layers.size(), layer,
- layer->getWidth(), layer->getHeight(),
- layer->type(), layer->getRefCnt(),
- layer->texture(), layer->imageRef(),
- layer->imageTexture(), (LayerAndroid*) layer->getRootLayer(),
- (LayerAndroid*) layer->getParent());
+ ALOGD("[%d/%d] layer %x (%.2f, %.2f) of type %d, refcount(%d) has texture %x has image ref %x (%x) root: %x parent: %x",
+ i, m_layers.size(), layer,
+ layer->getWidth(), layer->getHeight(),
+ layer->type(), layer->getRefCnt(),
+ layer->texture(), layer->imageRef(),
+ layer->imageTexture(), (LayerAndroid*) layer->getRootLayer(),
+ (LayerAndroid*) layer->getParent());
}
#endif
}
diff --git a/Source/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp b/Source/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
deleted file mode 100644
index 4c5af9e..0000000
--- a/Source/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
+++ /dev/null
@@ -1,217 +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.
- */
-
-#include "config.h"
-#include "DoubleBufferedTexture.h"
-
-#include "ClassTracker.h"
-#include "GLUtils.h"
-
-#define LOG_NDEBUG 1
-#define LOG_TAG "DoubleBufferedTexture.cpp"
-#include <utils/Log.h>
-
-namespace WebCore {
-
-DoubleBufferedTexture::DoubleBufferedTexture(EGLContext sharedContext, SharedTextureMode mode)
-{
- m_sharedTextureMode = mode;
-
- m_textureA = new SharedTexture(m_sharedTextureMode);
- if (m_sharedTextureMode == EglImageMode)
- m_textureB = new SharedTexture(m_sharedTextureMode);
- else
- m_textureB = 0;
-
- m_display = eglGetCurrentDisplay();
- m_pContext = EGL_NO_CONTEXT;
- m_cContext = sharedContext;
- m_writeableTexture = m_textureA;
- m_lockedConsumerTexture = GL_NO_TEXTURE;
- m_supportsEGLImage = GLUtils::isEGLImageSupported();
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("DoubleBufferedTexture");
-#endif
-}
-
-DoubleBufferedTexture::~DoubleBufferedTexture()
-{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("DoubleBufferedTexture");
-#endif
- delete m_textureA;
- delete m_textureB;
-}
-
-SharedTexture* DoubleBufferedTexture::getWriteableTexture()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return m_textureA;
- return reinterpret_cast<SharedTexture*>(
- android_atomic_release_load((int32_t*)&m_writeableTexture));
-}
-
-SharedTexture* DoubleBufferedTexture::getReadableTexture()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return m_textureA;
- return (getWriteableTexture() != m_textureA) ? m_textureA : m_textureB;
-}
-
-EGLContext DoubleBufferedTexture::producerAcquireContext()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return EGL_NO_CONTEXT;
-
- if (m_pContext != EGL_NO_CONTEXT) {
- LOGV("AquireContext has previously generated a context.\n");
- return m_pContext;
- }
-
- // check to see if a context already exists on this thread
- EGLContext context = eglGetCurrentContext();
-
- // if no context exists then create one
- if (context == EGL_NO_CONTEXT) {
- EGLContext sharedContext = m_supportsEGLImage ? EGL_NO_CONTEXT : m_cContext;
- context = GLUtils::createBackgroundContext(sharedContext);
- }
-
- if (context == EGL_NO_CONTEXT) {
- LOGE("eglCreateContext failed");
- return EGL_NO_CONTEXT;
- }
-
- // initialize the producer's textures
- m_textureA->lock();
- if (m_sharedTextureMode == EglImageMode)
- m_textureB->lock();
-
- m_textureA->initSourceTexture();
- LOGV("Initialized Textures A (%d)", m_textureA->getSourceTextureId());
- if (m_sharedTextureMode == EglImageMode) {
- m_textureB->initSourceTexture();
- LOGV("Initialized Textures B (%d)", m_textureB->getSourceTextureId());
- }
-
- m_textureA->unlock();
- if (m_sharedTextureMode == EglImageMode)
- m_textureB->unlock();
-
- m_pContext = context;
- return context;
-}
-
-// For MediaTexture only
-void DoubleBufferedTexture::producerDeleteTextures()
-{
- m_textureA->lock();
- if (m_sharedTextureMode == EglImageMode)
- m_textureB->lock();
-
- LOGV("Deleting Producer Textures A (%d)", m_textureA->getSourceTextureId());
- m_textureA->deleteSourceTexture();
- if (m_sharedTextureMode == EglImageMode){
- LOGV("Deleting Producer Textures B (%d)", m_textureB->getSourceTextureId());
- m_textureB->deleteSourceTexture();
- }
-
- m_textureA->unlock();
- if (m_sharedTextureMode == EglImageMode)
- m_textureB->unlock();
-}
-
-// For MediaTexture only
-void DoubleBufferedTexture::consumerDeleteTextures()
-{
- m_textureA->lock();
- if (m_sharedTextureMode == EglImageMode)
- m_textureB->lock();
-
- LOGV("Deleting Consumer Textures A (%d)", m_textureA->getTargetTextureId());
- m_textureA->deleteTargetTexture();
- if (m_sharedTextureMode == EglImageMode) {
- LOGV("Deleting Consumer Textures B (%d)", m_textureB->getTargetTextureId());
- m_textureB->deleteTargetTexture();
- }
-
- m_textureA->unlock();
- if (m_sharedTextureMode == EglImageMode)
- m_textureB->unlock();
-}
-
-TextureInfo* DoubleBufferedTexture::producerLock()
-{
- SharedTexture* sharedTex = getWriteableTexture();
- LOGV("Acquiring P Lock (%d)", sharedTex->getSourceTextureId());
- TextureInfo* texInfo = sharedTex->lockSource();
- LOGV("Acquired P Lock");
-
- return texInfo;
-}
-
-void DoubleBufferedTexture::producerRelease()
-{
- // get the writable texture and unlock it
- SharedTexture* sharedTex = getWriteableTexture();
- LOGV("Releasing P Lock (%d)", sharedTex->getSourceTextureId());
- sharedTex->releaseSource();
- LOGV("Released P Lock (%d)", sharedTex->getSourceTextureId());
-}
-
-void DoubleBufferedTexture::producerReleaseAndSwap()
-{
- producerRelease();
- if (m_sharedTextureMode == EglImageMode) {
- // swap the front and back buffers using an atomic op for the memory barrier
- android_atomic_acquire_store((int32_t)getReadableTexture(), (int32_t*)&m_writeableTexture);
- }
-}
-
-TextureInfo* DoubleBufferedTexture::consumerLock()
-{
- SharedTexture* sharedTex = getReadableTexture();
- LOGV("Acquiring C Lock (%d)", sharedTex->getSourceTextureId());
- m_lockedConsumerTexture = sharedTex;
-
- TextureInfo* texInfo = sharedTex->lockTarget();
- LOGV("Acquired C Lock");
-
- if (!texInfo)
- LOGV("Released C Lock (Empty)");
-
- return texInfo;
-}
-
-void DoubleBufferedTexture::consumerRelease()
-{
- // we must check to see what texture the consumer had locked since the
- // producer may have swapped out the readable buffer
- SharedTexture* sharedTex = m_lockedConsumerTexture;
- sharedTex->releaseTarget();
- LOGV("Released C Lock (%d)", sharedTex->getSourceTextureId());
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/DumpLayer.cpp b/Source/WebCore/platform/graphics/android/DumpLayer.cpp
new file mode 100644
index 0000000..5551965
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/DumpLayer.cpp
@@ -0,0 +1,83 @@
+#include "config.h"
+#include "DumpLayer.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+void lwrite(FILE* file, const char* str)
+{
+ fwrite(str, sizeof(char), strlen(str), file);
+}
+
+void writeIndent(FILE* file, int indentLevel)
+{
+ if (indentLevel)
+ fprintf(file, "%*s", indentLevel*2, " ");
+}
+
+void writeln(FILE* file, int indentLevel, const char* str)
+{
+ writeIndent(file, indentLevel);
+ lwrite(file, str);
+ lwrite(file, "\n");
+}
+
+void writeIntVal(FILE* file, int indentLevel, const char* str, int value)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = %d;\n", str, value);
+}
+
+void writeHexVal(FILE* file, int indentLevel, const char* str, int value)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = %x;\n", str, value);
+}
+
+void writeFloatVal(FILE* file, int indentLevel, const char* str, float value)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = %.3f;\n", str, value);
+}
+
+void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { x = %.3f; y = %.3f; };\n", str, point.fX, point.fY);
+}
+
+void writeIntPoint(FILE* file, int indentLevel, const char* str, IntPoint point)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { x = %d; y = %d; };\n", str, point.x(), point.y());
+}
+
+void writeSize(FILE* file, int indentLevel, const char* str, SkSize size)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height());
+}
+
+void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n",
+ str, rect.fLeft, rect.fTop, rect.width(), rect.height());
+}
+
+void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f),"
+ "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) };\n",
+ str,
+ matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
+ matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(),
+ matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(),
+ matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44());
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/DumpLayer.h b/Source/WebCore/platform/graphics/android/DumpLayer.h
new file mode 100644
index 0000000..5b30952
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/DumpLayer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DumpLayer_h
+#define DumpLayer_h
+
+#include "IntPoint.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkSize.h"
+#include "TransformationMatrix.h"
+
+// Debug tools : dump the layers tree in a file.
+// The format is simple:
+// properties have the form: key = value;
+// all statements are finished with a semi-colon.
+// value can be:
+// - int
+// - float
+// - array of elements
+// - composed type
+// a composed type enclose properties in { and }
+// an array enclose composed types in { }, separated with a comma.
+// exemple:
+// {
+// x = 3;
+// y = 4;
+// value = {
+// x = 3;
+// y = 4;
+// };
+// anarray = [
+// { x = 3; },
+// { y = 4; }
+// ];
+// }
+
+namespace WebCore {
+
+void lwrite(FILE* file, const char* str);
+void writeIndent(FILE* file, int indentLevel);
+void writeln(FILE* file, int indentLevel, const char* str);
+void writeIntVal(FILE* file, int indentLevel, const char* str, int value);
+void writeHexVal(FILE* file, int indentLevel, const char* str, int value);
+void writeFloatVal(FILE* file, int indentLevel, const char* str, float value);
+void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point);
+void writeIntPoint(FILE* file, int indentLevel, const char* str, IntPoint point);
+void writeSize(FILE* file, int indentLevel, const char* str, SkSize size);
+void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect);
+void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix);
+
+}
+
+#endif // DumpLayer_h
diff --git a/Source/WebCore/platform/graphics/android/FixedPositioning.cpp b/Source/WebCore/platform/graphics/android/FixedPositioning.cpp
new file mode 100644
index 0000000..989eebd
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/FixedPositioning.cpp
@@ -0,0 +1,105 @@
+#define LOG_TAG "FixedPositioning"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "FixedPositioning.h"
+
+#include "AndroidLog.h"
+#include "DumpLayer.h"
+#include "IFrameLayerAndroid.h"
+#include "TilesManager.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+// Called when copying the layer tree to the UI
+FixedPositioning::FixedPositioning(LayerAndroid* layer, const FixedPositioning& position)
+ : m_layer(layer)
+ , m_fixedLeft(position.m_fixedLeft)
+ , m_fixedTop(position.m_fixedTop)
+ , m_fixedRight(position.m_fixedRight)
+ , m_fixedBottom(position.m_fixedBottom)
+ , m_fixedMarginLeft(position.m_fixedMarginLeft)
+ , m_fixedMarginTop(position.m_fixedMarginTop)
+ , m_fixedMarginRight(position.m_fixedMarginRight)
+ , m_fixedMarginBottom(position.m_fixedMarginBottom)
+ , m_fixedRect(position.m_fixedRect)
+ , m_renderLayerPos(position.m_renderLayerPos)
+{
+}
+
+// Executed on the UI
+IFrameLayerAndroid* FixedPositioning::updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer)
+{
+ // So if this is a fixed layer inside a iframe, use the iframe offset
+ // and the iframe's size as the viewport and pass to the children
+ if (parentIframeLayer) {
+ viewport = SkRect::MakeXYWH(parentIframeLayer->iframeOffset().x(),
+ parentIframeLayer->iframeOffset().y(),
+ parentIframeLayer->getSize().width(),
+ parentIframeLayer->getSize().height());
+ }
+ float w = viewport.width();
+ float h = viewport.height();
+ float dx = viewport.fLeft;
+ float dy = viewport.fTop;
+ float x = dx;
+ float y = dy;
+
+ // It turns out that when it is 'auto', we should use the webkit value
+ // from the original render layer's X,Y, that will take care of alignment
+ // with the parent's layer and fix Margin etc.
+ if (!(m_fixedLeft.defined() || m_fixedRight.defined()))
+ x += m_renderLayerPos.x();
+ else if (m_fixedLeft.defined() || !m_fixedRight.defined())
+ x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft;
+ else
+ x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight;
+
+ if (!(m_fixedTop.defined() || m_fixedBottom.defined()))
+ y += m_renderLayerPos.y();
+ else if (m_fixedTop.defined() || !m_fixedBottom.defined())
+ y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop;
+ else
+ y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom;
+
+ m_layer->setPosition(x, y);
+
+ return parentIframeLayer;
+}
+
+void FixedPositioning::contentDraw(SkCanvas* canvas, Layer::PaintStyle style)
+{
+ if (TilesManager::instance()->getShowVisualIndicator()) {
+ SkPaint paint;
+ paint.setARGB(80, 255, 0, 0);
+ canvas->drawRect(m_fixedRect, paint);
+ }
+}
+
+void writeLength(FILE* file, int indentLevel, const char* str, SkLength length)
+{
+ if (!length.defined())
+ return;
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value);
+}
+
+void FixedPositioning::dumpLayer(FILE* file, int indentLevel) const
+{
+ writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft);
+ writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop);
+ writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight);
+ writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom);
+ writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft);
+ writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop);
+ writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight);
+ writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom);
+ writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect);
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/FixedPositioning.h b/Source/WebCore/platform/graphics/android/FixedPositioning.h
new file mode 100644
index 0000000..973113b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/FixedPositioning.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 FixedPositioning_h
+#define FixedPositioning_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerAndroid.h"
+
+namespace WebCore {
+
+class IFrameLayerAndroid;
+
+struct SkLength {
+ enum SkLengthType { Undefined, Auto, Relative,
+ Percent, Fixed, Static, Intrinsic, MinIntrinsic };
+ SkLengthType type;
+ SkScalar value;
+ SkLength()
+ {
+ type = Undefined;
+ value = 0;
+ }
+ bool defined() const
+ {
+ if (type == Undefined)
+ return false;
+ return true;
+ }
+ float calcFloatValue(float max) const
+ {
+ switch (type) {
+ case Percent:
+ return (max * value) / 100.0f;
+ case Fixed:
+ return value;
+ default:
+ return value;
+ }
+ }
+};
+
+class FixedPositioning {
+
+public:
+ FixedPositioning(LayerAndroid* layer = 0) : m_layer(layer) {}
+ FixedPositioning(LayerAndroid* layer, const FixedPositioning& position);
+ virtual ~FixedPositioning() {};
+
+ void setFixedPosition(SkLength left, // CSS left property
+ SkLength top, // CSS top property
+ SkLength right, // CSS right property
+ SkLength bottom, // CSS bottom property
+ SkLength marginLeft, // CSS margin-left property
+ SkLength marginTop, // CSS margin-top property
+ SkLength marginRight, // CSS margin-right property
+ SkLength marginBottom, // CSS margin-bottom property
+ const IntPoint& renderLayerPos, // For undefined fixed position
+ SkRect viewRect) { // view rect, can be smaller than the layer's
+ m_fixedLeft = left;
+ m_fixedTop = top;
+ m_fixedRight = right;
+ m_fixedBottom = bottom;
+ m_fixedMarginLeft = marginLeft;
+ m_fixedMarginTop = marginTop;
+ m_fixedMarginRight = marginRight;
+ m_fixedMarginBottom = marginBottom;
+ m_fixedRect = viewRect;
+ m_renderLayerPos = renderLayerPos;
+ }
+
+ IFrameLayerAndroid* updatePosition(SkRect viewPort,
+ IFrameLayerAndroid* parentIframeLayer);
+
+ void contentDraw(SkCanvas* canvas, Layer::PaintStyle style);
+
+ void dumpLayer(FILE*, int indentLevel) const;
+
+ // ViewStateSerializer friends
+ friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
+ friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
+
+private:
+ LayerAndroid* m_layer;
+
+ SkLength m_fixedLeft;
+ SkLength m_fixedTop;
+ SkLength m_fixedRight;
+ SkLength m_fixedBottom;
+ SkLength m_fixedMarginLeft;
+ SkLength m_fixedMarginTop;
+ SkLength m_fixedMarginRight;
+ SkLength m_fixedMarginBottom;
+ SkRect m_fixedRect;
+
+ // When fixed element is undefined or auto, the render layer's position
+ // is needed for offset computation
+ IntPoint m_renderLayerPos;
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // FixedPositioning_h
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
index 0a8c0c1..c8b9488 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -52,6 +52,7 @@
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnArrayPtr.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/unicode/CharacterNames.h>
#include <wtf/unicode/Unicode.h>
#endif
@@ -87,6 +88,8 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc,
if (!mode)
return false;
+ paint->setVerticalText(font->platformData().orientation() == Vertical);
+
FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
@@ -192,8 +195,6 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs);
SkPoint* pos = storage.get();
- SkPoint* vPosBegin = storage2.get();
- SkPoint* vPosEnd = storage3.get();
SkCanvas* canvas = gc->platformContext()->mCanvas;
@@ -201,6 +202,9 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
point.xy + [width, height, width, height, ...], so we have to convert
*/
+ if (font->platformData().orientation() == Vertical)
+ y += SkFloatToScalar(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
+
if (EmojiFont::IsAvailable()) {
// set filtering, to make scaled images look nice(r)
paint.setFilterBitmap(true);
@@ -230,27 +234,25 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
} else {
- bool isVertical = font->platformData().orientation() == Vertical;
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
y += SkFloatToScalar(adv[i].height());
- if (isVertical) {
- SkScalar myWidth = SkFloatToScalar(adv[i].width());
- vPosBegin[i].set(x + myWidth, y);
- vPosEnd[i].set(x + myWidth, y - myWidth);
- x += myWidth;
-
- SkPath path;
- path.reset();
- path.moveTo(vPosBegin[i]);
- path.lineTo(vPosEnd[i]);
- canvas->drawTextOnPath(glyphs + i, 2, path, 0, paint);
- }
- else
- x += SkFloatToScalar(adv[i].width());
+ x += SkFloatToScalar(adv[i].width());
}
- if (!isVertical)
- canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
+
+ if (font->platformData().orientation() == Vertical) {
+ canvas->save();
+ canvas->rotate(-90);
+ SkMatrix rotator;
+ rotator.reset();
+ rotator.setRotate(90);
+ rotator.mapPoints(pos, numGlyphs);
+ }
+
+ canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
+
+ if (font->platformData().orientation() == Vertical)
+ canvas->restore();
}
}
@@ -379,7 +381,7 @@ static int truncateFixedPointToInteger(HB_Fixed value)
// can call |reset| to start over again.
class TextRunWalker {
public:
- TextRunWalker(const TextRun&, unsigned, const Font*);
+ TextRunWalker(const TextRun&, int, int, const Font*);
~TextRunWalker();
bool isWordBreak(unsigned, bool);
@@ -425,10 +427,10 @@ public:
// Return the length of the array returned by |glyphs|
unsigned length() const { return m_item.num_glyphs; }
- // Return the x offset for each of the glyphs. Note that this is translated
+ // Return the offset for each of the glyphs. Note that this is translated
// by the current x offset and that the x offset is updated for each script
// run.
- const SkScalar* xPositions() const { return m_xPositions; }
+ const SkPoint* positions() const { return m_positions; }
// Get the advances (widths) for each glyph.
const HB_Fixed* advances() const { return m_item.advances; }
@@ -472,7 +474,7 @@ private:
void createGlyphArrays(int);
void resetGlyphArrays();
void shapeGlyphs();
- void setGlyphXPositions(bool);
+ void setGlyphPositions(bool);
static void normalizeSpacesAndMirrorChars(const UChar* source, bool rtl,
UChar* destination, int length);
@@ -485,10 +487,11 @@ private:
const Font* const m_font;
HB_ShaperItem m_item;
uint16_t* m_glyphs16; // A vector of 16-bit glyph ids.
- SkScalar* m_xPositions; // A vector of x positions for each glyph.
+ SkPoint* m_positions; // A vector of positions for each glyph.
ssize_t m_indexOfNextScriptRun; // Indexes the script run in |m_run|.
- const unsigned m_startingX; // Offset in pixels of the first script run.
- unsigned m_offsetX; // Offset in pixels to the start of the next script run.
+ const int m_startingX; // Offset in pixels of the first script run.
+ const int m_startingY; // Offset in pixels of the first script run.
+ int m_offsetX; // Offset in pixels to the start of the next script run.
unsigned m_pixelWidth; // Width (in px) of the current script run.
unsigned m_numCodePoints; // Code points in current script run.
unsigned m_glyphsArrayCapacity; // Current size of all the Harfbuzz arrays.
@@ -519,9 +522,10 @@ const char* TextRunWalker::paths[] = {
"/system/fonts/DroidSansThai.ttf"
};
-TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font* font)
+TextRunWalker::TextRunWalker(const TextRun& run, int startingX, int startingY, const Font* font)
: m_font(font)
, m_startingX(startingX)
+ , m_startingY(startingY)
, m_offsetX(m_startingX)
, m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer))
, m_iterateBackwards(m_run.rtl())
@@ -650,7 +654,7 @@ bool TextRunWalker::nextScriptRun()
setupFontForScriptRun();
shapeGlyphs();
- setGlyphXPositions(rtl());
+ setGlyphPositions(rtl());
return true;
}
@@ -737,6 +741,16 @@ void TextRunWalker::setupFontForScriptRun()
}
m_item.face = complexPlatformData->harfbuzzFace();
m_item.font->userData = const_cast<FontPlatformData*>(complexPlatformData);
+
+ int size = complexPlatformData->size();
+ m_item.font->x_ppem = size;
+ m_item.font->y_ppem = size;
+ // x_ and y_scale are the conversion factors from font design space (fEmSize) to 1/64th of device pixels in 16.16 format.
+ const int devicePixelFraction = 64;
+ const int multiplyFor16Dot16 = 1 << 16;
+ int scale = devicePixelFraction * size * multiplyFor16Dot16 / complexPlatformData->emSizeInFontUnits();
+ m_item.font->x_scale = scale;
+ m_item.font->y_scale = scale;
}
HB_FontRec* TextRunWalker::allocHarfbuzzFont()
@@ -745,13 +759,6 @@ HB_FontRec* TextRunWalker::allocHarfbuzzFont()
memset(font, 0, sizeof(HB_FontRec));
font->klass = &harfbuzzSkiaClass;
font->userData = 0;
- // The values which harfbuzzSkiaClass returns are already scaled to
- // pixel units, so we just set all these to one to disable further
- // scaling.
- font->x_ppem = 1;
- font->y_ppem = 1;
- font->x_scale = 1;
- font->y_scale = 1;
return font;
}
@@ -763,7 +770,7 @@ void TextRunWalker::deleteGlyphArrays()
delete[] m_item.advances;
delete[] m_item.offsets;
delete[] m_glyphs16;
- delete[] m_xPositions;
+ delete[] m_positions;
}
void TextRunWalker::createGlyphArrays(int size)
@@ -774,7 +781,7 @@ void TextRunWalker::createGlyphArrays(int size)
m_item.offsets = new HB_FixedPoint[size];
m_glyphs16 = new uint16_t[size];
- m_xPositions = new SkScalar[size];
+ m_positions = new SkPoint[size];
m_item.num_glyphs = size;
m_glyphsArrayCapacity = size; // Save the GlyphArrays size.
@@ -790,7 +797,7 @@ void TextRunWalker::resetGlyphArrays()
memset(m_item.advances, 0, size * sizeof(m_item.advances[0]));
memset(m_item.offsets, 0, size * sizeof(m_item.offsets[0]));
memset(m_glyphs16, 0, size * sizeof(m_glyphs16[0]));
- memset(m_xPositions, 0, size * sizeof(m_xPositions[0]));
+ memset(m_positions, 0, size * sizeof(m_positions[0]));
}
void TextRunWalker::shapeGlyphs()
@@ -810,7 +817,7 @@ void TextRunWalker::shapeGlyphs()
}
}
-void TextRunWalker::setGlyphXPositions(bool isRTL)
+void TextRunWalker::setGlyphPositions(bool isRTL)
{
int position = 0;
// logClustersIndex indexes logClusters for the first (or last when
@@ -825,7 +832,9 @@ void TextRunWalker::setGlyphXPositions(bool isRTL)
int i = isRTL ? m_item.num_glyphs - iter - 1 : iter;
m_glyphs16[i] = m_item.glyphs[i];
- m_xPositions[i] = SkIntToScalar(m_offsetX + position);
+ int offsetX = truncateFixedPointToInteger(m_item.offsets[i].x);
+ int offsetY = truncateFixedPointToInteger(m_item.offsets[i].y);
+ m_positions[i].set(SkIntToScalar(m_offsetX + position) + offsetX, m_startingY + offsetY);
int advance = truncateFixedPointToInteger(m_item.advances[i]);
// The first half of the conjunction works around the case where
@@ -846,6 +855,21 @@ void TextRunWalker::setGlyphXPositions(bool isRTL)
}
}
+ // ZeroWidthJoiners and ZeroWidthNonJoiners should be stripped by
+ // Harfbuzz, but aren't. Check for zwj and zwnj and replace with a
+ // zero width space. We get the glyph data for space instead of
+ // zeroWidthSpace because the latter was seen to render with an
+ // unexpected code point (the symbol for a cloud). Since the standard
+ // space is in page zero and since we've also confirmed that there is
+ // no advance on this glyph, that should be ok.
+ if (0 == m_item.advances[i]) {
+ const HB_UChar16 c = m_item.string[m_item.item.pos + logClustersIndex];
+ if ((c == zeroWidthJoiner) || (c == zeroWidthNonJoiner)) {
+ static Glyph spaceGlyph = m_font->glyphDataForCharacter(space, false).glyph;
+ m_glyphs16[i] = spaceGlyph;
+ }
+ }
+
// TODO We would like to add m_letterSpacing after each cluster, but I
// don't know where the cluster information is. This is typically
// fine for Roman languages, but breaks more complex languages
@@ -878,10 +902,14 @@ void TextRunWalker::normalizeSpacesAndMirrorChars(const UChar* source, bool rtl,
UChar32 character;
int nextPosition = position;
U16_NEXT(source, nextPosition, length, character);
+
if (Font::treatAsSpace(character))
- character = ' ';
+ character = space;
+ else if (Font::treatAsZeroWidthSpaceInComplexScript(character))
+ character = zeroWidthSpace;
else if (rtl)
character = u_charMirror(character);
+
U16_APPEND(destination, position, length, character, error);
ASSERT(!error);
position = nextPosition;
@@ -947,7 +975,7 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run,
{
int fromX = -1, toX = -1, fromAdvance = -1, toAdvance = -1;
- TextRunWalker walker(run, 0, this);
+ TextRunWalker walker(run, 0, 0, this);
walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing());
// Base will point to the x offset for the current script run. Note that, in
@@ -974,16 +1002,16 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run,
// find which glyph this code-point contributed to and find its x
// position.
int glyph = walker.logClusters()[from];
- fromX = base + walker.xPositions()[glyph];
+ fromX = base + walker.positions()[glyph].x();
fromAdvance = walker.advances()[glyph];
- } else
+ } else if (!walker.rtl())
from -= numCodePoints;
if (toX == -1 && to < numCodePoints) {
int glyph = walker.logClusters()[to];
- toX = base + walker.xPositions()[glyph];
+ toX = base + walker.positions()[glyph].x();
toAdvance = walker.advances()[glyph];
- } else
+ } else if (!walker.rtl())
to -= numCodePoints;
if (!walker.rtl())
@@ -1028,7 +1056,7 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
SkCanvas* canvas = gc->platformContext()->mCanvas;
bool haveMultipleLayers = isCanvasMultiLayered(canvas);
- TextRunWalker walker(run, point.x(), this);
+ TextRunWalker walker(run, point.x(), point.y(), this);
walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing());
walker.setPadding(run.expansion());
@@ -1036,14 +1064,14 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
if (fill) {
walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint);
adjustTextRenderMode(&fillPaint, haveMultipleLayers);
- canvas->drawPosTextH(walker.glyphs(), walker.length() << 1,
- walker.xPositions(), point.y(), fillPaint);
+ canvas->drawPosText(walker.glyphs(), walker.length() << 1,
+ walker.positions(), fillPaint);
}
if (stroke) {
walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint);
adjustTextRenderMode(&strokePaint, haveMultipleLayers);
- canvas->drawPosTextH(walker.glyphs(), walker.length() << 1,
- walker.xPositions(), point.y(), strokePaint);
+ canvas->drawPosText(walker.glyphs(), walker.length() << 1,
+ walker.positions(), strokePaint);
}
}
}
@@ -1051,7 +1079,7 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
float Font::floatWidthForComplexText(const TextRun& run,
HashSet<const SimpleFontData*>*, GlyphOverflow*) const
{
- TextRunWalker walker(run, 0, this);
+ TextRunWalker walker(run, 0, 0, this);
walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing());
return walker.widthOfFullRun();
}
@@ -1083,7 +1111,7 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float x,
{
// (Mac code ignores includePartialGlyphs, and they don't know what it's
// supposed to do, so we just ignore it as well.)
- TextRunWalker walker(run, 0, this);
+ TextRunWalker walker(run, 0, 0, this);
walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing());
// If this is RTL text, the first glyph from the left is actually the last
diff --git a/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp b/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp
index 4fc3b4e..5696a46 100644
--- a/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp
@@ -34,7 +34,6 @@
#include "SkPaint.h"
#include "SkTypeface.h"
#include "SkUtils.h"
-#include <wtf/text/CString.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
index c6dd174..88822df 100644
--- a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/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/FontPlatformData.h
index 5c3313e..1e46971 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/FontPlatformData.h
@@ -82,6 +82,7 @@ public:
float size() const { return mTextSize; }
unsigned hash() const;
+ int emSizeInFontUnits() const;
bool isFixedPitch() const;
#ifndef NDEBUG
@@ -113,6 +114,7 @@ private:
SkTypeface* mTypeface;
float mTextSize;
+ mutable int mEmSizeInFontUnits;
bool mFakeBold;
bool mFakeItalic;
FontOrientation mOrientation;
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
index 3c90246..fc254c0 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
@@ -33,6 +33,7 @@
#ifdef SUPPORT_COMPLEX_SCRIPTS
#include "HarfbuzzSkia.h"
#endif
+#include "SkAdvancedTypefaceMetrics.h"
#include "SkPaint.h"
#include "SkTypeface.h"
@@ -74,7 +75,7 @@ FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace()
}
FontPlatformData::FontPlatformData()
- : mTypeface(NULL), mTextSize(0), mFakeBold(false), mFakeItalic(false),
+ : mTypeface(NULL), mTextSize(0), mEmSizeInFontUnits(0), mFakeBold(false), mFakeItalic(false),
mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight)
{
inc_count();
@@ -87,10 +88,10 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src)
SkSafeRef(src.mTypeface);
}
- mTypeface = src.mTypeface;
-
- mTextSize = src.mTextSize;
- mFakeBold = src.mFakeBold;
+ mTypeface = src.mTypeface;
+ mTextSize = src.mTextSize;
+ mEmSizeInFontUnits = src.mEmSizeInFontUnits;
+ mFakeBold = src.mFakeBold;
mFakeItalic = src.mFakeItalic;
m_harfbuzzFace = src.m_harfbuzzFace;
mOrientation = src.mOrientation;
@@ -102,7 +103,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src)
FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic,
FontOrientation orientation, TextOrientation textOrientation)
- : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic),
+ : mTypeface(tf), mTextSize(textSize), mEmSizeInFontUnits(0), mFakeBold(fakeBold), mFakeItalic(fakeItalic),
mOrientation(orientation), mTextOrientation(textOrientation)
{
if (hashTableDeletedFontValue() != mTypeface) {
@@ -114,8 +115,8 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold
}
FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
- : mTypeface(src.mTypeface), mTextSize(textSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic),
- m_harfbuzzFace(src.m_harfbuzzFace), mOrientation(src.mOrientation), mTextOrientation(src.mTextOrientation)
+ : mTypeface(src.mTypeface), mTextSize(textSize), mEmSizeInFontUnits(src.mEmSizeInFontUnits), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic),
+ mOrientation(src.mOrientation), mTextOrientation(src.mTextOrientation), m_harfbuzzFace(src.m_harfbuzzFace)
{
if (hashTableDeletedFontValue() != mTypeface) {
SkSafeRef(mTypeface);
@@ -126,7 +127,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
}
FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
- : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique),
+ : mTypeface(NULL), mTextSize(size), mEmSizeInFontUnits(0), mFakeBold(bold), mFakeItalic(oblique),
mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight)
{
inc_count();
@@ -134,7 +135,7 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
}
FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf)
- : mTypeface(tf), mTextSize(src.mTextSize), mFakeBold(src.mFakeBold),
+ : mTypeface(tf), mTextSize(src.mTextSize), mEmSizeInFontUnits(0), mFakeBold(src.mFakeBold),
mFakeItalic(src.mFakeItalic), mOrientation(src.mOrientation),
mTextOrientation(src.mTextOrientation)
{
@@ -158,6 +159,22 @@ FontPlatformData::~FontPlatformData()
}
}
+int FontPlatformData::emSizeInFontUnits() const
+{
+ if (mEmSizeInFontUnits)
+ return mEmSizeInFontUnits;
+
+ SkAdvancedTypefaceMetrics* metrics = 0;
+ if (mTypeface)
+ metrics = mTypeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
+ if (metrics) {
+ mEmSizeInFontUnits = metrics->fEmSize;
+ metrics->unref();
+ } else
+ mEmSizeInFontUnits = 1000; // default value copied from Skia.
+ return mEmSizeInFontUnits;
+}
+
FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
{
if (hashTableDeletedFontValue() != src.mTypeface) {
@@ -167,9 +184,10 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
SkSafeUnref(mTypeface);
}
- mTypeface = src.mTypeface;
- mTextSize = src.mTextSize;
- mFakeBold = src.mFakeBold;
+ mTypeface = src.mTypeface;
+ mEmSizeInFontUnits = src.mEmSizeInFontUnits;
+ mTextSize = src.mTextSize;
+ mFakeBold = src.mFakeBold;
mFakeItalic = src.mFakeItalic;
m_harfbuzzFace = src.m_harfbuzzFace;
mOrientation = src.mOrientation;
@@ -180,10 +198,6 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
void FontPlatformData::setupPaint(SkPaint* paint) const
{
- float ts = mTextSize;
- if (!(ts > 0))
- ts = 12;
-
if (hashTableDeletedFontValue() == mTypeface)
paint->setTypeface(0);
else
@@ -192,7 +206,7 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
paint->setAntiAlias(true);
paint->setSubpixelText(true);
paint->setHinting(SkPaint::kSlight_Hinting);
- paint->setTextSize(SkFloatToScalar(ts));
+ paint->setTextSize(SkFloatToScalar(mTextSize));
paint->setFakeBoldText(mFakeBold);
paint->setTextSkewX(mFakeItalic ? -SK_Scalar1/4 : 0);
#ifndef SUPPORT_COMPLEX_SCRIPTS
diff --git a/Source/WebCore/platform/graphics/android/GLExtras.cpp b/Source/WebCore/platform/graphics/android/GLExtras.cpp
index 873ea33..1676489 100644
--- a/Source/WebCore/platform/graphics/android/GLExtras.cpp
+++ b/Source/WebCore/platform/graphics/android/GLExtras.cpp
@@ -23,50 +23,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "GLExtras"
+#define LOG_NDEBUG 1
+
#include "config.h"
+#include "AndroidLog.h"
#include "DrawExtra.h"
-#include "FindCanvas.h"
#include "GLExtras.h"
#include "IntRect.h"
#include "TilesManager.h"
#include "android_graphics.h"
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "GLExtras", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLExtras", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
// Touch ring border width. This is doubled if the ring is not pressed
#define RING_BORDER_WIDTH 1
-// Color of the ring is 0x6633b5e5 (copied from framework's holo_light)
-#define COLOR_HOLO_LIGHT &m_lightRingTexture, 0x33, 0xb5, 0xe5, 0.4f
-// Color of the ring is 0x660099cc (copied from framework's holo_dark)
-#define COLOR_HOLO_DARK &m_darkRingTexture, 0x00, 0x99, 0xcc, 0.6f
-// Put a cap on the number of matches to draw. If the current page has more
-// matches than this, only draw the focused match. This both prevents clutter
-// on the page and keeps the performance happy
-#define MAX_NUMBER_OF_MATCHES_TO_DRAW 101
GLExtras::GLExtras()
- : m_findOnPage(0)
- , m_ring(0)
- , m_drawExtra(0)
- , m_lightRingTexture(-1)
- , m_darkRingTexture(-1)
+ : m_drawExtra(0)
+ , m_viewport()
{
}
@@ -74,22 +48,28 @@ GLExtras::~GLExtras()
{
}
-void GLExtras::drawRing(SkRect& srcRect, int* texture, int r, int g, int b, float a)
+void GLExtras::drawRing(SkRect& srcRect, Color color, const TransformationMatrix* drawMat)
{
- if (*texture == -1)
- *texture = GLUtils::createSampleColorTexture(r, g, b);
-
if (srcRect.fRight <= srcRect.fLeft || srcRect.fBottom <= srcRect.fTop) {
// Invalid rect, reject it
return;
}
- XLOG("drawQuad [%fx%f, %f, %f]", srcRect.fLeft, srcRect.fTop,
- srcRect.width(), srcRect.height());
- TilesManager::instance()->shader()->drawQuad(srcRect, *texture, a);
+ ALOGV("drawQuad [%fx%f, %f, %f]", srcRect.fLeft, srcRect.fTop,
+ srcRect.width(), srcRect.height());
+ // Pull the alpha out of the color so that the shader applies it correctly.
+ // Otherwise we either don't have blending enabled, or the alpha will get
+ // 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);
}
-void GLExtras::drawRegion(const SkRegion& region, bool fill,
- bool drawBorder, bool useDark)
+void GLExtras::drawRegion(const SkRegion& region, bool fill, bool drawBorder,
+ const TransformationMatrix* drawMat, Color color)
{
if (region.isEmpty())
return;
@@ -99,10 +79,7 @@ void GLExtras::drawRegion(const SkRegion& region, bool fill,
const SkIRect& ir = rgnIter.rect();
SkRect r;
r.set(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom);
- if (useDark)
- drawRing(r, COLOR_HOLO_DARK);
- else
- drawRing(r, COLOR_HOLO_LIGHT);
+ drawRing(r, color, drawMat);
rgnIter.next();
}
}
@@ -143,10 +120,7 @@ void GLExtras::drawRegion(const SkRegion& region, bool fill,
clip.setRect(line);
}
r.set(line.fLeft, line.fTop, line.fRight, line.fBottom);
- if (useDark)
- drawRing(r, COLOR_HOLO_DARK);
- else
- drawRing(r, COLOR_HOLO_LIGHT);
+ drawRing(r, color, drawMat);
if (startRect.isEmpty()) {
startRect.set(line.fLeft, line.fTop, line.fRight, line.fBottom);
}
@@ -157,57 +131,8 @@ void GLExtras::drawRegion(const SkRegion& region, bool fill,
}
}
-void GLExtras::drawCursorRings()
-{
- SkRegion region;
- for (size_t i = 0; i < m_ring->rings().size(); i++) {
- IntRect rect = m_ring->rings().at(i);
- if (i == 0)
- region.setRect(rect);
- else
- region.op(rect, SkRegion::kUnion_Op);
- }
- drawRegion(region, m_ring->m_isPressed, !m_ring->m_isButton, false);
-}
-
-void GLExtras::drawFindOnPage(SkRect& viewport)
-{
- WTF::Vector<MatchInfo>* matches = m_findOnPage->matches();
- XLOG("drawFindOnPage, matches: %p", matches);
- if (!matches || !m_findOnPage->isCurrentLocationValid())
- return;
- int count = matches->size();
- int current = m_findOnPage->currentMatchIndex();
- XLOG("match count: %d", count);
- if (count < MAX_NUMBER_OF_MATCHES_TO_DRAW)
- for (int i = 0; i < count; i++) {
- MatchInfo& info = matches->at(i);
- const SkRegion& region = info.getLocation();
- SkIRect rect = region.getBounds();
- if (rect.intersect(viewport.fLeft, viewport.fTop,
- viewport.fRight, viewport.fBottom))
- drawRegion(region, i == current, false, true);
-#ifdef DEBUG
- else
- XLOG("Quick rejecting [%dx%d, %d, %d", rect.fLeft, rect.fTop,
- rect.width(), rect.height());
-#endif // DEBUG
- }
- else {
- MatchInfo& info = matches->at(current);
- drawRegion(info.getLocation(), true, false, true);
- }
-}
-
-void GLExtras::drawGL(IntRect& webViewRect, SkRect& viewport, int titleBarHeight)
+void GLExtras::drawGL(const LayerAndroid* layer)
{
- if (m_drawExtra) {
- if (m_drawExtra == m_ring)
- drawCursorRings();
- else if (m_drawExtra == m_findOnPage)
- drawFindOnPage(viewport);
- else
- XLOGC("m_drawExtra %p is unknown! (cursor: %p, find: %p",
- m_drawExtra, m_ring, m_findOnPage);
- }
+ if (m_drawExtra)
+ m_drawExtra->drawGL(this, layer);
}
diff --git a/Source/WebCore/platform/graphics/android/GLExtras.h b/Source/WebCore/platform/graphics/android/GLExtras.h
index c52e951..59a7c3c 100644
--- a/Source/WebCore/platform/graphics/android/GLExtras.h
+++ b/Source/WebCore/platform/graphics/android/GLExtras.h
@@ -26,41 +26,33 @@
#ifndef GLExtras_h
#define GLExtras_h
+#include "Color.h"
+#include "DrawExtra.h"
#include "SkRect.h"
#include "SkRegion.h"
-namespace android {
- class FindOnPage;
- class CursorRing;
- class DrawExtra;
-}
-
namespace WebCore {
+class LayerAndroid;
+class TransformationMatrix;
+
class GLExtras {
public:
GLExtras();
virtual ~GLExtras();
- void drawGL(IntRect& webViewRect, SkRect& viewport, int titleBarHeight);
- void setFindOnPageExtra(android::FindOnPage* findOnPage) {
- m_findOnPage = findOnPage;
- }
- void setCursorRingExtra(android::CursorRing* ring) { m_ring = ring; }
+ void drawGL(const LayerAndroid* layer);
void setDrawExtra(android::DrawExtra* extra) { m_drawExtra = extra; }
+ void setViewport(const SkRect & viewport) { m_viewport = viewport; }
-private:
- void drawRing(SkRect& srcRect, int* texture, int r, int g, int b, float a);
void drawRegion(const SkRegion& region, bool fill, bool drawBorder,
- bool useDark = false);
- void drawCursorRings();
- void drawFindOnPage(SkRect& viewport);
+ const TransformationMatrix* drawMat, Color color = COLOR_HOLO_LIGHT);
+
+private:
+ void drawRing(SkRect& srcRect, Color color, const TransformationMatrix* drawMat);
- android::FindOnPage* m_findOnPage;
- android::CursorRing* m_ring;
android::DrawExtra* m_drawExtra;
- int m_lightRingTexture;
- int m_darkRingTexture;
+ SkRect m_viewport;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp
index 97a53fe..beb62db 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp
@@ -23,6 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "GLUtils"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "GLUtils.h"
@@ -31,26 +34,15 @@
#include "ShaderProgram.h"
#include "TilesManager.h"
-#include <cutils/log.h>
+#include <AndroidLog.h>
+#include <android/native_window.h>
#include <gui/SurfaceTexture.h>
#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+// We will limit GL error logging for LOG_VOLUME_PER_CYCLE times every
+// LOG_VOLUME_PER_CYCLE seconds.
+#define LOG_CYCLE 30.0
+#define LOG_VOLUME_PER_CYCLE 20
struct ANativeWindowBuffer;
@@ -116,10 +108,35 @@ void GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, flo
// GL & EGL error checks
/////////////////////////////////////////////////////////////////////////////////////////
-static void crashIfOOM(GLint errorCode) {
+double GLUtils::m_previousLogTime = 0;
+int GLUtils::m_currentLogCounter = 0;
+
+bool GLUtils::allowGLLog()
+{
+ if (m_currentLogCounter < LOG_VOLUME_PER_CYCLE) {
+ m_currentLogCounter++;
+ return true;
+ }
+
+ // when we are in Log cycle and over the log limit, just return false
+ double currentTime = WTF::currentTime();
+ double delta = currentTime - m_previousLogTime;
+ bool inLogCycle = (delta <= LOG_CYCLE) && (delta > 0);
+ if (inLogCycle)
+ return false;
+
+ // When we are out of Log Cycle and over the log limit, we need to reset
+ // the counter and timer.
+ m_previousLogTime = currentTime;
+ m_currentLogCounter = 0;
+ return false;
+}
+
+static void crashIfOOM(GLint errorCode)
+{
const GLint OOM_ERROR_CODE = 0x505;
if (errorCode == OOM_ERROR_CODE) {
- XLOG("Fatal OOM detected.");
+ ALOGE("ERROR: Fatal OOM detected.");
CRASH();
}
}
@@ -127,11 +144,17 @@ static void crashIfOOM(GLint errorCode) {
void GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
{
if (returnVal != EGL_TRUE) {
- XLOG("EGL ERROR - %s() returned %d\n", op, returnVal);
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("EGL ERROR - %s() returned %d\n", op, returnVal);
}
for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
- XLOG("after %s() eglError (0x%x)\n", op, error);
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("after %s() eglError (0x%x)\n", op, error);
crashIfOOM(error);
}
}
@@ -140,7 +163,10 @@ bool GLUtils::checkGlError(const char* op)
{
bool ret = false;
for (GLint error = glGetError(); error; error = glGetError()) {
- XLOG("GL ERROR - after %s() glError (0x%x)\n", op, error);
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("GL ERROR - after %s() glError (0x%x)\n", op, error);
crashIfOOM(error);
ret = true;
}
@@ -151,7 +177,10 @@ bool GLUtils::checkGlErrorOn(void* p, const char* op)
{
bool ret = false;
for (GLint error = glGetError(); error; error = glGetError()) {
- XLOG("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
crashIfOOM(error);
ret = true;
}
@@ -161,7 +190,10 @@ bool GLUtils::checkGlErrorOn(void* p, const char* op)
void GLUtils::checkSurfaceTextureError(const char* functionName, int status)
{
if (status != NO_ERROR) {
- XLOG("ERROR at calling %s status is (%d)", functionName, status);
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("ERROR at calling %s status is (%d)", functionName, status);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -237,7 +269,7 @@ static EGLConfig defaultPbufferConfig(EGLDisplay display)
eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
GLUtils::checkEglError("eglPbufferConfig");
if (numConfigs != 1)
- LOGI("eglPbufferConfig failed (%d)\n", numConfigs);
+ ALOGI("eglPbufferConfig failed (%d)\n", numConfigs);
return config;
}
@@ -269,7 +301,7 @@ EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
checkEglError("eglGetDisplay");
if (display == EGL_NO_DISPLAY) {
- XLOG("eglGetDisplay returned EGL_NO_DISPLAY");
+ ALOGE("eglGetDisplay returned EGL_NO_DISPLAY");
return EGL_NO_CONTEXT;
}
@@ -278,7 +310,7 @@ EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion);
checkEglError("eglInitialize", returnValue);
if (returnValue != EGL_TRUE) {
- XLOG("eglInitialize failed\n");
+ ALOGE("eglInitialize failed\n");
return EGL_NO_CONTEXT;
}
@@ -292,14 +324,14 @@ EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs);
checkEglError("eglCreateContext");
if (context == EGL_NO_CONTEXT) {
- XLOG("eglCreateContext failed\n");
+ ALOGE("eglCreateContext failed\n");
return EGL_NO_CONTEXT;
}
returnValue = eglMakeCurrent(display, surface, surface, context);
checkEglError("eglMakeCurrent", returnValue);
if (returnValue != EGL_TRUE) {
- XLOG("eglMakeCurrent failed\n");
+ ALOGE("eglMakeCurrent failed\n");
return EGL_NO_CONTEXT;
}
@@ -313,7 +345,8 @@ void GLUtils::deleteTexture(GLuint* texture)
*texture = 0;
}
-GLuint GLUtils::createSampleColorTexture(int r, int g, int b) {
+GLuint GLUtils::createSampleColorTexture(int r, int g, int b)
+{
GLuint texture;
glGenTextures(1, &texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -370,126 +403,154 @@ GLuint GLUtils::createBaseTileGLTexture(int width, int height)
GLUtils::checkGlError("glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#ifdef DEBUG
+ delete pixels;
+#endif
return texture;
}
+bool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
+{
+ // If the bitmap is the pure color, skip the transfer step, and update the BaseTile 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);
+ bitmap.lockPixels();
+ bool sameColor = true;
+ int bitmapWidth = bitmap.width();
+
+ // Create a row of pure color using the first pixel.
+ // TODO: improve the perf here, by either picking a random pixel, or
+ // creating an array of rows with pre-defined commonly used color, add
+ // smart LUT to speed things up if possible.
+ int* firstPixelPtr = static_cast<int*> (bitmap.getPixels());
+ int* pixelsRow = new int[bitmapWidth];
+ for (int i = 0; i < bitmapWidth; i++)
+ pixelsRow[i] = (*firstPixelPtr);
+
+ // Then compare the pure color row with each row of the bitmap.
+ for (int j = 0; j < bitmap.height(); j++) {
+ if (memcmp(pixelsRow, &firstPixelPtr[bitmapWidth * j], 4 * bitmapWidth)) {
+ sameColor = false;
+ break;
+ }
+ }
+ delete pixelsRow;
+ pixelsRow = 0;
+
+ if (sameColor) {
+ char* rgbaPtr = static_cast<char*>(bitmap.getPixels());
+ pureColor = Color(rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
+ ALOGV("sameColor tile found , %x at (%d, %d, %d, %d)",
+ *firstPixelPtr, rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
+ }
+ bitmap.unlockPixels();
+
+ return sameColor;
+}
+
+// Return true when the tile is pure color.
+bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
+ const SkBitmap& bitmap)
+{
+ bool skipTransfer = false;
+ BaseTile* tilePtr = renderInfo->baseTile;
+
+ // TODO: use pure color for partial invals as well
+ if (renderInfo->invalRect)
+ return false;
+
+ if (tilePtr) {
+ BaseTileTexture* tileTexture = tilePtr->backTexture();
+ // Check the bitmap, and make everything ready here.
+ 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);
+
+ skipTransfer = true;
+ }
+ }
+ return skipTransfer;
+}
+
void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap)
{
if (!renderInfo)
return;
- const int x = renderInfo->invalRect->fLeft;
- const int y = renderInfo->invalRect->fTop;
const SkSize& requiredSize = renderInfo->tileSize;
TextureInfo* textureInfo = renderInfo->textureInfo;
- SharedTextureMode mode = textureInfo->getSharedTextureMode();
- if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height)) {
- if (mode == EglImageMode)
- GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, x, y, bitmap);
- else if (mode == SurfaceTextureMode)
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- GLUtils::updateSurfaceTextureWithBitmap(renderInfo, x, y, bitmap);
-#else
- GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, x, y, bitmap);
-#endif
- } else {
+ if (skipTransferForPureColor(renderInfo, bitmap))
+ return;
+
+ if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
+ GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
+ else {
if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
- XLOG("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
- bitmap.width(), bitmap.height(),
- requiredSize.width(), requiredSize.height());
+ ALOGV("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
+ bitmap.width(), bitmap.height(),
+ requiredSize.width(), requiredSize.height());
}
+ GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
- if (mode == EglImageMode)
- GLUtils::createTextureWithBitmap(textureInfo->m_textureId, bitmap);
- else if (mode == SurfaceTextureMode)
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- GLUtils::createSurfaceTextureWithBitmap(renderInfo, bitmap);
-#else
- GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, 0, 0, bitmap);
-#endif
textureInfo->m_width = bitmap.width();
textureInfo->m_height = bitmap.height();
textureInfo->m_internalFormat = GL_RGBA;
}
}
-#if DEPRECATED_SURFACE_TEXTURE_MODE
-void GLUtils::createSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap, GLint filter)
+void GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
{
+ if (!renderInfo
+ || !renderInfo->textureInfo
+ || !renderInfo->baseTile)
+ return;
- TextureInfo* texture = renderInfo->textureInfo;
-
- texture->m_width = bitmap.width();
- texture->m_height = bitmap.height();
- texture->m_internalFormat = GL_RGBA;
-
- sp<android::SurfaceTexture> surfaceTexture = texture->m_surfaceTexture;
- sp<ANativeWindow> ANW = texture->m_ANW;
-
- int result;
- result = native_window_set_buffers_geometry(ANW.get(),
- texture->m_width, texture->m_height, HAL_PIXEL_FORMAT_RGBA_8888);
- checkSurfaceTextureError("native_window_set_buffers_geometry", result);
- result = native_window_set_usage(ANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
- checkSurfaceTextureError("native_window_set_usage", result);
-
- updateSurfaceTextureWithBitmap(renderInfo, 0, 0, bitmap, filter);
+ TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, bitmap);
}
-void GLUtils::updateSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap, GLint filter)
+bool GLUtils::updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap)
{
- TextureInfo* texture = renderInfo->textureInfo;
- sp<android::SurfaceTexture> surfaceTexture = texture->m_surfaceTexture;
- sp<ANativeWindow> ANW = texture->m_ANW;
-
- ANativeWindowBuffer* anb;
- int status = ANW->dequeueBuffer(ANW.get(), &anb);
- checkSurfaceTextureError("dequeueBuffer", status);
-
- if (status != NO_ERROR) { // FIXME: add proper error handling!
- native_window_set_buffer_count(ANW.get(), 3);
- return;
+ 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());
- sp<android::GraphicBuffer> buf(new android::GraphicBuffer(anb, false));
- status |= ANW->lockBuffer(ANW.get(), buf->getNativeBuffer());
- checkSurfaceTextureError("lockBuffer", status);
-
- // Fill the buffer with the content of the bitmap
- uint8_t* img = 0;
- status |= buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- checkSurfaceTextureError("lock", status);
-
- if (status == NO_ERROR) {
- int row, col;
- int bpp = 4; // Now 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[(buf->getStride() * (row + x) + y) * bpp]);
+ uint8_t* dst = &(img[buffer.stride * row * bpp]);
uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
memcpy(dst, src, bpp * bitmap.width());
}
- bitmap.unlockPixels();
- }
- buf->unlock();
- status = ANW->queueBuffer(ANW.get(), buf->getNativeBuffer());
- checkSurfaceTextureError("queueBuffer", status);
-}
-#endif
-
-void GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap)
-{
- if (!renderInfo
- || !renderInfo->textureInfo
- || !renderInfo->baseTile)
- return;
+ else
+ memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
- TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, x, y, bitmap);
+ bitmap.unlockPixels();
+ ANativeWindow_unlockAndPost(anw);
+ return true;
}
void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
@@ -505,9 +566,12 @@ void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GL
0, internalformat, type, bitmap.getPixels());
bitmap.unlockPixels();
if (GLUtils::checkGlError("glTexImage2D")) {
- XLOG("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
- " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
- bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
+ " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
+ bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
@@ -523,7 +587,8 @@ void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GL
glDeleteFramebuffers(1, &fboID);
}
-void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitmap& bitmap, GLint filter)
+void GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
+ const IntRect& inval, GLint filter)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
@@ -532,13 +597,21 @@ void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitm
int internalformat = getInternalFormat(config);
int type = getType(config);
bitmap.lockPixels();
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, bitmap.width(), bitmap.height(),
- internalformat, type, bitmap.getPixels());
+ if (inval.isEmpty()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+ internalformat, type, bitmap.getPixels());
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), inval.width(), inval.height(),
+ internalformat, type, bitmap.getPixels());
+ }
bitmap.unlockPixels();
if (GLUtils::checkGlError("glTexSubImage2D")) {
- XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
- " x %d, y %d, internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
- bitmap.width(), bitmap.height(), x, y, internalformat, type, bitmap.getPixels());
+#ifndef DEBUG
+ if (allowGLLog())
+#endif
+ ALOGE("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
+ " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
+ bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
@@ -571,6 +644,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/GLUtils.h
index 68acbab..f24ea0d 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.h
+++ b/Source/WebCore/platform/graphics/android/GLUtils.h
@@ -28,6 +28,7 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "Color.h"
#include "SkBitmap.h"
#include "SkMatrix.h"
#include "SkSize.h"
@@ -73,17 +74,22 @@ public:
static GLuint createBaseTileGLTexture(int width, int height);
static void createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
- static void updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
+ static void updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, const IntRect&, GLint filter = GL_LINEAR);
static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image);
static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
static void paintTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap);
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- static void createSurfaceTextureWithBitmap(const TileRenderInfo* , const SkBitmap& bitmap, GLint filter = GL_LINEAR);
- static void updateSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
-#endif
- static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, 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;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 3bcda9a..a5080ca 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -23,11 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "GLWebViewState"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "GLWebViewState.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "BaseLayerAndroid.h"
#include "ClassTracker.h"
#include "GLUtils.h"
@@ -36,29 +40,10 @@
#include "ScrollableLayerAndroid.h"
#include "SkPath.h"
#include "TilesManager.h"
-#include "TilesTracker.h"
-#include "TreeManager.h"
-#include <wtf/CurrentTime.h>
-
+#include "SurfaceCollection.h"
+#include "SurfaceCollectionManager.h"
#include <pthread.h>
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLWebViewState", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+#include <wtf/CurrentTime.h>
#define FIRST_TILED_PAGE_ID 1
#define SECOND_TILED_PAGE_ID 2
@@ -69,32 +54,28 @@
#define MIN_SCALE_WARNING 0.1
#define MAX_SCALE_WARNING 10
+// fps indicator is FPS_INDICATOR_HEIGHT pixels high.
+// The max width is equal to MAX_FPS_VALUE fps.
+#define FPS_INDICATOR_HEIGHT 10
+#define MAX_FPS_VALUE 60
+
+#define COLLECTION_SWAPPED_COUNTER_MODULE 10
+
namespace WebCore {
using namespace android;
GLWebViewState::GLWebViewState()
- : m_zoomManager(this)
- , m_currentPictureCounter(0)
- , 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_highEndGfx(false)
, 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");
@@ -108,39 +89,26 @@ GLWebViewState::GLWebViewState()
GLWebViewState::~GLWebViewState()
{
- // Take care of the transfer queue such that Tex Gen thread will not stuck
- TilesManager::instance()->unregisterGLWebViewState(this);
-
- // 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
}
-void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval,
- bool showVisualIndicator, bool isPictureAfterFirstLayout)
+bool GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndicator,
+ bool isPictureAfterFirstLayout)
{
- if (!layer || isPictureAfterFirstLayout) {
- // TODO: move this into TreeManager
- m_zoomManager.swapPages(); // reset zoom state
- m_tiledPageA->discardTextures();
- m_tiledPageB->discardTextures();
+ if (!layer || isPictureAfterFirstLayout)
m_layersRenderingMode = kAllTextures;
- }
+
+ SurfaceCollection* collection = 0;
if (layer) {
- XLOG("new base layer %p, (inval region empty %d) with child %p", layer, inval.isEmpty(), layer->getChild(0));
+ ALOGV("layer tree %p, with child %p", layer, layer->getChild(0));
layer->setState(this);
- layer->markAsDirty(inval); // TODO: set in webview.cpp
+ collection = new SurfaceCollection(layer);
}
- m_treeManager.updateWithTree(layer, isPictureAfterFirstLayout);
+ bool queueFull = m_surfaceCollectionManager.updateWithSurfaceCollection(
+ collection, isPictureAfterFirstLayout);
m_glExtras.setDrawExtra(0);
#ifdef MEASURES_PERF
@@ -150,135 +118,54 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
#endif
TilesManager::instance()->setShowVisualIndicator(showVisualIndicator);
+ return queueFull;
}
void GLWebViewState::scrollLayer(int layerId, int x, int y)
{
- m_treeManager.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 layers tree 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)
-{
- m_currentPictureCounter++;
- if (!rect.isEmpty()) {
- // find which tiles fall within the invalRect and mark them as dirty
- m_tiledPageA->invalidateRect(rect, m_currentPictureCounter);
- m_tiledPageB->invalidateRect(rect, m_currentPictureCounter);
- if (m_frameworkInval.isEmpty())
- m_frameworkInval = rect;
- else
- m_frameworkInval.unite(rect);
- XLOG("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());
-}
-
-unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
-{
- m_treeManager.drawCanvas(canvas, m_layersRenderingMode == kSingleSurfaceRendering);
- return m_currentPictureCounter;
-}
-
-TiledPage* GLWebViewState::sibling(TiledPage* page)
-{
- return (page == m_tiledPageA) ? m_tiledPageB : m_tiledPageA;
+ m_surfaceCollectionManager.updateScrollableLayer(layerId, x, y);
}
-TiledPage* GLWebViewState::frontPage()
+void GLWebViewState::setViewport(const SkRect& viewport, float scale)
{
- android::Mutex::Autolock lock(m_tiledPageLock);
- return m_usePageA ? m_tiledPageA : m_tiledPageB;
-}
+ // allocate max possible number of tiles visible with this viewport / expandedTileBounds
+ const float invTileContentWidth = scale / TilesManager::tileWidth();
+ const float invTileContentHeight = scale / TilesManager::tileHeight();
-TiledPage* GLWebViewState::backPage()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- return m_usePageA ? m_tiledPageB : m_tiledPageA;
-}
+ int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1;
+ int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1;
-void GLWebViewState::swapPages()
-{
- android::Mutex::Autolock lock(m_tiledPageLock);
- m_usePageA ^= true;
- TiledPage* oldPage = m_usePageA ? m_tiledPageB : m_tiledPageA;
- zoomManager()->swapPages();
- oldPage->discardTextures();
-}
+ TilesManager* manager = TilesManager::instance();
+ int maxTextureCount = viewMaxTileX * viewMaxTileY * (manager->highEndGfx() ? 4 : 2);
-int GLWebViewState::baseContentWidth()
-{
- return m_treeManager.baseContentWidth();
-}
-int GLWebViewState::baseContentHeight()
-{
- return m_treeManager.baseContentHeight();
-}
+ manager->setMaxTextureCount(maxTextureCount);
-void GLWebViewState::setViewport(SkRect& viewport, float scale)
-{
- if ((m_viewport == viewport) &&
- (zoomManager()->futureScale() == scale))
+ // TODO: investigate whether we can move this return earlier.
+ if ((m_viewport == viewport)
+ && (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;
- m_viewport = viewport;
-
- XLOG("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)",
- m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
- m_viewport.width(), m_viewport.height(), scale,
- zoomManager()->currentScale(), zoomManager()->futureScale());
-
- const float invTileContentWidth = scale / TilesManager::tileWidth();
- const float invTileContentHeight = scale / TilesManager::tileHeight();
- 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)));
-
- // allocate max possible number of tiles visible with this viewport
- int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1;
- int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1;
-
- int maxTextureCount = (viewMaxTileX + m_expandedTileBoundsX * 2) *
- (viewMaxTileY + m_expandedTileBoundsY * 2) * (m_highEndGfx ? 4 : 2);
+ // detect viewport scrolling from short programmatic scrolls/jumps
+ m_isViewportScrolling = m_viewport != viewport && SkRect::Intersects(m_viewport, viewport);
+ m_viewport = viewport;
- TilesManager::instance()->setMaxTextureCount(maxTextureCount);
- m_tiledPageA->updateBaseTileSize();
- m_tiledPageB->updateBaseTileSize();
+ 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);
}
#ifdef MEASURES_PERF
void GLWebViewState::dumpMeasures()
{
for (int i = 0; i < m_timeCounter; i++) {
- XLOGC("%d delay: %d ms", m_totalTimeCounter + i,
+ ALOGD("%d delay: %d ms", m_totalTimeCounter + i,
static_cast<int>(m_delayTimes[i]*1000));
m_delayTimes[i] = 0;
}
@@ -287,14 +174,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())
@@ -316,42 +195,34 @@ 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(IntRect& viewRect, SkRect& visibleRect,
- IntRect& webViewRect, int titleBarHeight,
- IntRect& screenClip, float scale)
+double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
+ const IntRect& webViewRect, int titleBarHeight,
+ const IntRect& screenClip, float scale)
{
int left = viewRect.x();
int top = viewRect.y();
int width = viewRect.width();
int height = viewRect.height();
-
- ShaderProgram* shader = TilesManager::instance()->shader();
- if (shader->program() == -1) {
- XLOG("Reinit shader");
- shader->init();
+ TilesManager* tilesManager = TilesManager::instance();
+
+ // Make sure GL resources are created on the UI thread.
+ // They are created either for the first time, or after EGL context
+ // recreation caused by onTrimMemory in the framework.
+ ShaderProgram* shader = tilesManager->shader();
+ if (shader->needsInit()) {
+ ALOGD("Reinit shader");
+ shader->initGLResources();
}
- shader->setViewport(visibleRect, scale);
- shader->setViewRect(viewRect);
- shader->setWebViewRect(webViewRect);
- shader->setTitleBarHeight(titleBarHeight);
- shader->setScreenClip(screenClip);
- shader->resetBlending();
+ TransferQueue* transferQueue = tilesManager->transferQueue();
+ if (transferQueue->needsInit()) {
+ ALOGD("Reinit transferQueue");
+ transferQueue->initGLResources(TilesManager::tileWidth(),
+ TilesManager::tileHeight());
+ }
+ // TODO: Add the video GL resource re-initialization code here.
+ shader->setupDrawing(viewRect, visibleRect, webViewRect,
+ titleBarHeight, screenClip, scale);
shader->calculateAnimationDelta();
glViewport(left + shader->getAnimationDeltaX(),
@@ -361,7 +232,6 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect,
double currentTime = WTF::currentTime();
setViewport(visibleRect, scale);
- m_zoomManager.processNewScale(currentTime, scale);
return currentTime;
}
@@ -409,7 +279,7 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded)
if (m_layersRenderingMode != layersRenderingMode) {
char* mode[] = { "kAllTextures", "kClippedTextures",
"kScrollableAndFixedLayers", "kFixedLayers", "kSingleSurfaceRendering" };
- XLOGC("Change from mode %s to %s -- We need textures: fixed: %d,"
+ ALOGD("Change from mode %s to %s -- We need textures: fixed: %d,"
" scrollable: %d, clipped: %d, full: %d, max textures: %d",
static_cast<char*>(mode[layersRenderingMode]),
static_cast<char*>(mode[m_layersRenderingMode]),
@@ -427,90 +297,67 @@ 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* treesSwappedPtr, bool* newTreeHasAnimPtr)
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr)
{
- m_scale = scale;
- TilesManager::instance()->getProfiler()->nextFrame(viewport.fLeft,
- viewport.fTop,
- viewport.fRight,
- viewport.fBottom,
- scale);
- TilesManager::instance()->incDrawGLCount();
-
-#ifdef DEBUG
- TilesManager::instance()->getTilesTracker()->clear();
-#endif
-
- float viewWidth = (viewport.fRight - viewport.fLeft) * TILE_PREFETCH_RATIO;
- float viewHeight = (viewport.fBottom - viewport.fTop) * TILE_PREFETCH_RATIO;
- bool useMinimalMemory = TilesManager::instance()->useMinimalMemory();
- bool useHorzPrefetch = useMinimalMemory ? 0 : viewWidth < baseContentWidth();
- bool useVertPrefetch = useMinimalMemory ? 0 : viewHeight < baseContentHeight();
- m_expandedTileBoundsX = (useHorzPrefetch) ? TILE_PREFETCH_DISTANCE : 0;
- m_expandedTileBoundsY = (useVertPrefetch) ? TILE_PREFETCH_DISTANCE : 0;
-
- XLOG("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);
+ TilesManager* tilesManager = TilesManager::instance();
+ tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop,
+ viewport.fRight, viewport.fBottom,
+ scale);
+ tilesManager->incDrawGLCount();
+
+ 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);
+
+ ALOGV("drawGL, invalRect(%d, %d, %d, %d), webViewRect(%d, %d, %d, %d)"
+ "clip (%d, %d, %d, %d), scale %f",
+ invalRect->x(), invalRect->y(), invalRect->width(), invalRect->height(),
+ webViewRect.x(), webViewRect.y(), webViewRect.width(), webViewRect.height(),
+ clip.x(), clip.y(), clip.width(), clip.height(), scale);
resetLayersDirtyArea();
- // when adding or removing layers, use the the paintingBaseLayer's tree so
- // that content that moves to the base layer from a layer is synchronized
-
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING)
- XLOGC("WARNING, scale seems corrupted before update: %e", scale);
+ ALOGW("WARNING, scale seems corrupted before update: %e", scale);
// Here before we draw, update the BaseTile which has updated content.
// Inside this function, just do GPU blits from the transfer queue into
// the BaseTiles' texture.
- TilesManager::instance()->transferQueue()->updateDirtyBaseTiles();
+ tilesManager->transferQueue()->updateDirtyBaseTiles();
// 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);
- if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING)
- XLOGC("WARNING, scale seems corrupted after update: %e", scale);
+ if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
+ ALOGW("WARNING, scale seems corrupted after update: %e", scale);
+ CRASH();
+ }
// gather the textures we can use
- TilesManager::instance()->gatherLayerTextures();
+ tilesManager->gatherTextures();
double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale);
TexturesResult nbTexturesNeeded;
bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering;
- ret |= m_treeManager.drawGL(currentTime, rect, viewport,
- scale, fastSwap,
- treesSwappedPtr, newTreeHasAnimPtr,
- &nbTexturesNeeded);
- if (!ret)
- resetFrameworkInval();
+ m_glExtras.setViewport(viewport);
+ ret |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport,
+ scale, fastSwap,
+ collectionsSwappedPtr, newCollectionHasAnimPtr,
+ &nbTexturesNeeded);
int nbTexturesForImages = ImagesManager::instance()->nbTextures();
- XLOG("*** We have %d textures for images, %d full, %d clipped, total %d / %d",
+ ALOGV("*** We have %d textures for images, %d full, %d clipped, total %d / %d",
nbTexturesForImages, nbTexturesNeeded.full, nbTexturesNeeded.clipped,
nbTexturesNeeded.full + nbTexturesForImages,
nbTexturesNeeded.clipped + nbTexturesForImages);
@@ -518,45 +365,27 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
nbTexturesNeeded.clipped += nbTexturesForImages;
ret |= setLayersRenderingMode(nbTexturesNeeded);
- FloatRect extrasclip(0, 0, rect.width(), rect.height());
- TilesManager::instance()->shader()->clip(extrasclip);
-
- m_glExtras.drawGL(webViewRect, viewport, titleBarHeight);
-
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Clean up GL textures for video layer.
- TilesManager::instance()->videoLayerManager()->deleteUnusedTextures();
- ret |= TilesManager::instance()->invertedScreenSwitch();
+ tilesManager->videoLayerManager()->deleteUnusedTextures();
if (ret) {
// ret==true && 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::instance()->invertedScreenSwitch()) {
- fullScreenInval = true;
- TilesManager::instance()->setInvertedScreenSwitch(false);
- }
+ bool fullScreenInval = m_frameworkLayersInval.isEmpty();
if (!fullScreenInval) {
- FloatRect frameworkInval = TilesManager::instance()->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());
+ m_frameworkLayersInval.inflate(1);
- inval.unite(m_frameworkLayersInval);
+ invalRect->setX(m_frameworkLayersInval.x());
+ invalRect->setY(m_frameworkLayersInval.y());
+ invalRect->setWidth(m_frameworkLayersInval.width());
+ invalRect->setHeight(m_frameworkLayersInval.height());
- invalRect->setX(inval.x());
- invalRect->setY(inval.y());
- invalRect->setWidth(inval.width());
- invalRect->setHeight(inval.height());
-
- XLOG("invalRect(%d, %d, %d, %d)", inval.x(),
- inval.y(), inval.width(), inval.height());
+ ALOGV("invalRect(%d, %d, %d, %d)", inval.x(),
+ inval.y(), inval.width(), inval.height());
if (!invalRect->intersects(rect)) {
// invalidate is occurring offscreen, do full inval to guarantee redraw
@@ -570,10 +399,28 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
invalRect->setWidth(0);
invalRect->setHeight(0);
}
- } else {
- resetFrameworkInval();
}
+ showFrameInfo(rect, *collectionsSwappedPtr);
+
+ return ret;
+}
+
+void GLWebViewState::showFrameInfo(const IntRect& rect, bool collectionsSwapped)
+{
+ bool showVisualIndicator = TilesManager::instance()->getShowVisualIndicator();
+
+ bool drawOrDumpFrameInfo = showVisualIndicator;
+#ifdef MEASURES_PERF
+ drawOrDumpFrameInfo |= m_measurePerfs;
+#endif
+ if (!drawOrDumpFrameInfo)
+ return;
+
+ double currentDrawTime = WTF::currentTime();
+ double delta = currentDrawTime - m_prevDrawTime;
+ m_prevDrawTime = currentDrawTime;
+
#ifdef MEASURES_PERF
if (m_measurePerfs) {
m_delayTimes[m_timeCounter++] = delta;
@@ -582,12 +429,37 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
}
#endif
-#ifdef DEBUG
- TilesManager::instance()->getTilesTracker()->showTrackTextures();
- ImagesManager::instance()->showImages();
-#endif
+ IntRect frameInfoRect = rect;
+ frameInfoRect.setHeight(FPS_INDICATOR_HEIGHT);
+ double ratio = (1.0 / delta) / MAX_FPS_VALUE;
- return ret;
+ clearRectWithColor(frameInfoRect, 1, 1, 1, 1);
+ frameInfoRect.setWidth(frameInfoRect.width() * ratio);
+ clearRectWithColor(frameInfoRect, 1, 0, 0, 1);
+
+ // Draw the collection swap counter as a circling progress bar.
+ // This will basically show how fast we are updating the collection.
+ static int swappedCounter = 0;
+ if (collectionsSwapped)
+ swappedCounter = (swappedCounter + 1) % COLLECTION_SWAPPED_COUNTER_MODULE;
+
+ frameInfoRect = rect;
+ frameInfoRect.setHeight(FPS_INDICATOR_HEIGHT);
+ frameInfoRect.move(0, FPS_INDICATOR_HEIGHT);
+
+ clearRectWithColor(frameInfoRect, 1, 1, 1, 1);
+ ratio = (swappedCounter + 1.0) / COLLECTION_SWAPPED_COUNTER_MODULE;
+
+ frameInfoRect.setWidth(frameInfoRect.width() * ratio);
+ clearRectWithColor(frameInfoRect, 0, 1, 0, 1);
+}
+
+void GLWebViewState::clearRectWithColor(const IntRect& rect, float r, float g,
+ float b, float a)
+{
+ glScissor(rect.x(), rect.y(), rect.width(), rect.height());
+ glClearColor(r, g, b, a);
+ glClear(GL_COLOR_BUFFER_BIT);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 8d89704..e4b3b3b 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 "TreeManager.h"
-#include "ZoomManager.h"
+#include "SurfaceCollectionManager.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;
@@ -171,57 +166,26 @@ public:
GLWebViewState();
~GLWebViewState();
- ZoomManager* zoomManager() { return &m_zoomManager; }
- const SkIRect& futureViewport() const { return m_futureViewportTileBounds; }
- void setFutureViewport(const SkIRect& viewport) { m_futureViewportTileBounds = viewport; }
-
- unsigned int paintBaseLayerContent(SkCanvas* canvas);
- void setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval, bool showVisualIndicator,
+ 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();
-
- void setViewport(SkRect& viewport, float scale);
-
- // 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; }
-
- unsigned int currentPictureCounter() const { return m_currentPictureCounter; }
-
void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; }
- bool isScrolling() { return m_isScrolling; }
-
- void drawBackground(Color& backgroundColor);
- double setupDrawing(IntRect& viewRect, SkRect& visibleRect,
- IntRect& webViewRect, int titleBarHeight,
- IntRect& screenClip, float scale);
+ bool isScrolling() { return m_isScrolling || m_isViewportScrolling; }
bool setLayersRenderingMode(TexturesResult&);
- void fullInval();
bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
IntRect& webViewRect, int titleBarHeight,
IntRect& clip, float scale,
- bool* treesSwappedPtr, bool* newTreeHasAnimPtr);
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr);
#ifdef MEASURES_PERF
void dumpMeasures();
#endif
- void resetFrameworkInval();
void addDirtyArea(const IntRect& rect);
void resetLayersDirtyArea();
@@ -232,10 +196,6 @@ public:
m_goingLeft = goingLeft;
}
- int expandedTileBoundsX() { return m_expandedTileBoundsX; }
- int expandedTileBoundsY() { return m_expandedTileBoundsY; }
- void setHighEndGfx(bool highEnd) { m_highEndGfx = highEnd; }
-
float scale() { return m_scale; }
enum LayersRenderingMode {
@@ -250,24 +210,17 @@ 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,
+ const IntRect& screenClip, float scale);
+ void showFrameInfo(const IntRect& rect, bool collectionsSwapped);
+ void clearRectWithColor(const IntRect& rect, float r, float g,
+ 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;
-
- unsigned int m_currentPictureCounter;
- bool m_usePageA;
- TiledPage* m_tiledPageA;
- TiledPage* m_tiledPageB;
- IntRect m_lastInval;
- IntRect m_frameworkInval;
IntRect m_frameworkLayersInval;
#ifdef MEASURES_PERF
@@ -279,17 +232,14 @@ private:
GLExtras m_glExtras;
bool m_isScrolling;
+ bool m_isViewportScrolling;
bool m_goingDown;
bool m_goingLeft;
- int m_expandedTileBoundsX;
- int m_expandedTileBoundsY;
- bool m_highEndGfx;
-
float m_scale;
LayersRenderingMode m_layersRenderingMode;
- TreeManager m_treeManager;
+ SurfaceCollectionManager m_surfaceCollectionManager;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.cpp b/Source/WebCore/platform/graphics/android/GaneshContext.cpp
index 03e6eb7..620fccf 100644
--- a/Source/WebCore/platform/graphics/android/GaneshContext.cpp
+++ b/Source/WebCore/platform/graphics/android/GaneshContext.cpp
@@ -23,37 +23,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "GaneshContext"
+#define LOG_NDEBUG 1
#include "config.h"
#include "GaneshContext.h"
+
+#include "AndroidLog.h"
#include "GLUtils.h"
#include "android/native_window.h"
#if USE(ACCELERATED_COMPOSITING)
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GaneshContext", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
GaneshContext::GaneshContext()
: m_grContext(0)
- , m_baseTileDeviceFBO(0)
- , m_baseTileFBO(0)
- , m_baseTileStencil(0)
, m_baseTileDeviceSurface(0)
, m_surfaceConfig(0)
, m_surfaceContext(EGL_NO_CONTEXT)
@@ -90,33 +76,17 @@ SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo)
// reset the Ganesh context to prevent rendering issues.
bool contextNeedsReset = false;
if (eglGetCurrentContext() != m_surfaceContext) {
- XLOG("Warning: EGLContext has Changed! %p, %p", m_surfaceContext,
- eglGetCurrentContext());
+ ALOGV("Warning: EGLContext has Changed! %p, %p",
+ m_surfaceContext, eglGetCurrentContext());
contextNeedsReset = true;
}
- SkDevice* device = 0;
- if (renderInfo.textureInfo->getSharedTextureMode() == SurfaceTextureMode)
- device = getDeviceForBaseTileSurface(renderInfo);
- else if (renderInfo.textureInfo->getSharedTextureMode() == EglImageMode)
- device = getDeviceForBaseTileFBO(renderInfo);
-
- // We must reset the Ganesh context only after we are sure we have
- // re-established our EGLContext as the current context.
- if (device && contextNeedsReset)
- getGrContext()->resetContext();
-
- return device;
-}
-
-SkDevice* GaneshContext::getDeviceForBaseTileSurface(const TileRenderInfo& renderInfo)
-{
EGLDisplay display;
if (!m_surfaceContext) {
if(eglGetCurrentContext() != EGL_NO_CONTEXT) {
- XLOG("ERROR: should not have a context yet");
+ ALOGV("ERROR: should not have a context yet");
}
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -154,7 +124,6 @@ SkDevice* GaneshContext::getDeviceForBaseTileSurface(const TileRenderInfo& rende
}
TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
-
if (tileQueue->m_eglSurface == EGL_NO_SURFACE) {
const float tileWidth = renderInfo.tileSize.width();
@@ -170,112 +139,43 @@ SkDevice* GaneshContext::getDeviceForBaseTileSurface(const TileRenderInfo& rende
tileQueue->m_eglSurface = eglCreateWindowSurface(display, m_surfaceConfig, anw, NULL);
GLUtils::checkEglError("eglCreateWindowSurface");
- XLOG("eglCreateWindowSurface");
+ ALOGV("eglCreateWindowSurface");
}
EGLBoolean returnValue = eglMakeCurrent(display, tileQueue->m_eglSurface, tileQueue->m_eglSurface, m_surfaceContext);
GLUtils::checkEglError("eglMakeCurrent", returnValue);
- XLOG("eglMakeCurrent");
+ ALOGV("eglMakeCurrent");
if (!m_baseTileDeviceSurface) {
- GrPlatformSurfaceDesc surfaceDesc;
- surfaceDesc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
- surfaceDesc.fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit;
- surfaceDesc.fWidth = TilesManager::tileWidth();
- surfaceDesc.fHeight = TilesManager::tileHeight();
- surfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
- surfaceDesc.fStencilBits = 8;
- surfaceDesc.fPlatformRenderTarget = 0;
+ GrPlatformRenderTargetDesc renderTargetDesc;
+ renderTargetDesc.fWidth = TilesManager::tileWidth();
+ renderTargetDesc.fHeight = TilesManager::tileHeight();
+ renderTargetDesc.fConfig = kRGBA_8888_PM_GrPixelConfig;
+ renderTargetDesc.fSampleCnt = 0;
+ renderTargetDesc.fStencilBits = 8;
+ renderTargetDesc.fRenderTargetHandle = 0;
GrContext* grContext = getGrContext();
- GrRenderTarget* renderTarget = (GrRenderTarget*) grContext->createPlatformSurface(surfaceDesc);
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- renderInfo.tileSize.width(),
- renderInfo.tileSize.height());
+ GrRenderTarget* renderTarget = grContext->createPlatformRenderTarget(renderTargetDesc);
- m_baseTileDeviceSurface = new SkGpuDevice(grContext, bitmap, renderTarget);
+ m_baseTileDeviceSurface = new SkGpuDevice(grContext, renderTarget);
renderTarget->unref();
- XLOG("generated device %p", m_baseTileDeviceSurface);
+ ALOGV("generated device %p", m_baseTileDeviceSurface);
}
GLUtils::checkGlError("getDeviceForBaseTile");
- return m_baseTileDeviceSurface;
-}
-
-SkDevice* GaneshContext::getDeviceForBaseTileFBO(const TileRenderInfo& renderInfo)
-{
- const GLuint textureId = renderInfo.textureInfo->m_textureId;
- const float tileWidth = renderInfo.tileSize.width();
- const float tileHeight = renderInfo.tileSize.height();
-
- // bind to the current texture
- glBindTexture(GL_TEXTURE_2D, textureId);
-
- // setup the texture if needed
- if (renderInfo.textureInfo->m_width != tileWidth
- || renderInfo.textureInfo->m_height != tileHeight) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tileWidth, tileHeight,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- renderInfo.textureInfo->m_width = tileWidth;
- renderInfo.textureInfo->m_height = tileHeight;
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
-
- if (!m_baseTileFBO) {
- glGenFramebuffers(1, &m_baseTileFBO);
- XLOG("generated FBO");
- }
-
- if (!m_baseTileStencil) {
- glGenRenderbuffers(1, &m_baseTileStencil);
- glBindRenderbuffer(GL_RENDERBUFFER, m_baseTileStencil);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
- TilesManager::tileWidth(),
- TilesManager::tileHeight());
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
- XLOG("generated stencil");
- }
-
- // bind the FBO and attach the texture and stencil
- glBindFramebuffer(GL_FRAMEBUFFER, m_baseTileFBO);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_baseTileStencil);
-
- if (!m_baseTileDeviceFBO) {
-
- GrPlatformSurfaceDesc surfaceDesc;
- surfaceDesc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
- surfaceDesc.fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit;
- surfaceDesc.fWidth = TilesManager::tileWidth();
- surfaceDesc.fHeight = TilesManager::tileHeight();
- surfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
- surfaceDesc.fStencilBits = 8;
- surfaceDesc.fPlatformRenderTarget = m_baseTileFBO;
-
- GrContext* grContext = getGrContext();
- GrRenderTarget* renderTarget = (GrRenderTarget*) grContext->createPlatformSurface(surfaceDesc);
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- TilesManager::tileWidth(), TilesManager::tileWidth());
-
- m_baseTileDeviceFBO = new SkGpuDevice(grContext, bitmap, renderTarget);
- renderTarget->unref();
- XLOG("generated device %p", m_baseTileDeviceFBO);
- }
+ // 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)
+ getGrContext()->resetContext();
- GLUtils::checkGlError("getDeviceForBaseTile");
- return m_baseTileDeviceFBO;
+ return m_baseTileDeviceSurface;
}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.h b/Source/WebCore/platform/graphics/android/GaneshContext.h
index 12ea92d..def35e5 100644
--- a/Source/WebCore/platform/graphics/android/GaneshContext.h
+++ b/Source/WebCore/platform/graphics/android/GaneshContext.h
@@ -48,20 +48,8 @@ private:
GaneshContext();
GrContext* getGrContext();
-
- // Creates a device for rendering into a SurfaceTexture via an EGLSurface
- SkDevice* getDeviceForBaseTileSurface(const TileRenderInfo& renderInfo);
- // Creates a device for rendering into a EGLImage via an FBO
- SkDevice* getDeviceForBaseTileFBO(const TileRenderInfo& renderInfo);
-
GrContext* m_grContext;
- // FBO specific variables
- SkGpuDevice* m_baseTileDeviceFBO;
- GLuint m_baseTileFBO;
- GLuint m_baseTileStencil;
-
- // Surface specific variables
SkGpuDevice* m_baseTileDeviceSurface;
EGLConfig m_surfaceConfig;
EGLContext m_surfaceContext;
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
index f4df33a..559af1f 100644
--- a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
@@ -23,46 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "GaneshRenderer"
+#define LOG_NDEBUG 1
#include "config.h"
#include "GaneshRenderer.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "GaneshContext.h"
#include "SkCanvas.h"
#include "SkGpuDevice.h"
#include "TilesManager.h"
-
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GaneshRenderer", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
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
@@ -79,25 +55,18 @@ GaneshRenderer::~GaneshRenderer()
void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- if (renderInfo.measurePerf)
- m_perfMon.start(TAG_CREATE_FBO);
-
GaneshContext* ganesh = GaneshContext::instance();
-#if !DEPRECATED_SURFACE_TEXTURE_MODE
- if (renderInfo.textureInfo->getSharedTextureMode() == SurfaceTextureMode) {
- TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
+ TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
- tileQueue->lockQueue();
+ tileQueue->lockQueue();
- bool ready = tileQueue->readyForUpdate();
- if (!ready) {
- XLOG("!ready");
- tileQueue->unlockQueue();
- return;
- }
+ bool ready = tileQueue->readyForUpdate();
+ if (!ready) {
+ ALOGV("!ready");
+ tileQueue->unlockQueue();
+ return;
}
-#endif
SkDevice* device = NULL;
if (renderInfo.tileSize.width() == TilesManager::tileWidth()
@@ -105,25 +74,13 @@ void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
device = ganesh->getDeviceForBaseTile(renderInfo);
} else {
// TODO support arbitrary sizes for layers
- XLOG("ERROR: expected (%d,%d) actual (%d,%d)",
- TilesManager::tileWidth(), TilesManager::tileHeight(),
- renderInfo.tileSize.width(), renderInfo.tileSize.height());
- }
-
- if (renderInfo.measurePerf) {
- m_perfMon.stop(TAG_CREATE_FBO);
- m_perfMon.start(TAG_DRAW_PICTURE);
+ ALOGV("ERROR: expected (%d,%d) actual (%d,%d)",
+ TilesManager::tileWidth(), TilesManager::tileHeight(),
+ renderInfo.tileSize.width(), renderInfo.tileSize.height());
}
// set the GPU device to the canvas
canvas->setDevice(device);
- canvas->setDeviceFactory(device->getDeviceFactory());
-
- // invert canvas contents
- if (renderInfo.textureInfo->getSharedTextureMode() == EglImageMode) {
- canvas->scale(SK_Scalar1, -SK_Scalar1);
- canvas->translate(0, -renderInfo.tileSize.height());
- }
}
void GaneshRenderer::setupPartialInval(const TileRenderInfo& renderInfo, SkCanvas* canvas)
@@ -138,34 +95,16 @@ 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);
- }
-
- XLOG("rendered to tile (%d,%d)", renderInfo.x, renderInfo.y);
+ ALOGV("rendered to tile (%d,%d)", renderInfo.x, renderInfo.y);
GaneshContext::instance()->flush();
// In SurfaceTextureMode we must call swapBuffers to unlock and post the
// tile's ANativeWindow (i.e. SurfaceTexture) buffer
- if (renderInfo.textureInfo->getSharedTextureMode() == SurfaceTextureMode) {
-#if !DEPRECATED_SURFACE_TEXTURE_MODE
- TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
- eglSwapBuffers(eglGetCurrentDisplay(), tileQueue->m_eglSurface);
- tileQueue->addItemInTransferQueue(&renderInfo, GpuUpload, 0);
- tileQueue->unlockQueue();
-#endif
- }
-
- if (renderInfo.measurePerf)
- m_perfMon.stop(TAG_UPDATE_TEXTURE);
-}
-
-const String* GaneshRenderer::getPerformanceTags(int& tagCount)
-{
- tagCount = TAG_COUNT;
- return TAGS;
+ TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
+ eglSwapBuffers(eglGetCurrentDisplay(), tileQueue->m_eglSurface);
+ tileQueue->addItemInTransferQueue(&renderInfo, GpuUpload, 0);
+ tileQueue->unlockQueue();
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.h b/Source/WebCore/platform/graphics/android/GaneshRenderer.h
index 0e1d41e..d7eda24 100644
--- a/Source/WebCore/platform/graphics/android/GaneshRenderer.h
+++ b/Source/WebCore/platform/graphics/android/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/GradientAndroid.cpp b/Source/WebCore/platform/graphics/android/GradientAndroid.cpp
index b8dc9dd..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,40 +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)
{
- SkRect r;
- 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
index a490d5f..7d6c809 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -26,6 +26,7 @@
#include "GraphicsContext.h"
#include "AffineTransform.h"
+#include "Font.h"
#include "Gradient.h"
#include "NotImplemented.h"
#include "Path.h"
@@ -36,6 +37,7 @@
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
+#include "SkCornerPathEffect.h"
#include "SkDashPathEffect.h"
#include "SkDevice.h"
#include "SkGradientShader.h"
@@ -47,427 +49,36 @@
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)
- {};
-};
-
+// This class just holds onto a PlatformContextSkia for GraphicsContext.
class GraphicsContextPlatformPrivate {
+ WTF_MAKE_NONCOPYABLE(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;
- // This is a list of clipping paths which are currently active, in the
- // order in which they were pushed.
- WTF::Vector<SkPath> antiAliasClipPaths;
-
- 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(PlatformGraphicsContext* platformContext)
+ : m_context(platformContext) { }
+
+ PlatformGraphicsContext* context() { return m_context; }
- 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()
- {
- if (!m_state->antiAliasClipPaths.isEmpty())
- applyAntiAliasedClipPaths(m_state->antiAliasClipPaths);
-
- 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;
- }
-
- void clipPathAntiAliased(const SkPath& clipPath)
- {
- // If we are currently tracking any anti-alias clip paths, then we already
- // have a layer in place and don't need to add another.
- bool haveLayerOutstanding = m_state->antiAliasClipPaths.size();
-
- // See comments in applyAntiAliasedClipPaths about how this works.
- m_state->antiAliasClipPaths.append(clipPath);
- if (!haveLayerOutstanding) {
- SkRect bounds = clipPath.getBounds();
- if (m_platformGfxCtx && m_platformGfxCtx->mCanvas) {
- m_platformGfxCtx->mCanvas->saveLayerAlpha(&bounds, 255,
- static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag
- | SkCanvas::kFullColorLayer_SaveFlag
- | SkCanvas::kClipToLayer_SaveFlag));
- m_platformGfxCtx->mCanvas->save();
- } else
- ASSERT(0);
- }
- }
-
- void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
- {
- // Anti-aliased clipping:
- //
- // Refer to PlatformContextSkia.cpp's applyAntiAliasedClipPaths() for more details
-
- if (m_platformGfxCtx && m_platformGfxCtx->mCanvas)
- m_platformGfxCtx->mCanvas->restore();
-
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kClear_Mode);
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kFill_Style);
-
- if (m_platformGfxCtx && m_platformGfxCtx->mCanvas) {
- for (size_t i = paths.size() - 1; i < paths.size(); --i) {
- paths[i].setFillType(SkPath::kInverseWinding_FillType);
- m_platformGfxCtx->mCanvas->drawPath(paths[i], paint);
- }
- m_platformGfxCtx->mCanvas->restore();
- } else
- ASSERT(0);
- }
-
- 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&);
+ // Non-owning pointer to the PlatformContext.
+ PlatformGraphicsContext* m_context;
};
-static SkShader::TileMode SpreadMethod2TileMode(GradientSpreadMethod sm)
+static SkShader* extractShader(Pattern* pat, Gradient* grad)
{
- 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)));
- }
+ if (pat)
+ return pat->platformPattern(AffineTransform());
+ else if (grad)
+ return grad->platformGradient();
+ return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////
GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height)
{
- PlatformGraphicsContext* pgc = new PlatformGraphicsContext();
+ PlatformGraphicsContext* pgc = new PlatformGraphicsContext(new SkCanvas, true);
SkBitmap bitmap;
@@ -484,7 +95,9 @@ GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height)
void GraphicsContext::platformInit(PlatformGraphicsContext* gc)
{
- m_data = new GraphicsContextPlatformPrivate(this, gc);
+ if (gc)
+ gc->setGraphicsContext(this);
+ m_data = new GraphicsContextPlatformPrivate(gc);
setPaintingDisabled(!gc || !gc->mCanvas);
}
@@ -495,28 +108,26 @@ void GraphicsContext::platformDestroy()
void GraphicsContext::savePlatformState()
{
- // Save our private State
- m_data->save();
- // Save our native canvas
- GC2CANVAS(this)->save();
+ if (paintingDisabled())
+ return;
+ platformContext()->save();
}
void GraphicsContext::restorePlatformState()
{
- // Restore our private State
- m_data->restore();
- // Restore our native canvas
- GC2CANVAS(this)->restore();
+ if (paintingDisabled())
+ return;
+ platformContext()->restore();
}
bool GraphicsContext::willFill() const
{
- return m_data->getState()->fillColor;
+ return m_state.fillColor.rgb();
}
bool GraphicsContext::willStroke() const
{
- return m_data->getState()->strokeColor;
+ return m_state.strokeColor.rgb();
}
// Draws a filled rectangle with a stroked border.
@@ -525,24 +136,7 @@ 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);
- }
+ platformContext()->drawRect(rect);
}
// This is only used to draw borders.
@@ -551,119 +145,24 @@ 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;
+ platformContext()->drawLine(point1, point2);
}
-void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool)
+void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool /* printing */)
{
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);
+ platformContext()->drawLineForText(pt, width);
}
-// TODO: Should we draw different based on TextCheckingLineStyle?
-void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, TextCheckingLineStyle)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width,
+ TextCheckingLineStyle style)
{
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);
+ platformContext()->drawLineForTextChecking(pt, width, style);
}
// This method is only used to draw the little circles used in lists.
@@ -672,28 +171,7 @@ 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);
+ platformContext()->drawEllipse(rect);
}
void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan)
@@ -701,138 +179,43 @@ 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);
+ platformContext()->strokeArc(r, startAngle, angleSpan);
}
-void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
+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);
- }
+ 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)
+ const IntSize& bottomLeft, const IntSize& bottomRight,
+ const Color& color, ColorSpace 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);
+ platformContext()->fillRoundedRect(rect, topLeft, topRight,
+ bottomLeft, bottomRight, color, colorSpace);
}
void GraphicsContext::fillRect(const FloatRect& rect)
{
- save();
- SkPaint paint;
-
- m_data->setupPaintFill(&paint);
-
- extactShader(&paint,
- m_state.fillPattern.get(),
- m_state.fillGradient.get());
+ if (paintingDisabled())
+ return;
- GC2CANVAS(this)->drawRect(rect, paint);
- restore();
+ platformContext()->fillRect(rect);
}
-void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace)
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace 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();
- }
+ platformContext()->fillRect(rect, color, colorSpace);
}
void GraphicsContext::clip(const FloatRect& rect)
@@ -840,7 +223,7 @@ void GraphicsContext::clip(const FloatRect& rect)
if (paintingDisabled())
return;
- GC2CANVAS(this)->clipRect(rect);
+ platformContext()->clip(rect);
}
void GraphicsContext::clip(const Path& path)
@@ -848,7 +231,7 @@ void GraphicsContext::clip(const Path& path)
if (paintingDisabled())
return;
- m_data->clipPathAntiAliased(*path.platformPath());
+ platformContext()->clip(path);
}
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
@@ -856,24 +239,15 @@ 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);
- }
- m_data->clipPathAntiAliased(path);
+ platformContext()->addInnerRoundedRectClip(rect, thickness);
}
void GraphicsContext::canvasClip(const Path& path)
{
- clip(path);
+ if (paintingDisabled())
+ return;
+
+ platformContext()->canvasClip(path);
}
void GraphicsContext::clipOut(const IntRect& r)
@@ -881,7 +255,7 @@ void GraphicsContext::clipOut(const IntRect& r)
if (paintingDisabled())
return;
- GC2CANVAS(this)->clipRect(r, SkRegion::kDifference_Op);
+ platformContext()->clipOut(r);
}
#if ENABLE(SVG)
@@ -890,9 +264,7 @@ 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);
+ platformContext()->clipPath(pathToClip, clipRule);
}
#endif
@@ -901,7 +273,7 @@ void GraphicsContext::clipOut(const Path& p)
if (paintingDisabled())
return;
- GC2CANVAS(this)->clipPath(*p.platformPath(), SkRegion::kDifference_Op);
+ platformContext()->clipOut(p);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
@@ -913,20 +285,12 @@ KRenderingDeviceContext* GraphicsContext::createRenderingDeviceContext()
}
#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);
+ platformContext()->beginTransparencyLayer(opacity);
}
void GraphicsContext::endTransparencyLayer()
@@ -934,44 +298,58 @@ void GraphicsContext::endTransparencyLayer()
if (paintingDisabled())
return;
- GC2CANVAS(this)->restore();
+ platformContext()->endTransparencyLayer();
}
///////////////////////////////////////////////////////////////////////////
-void GraphicsContext::setupBitmapPaint(SkPaint* paint)
-{
- m_data->setupPaintBitmap(paint);
-}
-
void GraphicsContext::setupFillPaint(SkPaint* paint)
{
- m_data->setupPaintFill(paint);
+ if (paintingDisabled())
+ return;
+ platformContext()->setupPaintFill(paint);
}
void GraphicsContext::setupStrokePaint(SkPaint* paint)
{
- m_data->setupPaintStroke(paint, 0);
+ if (paintingDisabled())
+ return;
+ platformContext()->setupPaintStroke(paint, 0);
}
bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset)
{
- return m_data->getState()->setupShadowPaint(this, paint, offset);
+ if (paintingDisabled())
+ return false;
+ return platformContext()->setupPaintShadow(paint, offset);
}
void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace)
{
- m_data->setStrokeColor(c);
+ if (paintingDisabled())
+ return;
+ platformContext()->setStrokeColor(c);
}
void GraphicsContext::setPlatformStrokeThickness(float f)
{
- m_data->setStrokeThickness(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)
{
- m_data->setFillColor(c);
+ if (paintingDisabled())
+ return;
+ platformContext()->setFillColor(c);
}
void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace)
@@ -987,7 +365,7 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const
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);
+ platformContext()->setShadow(blur, size.width(), size.height(), c);
}
void GraphicsContext::clearPlatformShadow()
@@ -995,14 +373,17 @@ void GraphicsContext::clearPlatformShadow()
if (paintingDisabled())
return;
- m_data->getState()->setShadow(0, 0, 0, 0);
+ platformContext()->setShadow(0, 0, 0, 0);
}
///////////////////////////////////////////////////////////////////////////////
-void GraphicsContext::drawFocusRing(const Vector<IntRect>&, int, int, const Color&)
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
{
- // Do nothing, since we draw the focus ring independently.
+ if (paintingDisabled())
+ return;
+
+ platformContext()->drawFocusRing(rects, width, offset, color);
}
void GraphicsContext::drawFocusRing(const Path&, int, int, const Color&)
@@ -1013,22 +394,28 @@ void GraphicsContext::drawFocusRing(const Path&, int, int, const Color&)
PlatformGraphicsContext* GraphicsContext::platformContext() const
{
ASSERT(!paintingDisabled());
- return m_data->getPlatformGfxCtx();
+ return m_data->context();
}
void GraphicsContext::setMiterLimit(float limit)
{
- m_data->getState()->miterLimit = limit;
+ if (paintingDisabled())
+ return;
+ platformContext()->setMiterLimit(limit);
}
void GraphicsContext::setAlpha(float alpha)
{
- m_data->getState()->alpha = alpha;
+ if (paintingDisabled())
+ return;
+ platformContext()->setAlpha(alpha);
}
void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
{
- m_data->getState()->mode = WebCoreCompositeToSkiaComposite(op);
+ if (paintingDisabled())
+ return;
+ platformContext()->setCompositeOperation(op);
}
void GraphicsContext::clearRect(const FloatRect& rect)
@@ -1036,11 +423,7 @@ 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);
+ platformContext()->clearRect(rect);
}
void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
@@ -1048,29 +431,14 @@ 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);
+ platformContext()->strokeRect(rect, lineWidth);
}
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 (paintingDisabled())
+ return;
+ platformContext()->setLineCap(cap);
}
#if ENABLE(SVG)
@@ -1079,67 +447,43 @@ 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;
+ platformContext()->setLineDash(dashes, dashOffset);
}
#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;
- }
+ if (paintingDisabled())
+ return;
+ platformContext()->setLineJoin(join);
}
void GraphicsContext::scale(const FloatSize& size)
{
if (paintingDisabled())
return;
- GC2CANVAS(this)->scale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
+ platformContext()->scale(size);
}
void GraphicsContext::rotate(float angleInRadians)
{
if (paintingDisabled())
return;
- GC2CANVAS(this)->rotate(SkFloatToScalar(angleInRadians * (180.0f / 3.14159265f)));
+ platformContext()->rotate(angleInRadians);
}
void GraphicsContext::translate(float x, float y)
{
if (paintingDisabled())
return;
- GC2CANVAS(this)->translate(SkFloatToScalar(x), SkFloatToScalar(y));
+ platformContext()->translate(x, y);
}
void GraphicsContext::concatCTM(const AffineTransform& affine)
{
if (paintingDisabled())
return;
- GC2CANVAS(this)->concat(affine);
+ platformContext()->concatCTM(affine);
}
// This is intended to round the rect to device pixels (through the CTM)
@@ -1164,39 +508,52 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMo
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);
+void GraphicsContext::setPlatformShouldAntialias(bool useAA)
+{
+ if (paintingDisabled())
+ return;
+ platformContext()->setShouldAntialias(useAA);
+}
- CGPDFContextSetURLForRect(context, urlRef,
- CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
+void GraphicsContext::setPlatformFillGradient(Gradient* fillGradient)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(0, fillGradient);
+ platformContext()->setFillShader(shader);
+}
- CFRelease(urlRef);
+void GraphicsContext::setPlatformFillPattern(Pattern* fillPattern)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(fillPattern, 0);
+ platformContext()->setFillShader(shader);
}
-#endif
+
+void GraphicsContext::setPlatformStrokeGradient(Gradient* strokeGradient)
+{
+ if (paintingDisabled())
+ return;
+ SkShader* shader = extractShader(0, strokeGradient);
+ platformContext()->setStrokeShader(shader);
}
-void GraphicsContext::setPlatformShouldAntialias(bool useAA)
+void GraphicsContext::setPlatformStrokePattern(Pattern* strokePattern)
{
if (paintingDisabled())
return;
- m_data->getState()->useAA = useAA;
+ SkShader* shader = extractShader(strokePattern, 0);
+ platformContext()->setStrokeShader(shader);
}
AffineTransform GraphicsContext::getCTM() const
{
- const SkMatrix& m = GC2CANVAS(this)->getTotalMatrix();
+ if (paintingDisabled())
+ return AffineTransform();
+ const SkMatrix& m = platformContext()->getTotalMatrix();
return AffineTransform(SkScalarToDouble(m.getScaleX()), // a
SkScalarToDouble(m.getSkewY()), // b
SkScalarToDouble(m.getSkewX()), // c
@@ -1218,43 +575,18 @@ void GraphicsContext::setCTM(const AffineTransform& transform)
void GraphicsContext::fillPath(const Path& pathToFill)
{
- SkPath* path = pathToFill.platformPath();
- if (paintingDisabled() || !path)
+ if (paintingDisabled())
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);
+ platformContext()->fillPath(pathToFill, fillRule());
}
void GraphicsContext::strokePath(const Path& pathToStroke)
{
- const SkPath* path = pathToStroke.platformPath();
- if (paintingDisabled() || !path)
+ if (paintingDisabled())
return;
- SkPaint paint;
- m_data->setupPaintStroke(&paint, 0);
-
- extactShader(&paint,
- m_state.strokePattern.get(),
- m_state.strokeGradient.get());
-
- GC2CANVAS(this)->drawPath(*path, paint);
+ platformContext()->strokePath(pathToStroke);
}
InterpolationQuality GraphicsContext::imageInterpolationQuality() const
@@ -1280,7 +612,8 @@ void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode)
// Certainly safe to do nothing for the present.
}
-void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias)
+void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint*,
+ bool antialias)
{
if (paintingDisabled())
return;
@@ -1291,6 +624,19 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint*, boo
// 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
///////////////////////////////////////////////////////////////////////////////
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 567b54b..fa620e0 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -14,20 +14,29 @@
* limitations under the License.
*/
+#define LOG_TAG "GraphicsLayerAndroid"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "GraphicsLayerAndroid.h"
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidAnimation.h"
+#include "AndroidLog.h"
#include "Animation.h"
+#include "CanvasLayer.h"
#include "FloatRect.h"
+#include "FixedPositioning.h"
#include "GraphicsContext.h"
+#include "IFrameContentLayerAndroid.h"
+#include "IFrameLayerAndroid.h"
#include "Image.h"
#include "ImagesManager.h"
#include "Layer.h"
#include "Length.h"
#include "MediaLayer.h"
+#include "PictureLayerContent.h"
#include "PlatformBridge.h"
#include "PlatformGraphicsContext.h"
#include "RenderLayerBacking.h"
@@ -40,23 +49,9 @@
#include "TransformationMatrix.h"
#include "TranslateTransformOperation.h"
-#include <cutils/log.h>
#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
-#undef LOG
-#define LOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
-#define MLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
-#define TLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GraphicsLayer", __VA_ARGS__)
-
-#undef LOG
-#define LOG(...)
-#undef MLOG
-#define MLOG(...)
-#undef TLOG
-#define TLOG(...)
-#undef LAYER_DEBUG
-
using namespace std;
static bool gPaused;
@@ -125,7 +120,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++;
}
@@ -148,7 +147,7 @@ void GraphicsLayerAndroid::setName(const String& name)
NativeLayer GraphicsLayerAndroid::nativeLayer() const
{
- LOG("(%x) nativeLayer", this);
+ ALOGV("(%x) nativeLayer", this);
return 0;
}
@@ -167,7 +166,7 @@ void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
{
#ifndef NDEBUG
const String& name = childLayer->name();
- LOG("(%x) addChild: %x (%s)", this, childLayer, name.latin1().data());
+ ALOGV("(%x) addChild: %x (%s)", this, childLayer, name.latin1().data());
#endif
GraphicsLayer::addChild(childLayer);
m_needsSyncChildren = true;
@@ -176,7 +175,7 @@ void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer)
void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
{
- LOG("(%x) addChild %x AtIndex %d", this, childLayer, index);
+ ALOGV("(%x) addChild %x AtIndex %d", this, childLayer, index);
GraphicsLayer::addChildAtIndex(childLayer, index);
m_needsSyncChildren = true;
askForSync();
@@ -184,7 +183,7 @@ void GraphicsLayerAndroid::addChildAtIndex(GraphicsLayer* childLayer, int index)
void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
{
- LOG("(%x) addChild %x Below %x", this, childLayer, sibling);
+ ALOGV("(%x) addChild %x Below %x", this, childLayer, sibling);
GraphicsLayer::addChildBelow(childLayer, sibling);
m_needsSyncChildren = true;
askForSync();
@@ -192,7 +191,7 @@ void GraphicsLayerAndroid::addChildBelow(GraphicsLayer* childLayer, GraphicsLaye
void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
{
- LOG("(%x) addChild %x Above %x", this, childLayer, sibling);
+ ALOGV("(%x) addChild %x Above %x", this, childLayer, sibling);
GraphicsLayer::addChildAbove(childLayer, sibling);
m_needsSyncChildren = true;
askForSync();
@@ -200,7 +199,7 @@ void GraphicsLayerAndroid::addChildAbove(GraphicsLayer* childLayer, GraphicsLaye
bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
{
- LOG("(%x) replaceChild %x by %x", this, oldChild, newChild);
+ ALOGV("(%x) replaceChild %x by %x", this, oldChild, newChild);
bool ret = GraphicsLayer::replaceChild(oldChild, newChild);
if (ret) {
m_needsSyncChildren = true;
@@ -211,7 +210,7 @@ bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer*
void GraphicsLayerAndroid::removeFromParent()
{
- LOG("(%x) removeFromParent()", this);
+ ALOGV("(%x) removeFromParent()", this);
GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
GraphicsLayer::removeFromParent();
// Update the parent's children.
@@ -221,7 +220,7 @@ void GraphicsLayerAndroid::removeFromParent()
}
}
-void GraphicsLayerAndroid::updateFixedPosition()
+void GraphicsLayerAndroid::updatePositionedLayers()
{
RenderLayer* renderLayer = renderLayerFromClient(m_client);
if (!renderLayer)
@@ -232,10 +231,15 @@ void GraphicsLayerAndroid::updateFixedPosition()
return;
// We will need the Iframe flag in the LayerAndroid tree for fixed position
- if (view->isRenderIFrame())
- m_contentLayer->setIsIframe(true);
+ if (view->isRenderIFrame() && !m_contentLayer->isIFrame()) {
+ LayerAndroid* layer = new IFrameLayerAndroid(*m_contentLayer);
+ m_contentLayer->unref();
+ m_contentLayer = layer;
+ }
+
// If we are a fixed position layer, just set it
if (view->isPositioned() && view->style()->position() == FixedPosition) {
+ m_contentLayer->setAbsolutePosition(false);
// We need to get the passed CSS properties for the element
SkLength left, top, right, bottom;
left = convertLength(view->style()->left());
@@ -264,11 +268,23 @@ void GraphicsLayerAndroid::updateFixedPosition()
SkRect viewRect;
viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h);
IntPoint renderLayerPos(renderLayer->x(), renderLayer->y());
- m_contentLayer->setFixedPosition(left, top, right, bottom,
- marginLeft, marginTop,
- marginRight, marginBottom,
- renderLayerPos,
- viewRect);
+
+ FixedPositioning* fixedPosition = m_contentLayer->fixedPosition();
+ if (!fixedPosition) {
+ fixedPosition = new FixedPositioning();
+ m_contentLayer->setFixedPosition(fixedPosition);
+ }
+
+ fixedPosition->setFixedPosition(left, top, right, bottom,
+ marginLeft, marginTop,
+ marginRight, marginBottom,
+ renderLayerPos,
+ viewRect);
+ } else if (view->isPositioned() && view->style()->position() == AbsolutePosition) {
+ m_contentLayer->setAbsolutePosition(true);
+ } else {
+ m_contentLayer->setFixedPosition(0);
+ m_contentLayer->setAbsolutePosition(false);
}
}
@@ -280,7 +296,7 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
GraphicsLayer::setPosition(point);
#ifdef LAYER_DEBUG_2
- LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
+ 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
@@ -312,7 +328,7 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
{
if (size == m_size)
return;
- MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
+ ALOGV("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
GraphicsLayer::setSize(size);
// If it is a media layer the size may have changed as a result of the media
@@ -323,8 +339,8 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
RenderBox* box = layer->renderBox();
int outline = box->view()->maximalOutlineSize();
static_cast<MediaLayer*>(m_contentLayer)->setOutlineSize(outline);
- LOG("Media Outline: %d %p %p %p", outline, m_client, layer, box);
- LOG("Media Size: %g,%g", size.width(), size.height());
+ ALOGV("Media Outline: %d %p %p %p", outline, m_client, layer, box);
+ ALOGV("Media Size: %g,%g", size.width(), size.height());
}
m_contentLayer->setSize(size.width(), size.height());
@@ -356,7 +372,7 @@ void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t)
{
if (t == m_childrenTransform)
return;
- LOG("(%x) setChildrenTransform", this);
+ ALOGV("(%x) setChildrenTransform", this);
GraphicsLayer::setChildrenTransform(t);
m_contentLayer->setChildrenTransform(t);
@@ -405,7 +421,7 @@ void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
{
if (color == m_backgroundColor && m_backgroundColorSet)
return;
- LOG("(%x) setBackgroundColor", this);
+ ALOGV("(%x) setBackgroundColor", this);
GraphicsLayer::setBackgroundColor(color);
SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue());
m_contentLayer->setBackgroundColor(c);
@@ -418,7 +434,7 @@ void GraphicsLayerAndroid::clearBackgroundColor()
if (!m_backgroundColorSet)
return;
- LOG("(%x) clearBackgroundColor", this);
+ ALOGV("(%x) clearBackgroundColor", this);
GraphicsLayer::clearBackgroundColor();
askForSync();
}
@@ -427,7 +443,7 @@ void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
{
if (opaque == m_contentsOpaque)
return;
- LOG("(%x) setContentsOpaque (%d)", this, opaque);
+ ALOGV("(%x) setContentsOpaque (%d)", this, opaque);
GraphicsLayer::setContentsOpaque(opaque);
m_haveContents = true;
askForSync();
@@ -435,13 +451,13 @@ void GraphicsLayerAndroid::setContentsOpaque(bool opaque)
void GraphicsLayerAndroid::setOpacity(float opacity)
{
- LOG("(%x) setOpacity: %.2f", this, opacity);
+ ALOGV("(%x) setOpacity: %.2f", this, opacity);
float clampedOpacity = max(0.0f, min(opacity, 1.0f));
if (clampedOpacity == m_opacity)
return;
- MLOG("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
+ ALOGV("(%x) setFinalOpacity: %.2f=>%.2f (%.2f)", this,
opacity, clampedOpacity, m_opacity);
GraphicsLayer::setOpacity(clampedOpacity);
m_contentLayer->setOpacity(clampedOpacity);
@@ -450,7 +466,7 @@ void GraphicsLayerAndroid::setOpacity(float opacity)
void GraphicsLayerAndroid::setNeedsDisplay()
{
- LOG("(%x) setNeedsDisplay()", this);
+ ALOGV("(%x) setNeedsDisplay()", this);
FloatRect rect(0, 0, m_size.width(), m_size.height());
setNeedsDisplayInRect(rect);
}
@@ -508,6 +524,8 @@ void GraphicsLayerAndroid::updateScrollingLayers()
if (layerNeedsOverflow) {
ASSERT(!m_foregroundLayer && !m_foregroundClipLayer);
m_foregroundLayer = new ScrollableLayerAndroid(layer);
+
+ // TODO: can clip layer be set to not intrinsically composited?
m_foregroundClipLayer = new LayerAndroid(layer);
m_foregroundClipLayer->setMasksToBounds(true);
m_foregroundClipLayer->addChild(m_foregroundLayer);
@@ -518,7 +536,7 @@ void GraphicsLayerAndroid::updateScrollingLayers()
// No need to copy the children as they will be removed and synced.
m_contentLayer->removeChildren();
// Replace the content layer with a scrollable layer.
- LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer);
+ LayerAndroid* layer = new IFrameContentLayerAndroid(*m_contentLayer);
m_contentLayer->unref();
m_contentLayer = layer;
if (m_parent) {
@@ -555,10 +573,25 @@ void GraphicsLayerAndroid::updateScrollingLayers()
#endif
}
+void GraphicsLayerAndroid::updateScrollOffset() {
+ RenderLayer* layer = renderLayerFromClient(m_client);
+ if (!layer || !(m_foregroundLayer || m_contentLayer->contentIsScrollable()))
+ return;
+ if (m_foregroundLayer) {
+ IntSize scroll = layer->scrolledContentOffset();
+ m_foregroundLayer->setScrollOffset(IntPoint(scroll.width(), scroll.height()));
+ } else if (m_contentLayer->isIFrameContent()) {
+ IntPoint p(layer->renderer()->frame()->view()->scrollX(),
+ layer->renderer()->frame()->view()->scrollY());
+ static_cast<IFrameContentLayerAndroid*>(m_contentLayer)->setIFrameScrollOffset(p);
+ }
+ askForSync();
+}
+
bool GraphicsLayerAndroid::repaint()
{
- LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
- this, gPaused, m_needsRepaint, m_haveContents);
+ ALOGV("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
+ this, gPaused, m_needsRepaint, m_haveContents);
if (!gPaused && m_haveContents && m_needsRepaint && !m_image) {
// with SkPicture, we request the entire layer's content.
@@ -571,16 +604,17 @@ bool GraphicsLayerAndroid::repaint()
PaintingPhase phase(this);
// Paint the background into a separate context.
phase.set(GraphicsLayerPaintBackground);
- if (!paintContext(m_contentLayer->recordContext(), layerBounds))
+ if (!paintContext(m_contentLayer, layerBounds))
return false;
- m_contentLayer->checkTextPresence();
// Construct the foreground layer and draw.
RenderBox* box = layer->renderBox();
int outline = box->view()->maximalOutlineSize();
IntRect contentsRect(0, 0,
- box->borderLeft() + box->borderRight() + layer->scrollWidth(),
- box->borderTop() + box->borderBottom() + layer->scrollHeight());
+ box->borderLeft() + box->borderRight() + layer->scrollWidth()
+ + layer->verticalScrollbarWidth(),
+ box->borderTop() + box->borderBottom() + layer->scrollHeight()
+ + layer->horizontalScrollbarHeight());
contentsRect.inflate(outline);
// Update the foreground layer size.
m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height());
@@ -591,8 +625,7 @@ bool GraphicsLayerAndroid::repaint()
IntSize scroll = layer->scrolledContentOffset();
layer->scrollToOffset(0, 0);
// At this point, it doesn't matter if painting failed.
- (void) paintContext(m_foregroundLayer->recordContext(), contentsRect);
- m_foregroundLayer->checkTextPresence();
+ (void) paintContext(m_foregroundLayer, contentsRect);
layer->scrollToOffset(scroll.width(), scroll.height());
// Construct the clip layer for masking the contents.
@@ -606,6 +639,11 @@ bool GraphicsLayerAndroid::repaint()
m_foregroundClipLayer->setPosition(x, y);
m_foregroundClipLayer->setSize(width, height);
+ int rtlOffset = 0; // LTR uses no offset.
+ if (!layer->renderer()->style()->isLeftToRightDirection())
+ rtlOffset = layer->scrollWidth() - width; // Scroll all the way right.
+ m_foregroundLayer->setScrollOffset(IntPoint(scroll.width() + rtlOffset,
+ scroll.height()));
// Need to offset the foreground layer by the clip layer in order
// for the contents to be in the correct position.
m_foregroundLayer->setPosition(-x, -y);
@@ -619,32 +657,33 @@ bool GraphicsLayerAndroid::repaint()
SkRegion region;
region.setRect(0, 0, contentsRect.width(), contentsRect.height());
m_foregroundLayer->markAsDirty(region);
- m_foregroundLayer->needsRepaint();
} else {
// If there is no contents clip, we can draw everything into one
// picture.
- if (!paintContext(m_contentLayer->recordContext(), layerBounds))
+ bool painting = paintContext(m_contentLayer, layerBounds);
+ if (!painting)
return false;
- m_contentLayer->checkTextPresence();
// Check for a scrollable iframe and report the scrolling
// limits based on the view size.
- if (m_contentLayer->contentIsScrollable()) {
+ if (m_contentLayer->isIFrameContent()) {
FrameView* view = layer->renderer()->frame()->view();
- static_cast<ScrollableLayerAndroid*>(m_contentLayer)->setScrollLimits(
+ static_cast<IFrameContentLayerAndroid*>(m_contentLayer)->setScrollLimits(
m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight());
+ ALOGV("setScrollLimits(%.2f, %.2f, w: %d h: %d) layer %d, frame scroll position is %d, %d",
+ m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight(),
+ m_contentLayer->uniqueId(), view->scrollX(), view->scrollY());
}
}
- LOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
- this, m_size.width(), m_size.height(),
- m_contentLayer->getPosition().fX,
- m_contentLayer->getPosition().fY,
- m_contentLayer->getSize().width(),
- m_contentLayer->getSize().height());
+ ALOGV("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!",
+ this, m_size.width(), m_size.height(),
+ m_contentLayer->getPosition().fX,
+ m_contentLayer->getPosition().fY,
+ m_contentLayer->getSize().width(),
+ m_contentLayer->getSize().height());
m_contentLayer->markAsDirty(m_dirtyRegion);
m_dirtyRegion.setEmpty();
- m_contentLayer->needsRepaint();
m_needsRepaint = false;
return true;
@@ -654,7 +693,6 @@ bool GraphicsLayerAndroid::repaint()
// texture. Only do so if we effectively have a new image!
m_contentLayer->markAsDirty(m_dirtyRegion);
m_dirtyRegion.setEmpty();
- m_contentLayer->needsRepaint();
m_newImage = false;
m_needsRepaint = false;
return true;
@@ -662,19 +700,32 @@ bool GraphicsLayerAndroid::repaint()
return false;
}
-bool GraphicsLayerAndroid::paintContext(SkPicture* context,
+bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
const IntRect& rect)
{
- SkAutoPictureRecord arp(context, rect.width(), rect.height());
- SkCanvas* canvas = arp.getRecordingCanvas();
+ if (!layer)
+ return false;
- if (!canvas)
+ SkPicture* picture = new SkPicture();
+ SkCanvas* canvas = picture->beginRecording(rect.width(), rect.height(), 0);
+ if (!canvas) {
+ picture->endRecording();
+ SkSafeUnref(picture);
return false;
+ }
PlatformGraphicsContext platformContext(canvas);
GraphicsContext graphicsContext(&platformContext);
paintGraphicsLayerContents(graphicsContext, rect);
+
+ picture->endRecording();
+
+ PictureLayerContent* layerContent = new PictureLayerContent(picture);
+ layerContent->checkForOptimisations();
+ layer->setContent(layerContent);
+ SkSafeUnref(layerContent);
+ SkSafeUnref(picture);
return true;
}
@@ -683,8 +734,8 @@ void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
// rect is in the render object coordinates
if (!m_image && !drawsContent()) {
- LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
- this, rect.x(), rect.y(), rect.width(), rect.height());
+ ALOGV("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
+ this, rect.x(), rect.y(), rect.width(), rect.height());
return;
}
@@ -736,20 +787,20 @@ bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList&
const Animation* animation, const String& keyframesName, double beginTime)
{
bool isKeyframe = valueList.size() > 2;
- TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
- isKeyframe, keyframesName.latin1().data(), beginTime);
+ ALOGV("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
+ isKeyframe, keyframesName.latin1().data(), beginTime);
switch (valueList.property()) {
case AnimatedPropertyInvalid: break;
case AnimatedPropertyWebkitTransform: break;
case AnimatedPropertyBackgroundColor: break;
case AnimatedPropertyOpacity: {
- MLOG("ANIMATEDPROPERTYOPACITY");
+ ALOGV("ANIMATEDPROPERTYOPACITY");
KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity);
for (unsigned int i = 0; i < valueList.size(); i++) {
FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i);
- PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
+ RefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(),
originalValue->value(),
timingFunction);
@@ -785,13 +836,13 @@ bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const Keyframe
const IntSize& boxSize)
{
ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
- TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
- keyframesName.latin1().data(), beginTime);
+ ALOGV("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
+ keyframesName.latin1().data(), beginTime);
KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform);
for (unsigned int i = 0; i < valueList.size(); i++) {
TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i);
- PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
+ RefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(),
originalValue->value(),
timingFunction);
@@ -816,36 +867,36 @@ bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const Keyframe
void GraphicsLayerAndroid::removeAnimationsForProperty(AnimatedPropertyID anID)
{
- TLOG("NRO removeAnimationsForProperty(%d)", anID);
+ ALOGV("NRO removeAnimationsForProperty(%d)", anID);
m_contentLayer->removeAnimationsForProperty(anID);
askForSync();
}
void GraphicsLayerAndroid::removeAnimationsForKeyframes(const String& keyframesName)
{
- TLOG("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
+ ALOGV("NRO removeAnimationsForKeyframes(%s)", keyframesName.latin1().data());
m_contentLayer->removeAnimationsForKeyframes(keyframesName);
askForSync();
}
void GraphicsLayerAndroid::pauseAnimation(const String& keyframesName)
{
- TLOG("NRO pauseAnimation(%s)", keyframesName.latin1().data());
+ ALOGV("NRO pauseAnimation(%s)", keyframesName.latin1().data());
}
void GraphicsLayerAndroid::suspendAnimations(double time)
{
- TLOG("NRO suspendAnimations(%.2f)", time);
+ ALOGV("NRO suspendAnimations(%.2f)", time);
}
void GraphicsLayerAndroid::resumeAnimations()
{
- TLOG("NRO resumeAnimations()");
+ ALOGV("NRO resumeAnimations()");
}
void GraphicsLayerAndroid::setContentsToImage(Image* image)
{
- TLOG("(%x) setContentsToImage", this, image);
+ ALOGV("(%x) setContentsToImage", this, image);
if (image && image != m_image) {
image->ref();
if (m_image)
@@ -899,7 +950,7 @@ void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
PlatformLayer* GraphicsLayerAndroid::platformLayer() const
{
- LOG("platformLayer");
+ ALOGV("platformLayer");
return m_contentLayer;
}
@@ -917,7 +968,7 @@ void GraphicsLayerAndroid::setZPosition(float position)
{
if (position == m_zPosition)
return;
- LOG("(%x) setZPosition: %.2f", this, position);
+ ALOGV("(%x) setZPosition: %.2f", this, position);
GraphicsLayer::setZPosition(position);
askForSync();
}
@@ -988,8 +1039,14 @@ void GraphicsLayerAndroid::gatherRootLayers(Vector<const RenderLayer*>& list)
void GraphicsLayerAndroid::syncCompositingStateForThisLayerOnly()
{
+ if (m_contentLayer) {
+ RenderLayer* renderLayer = renderLayerFromClient(m_client);
+ int intrinsicallyComposited = renderLayer ? renderLayer->intrinsicallyComposited() : true;
+ m_contentLayer->setIntrinsicallyComposited(intrinsicallyComposited);
+ }
+
updateScrollingLayers();
- updateFixedPosition();
+ updatePositionedLayers();
syncChildren();
syncMask();
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index e6d75b0..27dfde2 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -24,7 +24,9 @@
#include "GraphicsLayer.h"
#include "GraphicsLayerClient.h"
#include "LayerAndroid.h"
+#include "LayerContent.h"
#include "RefPtr.h"
+#include "ScrollableLayerAndroid.h"
#include "SkBitmapRef.h"
#include "Vector.h"
@@ -122,9 +124,12 @@ public:
void notifyClientAnimationStarted();
LayerAndroid* contentLayer() { return m_contentLayer; }
+ ScrollableLayerAndroid* foregroundLayer() { return m_foregroundLayer; }
static int instancesCount();
+ virtual void updateScrollOffset();
+
private:
void askForSync();
@@ -132,14 +137,14 @@ private:
void syncChildren();
void syncMask();
- void updateFixedPosition();
+ void updatePositionedLayers();
void updateScrollingLayers();
// with SkPicture, we always repaint the entire layer's content.
bool repaint();
void needsNotifyClient();
- bool paintContext(SkPicture* context, const IntRect& rect);
+ bool paintContext(LayerAndroid* layer, const IntRect& rect);
bool m_needsSyncChildren;
bool m_needsSyncMask;
diff --git a/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp
new file mode 100644
index 0000000..dadb13d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.cpp
@@ -0,0 +1,42 @@
+#define LOG_TAG "IFrameContentLayerAndroid"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "IFrameContentLayerAndroid.h"
+
+#include "AndroidLog.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+bool IFrameContentLayerAndroid::scrollTo(int x, int y)
+{
+ IntRect scrollBounds;
+ getScrollBounds(&scrollBounds);
+ if (!scrollBounds.width() && !scrollBounds.height())
+ return false;
+ SkScalar newX = SkScalarPin(x, scrollBounds.x(), scrollBounds.width());
+ SkScalar newY = SkScalarPin(y, scrollBounds.y(), scrollBounds.height());
+ // Check for no change.
+ if (newX == m_iframeScrollOffset.x() && newY == m_iframeScrollOffset.y())
+ return false;
+ newX = newX - m_iframeScrollOffset.x();
+ newY = newY - m_iframeScrollOffset.y();
+ setScrollOffset(IntPoint(newX, newY));
+ return true;
+}
+
+void IFrameContentLayerAndroid::getScrollRect(SkIRect* out) const
+{
+ const SkPoint& pos = getPosition();
+ out->fLeft = m_scrollLimits.fLeft - pos.fX + m_iframeScrollOffset.x();
+ out->fTop = m_scrollLimits.fTop - pos.fY + m_iframeScrollOffset.y();
+
+ out->fRight = getSize().width() - m_scrollLimits.width();
+ out->fBottom = getSize().height() - m_scrollLimits.height();
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h b/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h
new file mode 100644
index 0000000..64b2d06
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/IFrameContentLayerAndroid.h
@@ -0,0 +1,78 @@
+/*
+ * 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 IFrameContentLayerAndroid_h
+#define IFrameContentLayerAndroid_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "ScrollableLayerAndroid.h"
+
+namespace WebCore {
+
+class IFrameContentLayerAndroid : public ScrollableLayerAndroid {
+
+public:
+ IFrameContentLayerAndroid(RenderLayer* owner)
+ : ScrollableLayerAndroid(owner) {}
+ IFrameContentLayerAndroid(const ScrollableLayerAndroid& layer)
+ : ScrollableLayerAndroid(layer) {}
+ IFrameContentLayerAndroid(const LayerAndroid& layer)
+ : ScrollableLayerAndroid(layer) {}
+ IFrameContentLayerAndroid(const IFrameContentLayerAndroid& layer)
+ : ScrollableLayerAndroid(layer)
+ , m_iframeScrollOffset(layer.m_iframeScrollOffset) {}
+
+ virtual ~IFrameContentLayerAndroid() {};
+
+ // isIFrame() return true for compatibility reason (see ViewStateSerializer)
+ virtual bool isIFrame() const { return true; }
+ virtual bool isIFrameContent() const { return true; }
+
+ virtual LayerAndroid* copy() const { return new IFrameContentLayerAndroid(*this); }
+ virtual SubclassType subclassType() { return LayerAndroid::IFrameContentLayer; }
+
+ // Scrolls to the given position in the layer.
+ // Returns whether or not any scrolling was required.
+ virtual bool scrollTo(int x, int y);
+
+ // Fills the rect with the current scroll offset and the maximum scroll offset.
+ // fLeft = scrollX
+ // fTop = scrollY
+ // fRight = maxScrollX
+ // fBottom = maxScrollY
+ virtual void getScrollRect(SkIRect*) const;
+
+ void setIFrameScrollOffset(IntPoint offset) { m_iframeScrollOffset = offset; }
+
+private:
+ IntPoint m_iframeScrollOffset;
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // IFrameContentLayerAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp
new file mode 100644
index 0000000..3532542
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.cpp
@@ -0,0 +1,40 @@
+#define LOG_TAG "IFrameLayerAndroid"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "IFrameLayerAndroid.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "AndroidLog.h"
+#include "DumpLayer.h"
+
+namespace WebCore {
+
+IFrameLayerAndroid* IFrameLayerAndroid::updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer)
+{
+ // As we are an iframe, accumulate the offset from the parent with
+ // the current position, and change the parent pointer.
+
+ // If this is the top level, take the current position
+ SkPoint parentOffset;
+ parentOffset.set(0,0);
+ if (parentIframeLayer)
+ parentOffset = parentIframeLayer->getPosition();
+
+ SkPoint offset = parentOffset + getPosition();
+ m_iframeOffset = IntPoint(offset.fX, offset.fY);
+
+ return this;
+}
+
+void IFrameLayerAndroid::dumpLayer(FILE* file, int indentLevel) const
+{
+ writeIntVal(file, indentLevel + 1, "m_isIframe", true);
+ writeIntPoint(file, indentLevel + 1, "m_iframeOffset", m_iframeOffset);
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/DoubleBufferedTexture.h b/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.h
index 821b79b..e12188a 100644
--- a/Source/WebCore/platform/graphics/android/DoubleBufferedTexture.h
+++ b/Source/WebCore/platform/graphics/android/IFrameLayerAndroid.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010, 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,52 +23,46 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DoubleBufferedTexture_h
-#define DoubleBufferedTexture_h
+#ifndef IFrameLayerAndroid_h
+#define IFrameLayerAndroid_h
-#include "SharedTexture.h"
-#include <EGL/egl.h>
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerAndroid.h"
namespace WebCore {
-class DoubleBufferedTexture {
+class IFrameLayerAndroid : public LayerAndroid {
+
public:
- // consumer thread functions
- DoubleBufferedTexture(EGLContext sharedContext, SharedTextureMode mode);
- virtual ~DoubleBufferedTexture();
-
- // provider thread functions
- virtual TextureInfo* producerLock();
- virtual void producerRelease();
- virtual void producerReleaseAndSwap();
- EGLContext producerAcquireContext();
- void producerDeleteTextures();
-
- // consumer thread functions
- TextureInfo* consumerLock();
- void consumerRelease();
- void consumerDeleteTextures();
-
-protected:
- SharedTexture* getReadableTexture();
- SharedTexture* getWriteableTexture();
-
- SharedTexture* m_textureA;
- SharedTexture* m_textureB;
-
- SharedTextureMode m_sharedTextureMode;
-private:
+ IFrameLayerAndroid(RenderLayer* owner)
+ : LayerAndroid(owner) {}
+ IFrameLayerAndroid(const LayerAndroid& layer)
+ : LayerAndroid(layer) {}
+ IFrameLayerAndroid(const IFrameLayerAndroid& layer)
+ : LayerAndroid(layer)
+ , m_iframeOffset(layer.m_iframeOffset) {}
+
+ virtual ~IFrameLayerAndroid() {};
+
+ virtual bool isIFrame() const { return true; }
- SharedTexture* m_writeableTexture;
- SharedTexture* m_lockedConsumerTexture; // only used by the consumer
+ virtual LayerAndroid* copy() const { return new IFrameLayerAndroid(*this); }
+ virtual SubclassType subclassType() { return LayerAndroid::IFrameLayer; }
- EGLDisplay m_display;
- EGLContext m_pContext;
- EGLContext m_cContext;
+ virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer);
- bool m_supportsEGLImage;
+ virtual void dumpLayer(FILE*, int indentLevel) const;
+
+ const IntPoint& iframeOffset() const { return m_iframeOffset; }
+
+private:
+ IntPoint m_iframeOffset;
};
-} // namespace WebCore
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
-#endif // DoubleBufferedTexture_h
+#endif // IFrameLayerAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/ImageAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
index 01fe272..08f72e0 100644
--- a/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
@@ -44,7 +44,7 @@
#include "SkTemplates.h"
#include "SkiaUtils.h"
-#include <utils/AssetManager.h>
+#include <androidfw/AssetManager.h>
//#define TRACE_SUBSAMPLED_BITMAPS
//#define TRACE_SKIPPED_BITMAPS
@@ -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 691fbca..f148881 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -36,6 +36,7 @@
#include "SkBitmapRef.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
+#include "SkData.h"
#include "SkDevice.h"
#include "SkImageEncoder.h"
#include "SkStream.h"
@@ -195,7 +196,7 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
ASSERT(destx >= 0);
ASSERT(destx < m_size.width());
ASSERT(originx >= 0);
- ASSERT(originx <= sourceRect.right());
+ ASSERT(originx <= sourceRect.maxX());
int endx = destPoint.x() + sourceRect.maxX();
ASSERT(endx <= m_size.width());
@@ -207,7 +208,7 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
ASSERT(desty >= 0);
ASSERT(desty < m_size.height());
ASSERT(originy >= 0);
- ASSERT(originy <= sourceRect.bottom());
+ ASSERT(originy <= sourceRect.maxY());
int endy = destPoint.y() + sourceRect.maxY();
ASSERT(endy <= m_size.height());
@@ -241,7 +242,9 @@ String ImageBuffer::toDataURL(const String&, const double*) const
// Convert it into base64.
Vector<char> pngEncodedData;
- pngEncodedData.append(pngStream.getStream(), pngStream.getOffset());
+ SkData* streamData = pngStream.copyToData();
+ pngEncodedData.append((char*)streamData->data(), streamData->size());
+ streamData->unref();
Vector<char> base64EncodedData;
base64Encode(pngEncodedData, base64EncodedData);
// Append with a \0 so that it's a valid string.
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp
index 23e3899..7d3f2b8 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp
@@ -23,9 +23,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "ImageTexture"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "ImageTexture.h"
+#include "AndroidLog.h"
#include "ImagesManager.h"
#include "LayerAndroid.h"
#include "SkDevice.h"
@@ -33,25 +37,6 @@
#include "TilesManager.h"
#include "TiledTexture.h"
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "ImageTexture", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ImageTexture", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
// CRC computation adapted from Tools/DumpRenderTree/CyclicRedundancyCheck.cpp
@@ -126,7 +111,7 @@ SkBitmap* ImageTexture::convertBitmap(SkBitmap* bitmap)
// Create a copy of the image
img->setConfig(SkBitmap::kARGB_8888_Config, w, h);
img->allocPixels();
- SkDevice* device = new SkDevice(NULL, *img, false);
+ SkDevice* device = new SkDevice(*img);
SkCanvas canvas;
canvas.setDevice(device);
device->unref();
@@ -166,7 +151,7 @@ int ImageTexture::nbTextures()
// a list of the clients layer, etc.)
IntRect visibleArea(0, 0, m_image->width(), m_image->height());
int nbTextures = m_texture->nbTextures(visibleArea, 1.0);
- XLOG("ImageTexture %p, %d x %d needs %d textures",
+ ALOGV("ImageTexture %p, %d x %d needs %d textures",
this, m_image->width(), m_image->height(),
nbTextures);
return nbTextures;
@@ -188,18 +173,19 @@ bool ImageTexture::prepareGL(GLWebViewState* state)
return false;
if (!m_texture && m_picture) {
- m_texture = new TiledTexture(this);
+ bool isLayerTile = true;
+ m_texture = new TiledTexture(isLayerTile);
SkRegion region;
region.setRect(0, 0, m_image->width(), m_image->height());
- m_texture->update(region, m_picture);
+ m_texture->markAsDirty(region);
}
if (!m_texture)
return false;
- IntRect visibleArea(0, 0, m_image->width(), m_image->height());
- m_texture->prepare(state, 1.0, true, true, visibleArea);
- if (m_texture->ready()) {
+ 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;
}
@@ -230,7 +216,20 @@ float ImageTexture::opacity()
return m_layer->drawOpacity();
}
-void ImageTexture::drawGL(LayerAndroid* layer)
+bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas)
+{
+ if (!m_picture) {
+ ALOGV("IT %p COULDNT PAINT, NO PICTURE", this);
+ return false;
+ }
+
+ ALOGV("IT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), m_picture);
+ canvas->drawPicture(*m_picture);
+
+ return true;
+}
+
+void ImageTexture::drawGL(LayerAndroid* layer, float opacity)
{
if (!layer)
return;
@@ -240,8 +239,10 @@ void ImageTexture::drawGL(LayerAndroid* layer)
// TiledTexture::draw() will call us back to know the
// transform and opacity, so we need to set m_layer
m_layer = layer;
- if (m_texture)
- m_texture->draw();
+ if (m_texture) {
+ IntRect visibleArea = m_layer->visibleArea();
+ m_texture->drawGL(visibleArea, opacity, transform());
+ }
m_layer = 0;
}
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h
index 6c6a075..91c8a29 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.h
@@ -67,13 +67,13 @@ class TiledTexture;
// so that we can share the same textures and limits as the rest of the layers.
//
/////////////////////////////////////////////////////////////////////////////////
-class ImageTexture : public SurfacePainter {
+class ImageTexture : public TilePainter {
public:
ImageTexture(SkBitmap* bmp, unsigned crc);
virtual ~ImageTexture();
bool prepareGL(GLWebViewState*);
- void drawGL(LayerAndroid* painter);
+ void drawGL(LayerAndroid* layer, float opacity);
void drawCanvas(SkCanvas*, SkRect&);
bool hasContentToShow();
SkBitmap* bitmap() { return m_image; }
@@ -85,14 +85,15 @@ public:
bool equalsCRC(unsigned crc);
// methods used by TiledTexture
- virtual const TransformationMatrix* transform();
+ virtual bool paint(BaseTile* tile, SkCanvas* canvas);
virtual float opacity();
int nbTextures();
- virtual SurfaceType type() { return SurfacePainter::ImageSurface; }
+ virtual SurfaceType type() { return TilePainter::Image; }
private:
+ const TransformationMatrix* transform();
SkBitmapRef* m_imageRef;
SkBitmap* m_image;
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.cpp b/Source/WebCore/platform/graphics/android/ImagesManager.cpp
index 65c41d1..8452503 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/ImagesManager.cpp
@@ -23,33 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "ImagesManager"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "ImagesManager.h"
+#include "AndroidLog.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkRefCnt.h"
#include "ImageTexture.h"
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "ImagesManager", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ImagesManager", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
ImagesManager* ImagesManager::instance()
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.h b/Source/WebCore/platform/graphics/android/ImagesManager.h
index a3ea859..b915a46 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.h
+++ b/Source/WebCore/platform/graphics/android/ImagesManager.h
@@ -32,6 +32,8 @@
#include "SkRefCnt.h"
#include "Vector.h"
+#include <utils/threads.h>
+
namespace WebCore {
class ImageTexture;
diff --git a/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp b/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp
new file mode 100644
index 0000000..f9edb74
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp
@@ -0,0 +1,133 @@
+/*
+ * 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 "InspectorCanvas"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "InspectorCanvas.h"
+
+#include "AndroidLog.h"
+#include "SkPicture.h"
+
+namespace WebCore {
+
+
+void InspectorCanvas::setHasText()
+{
+ m_hasText = true;
+ setHasContent();
+}
+
+void InspectorCanvas::setHasContent()
+{
+ m_hasContent = true;
+ if (m_hasText) {
+ // has text. Have to paint properly, so no further
+ // information is useful
+ m_picture->abortPlayback();
+ }
+}
+
+void InspectorCanvas::setIsBackground(const SkPaint& paint)
+{
+ // TODO: if the paint is a solid color, opaque, and the last instruction in
+ // the picture, replace the picture with simple draw rect info
+ setHasContent();
+}
+
+void InspectorCanvas::commonDrawBitmap(const SkBitmap& bitmap,
+ const SkIRect* rect,
+ const SkMatrix&,
+ const SkPaint&)
+{
+ setHasContent();
+}
+
+void InspectorCanvas::drawPaint(const SkPaint& paint)
+{
+ setHasContent();
+}
+
+void InspectorCanvas::drawPath(const SkPath&, const SkPaint& paint)
+{
+ setHasContent();
+}
+void InspectorCanvas::drawPoints(PointMode, size_t,
+ const SkPoint [], const SkPaint& paint)
+{
+ setHasContent();
+}
+
+void InspectorCanvas::drawRect(const SkRect& rect, const SkPaint& paint)
+{
+ if (rect.fLeft == 0
+ && rect.fTop == 0
+ && rect.width() >= m_picture->width()
+ && rect.height() >= m_picture->height()) {
+ // rect same size as canvas, treat layer as a single color rect until
+ // more content is drawn
+ setIsBackground(paint);
+ } else {
+ // regular rect drawing path
+ setHasContent();
+ }
+ ALOGV("draw rect at %f %f, size %f %f, picture size %d %d",
+ rect.fLeft, rect.fTop, rect.width(), rect.height(),
+ m_picture->width(), m_picture->height());
+}
+void InspectorCanvas::drawSprite(const SkBitmap& , int , int ,
+ const SkPaint* paint)
+{
+ setHasContent();
+}
+
+void InspectorCanvas::drawText(const void*, size_t byteLength, SkScalar,
+ SkScalar, const SkPaint& paint)
+{
+ setHasText();
+}
+
+void InspectorCanvas::drawPosText(const void* , size_t byteLength,
+ const SkPoint [], const SkPaint& paint)
+{
+ setHasText();
+}
+
+void InspectorCanvas::drawPosTextH(const void*, size_t byteLength,
+ const SkScalar [], SkScalar,
+ const SkPaint& paint)
+{
+ setHasText();
+}
+
+void InspectorCanvas::drawTextOnPath(const void*, size_t byteLength,
+ const SkPath&, const SkMatrix*,
+ const SkPaint& paint)
+{
+ setHasText();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/InspectorCanvas.h b/Source/WebCore/platform/graphics/android/InspectorCanvas.h
new file mode 100644
index 0000000..415a579
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/InspectorCanvas.h
@@ -0,0 +1,102 @@
+/*
+ * 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 InspectorCanvas_h
+#define InspectorCanvas_h
+
+#include "SkBounder.h"
+#include "SkCanvas.h"
+
+namespace WebCore {
+
+class InspectorBounder : public SkBounder {
+ virtual bool onIRect(const SkIRect& rect)
+ {
+ return false;
+ }
+};
+
+class InspectorCanvas : public SkCanvas {
+public:
+ InspectorCanvas(SkBounder* bounder, SkPicture* picture)
+ : m_picture(picture)
+ , m_hasText(false)
+ , m_hasContent(false)
+ {
+ setBounder(bounder);
+ }
+
+ bool hasText() {return m_hasText;}
+ bool hasContent() {return m_hasContent;}
+
+ virtual bool clipPath(const SkPath&, SkRegion::Op) {
+ return true;
+ }
+
+ virtual void commonDrawBitmap(const SkBitmap& bitmap,
+ const SkIRect* rect,
+ const SkMatrix&,
+ const SkPaint&);
+
+ virtual void drawPaint(const SkPaint& paint);
+ virtual void drawPath(const SkPath&, const SkPaint& paint);
+ virtual void drawPoints(PointMode, size_t,
+ const SkPoint [], const SkPaint& paint);
+
+ virtual void drawRect(const SkRect& , const SkPaint& paint);
+ virtual void drawSprite(const SkBitmap& , int , int ,
+ const SkPaint* paint = NULL);
+
+ virtual void drawText(const void*, size_t byteLength, SkScalar,
+ SkScalar, const SkPaint& paint);
+ virtual void drawPosText(const void* , size_t byteLength,
+ const SkPoint [], const SkPaint& paint);
+ virtual void drawPosTextH(const void*, size_t byteLength,
+ const SkScalar [], SkScalar,
+ const SkPaint& paint);
+ virtual void drawTextOnPath(const void*, size_t byteLength,
+ const SkPath&, const SkMatrix*,
+ const SkPaint& paint);
+
+private:
+
+ // vector instructions exist, must repaint at any scale
+ void setHasText();
+
+ // painting is required
+ void setHasContent();
+
+ // rect covering entire content, don't need to use a texture if nothing else
+ // is painted
+ void setIsBackground(const SkPaint& paint);
+
+ SkPicture* m_picture;
+ bool m_hasText;
+ bool m_hasContent;
+};
+
+} // namespace WebCore
+
+#endif // InspectorCanvas_h
diff --git a/Source/WebCore/platform/graphics/android/Layer.cpp b/Source/WebCore/platform/graphics/android/Layer.cpp
index 9280461..48e36fc 100644
--- a/Source/WebCore/platform/graphics/android/Layer.cpp
+++ b/Source/WebCore/platform/graphics/android/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
@@ -158,13 +163,9 @@ void Layer::localToAncestor(const Layer* ancestor, SkMatrix* matrix) const {
///////////////////////////////////////////////////////////////////////////////
-void Layer::onDraw(SkCanvas*, SkScalar opacity) {
-// SkDebugf("----- no onDraw for %p\n", this);
-}
-
#include "SkString.h"
-void Layer::draw(SkCanvas* canvas, SkScalar opacity) {
+void Layer::draw(SkCanvas* canvas, android::DrawExtra* extra, SkScalar opacity) {
#if 0
SkString str1, str2;
// getMatrix().toDumpString(&str1);
@@ -193,7 +194,7 @@ void Layer::draw(SkCanvas* canvas, SkScalar opacity) {
canvas->concat(tmp);
}
- onDraw(canvas, opacity);
+ onDraw(canvas, opacity, extra, FlattenedLayers);
#ifdef DEBUG_DRAW_LAYER_BOUNDS
{
@@ -213,7 +214,7 @@ void Layer::draw(SkCanvas* canvas, SkScalar opacity) {
if (count > 0) {
canvas->concat(getChildrenMatrix());
for (int i = 0; i < count; i++) {
- getChild(i)->draw(canvas, opacity);
+ getChild(i)->draw(canvas, extra, opacity);
}
}
}
diff --git a/Source/WebCore/platform/graphics/android/Layer.h b/Source/WebCore/platform/graphics/android/Layer.h
index 5200a3d..996547b 100644
--- a/Source/WebCore/platform/graphics/android/Layer.h
+++ b/Source/WebCore/platform/graphics/android/Layer.h
@@ -17,6 +17,7 @@
#ifndef Layer_DEFINED
#define Layer_DEFINED
+#include "DrawExtra.h"
#include "TestExport.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"
@@ -64,19 +65,6 @@ public:
void setChildrenMatrix(const SkMatrix& matrix) { m_childrenMatrix = matrix; }
// rendering asset management
-
- // tell rendering assets to update their tile content with most recent painted data
- virtual void swapTiles() {}
-
- // tell rendering assets to use this layer tree for drawing
- virtual void setIsDrawing(bool isDrawing) {}
-
- // take rendering assets from drawing tree, or create if they don't exist
- virtual void setIsPainting(Layer* drawingTree) {}
-
- // if a similar layer exists in the replacement tree, add invals to it
- virtual void mergeInvalsInto(Layer* replacementTree) {}
-
void markAsDirty(const SkRegion& invalRegion) {
m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
}
@@ -87,14 +75,6 @@ public:
// drawing
- virtual bool isReady() { return false; }
-
- // TODO: clean out several of these, leave them in GLWebViewState
-
- virtual bool prepare(double currentTime, WebCore::IntRect& viewRect,
- SkRect& visibleRect, float scale) { return 0; }
- virtual bool drawGL(WebCore::IntRect& viewRect,
- SkRect& visibleRect, float scale) { return 0; }
WebCore::GLWebViewState* state() { return m_state; }
void setState(WebCore::GLWebViewState* state);
@@ -140,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.
@@ -165,17 +145,15 @@ public:
// paint method
virtual bool drawCanvas(SkCanvas*) { return false; }
- void draw(SkCanvas*, SkScalar opacity);
- void draw(SkCanvas* canvas) {
- this->draw(canvas, SK_Scalar1);
- }
+ void draw(SkCanvas*, android::DrawExtra* extra, SkScalar opacity = SK_Scalar1);
void setHasOverflowChildren(bool value) { m_hasOverflowChildren = value; }
virtual bool contentIsScrollable() const { return false; }
+ typedef enum { MergedLayers, UnmergedLayers, FlattenedLayers } PaintStyle;
protected:
- virtual void onDraw(SkCanvas*, SkScalar opacity);
+ virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style) {}
bool m_hasOverflowChildren;
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 962bcdf..b40e00a 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -1,44 +1,40 @@
+#define LOG_TAG "LayerAndroid"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "LayerAndroid.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "AndroidAnimation.h"
#include "ClassTracker.h"
#include "DrawExtra.h"
+#include "DumpLayer.h"
+#include "FixedPositioning.h"
#include "GLUtils.h"
#include "ImagesManager.h"
+#include "InspectorCanvas.h"
+#include "LayerContent.h"
+#include "LayerGroup.h"
#include "MediaLayer.h"
-#include "PaintedSurface.h"
#include "ParseCanvas.h"
+#include "PictureLayerContent.h"
#include "SkBitmapRef.h"
-#include "SkBounder.h"
#include "SkDrawFilter.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
-#include <math.h>
-
-#define LAYER_DEBUG // Add diagonals for debugging
-#undef LAYER_DEBUG
-
-#include <cutils/log.h>
#include <wtf/text/CString.h>
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "LayerAndroid", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "LayerAndroid", __VA_ARGS__)
-
-#else
+#include <math.h>
-#undef XLOG
-#define XLOG(...)
+#define DISABLE_LAYER_MERGE
+#undef DISABLE_LAYER_MERGE
-#endif // DEBUG
+#define LAYER_GROUPING_DEBUG
+#undef LAYER_GROUPING_DEBUG
namespace WebCore {
@@ -55,112 +51,30 @@ private:
int m_opacity;
};
-class HasTextBounder : public SkBounder {
- virtual bool onIRect(const SkIRect& rect)
- {
- return false;
- }
-};
-
-class HasTextCanvas : public SkCanvas {
-public:
- HasTextCanvas(SkBounder* bounder, SkPicture* picture)
- : m_picture(picture)
- , m_hasText(false)
- {
- setBounder(bounder);
- }
-
- void setHasText()
- {
- m_hasText = true;
- m_picture->abortPlayback();
- }
-
- bool hasText()
- {
- return m_hasText;
- }
-
- virtual bool clipPath(const SkPath&, SkRegion::Op) {
- return true;
- }
-
- virtual void commonDrawBitmap(const SkBitmap& bitmap,
- const SkIRect* rect,
- const SkMatrix&,
- const SkPaint&) {}
-
- virtual void drawPaint(const SkPaint& paint) {}
- virtual void drawPath(const SkPath&, const SkPaint& paint) {}
- virtual void drawPoints(PointMode, size_t,
- const SkPoint [], const SkPaint& paint) {}
-
- virtual void drawRect(const SkRect& , const SkPaint& paint) {}
- virtual void drawSprite(const SkBitmap& , int , int ,
- const SkPaint* paint = NULL) {}
-
- virtual void drawText(const void*, size_t byteLength, SkScalar,
- SkScalar, const SkPaint& paint)
- {
- setHasText();
- }
-
- virtual void drawPosText(const void* , size_t byteLength,
- const SkPoint [], const SkPaint& paint)
- {
- setHasText();
- }
-
- virtual void drawPosTextH(const void*, size_t byteLength,
- const SkScalar [], SkScalar,
- const SkPaint& paint)
- {
- setHasText();
- }
-
- virtual void drawTextOnPath(const void*, size_t byteLength,
- const SkPath&, const SkMatrix*,
- const SkPaint& paint)
- {
- setHasText();
- }
-
- virtual void drawPicture(SkPicture& picture) {
- SkCanvas::drawPicture(picture);
- }
-
-private:
-
- SkPicture* m_picture;
- bool m_hasText;
-};
-
///////////////////////////////////////////////////////////////////////////////
LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
+ m_uniqueId(++gUniqueId),
m_haveClip(false),
- m_isFixed(false),
- m_isIframe(false),
m_backfaceVisibility(true),
m_visible(true),
m_preserves3D(false),
m_anchorPointZ(0),
- m_recordingPicture(0),
- m_uniqueId(++gUniqueId),
- m_texture(0),
+ m_isPositionAbsolute(false),
+ m_fixedPosition(0),
+ m_zValue(0),
+ m_content(0),
m_imageCRC(0),
- m_pictureUsed(0),
m_scale(1),
m_lastComputeTextureSize(0),
m_owningLayer(owner),
m_type(LayerAndroid::WebCoreLayer),
- m_hasText(true)
+ m_intrinsicallyComposited(true),
+ m_layerGroup(0)
{
m_backgroundColor = 0;
m_preserves3D = false;
- m_iframeOffset.set(0,0);
m_dirtyRegion.setEmpty();
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("LayerAndroid");
@@ -169,110 +83,101 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
}
LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
- m_haveClip(layer.m_haveClip),
- m_isIframe(layer.m_isIframe),
m_uniqueId(layer.m_uniqueId),
- m_texture(0),
+ m_haveClip(layer.m_haveClip),
+ m_isPositionAbsolute(layer.m_isPositionAbsolute),
+ m_fixedPosition(0),
+ m_zValue(layer.m_zValue),
m_owningLayer(layer.m_owningLayer),
m_type(LayerAndroid::UILayer),
- m_hasText(true)
+ m_intrinsicallyComposited(layer.m_intrinsicallyComposited),
+ m_layerGroup(0)
{
- m_isFixed = layer.m_isFixed;
m_imageCRC = layer.m_imageCRC;
if (m_imageCRC)
ImagesManager::instance()->retainImage(m_imageCRC);
- m_renderLayerPos = layer.m_renderLayerPos;
m_transform = layer.m_transform;
m_backfaceVisibility = layer.m_backfaceVisibility;
m_visible = layer.m_visible;
m_backgroundColor = layer.m_backgroundColor;
- m_fixedLeft = layer.m_fixedLeft;
- m_fixedTop = layer.m_fixedTop;
- m_fixedRight = layer.m_fixedRight;
- m_fixedBottom = layer.m_fixedBottom;
- m_fixedMarginLeft = layer.m_fixedMarginLeft;
- m_fixedMarginTop = layer.m_fixedMarginTop;
- m_fixedMarginRight = layer.m_fixedMarginRight;
- m_fixedMarginBottom = layer.m_fixedMarginBottom;
- m_fixedRect = layer.m_fixedRect;
- m_iframeOffset = layer.m_iframeOffset;
- m_recordingPicture = layer.m_recordingPicture;
- SkSafeRef(m_recordingPicture);
+ m_offset = layer.m_offset;
+
+ m_content = layer.m_content;
+ SkSafeRef(m_content);
m_preserves3D = layer.m_preserves3D;
m_anchorPointZ = layer.m_anchorPointZ;
+
+ if (layer.m_fixedPosition) {
+ m_fixedPosition = new FixedPositioning(this, *layer.m_fixedPosition);
+ Layer::setShouldInheritFromRootTransform(true);
+ }
+
m_drawTransform = layer.m_drawTransform;
m_childrenTransform = layer.m_childrenTransform;
- m_pictureUsed = layer.m_pictureUsed;
m_dirtyRegion = layer.m_dirtyRegion;
m_scale = layer.m_scale;
m_lastComputeTextureSize = 0;
- for (int i = 0; i < layer.countChildren(); i++)
- addChild(layer.getChild(i)->copy())->unref();
+ // If we have absolute elements, we may need to reorder them if they
+ // are followed by another layer that is not also absolutely positioned.
+ // (as absolutely positioned elements are out of the normal flow)
+ bool hasAbsoluteChildren = false;
+ bool hasOnlyAbsoluteFollowers = true;
+ for (int i = 0; i < layer.countChildren(); i++) {
+ if (layer.getChild(i)->isPositionAbsolute()) {
+ hasAbsoluteChildren = true;
+ continue;
+ }
+ if (hasAbsoluteChildren
+ && !layer.getChild(i)->isPositionAbsolute()) {
+ hasOnlyAbsoluteFollowers = false;
+ break;
+ }
+ }
+
+ if (hasAbsoluteChildren && !hasOnlyAbsoluteFollowers) {
+ Vector<LayerAndroid*> normalLayers;
+ Vector<LayerAndroid*> absoluteLayers;
+ for (int i = 0; i < layer.countChildren(); i++) {
+ LayerAndroid* child = layer.getChild(i);
+ if (child->isPositionAbsolute()
+ || child->isPositionFixed())
+ absoluteLayers.append(child);
+ else
+ normalLayers.append(child);
+ }
+ for (unsigned int i = 0; i < normalLayers.size(); i++)
+ addChild(normalLayers[i]->copy())->unref();
+ for (unsigned int i = 0; i < absoluteLayers.size(); i++)
+ addChild(absoluteLayers[i]->copy())->unref();
+ } else {
+ for (int i = 0; i < layer.countChildren(); i++)
+ addChild(layer.getChild(i)->copy())->unref();
+ }
KeyframesMap::const_iterator end = layer.m_animations.end();
for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) {
m_animations.add(it->first, it->second);
}
- m_hasText = layer.m_hasText;
-
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("LayerAndroid - recopy (UI)");
ClassTracker::instance()->add(this);
#endif
}
-void LayerAndroid::checkTextPresence()
-{
- if (m_recordingPicture) {
- // Let's check if we have text or not. If we don't, we can limit
- // ourselves to scale 1!
- HasTextBounder hasTextBounder;
- HasTextCanvas checker(&hasTextBounder, m_recordingPicture);
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- m_recordingPicture->width(),
- m_recordingPicture->height());
- checker.setBitmapDevice(bitmap);
- checker.drawPicture(*m_recordingPicture);
- m_hasText = checker.hasText();
- }
-}
-
-LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
- m_haveClip(false),
- m_isFixed(false),
- m_isIframe(false),
- m_recordingPicture(picture),
- m_uniqueId(++gUniqueId),
- m_texture(0),
- m_imageCRC(0),
- m_scale(1),
- m_lastComputeTextureSize(0),
- m_owningLayer(0),
- m_type(LayerAndroid::NavCacheLayer),
- m_hasText(true)
-{
- m_backgroundColor = 0;
- SkSafeRef(m_recordingPicture);
- m_iframeOffset.set(0,0);
- m_dirtyRegion.setEmpty();
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("LayerAndroid - from picture");
- ClassTracker::instance()->add(this);
-#endif
-}
-
LayerAndroid::~LayerAndroid()
{
if (m_imageCRC)
ImagesManager::instance()->releaseImage(m_imageCRC);
+ if (m_fixedPosition)
+ delete m_fixedPosition;
- SkSafeUnref(m_recordingPicture);
+ SkSafeUnref(m_content);
+ // Don't unref m_layerGroup, owned by BaseLayerAndroid
m_animations.clear();
#ifdef DEBUG_COUNT
ClassTracker::instance()->remove(this);
@@ -280,11 +185,14 @@ 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
}
+bool LayerAndroid::hasText()
+{
+ return m_content && m_content->hasText();
+}
+
static int gDebugNbAnims = 0;
bool LayerAndroid::evaluateAnimations()
@@ -395,8 +303,6 @@ void LayerAndroid::setBackgroundColor(SkColor color)
m_backgroundColor = color;
}
-static int gDebugChildLevel;
-
FloatPoint LayerAndroid::translation() const
{
TransformationMatrix::DecomposedType tDecomp;
@@ -454,216 +360,38 @@ void LayerAndroid::clipInner(SkTDArray<SkRect>* region,
localBounds.intersect(local);
if (localBounds.isEmpty())
return;
- if (m_recordingPicture && boundsIsUnique(*region, localBounds))
+ if (m_content && boundsIsUnique(*region, localBounds))
*region->append() = localBounds;
for (int i = 0; i < countChildren(); i++)
getChild(i)->clipInner(region, m_haveClip ? localBounds : local);
}
-class FindCheck : public SkBounder {
-public:
- FindCheck()
- : m_drew(false)
- , m_drewText(false)
- {
- }
-
- bool drew() const { return m_drew; }
- bool drewText() const { return m_drewText; }
- void reset() { m_drew = m_drewText = false; }
-
-protected:
- virtual bool onIRect(const SkIRect& )
- {
- m_drew = true;
- return false;
- }
-
- virtual bool onIRectGlyph(const SkIRect& , const SkBounder::GlyphRec& )
- {
- m_drew = m_drewText = true;
- return false;
- }
-
- bool m_drew;
- bool m_drewText;
-};
-
-class FindCanvas : public ParseCanvas {
-public:
- void draw(SkPicture* picture, SkScalar offsetX, SkScalar offsetY)
- {
- save();
- translate(-offsetX, -offsetY);
- picture->draw(this);
- restore();
- }
-};
-
-class LayerAndroid::FindState {
-public:
- static const int TOUCH_SLOP = 10;
-
- FindState(int x, int y)
- : m_x(x)
- , m_y(y)
- , m_bestX(x)
- , m_bestY(y)
- , m_best(0)
- {
- m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, TOUCH_SLOP * 2,
- TOUCH_SLOP * 2);
- m_checker.setBounder(&m_findCheck);
- m_checker.setBitmapDevice(m_bitmap);
- }
-
- const LayerAndroid* best() const { return m_best; }
- int bestX() const { return m_bestX; }
- int bestY() const { return m_bestY; }
-
- bool drew(SkPicture* picture, const SkRect& localBounds)
- {
- m_findCheck.reset();
- SkScalar localX = SkIntToScalar(m_x - TOUCH_SLOP) - localBounds.fLeft;
- SkScalar localY = SkIntToScalar(m_y - TOUCH_SLOP) - localBounds.fTop;
- m_checker.draw(picture, localX, localY);
- return m_findCheck.drew();
- }
-
- bool drewText() { return m_findCheck.drewText(); }
-
- void setBest(const LayerAndroid* best, int x, int y)
- {
- m_best = best;
- m_bestX = x;
- m_bestY = y;
- }
- int x() const { return m_x; }
- int y() const { return m_y; }
-
- void setLocation(int x, int y)
- {
- m_x = x;
- m_y = y;
- }
-
-protected:
- int m_x;
- int m_y;
- int m_bestX;
- int m_bestY;
- const LayerAndroid* m_best;
- FindCheck m_findCheck;
- SkBitmap m_bitmap;
- FindCanvas m_checker;
-};
-
-void LayerAndroid::findInner(LayerAndroid::FindState& state) const
-{
- int x = state.x();
- int y = state.y();
- SkRect localBounds;
- bounds(&localBounds);
- if (!localBounds.contains(x, y))
- return;
- // Move into local coordinates.
- state.setLocation(x - localBounds.fLeft, y - localBounds.fTop);
- for (int i = 0; i < countChildren(); i++)
- getChild(i)->findInner(state);
- // Move back into the parent coordinates.
- int testX = state.x();
- int testY = state.y();
- state.setLocation(x + localBounds.fLeft, y + localBounds.fTop);
- if (!m_recordingPicture)
- return;
- if (!contentIsScrollable() && !state.drew(m_recordingPicture, localBounds))
- return;
- state.setBest(this, testX, testY); // set last match (presumably on top)
-}
-
-const LayerAndroid* LayerAndroid::find(int* xPtr, int* yPtr, SkPicture* root) const
+IFrameLayerAndroid* LayerAndroid::updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer)
{
- FindState state(*xPtr, *yPtr);
- SkRect rootBounds;
- rootBounds.setEmpty();
- if (root && state.drew(root, rootBounds) && state.drewText())
- return 0; // use the root picture only if it contains the text
- findInner(state);
- *xPtr = state.bestX();
- *yPtr = state.bestY();
- return state.best();
+ // subclasses can implement this virtual function to modify their position
+ if (m_fixedPosition)
+ return m_fixedPosition->updatePosition(viewport, parentIframeLayer);
+ return parentIframeLayer;
}
-///////////////////////////////////////////////////////////////////////////////
-
-bool LayerAndroid::updateFixedLayersPositions(SkRect viewport, LayerAndroid* parentIframeLayer)
+void LayerAndroid::updateLayerPositions(SkRect viewport, IFrameLayerAndroid* parentIframeLayer)
{
- bool hasFixedElements = false;
- XLOG("updating fixed positions, using viewport %fx%f - %fx%f",
- viewport.fLeft, viewport.fTop,
- viewport.width(), viewport.height());
- // If this is an iframe, accumulate the offset from the parent with
- // current position, and change the parent pointer.
- if (m_isIframe) {
- // If this is the top level, take the current position
- SkPoint parentOffset;
- parentOffset.set(0,0);
- if (parentIframeLayer)
- parentOffset = parentIframeLayer->getPosition();
-
- m_iframeOffset = parentOffset + getPosition();
-
- parentIframeLayer = this;
- }
+ ALOGV("updating fixed positions, using viewport %fx%f - %fx%f",
+ viewport.fLeft, viewport.fTop,
+ viewport.width(), viewport.height());
- if (m_isFixed) {
- hasFixedElements = true;
- // So if this is a fixed layer inside a iframe, use the iframe offset
- // and the iframe's size as the viewport and pass to the children
- if (parentIframeLayer) {
- viewport = SkRect::MakeXYWH(parentIframeLayer->m_iframeOffset.fX,
- parentIframeLayer->m_iframeOffset.fY,
- parentIframeLayer->getSize().width(),
- parentIframeLayer->getSize().height());
- }
- float w = viewport.width();
- float h = viewport.height();
- float dx = viewport.fLeft;
- float dy = viewport.fTop;
- float x = dx;
- float y = dy;
-
- // It turns out that when it is 'auto', we should use the webkit value
- // from the original render layer's X,Y, that will take care of alignment
- // with the parent's layer and fix Margin etc.
- if (!(m_fixedLeft.defined() || m_fixedRight.defined()))
- x += m_renderLayerPos.x();
- else if (m_fixedLeft.defined() || !m_fixedRight.defined())
- x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft;
- else
- x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight;
-
- if (!(m_fixedTop.defined() || m_fixedBottom.defined()))
- y += m_renderLayerPos.y();
- else if (m_fixedTop.defined() || !m_fixedBottom.defined())
- y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop;
- else
- y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom;
-
- this->setPosition(x, y);
- }
+ IFrameLayerAndroid* iframeLayer = updatePosition(viewport, parentIframeLayer);
int count = this->countChildren();
for (int i = 0; i < count; i++)
- hasFixedElements |= this->getChild(i)->updateFixedLayersPositions(viewport, parentIframeLayer);
-
- return hasFixedElements;
+ this->getChild(i)->updateLayerPositions(viewport, iframeLayer);
}
void LayerAndroid::updatePositions()
{
// apply the viewport to us
- if (!m_isFixed) {
+ if (!isPositionFixed()) {
// turn our fields into a matrix.
//
// FIXME: this should happen in the caller, and we should remove these
@@ -685,13 +413,11 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
m_atomicSync.lock();
IntSize layerSize(getSize().width(), getSize().height());
FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY);
- FloatPoint position(getPosition().fX, getPosition().fY);
- float centerOffsetX = (0.5f - anchorPoint.x()) * layerSize.width();
- float centerOffsetY = (0.5f - anchorPoint.y()) * layerSize.height();
+ FloatPoint position(getPosition().fX - m_offset.x(), getPosition().fY - m_offset.y());
float originX = anchorPoint.x() * layerSize.width();
float originY = anchorPoint.y() * layerSize.height();
TransformationMatrix localMatrix;
- if (!m_isFixed)
+ if (!isPositionFixed())
localMatrix = parentMatrix;
localMatrix.translate3d(originX + position.x(),
originY + position.y(),
@@ -708,9 +434,9 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
// that layers (defined in content coordinates) will align to display/view pixels
float desiredContentX = round(m_drawTransform.m41() * scale) / scale;
float desiredContentY = round(m_drawTransform.m42() * scale) / scale;
- XLOG("fudging translation from %f, %f to %f, %f",
- m_drawTransform.m41(), m_drawTransform.m42(),
- desiredContentX, desiredContentY);
+ ALOGV("fudging translation from %f, %f to %f, %f",
+ m_drawTransform.m41(), m_drawTransform.m42(),
+ desiredContentX, desiredContentY);
m_drawTransform.setM41(desiredContentX);
m_drawTransform.setM42(desiredContentY);
}
@@ -733,6 +459,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) {
@@ -759,13 +488,27 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
// now apply it to our children
+ TransformationMatrix childMatrix;
+ childMatrix = localMatrix;
+ childMatrix.translate3d(m_offset.x(), m_offset.y(), 0);
if (!m_childrenTransform.isIdentity()) {
- localMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f);
- localMatrix.multiply(m_childrenTransform);
- localMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
+ childMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f);
+ childMatrix.multiply(m_childrenTransform);
+ childMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
}
for (int i = 0; i < count; i++)
- this->getChild(i)->updateGLPositionsAndScale(localMatrix, drawClip(), opacity, scale);
+ this->getChild(i)->updateGLPositionsAndScale(childMatrix, drawClip(), opacity, scale);
+}
+
+bool LayerAndroid::visible() {
+ // TODO: avoid climbing tree each access
+ LayerAndroid* current = this;
+ while (current->getParent()) {
+ if (!current->m_visible)
+ return false;
+ current = static_cast<LayerAndroid*>(current->getParent());
+ }
+ return true;
}
void LayerAndroid::setContentsImage(SkBitmapRef* img)
@@ -775,16 +518,16 @@ void LayerAndroid::setContentsImage(SkBitmapRef* img)
m_imageCRC = image ? image->imageCRC() : 0;
}
-bool LayerAndroid::needsTexture()
+void LayerAndroid::setContent(LayerContent* content)
{
- return m_imageCRC || (m_recordingPicture
- && m_recordingPicture->width() && m_recordingPicture->height());
+ SkSafeRef(content);
+ SkSafeUnref(m_content);
+ m_content = content;
}
-void LayerAndroid::removeTexture(PaintedSurface* texture)
+bool LayerAndroid::needsTexture()
{
- if (texture == m_texture)
- m_texture = 0;
+ return m_content && !m_content->isEmpty();
}
IntRect LayerAndroid::clippedRect() const
@@ -816,18 +559,6 @@ int LayerAndroid::nbTexturedLayers()
return nb;
}
-void LayerAndroid::computeTexturesAmount(TexturesResult* result)
-{
- if (!result)
- return;
-
- int count = this->countChildren();
- for (int i = 0; i < count; i++)
- this->getChild(i)->computeTexturesAmount(result);
- if (m_texture && m_visible)
- m_texture->computeTexturesAmount(result);
-}
-
void LayerAndroid::showLayer(int indent)
{
char spaces[256];
@@ -836,9 +567,9 @@ void LayerAndroid::showLayer(int indent)
spaces[i] = ' ';
if (!indent) {
- XLOGC("\n\n--- LAYERS TREE ---");
+ ALOGD("\n\n--- LAYERS TREE ---");
IntRect documentViewport(TilesManager::instance()->shader()->documentViewport());
- XLOGC("documentViewport(%d, %d, %d, %d)",
+ ALOGD("documentViewport(%d, %d, %d, %d)",
documentViewport.x(), documentViewport.y(),
documentViewport.width(), documentViewport.height());
}
@@ -848,87 +579,36 @@ void LayerAndroid::showLayer(int indent)
IntRect visible = visibleArea();
IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
m_clippingRect.width(), m_clippingRect.height());
- XLOGC("%s [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
- "clip (%d, %d, %d, %d) %s %s prepareContext(%x), pic w: %d h: %d",
- spaces, uniqueId(), m_owningLayer,
+ ALOGD("%s %s (%d) [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
+ "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d",
+ spaces, subclassName().latin1().data(), subclassType(), uniqueId(), m_owningLayer,
needsTexture() ? "needs a texture" : "no texture",
m_imageCRC ? "has an image" : "no image",
tr.x(), tr.y(), tr.width(), tr.height(),
visible.x(), visible.y(), visible.width(), visible.height(),
clip.x(), clip.y(), clip.width(), clip.height(),
contentIsScrollable() ? "SCROLLABLE" : "",
- isFixed() ? "FIXED" : "",
- m_recordingPicture,
- m_recordingPicture ? m_recordingPicture->width() : -1,
- m_recordingPicture ? m_recordingPicture->height() : -1);
+ isPositionFixed() ? "FIXED" : "",
+ m_content,
+ m_content ? m_content->width() : -1,
+ m_content ? m_content->height() : -1);
int count = this->countChildren();
for (int i = 0; i < count; i++)
this->getChild(i)->showLayer(indent + 1);
}
-void LayerAndroid::swapTiles()
-{
- int count = this->countChildren();
- for (int i = 0; i < count; i++)
- this->getChild(i)->swapTiles();
-
- if (m_texture)
- m_texture->swapTiles();
-}
-
-void LayerAndroid::setIsDrawing(bool isDrawing)
-{
- int count = this->countChildren();
- for (int i = 0; i < count; i++)
- this->getChild(i)->setIsDrawing(isDrawing);
-
- if (m_texture) {
- m_texture->setDrawingLayer(isDrawing ? this : 0);
- m_texture->clearPaintingLayer();
- }
-}
-
-void LayerAndroid::setIsPainting(Layer* drawingTree)
-{
- XLOG("setting layer %p as painting, needs texture %d, drawing tree %p",
- this, needsTexture(), drawingTree);
- int count = this->countChildren();
- for (int i = 0; i < count; i++)
- this->getChild(i)->setIsPainting(drawingTree);
-
-
- LayerAndroid* drawingLayer = 0;
- if (drawingTree)
- drawingLayer = static_cast<LayerAndroid*>(drawingTree)->findById(uniqueId());
-
- obtainTextureForPainting(drawingLayer);
-}
-
-void LayerAndroid::mergeInvalsInto(Layer* replacementTree)
+void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree)
{
int count = this->countChildren();
for (int i = 0; i < count; i++)
this->getChild(i)->mergeInvalsInto(replacementTree);
- LayerAndroid* replacementLayer = static_cast<LayerAndroid*>(replacementTree)->findById(uniqueId());
+ LayerAndroid* replacementLayer = replacementTree->findById(uniqueId());
if (replacementLayer)
replacementLayer->markAsDirty(m_dirtyRegion);
}
-bool LayerAndroid::isReady()
-{
- int count = countChildren();
- for (int i = 0; i < count; i++)
- if (!getChild(i)->isReady())
- return false;
-
- if (m_texture)
- return m_texture->isReady();
- // TODO: image, check if uploaded?
- return true;
-}
-
bool LayerAndroid::updateWithTree(LayerAndroid* newTree)
{
// Disable fast update for now
@@ -966,43 +646,115 @@ bool LayerAndroid::updateWithLayer(LayerAndroid* layer)
if (m_imageCRC != layer->m_imageCRC)
m_visible = false;
- if ((m_recordingPicture != layer->m_recordingPicture)
+ if ((m_content != layer->m_content)
|| (m_imageCRC != layer->m_imageCRC))
return true;
return false;
}
-void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingLayer)
+static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
{
- if (!needsTexture())
- return;
+ return a->zValue() > b->zValue();
+}
- if (m_imageCRC) {
- if (m_texture) {
- m_texture->setDrawingLayer(0);
- m_texture->clearPaintingLayer();
- m_texture = 0;
- }
- } else {
- if (drawingLayer) {
- // if a previous tree had the same layer, paint with that painted surface
- m_texture = drawingLayer->m_texture;
- }
+bool LayerAndroid::canJoinGroup(LayerGroup* group)
+{
+#ifdef DISABLE_LAYER_MERGE
+ return false;
+#else
+ // returns true if the layer can be merged onto the layergroup
+ if (!group)
+ return false;
- if (!m_texture)
- m_texture = new PaintedSurface();
+ LayerAndroid* lastLayer = group->getFirstLayer();
- // pass the invalidated regions to the PaintedSurface
- m_texture->setPaintingLayer(this, m_dirtyRegion);
- }
- m_dirtyRegion.setEmpty();
-}
+ // isolate non-tiled layers
+ // TODO: remove this check so that multiple tiled layers with a invisible
+ // one inbetween can be merged
+ if (!needsTexture() || !lastLayer->needsTexture())
+ return false;
+ // isolate clipped layers
+ // TODO: paint correctly with clip when merged
+ if (m_haveClip || lastLayer->m_haveClip)
+ return false;
-static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
+ // isolate intrinsically composited layers
+ if (m_intrinsicallyComposited || lastLayer->m_intrinsicallyComposited)
+ return false;
+
+ // TODO: investigate potential for combining transformed layers
+ if (!m_drawTransform.isIdentityOrTranslation()
+ || !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())
+ return false;
+
+ // TODO: compare other layer properties - fixed? overscroll? transformed?
+ return true;
+#endif
+}
+
+void LayerAndroid::assignGroups(LayerMergeState* mergeState)
{
- return a->zValue() > b->zValue();
+ // recurse through layers in draw order, and merge layers when able
+
+ bool needNewGroup = !mergeState->currentLayerGroup
+ || mergeState->nonMergeNestedLevel > 0
+ || !canJoinGroup(mergeState->currentLayerGroup);
+
+ if (needNewGroup) {
+ mergeState->currentLayerGroup = new LayerGroup();
+ mergeState->groupList->append(mergeState->currentLayerGroup);
+ }
+
+#ifdef LAYER_GROUPING_DEBUG
+ ALOGD("%*slayer %p(%d) rl %p %s group %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d",
+ 4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
+ needNewGroup ? "NEW" : "joins", mergeState->currentLayerGroup,
+ isPositionFixed(), m_animations.size() != 0,
+ m_intrinsicallyComposited,
+ m_haveClip,
+ contentIsScrollable());
+#endif
+
+ mergeState->currentLayerGroup->addLayer(this, m_drawTransform);
+ m_layerGroup = mergeState->currentLayerGroup;
+
+ if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
+ // disable layer merging within the children of these layer types
+ mergeState->nonMergeNestedLevel++;
+ }
+
+
+ // pass the layergroup 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();
+ if (count > 0) {
+ mergeState->depth++;
+ Vector <LayerAndroid*> sublayers;
+ for (int i = 0; i < count; i++)
+ sublayers.append(getChild(i));
+
+ // sort for the transparency
+ std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
+ for (int i = 0; i < count; i++)
+ sublayers[i]->assignGroups(mergeState);
+ mergeState->depth--;
+ }
+
+ if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
+ // re-enable joining
+ mergeState->nonMergeNestedLevel--;
+
+ // disallow layers painting after to join with this group
+ mergeState->currentLayerGroup = 0;
+ }
}
// We call this in WebViewCore, when copying the tree of layers.
@@ -1018,26 +770,14 @@ void LayerAndroid::clearDirtyRegion()
m_dirtyRegion.setEmpty();
}
-void LayerAndroid::prepare()
+int LayerAndroid::setHwAccelerated(bool hwAccelerated)
{
- XLOG("LA %p preparing, m_texture %p", this, m_texture);
-
+ int flags = InvalidateNone;
int count = this->countChildren();
- if (count > 0) {
- Vector <LayerAndroid*> sublayers;
- for (int i = 0; i < count; i++)
- sublayers.append(this->getChild(i));
-
- // now we sort for the transparency
- std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
-
- // iterate in reverse so top layers get textures first
- for (int i = count-1; i >= 0; i--)
- sublayers[i]->prepare();
- }
+ for (int i = 0; i < count; i++)
+ flags |= this->getChild(i)->setHwAccelerated(hwAccelerated);
- if (m_texture)
- m_texture->prepare(m_state);
+ return flags | onSetHwAccelerated(hwAccelerated);
}
IntRect LayerAndroid::unclippedArea()
@@ -1072,7 +812,7 @@ IntRect LayerAndroid::visibleArea()
return rect;
}
-bool LayerAndroid::drawCanvas(SkCanvas* canvas)
+bool LayerAndroid::drawCanvas(SkCanvas* canvas, bool drawChildren, PaintStyle style)
{
if (!m_visible)
return false;
@@ -1091,16 +831,14 @@ bool LayerAndroid::drawCanvas(SkCanvas* canvas)
SkMatrix canvasMatrix = canvas->getTotalMatrix();
matrix.postConcat(canvasMatrix);
canvas->setMatrix(matrix);
- SkRect layerRect;
- layerRect.fLeft = 0;
- layerRect.fTop = 0;
- layerRect.fRight = getWidth();
- layerRect.fBottom = getHeight();
- onDraw(canvas, m_drawOpacity);
+ onDraw(canvas, m_drawOpacity, 0, style);
}
+ if (!drawChildren)
+ return false;
+
// When the layer is dirty, the UI thread should be notified to redraw.
- askScreenUpdate |= drawChildrenCanvas(canvas);
+ askScreenUpdate |= drawChildrenCanvas(canvas, style);
m_atomicSync.lock();
if (askScreenUpdate || m_hasRunningAnimations || m_drawTransform.hasPerspective())
addDirtyArea();
@@ -1109,57 +847,29 @@ bool LayerAndroid::drawCanvas(SkCanvas* canvas)
return askScreenUpdate;
}
-bool LayerAndroid::drawGL()
+bool LayerAndroid::drawGL(bool layerTilesDisabled)
{
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(m_clippingRect);
- TilesManager::instance()->shader()->clip(clippingRect);
- if (!m_visible)
- return false;
+ if (!layerTilesDisabled && m_imageCRC) {
+ ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
+ if (imageTexture)
+ imageTexture->drawGL(this, getOpacity());
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+ }
+ m_state->glExtras()->drawGL(this);
bool askScreenUpdate = false;
- if (m_state->layersRenderingMode() < GLWebViewState::kScrollableAndFixedLayers) {
- if (m_texture)
- askScreenUpdate |= m_texture->draw();
- if (m_imageCRC) {
- ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
- if (imageTexture)
- imageTexture->drawGL(this);
- ImagesManager::instance()->releaseImage(m_imageCRC);
- }
- }
-
- // When the layer is dirty, the UI thread should be notified to redraw.
- askScreenUpdate |= drawChildrenGL();
m_atomicSync.lock();
- if (askScreenUpdate || m_hasRunningAnimations || m_drawTransform.hasPerspective())
+ if (m_hasRunningAnimations || m_drawTransform.hasPerspective()) {
+ askScreenUpdate = true;
addDirtyArea();
-
- m_atomicSync.unlock();
- return askScreenUpdate;
-}
-
-bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas)
-{
- bool askScreenUpdate = false;
- int count = this->countChildren();
- if (count > 0) {
- Vector <LayerAndroid*> sublayers;
- for (int i = 0; i < count; i++)
- sublayers.append(this->getChild(i));
-
- // now we sort for the transparency
- std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
- for (int i = 0; i < count; i++) {
- LayerAndroid* layer = sublayers[i];
- askScreenUpdate |= layer->drawCanvas(canvas);
- }
}
+ m_atomicSync.unlock();
return askScreenUpdate;
}
-bool LayerAndroid::drawChildrenGL()
+bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style)
{
bool askScreenUpdate = false;
int count = this->countChildren();
@@ -1172,40 +882,45 @@ bool LayerAndroid::drawChildrenGL()
std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
for (int i = 0; i < count; i++) {
LayerAndroid* layer = sublayers[i];
- askScreenUpdate |= layer->drawGL();
+ askScreenUpdate |= layer->drawCanvas(canvas, true, style);
}
}
return askScreenUpdate;
}
-void LayerAndroid::contentDraw(SkCanvas* canvas)
+void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style)
{
- if (m_recordingPicture)
- canvas->drawPicture(*m_recordingPicture);
+ if (m_content)
+ m_content->draw(canvas);
if (TilesManager::instance()->getShowVisualIndicator()) {
float w = getSize().width();
float h = getSize().height();
SkPaint paint;
- paint.setARGB(128, 255, 0, 0);
+
+ if (style == MergedLayers)
+ paint.setARGB(255, 255, 255, 0);
+ else if (style == UnmergedLayers)
+ paint.setARGB(255, 255, 0, 0);
+ else if (style == FlattenedLayers)
+ paint.setARGB(255, 255, 0, 255);
+
canvas->drawLine(0, 0, w, h, paint);
canvas->drawLine(0, h, w, 0, paint);
- paint.setARGB(128, 0, 255, 0);
- 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);
-
- if (m_isFixed) {
- SkPaint paint;
- paint.setARGB(80, 255, 0, 0);
- canvas->drawRect(m_fixedRect, 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)
+ return m_fixedPosition->contentDraw(canvas, style);
}
-void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
+void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity,
+ android::DrawExtra* extra, PaintStyle style)
{
if (m_haveClip) {
SkRect r;
@@ -1214,7 +929,7 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
return;
}
- if (!prepareContext())
+ if (masksToBounds() || !m_content)
return;
// we just have this save/restore for opacity...
@@ -1234,179 +949,23 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
}
ImagesManager::instance()->releaseImage(m_imageCRC);
}
- contentDraw(canvas);
+ contentDraw(canvas, style);
+ if (extra)
+ extra->draw(canvas, this);
}
-SkPicture* LayerAndroid::recordContext()
-{
- if (prepareContext(true))
- return m_recordingPicture;
- return 0;
-}
-
-bool LayerAndroid::prepareContext(bool force)
-{
- if (masksToBounds())
- return false;
-
- if (force || !m_recordingPicture ||
- (m_recordingPicture &&
- ((m_recordingPicture->width() != (int) getSize().width()) ||
- (m_recordingPicture->height() != (int) getSize().height())))) {
- SkSafeUnref(m_recordingPicture);
- m_recordingPicture = new SkPicture();
- }
-
- return m_recordingPicture;
-}
-
-SkRect LayerAndroid::subtractLayers(const SkRect& visibleRect) const
-{
- SkRect result;
- if (m_recordingPicture) {
- // FIXME: This seems wrong. localToGlobal() applies the full local transform,
- // se surely we should operate globalMatrix on size(), not bounds() with
- // the position removed? Perhaps we never noticed the bug because most
- // layers don't use a local transform?
- // See http://b/5338388
- SkRect globalRect = bounds();
- globalRect.offset(-getPosition()); // localToGlobal adds in position
- SkMatrix globalMatrix;
- localToGlobal(&globalMatrix);
- globalMatrix.mapRect(&globalRect);
- SkIRect roundedGlobal;
- globalRect.round(&roundedGlobal);
- SkIRect iVisibleRect;
- visibleRect.round(&iVisibleRect);
- SkRegion visRegion(iVisibleRect);
- visRegion.op(roundedGlobal, SkRegion::kDifference_Op);
- result.set(visRegion.getBounds());
-#if DEBUG_NAV_UI
- SkDebugf("%s visibleRect=(%g,%g,r=%g,b=%g) globalRect=(%g,%g,r=%g,b=%g)"
- "result=(%g,%g,r=%g,b=%g)", __FUNCTION__,
- visibleRect.fLeft, visibleRect.fTop,
- visibleRect.fRight, visibleRect.fBottom,
- globalRect.fLeft, globalRect.fTop,
- globalRect.fRight, globalRect.fBottom,
- result.fLeft, result.fTop, result.fRight, result.fBottom);
-#endif
- } else
- result = visibleRect;
- for (int i = 0; i < countChildren(); i++)
- result = getChild(i)->subtractLayers(result);
- return result;
-}
-
-// Debug tools : dump the layers tree in a file.
-// The format is simple:
-// properties have the form: key = value;
-// all statements are finished with a semi-colon.
-// value can be:
-// - int
-// - float
-// - array of elements
-// - composed type
-// a composed type enclose properties in { and }
-// an array enclose composed types in { }, separated with a comma.
-// exemple:
-// {
-// x = 3;
-// y = 4;
-// value = {
-// x = 3;
-// y = 4;
-// };
-// anarray = [
-// { x = 3; },
-// { y = 4; }
-// ];
-// }
-
-void lwrite(FILE* file, const char* str)
-{
- fwrite(str, sizeof(char), strlen(str), file);
+void LayerAndroid::setFixedPosition(FixedPositioning* position) {
+ if (m_fixedPosition && m_fixedPosition != position)
+ delete m_fixedPosition;
+ m_fixedPosition = position;
}
-void writeIndent(FILE* file, int indentLevel)
+void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const
{
- if (indentLevel)
- fprintf(file, "%*s", indentLevel*2, " ");
-}
-
-void writeln(FILE* file, int indentLevel, const char* str)
-{
- writeIndent(file, indentLevel);
- lwrite(file, str);
- lwrite(file, "\n");
-}
-
-void writeIntVal(FILE* file, int indentLevel, const char* str, int value)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = %d;\n", str, value);
-}
-
-void writeHexVal(FILE* file, int indentLevel, const char* str, int value)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = %x;\n", str, value);
-}
-
-void writeFloatVal(FILE* file, int indentLevel, const char* str, float value)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = %.3f;\n", str, value);
-}
-
-void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { x = %.3f; y = %.3f; };\n", str, point.fX, point.fY);
-}
-
-void writeSize(FILE* file, int indentLevel, const char* str, SkSize size)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height());
-}
-
-void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n",
- str, rect.fLeft, rect.fTop, rect.width(), rect.height());
-}
-
-void writeLength(FILE* file, int indentLevel, const char* str, SkLength length)
-{
- if (!length.defined())
- return;
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value);
-}
-
-void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix)
-{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f),"
- "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) };\n",
- str,
- matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
- matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(),
- matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(),
- matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44());
-}
-
-void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
-{
- writeln(file, indentLevel, "{");
-
writeHexVal(file, indentLevel + 1, "layer", (int)this);
writeIntVal(file, indentLevel + 1, "layerId", m_uniqueId);
writeIntVal(file, indentLevel + 1, "haveClip", m_haveClip);
- writeIntVal(file, indentLevel + 1, "isFixed", m_isFixed);
- writeIntVal(file, indentLevel + 1, "m_isIframe", m_isIframe);
- writePoint(file, indentLevel + 1, "m_iframeOffset", m_iframeOffset);
+ writeIntVal(file, indentLevel + 1, "isFixed", isPositionFixed());
writeFloatVal(file, indentLevel + 1, "opacity", getOpacity());
writeSize(file, indentLevel + 1, "size", getSize());
@@ -1417,22 +976,20 @@ void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform);
writeRect(file, indentLevel + 1, "clippingRect", SkRect(m_clippingRect));
- if (m_isFixed) {
- writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft);
- writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop);
- writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight);
- writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom);
- writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft);
- writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop);
- writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight);
- writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom);
- writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect);
+ if (m_content) {
+ writeIntVal(file, indentLevel + 1, "m_content.width", m_content->width());
+ writeIntVal(file, indentLevel + 1, "m_content.height", m_content->height());
}
- if (m_recordingPicture) {
- writeIntVal(file, indentLevel + 1, "m_recordingPicture.width", m_recordingPicture->width());
- writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height());
- }
+ if (m_fixedPosition)
+ return m_fixedPosition->dumpLayer(file, indentLevel);
+}
+
+void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
+{
+ writeln(file, indentLevel, "{");
+
+ dumpLayer(file, indentLevel);
if (countChildren()) {
writeln(file, indentLevel + 1, "children = [");
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index c1f1bc9..c7028c5 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -48,54 +48,29 @@ class SkPicture;
namespace WebCore {
class LayerAndroid;
+class LayerContent;
+class LayerGroup;
class ImageTexture;
}
namespace android {
class DrawExtra;
void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream);
-WebCore::LayerAndroid* deserializeLayer(SkStream* stream);
+WebCore::LayerAndroid* deserializeLayer(int version, SkStream* stream);
void cleanupImageRefs(WebCore::LayerAndroid* layer);
}
using namespace android;
-struct SkLength {
- enum SkLengthType { Undefined, Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
- SkLengthType type;
- SkScalar value;
- SkLength()
- {
- type = Undefined;
- value = 0;
- }
- bool defined() const
- {
- if (type == Undefined)
- return false;
- return true;
- }
- float calcFloatValue(float max) const
- {
- switch (type) {
- case Percent:
- return (max * value) / 100.0f;
- case Fixed:
- return value;
- default:
- return value;
- }
- }
-};
-
namespace WebCore {
class AndroidAnimation;
class BaseTileTexture;
+class FixedPositioning;
class GLWebViewState;
-class LayerAndroidFindState;
+class IFrameLayerAndroid;
+class LayerMergeState;
class RenderLayer;
-class TiledPage;
class PaintedSurface;
class TexturesResult {
@@ -115,15 +90,35 @@ public:
class TEST_EXPORT LayerAndroid : public Layer {
public:
- enum LayerType { UndefinedLayer, WebCoreLayer, UILayer, NavCacheLayer };
+ typedef enum { UndefinedLayer, WebCoreLayer, UILayer } LayerType;
+ typedef enum { StandardLayer, ScrollableLayer,
+ IFrameLayer, IFrameContentLayer,
+ CanvasLayer, BaseLayer } SubclassType;
+ typedef enum { InvalidateNone = 0, InvalidateLayers } InvalidateFlags;
+
+ String subclassName()
+ {
+ switch (subclassType()) {
+ case LayerAndroid::StandardLayer:
+ return "StandardLayer";
+ case LayerAndroid::ScrollableLayer:
+ return "ScrollableLayer";
+ case LayerAndroid::IFrameLayer:
+ 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;
@@ -139,30 +134,23 @@ public:
IntRect visibleArea();
virtual bool needsTexture();
- void removeTexture(PaintedSurface*);
// Debug helper methods
int nbLayers();
int nbTexturedLayers();
void showLayer(int indent = 0);
- void computeTexturesAmount(TexturesResult*);
-
float getScale() { return m_scale; }
- // draw layer and its children via Z, pre-order traversal
- virtual bool drawGL();
- bool drawChildrenGL();
- virtual bool drawCanvas(SkCanvas*);
- bool drawChildrenCanvas(SkCanvas*);
-
- // prepare layer and its children via reverse-Z, post-order traversal
- void prepare();
+ virtual bool drawGL(bool layerTilesDisabled);
+ virtual bool drawCanvas(SkCanvas* canvas, bool drawChildren, PaintStyle style);
+ bool drawChildrenCanvas(SkCanvas* canvas, PaintStyle style);
void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
const FloatRect& clip, float opacity, float scale);
void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
float drawOpacity() { return m_drawOpacity; }
+ bool visible();
void setVisible(bool value) { m_visible = value; }
bool preserves3D() { return m_preserves3D; }
@@ -170,35 +158,13 @@ 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; }
- void setFixedPosition(SkLength left, // CSS left property
- SkLength top, // CSS top property
- SkLength right, // CSS right property
- SkLength bottom, // CSS bottom property
- SkLength marginLeft, // CSS margin-left property
- SkLength marginTop, // CSS margin-top property
- SkLength marginRight, // CSS margin-right property
- SkLength marginBottom, // CSS margin-bottom property
- const IntPoint& renderLayerPos, // For undefined fixed position
- SkRect viewRect) { // view rect, can be smaller than the layer's
- m_fixedLeft = left;
- m_fixedTop = top;
- m_fixedRight = right;
- m_fixedBottom = bottom;
- m_fixedMarginLeft = marginLeft;
- m_fixedMarginTop = marginTop;
- m_fixedMarginRight = marginRight;
- m_fixedMarginBottom = marginBottom;
- m_fixedRect = viewRect;
- m_isFixed = true;
- m_renderLayerPos = renderLayerPos;
- setShouldInheritFromRootTransform(true);
- }
-
+ const IntPoint& scrollOffset() const { return m_offset; }
+ void setScrollOffset(IntPoint offset) { m_offset = offset; }
void setBackgroundColor(SkColor color);
void setMaskLayer(LayerAndroid*);
void setMasksToBounds(bool masksToBounds)
@@ -207,7 +173,8 @@ public:
}
bool masksToBounds() const { return m_haveClip; }
- SkPicture* recordContext();
+ LayerContent* content() { return m_content; }
+ void setContent(LayerContent* content);
void addAnimation(PassRefPtr<AndroidAnimation> anim);
void removeAnimationsForProperty(AnimatedPropertyID property);
@@ -218,13 +185,7 @@ public:
bool hasAnimations() const;
void addDirtyArea();
- SkPicture* picture() const { return m_recordingPicture; }
-
- // Given a rect in global space, subtracts from it the bounds of this layer
- // and of all of its children. Returns the bounding rectangle of the result,
- // in global space.
- SkRect subtractLayers(const SkRect&) const;
-
+ virtual void dumpLayer(FILE*, int indentLevel) const;
void dumpLayers(FILE*, int indentLevel) const;
void dumpToLog() const;
@@ -234,7 +195,9 @@ public:
This call is recursive, so it should be called on the root of the
hierarchy.
*/
- bool updateFixedLayersPositions(SkRect viewPort, LayerAndroid* parentIframeLayer = 0);
+ void updateLayerPositions(SkRect viewPort, IFrameLayerAndroid* parentIframeLayer = 0);
+ virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
+ IFrameLayerAndroid* parentIframeLayer);
/** Call this to update the position attribute, so that later calls
like bounds() will report the corrected position.
@@ -256,7 +219,6 @@ public:
return static_cast<LayerAndroid*>(this->INHERITED::getChild(index));
}
int uniqueId() const { return m_uniqueId; }
- bool isFixed() { return m_isFixed; }
/** This sets a content image -- calling it means we will use
the image directly when drawing the layer instead of using
@@ -270,62 +232,68 @@ public:
virtual LayerAndroid* copy() const { return new LayerAndroid(*this); }
- void needsRepaint() { m_pictureUsed++; }
- unsigned int pictureUsed() { return m_pictureUsed; }
-
- void clearDirtyRegion();
+ virtual void clearDirtyRegion();
- void contentDraw(SkCanvas*);
+ virtual void contentDraw(SkCanvas* canvas, PaintStyle style);
virtual bool isMedia() const { return false; }
virtual bool isVideo() const { return false; }
+ virtual bool isIFrame() const { return false; }
+ virtual bool isIFrameContent() const { return false; }
+
+ bool isPositionFixed() const { return m_fixedPosition; }
+ void setAbsolutePosition(bool isAbsolute) { m_isPositionAbsolute = isAbsolute; }
+ bool isPositionAbsolute() { return m_isPositionAbsolute; }
+ void setFixedPosition(FixedPositioning* position);
+ FixedPositioning* fixedPosition() { return m_fixedPosition; }
RenderLayer* owningLayer() const { return m_owningLayer; }
- void setIsIframe(bool isIframe) { m_isIframe = isIframe; }
float zValue() const { return m_zValue; }
// ViewStateSerializer friends
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
- friend LayerAndroid* android::deserializeLayer(SkStream* stream);
+ friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
friend void android::cleanupImageRefs(LayerAndroid* layer);
- PaintedSurface* texture() { return m_texture; }
- void obtainTextureForPainting(LayerAndroid* drawingLayer);
-
// Update layers using another tree. Only works for basic properties
// such as the position, the transform. Return true if anything more
// complex is needed.
bool updateWithTree(LayerAndroid*);
virtual bool updateWithLayer(LayerAndroid*);
- int type() { return m_type; }
+ LayerType type() { return m_type; }
+ virtual SubclassType subclassType() { return LayerAndroid::StandardLayer; }
- bool hasText() { return m_hasText; }
- void checkTextPresence();
+ bool hasText();
void copyAnimationStartTimesRecursive(LayerAndroid* oldTree);
// rendering asset management
- void swapTiles();
- void setIsDrawing(bool isDrawing);
- void setIsPainting(Layer* drawingTree);
- void mergeInvalsInto(Layer* replacementTree);
- bool isReady();
+ SkRegion* getInvalRegion() { return &m_dirtyRegion; }
+ void mergeInvalsInto(LayerAndroid* replacementTree);
-protected:
- virtual void onDraw(SkCanvas*, SkScalar opacity);
+ bool canJoinGroup(LayerGroup* group);
+ void assignGroups(LayerMergeState* mergeState);
+ LayerGroup* group() { return m_layerGroup; }
+ 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:
- class FindState;
#if DUMP_NAV_CACHE
friend class CachedLayer::Debug; // debugging access only
#endif
void copyAnimationStartTimes(LayerAndroid* oldLayer);
- void findInner(FindState&) const;
bool prepareContext(bool force = false);
void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const;
@@ -334,23 +302,7 @@ private:
// -------------------------------------------------------------------
bool m_haveClip;
- bool m_isFixed;
bool m_backgroundColorSet;
- bool m_isIframe;
-
- SkLength m_fixedLeft;
- SkLength m_fixedTop;
- SkLength m_fixedRight;
- SkLength m_fixedBottom;
- SkLength m_fixedMarginLeft;
- SkLength m_fixedMarginTop;
- SkLength m_fixedMarginRight;
- SkLength m_fixedMarginBottom;
- SkRect m_fixedRect;
-
- // When fixed element is undefined or auto, the render layer's position
- // is needed for offset computation
- IntPoint m_renderLayerPos;
bool m_backfaceVisibility;
bool m_visible;
@@ -361,13 +313,8 @@ private:
float m_anchorPointZ;
float m_drawOpacity;
- // Note that m_recordingPicture and m_imageRef are mutually exclusive;
- // m_recordingPicture is used when WebKit is asked to paint the layer's
- // content, while m_imageRef contains an image that we directly
- // composite, using the layer's dimensions as a destination rect.
- // We do this as if the layer only contains an image, directly compositing
- // it is a much faster method than using m_recordingPicture.
- SkPicture* m_recordingPicture;
+ bool m_isPositionAbsolute;
+ FixedPositioning* m_fixedPosition;
typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
KeyframesMap m_animations;
@@ -379,19 +326,19 @@ private:
// Fields that are not serialized (generated, cached, or non-serializable)
// -------------------------------------------------------------------
- SkPoint m_iframeOffset;
-
float m_zValue;
FloatRect m_clippingRect;
- int m_uniqueId;
-
- PaintedSurface* m_texture;
+ // 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
+ // composite, using the layer's dimensions as a destination rect.
+ // We do this as if the layer only contains an image, directly compositing
+ // it is a much faster method than using m_content.
+ LayerContent* m_content;
unsigned m_imageCRC;
- unsigned int m_pictureUsed;
-
// used to signal the framework we need a repaint
bool m_hasRunningAnimations;
@@ -408,9 +355,12 @@ private:
RenderLayer* m_owningLayer;
- int m_type;
+ LayerType m_type;
+ SubclassType m_subclassType;
+
+ bool m_intrinsicallyComposited;
- bool m_hasText;
+ LayerGroup* m_layerGroup;
typedef Layer INHERITED;
};
diff --git a/Source/WebCore/platform/graphics/android/LayerContent.h b/Source/WebCore/platform/graphics/android/LayerContent.h
new file mode 100644
index 0000000..97bc32a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/LayerContent.h
@@ -0,0 +1,56 @@
+/*
+ * 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 LayerContent_h
+#define LayerContent_h
+
+#include "SkRefCnt.h"
+#include <utils/threads.h>
+
+class SkCanvas;
+class SkPicture;
+class SkWStream;
+
+namespace WebCore {
+
+class LayerContent : public SkRefCnt {
+public:
+ virtual int width() = 0;
+ virtual int height() = 0;
+ virtual bool isEmpty() = 0;
+ virtual void checkForOptimisations() = 0;
+ virtual bool hasText() = 0;
+ 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
+
+#endif // LayerContent_h
diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/LayerGroup.cpp
new file mode 100644
index 0000000..7bdbd11
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/LayerGroup.cpp
@@ -0,0 +1,345 @@
+/*
+ * 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 "LayerGroup"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "LayerGroup.h"
+
+#include "AndroidLog.h"
+#include "ClassTracker.h"
+#include "LayerAndroid.h"
+#include "TiledTexture.h"
+#include "TilesManager.h"
+
+// LayerGroups with an area larger than 2048*2048 should never be unclipped
+#define MAX_UNCLIPPED_AREA 4194304
+
+namespace WebCore {
+
+LayerGroup::LayerGroup()
+ : m_dualTiledTexture(0)
+ , m_needsTexture(false)
+ , m_hasText(false)
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->increment("LayerGroup");
+#endif
+}
+
+LayerGroup::~LayerGroup()
+{
+ for (unsigned int i = 0; i < m_layers.size(); i++)
+ SkSafeUnref(m_layers[i]);
+ if (m_dualTiledTexture)
+ SkSafeUnref(m_dualTiledTexture);
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("LayerGroup");
+#endif
+}
+
+bool LayerGroup::tryUpdateLayerGroup(LayerGroup* oldLayerGroup)
+{
+ if (!needsTexture() || !oldLayerGroup->needsTexture())
+ return false;
+
+ // merge layer group based on first layer ID
+ if (getFirstLayer()->uniqueId() != oldLayerGroup->getFirstLayer()->uniqueId())
+ return false;
+
+ m_dualTiledTexture = oldLayerGroup->m_dualTiledTexture;
+ SkSafeRef(m_dualTiledTexture);
+
+ ALOGV("%p taking old DTT %p from group %p, nt %d",
+ this, m_dualTiledTexture, oldLayerGroup, oldLayerGroup->needsTexture());
+
+ if (!m_dualTiledTexture) {
+ // no DTT to inval, so don't worry about it.
+ return true;
+ }
+
+ if (singleLayer() && oldLayerGroup->singleLayer()) {
+ // both are single matching layers, simply apply inval
+ SkRegion* layerInval = getFirstLayer()->getInvalRegion();
+ m_dualTiledTexture->markAsDirty(*layerInval);
+ } else {
+ SkRegion invalRegion;
+ bool fullInval = m_layers.size() != oldLayerGroup->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()) {
+ // 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
+ SkPoint pos = m_layers[i]->getPosition();
+ m_layers[i]->getInvalRegion()->translate(pos.fX, pos.fY);
+ invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op);
+ break;
+ }
+ }
+ }
+
+ if (fullInval)
+ invalRegion.setRect(-1e8, -1e8, 2e8, 2e8);
+
+ m_dualTiledTexture->markAsDirty(invalRegion);
+ }
+ return true;
+}
+
+void LayerGroup::addLayer(LayerAndroid* layer, const TransformationMatrix& transform)
+{
+ m_layers.append(layer);
+ SkSafeRef(layer);
+
+ m_needsTexture |= layer->needsTexture();
+ m_hasText |= layer->hasText();
+
+ // calculate area size for comparison later
+ IntRect rect = layer->unclippedArea();
+ SkPoint pos = layer->getPosition();
+ rect.setLocation(IntPoint(pos.fX, pos.fY));
+
+ if (layer->needsTexture()) {
+ if (m_unclippedArea.isEmpty()) {
+ m_drawTransform = transform;
+ m_drawTransform.translate3d(-pos.fX, -pos.fY, 0);
+ 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",
+ 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()
+{
+ if (singleLayer())
+ return getFirstLayer()->visibleArea();
+
+ IntRect rect = m_unclippedArea;
+
+ // clip with the viewport in documents coordinate
+ IntRect documentViewport(TilesManager::instance()->shader()->documentViewport());
+ rect.intersect(documentViewport);
+
+ // TODO: handle recursive layer clip
+
+ return rect;
+}
+
+IntRect LayerGroup::unclippedArea()
+{
+ if (singleLayer())
+ return getFirstLayer()->unclippedArea();
+ return m_unclippedArea;
+}
+
+bool LayerGroup::useAggressiveRendering()
+{
+ // When the background is translucent, 0 < alpha < 255, we had to turn off
+ // low res to avoid artifacts from double drawing.
+ // TODO: avoid double drawing for low res tiles.
+ return isBase()
+ && (!m_background.alpha()
+ || !m_background.hasAlpha());
+}
+
+void LayerGroup::prepareGL(bool layerTilesDisabled)
+{
+ bool tilesDisabled = layerTilesDisabled && !isBase();
+ if (!m_dualTiledTexture) {
+ ALOGV("prepareGL on LG %p, no DTT, needsTexture? %d",
+ this, m_dualTiledTexture, needsTexture());
+
+ if (!needsTexture())
+ return;
+
+ m_dualTiledTexture = new DualTiledTexture(isBase());
+ }
+
+ if (tilesDisabled) {
+ m_dualTiledTexture->discardTextures();
+ } else {
+ bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors
+ IntRect prepareArea = computePrepareArea();
+ IntRect fullArea = unclippedArea();
+
+ ALOGV("prepareGL on LG %p with DTT %p, %d layers",
+ this, m_dualTiledTexture, m_layers.size());
+
+ m_dualTiledTexture->prepareGL(getFirstLayer()->state(), allowZoom,
+ prepareArea, fullArea,
+ this, useAggressiveRendering());
+ }
+}
+
+bool LayerGroup::drawGL(bool layerTilesDisabled)
+{
+ bool tilesDisabled = layerTilesDisabled && !isBase();
+ if (!getFirstLayer()->visible())
+ return false;
+
+ 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 && !tilesDisabled) {
+ ALOGV("drawGL on LG %p with DTT %p", this, m_dualTiledTexture);
+
+ // TODO: why this visibleArea is different from visibleRect at zooming for base?
+ IntRect drawArea = visibleArea();
+ askRedraw |= m_dualTiledTexture->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(tilesDisabled);
+
+ return askRedraw;
+}
+
+void LayerGroup::swapTiles()
+{
+ if (!m_dualTiledTexture)
+ return;
+
+ m_dualTiledTexture->swapTiles();
+}
+
+bool LayerGroup::isReady()
+{
+ if (!m_dualTiledTexture)
+ return true;
+
+ return m_dualTiledTexture->isReady();
+}
+
+IntRect LayerGroup::computePrepareArea() {
+ IntRect area;
+
+ if (!getFirstLayer()->contentIsScrollable()
+ && !isBase()
+ && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
+
+ area = unclippedArea();
+
+ double total = ((double) area.width()) * ((double) area.height());
+ if (total > MAX_UNCLIPPED_AREA)
+ area = visibleArea();
+ } else {
+ area = visibleArea();
+ }
+
+ return area;
+}
+
+void LayerGroup::computeTexturesAmount(TexturesResult* result)
+{
+ if (!m_dualTiledTexture || isBase())
+ return;
+
+ m_dualTiledTexture->computeTexturesAmount(result, getFirstLayer());
+}
+
+bool LayerGroup::isBase()
+{
+ // base layer group
+ // - doesn't use layer tiles (disables blending, doesn't compute textures amount)
+ // - ignores clip rects
+ // - only prepares clippedArea
+ return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer;
+}
+
+bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas)
+{
+ 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;
+ GLUtils::toSkMatrix(matrix, m_drawTransform);
+
+ SkMatrix inverse;
+ inverse.reset();
+ matrix.invert(&inverse);
+
+ SkMatrix canvasMatrix = canvas->getTotalMatrix();
+ inverse.postConcat(canvasMatrix);
+ canvas->setMatrix(inverse);
+
+ for (unsigned int i=0; i<m_layers.size(); i++)
+ m_layers[i]->drawCanvas(canvas, false, Layer::MergedLayers);
+ }
+ return true;
+}
+
+float LayerGroup::opacity()
+{
+ if (singleLayer())
+ return getFirstLayer()->drawOpacity();
+ return 1.0;
+}
+
+Color* LayerGroup::background()
+{
+ if (!isBase() || !m_background.isValid())
+ return 0;
+ return &m_background;
+}
+
+const TransformationMatrix* LayerGroup::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
+ if (singleLayer())
+ return getFirstLayer()->drawTransform();
+
+ return &m_drawTransform;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.h b/Source/WebCore/platform/graphics/android/LayerGroup.h
new file mode 100644
index 0000000..8e9608d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/LayerGroup.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 LayerGroup_h
+#define LayerGroup_h
+
+#include "Color.h"
+#include "IntRect.h"
+#include "TilePainter.h"
+#include "Vector.h"
+
+class SkCanvas;
+class SkRegion;
+
+namespace WebCore {
+
+class BaseTile;
+class DualTiledTexture;
+class LayerAndroid;
+class TexturesResult;
+
+class LayerGroup : public TilePainter {
+public:
+ LayerGroup();
+ virtual ~LayerGroup();
+
+ bool tryUpdateLayerGroup(LayerGroup* oldLayerGroup);
+
+ void addLayer(LayerAndroid* layer, const TransformationMatrix& transform);
+ void prepareGL(bool layerTilesDisabled);
+ bool drawGL(bool layerTilesDisabled);
+ void swapTiles();
+ bool isReady();
+
+ void computeTexturesAmount(TexturesResult* result);
+
+ LayerAndroid* getFirstLayer() { return m_layers[0]; }
+ 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 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;
+ 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)
+ , nonMergeNestedLevel(-1) // start at -1 to ignore first LayerAndroid's clipping
+ , depth(0)
+ {}
+
+ // vector storing all generated layer groups
+ Vector<LayerGroup*>* const groupList;
+
+ // currently merging group. if cleared, no more layers may join
+ LayerGroup* currentLayerGroup;
+
+ // records depth within non-mergeable parents (clipping, fixed, scrolling)
+ // and disable merging therein.
+ int nonMergeNestedLevel;
+
+ // counts layer tree depth for debugging
+ int depth;
+};
+
+} // namespace WebCore
+
+#endif //#define LayerGroup_h
diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/MediaLayer.cpp
index 12cfe38..6227ea4 100644
--- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/MediaLayer.cpp
@@ -13,41 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#define LOG_TAG "MediaLayer"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "MediaLayer.h"
+
+#include "AndroidLog.h"
#include "MediaTexture.h"
#include "TilesManager.h"
#if USE(ACCELERATED_COMPOSITING)
-#define LAYER_DEBUG
-#undef LAYER_DEBUG
-
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "MediaLayer", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
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;
m_outlineSize = 0;
- XLOG("Creating Media Layer %p", this);
+ ALOGV("Creating Media Layer %p", this);
}
MediaLayer::MediaLayer(const MediaLayer& layer) : LayerAndroid(layer)
@@ -57,16 +45,16 @@ MediaLayer::MediaLayer(const MediaLayer& layer) : LayerAndroid(layer)
m_isCopy = true;
m_outlineSize = layer.m_outlineSize;
- XLOG("Creating Media Layer Copy %p -> %p", &layer, this);
+ ALOGV("Creating Media Layer Copy %p -> %p", &layer, this);
}
MediaLayer::~MediaLayer()
{
- XLOG("Deleting Media Layer");
+ ALOGV("Deleting Media Layer");
m_mediaTexture->decStrong(this);
}
-bool MediaLayer::drawGL()
+bool MediaLayer::drawGL(bool layerTilesDisabled)
{
FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip());
TilesManager::instance()->shader()->clip(clippingRect);
@@ -92,8 +80,7 @@ bool MediaLayer::drawGL()
// draw any content or video if present
m_mediaTexture->draw(m, m_drawTransform, mediaBounds);
-
- return drawChildrenGL();
+ return false;
}
ANativeWindow* MediaLayer::acquireNativeWindowForContent()
diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.h b/Source/WebCore/platform/graphics/android/MediaLayer.h
index b94ec53..2f39d74 100644
--- a/Source/WebCore/platform/graphics/android/MediaLayer.h
+++ b/Source/WebCore/platform/graphics/android/MediaLayer.h
@@ -32,11 +32,11 @@ namespace WebCore {
class MediaLayer : public LayerAndroid {
public:
- MediaLayer(jobject webViewRef);
+ MediaLayer(jobject webViewRef, jobject webViewCoreRef);
MediaLayer(const MediaLayer& layer);
virtual ~MediaLayer();
- virtual bool drawGL();
+ virtual bool drawGL(bool layerTilesDisabled);
virtual void paintBitmapGL() const { };
virtual bool needsTexture() { return false; }
diff --git a/Source/WebCore/platform/graphics/android/MediaListener.h b/Source/WebCore/platform/graphics/android/MediaListener.h
index 5fcbbb2..2dfc08b 100644
--- a/Source/WebCore/platform/graphics/android/MediaListener.h
+++ b/Source/WebCore/platform/graphics/android/MediaListener.h
@@ -26,21 +26,6 @@
#include "MediaTexture.h"
#include "WebCoreJni.h"
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "MediaListener", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
class MediaListener : public android::SurfaceTexture::FrameAvailableListener {
diff --git a/Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
index 404ef08..535e7ae 100644
--- a/Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
+++ b/Source/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h
@@ -95,6 +95,7 @@ public:
virtual void onPosterFetched(SkBitmap*) { }
void onBuffering(int percent);
void onTimeupdate(int position);
+ void onRestoreState();
// These following two functions are used to turn on inline video support
bool supportsAcceleratedRendering() const { return true; }
diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.cpp b/Source/WebCore/platform/graphics/android/MediaTexture.cpp
index 1676186..faa20a1 100644
--- a/Source/WebCore/platform/graphics/android/MediaTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/MediaTexture.cpp
@@ -13,8 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#define LOG_TAG "MediaTexture"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "MediaTexture.h"
+
+#include "AndroidLog.h"
#include "TilesManager.h"
#include "GLUtils.h"
#include "MediaListener.h"
@@ -24,28 +30,9 @@
#include <android/native_window.h>
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
-#include <wtf/CurrentTime.h>
#include <JNIUtility.h>
#include "WebCoreJni.h"
-#define LAYER_DEBUG
-#undef LAYER_DEBUG
-
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "MediaTexture", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
// Limits the number of ANativeWindows that can be allocated for video playback.
// The limit is currently set to 2 as that is the current max number of
// simultaneous HW decodes that our OMX implementation allows. This forces the
@@ -54,14 +41,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;
@@ -76,10 +60,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()
@@ -111,16 +94,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);
}
@@ -171,7 +154,7 @@ void MediaTexture::draw(const TransformationMatrix& contentMatrix,
#ifdef DEBUG
if (!mediaBounds.contains(dimensions)) {
- XLOG("The video exceeds is parent's bounds.");
+ ALOGV("The video exceeds is parent's bounds.");
}
#endif // DEBUG
@@ -191,8 +174,7 @@ void MediaTexture::draw(const TransformationMatrix& contentMatrix,
bool forceAlphaBlending = !(
PIXEL_FORMAT_RGBX_8888 == f ||
PIXEL_FORMAT_RGB_888 == f ||
- PIXEL_FORMAT_RGB_565 == f ||
- PIXEL_FORMAT_RGB_332 == f);
+ PIXEL_FORMAT_RGB_565 == f);
TilesManager::instance()->shader()->drawLayerQuad(contentMatrix,
mediaBounds,
@@ -283,7 +265,6 @@ void MediaTexture::setDimensions(const ANativeWindow* window,
void MediaTexture::setFramerateCallback(const ANativeWindow* window,
FramerateCallbackProc callback)
{
- XLOG("Release ANW %p (%p):(%p)", this, m_surfaceTexture.get(), m_surfaceTextureClient.get());
android::Mutex::Autolock lock(m_mediaLock);
for (unsigned int i = 0; i < m_videoTextures.size(); i++) {
if (m_videoTextures[i]->nativeWindow.get() == window) {
diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.h b/Source/WebCore/platform/graphics/android/MediaTexture.h
index 97bb530..9ea7be2 100644
--- a/Source/WebCore/platform/graphics/android/MediaTexture.h
+++ b/Source/WebCore/platform/graphics/android/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/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
index 2d69706..4ae1f31 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
+++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
@@ -23,23 +23,30 @@
* 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 "ImageTexture.h"
#include "ImagesManager.h"
#include "LayerAndroid.h"
-#include "PaintedSurface.h"
+#include "TilesManager.h"
namespace WebCore {
-PaintTileOperation::PaintTileOperation(BaseTile* tile, SurfacePainter* surface)
- : QueuedOperation(QueuedOperation::PaintTile, tile->page())
- , m_tile(tile)
- , m_surface(surface)
+PaintTileOperation::PaintTileOperation(BaseTile* 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);
- SkSafeRef(m_surface);
+ SkSafeRef(m_painter);
}
PaintTileOperation::~PaintTileOperation()
@@ -49,18 +56,16 @@ PaintTileOperation::~PaintTileOperation()
m_tile = 0;
}
- if (m_surface && m_surface->type() == SurfacePainter::ImageSurface) {
- ImageTexture* image = static_cast<ImageTexture*>(m_surface);
+ if (m_painter && m_painter->type() == TilePainter::Image) {
+ ImageTexture* image = static_cast<ImageTexture*>(m_painter);
ImagesManager::instance()->releaseImage(image->imageCRC());
} else {
- SkSafeUnref(m_surface);
+ SkSafeUnref(m_painter);
}
}
bool PaintTileOperation::operator==(const QueuedOperation* operation)
{
- if (operation->type() != type())
- return false;
const PaintTileOperation* op = static_cast<const PaintTileOperation*>(operation);
return op->m_tile == m_tile;
}
@@ -68,7 +73,7 @@ bool PaintTileOperation::operator==(const QueuedOperation* operation)
void PaintTileOperation::run()
{
if (m_tile) {
- m_tile->paintBitmap();
+ m_tile->paintBitmap(m_painter);
m_tile->setRepaintPending(false);
m_tile = 0;
}
@@ -81,14 +86,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();
@@ -101,7 +101,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/PaintTileOperation.h
index bc74d03..afd2fc1 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h
+++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h
@@ -33,41 +33,40 @@
namespace WebCore {
class LayerAndroid;
-class SurfacePainter;
+class TilePainter;
class ImageTexture;
class PaintTileOperation : public QueuedOperation {
public:
- PaintTileOperation(BaseTile* tile, SurfacePainter* surface = 0);
+ PaintTileOperation(BaseTile* tile, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch);
virtual ~PaintTileOperation();
virtual bool operator==(const QueuedOperation* operation);
virtual void run();
// returns a rendering priority for m_tile, lower values are processed faster
virtual int priority();
- TilePainter* painter() { return m_tile->painter(); }
+ TilePainter* painter() { return m_painter; }
float scale() { return m_tile->scale(); }
private:
BaseTile* m_tile;
- SurfacePainter* m_surface;
+ TilePainter* m_painter;
+ GLWebViewState* m_state;
+ bool m_isLowResPrefetch;
};
class ScaleFilter : public OperationFilter {
public:
- ScaleFilter(TilePainter* painter, float scale)
+ ScaleFilter(const TilePainter* painter, float scale)
: m_painter(painter)
, m_scale(scale) {}
virtual bool check(QueuedOperation* operation)
{
- if (operation->type() == QueuedOperation::PaintTile) {
- PaintTileOperation* op = static_cast<PaintTileOperation*>(operation);
- if ((op->painter() == m_painter) && (op->scale() != m_scale))
- return true;
- }
- return false;
+ PaintTileOperation* op = static_cast<PaintTileOperation*>(operation);
+ return ((op->painter() == m_painter) && (op->scale() != m_scale));
}
private:
- TilePainter* m_painter;
+ const TilePainter* m_painter;
float m_scale;
};
@@ -77,12 +76,8 @@ public:
TilePainterFilter(TilePainter* painter) : m_painter(painter) {}
virtual bool check(QueuedOperation* operation)
{
- if (operation->type() == QueuedOperation::PaintTile) {
- PaintTileOperation* op = static_cast<PaintTileOperation*>(operation);
- if (op->painter() == m_painter)
- return true;
- }
- return false;
+ PaintTileOperation* op = static_cast<PaintTileOperation*>(operation);
+ return op->painter() == m_painter;
}
private:
TilePainter* m_painter;
diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp
deleted file mode 100644
index 45c7579..0000000
--- a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp
+++ /dev/null
@@ -1,224 +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.
- */
-
-#include "config.h"
-#include "PaintedSurface.h"
-
-
-#include "LayerAndroid.h"
-#include "TiledTexture.h"
-#include "TilesManager.h"
-#include "SkCanvas.h"
-#include "SkPicture.h"
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-// Layers with an area larger than 2048*2048 should never be unclipped
-#define MAX_UNCLIPPED_AREA 4194304
-
-namespace WebCore {
-
-PaintedSurface::PaintedSurface()
- : m_drawingLayer(0)
- , m_paintingLayer(0)
- , m_tiledTexture(0)
- , m_scale(0)
- , m_pictureUsed(0)
-{
- TilesManager::instance()->addPaintedSurface(this);
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("PaintedSurface");
-#endif
- m_tiledTexture = new DualTiledTexture(this);
-}
-
-PaintedSurface::~PaintedSurface()
-{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("PaintedSurface");
-#endif
- delete m_tiledTexture;
-}
-
-void PaintedSurface::prepare(GLWebViewState* state)
-{
- XLOG("PS %p has PL %p, DL %p", this, m_paintingLayer, m_drawingLayer);
- LayerAndroid* paintingLayer = m_paintingLayer;
- if (!paintingLayer)
- paintingLayer = m_drawingLayer;
-
- if (!paintingLayer)
- return;
-
- bool startFastSwap = false;
- if (state->isScrolling()) {
- // when scrolling, block updates and swap tiles as soon as they're ready
- startFastSwap = true;
- }
-
- XLOG("prepare layer %d %x at scale %.2f",
- paintingLayer->uniqueId(), paintingLayer,
- paintingLayer->getScale());
-
- IntRect visibleArea = computeVisibleArea(paintingLayer);
-
- m_scale = state->scale();
-
- // If we do not have text, we may as well limit ourselves to
- // a scale factor of one... this saves up textures.
- if (m_scale > 1 && !paintingLayer->hasText())
- m_scale = 1;
-
- m_tiledTexture->prepare(state, m_scale, m_pictureUsed != paintingLayer->pictureUsed(),
- startFastSwap, visibleArea);
-}
-
-bool PaintedSurface::draw()
-{
- if (!m_drawingLayer || !m_drawingLayer->needsTexture())
- return false;
-
- bool askRedraw = false;
- if (m_tiledTexture)
- askRedraw = m_tiledTexture->draw();
-
- return askRedraw;
-}
-
-void PaintedSurface::setPaintingLayer(LayerAndroid* layer, const SkRegion& dirtyArea)
-{
- m_paintingLayer = layer;
- if (m_tiledTexture)
- m_tiledTexture->update(dirtyArea, layer->picture());
-}
-
-bool PaintedSurface::isReady()
-{
- if (m_tiledTexture)
- return m_tiledTexture->isReady();
- return false;
-}
-
-void PaintedSurface::swapTiles()
-{
- if (m_tiledTexture)
- m_tiledTexture->swapTiles();
-}
-
-float PaintedSurface::opacity() {
- if (m_drawingLayer)
- return m_drawingLayer->drawOpacity();
- return 1.0;
-}
-
-const TransformationMatrix* PaintedSurface::transform() {
- // used exclusively for drawing, so only use m_drawingLayer
- if (!m_drawingLayer)
- return 0;
-
- return m_drawingLayer->drawTransform();
-}
-
-void PaintedSurface::computeTexturesAmount(TexturesResult* result)
-{
- if (!m_tiledTexture)
- return;
-
- // for now, always done on drawinglayer
- LayerAndroid* layer = m_drawingLayer;
-
- 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
- int nbTexturesUnclipped = m_tiledTexture->nbTextures(unclippedArea, m_scale);
- int nbTexturesClipped = m_tiledTexture->nbTextures(clippedVisibleArea, m_scale);
-
- // Set kFixedLayers level
- if (layer->isFixed())
- result->fixed += nbTexturesClipped;
-
- // Set kScrollableAndFixedLayers level
- if (layer->contentIsScrollable()
- || layer->isFixed())
- result->scrollable += nbTexturesClipped;
-
- // Set kClippedTextures level
- result->clipped += nbTexturesClipped;
-
- // Set kAllTextures level
- if (layer->contentIsScrollable())
- result->full += nbTexturesClipped;
- else
- result->full += nbTexturesUnclipped;
-}
-
-IntRect PaintedSurface::computeVisibleArea(LayerAndroid* layer) {
- IntRect area;
- if (!layer)
- return area;
-
- if (!layer->contentIsScrollable()
- && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
- area = layer->unclippedArea();
- double total = ((double) area.width()) * ((double) area.height());
- if (total > MAX_UNCLIPPED_AREA)
- area = layer->visibleArea();
- } else {
- area = layer->visibleArea();
- }
-
- return area;
-}
-
-bool PaintedSurface::owns(BaseTileTexture* texture)
-{
- if (m_tiledTexture)
- return m_tiledTexture->owns(texture);
- return false;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h
deleted file mode 100644
index b8ab7b8..0000000
--- a/Source/WebCore/platform/graphics/android/PaintedSurface.h
+++ /dev/null
@@ -1,94 +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 PaintedSurface_h
-#define PaintedSurface_h
-
-#include "BaseTileTexture.h"
-#include "ClassTracker.h"
-#include "IntRect.h"
-#include "LayerAndroid.h"
-#include "SkRefCnt.h"
-#include "TextureOwner.h"
-#include "TilesManager.h"
-#include "TilePainter.h"
-#include "TransformationMatrix.h"
-
-class SkCanvas;
-class SkRegion;
-
-namespace WebCore {
-
-class DualTiledTexture;
-
-class PaintedSurface : public SurfacePainter {
-public:
- PaintedSurface();
- virtual ~PaintedSurface();
-
- // PaintedSurface methods
-
- void prepare(GLWebViewState*);
- bool draw();
- bool paint(SkCanvas*);
-
- void setDrawingLayer(LayerAndroid* layer) { m_drawingLayer = layer; }
- LayerAndroid* drawingLayer() { return m_drawingLayer; }
-
- void setPaintingLayer(LayerAndroid* layer, const SkRegion& dirtyArea);
- void clearPaintingLayer() { m_paintingLayer = 0; }
- LayerAndroid* paintingLayer() { return m_paintingLayer; }
-
- void swapTiles();
- bool isReady();
-
- bool owns(BaseTileTexture* texture);
-
- void computeTexturesAmount(TexturesResult*);
- IntRect computeVisibleArea(LayerAndroid*);
-
- // TilePainter methods for TiledTexture
- virtual const TransformationMatrix* transform();
- virtual float opacity();
-
- // used by TiledTexture
- float scale() { return m_scale; }
- unsigned int pictureUsed() { return m_pictureUsed; }
-
-private:
- LayerAndroid* m_drawingLayer;
- LayerAndroid* m_paintingLayer;
- DualTiledTexture* m_tiledTexture;
-
- float m_scale;
-
- unsigned int m_pictureUsed;
-
- android::Mutex m_layerLock;
-};
-
-} // namespace WebCore
-
-#endif // PaintedSurface_h
diff --git a/Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp b/Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp
deleted file mode 100644
index 241cbef..0000000
--- a/Source/WebCore/platform/graphics/android/PerformanceMonitor.cpp
+++ /dev/null
@@ -1,104 +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.
- */
-
-#include "PerformanceMonitor.h"
-
-#include <wtf/text/CString.h>
-
-#include <wtf/CurrentTime.h>
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "PerformanceMonitor", __VA_ARGS__)
-
-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);
-
- float avg = 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) {
- XLOGC("=== DISPLAY MONITOR ====");
- shown = true;
- }
- XLOGC("item %s took longer than %d ms: %.2f", it->first.latin1().data(), limit, item->average_ms);
- }
- }
- if (shown)
- XLOGC("=== END DISPLAY MONITOR ====");
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp
new file mode 100644
index 0000000..4398146
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp
@@ -0,0 +1,106 @@
+#include "config.h"
+#include "PictureLayerContent.h"
+
+#include "InspectorCanvas.h"
+#include "SkPicture.h"
+
+namespace WebCore {
+
+PictureLayerContent::PictureLayerContent(SkPicture* picture)
+ : m_picture(picture)
+ , m_checkedContent(false)
+ , m_hasText(true)
+{
+ SkSafeRef(m_picture);
+}
+
+PictureLayerContent::PictureLayerContent(const PictureLayerContent& content)
+ : m_picture(content.m_picture)
+ , m_checkedContent(content.m_checkedContent)
+ , m_hasText(content.m_hasText)
+{
+ SkSafeRef(m_picture);
+}
+
+PictureLayerContent::~PictureLayerContent()
+{
+ SkSafeUnref(m_picture);
+}
+
+int PictureLayerContent::width()
+{
+ if (!m_picture)
+ return 0;
+ return m_picture->width();
+}
+
+int PictureLayerContent::height()
+{
+ if (!m_picture)
+ return 0;
+ return m_picture->height();
+}
+
+bool PictureLayerContent::isEmpty()
+{
+ if (!m_picture)
+ return true;
+ if (m_picture->width() == 0
+ || m_picture->height() == 0)
+ return true;
+ return false;
+}
+
+void PictureLayerContent::checkForOptimisations()
+{
+ if (!m_checkedContent)
+ hasText(); // for now only check the presence of text
+}
+
+bool PictureLayerContent::hasText()
+{
+ if (m_checkedContent)
+ return m_hasText;
+
+ // Let's check if we have text or not. If we don't, we can limit
+ // ourselves to scale 1!
+ InspectorBounder inspectorBounder;
+ InspectorCanvas checker(&inspectorBounder, m_picture);
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ m_picture->width(),
+ m_picture->height());
+ checker.setBitmapDevice(bitmap);
+ checker.drawPicture(*m_picture);
+ m_hasText = checker.hasText();
+ if (!checker.hasContent()) {
+ // no content to draw, discard picture so UI / tile generation
+ // doesn't bother with it
+ SkSafeUnref(m_picture);
+ m_picture = 0;
+ }
+
+ m_checkedContent = true;
+
+ return m_hasText;
+}
+
+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);
+}
+
+void PictureLayerContent::serialize(SkWStream* stream)
+{
+ if (!m_picture)
+ return;
+ m_picture->serialize(stream);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/PerformanceMonitor.h b/Source/WebCore/platform/graphics/android/PictureLayerContent.h
index 4ebbf6a..94bdfac 100644
--- a/Source/WebCore/platform/graphics/android/PerformanceMonitor.h
+++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, 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,37 +23,33 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PerformanceMonitor_h
-#define PerformanceMonitor_h
+#ifndef PictureLayerContent_h
+#define PictureLayerContent_h
-#include "config.h"
-
-#include <wtf/HashMap.h>
-#include <wtf/text/StringHash.h>
-#include <sys/time.h>
-#include <unistd.h>
+#include "LayerContent.h"
namespace WebCore {
-struct PerfItem {
- PerfItem() : average_ms(0), start_time() {}
- float average_ms;
- struct timeval start_time;
-};
-
-class PerformanceMonitor {
+class PictureLayerContent : public LayerContent {
public:
- PerformanceMonitor();
- virtual ~PerformanceMonitor();
- void start(const String &tag);
- void stop(const String &tag);
- float getAverageDuration(const String &tag);
- void display(int limit);
+ PictureLayerContent(SkPicture* picture);
+ PictureLayerContent(const PictureLayerContent& content);
+ ~PictureLayerContent();
+
+ virtual int width();
+ virtual int height();
+ virtual bool isEmpty();
+ virtual void checkForOptimisations();
+ virtual bool hasText();
+ virtual void draw(SkCanvas* canvas);
+ virtual void serialize(SkWStream* stream);
private:
- HashMap<String, PerfItem*, StringHash> m_tags;
+ SkPicture* m_picture;
+ bool m_checkedContent;
+ bool m_hasText;
};
-}
+} // WebCore
-#endif // PerformanceMonitor_h
+#endif // PictureLayerContent_h
diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp
new file mode 100644
index 0000000..8b72b0a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp
@@ -0,0 +1,41 @@
+#include "config.h"
+#include "PictureSetLayerContent.h"
+
+#include "SkCanvas.h"
+#include "SkPicture.h"
+
+namespace WebCore {
+
+PictureSetLayerContent::PictureSetLayerContent(const android::PictureSet& pictureSet)
+{
+ m_pictureSet.set(pictureSet);
+}
+
+PictureSetLayerContent::~PictureSetLayerContent()
+{
+ m_pictureSet.clear();
+}
+
+void PictureSetLayerContent::draw(SkCanvas* 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)
+{
+ if (!stream)
+ return;
+ SkPicture picture;
+ draw(picture.beginRecording(m_pictureSet.width(), m_pictureSet.height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag));
+ picture.endRecording();
+ picture.serialize(stream);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/DeleteTextureOperation.h b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h
index f3cb57c..61fc3f4 100644
--- a/Source/WebCore/platform/graphics/android/DeleteTextureOperation.h
+++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010, 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,39 +23,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DeleteTextureOperation_h
-#define DeleteTextureOperation_h
+#ifndef PictureSetLayerContent_h
+#define PictureSetLayerContent_h
-#include "GLUtils.h"
-#include "QueuedOperation.h"
+#include "LayerContent.h"
+#include "PictureSet.h"
namespace WebCore {
-class DeleteTextureOperation : public QueuedOperation {
+class PictureSetLayerContent : public LayerContent {
public:
- DeleteTextureOperation(GLuint textureId, EGLImageKHR eglImage)
- : QueuedOperation(QueuedOperation::DeleteTexture, 0)
- , m_textureId(textureId)
- , m_eglImage(eglImage) {}
- virtual bool operator==(const QueuedOperation* operation)
- {
- if (operation->type() != type())
- return false;
- const DeleteTextureOperation* op = static_cast<const DeleteTextureOperation*>(operation);
- return op->m_textureId == m_textureId;
- }
- virtual void run()
- {
- if (m_textureId)
- GLUtils::deleteTexture(&m_textureId);
- if (m_eglImage)
- eglDestroyImageKHR(eglGetCurrentDisplay(), m_eglImage);
- }
+ PictureSetLayerContent(const android::PictureSet& pictureSet);
+ ~PictureSetLayerContent();
+
+ virtual int width() { return m_pictureSet.width(); }
+ virtual int height() { return m_pictureSet.height(); }
+ virtual bool isEmpty() { return m_pictureSet.isEmpty(); }
+ virtual void checkForOptimisations() {}
+ virtual bool hasText() { return true; }
+ virtual void draw(SkCanvas* canvas);
+ virtual void serialize(SkWStream* stream);
+
private:
- GLuint m_textureId;
- EGLImageKHR m_eglImage;
+ android::PictureSet m_pictureSet;
};
-}
+} // WebCore
-#endif // DeleteTextureOperation_h
+#endif // PictureLayerContent_h
diff --git a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp
index 098534c..3c8ea3c 100644
--- a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.cpp
@@ -24,28 +24,1025 @@
*/
#include "config.h"
-#include "Node.h"
#include "PlatformGraphicsContext.h"
+
+#include "AffineTransform.h"
+#include "Font.h"
+#include "Gradient.h"
+#include "GraphicsContext.h"
+#include "Node.h"
+#include "NotImplemented.h"
+#include "Path.h"
+#include "Pattern.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"
namespace WebCore {
-PlatformGraphicsContext::PlatformGraphicsContext(SkCanvas* canvas)
- : mCanvas(canvas), m_deleteCanvas(false)
+// 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 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;
+}
+
+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);
+}
+
+//**************************************
+// State structs
+//**************************************
+
+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)
+ {};
+};
+
+struct PlatformGraphicsContext::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;
+ SkShader* fillShader;
+ SkColor strokeColor;
+ SkShader* strokeShader;
+ bool useAA;
+ StrokeStyle strokeStyle;
+
+ 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)
+ {
+ }
+
+ 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);
+ }
+
+ ~State()
+ {
+ SkSafeUnref(pathEffect);
+ SkSafeUnref(fillShader);
+ SkSafeUnref(strokeShader);
+ }
+
+ 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(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 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);
+ }
+
+ PlatformGraphicsContext::State cloneInheritedProperties();
+private:
+ // Not supported.
+ void operator=(const State&);
+};
+
+// Returns a new State with all of this object's inherited properties copied.
+PlatformGraphicsContext::State PlatformGraphicsContext::State::cloneInheritedProperties()
{
+ return PlatformGraphicsContext::State(*this);
}
-PlatformGraphicsContext::PlatformGraphicsContext()
- : mCanvas(new SkCanvas), m_deleteCanvas(true)
+//**************************************
+// PlatformGraphicsContext
+//**************************************
+
+PlatformGraphicsContext::PlatformGraphicsContext(SkCanvas* canvas,
+ bool takeCanvasOwnership)
+ : mCanvas(canvas)
+ , m_deleteCanvas(takeCanvasOwnership)
+ , m_stateStack(sizeof(State))
+ , m_gc(0)
{
+ m_stateStack.append(State());
+ m_state = &m_stateStack.last();
}
PlatformGraphicsContext::~PlatformGraphicsContext()
{
- if (m_deleteCanvas) {
-// printf("-------------------- deleting offscreen canvas\n");
+ if (m_deleteCanvas)
delete mCanvas;
+}
+
+//**************************************
+// State management
+//**************************************
+
+void PlatformGraphicsContext::beginTransparencyLayer(float opacity)
+{
+ SkCanvas* canvas = mCanvas;
+ canvas->saveLayerAlpha(0, (int)(opacity * 255), TRANSPARENCY_SAVEFLAGS);
+}
+
+void PlatformGraphicsContext::endTransparencyLayer()
+{
+ mCanvas->restore();
+}
+
+void PlatformGraphicsContext::save()
+{
+ m_stateStack.append(m_state->cloneInheritedProperties());
+ m_state = &m_stateStack.last();
+
+ // Save our native canvas.
+ mCanvas->save();
+}
+
+void PlatformGraphicsContext::restore()
+{
+ m_stateStack.removeLast();
+ m_state = &m_stateStack.last();
+
+ // Restore our native canvas.
+ mCanvas->restore();
+}
+
+//**************************************
+// 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:
+ SkDEBUGF(("PlatformGraphicsContext::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:
+ SkDEBUGF(("PlatformGraphicsContext::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;
+}
+
+//**************************************
+// Matrix operations
+//**************************************
+
+void PlatformGraphicsContext::concatCTM(const AffineTransform& affine)
+{
+ mCanvas->concat(affine);
+}
+
+void PlatformGraphicsContext::rotate(float angleInRadians)
+{
+ mCanvas->rotate(SkFloatToScalar(angleInRadians * (180.0f / 3.14159265f)));
+}
+
+void PlatformGraphicsContext::scale(const FloatSize& size)
+{
+ mCanvas->scale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
+}
+
+void PlatformGraphicsContext::translate(float x, float y)
+{
+ mCanvas->translate(SkFloatToScalar(x), SkFloatToScalar(y));
+}
+
+//**************************************
+// Clipping
+//**************************************
+
+void PlatformGraphicsContext::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 PlatformGraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
+void PlatformGraphicsContext::clip(const FloatRect& rect)
+{
+ mCanvas->clipRect(rect);
+}
+
+void PlatformGraphicsContext::clip(const Path& path)
+{
+ mCanvas->clipPath(*path.platformPath(), SkRegion::kIntersect_Op, true);
+}
+
+void PlatformGraphicsContext::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 PlatformGraphicsContext::clipOut(const IntRect& r)
+{
+ mCanvas->clipRect(r, SkRegion::kDifference_Op);
+}
+
+void PlatformGraphicsContext::clipOut(const Path& p)
+{
+ mCanvas->clipPath(*p.platformPath(), SkRegion::kDifference_Op);
+}
+
+void PlatformGraphicsContext::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 PlatformGraphicsContext::clearRect(const FloatRect& rect)
+{
+ SkPaint paint;
+
+ setupPaintFill(&paint);
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
+ mCanvas->drawRect(rect, paint);
+}
+
+//**************************************
+// Drawing
+//**************************************
+
+void PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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, 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);
+ }
+}
+
+void PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::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 PlatformGraphicsContext::fillRect(const FloatRect& rect)
+{
+ SkPaint paint;
+ setupPaintFill(&paint);
+ mCanvas->drawRect(rect, paint);
+}
+
+void PlatformGraphicsContext::fillRect(const FloatRect& rect,
+ const Color& color, ColorSpace)
+{
+ 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 PlatformGraphicsContext::fillRoundedRect(
+ const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
+ const IntSize& bottomLeft, const IntSize& bottomRight,
+ const Color& color, ColorSpace)
+{
+ 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 PlatformGraphicsContext::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 PlatformGraphicsContext::strokePath(const Path& pathToStroke)
+{
+ const SkPath* path = pathToStroke.platformPath();
+ if (!path)
+ return;
+
+ SkPaint paint;
+ setupPaintStroke(&paint, 0);
+
+ mCanvas->drawPath(*path, paint);
+}
+
+void PlatformGraphicsContext::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/PlatformGraphicsContext.h b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
index d22dbd8..ce126a4 100644
--- a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
+++ b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
@@ -27,31 +27,123 @@
#define platform_graphics_context_h
#include "IntRect.h"
+#include "GraphicsContext.h"
#include "RenderSkinAndroid.h"
-#include "RenderSkinButton.h"
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkTDArray.h"
+#include <wtf/Vector.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* canvas, bool takeCanvasOwnership = false);
~PlatformGraphicsContext();
-
+
+ void setGraphicsContext(GraphicsContext* gc) { m_gc = gc; }
+
+ // FIXME: Make mCanvas private
SkCanvas* mCanvas;
-
+ // FIXME: This is used by ImageBufferAndroid, which should really be
+ // managing the canvas lifecycle itself
bool deleteUs() const { return m_deleteCanvas; }
+
+ // State management
+ void beginTransparencyLayer(float opacity);
+ void endTransparencyLayer();
+ void save();
+ void restore();
+
+ // State values
+ void setAlpha(float alpha);
+ void setCompositeOperation(CompositeOperator op);
+ void setFillColor(const Color& c);
+ void setFillShader(SkShader* fillShader);
+ void setLineCap(LineCap cap);
+ void setLineDash(const DashArray& dashes, float dashOffset);
+ void setLineJoin(LineJoin join);
+ void setMiterLimit(float limit);
+ void setShadow(int radius, int dx, int dy, SkColor c);
+ void setShouldAntialias(bool useAA);
+ void setStrokeColor(const Color& c);
+ void setStrokeShader(SkShader* strokeShader);
+ void setStrokeStyle(StrokeStyle style);
+ void setStrokeThickness(float f);
+
+ // FIXME: These setupPaint* should be private, but
+ // they are used by FontAndroid currently
+ void setupPaintFill(SkPaint* paint) const;
+ 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.
+ bool setupPaintStroke(SkPaint* paint, SkRect* rect, bool isHLine = false);
+
+ // Matrix operations
+ void concatCTM(const AffineTransform& affine);
+ void rotate(float angleInRadians);
+ void scale(const FloatSize& size);
+ void translate(float x, float y);
+ const SkMatrix& getTotalMatrix() { return mCanvas->getTotalMatrix(); }
+
+ // Clipping
+ void addInnerRoundedRectClip(const IntRect& rect, int thickness);
+ void canvasClip(const Path& path);
+ void clip(const FloatRect& rect);
+ void clip(const Path& path);
+ void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+ void clipOut(const IntRect& r);
+ void clipOut(const Path& p);
+ void clipPath(const Path& pathToClip, WindRule clipRule);
+
+ // Drawing
+ void clearRect(const FloatRect& rect);
+ void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
+ CompositeOperator compositeOp, const FloatRect& destRect);
+ void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, CompositeOperator op);
+ void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
+ bool shouldAntialias);
+ void drawEllipse(const IntRect& rect);
+ void drawFocusRing(const Vector<IntRect>& rects, int /* width */,
+ int /* offset */, const Color& color);
+ void drawHighlightForText(const Font& font, const TextRun& run,
+ const FloatPoint& point, int h,
+ const Color& backgroundColor, ColorSpace colorSpace,
+ int from, int to, bool isActive);
+ void drawLine(const IntPoint& point1, const IntPoint& point2);
+ void drawLineForText(const FloatPoint& pt, float width);
+ void drawLineForTextChecking(const FloatPoint& pt, float width,
+ GraphicsContext::TextCheckingLineStyle);
+ void drawRect(const IntRect& rect);
+ void fillPath(const Path& pathToFill, WindRule fillRule);
+ void fillRect(const FloatRect& rect);
+ void fillRect(const FloatRect& rect, const Color& color, ColorSpace);
+ void fillRoundedRect(const IntRect& rect, const IntSize& topLeft,
+ const IntSize& topRight, const IntSize& bottomLeft,
+ const IntSize& bottomRight, const Color& color,
+ ColorSpace);
+ void strokeArc(const IntRect& r, int startAngle, int angleSpan);
+ void strokePath(const Path& pathToStroke);
+ void strokeRect(const FloatRect& rect, float lineWidth);
+
private:
- bool m_deleteCanvas;
+
+ // shadowsIgnoreTransforms is only true for canvas's ImageBuffer, which will
+ // have a GraphicsContext
+ bool shadowsIgnoreTransforms() const {
+ return m_gc && m_gc->shadowsIgnoreTransforms();
+ }
+
+ void setupPaintCommon(SkPaint* paint) const;
+
+ bool m_deleteCanvas;
+ struct State;
+ WTF::Vector<State> m_stateStack;
+ State* m_state;
+ GraphicsContext* m_gc; // Back-ptr to our parent
};
}
diff --git a/Source/WebCore/platform/graphics/android/QueuedOperation.h b/Source/WebCore/platform/graphics/android/QueuedOperation.h
index 1a83f65..f98efcd 100644
--- a/Source/WebCore/platform/graphics/android/QueuedOperation.h
+++ b/Source/WebCore/platform/graphics/android/QueuedOperation.h
@@ -28,23 +28,12 @@
namespace WebCore {
-class TiledPage;
-
class QueuedOperation {
public:
- enum OperationType { Undefined, PaintTile, PaintLayer, DeleteTexture };
- QueuedOperation(OperationType type, TiledPage* page)
- : m_type(type)
- , m_page(page) {}
virtual ~QueuedOperation() {}
virtual void run() = 0;
virtual bool operator==(const QueuedOperation* operation) = 0;
- virtual int priority() { return -1; }
- OperationType type() const { return m_type; }
- TiledPage* page() const { return m_page; }
-private:
- OperationType m_type;
- TiledPage* m_page;
+ virtual int priority() = 0;
};
class OperationFilter {
@@ -53,33 +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;
-};
-
-class PagePaintFilter : public OperationFilter {
-public:
- PagePaintFilter(TiledPage* page) : m_page(page) {}
- virtual bool check(QueuedOperation* operation)
- {
- if (operation->type() == QueuedOperation::PaintTile
- && 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/RasterRenderer.cpp
index 0c92de4..a012c8b 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
@@ -23,12 +23,15 @@
* 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"
@@ -36,35 +39,8 @@
#include "SkDevice.h"
#include "TilesManager.h"
-#include <wtf/text/CString.h>
-
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "RasterRenderer", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
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)
@@ -90,51 +66,47 @@ 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(NULL, *g_bitmap, false);
-
- if (renderInfo.measurePerf) {
- m_perfMon.stop(TAG_CREATE_BITMAP);
- m_perfMon.start(TAG_DRAW_PICTURE);
- }
+ SkDevice* device = new SkDevice(*g_bitmap);
canvas->setDevice(device);
device->unref();
- // ensure the canvas origin is translated to the coordinates of our inval rect
- canvas->translate(-renderInfo.invalRect->fLeft, -renderInfo.invalRect->fTop);
+ // If we have a partially painted bitmap
+ if (renderInfo.invalRect) {
+ SkRect clipRect = SkRect::MakeWH(renderInfo.invalRect->width(),
+ renderInfo.invalRect->height());
+ // ensure the canvas origin is translated to the coordinates of our inval rect
+ canvas->clipRect(clipRect);
+ canvas->translate(-renderInfo.invalRect->fLeft, -renderInfo.invalRect->fTop);
+ }
}
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/RasterRenderer.h
index 96b3f58..39e00f2 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.h
+++ b/Source/WebCore/platform/graphics/android/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/ScrollableLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
index 3c2ced5..f28c31d 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
@@ -1,3 +1,6 @@
+#define LOG_TAG "ScrollableLayerAndroid"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "ScrollableLayerAndroid.h"
@@ -5,31 +8,40 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
+
namespace WebCore {
bool ScrollableLayerAndroid::scrollTo(int x, int y)
{
- SkIRect scrollBounds;
- getScrollRect(&scrollBounds);
- if (!scrollBounds.fRight && !scrollBounds.fBottom)
+ IntRect scrollBounds;
+ getScrollBounds(&scrollBounds);
+ if (!scrollBounds.width() && !scrollBounds.height())
return false;
-
- SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight);
- SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom);
+ SkScalar newX = SkScalarPin(x, scrollBounds.x(), scrollBounds.width());
+ SkScalar newY = SkScalarPin(y, scrollBounds.y(), scrollBounds.height());
// Check for no change.
- if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop)
+ if (newX == m_offset.x() && newY == m_offset.y())
return false;
-
- setPosition(m_scrollLimits.fLeft - newX, m_scrollLimits.fTop - newY);
-
+ setScrollOffset(IntPoint(newX, newY));
return true;
}
+void ScrollableLayerAndroid::getScrollBounds(IntRect* out) const
+{
+ const SkPoint& pos = getPosition();
+ out->setX(m_scrollLimits.fLeft - pos.fX);
+ out->setY(m_scrollLimits.fTop - pos.fY);
+ out->setWidth(getSize().width() - m_scrollLimits.width());
+ out->setHeight(getSize().height() - m_scrollLimits.height());
+}
+
void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const
{
const SkPoint& pos = getPosition();
- out->fLeft = m_scrollLimits.fLeft - pos.fX;
- out->fTop = m_scrollLimits.fTop - pos.fY;
+ out->fLeft = m_scrollLimits.fLeft - pos.fX + m_offset.x();
+ out->fTop = m_scrollLimits.fTop - pos.fY + m_offset.y();
+
out->fRight = getSize().width() - m_scrollLimits.width();
out->fBottom = getSize().height() - m_scrollLimits.height();
}
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
index 5cba5d9..1f289e6 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
@@ -41,19 +41,20 @@ public:
virtual bool contentIsScrollable() const { return true; }
virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); }
+ virtual SubclassType subclassType() { return LayerAndroid::ScrollableLayer; }
virtual bool updateWithLayer(LayerAndroid*) { return true; }
// Scrolls to the given position in the layer.
// Returns whether or not any scrolling was required.
- bool scrollTo(int x, int y);
+ virtual bool scrollTo(int x, int y);
// Fills the rect with the current scroll offset and the maximum scroll offset.
// fLeft = scrollX
// fTop = scrollY
// fRight = maxScrollX
// fBottom = maxScrollY
- void getScrollRect(SkIRect*) const;
+ virtual void getScrollRect(SkIRect*) const;
void setScrollLimits(float x, float y, float width, float height)
{
@@ -68,9 +69,12 @@ public:
bool scrollRectIntoView(const SkIRect&);
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
- friend LayerAndroid* android::deserializeLayer(SkStream* stream);
+ friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
+
+protected:
+
+ void getScrollBounds(IntRect*) const;
-private:
// The position of the visible area of the layer, relative to the parent
// layer. This is fixed during scrolling. We acheive scrolling by modifying
// the position of the layer.
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
index 2a6a488..257e68f 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -23,23 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "ShaderProgram"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "ShaderProgram.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "FloatPoint3D.h"
#include "GLUtils.h"
#include "TilesManager.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ShaderProgram", __VA_ARGS__)
namespace WebCore {
@@ -62,6 +60,26 @@ static const char gFragmentShader[] =
" gl_FragColor *= alpha; "
"}\n";
+// We could pass the pureColor into either Vertex or Frag Shader.
+// The reason we passed the color into the Vertex Shader is that some driver
+// might create redundant copy when uniforms in fragment shader changed.
+static const char gPureColorVertexShader[] =
+ "attribute vec4 vPosition;\n"
+ "uniform mat4 projectionMatrix;\n"
+ "uniform vec4 inputColor;\n"
+ "varying vec4 v_color;\n"
+ "void main() {\n"
+ " gl_Position = projectionMatrix * vPosition;\n"
+ " v_color = inputColor;\n"
+ "}\n";
+
+static const char gPureColorFragmentShader[] =
+ "precision mediump float;\n"
+ "varying vec4 v_color;\n"
+ "void main() {\n"
+ " gl_FragColor = v_color;\n"
+ "}\n";
+
static const char gFragmentShaderInverted[] =
"precision mediump float;\n"
"varying vec2 v_texCoord; \n"
@@ -140,7 +158,7 @@ GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource)
char* buf = (char*) malloc(infoLen);
if (buf) {
glGetShaderInfoLog(shader, infoLen, 0, buf);
- XLOG("could not compile shader %d:\n%s\n", shaderType, buf);
+ ALOGE("could not compile shader %d:\n%s\n", shaderType, buf);
free(buf);
}
glDeleteShader(shader);
@@ -151,17 +169,17 @@ GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource)
return shader;
}
-GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource)
+GLint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource)
{
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
if (!vertexShader) {
- XLOG("couldn't load the vertex shader!");
+ ALOGE("couldn't load the vertex shader!");
return -1;
}
GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader) {
- XLOG("couldn't load the pixel shader!");
+ ALOGE("couldn't load the pixel shader!");
return -1;
}
@@ -181,7 +199,7 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag
char* buf = (char*) malloc(bufLength);
if (buf) {
glGetProgramInfoLog(program, bufLength, 0, buf);
- XLOG("could not link program:\n%s\n", buf);
+ ALOGE("could not link program:\n%s\n", buf);
free(buf);
}
}
@@ -189,6 +207,9 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag
program = -1;
}
}
+
+ ShaderResource newResource(program, vertexShader, pixelShader);
+ m_resources.append(newResource);
return program;
}
@@ -197,57 +218,101 @@ ShaderProgram::ShaderProgram()
, m_contrast(1)
, m_alphaLayer(false)
, m_currentScale(1.0f)
+ , m_needsInit(true)
{
- init();
}
-void ShaderProgram::init()
+void ShaderProgram::cleanupGLResources()
{
- m_program = createProgram(gVertexShader, gFragmentShader);
- m_programInverted = createProgram(gVertexShader, gFragmentShaderInverted);
- m_videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader);
- m_surfTexOESProgram =
+ for (unsigned int i = 0; i < m_resources.size(); i++) {
+ glDetachShader(m_resources[i].program, m_resources[i].vertexShader);
+ glDetachShader(m_resources[i].program, m_resources[i].fragmentShader);
+ glDeleteShader(m_resources[i].vertexShader);
+ glDeleteShader(m_resources[i].fragmentShader);
+ glDeleteProgram(m_resources[i].program);
+ }
+ glDeleteBuffers(1, m_textureBuffer);
+
+ m_resources.clear();
+ m_needsInit = true;
+ GLUtils::checkGlError("cleanupGLResources");
+
+ return;
+}
+
+void ShaderProgram::initGLResources()
+{
+ // To detect whether or not resources for ShaderProgram allocated
+ // successfully, we clean up pre-existing errors here and will check for
+ // new errors at the end of this function.
+ GLUtils::checkGlError("before initGLResources");
+
+ GLint tex2DProgram = createProgram(gVertexShader, gFragmentShader);
+ GLint pureColorProgram = createProgram(gPureColorVertexShader, gPureColorFragmentShader);
+ GLint tex2DInvProgram = createProgram(gVertexShader, gFragmentShaderInverted);
+ GLint videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader);
+ GLint texOESProgram =
createProgram(gVertexShader, gSurfaceTextureOESFragmentShader);
- m_surfTexOESProgramInverted =
+ GLint texOESInvProgram =
createProgram(gVertexShader, gSurfaceTextureOESFragmentShaderInverted);
- if (m_program == -1
- || m_programInverted == -1
- || m_videoProgram == -1
- || m_surfTexOESProgram == -1
- || m_surfTexOESProgramInverted == -1)
+ if (tex2DProgram == -1
+ || pureColorProgram == -1
+ || tex2DInvProgram == -1
+ || videoProgram == -1
+ || texOESProgram == -1
+ || texOESInvProgram == -1) {
+ m_needsInit = true;
return;
+ }
- m_hProjectionMatrix = glGetUniformLocation(m_program, "projectionMatrix");
- m_hAlpha = glGetUniformLocation(m_program, "alpha");
- m_hTexSampler = glGetUniformLocation(m_program, "s_texture");
- m_hPosition = glGetAttribLocation(m_program, "vPosition");
-
- m_hProjectionMatrixInverted = glGetUniformLocation(m_programInverted, "projectionMatrix");
- m_hAlphaInverted = glGetUniformLocation(m_programInverted, "alpha");
- m_hContrastInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "contrast");
- m_hTexSamplerInverted = glGetUniformLocation(m_programInverted, "s_texture");
- m_hPositionInverted = glGetAttribLocation(m_programInverted, "vPosition");
-
- m_hVideoProjectionMatrix =
- glGetUniformLocation(m_videoProgram, "projectionMatrix");
- m_hVideoTextureMatrix = glGetUniformLocation(m_videoProgram, "textureMatrix");
- m_hVideoTexSampler = glGetUniformLocation(m_videoProgram, "s_yuvTexture");
- m_hVideoPosition = glGetAttribLocation(m_program, "vPosition");
-
- m_hSTOESProjectionMatrix =
- glGetUniformLocation(m_surfTexOESProgram, "projectionMatrix");
- m_hSTOESAlpha = glGetUniformLocation(m_surfTexOESProgram, "alpha");
- m_hSTOESTexSampler = glGetUniformLocation(m_surfTexOESProgram, "s_texture");
- m_hSTOESPosition = glGetAttribLocation(m_surfTexOESProgram, "vPosition");
-
- m_hSTOESProjectionMatrixInverted =
- glGetUniformLocation(m_surfTexOESProgramInverted, "projectionMatrix");
- m_hSTOESAlphaInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "alpha");
- m_hSTOESContrastInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "contrast");
- m_hSTOESTexSamplerInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "s_texture");
- m_hSTOESPositionInverted = glGetAttribLocation(m_surfTexOESProgramInverted, "vPosition");
-
+ GLint pureColorPosition = glGetAttribLocation(pureColorProgram, "vPosition");
+ GLint pureColorProjMtx = glGetUniformLocation(pureColorProgram, "projectionMatrix");
+ GLint pureColorValue = glGetUniformLocation(pureColorProgram, "inputColor");
+ m_handleArray[PureColor].init(-1, -1, pureColorPosition, pureColorProgram,
+ pureColorProjMtx, pureColorValue, -1, -1);
+
+ GLint tex2DAlpha = glGetUniformLocation(tex2DProgram, "alpha");
+ GLint tex2DPosition = glGetAttribLocation(tex2DProgram, "vPosition");
+ GLint tex2DProjMtx = glGetUniformLocation(tex2DProgram, "projectionMatrix");
+ GLint tex2DTexSampler = glGetUniformLocation(tex2DProgram, "s_texture");
+ m_handleArray[Tex2D].init(tex2DAlpha, -1, tex2DPosition, tex2DProgram,
+ tex2DProjMtx, -1, tex2DTexSampler, -1);
+
+ GLint tex2DInvAlpha = glGetUniformLocation(tex2DInvProgram, "alpha");
+ GLint tex2DInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
+ GLint tex2DInvPosition = glGetAttribLocation(tex2DInvProgram, "vPosition");
+ GLint tex2DInvProjMtx = glGetUniformLocation(tex2DInvProgram, "projectionMatrix");
+ GLint tex2DInvTexSampler = glGetUniformLocation(tex2DInvProgram, "s_texture");
+ m_handleArray[Tex2DInv].init(tex2DInvAlpha, tex2DInvContrast,
+ tex2DInvPosition, tex2DInvProgram,
+ tex2DInvProjMtx, -1,
+ tex2DInvTexSampler, -1);
+
+ GLint texOESAlpha = glGetUniformLocation(texOESProgram, "alpha");
+ GLint texOESPosition = glGetAttribLocation(texOESProgram, "vPosition");
+ GLint texOESProjMtx = glGetUniformLocation(texOESProgram, "projectionMatrix");
+ GLint texOESTexSampler = glGetUniformLocation(texOESProgram, "s_texture");
+ m_handleArray[TexOES].init(texOESAlpha, -1, texOESPosition, texOESProgram,
+ texOESProjMtx, -1, texOESTexSampler, -1);
+
+ GLint texOESInvAlpha = glGetUniformLocation(texOESInvProgram, "alpha");
+ GLint texOESInvContrast = glGetUniformLocation(texOESInvProgram, "contrast");
+ GLint texOESInvPosition = glGetAttribLocation(texOESInvProgram, "vPosition");
+ GLint texOESInvProjMtx = glGetUniformLocation(texOESInvProgram, "projectionMatrix");
+ GLint texOESInvTexSampler = glGetUniformLocation(texOESInvProgram, "s_texture");
+ m_handleArray[TexOESInv].init(texOESInvAlpha, texOESInvContrast,
+ texOESInvPosition, texOESInvProgram,
+ texOESInvProjMtx, -1,
+ texOESInvTexSampler, -1);
+
+ GLint videoPosition = glGetAttribLocation(videoProgram, "vPosition");
+ GLint videoProjMtx = glGetUniformLocation(videoProgram, "projectionMatrix");
+ GLint videoTexSampler = glGetUniformLocation(videoProgram, "s_yuvTexture");
+ GLint videoTexMtx = glGetUniformLocation(videoProgram, "textureMatrix");
+ m_handleArray[Video].init(-1, -1, videoPosition, videoProgram,
+ videoProjMtx, -1, videoTexSampler,
+ videoTexMtx);
const GLfloat coord[] = {
0.0f, 0.0f, // C
@@ -260,7 +325,14 @@ void ShaderProgram::init()
glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW);
- GLUtils::checkGlError("init");
+ TransformationMatrix matrix;
+ // Map x,y from (0,1) to (-1, 1)
+ matrix.scale3d(2, 2, 1);
+ matrix.translate3d(-0.5, -0.5, 0);
+ GLUtils::toGLMatrix(m_transferProjMtx, matrix);
+
+ m_needsInit = GLUtils::checkGlError("initGLResources");
+ return;
}
void ShaderProgram::resetBlending()
@@ -288,17 +360,71 @@ void ShaderProgram::setBlendingState(bool enableBlending)
// Drawing
/////////////////////////////////////////////////////////////////////////////////////////
-void ShaderProgram::setViewport(SkRect& viewport, float scale)
+void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
+ const IntRect& webViewRect, int titleBarHeight,
+ const IntRect& screenClip, float scale)
{
+ m_webViewRect = webViewRect;
+ m_titleBarHeight = titleBarHeight;
+
+ //// viewport ////
TransformationMatrix ortho;
- GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop,
- viewport.fRight, viewport.fBottom, -1000, 1000);
- m_projectionMatrix = ortho;
- m_viewport = viewport;
+ GLUtils::setOrthographicMatrix(ortho, visibleRect.fLeft, visibleRect.fTop,
+ visibleRect.fRight, visibleRect.fBottom, -1000, 1000);
+ // In most case , visibleRect / viewRect * scale should 1.0, but for the
+ // translation case, the scale factor can be 1 but visibleRect is smaller
+ // than viewRect, we need to tune in this factor to make sure we scale them
+ // right. Conceptually, that means, no matter how animation affects the
+ // visibleRect, the scaling should respect the viewRect if zoomScale is 1.0.
+ // Note that at TiledPage, we already scale the tile size inversely to make
+ // zooming animation right.
+ float orthoScaleX = scale * visibleRect.width() / viewRect.width();
+ float orthoScaleY = scale * visibleRect.height() / viewRect.height();
+
+ TransformationMatrix orthoScale;
+ orthoScale.scale3d(orthoScaleX, orthoScaleY, 1.0);
+
+ m_projectionMatrix = ortho * orthoScale;
+ m_viewport = visibleRect;
m_currentScale = scale;
+
+
+ //// viewRect ////
+ m_viewRect = viewRect;
+
+ // We do clipping using glScissor, which needs to take
+ // coordinates in screen space. The following matrix transform
+ // content coordinates in screen coordinates.
+ TransformationMatrix viewTranslate;
+ viewTranslate.translate(1.0, 1.0);
+
+ TransformationMatrix viewScale;
+ viewScale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
+
+ m_documentToScreenMatrix = viewScale * viewTranslate * m_projectionMatrix;
+
+ viewTranslate.scale3d(1, -1, 1);
+ m_documentToInvScreenMatrix = viewScale * viewTranslate * m_projectionMatrix;
+
+ IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height());
+ m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect);
+
+
+ //// clipping ////
+ IntRect mclip = screenClip;
+
+ // the clip from frameworks is in full screen coordinates
+ mclip.setY(screenClip.y() - m_webViewRect.y() - m_titleBarHeight);
+ FloatRect tclip = convertInvScreenCoordToScreenCoord(mclip);
+ m_screenClip.setLocation(IntPoint(tclip.x(), tclip.y()));
+ // use ceilf to handle view -> doc -> view coord rounding errors
+ m_screenClip.setSize(IntSize(ceilf(tclip.width()), ceilf(tclip.height())));
+
+ resetBlending();
}
-void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrixHandle)
+// Calculate the matrix given the geometry.
+void ShaderProgram::setProjectionMatrix(const SkRect& geometry, GLfloat* mtxPtr)
{
TransformationMatrix translate;
translate.translate3d(geometry.fLeft, geometry.fTop, 0.0);
@@ -312,113 +438,75 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrix
else
total = m_projectionMatrix * translate * scale;
- GLfloat projectionMatrix[16];
- GLUtils::toGLMatrix(projectionMatrix, total);
- glUniformMatrix4fv(projectionMatrixHandle, 1, GL_FALSE, projectionMatrix);
+ GLUtils::toGLMatrix(mtxPtr, total);
}
-void ShaderProgram::drawQuadInternal(SkRect& geometry,
- GLint textureId,
- float opacity,
- GLint program,
- GLint projectionMatrixHandle,
- GLint texSampler,
- GLenum textureTarget,
- GLint position,
- GLint alpha,
- GLint texFilter,
- GLint contrast)
+// Calculate the right color value sent into the shader considering the (0,1)
+// clamp and alpha blending.
+Color ShaderProgram::shaderColor(Color pureColor, float opacity)
{
- glUseProgram(program);
-
- if (!geometry.isEmpty())
- setProjectionMatrix(geometry, projectionMatrixHandle);
- else {
- TransformationMatrix matrix;
- // Map x,y from (0,1) to (-1, 1)
- matrix.scale3d(2, 2, 1);
- matrix.translate3d(-0.5, -0.5, 0);
- GLfloat projectionMatrix[16];
- GLUtils::toGLMatrix(projectionMatrix, matrix);
- glUniformMatrix4fv(projectionMatrixHandle, 1, GL_FALSE, projectionMatrix);
+ float r = pureColor.red() / 255.0;
+ float g = pureColor.green() / 255.0;
+ float b = pureColor.blue() / 255.0;
+ float a = pureColor.alpha() / 255.0;
+
+ if (TilesManager::instance()->invertedScreen()) {
+ float intensity = a - (0.2989 * r + 0.5866 * g + 0.1145 * b);
+ intensity = ((intensity - a / 2.0) * m_contrast) + a / 2.0;
+ intensity *= opacity;
+ return Color(intensity, intensity, intensity, a * opacity);
}
-
- glActiveTexture(GL_TEXTURE0);
- glUniform1i(texSampler, 0);
- glBindTexture(textureTarget, textureId);
- glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, texFilter);
- glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, texFilter);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
- glEnableVertexAttribArray(position);
- glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glUniform1f(alpha, opacity);
- if (contrast != -1)
- glUniform1f(contrast, m_contrast);
-
- setBlendingState(opacity < 1.0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ return Color(r * opacity, g * opacity, b * opacity, a * opacity);
}
-void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity,
- GLenum textureTarget, GLint texFilter)
+// For shaders using texture, it is easy to get the type from the textureTarget.
+ShaderType ShaderProgram::getTextureShaderType(GLenum textureTarget)
{
+ ShaderType type = UndefinedShader;
if (textureTarget == GL_TEXTURE_2D) {
- if (!TilesManager::instance()->invertedScreen()) {
- drawQuadInternal(geometry, textureId, opacity, m_program,
- m_hProjectionMatrix,
- m_hTexSampler, GL_TEXTURE_2D,
- m_hPosition, m_hAlpha, texFilter);
- } else {
+ if (!TilesManager::instance()->invertedScreen())
+ type = Tex2D;
+ else {
// With the new GPU texture upload path, we do not use an FBO
// to blit the texture we receive from the TexturesGenerator thread.
// To implement inverted rendering, we thus have to do the rendering
// live, by using a different shader.
- drawQuadInternal(geometry, textureId, opacity, m_programInverted,
- m_hProjectionMatrixInverted,
- m_hTexSamplerInverted, GL_TEXTURE_2D,
- m_hPositionInverted, m_hAlphaInverted, texFilter,
- m_hContrastInverted);
+ type = Tex2DInv;
}
- } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
- && !TilesManager::instance()->invertedScreen()) {
- drawQuadInternal(geometry, textureId, opacity, m_surfTexOESProgram,
- m_hSTOESProjectionMatrix,
- m_hSTOESTexSampler, GL_TEXTURE_EXTERNAL_OES,
- m_hSTOESPosition, m_hSTOESAlpha, texFilter);
- } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
- && TilesManager::instance()->invertedScreen()) {
- drawQuadInternal(geometry, textureId, opacity, m_surfTexOESProgramInverted,
- m_hSTOESProjectionMatrixInverted,
- m_hSTOESTexSamplerInverted, GL_TEXTURE_EXTERNAL_OES,
- m_hSTOESPositionInverted, m_hSTOESAlphaInverted,
- texFilter, m_hSTOESContrastInverted);
+ } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) {
+ if (!TilesManager::instance()->invertedScreen())
+ type = TexOES;
+ else
+ type = TexOESInv;
}
- GLUtils::checkGlError("drawQuad");
+ return type;
}
-void ShaderProgram::setViewRect(const IntRect& viewRect)
+void ShaderProgram::drawQuad(const SkRect& geometry, int textureId, float opacity,
+ Color pureColor, GLenum textureTarget, GLint texFilter)
{
- m_viewRect = viewRect;
-
- // We do clipping using glScissor, which needs to take
- // coordinates in screen space. The following matrix transform
- // content coordinates in screen coordinates.
- TransformationMatrix translate;
- translate.translate(1.0, 1.0);
-
- TransformationMatrix scale;
- scale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
-
- m_documentToScreenMatrix = scale * translate * m_projectionMatrix;
-
- translate.scale3d(1, -1, 1);
- m_documentToInvScreenMatrix = scale * translate * m_projectionMatrix;
-
- IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height());
- m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect);
+ 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 || pureColor.hasAlpha());
+ drawQuadInternal(type, finalMatrix, textureId, opacity, textureTarget,
+ texFilter, pureColor);
+ }
+ GLUtils::checkGlError("drawQuad");
}
// This function transform a clip rect extracted from the current layer
@@ -465,24 +553,15 @@ FloatRect ShaderProgram::convertScreenCoordToInvScreenCoord(const FloatRect& rec
return rectInInvScreenCoord(documentRect);
}
-void ShaderProgram::setScreenClip(const IntRect& clip)
-{
- m_screenClip = clip;
- IntRect mclip = clip;
-
- // the clip from frameworks is in full screen coordinates
- mclip.setY(clip.y() - m_webViewRect.y() - m_titleBarHeight);
- FloatRect tclip = convertInvScreenCoordToScreenCoord(mclip);
- IntRect screenClip(tclip.x(), tclip.y(), tclip.width(), tclip.height());
- m_screenClip = screenClip;
-}
-
// clip is in screen coordinates
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.
@@ -530,40 +609,45 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo
return result.z();
}
-void ShaderProgram::drawLayerQuadInternal(const GLfloat* projectionMatrix,
- int textureId, float opacity,
- GLenum textureTarget, GLint program,
- GLint matrix, GLint texSample,
- GLint position, GLint alpha,
- GLint contrast)
+void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
+ int textureId, float opacity,
+ GLenum textureTarget, GLenum filter,
+ const Color& pureColor)
{
- glUseProgram(program);
- glUniformMatrix4fv(matrix, 1, GL_FALSE, projectionMatrix);
-
- glActiveTexture(GL_TEXTURE0);
- glUniform1i(texSample, 0);
- glBindTexture(textureTarget, textureId);
- glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
+ glUseProgram(m_handleArray[type].programHandle);
+ glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix);
+
+ if (type != PureColor) {
+ glActiveTexture(GL_TEXTURE0);
+ glUniform1i(m_handleArray[type].texSamplerHandle, 0);
+ glBindTexture(textureTarget, textureId);
+ glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, filter);
+ glUniform1f(m_handleArray[type].alphaHandle, opacity);
+
+ GLint contrastHandle = m_handleArray[type].contrastHandle;
+ if (contrastHandle != -1)
+ glUniform1f(contrastHandle, m_contrast);
+ } else {
+ glUniform4f(m_handleArray[type].pureColorHandle,
+ pureColor.red() / 255.0, pureColor.green() / 255.0,
+ pureColor.blue() / 255.0, pureColor.alpha() / 255.0);
+ }
+ GLint positionHandle = m_handleArray[type].positionHandle;
glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
- glEnableVertexAttribArray(position);
- glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glUniform1f(alpha, opacity);
- if (contrast != -1)
- glUniform1f(contrast, m_contrast);
-}
+ glEnableVertexAttribArray(positionHandle);
+ glVertexAttribPointer(positionHandle, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+}
void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
const SkRect& geometry, int textureId,
float opacity, bool forceBlending,
- GLenum textureTarget)
+ GLenum textureTarget,
+ Color pureColor)
{
-
TransformationMatrix modifiedDrawMatrix = drawMatrix;
// move the drawing depending on where the texture is on the layer
modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
@@ -578,37 +662,23 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
- if (textureTarget == GL_TEXTURE_2D) {
- if (!TilesManager::instance()->invertedScreen()) {
- drawLayerQuadInternal(projectionMatrix, textureId, opacity,
- GL_TEXTURE_2D, m_program,
- m_hProjectionMatrix, m_hTexSampler,
- m_hPosition, m_hAlpha);
- } else {
- drawLayerQuadInternal(projectionMatrix, textureId, opacity,
- GL_TEXTURE_2D, m_programInverted,
- m_hProjectionMatrixInverted, m_hTexSamplerInverted,
- m_hPositionInverted, m_hAlphaInverted,
- m_hContrastInverted);
- }
- } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
- && !TilesManager::instance()->invertedScreen()) {
- drawLayerQuadInternal(projectionMatrix, textureId, opacity,
- GL_TEXTURE_EXTERNAL_OES, m_surfTexOESProgram,
- m_hSTOESProjectionMatrix, m_hSTOESTexSampler,
- m_hSTOESPosition, m_hSTOESAlpha);
- } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
- && TilesManager::instance()->invertedScreen()) {
- drawLayerQuadInternal(projectionMatrix, textureId, opacity,
- GL_TEXTURE_EXTERNAL_OES, m_surfTexOESProgramInverted,
- m_hSTOESProjectionMatrixInverted, m_hSTOESTexSamplerInverted,
- m_hSTOESPositionInverted, m_hSTOESAlphaInverted,
- m_hSTOESContrastInverted);
+ bool enableBlending = forceBlending || opacity < 1.0;
+
+ ShaderType type = UndefinedShader;
+ if (!textureId) {
+ pureColor = shaderColor(pureColor, opacity);
+ if (pureColor.rgb() == Color::transparent && enableBlending)
+ return;
+ type = PureColor;
+ } else
+ type = getTextureShaderType(textureTarget);
+
+ if (type != UndefinedShader) {
+ setBlendingState(enableBlending);
+ drawQuadInternal(type, projectionMatrix, textureId, opacity,
+ textureTarget, GL_LINEAR, pureColor);
}
- setBlendingState(forceBlending || opacity < 1.0);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
GLUtils::checkGlError("drawLayerQuad");
}
@@ -617,7 +687,7 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
int textureId)
{
// switch to our custom yuv video rendering program
- glUseProgram(m_videoProgram);
+ glUseProgram(m_handleArray[Video].programHandle);
TransformationMatrix modifiedDrawMatrix = drawMatrix;
modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
@@ -626,16 +696,19 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
- glUniformMatrix4fv(m_hVideoProjectionMatrix, 1, GL_FALSE, projectionMatrix);
- glUniformMatrix4fv(m_hVideoTextureMatrix, 1, GL_FALSE, textureMatrix);
+ glUniformMatrix4fv(m_handleArray[Video].projMtxHandle, 1, GL_FALSE,
+ projectionMatrix);
+ glUniformMatrix4fv(m_handleArray[Video].videoMtxHandle, 1, GL_FALSE,
+ textureMatrix);
glActiveTexture(GL_TEXTURE0);
- glUniform1i(m_hVideoTexSampler, 0);
+ glUniform1i(m_handleArray[Video].texSamplerHandle, 0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
+ GLint videoPosition = m_handleArray[Video].positionHandle;
glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
- glEnableVertexAttribArray(m_hVideoPosition);
- glVertexAttribPointer(m_hVideoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(videoPosition);
+ glVertexAttribPointer(videoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
setBlendingState(false);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h
index 9ab7a46..98d45b5 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h
@@ -19,6 +19,7 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "Color.h"
#include "FloatRect.h"
#include "IntRect.h"
#include "SkRect.h"
@@ -29,14 +30,85 @@
namespace WebCore {
+enum ShaderType {
+ UndefinedShader = -1,
+ PureColor,
+ Tex2D,
+ Tex2DInv,
+ TexOES,
+ TexOESInv,
+ Video,
+ // When growing this enum list, make sure to insert before the
+ // MaxShaderNumber and init the m_handleArray accordingly.
+ MaxShaderNumber
+};
+
+struct ShaderHandles {
+ ShaderHandles()
+ : alphaHandle(-1)
+ , contrastHandle(-1)
+ , positionHandle(-1)
+ , programHandle(-1)
+ , projMtxHandle(-1)
+ , pureColorHandle(-1)
+ , texSamplerHandle(-1)
+ , videoMtxHandle(-1)
+ {
+ }
+
+ void init(GLint alphaHdl, GLint contrastHdl, GLint posHdl, GLint pgmHdl,
+ GLint projMtxHdl, GLint colorHdl, GLint texSamplerHdl,
+ GLint videoMtxHdl)
+ {
+ alphaHandle = alphaHdl;
+ contrastHandle = contrastHdl;
+ positionHandle = posHdl;
+ programHandle = pgmHdl;
+ projMtxHandle = projMtxHdl;
+ pureColorHandle = colorHdl;
+ texSamplerHandle = texSamplerHdl;
+ videoMtxHandle = videoMtxHdl;
+ }
+
+ GLint alphaHandle;
+ GLint contrastHandle;
+ GLint positionHandle;
+ GLint programHandle;
+ GLint projMtxHandle;
+ GLint pureColorHandle;
+ GLint texSamplerHandle;
+ GLint videoMtxHandle;
+};
+
+struct ShaderResource {
+ ShaderResource()
+ : program(-1)
+ , vertexShader(-1)
+ , fragmentShader(-1)
+ {
+ };
+
+ ShaderResource(GLuint prog, GLuint vertex, GLuint fragment)
+ : program(prog)
+ , vertexShader(vertex)
+ , fragmentShader(fragment)
+ {
+ };
+
+ GLuint program;
+ GLuint vertexShader;
+ GLuint fragmentShader;
+};
+
class ShaderProgram {
public:
ShaderProgram();
- void init();
- int program() { return m_program; }
-
+ void initGLResources();
+ void cleanupGLResources();
// Drawing
- void setViewport(SkRect& viewport, float scale);
+ void setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
+ const IntRect& webViewRect, int titleBarHeight,
+ const IntRect& screenClip, float scale);
float zValue(const TransformationMatrix& drawMatrix, float w, float h);
// For drawQuad and drawLayerQuad, they can handle 3 cases for now:
@@ -44,22 +116,18 @@ public:
// Normal texture in GL_TEXTURE_2D target.
// 2) textureTarget == GL_TEXTURE_EXTERNAL_OES
// Surface texture in GL_TEXTURE_EXTERNAL_OES target.
- // 3) textureTarget == 0 (Will be deprecated soon)
- // Surface texture in GL_TEXTURE_2D target.
- //
- // TODO: Shrink the support modes into 2 (1 and 2) after media framework
- // support Surface texture in GL_TEXTURE_EXTERNAL_OES target on all
- // platforms.
- void drawQuad(SkRect& geometry, int textureId, float opacity,
+ // 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);
+ GLenum textureTarget = GL_TEXTURE_2D,
+ Color pureColor = Color());
void drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
float* textureMatrix, SkRect& geometry, int textureId);
- void setViewRect(const IntRect& viewRect);
FloatRect rectInScreenCoord(const TransformationMatrix& drawMatrix,
const IntSize& size);
FloatRect rectInInvScreenCoord(const TransformationMatrix& drawMatrix,
@@ -71,16 +139,13 @@ public:
FloatRect convertInvScreenCoordToScreenCoord(const FloatRect& rect);
FloatRect convertScreenCoordToInvScreenCoord(const FloatRect& rect);
- void setTitleBarHeight(int height) { m_titleBarHeight = height; }
- void setWebViewRect(const IntRect& rect) { m_webViewRect = rect; }
- void setScreenClip(const IntRect& clip);
void clip(const FloatRect& rect);
IntRect clippedRectWithViewport(const IntRect& rect, int margin = 0);
FloatRect documentViewport() { return m_documentViewport; }
- void resetBlending();
float contrast() { return m_contrast; }
- void setContrast(float c) {
+ void setContrast(float c)
+ {
float contrast = c;
if (contrast < 0)
contrast = 0;
@@ -100,33 +165,22 @@ public:
void calculateAnimationDelta();
int getAnimationDeltaX() { return m_animationDelta.x(); }
int getAnimationDeltaY() { return m_animationDelta.y(); }
+ bool needsInit() { return m_needsInit; }
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
- GLuint createProgram(const char* vertexSource, const char* fragmentSource);
- void setProjectionMatrix(SkRect& geometry, GLint projectionMatrixHandle);
-
+ GLint createProgram(const char* vertexSource, const char* fragmentSource);
+ void setProjectionMatrix(const SkRect& geometry, GLfloat* mtxPtr);
void setBlendingState(bool enableBlending);
-
- void drawQuadInternal(SkRect& geometry, GLint textureId, float opacity,
- GLint program, GLint projectionMatrixHandle,
- GLint texSampler, GLenum textureTarget,
- GLint position, GLint alpha,
- GLint texFilter, GLint contrast = -1);
-
- void drawLayerQuadInternal(const GLfloat* projectionMatrix, int textureId,
- float opacity, GLenum textureTarget, GLint program,
- GLint matrix, GLint texSample,
- GLint position, GLint alpha, GLint contrast = -1);
+ void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
+ float opacity, GLenum textureTarget, GLenum filter,
+ const Color& pureColor);
+ Color shaderColor(Color pureColor, float opacity);
+ ShaderType getTextureShaderType(GLenum textureTarget);
+ void resetBlending();
bool m_blendingEnabled;
- int m_program;
- int m_programInverted;
- int m_videoProgram;
- int m_surfTexOESProgram;
- int m_surfTexOESProgramInverted;
-
TransformationMatrix m_projectionMatrix;
GLuint m_textureBuffer[1];
@@ -141,37 +195,9 @@ private:
FloatRect m_documentViewport;
- // uniforms
- GLint m_hProjectionMatrix;
- GLint m_hAlpha;
- GLint m_hTexSampler;
- GLint m_hProjectionMatrixInverted;
- GLint m_hAlphaInverted;
- GLint m_hContrastInverted;
- GLint m_hTexSamplerInverted;
- GLint m_hVideoProjectionMatrix;
- GLint m_hVideoTextureMatrix;
- GLint m_hVideoTexSampler;
-
- GLint m_hSTOESProjectionMatrix;
- GLint m_hSTOESAlpha;
- GLint m_hSTOESTexSampler;
- GLint m_hSTOESPosition;
-
- GLint m_hSTOESProjectionMatrixInverted;
- GLint m_hSTOESAlphaInverted;
- GLint m_hSTOESContrastInverted;
- GLint m_hSTOESTexSamplerInverted;
- GLint m_hSTOESPositionInverted;
-
float m_contrast;
- // attribs
- GLint m_hPosition;
- GLint m_hPositionInverted;
- GLint m_hVideoPosition;
-
- bool m_alphaLayer;
+ bool m_alphaLayer;
TransformationMatrix m_webViewMatrix;
float m_currentScale;
@@ -184,8 +210,23 @@ private:
// TODO: Given that m_webViewMatrix contains most of the tranformation
// information, we should be able to get rid of some parameter we got from
// Java side and simplify our code.
- TransformationMatrix m_repositionMatrix;
+ TransformationMatrix m_repositionMatrix;
IntPoint m_animationDelta;
+
+ // Put all the uniform location (handle) info into an array, and group them
+ // by the shader's type, this can help to clean up the interface.
+ // TODO: use the type and data comparison to skip GL call if possible.
+ ShaderHandles m_handleArray[MaxShaderNumber];
+
+ // If there is any GL error happens such that the Shaders are not initialized
+ // successfully at the first time, then we need to init again when we draw.
+ bool m_needsInit;
+
+ // For transfer queue blitting, we need a special matrix map from (0,1) to
+ // (-1,1)
+ GLfloat m_transferProjMtx[16];
+
+ Vector<ShaderResource> m_resources;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/SharedTexture.cpp b/Source/WebCore/platform/graphics/android/SharedTexture.cpp
deleted file mode 100644
index 74cd2c6..0000000
--- a/Source/WebCore/platform/graphics/android/SharedTexture.cpp
+++ /dev/null
@@ -1,248 +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.
- */
-
-#include "config.h"
-#include "SharedTexture.h"
-
-#include "GLUtils.h"
-#include <android/native_window.h>
-#include <gui/SurfaceTexture.h>
-#include <gui/SurfaceTextureClient.h>
-
-#define LOG_NDEBUG 1
-#define LOG_TAG "SharedTexture.cpp"
-#include <utils/Log.h>
-
-namespace WebCore {
-
-SharedTexture::SharedTexture(SharedTextureMode mode)
-{
- m_sharedTextureMode = mode;
-
- m_sourceTexture = new TextureInfo(m_sharedTextureMode);
- m_targetTexture = 0;
-
- if (m_sharedTextureMode == EglImageMode) {
- m_targetTexture = new TextureInfo(m_sharedTextureMode);
- m_eglImage = EGL_NO_IMAGE_KHR;
- m_isNewImage = true;
- m_syncObject = EGL_NO_SYNC_KHR;
-
- // Defer initialization of these values until we initialize the source
- // texture. This ensures that this initialization happens in the appropriate
- // thread.
- m_display = 0;
- m_supportsEGLImage = false;
- m_supportsEGLFenceSyncKHR = false;
- } else if (m_sharedTextureMode == SurfaceTextureMode) {
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- glGenTextures(1, &m_sourceTexture->m_textureId);
-
- m_sourceTexture->m_surfaceTexture =
- new android::SurfaceTexture(m_sourceTexture->m_textureId, false);
- m_sourceTexture->m_ANW =
- new android::SurfaceTextureClient(m_sourceTexture->m_surfaceTexture);
-#endif
- }
-}
-
-// called by the consumer when it no longer wants to consume and after it has
-// terminated all providers. If EGLImages are used, the deletion of the
-// source texture and EGLImage is the responsibility of the caller.
-SharedTexture::~SharedTexture()
-{
- if (m_sharedTextureMode == EglImageMode)
- deleteTargetTexture();
- else if (m_sharedTextureMode == SurfaceTextureMode) {
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- m_sourceTexture->m_surfaceTexture.clear();
- m_sourceTexture->m_ANW.clear();
- GLUtils::deleteTexture(&m_sourceTexture->m_textureId);
-#endif
- }
- delete m_sourceTexture;
- delete m_targetTexture;
-}
-
-
-void SharedTexture::initSourceTexture()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return;
-
- m_display = eglGetCurrentDisplay();
- m_supportsEGLImage = GLUtils::isEGLImageSupported();
- m_supportsEGLFenceSyncKHR = GLUtils::isEGLFenceSyncSupported();
-
- // TODO temporarily disable fence sync until the EGL framework fixes
- // performance issues that result from consistently adding/removing fences.
- m_supportsEGLFenceSyncKHR = false;
-
- LOGI("imageEGL: %d syncKHR: %d", m_supportsEGLImage, m_supportsEGLFenceSyncKHR);
-
- glGenTextures(1, &m_sourceTexture->m_textureId);
-
-}
-
-// For MediaTexture only
-void SharedTexture::deleteSourceTexture()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return;
- // We need to delete the source texture and EGLImage in the thread in which
- // it was created. In theory we should be able to delete the EGLImage
- // from either thread, but it currently throws an error if not deleted
- // in the same EGLContext from which it was created.
- if (m_supportsEGLImage) {
- GLUtils::deleteTexture(&m_sourceTexture->m_textureId);
- if (m_eglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(eglGetCurrentDisplay(), m_eglImage);
- m_eglImage = EGL_NO_IMAGE_KHR;
- m_isNewImage = true;
- }
- LOGI("Deleted Source Texture and EGLImage");
- }
-}
-
-// For MediaTexture only
-void SharedTexture::deleteTargetTexture()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return;
-
- if (m_supportsEGLImage)
- GLUtils::deleteTexture(&m_targetTexture->m_textureId);
- else
- GLUtils::deleteTexture(&m_sourceTexture->m_textureId);
-}
-
-TextureInfo* SharedTexture::lockSource()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return m_sourceTexture;
-
- m_lock.lock();
-
- if (m_supportsEGLFenceSyncKHR && m_syncObject != EGL_NO_SYNC_KHR) {
-
- EGLint status = eglClientWaitSyncKHR(m_display, m_syncObject, 0, 1000000);
-
- if (status == EGL_TIMEOUT_EXPIRED_KHR)
- LOGE("Sync timeout for shared texture (%d)", m_sourceTexture->m_textureId);
-
- eglDestroySyncKHR(m_display, m_syncObject);
- m_syncObject = EGL_NO_SYNC_KHR;
- }
- return m_sourceTexture;
-}
-
-void SharedTexture::releaseSource()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return;
-
- if (m_supportsEGLImage) {
- // delete the existing image if needed
- if (!m_sourceTexture->equalsAttributes(m_targetTexture)) {
- if (m_eglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(m_display, m_eglImage);
- m_eglImage = EGL_NO_IMAGE_KHR;
- m_isNewImage = true;
- }
- m_targetTexture->copyAttributes(m_sourceTexture);
- }
-
- // create an image from the texture, only when the texture is valid
- if (m_eglImage == EGL_NO_IMAGE_KHR && m_sourceTexture->m_width
- && m_sourceTexture->m_height) {
- GLUtils::createEGLImageFromTexture(m_sourceTexture->m_textureId, &m_eglImage);
- LOGV("Generating Image (%d) 0x%x", m_sourceTexture->m_textureId, m_eglImage);
-
- glFinish(); // ensures the texture is ready to be used by the consumer
- }
-
- } else {
-
- m_targetTexture = m_sourceTexture;
-
- // in the case of shared contexts we must flush the texture edits to the
- // GPU. This ensures the edits complete prior to allowing the texture to
- // be bound on the producers context.
- glFlush();
- }
-
- m_lock.unlock();
-}
-
-TextureInfo* SharedTexture::lockTarget()
-{
- // Note that the source and targe are the same when using Surface Texture.
- if (m_sharedTextureMode == SurfaceTextureMode) {
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- m_sourceTexture->m_surfaceTexture->updateTexImage();
-#endif
- return m_sourceTexture;
- }
-
- m_lock.lock();
-
- if ((!m_supportsEGLImage && m_targetTexture->m_textureId == GL_NO_TEXTURE)
- || (m_supportsEGLImage && m_eglImage == EGL_NO_IMAGE_KHR)) {
- m_lock.unlock();
- return 0;
- }
-
- if (m_supportsEGLImage && (m_isNewImage || m_targetTexture->m_textureId == GL_NO_TEXTURE)) {
- if (m_targetTexture->m_textureId == GL_NO_TEXTURE)
- glGenTextures(1, &m_targetTexture->m_textureId);
-
- GLUtils::createTextureFromEGLImage(m_targetTexture->m_textureId, m_eglImage);
- LOGV("Generating Consumer Texture from 0x%x", m_eglImage);
- m_isNewImage = false;
- }
- return m_targetTexture;
-}
-
-void SharedTexture::releaseTarget()
-{
- if (m_sharedTextureMode == SurfaceTextureMode)
- return;
-
- if (m_supportsEGLFenceSyncKHR) {
- if (m_syncObject != EGL_NO_SYNC_KHR)
- eglDestroySyncKHR(m_display, m_syncObject);
- m_syncObject = eglCreateSyncKHR(m_display, EGL_SYNC_FENCE_KHR, 0);
- } else {
- // TODO the flush currently prevents the screen from getting partial
- // updates but the only way to guarantee this is to call glFinish. Until
- // we support an EGL sync we will leave flush enable in order to test
- // with modest performance.
- glFlush();
- }
-
- m_lock.unlock();
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/SharedTexture.h b/Source/WebCore/platform/graphics/android/SharedTexture.h
deleted file mode 100644
index 305a442..0000000
--- a/Source/WebCore/platform/graphics/android/SharedTexture.h
+++ /dev/null
@@ -1,118 +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 SharedTexture_h
-#define SharedTexture_h
-
-#include "TextureInfo.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <utils/threads.h>
-
-namespace WebCore {
-
-/**
- * SharedTexture is a class that encapsulates all the necessary variables
- * needed to share a single texture across threads. In the case that threads
- * communicate using EGL's sharedContext mechanism or do not support the proper
- * EGLImage extensions the targetTexture, eglImage, and isNewImage variables are
- * not used.
- */
-class SharedTexture {
-public:
- // consumer thread functions
- SharedTexture(SharedTextureMode mode);
- ~SharedTexture();
-
- TextureInfo* lockSource();
- void releaseSource();
-
- TextureInfo* lockTarget();
- void releaseTarget();
-
- // these locks are only used for the methods below
- void lock() { m_lock.lock(); }
- void unlock() { m_lock.unlock(); }
-
- void initSourceTexture(); // producer thread only
- void deleteSourceTexture(); // producer thread only
- void deleteTargetTexture(); // consumer thread only
- GLuint getSourceTextureId() { return m_sourceTexture->m_textureId; }
- GLuint getTargetTextureId() { return m_targetTexture->m_textureId; }
- EGLImageKHR getEGLImage() { return m_eglImage; }
-
-private:
- /**
- * The mutex is used to ensure that the contents of the struct are current across
- * threads and that only one thread is manipulating the texture at a given time.
- */
- android::Mutex m_lock;
- /**
- * The texture and its associated metadata that is used by the producer. The
- * texture is created in the producer's thread and can only be read by the
- * consumer when the consumer shares the same context as the producer. The
- * metadata is used to track changes to the texture that would orphan the
- * target texture and require a new EGLImage to be constructed.
- */
- TextureInfo* m_sourceTexture;
- /**
- * The target texture stores the id and metadata of the texture that is to be
- * used by the consumer. In the case where EGLImages are supported this hold
- * the current eglImage target.
- */
- TextureInfo* m_targetTexture;
- /**
- * The EGLImage is used to share the texture between EGLContexts on two
- * different threads. This serves as an alternative to sharing the contexts
- * but is only used if GL and EGL support the required extensions.
- */
- EGLImageKHR m_eglImage;
- /**
- * This flag is used to determine if the eglImage has been updated. This
- * signals the consumer thread to rebind the targetTexture to the new image.
- */
- bool m_isNewImage;
- /**
- * The sync allows the consumer to release the lock prior to the commands
- * executing on the GPU. Prior to releasing the lock the consumer creates
- * a sync object and stores it here. After locking the texture the client
- * must check that the sync has completed prior to manipulating the texture.
- * This value is only used if the proper EGL extensions are supported.
- */
- EGLSyncKHR m_syncObject;
-
- EGLDisplay m_display;
-
- bool m_supportsEGLImage;
- bool m_supportsEGLFenceSyncKHR;
-
- SharedTextureMode m_sharedTextureMode;
-};
-
-} // namespace WebCore
-
-#endif // SharedTexture_h
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp
new file mode 100644
index 0000000..78c3fbb
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/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 "LayerGroup.h"
+#include "ScrollableLayerAndroid.h"
+#include "TilesManager.h"
+
+namespace WebCore {
+
+////////////////////////////////////////////////////////////////////////////////
+// TILED PAINTING / GROUPS //
+////////////////////////////////////////////////////////////////////////////////
+
+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 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);
+ if (m_layerGroups[i]->isBase())
+ m_layerGroups[i]->setBackground(getBackground());
+ }
+
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->increment("SurfaceCollection");
+#endif
+}
+
+SurfaceCollection::~SurfaceCollection()
+{
+ SkSafeUnref(m_compositedRoot);
+ 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)
+{
+ 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)
+{
+#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_layerGroups.size(); i++)
+ needsRedraw |= m_layerGroups[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_layerGroups.size(); i++)
+ m_layerGroups[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_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);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RECURSIVE ANIMATION / INVALS / LAYERS //
+////////////////////////////////////////////////////////////////////////////////
+
+void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface)
+{
+ 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()
+{
+ 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/SurfaceCollection.h
new file mode 100644
index 0000000..e73ec9a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.h
@@ -0,0 +1,75 @@
+/*
+ * 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 SurfaceCollection_h
+#define SurfaceCollection_h
+
+#include "Color.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "Vector.h"
+
+class SkCanvas;
+class SkRegion;
+
+namespace WebCore {
+
+class LayerAndroid;
+class LayerGroup;
+class TexturesResult;
+
+class SurfaceCollection : public SkRefCnt {
+// TODO: investigate webkit threadsafe ref counting
+public:
+ SurfaceCollection(LayerAndroid* compositedRoot);
+ virtual ~SurfaceCollection();
+
+ // Tiled painting methods (executed on groups)
+ void prepareGL(const SkRect& visibleRect);
+ bool drawGL(const SkRect& visibleRect);
+ Color getBackground();
+ void swapTiles();
+ bool isReady();
+ void computeTexturesAmount(TexturesResult* result);
+
+ // Recursive tree methods (animations, invals, etc)
+ void setIsPainting(SurfaceCollection* drawingSurfaceCollection);
+ void setIsDrawing();
+ void mergeInvalsInto(SurfaceCollection* replacementSurfaceCollection);
+ void evaluateAnimations(double currentTime);
+
+ bool hasCompositedLayers();
+ bool hasCompositedAnimations();
+ void updateScrollableLayer(int layerId, int x, int y);
+
+private:
+ void updateLayerPositions(const SkRect& visibleRect);
+ LayerAndroid* m_compositedRoot;
+ Vector<LayerGroup*> m_layerGroups;
+};
+
+} // namespace WebCore
+
+#endif //#define SurfaceCollection_h
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
new file mode 100644
index 0000000..c3c4bda
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
@@ -0,0 +1,245 @@
+/*
+ * 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 "SurfaceCollectionManager"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "SurfaceCollectionManager.h"
+
+#include "AndroidLog.h"
+#include "LayerGroup.h"
+#include "TilesManager.h"
+#include "SurfaceCollection.h"
+
+namespace WebCore {
+
+SurfaceCollectionManager::SurfaceCollectionManager(GLWebViewState* state)
+ : m_state(state)
+ , m_drawingCollection(0)
+ , m_paintingCollection(0)
+ , m_queuedCollection(0)
+ , m_fastSwapMode(false)
+{
+}
+
+SurfaceCollectionManager::~SurfaceCollectionManager()
+{
+ clearCollections();
+}
+
+// the painting collection has finished painting:
+// discard the drawing collection
+// swap the painting collection in place of the drawing collection
+// and start painting the queued collection
+void SurfaceCollectionManager::swap()
+{
+ // swap can't be called unless painting just finished
+ ASSERT(m_paintingCollection);
+
+ android::Mutex::Autolock lock(m_paintSwapLock);
+
+ ALOGV("SWAPPING, D %p, P %p, Q %p",
+ m_drawingCollection, m_paintingCollection, m_queuedCollection);
+
+ // if we have a drawing collection, discard it since the painting collection is done
+ if (m_drawingCollection) {
+ ALOGV("destroying drawing collection %p", m_drawingCollection);
+ SkSafeUnref(m_drawingCollection);
+ }
+
+ // painting collection becomes the drawing collection
+ ALOGV("drawing collection %p", m_paintingCollection);
+ m_paintingCollection->setIsDrawing(); // initialize animations
+
+ if (m_queuedCollection) {
+ // start painting with the queued collection
+ ALOGV("now painting collection %p", m_queuedCollection);
+ m_queuedCollection->setIsPainting(m_paintingCollection);
+ }
+ m_drawingCollection = m_paintingCollection;
+ m_paintingCollection = m_queuedCollection;
+ m_queuedCollection = 0;
+
+ ALOGV("SWAPPING COMPLETE, D %p, P %p, Q %p",
+ m_drawingCollection, m_paintingCollection, m_queuedCollection);
+}
+
+// clear all of the content in the three collections held by the collection manager
+void SurfaceCollectionManager::clearCollections()
+{
+ ALOGV("SurfaceCollectionManager %p removing PS from state %p", this, m_state);
+
+ SkSafeUnref(m_drawingCollection);
+ m_drawingCollection = 0;
+ SkSafeUnref(m_paintingCollection);
+ m_paintingCollection = 0;
+ SkSafeUnref(m_queuedCollection);
+ m_queuedCollection = 0;
+}
+
+// a new layer collection has arrived, queue it if we're painting something already,
+// or start painting it if we aren't. Returns true if the manager has two collections
+// already queued.
+bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* newCollection,
+ bool brandNew)
+{
+ // can't have a queued collection unless have a painting collection too
+ ASSERT(m_paintingCollection || !m_queuedCollection);
+
+ android::Mutex::Autolock lock(m_paintSwapLock);
+
+ if (!newCollection || brandNew) {
+ clearCollections();
+ if (brandNew) {
+ m_paintingCollection = newCollection;
+ m_paintingCollection->setIsPainting(m_drawingCollection);
+ }
+ 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) {
+ // already have a queued collection, copy over invals so the regions are
+ // eventually repainted and let the old queued collection be discarded
+ m_queuedCollection->mergeInvalsInto(newCollection);
+
+ if (!TilesManager::instance()->useDoubleBuffering()) {
+ // not double buffering, count discarded collection/webkit paint as an update
+ TilesManager::instance()->incContentUpdates();
+ }
+
+ ALOGV("DISCARDING collection - %p, has children %d, has animations %d",
+ newCollection, newCollection->hasCompositedLayers(),
+ newCollection->hasCompositedAnimations());
+ }
+ SkSafeUnref(m_queuedCollection);
+ m_queuedCollection = newCollection;
+ } else {
+ // don't have painting collection, paint this one!
+ m_paintingCollection = newCollection;
+ m_paintingCollection->setIsPainting(m_drawingCollection);
+ }
+ return m_paintingCollection && TilesManager::instance()->useDoubleBuffering();
+}
+
+void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y)
+{
+ if (m_queuedCollection)
+ m_queuedCollection->updateScrollableLayer(layerId, x, y);
+ if (m_paintingCollection)
+ m_paintingCollection->updateScrollableLayer(layerId, x, y);
+ if (m_drawingCollection)
+ m_drawingCollection->updateScrollableLayer(layerId, x, y);
+}
+
+bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
+ SkRect& visibleRect, float scale,
+ bool enterFastSwapMode,
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
+ TexturesResult* texturesResultPtr)
+{
+ m_fastSwapMode |= enterFastSwapMode;
+
+ ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d",
+ m_drawingCollection, m_paintingCollection, m_queuedCollection, m_fastSwapMode);
+
+ bool ret = false;
+ bool didCollectionSwap = false;
+ if (m_paintingCollection) {
+ ALOGV("preparing painting collection %p", m_paintingCollection);
+
+ m_paintingCollection->evaluateAnimations(currentTime);
+
+ m_paintingCollection->prepareGL(visibleRect);
+ m_paintingCollection->computeTexturesAmount(texturesResultPtr);
+
+ if (!TilesManager::instance()->useDoubleBuffering() || m_paintingCollection->isReady()) {
+ ALOGV("have painting collection %p ready, swapping!", m_paintingCollection);
+ didCollectionSwap = true;
+ TilesManager::instance()->incContentUpdates();
+ if (collectionsSwappedPtr)
+ *collectionsSwappedPtr = true;
+ if (newCollectionHasAnimPtr)
+ *newCollectionHasAnimPtr = m_paintingCollection->hasCompositedAnimations();
+ swap();
+ }
+ } else if (m_drawingCollection) {
+ ALOGV("preparing drawing collection %p", m_drawingCollection);
+ m_drawingCollection->prepareGL(visibleRect);
+ m_drawingCollection->computeTexturesAmount(texturesResultPtr);
+ }
+
+ // Don't have a drawing collection, draw white background
+ Color background = Color::white;
+ if (m_drawingCollection) {
+ bool drawingReady = didCollectionSwap || m_drawingCollection->isReady();
+
+ // call the page swap callback if registration happened without more collections enqueued
+ if (collectionsSwappedPtr && drawingReady && !m_paintingCollection)
+ *collectionsSwappedPtr = true;
+
+ if (didCollectionSwap || m_fastSwapMode || (drawingReady && !m_paintingCollection))
+ m_drawingCollection->swapTiles();
+
+ if (drawingReady) {
+ // exit fast swap mode, as content is up to date
+ m_fastSwapMode = false;
+ } else {
+ // drawing isn't ready, must redraw
+ ret = true;
+ }
+
+ m_drawingCollection->evaluateAnimations(currentTime);
+
+ 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();
+ }
+
+ // 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)
+ ret |= m_drawingCollection->drawGL(visibleRect);
+
+ if (m_paintingCollection) {
+ ALOGV("still have painting collection %p", m_paintingCollection);
+ return true;
+ }
+
+ return ret;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TreeManager.h b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h
index 83d5300..304d57f 100644
--- a/Source/WebCore/platform/graphics/android/TreeManager.h
+++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h
@@ -23,61 +23,52 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TreeManager_h
-#define TreeManager_h
+#ifndef SurfaceCollectionManager_h
+#define SurfaceCollectionManager_h
#include "TestExport.h"
#include <utils/threads.h>
-#include "PerformanceMonitor.h"
-class Layer;
class SkRect;
class SkCanvas;
namespace WebCore {
+class GLWebViewState;
class IntRect;
class TexturesResult;
+class SurfaceCollection;
-class TEST_EXPORT TreeManager {
+class TEST_EXPORT SurfaceCollectionManager {
public:
- TreeManager();
+ SurfaceCollectionManager(GLWebViewState* state);
- ~TreeManager();
+ ~SurfaceCollectionManager();
- void updateWithTree(Layer* tree, bool brandNew);
+ bool updateWithSurfaceCollection(SurfaceCollection* collection, bool brandNew);
void updateScrollableLayer(int layerId, int x, int y);
bool drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
- bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr,
+ bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
TexturesResult* texturesResultPtr);
- void drawCanvas(SkCanvas* canvas, bool drawLayers);
-
- // used in debugging (to avoid exporting TilesManager symbols)
- static int getTotalPaintedSurfaceCount();
-
- int baseContentWidth();
- int baseContentHeight();
-
private:
- static void updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y);
-
void swap();
- void clearTrees();
+ void clearCollections();
android::Mutex m_paintSwapLock;
- Layer* m_drawingTree;
- Layer* m_paintingTree;
- Layer* m_queuedTree;
+ GLWebViewState* m_state;
+
+ SurfaceCollection* m_drawingCollection;
+ SurfaceCollection* m_paintingCollection;
+ SurfaceCollection* m_queuedCollection;
bool m_fastSwapMode;
- PerformanceMonitor m_perf;
};
} // namespace WebCore
-#endif //#define TreeManager_h
+#endif //#define SurfaceCollectionManager_h
diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.cpp b/Source/WebCore/platform/graphics/android/TextureInfo.cpp
index 5356dcb..f5c8b02 100644
--- a/Source/WebCore/platform/graphics/android/TextureInfo.cpp
+++ b/Source/WebCore/platform/graphics/android/TextureInfo.cpp
@@ -35,15 +35,12 @@
namespace WebCore {
-TextureInfo::TextureInfo(SharedTextureMode mode)
+TextureInfo::TextureInfo()
{
m_textureId = GL_NO_TEXTURE;
m_width = 0;
m_height = 0;
m_internalFormat = 0;
- m_sharedTextureMode = mode;
- m_eglSurface = EGL_NO_SURFACE;
- m_pictureCount = 0;
}
bool TextureInfo::equalsAttributes(const TextureInfo* otherTexture)
diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.h b/Source/WebCore/platform/graphics/android/TextureInfo.h
index 1c48937..4684df2 100644
--- a/Source/WebCore/platform/graphics/android/TextureInfo.h
+++ b/Source/WebCore/platform/graphics/android/TextureInfo.h
@@ -34,8 +34,6 @@
#include "BaseTile.h"
using android::sp;
-#define DEPRECATED_SURFACE_TEXTURE_MODE 0
-
namespace android {
class SurfaceTexture;
}
@@ -47,39 +45,20 @@ static const GLuint GL_NO_TEXTURE = 0;
* TextureInfo is a class that stores both the texture and metadata about the
* texture.
*/
-enum SharedTextureMode {
- EglImageMode,
- SurfaceTextureMode
-};
class TextureInfo {
public:
-
- TextureInfo(SharedTextureMode mode);
+ TextureInfo();
bool equalsAttributes(const TextureInfo* otherTexture);
void copyAttributes(const TextureInfo* sourceTexture);
- SharedTextureMode getSharedTextureMode() { return m_sharedTextureMode; }
bool operator==(const TextureInfo& otherTexture);
GLuint m_textureId;
int32_t m_width;
int32_t m_height;
GLenum m_internalFormat;
-
- // Surface Texture specific data
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- sp<android::SurfaceTexture> m_surfaceTexture;
-#endif
- // TODO: Delete this after the Ganesh code path get fixed.
- sp<ANativeWindow> m_ANW;
- // The EGLSurface wraps the m_ANW to enable direct OpenGL rendering (e.g. Ganesh)
- EGLSurface m_eglSurface;
-
- int m_pictureCount;
-private:
- SharedTextureMode m_sharedTextureMode;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TextureOwner.h b/Source/WebCore/platform/graphics/android/TextureOwner.h
index 5434dbf..4f9e6ef 100644
--- a/Source/WebCore/platform/graphics/android/TextureOwner.h
+++ b/Source/WebCore/platform/graphics/android/TextureOwner.h
@@ -31,7 +31,6 @@ class Layer;
namespace WebCore {
-class TiledPage;
class BaseTileTexture;
class GLWebViewState;
@@ -39,8 +38,6 @@ 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 isRepaintPending() = 0;
virtual unsigned long long drawCount() = 0;
diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
index bccb99b..3279ec2 100644
--- a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -23,32 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "TexturesGenerator"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "TexturesGenerator.h"
#if USE(ACCELERATED_COMPOSITING)
-#include "BaseLayerAndroid.h"
+#include "AndroidLog.h"
#include "GLUtils.h"
#include "PaintTileOperation.h"
#include "TilesManager.h"
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TexturesGenerator", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
void TexturesGenerator::scheduleOperation(QueuedOperation* operation)
@@ -60,21 +47,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 PagePaintFilter(page), waitForRunning);
-}
-
-void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
-{
- removeOperationsForFilter(filter, true);
-}
-
void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning)
{
if (!filter)
@@ -104,7 +76,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;
@@ -122,8 +94,7 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool
status_t TexturesGenerator::readyToRun()
{
- TilesManager::instance()->markGeneratorAsReady();
- XLOG("Thread ready to run");
+ ALOGV("Thread ready to run");
return NO_ERROR;
}
@@ -167,20 +138,21 @@ bool TexturesGenerator::threadLoop()
while (!mRequestedOperations.size())
mRequestedOperationsCond.wait(mRequestedOperationsLock);
- XLOG("threadLoop, got signal");
+ ALOGV("threadLoop, got signal");
mRequestedOperationsLock.unlock();
m_currentOperation = 0;
bool stop = false;
while (!stop) {
mRequestedOperationsLock.lock();
- XLOG("threadLoop, %d operations in the queue", mRequestedOperations.size());
+ ALOGV("threadLoop, %d operations in the queue", mRequestedOperations.size());
if (mRequestedOperations.size())
m_currentOperation = popNext();
mRequestedOperationsLock.unlock();
if (m_currentOperation) {
- XLOG("threadLoop, painting the request with priority %d", m_currentOperation->priority());
+ ALOGV("threadLoop, painting the request with priority %d",
+ m_currentOperation->priority());
m_currentOperation->run();
}
@@ -192,14 +164,14 @@ 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();
if (oldOperation)
delete oldOperation; // delete outside lock
}
- XLOG("threadLoop empty");
+ ALOGV("threadLoop empty");
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.h b/Source/WebCore/platform/graphics/android/TexturesGenerator.h
index 2e3b6b4..35a3386 100644
--- a/Source/WebCore/platform/graphics/android/TexturesGenerator.h
+++ b/Source/WebCore/platform/graphics/android/TexturesGenerator.h
@@ -29,29 +29,27 @@
#if USE(ACCELERATED_COMPOSITING)
#include "QueuedOperation.h"
-#include "TiledPage.h"
#include "TilePainter.h"
+#include "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);
@@ -63,6 +61,7 @@ private:
android::Condition mRequestedOperationsCond;
bool m_waitForCompletion;
QueuedOperation* m_currentOperation;
+ TilesManager* m_tilesManager;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h
index 4d0f5dc..a5dafa9 100644
--- a/Source/WebCore/platform/graphics/android/TilePainter.h
+++ b/Source/WebCore/platform/graphics/android/TilePainter.h
@@ -34,21 +34,23 @@ class SkCanvas;
namespace WebCore {
class BaseTile;
+class Color;
-class TilePainter {
+class TilePainter : public SkRefCnt {
+// TODO: investigate webkit threadsafe ref counting
public:
- virtual ~TilePainter() { }
- virtual bool paint(BaseTile* tile, SkCanvas*, unsigned int*) = 0;
- virtual const TransformationMatrix* transform() { return 0; }
-};
-
-class SurfacePainter : public SkRefCnt {
-public:
- virtual ~SurfacePainter() { }
- virtual const TransformationMatrix* transform() { return 0; }
- virtual float opacity() { return 1.0; }
- enum SurfaceType { PaintedSurface, ImageSurface };
- virtual SurfaceType type() { return PaintedSurface; }
+ virtual ~TilePainter() { }
+ virtual bool paint(BaseTile* 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; }
+
+private:
+ unsigned int m_updateCount;
};
}
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
deleted file mode 100644
index 31a0593..0000000
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ /dev/null
@@ -1,413 +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.
- */
-
-#include "config.h"
-#include "TiledPage.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "GLUtils.h"
-#include "IntRect.h"
-#include "PaintTileOperation.h"
-#include "SkPaint.h"
-#include "SkPaintFlagsDrawFilter.h"
-#include "TilesManager.h"
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TiledPage", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledPage", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-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_latestPictureInval(0)
- , 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()
-{
- // 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::instance()->removeOperationsForPage(this);
- 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, const unsigned int pictureCount)
-{
- // 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));
-
- XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY);
- // We defer marking the tile as dirty until the next time we need to prepare
- // to draw.
- m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op);
- m_invalTilesRegion.op(inval.x(), inval.y(), inval.maxX(), inval.maxY(), SkRegion::kUnion_Op);
- m_latestPictureInval = pictureCount;
-}
-
-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) {
- XLOG("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) {
- XLOG("ERROR: No tile available for tile %d %d", x, y);
- }
-
- if (currentTile) {
- currentTile->setGLWebViewState(m_glWebViewState);
- currentTile->setPage(this);
-
- currentTile->setContents(this, 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);
- TilesManager::instance()->scheduleOperation(operation);
- }
- }
- }
-}
-
-bool TiledPage::updateTileDirtiness(const SkIRect& tileBounds)
-{
- if (!m_glWebViewState || tileBounds.isEmpty()) {
- m_invalRegion.setEmpty();
- m_invalTilesRegion.setEmpty();
- return false;
- }
-
- bool visibleTileIsDirty = false;
- for (int x = 0; x < m_baseTileSize; x++) {
-
- BaseTile& tile = m_baseTiles[x];
-
- // if the tile is in the dirty region then we must invalidate it
- if (m_invalRegion.contains(tile.x(), tile.y())) {
- tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion);
- if (tileBounds.contains(tile.x(), tile.y()))
- visibleTileIsDirty = true;
- }
- }
-
- // clear the invalidated region as all tiles within that region have now
- // been marked as dirty.
- m_invalRegion.setEmpty();
- m_invalTilesRegion.setEmpty();
- return visibleTileIsDirty;
-}
-
-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();
-
- // Expand number of tiles to allow tiles outside of viewport to be prepared for
- // smoother scrolling.
- int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
- int nMaxTilesPerPage = m_baseTileSize / 2;
-
- 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);
- nbTilesHeight = std::min(nbTilesHeight, maxY - firstTileY);
-
- // 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)
- {
- XLOGC("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();
- XLOG("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--;
- }
- }
- XLOG("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++;
- }
-
- XLOG("%p greedy swapped %d textures, returning true", this, swaps);
- return fullSwap;
-}
-
-void TiledPage::prepareForDrawGL(float transparency, const SkIRect& tileBounds)
-{
- m_willDraw = true;
- m_transparency = transparency;
- m_tileBounds = tileBounds;
-}
-
-void TiledPage::drawGL()
-{
- if (!m_glWebViewState || m_transparency == 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.draw(m_transparency, rect, m_scale);
- }
-
- TilesManager::instance()->getProfiler()->nextTile(tile, m_invScale, tileInView);
- }
- m_willDraw = false; // don't redraw until re-prepared
-}
-
-bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed)
-{
- static SkPaintFlagsDrawFilter prefetchFilter(SkPaint::kAllFlags,
- SkPaint::kAntiAlias_Flag);
-
- if (!m_glWebViewState)
- return false;
-
- if (isPrefetchPage())
- canvas->setDrawFilter(&prefetchFilter);
-
- *pictureUsed = 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 791e1f6..0000000
--- a/Source/WebCore/platform/graphics/android/TiledPage.h
+++ /dev/null
@@ -1,141 +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, return true if visible ones are
- // dirty (and thus repaint needed)
- bool updateTileDirtiness(const SkIRect& tileBounds);
-
- // 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 transparency and bounds to be drawn in drawGL()
- void prepareForDrawGL(float transparency, 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*, SkCanvas*, unsigned int*);
-
- // 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, const unsigned int pictureCount);
- 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;
-
- // used to identify the tiles that have been invalidated (marked dirty) since
- // the last time updateTileState() has been called. The region is stored in
- // terms of the (x,y) coordinates used to determine the location of the tile
- // within the page, not in content/view pixel coordinates.
- SkRegion m_invalRegion;
-
- // inval regions in content coordinates
- SkRegion m_invalTilesRegion;
- unsigned int m_latestPictureInval;
- bool m_prepare;
- bool m_scrollingDown;
- bool m_isPrefetchPage;
-
- // info saved in prepare, used in drawGL()
- bool m_willDraw;
- SkIRect m_tileBounds;
- float m_transparency;
-};
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
-#endif // TiledPage_h
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
index d538416..11cf906 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
@@ -23,48 +23,35 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "TiledTexture"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "TiledTexture.h"
-#include "TilesManager.h"
-#include "TilesTracker.h"
-
-#include "PaintedSurface.h"
+#include "AndroidLog.h"
#include "PaintTileOperation.h"
#include "SkCanvas.h"
#include "SkPicture.h"
+#include "TilesManager.h"
-#include <cutils/log.h>
#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__)
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TiledTexture", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+#define LOW_RES_PREFETCH_SCALE_MODIFIER 0.3f
+#define EXPANDED_BOUNDS_INFLATE 1
+#define EXPANDED_PREFETCH_BOUNDS_Y_INFLATE 1
namespace WebCore {
TiledTexture::~TiledTexture()
{
- SkSafeUnref(m_paintingPicture);
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("TiledTexture");
#endif
removeTiles();
}
-bool TiledTexture::ready()
+bool TiledTexture::isReady()
{
bool tilesAllReady = true;
bool tilesVisible = false;
@@ -82,32 +69,40 @@ bool TiledTexture::ready()
// in order to unblock the zooming process.
// FIXME: have a better system -- maybe keeping the last scale factor
// able to fully render everything
- XLOG("TT %p, ready %d, visible %d, texturesRemain %d",
- this, tilesAllReady, tilesVisible,
- TilesManager::instance()->layerTexturesRemain());
+ ALOGV("TT %p, ready %d, visible %d, texturesRemain %d",
+ this, tilesAllReady, tilesVisible,
+ TilesManager::instance()->layerTexturesRemain());
return !TilesManager::instance()->layerTexturesRemain()
|| !tilesVisible || tilesAllReady;
}
+bool TiledTexture::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 TiledTexture::swapTiles()
{
int swaps = 0;
for (unsigned int i = 0; i < m_tiles.size(); i++)
if (m_tiles[i]->swapTexturesIfNeeded())
swaps++;
- XLOG("TT %p swapping, swaps = %d", this, swaps);
+ ALOGV("TT %p swapping, swaps = %d", this, swaps);
}
-IntRect TiledTexture::computeTilesArea(IntRect& visibleArea, float scale)
+IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale)
{
IntRect computedArea;
- IntRect area(visibleArea.x() * scale,
- visibleArea.y() * scale,
- ceilf(visibleArea.width() * scale),
- ceilf(visibleArea.height() * scale));
+ IntRect area(contentArea.x() * scale,
+ contentArea.y() * scale,
+ ceilf(contentArea.width() * scale),
+ ceilf(contentArea.height() * scale));
- XLOG("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height());
+ ALOGV("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height());
if (area.width() == 0 && area.height() == 0) {
computedArea.setWidth(0);
@@ -115,8 +110,8 @@ IntRect TiledTexture::computeTilesArea(IntRect& visibleArea, 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);
@@ -127,87 +122,111 @@ IntRect TiledTexture::computeTilesArea(IntRect& visibleArea, float scale)
return computedArea;
}
-void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint,
- bool startFastSwap, IntRect& visibleArea)
+void TiledTexture::prepareGL(GLWebViewState* state, float scale,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool isLowResPrefetch, bool useExpandPrefetch)
{
- if (!m_surface)
- return;
-
// first, how many tiles do we need
- m_area = computeTilesArea(visibleArea, scale);
+ m_area = computeTilesArea(prepareArea, scale);
if (m_area.isEmpty())
return;
- XLOG("for TiledTexture %p, we prepare with scale %.2f, have a visible area of "
- " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
- this, scale,
- visibleArea.x(), visibleArea.y(),
- visibleArea.width(), visibleArea.height(),
- m_area.x(), m_area.y(),
- m_area.width(), m_area.height());
+ ALOGV("prepare TiledTexture %p with scale %.2f, prepareArea "
+ " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
+ this, scale,
+ prepareArea.x(), prepareArea.y(),
+ prepareArea.width(), prepareArea.height(),
+ m_area.x(), m_area.y(),
+ m_area.width(), m_area.height());
bool goingDown = m_prevTileY < m_area.y();
m_prevTileY = m_area.y();
if (scale != m_scale)
- TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(this, scale));
+ TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, m_scale));
m_scale = scale;
// apply dirty region to affected tiles
if (!m_dirtyRegion.isEmpty()) {
- for (unsigned int i = 0; i < m_tiles.size(); i++) {
- // TODO: don't mark all tiles dirty
- m_tiles[i]->markAsDirty(1, m_dirtyRegion);
+ 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::instance()->getProfiler()->enabled()) {
+ SkRegion::Iterator iterator(m_dirtyRegion);
+ while (!iterator.done()) {
+ SkIRect r = iterator.rect();
+ TilesManager::instance()->getProfiler()->nextInval(r, scale);
+ iterator.next();
+ }
}
+ m_dirtyRegion.setEmpty();
}
- 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(repaint, m_area.x() + i, m_area.y() + j);
- }
+ for (int j = 0; j < m_area.height(); j++)
+ prepareTile(m_area.x() + i, m_area.y() + j,
+ painter, state, isLowResPrefetch, false);
} else {
- for (int j = m_area.height() - 1; j >= 0; j--) {
- prepareTile(repaint, m_area.x() + i, m_area.y() + j);
- }
+ for (int j = m_area.height() - 1; j >= 0; j--)
+ 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;
+ expandedArea.inflate(EXPANDED_BOUNDS_INFLATE);
+
+ if (isLowResPrefetch)
+ expandedArea.inflate(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::update(const SkRegion& invalRegion, SkPicture* picture)
+void TiledTexture::markAsDirty(const SkRegion& invalRegion)
{
- XLOG("TT %p update, current region empty %d, new empty %d, painting picture %p",
- this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty(), picture);
+ ALOGV("TT %p markAsDirty, current region empty %d, new empty %d",
+ this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty());
m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
-
- android::Mutex::Autolock lock(m_paintingPictureSync);
- SkSafeRef(picture);
- SkSafeUnref(m_paintingPicture);
- m_paintingPicture = picture;
}
-void TiledTexture::prepareTile(bool repaint, int x, int y)
+void TiledTexture::prepareTile(int x, int y, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch)
{
BaseTile* tile = getTile(x, y);
if (!tile) {
- tile = new BaseTile(true);
+ bool isLayerTile = !m_isBaseSurface;
+ tile = new BaseTile(isLayerTile);
m_tiles.append(tile);
}
- XLOG("preparing tile %p at %d, %d, painter is this %p", tile, x, y, this);
- tile->setContents(this, x, y, m_scale);
+ ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter);
+
+ tile->setContents(x, y, m_scale, isExpandPrefetch);
// TODO: move below (which is largely the same for layers / tiled page) into
- // prepare() function
+ // prepareGL() function
if (tile->isDirty() || !tile->frontTexture())
tile->reserveTexture();
- bool hasPicture = m_paintingPicture != 0; // safely read on UI thread, since only UI thread writes
- if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && hasPicture) {
- PaintTileOperation *operation = new PaintTileOperation(tile, m_surface);
+ 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,
+ state, isLowResPrefetch);
TilesManager::instance()->scheduleOperation(operation);
}
}
@@ -239,79 +258,94 @@ int TiledTexture::nbTextures(IntRect& area, float scale)
return numberTextures;
}
-bool TiledTexture::draw()
+bool TiledTexture::drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform,
+ const Color* background)
{
- if (!m_surface)
- return true;
-
- XLOG("TT %p draw", this);
-
-#ifdef DEBUG
- TilesManager::instance()->getTilesTracker()->trackLayer();
-#endif
-
+ m_area = computeTilesArea(visibleArea, m_scale);
if (m_area.width() == 0 || m_area.height() == 0)
return false;
-#ifdef DEBUG
- TilesManager::instance()->getTilesTracker()->trackVisibleLayer();
-#endif
-
- 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 translucentBaseSurface =
+ background ? (background->hasAlpha() && background->alpha() > 0) : false;
+ if (translucentBaseSurface) {
+ 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];
- if (tile->isTileVisible(m_area)) {
+ bool tileInView = tile->isTileVisible(m_area);
+ if (tileInView) {
askRedraw |= !tile->isTileReady();
SkRect rect;
rect.fLeft = tile->x() * tileWidth;
rect.fTop = tile->y() * tileHeight;
rect.fRight = rect.fLeft + tileWidth;
rect.fBottom = rect.fTop + tileHeight;
- XLOG("- [%d], { painter %x vs %x }, tile %x (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
- i, this, tile->painter(), tile, tile->isLayerTile(), tile->x(), tile->y(),
- tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
- tile->draw(m_surface->opacity(), rect, m_scale);
-#ifdef DEBUG
- TilesManager::instance()->getTilesTracker()->track(tile->isTileReady(), tile->backTexture());
-#endif
+ ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
+ tile, tile->isLayerTile(), tile->x(), tile->y(),
+ tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
+
+ bool success = tile->drawGL(opacity, rect, m_scale, transform);
+ if (translucentBaseSurface && 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++;
}
- }
-
- // need to redraw if some visible tile wasn't ready
- return askRedraw;
-}
-
-bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed)
-{
- m_paintingPictureSync.lock();
- SkPicture* picture = m_paintingPicture;
- SkSafeRef(picture);
- m_paintingPictureSync.unlock();
- if (!picture) {
- XLOG("TT %p COULDNT PAINT, NO PICTURE", this);
- return false;
+ if (translucentBaseSurface)
+ TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView);
}
- XLOG("TT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), picture);
-
- canvas->drawPicture(*picture);
+ // Draw missing Regions with blend turned on
+ if (translucentBaseSurface)
+ drawMissingRegion(missingRegion, opacity, background);
- SkSafeUnref(picture);
+ ALOGV("TT %p drew %d tiles, redraw due to notready %d, scale %f",
+ this, drawn, askRedraw, m_scale);
- return true;
+ // need to redraw if some visible tile wasn't ready
+ return askRedraw;
}
-const TransformationMatrix* TiledTexture::transform()
+void TiledTexture::drawMissingRegion(const SkRegion& region, float opacity,
+ const Color* background)
{
- if (!m_surface)
- return 0;
- return m_surface->transform();
+ 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() );
+ shader->drawQuad(rect, 0, opacity, postAlpha);
+ iterator.next();
+ }
}
void TiledTexture::removeTiles()
@@ -324,28 +358,15 @@ void TiledTexture::removeTiles()
void TiledTexture::discardTextures()
{
+ ALOGV("TT %p discarding textures", this);
for (unsigned int i = 0; i < m_tiles.size(); i++)
m_tiles[i]->discardTextures();
}
-bool TiledTexture::owns(BaseTileTexture* texture)
-{
- for (unsigned int i = 0; i < m_tiles.size(); i++) {
- BaseTile* tile = m_tiles[i];
- if (tile->frontTexture() == texture)
- return true;
- if (tile->backTexture() == texture)
- return true;
- }
- return false;
-}
-
-DualTiledTexture::DualTiledTexture(SurfacePainter* surface)
+DualTiledTexture::DualTiledTexture(bool isBaseSurface)
{
- m_textureA = new TiledTexture(surface);
- m_textureB = new TiledTexture(surface);
- m_frontTexture = m_textureA;
- m_backTexture = m_textureB;
+ m_frontTexture = new TiledTexture(isBaseSurface);
+ m_backTexture = new TiledTexture(isBaseSurface);
m_scale = -1;
m_futureScale = -1;
m_zooming = false;
@@ -353,17 +374,22 @@ DualTiledTexture::DualTiledTexture(SurfacePainter* surface)
DualTiledTexture::~DualTiledTexture()
{
- delete m_textureA;
- delete m_textureB;
+ delete m_frontTexture;
+ delete m_backTexture;
}
-void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint,
- bool startFastSwap, IntRect& visibleArea)
+void DualTiledTexture::prepareGL(GLWebViewState* state, bool allowZoom,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool aggressiveRendering)
{
- // 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_preZoomVisibleArea = visibleArea;
+ 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;
@@ -371,43 +397,55 @@ void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint,
m_zooming = true;
}
- XLOG("Preparing DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d",
- this, scale, m_scale, m_futureScale, m_zooming);
+ bool useExpandPrefetch = aggressiveRendering;
+ 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_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
+ swapTiledTextures();
- if (m_scale > 0)
- m_frontTexture->prepare(state, m_scale, repaint, startFastSwap, m_preZoomVisibleArea);
+ m_frontTexture->swapTiles();
+ m_backTexture->discardTextures();
- // If we had a scheduled update
- if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) {
- m_backTexture->prepare(state, m_futureScale, repaint, startFastSwap, visibleArea);
- if (m_backTexture->ready()) {
- m_backTexture->swapTiles();
- swap();
+ m_scale = m_futureScale;
m_zooming = false;
}
}
}
-void DualTiledTexture::swap()
+bool DualTiledTexture::drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform,
+ bool aggressiveRendering, const Color* background)
{
- 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();
-}
+ // draw low res prefetch page, if needed
+ if (aggressiveRendering && !m_zooming && m_frontTexture->isMissingContent())
+ m_backTexture->drawGL(visibleArea, opacity, transform);
-bool DualTiledTexture::draw()
-{
- bool needsRepaint = m_frontTexture->draw();
+ bool needsRepaint = m_frontTexture->drawGL(visibleArea, opacity, transform, background);
needsRepaint |= m_zooming;
needsRepaint |= (m_scale <= 0);
return needsRepaint;
}
-void DualTiledTexture::update(const SkRegion& dirtyArea, SkPicture* picture)
+void DualTiledTexture::markAsDirty(const SkRegion& dirtyArea)
{
- m_backTexture->update(dirtyArea, picture);
- m_frontTexture->update(dirtyArea, picture);
+ m_backTexture->markAsDirty(dirtyArea);
+ m_frontTexture->markAsDirty(dirtyArea);
}
void DualTiledTexture::swapTiles()
@@ -416,11 +454,46 @@ void DualTiledTexture::swapTiles()
m_frontTexture->swapTiles();
}
-bool DualTiledTexture::owns(BaseTileTexture* texture)
+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;
+}
+
+void DualTiledTexture::swapTiledTextures()
{
- bool owns = m_textureA->owns(texture);
- owns |= m_textureB->owns(texture);
- return owns;
+ TiledTexture* 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/TiledTexture.h
index 444ab14..2e19cea 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.h
+++ b/Source/WebCore/platform/graphics/android/TiledTexture.h
@@ -31,6 +31,7 @@
#include "ClassTracker.h"
#include "IntRect.h"
#include "LayerAndroid.h"
+#include "SkRefCnt.h"
#include "SkRegion.h"
#include "TextureOwner.h"
#include "TilePainter.h"
@@ -39,15 +40,12 @@ class SkCanvas;
namespace WebCore {
-class TiledTexture : public TilePainter {
+class TiledTexture {
public:
- TiledTexture(SurfacePainter* surface)
- : m_paintingPicture(0)
- , m_surface(surface)
- , m_prevTileX(0)
- , m_prevTileY(0)
+ TiledTexture(bool isBaseSurface)
+ : m_prevTileY(0)
, m_scale(1)
- , m_swapWhateverIsReady(false)
+ , m_isBaseSurface(isBaseSurface)
{
m_dirtyRegion.setEmpty();
#ifdef DEBUG_COUNT
@@ -57,69 +55,66 @@ public:
virtual ~TiledTexture();
- IntRect computeTilesArea(IntRect& visibleArea, float scale);
+ static IntRect computeTilesArea(const IntRect& contentArea, float scale);
- void prepare(GLWebViewState* state, float scale, bool repaint,
- bool startFastSwap, IntRect& visibleArea);
+ void prepareGL(GLWebViewState* state, float scale,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool isLowResPrefetch = false,
+ bool useExpandPrefetch = false);
void swapTiles();
- bool draw();
+ bool drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform, const Color* background = 0);
- void prepareTile(bool repaint, int x, int y);
- void update(const SkRegion& dirtyArea, SkPicture* picture);
+ void prepareTile(int x, int y, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch);
+ void markAsDirty(const SkRegion& dirtyArea);
BaseTile* getTile(int x, int y);
void removeTiles();
void discardTextures();
- bool owns(BaseTileTexture* texture);
- // TilePainter methods
- bool paint(BaseTile* tile, SkCanvas*, unsigned int*);
- virtual const TransformationMatrix* transform();
-
- float scale() { return m_scale; }
- bool ready();
+ bool isReady();
+ bool isMissingContent();
int nbTextures(IntRect& area, float scale);
private:
- bool tileIsVisible(BaseTile* tile);
-
- // protect m_paintingPicture
- // update() on UI thread modifies
- // paint() on texture gen thread reads
- android::Mutex m_paintingPictureSync;
- SkPicture* m_paintingPicture;
-
- SurfacePainter* m_surface;
+ void drawMissingRegion(const SkRegion& region, float opacity, const Color* tileBackground);
Vector<BaseTile*> m_tiles;
- // tile coordinates in viewport, set in prepare()
IntRect m_area;
SkRegion m_dirtyRegion;
- int m_prevTileX;
int m_prevTileY;
float m_scale;
- bool m_swapWhateverIsReady;
+ bool m_isBaseSurface;
};
-class DualTiledTexture {
+class DualTiledTexture : public SkRefCnt {
+// TODO: investigate webkit threadsafe ref counting
public:
- DualTiledTexture(SurfacePainter* surface);
+ DualTiledTexture(bool isBaseSurface);
~DualTiledTexture();
- void prepare(GLWebViewState* state, float scale, bool repaint,
- bool startFastSwap, IntRect& area);
+ void prepareGL(GLWebViewState* state, bool allowZoom,
+ const IntRect& prepareArea, const IntRect& unclippedArea,
+ TilePainter* painter, bool aggressiveRendering);
void swapTiles();
- void swap();
- bool draw();
- void update(const SkRegion& dirtyArea, SkPicture* picture);
- bool owns(BaseTileTexture* texture);
+ bool drawGL(const IntRect& visibleArea, float opacity,
+ const TransformationMatrix* transform, bool aggressiveRendering,
+ const Color* background);
+ void markAsDirty(const SkRegion& dirtyArea);
+ void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer);
+ void discardTextures()
+ {
+ m_frontTexture->discardTextures();
+ m_backTexture->discardTextures();
+ }
bool isReady()
{
- return !m_zooming && m_frontTexture->ready();
+ return !m_zooming && m_frontTexture->isReady();
}
int nbTextures(IntRect& area, float scale)
@@ -131,18 +126,17 @@ public:
}
private:
+ void swapTiledTextures();
+
// Delay before we schedule a new tile at the new scale factor
static const double s_zoomUpdateDelay = 0.2; // 200 ms
TiledTexture* m_frontTexture;
TiledTexture* m_backTexture;
- TiledTexture* m_textureA;
- TiledTexture* m_textureB;
float m_scale;
float m_futureScale;
double m_zoomUpdateTime;
bool m_zooming;
- IntRect m_preZoomVisibleArea;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index 62324d7..eeedc07 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -23,13 +23,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "TilesManager"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "TilesManager.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "BaseTile.h"
-#include "PaintedSurface.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPaint.h"
@@ -37,26 +40,7 @@
#include <cutils/atomic.h>
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
-
-
-#include <cutils/log.h>
#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TilesManager", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesManager", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
// Important: We need at least twice as many textures as is needed to cover
// one viewport, otherwise the allocation may stall.
@@ -72,8 +56,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
@@ -96,30 +78,34 @@ int TilesManager::getMaxTextureAllocation()
TilesManager::TilesManager()
: m_layerTexturesRemain(true)
+ , m_highEndGfx(false)
, m_maxTextureCount(0)
, m_maxLayerTextureCount(0)
, m_generatorReady(false)
, m_showVisualIndicator(false)
, m_invertedScreen(false)
- , m_invertedScreenSwitch(false)
, m_useMinimalMemory(true)
+ , m_useDoubleBuffering(true)
+ , m_contentUpdates(0)
+ , m_webkitContentUpdates(0)
+ , m_queue(0)
, m_drawGLCount(1)
, m_lastTimeLayersUsed(0)
, m_hasLayerTextures(false)
{
- XLOG("TilesManager ctor");
+ ALOGV("TilesManager ctor");
m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
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");
}
void TilesManager::allocateTiles()
{
int nbTexturesToAllocate = m_maxTextureCount - m_textures.size();
- XLOG("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_maxTextureCount);
+ 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(
@@ -134,12 +120,12 @@ void TilesManager::allocateTiles()
}
int nbLayersTexturesToAllocate = m_maxLayerTextureCount - m_tilesTextures.size();
- XLOG("%d layers tiles to allocate (%d textures planned)",
- nbLayersTexturesToAllocate, m_maxLayerTextureCount);
+ ALOGV("%d layers tiles to allocate (%d textures planned)",
+ nbLayersTexturesToAllocate, m_maxLayerTextureCount);
int nbLayersTexturesAllocated = 0;
for (int i = 0; i < nbLayersTexturesToAllocate; i++) {
BaseTileTexture* texture = new BaseTileTexture(
- layerTileWidth(), layerTileHeight());
+ 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 =
@@ -148,14 +134,14 @@ void TilesManager::allocateTiles()
m_tilesTextures.append(loadedTexture);
nbLayersTexturesAllocated++;
}
- XLOG("allocated %d textures for base (total: %d, %d Mb), %d textures for layers (total: %d, %d Mb)",
- 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);
+ ALOGV("allocated %d textures for base (total: %d, %d Mb), %d textures for layers (total: %d, %d Mb)",
+ nbTexturesAllocated, m_textures.size(),
+ m_textures.size() * TILE_WIDTH * TILE_HEIGHT * 4 / 1024 / 1024,
+ nbLayersTexturesAllocated, m_tilesTextures.size(),
+ m_tilesTextures.size() * tileWidth() * tileHeight() * 4 / 1024 / 1024);
}
-void TilesManager::deallocateTextures(bool allTextures)
+void TilesManager::discardTextures(bool allTextures, bool glTextures)
{
const unsigned int max = m_textures.size();
@@ -169,24 +155,52 @@ void TilesManager::deallocateTextures(bool allTextures)
sparedDrawCount = std::max(sparedDrawCount, owner->drawCount());
}
}
- deallocateTexturesVector(sparedDrawCount, m_textures);
- deallocateTexturesVector(sparedDrawCount, m_tilesTextures);
+ discardTexturesVector(sparedDrawCount, m_textures, glTextures);
+ discardTexturesVector(sparedDrawCount, m_tilesTextures, glTextures);
}
-void TilesManager::deallocateTexturesVector(unsigned long long sparedDrawCount,
- WTF::Vector<BaseTileTexture*>& textures)
+void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount,
+ WTF::Vector<BaseTileTexture*>& textures,
+ bool deallocateGLTextures)
{
const unsigned int max = textures.size();
int dealloc = 0;
+ WTF::Vector<int> discardedIndex;
for (unsigned int i = 0; i < max; i++) {
TextureOwner* owner = textures[i]->owner();
if (!owner || owner->drawCount() < sparedDrawCount) {
- textures[i]->discardGLTexture();
+ if (deallocateGLTextures) {
+ // deallocate textures' gl memory
+ textures[i]->discardGLTexture();
+ discardedIndex.append(i);
+ } else if (owner) {
+ // simply detach textures from owner
+ static_cast<BaseTile*>(owner)->discardTextures();
+ }
dealloc++;
}
}
- XLOG("Deallocated %d gl textures (out of %d base tiles and %d layer tiles)",
- dealloc, max, maxLayer);
+
+ bool base = textures == m_textures;
+ // Clean up the vector of BaseTileTextures and reset the max texture count.
+ if (discardedIndex.size()) {
+ android::Mutex::Autolock lock(m_texturesLock);
+ for (int i = discardedIndex.size() - 1; i >= 0; i--)
+ textures.remove(discardedIndex[i]);
+
+ int remainedTextureNumber = textures.size();
+ int* countPtr = base ? &m_maxTextureCount : &m_maxLayerTextureCount;
+ if (remainedTextureNumber < *countPtr) {
+ ALOGV("reset maxTextureCount for %s tiles from %d to %d",
+ base ? "base" : "layer", *countPtr, remainedTextureNumber);
+ *countPtr = remainedTextureNumber;
+ }
+
+ }
+
+ ALOGV("Discarded %d %s textures (out of %d %s tiles)",
+ dealloc, (deallocateGLTextures ? "gl" : ""),
+ max, base ? "base" : "layer");
}
void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
@@ -209,7 +223,7 @@ void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextur
void TilesManager::printTextures()
{
#ifdef DEBUG
- XLOG("++++++");
+ ALOGV("++++++");
for (unsigned int i = 0; i < m_textures.size(); i++) {
BaseTileTexture* texture = m_textures[i];
BaseTile* o = 0;
@@ -221,28 +235,18 @@ void TilesManager::printTextures()
x = o->x();
y = o->y();
}
- XLOG("[%d] texture %x busy: %d owner: %x (%d, %d) page: %x scale: %.2f",
- i, texture,
- texture->busy(), o, x, y, o ? o->page() : 0, o ? o->scale() : 0);
+ 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);
}
- XLOG("------");
+ ALOGV("------");
#endif // DEBUG
}
-void TilesManager::addPaintedSurface(PaintedSurface* surface)
-{
- m_paintedSurfaces.append(surface);
-}
-
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;
}
@@ -253,8 +257,8 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
// Sanity check that the tile does not already own a texture
if (owner->backTexture() && owner->backTexture()->owner() == owner) {
- XLOG("same owner (%d, %d), getAvailableBackTexture(%x) => texture %x",
- owner->x(), owner->y(), owner, owner->backTexture());
+ ALOGV("same owner (%d, %d), getAvailableBackTexture(%x) => texture %x",
+ owner->x(), owner->y(), owner, owner->backTexture());
if (owner->isLayerTile())
m_availableTilesTextures.remove(m_availableTilesTextures.find(owner->backTexture()));
else
@@ -274,9 +278,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
// busy anyway
// 2. If a tile isn't owned, break with that one
// 3. Don't let tiles acquire their front textures
- // 4. If we find a tile in the same page with a different scale,
- // it's old and not visible. Break with that one
- // 5. Otherwise, use the least recently prepared tile, but ignoring tiles
+ // 4. Otherwise, use the least recently prepared tile, but ignoring tiles
// drawn in the last frame to avoid flickering
BaseTileTexture* farthestTexture = 0;
@@ -285,12 +287,6 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
for (unsigned int i = 0; i < max; i++) {
BaseTileTexture* texture = (*availableTexturePool)[i];
BaseTile* currentOwner = static_cast<BaseTile*>(texture->owner());
-
- if (texture->busy()) {
- // don't bother, since the acquire() will likely fail
- continue;
- }
-
if (!currentOwner) {
// unused texture! take it!
farthestTexture = texture;
@@ -303,14 +299,6 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
continue;
}
- if (currentOwner->painter() == owner->painter() && texture->scale() != owner->scale()) {
- // if we render the back page with one scale, then another while
- // still zooming, we recycle the tiles with the old scale instead of
- // taking ones from the front page
- farthestTexture = texture;
- break;
- }
-
unsigned long long textureDrawCount = currentOwner->drawCount();
if (oldestDrawCount > textureDrawCount) {
farthestTexture = texture;
@@ -324,11 +312,11 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
if (previousOwner) {
previousOwner->removeTexture(farthestTexture);
- XLOG("%s texture %p stolen from tile %d, %d for %d, %d, drawCount was %llu (now %llu)",
- owner->isLayerTile() ? "LAYER" : "BASE",
- farthestTexture, previousOwner->x(), previousOwner->y(),
- owner->x(), owner->y(),
- oldestDrawCount, getDrawGLCount());
+ ALOGV("%s texture %p stolen from tile %d, %d for %d, %d, drawCount was %llu (now %llu)",
+ owner->isLayerTile() ? "LAYER" : "BASE",
+ farthestTexture, previousOwner->x(), previousOwner->y(),
+ owner->x(), owner->y(),
+ oldestDrawCount, getDrawGLCount());
}
availableTexturePool->remove(availableTexturePool->find(farthestTexture));
@@ -343,7 +331,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
}
}
- XLOG("Couldn't find an available texture for %s tile %x (%d, %d) out of %d available",
+ ALOGV("Couldn't find an available texture for %s tile %x (%d, %d) out of %d available",
owner->isLayerTile() ? "LAYER" : "BASE",
owner, owner->x(), owner->y(), max);
#ifdef DEBUG
@@ -352,6 +340,16 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return 0;
}
+void TilesManager::setHighEndGfx(bool highEnd)
+{
+ m_highEndGfx = highEnd;
+}
+
+bool TilesManager::highEndGfx()
+{
+ return m_highEndGfx;
+}
+
int TilesManager::maxTextureCount()
{
android::Mutex::Autolock lock(m_texturesLock);
@@ -366,7 +364,7 @@ int TilesManager::maxLayerTextureCount()
void TilesManager::setMaxTextureCount(int max)
{
- XLOG("setMaxTextureCount: %d (current: %d, total:%d)",
+ ALOGV("setMaxTextureCount: %d (current: %d, total:%d)",
max, m_maxTextureCount, MAX_TEXTURE_ALLOCATION);
if (m_maxTextureCount == MAX_TEXTURE_ALLOCATION ||
max <= m_maxTextureCount)
@@ -384,13 +382,14 @@ void TilesManager::setMaxTextureCount(int max)
void TilesManager::setMaxLayerTextureCount(int max)
{
- XLOG("setMaxLayerTextureCount: %d (current: %d, total:%d)",
+ ALOGV("setMaxLayerTextureCount: %d (current: %d, total:%d)",
max, m_maxLayerTextureCount, MAX_TEXTURE_ALLOCATION);
if (!max && m_hasLayerTextures) {
double secondsSinceLayersUsed = WTF::currentTime() - m_lastTimeLayersUsed;
if (secondsSinceLayersUsed > LAYER_TEXTURES_DESTROY_TIMEOUT) {
unsigned long long sparedDrawCount = ~0; // by default, spare no textures
- deallocateTexturesVector(sparedDrawCount, m_tilesTextures);
+ bool deleteGLTextures = true;
+ discardTexturesVector(sparedDrawCount, m_tilesTextures, deleteGLTextures);
m_hasLayerTextures = false;
}
return;
@@ -411,6 +410,15 @@ void TilesManager::setMaxLayerTextureCount(int max)
m_hasLayerTextures = true;
}
+TransferQueue* TilesManager::transferQueue()
+{
+ // 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;
+}
float TilesManager::tileWidth()
{
@@ -422,75 +430,11 @@ float TilesManager::tileHeight()
return TILE_HEIGHT;
}
-float TilesManager::layerTileWidth()
-{
- return LAYER_TILE_WIDTH;
-}
-
-float TilesManager::layerTileHeight()
-{
- return LAYER_TILE_HEIGHT;
-}
-
-void TilesManager::paintedSurfacesCleanup(GLWebViewState* state)
-{
- // PaintedSurfaces are created by LayerAndroid with a refcount of 1,
- // and just transferred to new (corresponding) layers when a new layer tree
- // is received.
- // PaintedSurface also keep a reference on the Layer it currently has, so
- // when we unref the tree of layer, those layers with a PaintedSurface will
- // still be around if we do nothing.
- // Here, if the surface does not have any associated layer, it means that we
- // received a new layer tree without a corresponding layer (i.e. a layer
- // using a texture has been removed by webkit).
- // In that case, we remove the PaintedSurface from our list, and unref it.
- // If the surface does have a layer, but the GLWebViewState associated to
- // that layer is different from the one passed in parameter, it means we can
- // also remove the surface (and we also remove/unref any layer that surface
- // has). We do this when we deallocate GLWebViewState (i.e. the webview has
- // been destroyed) and also when we switch to a page without
- // composited layers.
-
- WTF::Vector<PaintedSurface*> collect;
- for (unsigned int i = 0; i < m_paintedSurfaces.size(); i++) {
- PaintedSurface* surface = m_paintedSurfaces[i];
-
- Layer* drawing = surface->drawingLayer();
- Layer* painting = surface->paintingLayer();
-
- XLOG("considering PS %p, drawing %p, painting %p", surface, drawing, painting);
-
- bool drawingMatchesState = state && drawing && (drawing->state() == state);
- bool paintingMatchesState = state && painting && (painting->state() == state);
-
- if ((!painting && !drawing) || drawingMatchesState || paintingMatchesState) {
- XLOG("trying to remove PS %p, painting %p, drawing %p, DMS %d, PMS %d",
- surface, painting, drawing, drawingMatchesState, paintingMatchesState);
- collect.append(surface);
- }
- }
- for (unsigned int i = 0; i < collect.size(); i++) {
- PaintedSurface* surface = collect[i];
- m_paintedSurfaces.remove(m_paintedSurfaces.find(surface));
- SkSafeUnref(surface);
- }
-}
-
-void TilesManager::unregisterGLWebViewState(GLWebViewState* state)
-{
- // Discard the whole queue b/c we lost GL context already.
- // Note the real updateTexImage will still wait for the next draw.
- transferQueue()->discardQueue();
-}
-
TilesManager* TilesManager::instance()
{
if (!gInstance) {
gInstance = new TilesManager();
- XLOG("instance(), new gInstance is %x", gInstance);
- XLOG("Waiting for the generator...");
- gInstance->waitForGenerator();
- XLOG("Generator ready!");
+ ALOGV("instance(), new gInstance is %x", gInstance);
}
return gInstance;
}
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 9782fbb..05fc1af 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -35,9 +35,7 @@
#include "ShaderProgram.h"
#include "SkBitmapRef.h"
#include "TexturesGenerator.h"
-#include "TiledPage.h"
#include "TilesProfiler.h"
-#include "TilesTracker.h"
#include "TransferQueue.h"
#include "VideoLayerManager.h"
#include <utils/threads.h>
@@ -45,10 +43,9 @@
namespace WebCore {
-class PaintedSurface;
-
class TilesManager {
public:
+ // May only be called from the UI thread
static TilesManager* instance();
static GLint getMaxTextureSize();
static int getMaxTextureAllocation();
@@ -63,29 +60,15 @@ 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);
}
- void swapLayersTextures(LayerAndroid* newTree, LayerAndroid* oldTree);
- void addPaintedSurface(PaintedSurface* surface);
-
ShaderProgram* shader() { return &m_shader; }
- TransferQueue* transferQueue() { return &m_queue; }
+ TransferQueue* transferQueue();
VideoLayerManager* videoLayerManager() { return &m_videoLayerManager; }
- void gatherLayerTextures();
void gatherTextures();
bool layerTexturesRemain() { return m_layerTexturesRemain; }
void gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
@@ -93,18 +76,11 @@ public:
BaseTileTexture* getAvailableTexture(BaseTile* owner);
- void markGeneratorAsReady()
- {
- {
- android::Mutex::Autolock lock(m_generatorLock);
- m_generatorReady = true;
- }
- m_generatorReadyCond.signal();
- }
-
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();
int maxTextureCount();
int maxLayerTextureCount();
@@ -112,15 +88,11 @@ public:
void setMaxLayerTextureCount(int max);
static float tileWidth();
static float tileHeight();
- static float layerTileWidth();
- static float layerTileHeight();
- void paintedSurfacesCleanup(GLWebViewState* state = 0);
- void unregisterGLWebViewState(GLWebViewState* state);
void allocateTiles();
- // Called when webview is hidden to discard graphics memory
- void deallocateTextures(bool allTextures);
+ // remove all tiles from textures (and optionally deallocate gl memory)
+ void discardTextures(bool allTextures, bool glTextures);
bool getShowVisualIndicator()
{
@@ -132,43 +104,21 @@ public:
m_showVisualIndicator = showVisualIndicator;
}
- SharedTextureMode getSharedTextureMode()
- {
- return SurfaceTextureMode;
- }
-
TilesProfiler* getProfiler()
{
return &m_profiler;
}
- TilesTracker* getTilesTracker()
- {
- return &m_tilesTracker;
- }
-
bool invertedScreen()
{
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);
@@ -184,6 +134,19 @@ public:
return m_useMinimalMemory;
}
+ void setUseDoubleBuffering(bool useDoubleBuffering)
+ {
+ m_useDoubleBuffering = useDoubleBuffering;
+ }
+ bool useDoubleBuffering() { return m_useDoubleBuffering; }
+
+
+ unsigned int incWebkitContentUpdates() { return m_webkitContentUpdates++; }
+
+ void incContentUpdates() { m_contentUpdates++; }
+ unsigned int getContentUpdates() { return m_contentUpdates; }
+ void clearContentUpdates() { m_contentUpdates = 0; }
+
void incDrawGLCount()
{
m_drawGLCount++;
@@ -194,23 +157,12 @@ public:
return m_drawGLCount;
}
- int getPaintedSurfaceCount()
- {
- return m_paintedSurfaces.size();
- }
-
private:
TilesManager();
- void waitForGenerator()
- {
- android::Mutex::Autolock lock(m_generatorLock);
- while (!m_generatorReady)
- m_generatorReadyCond.wait(m_generatorLock);
- }
-
- void deallocateTexturesVector(unsigned long long sparedDrawCount,
- WTF::Vector<BaseTileTexture*>& textures);
+ void discardTexturesVector(unsigned long long sparedDrawCount,
+ WTF::Vector<BaseTileTexture*>& textures,
+ bool deallocateGLTextures);
Vector<BaseTileTexture*> m_textures;
Vector<BaseTileTexture*> m_availableTextures;
@@ -219,8 +171,7 @@ private:
Vector<BaseTileTexture*> m_availableTilesTextures;
bool m_layerTexturesRemain;
- Vector<PaintedSurface*> m_paintedSurfaces;
-
+ bool m_highEndGfx;
int m_maxTextureCount;
int m_maxLayerTextureCount;
@@ -228,25 +179,25 @@ private:
bool m_showVisualIndicator;
bool m_invertedScreen;
- bool m_invertedScreenSwitch;
bool m_useMinimalMemory;
+ bool m_useDoubleBuffering;
+ unsigned int m_contentUpdates; // nr of successful tiled paints
+ unsigned int m_webkitContentUpdates; // nr of paints from webkit
+
sp<TexturesGenerator> m_pixmapsGenerationThread;
android::Mutex m_texturesLock;
- android::Mutex m_generatorLock;
- android::Condition m_generatorReadyCond;
static TilesManager* gInstance;
ShaderProgram m_shader;
- TransferQueue m_queue;
+ TransferQueue* m_queue;
VideoLayerManager m_videoLayerManager;
TilesProfiler m_profiler;
- TilesTracker m_tilesTracker;
unsigned long long m_drawGLCount;
double m_lastTimeLayersUsed;
bool m_hasLayerTextures;
diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp b/Source/WebCore/platform/graphics/android/TilesProfiler.cpp
index 0271ee3..2cc6873 100644
--- a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesProfiler.cpp
@@ -23,29 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "TilesProfiler"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "TilesProfiler.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesProfiler", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
// Hard limit on amount of frames (and thus memory) profiling can take
#define MAX_PROF_FRAMES 400
#define INVAL_CODE -2
@@ -63,19 +52,19 @@ void TilesProfiler::start()
m_badTiles = 0;
m_records.clear();
m_time = currentTimeMS();
- XLOG("initializing tileprofiling");
+ ALOGV("initializing tileprofiling");
}
float TilesProfiler::stop()
{
m_enabled = false;
- XLOG("completed tile profiling, observed %d frames", m_records.size());
+ ALOGV("completed tile profiling, observed %d frames", m_records.size());
return (1.0 * m_goodTiles) / (m_goodTiles + m_badTiles);
}
void TilesProfiler::clear()
{
- XLOG("clearing tile profiling of its %d frames", m_records.size());
+ ALOGV("clearing tile profiling of its %d frames", m_records.size());
m_records.clear();
}
@@ -90,8 +79,8 @@ void TilesProfiler::nextFrame(int left, int top, int right, int bottom, float sc
#ifdef DEBUG
if (m_records.size() != 0) {
- XLOG("completed tile profiling frame, observed %d tiles. %f ms since last",
- m_records[0].size(), timeDelta);
+ ALOGD("completed tile profiling frame, observed %d tiles. %f ms since last",
+ m_records[0].size(), timeDelta);
}
#endif // DEBUG
@@ -103,14 +92,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(BaseTile* 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();
@@ -122,20 +111,20 @@ void TilesProfiler::nextTile(BaseTile& tile, float scale, bool inView)
}
m_records.last().append(TileProfileRecord(
left, top, right, bottom,
- scale, isReady, (int)tile.drawCount()));
- XLOG("adding tile %d %d %d %d, scale %f", left, top, right, bottom, scale);
+ 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));
- XLOG("adding inval region %d %d %d %d, scale %f", rect.x(), rect.y(),
- rect.maxX(), rect.maxY(), scale);
+ rect.right(), rect.bottom(), scale, false, INVAL_CODE));
+ ALOGV("adding inval region %d %d %d %d, scale %f", rect.x(), rect.y(),
+ rect.right(), rect.bottom(), scale);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.h b/Source/WebCore/platform/graphics/android/TilesProfiler.h
index 286d350..a13d471 100644
--- a/Source/WebCore/platform/graphics/android/TilesProfiler.h
+++ b/Source/WebCore/platform/graphics/android/TilesProfiler.h
@@ -58,8 +58,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(BaseTile* tile, float scale, bool inView);
+ void nextInval(const SkIRect& rect, float scale);
int numFrames() {
return m_records.size();
};
@@ -72,6 +72,8 @@ public:
return &m_records[frame][tile];
}
+ bool enabled() { return m_enabled; }
+
private:
bool m_enabled;
unsigned int m_goodTiles;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index 73cc570..a3552ac 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -23,35 +23,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "TransferQueue"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "TransferQueue.h"
#if USE(ACCELERATED_COMPOSITING)
+#include "AndroidLog.h"
#include "BaseTile.h"
-#include "PaintedSurface.h"
+#include "GLUtils.h"
+#include "TilesManager.h"
#include <android/native_window.h>
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <wtf/text/CString.h>
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TransferQueue", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TransferQueue", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-#define ST_BUFFER_NUMBER 6
+// For simple webView usage, MINIMAL_SIZE is recommended for memory saving.
+// In browser case, EFFICIENT_SIZE is preferred.
+#define MINIMAL_SIZE 1
+#define EFFICIENT_SIZE 6
// Set this to 1 if we would like to take the new GpuUpload approach which
// relied on the glCopyTexSubImage2D instead of a glDraw call
@@ -59,7 +50,7 @@
namespace WebCore {
-TransferQueue::TransferQueue()
+TransferQueue::TransferQueue(bool useMinimalMem)
: m_eglSurface(EGL_NO_SURFACE)
, m_transferQueueIndex(0)
, m_fboID(0)
@@ -70,43 +61,55 @@ TransferQueue::TransferQueue()
, m_currentUploadType(DEFAULT_UPLOAD_TYPE)
{
memset(&m_GLStateBeforeBlit, 0, sizeof(m_GLStateBeforeBlit));
-
- m_emptyItemCount = ST_BUFFER_NUMBER;
-
- m_transferQueue = new TileTransferData[ST_BUFFER_NUMBER];
-
- // Two bugs made the GPU upload path unreliable on the GPU-accelerated
- // emulator. The bugs are being fixed in later branches, but the fixes are
- // too risky for this branch. Default to the CpuUpload path for now.
- char qemuProp[PROPERTY_VALUE_MAX + 1];
- property_get("ro.kernel.qemu", qemuProp, "0");
- if (atoi(qemuProp) == 1)
- m_currentUploadType = CpuUpload;
+ m_transferQueueSize = useMinimalMem ? MINIMAL_SIZE : EFFICIENT_SIZE;
+ m_emptyItemCount = m_transferQueueSize;
+ m_transferQueue = new TileTransferData[m_transferQueueSize];
}
TransferQueue::~TransferQueue()
{
- glDeleteFramebuffers(1, &m_fboID);
- m_fboID = 0;
- glDeleteTextures(1, &m_sharedSurfaceTextureId);
- m_sharedSurfaceTextureId = 0;
-
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ cleanupGLResources();
delete[] m_transferQueue;
}
-void TransferQueue::initSharedSurfaceTextures(int width, int height)
+// This should be called within the m_transferQueueItemLocks.
+// Now only called by emptyQueue() and destructor.
+void TransferQueue::cleanupGLResources()
+{
+ if (m_sharedSurfaceTexture.get()) {
+ m_sharedSurfaceTexture->abandon();
+ m_sharedSurfaceTexture.clear();
+ }
+ if (m_fboID) {
+ glDeleteFramebuffers(1, &m_fboID);
+ m_fboID = 0;
+ }
+ if (m_sharedSurfaceTextureId) {
+ glDeleteTextures(1, &m_sharedSurfaceTextureId);
+ m_sharedSurfaceTextureId = 0;
+ }
+}
+
+void TransferQueue::initGLResources(int width, int height)
{
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
if (!m_sharedSurfaceTextureId) {
glGenTextures(1, &m_sharedSurfaceTextureId);
m_sharedSurfaceTexture =
#if GPU_UPLOAD_WITHOUT_DRAW
- new android::SurfaceTexture(m_sharedSurfaceTextureId, true, GL_TEXTURE_2D);
+ new android::SurfaceTexture(m_sharedSurfaceTextureId, true,
+ GL_TEXTURE_2D, false);
#else
new android::SurfaceTexture(m_sharedSurfaceTextureId);
#endif
m_ANW = new android::SurfaceTextureClient(m_sharedSurfaceTexture);
m_sharedSurfaceTexture->setSynchronousMode(true);
- m_sharedSurfaceTexture->setBufferCount(ST_BUFFER_NUMBER+1);
+
+ int extraBuffersNeeded = 0;
+ m_ANW->query(m_ANW.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+ &extraBuffersNeeded);
+ m_sharedSurfaceTexture->setBufferCount(m_transferQueueSize + extraBuffersNeeded);
int result = native_window_set_buffers_geometry(m_ANW.get(),
width, height, HAL_PIXEL_FORMAT_RGBA_8888);
@@ -123,27 +126,18 @@ void TransferQueue::initSharedSurfaceTextures(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
// the content is discarded.
-bool TransferQueue::checkObsolete(int index)
+bool TransferQueue::checkObsolete(const TileTransferData* data)
{
- BaseTile* baseTilePtr = m_transferQueue[index].savedBaseTilePtr;
+ BaseTile* baseTilePtr = data->savedBaseTilePtr;
if (!baseTilePtr) {
- XLOG("Invalid savedBaseTilePtr , such that the tile is obsolete");
+ ALOGV("Invalid savedBaseTilePtr , such that the tile is obsolete");
return true;
}
BaseTileTexture* baseTileTexture = baseTilePtr->backTexture();
- if (!baseTileTexture) {
- XLOG("Invalid baseTileTexture , such that the tile is obsolete");
- return true;
- }
-
- const TextureTileInfo* tileInfo = &m_transferQueue[index].tileInfo;
-
- if (tileInfo->m_x != baseTilePtr->x()
- || tileInfo->m_y != baseTilePtr->y()
- || tileInfo->m_scale != baseTilePtr->scale()
- || tileInfo->m_painter != baseTilePtr->painter()) {
- XLOG("Mismatching x, y, scale or painter , such that the tile is obsolete");
+ if (!baseTileTexture || baseTileTexture != data->savedBaseTileTexturePtr) {
+ ALOGV("Invalid baseTileTexture %p (vs expected %p), such that the tile is obsolete",
+ baseTileTexture, data->savedBaseTileTexturePtr);
return true;
}
@@ -151,20 +145,46 @@ bool TransferQueue::checkObsolete(int index)
}
void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
+ BaseTileTexture* frontTex,
GLuint srcTexId, GLenum srcTexTarget,
int index)
{
#if GPU_UPLOAD_WITHOUT_DRAW
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
+ glBindTexture(GL_TEXTURE_2D, destTex->m_ownTextureId);
+
+ int textureWidth = destTex->getSize().width();
+ int textureHeight = destTex->getSize().height();
+
+ IntRect inval = m_transferQueue[index].invalRect;
+ bool partialInval = !inval.isEmpty();
+
+ if (partialInval && frontTex) {
+ // recopy the previous texture to the new one, as
+ // the partial update will not cover the entire texture
+ glFramebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ frontTex->m_ownTextureId,
+ 0);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
+ textureWidth, textureHeight);
+ }
+
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
srcTexId,
0);
- glBindTexture(GL_TEXTURE_2D, destTex->m_ownTextureId);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
- destTex->getSize().width(),
- destTex->getSize().height());
+
+ if (!partialInval) {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
+ textureWidth, textureHeight);
+ } else {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), 0, 0,
+ inval.width(), inval.height());
+ }
+
#else
// Then set up the FBO and copy the SurfTex content in.
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
@@ -177,7 +197,7 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
destTex->getSize().height());
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
- XLOG("Error: glCheckFramebufferStatus failed");
+ ALOGV("Error: glCheckFramebufferStatus failed");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return;
}
@@ -265,15 +285,33 @@ void TransferQueue::setHasGLContext(bool hasContext)
m_hasGLContext = hasContext;
}
-// Only called when WebView is destroyed or switching the uploadType.
-void TransferQueue::discardQueue()
+void TransferQueue::setPendingDiscardWithLock()
{
android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ setPendingDiscard();
+}
+
+void TransferQueue::emptyQueue()
+{
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ setPendingDiscard();
+ cleanupPendingDiscard();
+ cleanupGLResources();
+}
- for (int i = 0 ; i < ST_BUFFER_NUMBER; i++)
+// Set all the content in the queue to pendingDiscard, after this, there will
+// be nothing added to the queue, and this can be called in any thread.
+// However, in order to discard the content in the Surface Texture using
+// updateTexImage, cleanupPendingDiscard need to be called on the UI thread.
+// Must be called within a m_transferQueueItemLocks.
+void TransferQueue::setPendingDiscard()
+{
+ for (int i = 0 ; i < m_transferQueueSize; i++)
if (m_transferQueue[i].status == pendingBlit)
m_transferQueue[i].status = pendingDiscard;
+ m_pureColorTileQueue.clear();
+
bool GLContextExisted = getHasGLContext();
// Unblock the Tex Gen thread first before Tile Page deletion.
// Otherwise, there will be a deadlock while removing operations.
@@ -284,38 +322,67 @@ void TransferQueue::discardQueue()
m_transferQueueItemCond.signal();
}
+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();
+ destTexture->setPureColor(data->pureColor);
+ destTexture->transferComplete();
+ }
+ } else if (data->status == emptyItem || data->status == pendingDiscard) {
+ // The queue should be clear instead of setting to different status.
+ ALOGV("Warning: Don't expect an emptyItem here.");
+ }
+ }
+ m_pureColorTileQueue.clear();
+}
+
// Call on UI thread to copy from the shared Surface Texture to the BaseTile's texture.
void TransferQueue::updateDirtyBaseTiles()
{
android::Mutex::Autolock lock(m_transferQueueItemLocks);
- cleanupTransportQueue();
+ cleanupPendingDiscard();
if (!getHasGLContext())
setHasGLContext(true);
+ // Check the pure color tile first, since it is simpler.
+ updatePureColorTiles();
+
// Start from the oldest item, we call the updateTexImage to retrive
// the texture and blit that into each BaseTile's texture.
const int nextItemIndex = getNextTransferQueueIndex();
int index = nextItemIndex;
bool usedFboForUpload = false;
- for (int k = 0; k < ST_BUFFER_NUMBER ; k++) {
+ for (int k = 0; k < m_transferQueueSize ; k++) {
if (m_transferQueue[index].status == pendingBlit) {
- bool obsoleteBaseTile = checkObsolete(index);
+ bool obsoleteBaseTile = 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;
- if (!obsoleteBaseTile)
+ BaseTileTexture* frontTexture = 0;
+ if (!obsoleteBaseTile) {
destTexture = m_transferQueue[index].savedBaseTilePtr->backTexture();
+ // while destTexture is guaranteed to not be null, frontTexture
+ // might be (first transfer)
+ frontTexture = m_transferQueue[index].savedBaseTilePtr->frontTexture();
+ }
+
if (m_transferQueue[index].uploadType == GpuUpload) {
status_t result = m_sharedSurfaceTexture->updateTexImage();
if (result != OK)
- XLOGC("unexpected error: updateTexImage return %d", result);
+ ALOGE("unexpected error: updateTexImage return %d", result);
}
m_transferQueue[index].savedBaseTilePtr = 0;
m_transferQueue[index].status = emptyItem;
if (obsoleteBaseTile) {
- XLOG("Warning: the texture is obsolete for this baseTile");
- index = (index + 1) % ST_BUFFER_NUMBER;
+ ALOGV("Warning: the texture is obsolete for this baseTile");
+ index = (index + 1) % m_transferQueueSize;
continue;
}
@@ -324,33 +391,29 @@ void TransferQueue::updateDirtyBaseTiles()
if (m_transferQueue[index].uploadType == CpuUpload) {
// Here we just need to upload the bitmap content to the GL Texture
- GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, 0, 0,
- *m_transferQueue[index].bitmap);
+ GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId,
+ *m_transferQueue[index].bitmap,
+ m_transferQueue[index].invalRect);
} else {
if (!usedFboForUpload) {
saveGLState();
usedFboForUpload = true;
}
- blitTileFromQueue(m_fboID, destTexture,
+ blitTileFromQueue(m_fboID, destTexture, frontTexture,
m_sharedSurfaceTextureId,
m_sharedSurfaceTexture->getCurrentTextureTarget(),
index);
}
- // After the base tile copied into the GL texture, we need to
- // update the texture's info such that at draw time, readyFor
- // will find the latest texture's info
- // We don't need a map any more, each texture contains its own
- // texturesTileInfo.
- destTexture->setOwnTextureTileInfoFromQueue(&m_transferQueue[index].tileInfo);
-
- XLOG("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d",
- m_transferQueue[index].tileInfo.m_x,
- m_transferQueue[index].tileInfo.m_y,
- destTexture,
- destTexture->m_ownTextureId);
+ destTexture->setPure(false);
+ destTexture->transferComplete();
+
+ ALOGV("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d",
+ m_transferQueue[index].savedBaseTilePtr,
+ destTexture,
+ destTexture->m_ownTextureId);
}
- index = (index + 1) % ST_BUFFER_NUMBER;
+ index = (index + 1) % m_transferQueueSize;
}
// Clean up FBO setup. Doing this for both CPU/GPU upload can make the
@@ -362,14 +425,14 @@ void TransferQueue::updateDirtyBaseTiles()
GLUtils::checkGlError("updateDirtyBaseTiles");
}
- m_emptyItemCount = ST_BUFFER_NUMBER;
+ m_emptyItemCount = m_transferQueueSize;
m_transferQueueItemCond.signal();
}
void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
- int x, int y, const SkBitmap& bitmap)
+ const SkBitmap& bitmap)
{
- if (!tryUpdateQueueWithBitmap(renderInfo, x, y, bitmap)) {
+ 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;
@@ -379,83 +442,87 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
}
bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
- int x, int y, const SkBitmap& bitmap)
+ const SkBitmap& bitmap)
{
- m_transferQueueItemLocks.lock();
+ // This lock need to cover the full update since it is possible that queue
+ // will be cleaned up in the middle of this update without the lock.
+ // The Surface Texture will not block us since the readyForUpdate will check
+ // availability of the slots in the queue first.
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
bool ready = readyForUpdate();
TextureUploadType currentUploadType = m_currentUploadType;
- m_transferQueueItemLocks.unlock();
if (!ready) {
- XLOG("Quit bitmap update: not ready! for tile x y %d %d",
- renderInfo->x, renderInfo->y);
+ ALOGV("Quit bitmap update: not ready! for tile x y %d %d",
+ renderInfo->x, renderInfo->y);
return false;
}
if (currentUploadType == GpuUpload) {
// a) Dequeue the Surface Texture and write into the buffer
if (!m_ANW.get()) {
- XLOG("ERROR: ANW is null");
+ ALOGV("ERROR: ANW is null");
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, col;
- int bpp = 4; // Now we only deal with RGBA8888 format.
- int width = TilesManager::instance()->tileWidth();
- int height = TilesManager::instance()->tileHeight();
- if (!x && !y && 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();
- } else {
- // TODO: implement the partial invalidate here!
- XLOG("ERROR: don't expect to get here yet before we support partial inval");
- }
-
- ANativeWindow_unlockAndPost(m_ANW.get());
}
- m_transferQueueItemLocks.lock();
// b) After update the Surface Texture, now udpate the transfer queue info.
addItemInTransferQueue(renderInfo, currentUploadType, &bitmap);
- m_transferQueueItemLocks.unlock();
- XLOG("Bitmap updated x, y %d %d, baseTile %p",
- renderInfo->x, renderInfo->y, renderInfo->baseTile);
+ ALOGV("Bitmap updated x, y %d %d, baseTile %p",
+ renderInfo->x, renderInfo->y, renderInfo->baseTile);
return true;
}
+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 = renderInfo->pureColor;
+ m_pureColorTileQueue.append(data);
+}
+
+// Translates the info from TileRenderInfo and others to TileTransferData.
+// This is used by pure color tiles and normal tiles.
+void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
+ TextureUploadType type,
+ TileTransferData* data)
+{
+ data->savedBaseTileTexturePtr = renderInfo->baseTile->backTexture();
+ data->savedBaseTilePtr = renderInfo->baseTile;
+ data->status = pendingBlit;
+ data->uploadType = type;
+
+ IntRect inval(0, 0, 0, 0);
+ if (renderInfo->invalRect) {
+ inval.setX(renderInfo->invalRect->fLeft);
+ inval.setY(renderInfo->invalRect->fTop);
+ inval.setWidth(renderInfo->invalRect->width());
+ inval.setHeight(renderInfo->invalRect->height());
+ }
+ data->invalRect = inval;
+}
+
// Note that there should be lock/unlock around this function call.
// Currently only called by GLUtils::updateSharedSurfaceTextureWithBitmap.
void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
TextureUploadType type,
const SkBitmap* bitmap)
{
- m_transferQueueIndex = (m_transferQueueIndex + 1) % ST_BUFFER_NUMBER;
+ m_transferQueueIndex = (m_transferQueueIndex + 1) % m_transferQueueSize;
int index = m_transferQueueIndex;
if (m_transferQueue[index].savedBaseTilePtr
|| m_transferQueue[index].status != emptyItem) {
- XLOG("ERROR update a tile which is dirty already @ index %d", index);
+ ALOGV("ERROR update a tile which is dirty already @ index %d", index);
}
- m_transferQueue[index].savedBaseTileTexturePtr = renderInfo->baseTile->backTexture();
- m_transferQueue[index].savedBaseTilePtr = renderInfo->baseTile;
- m_transferQueue[index].status = pendingBlit;
- m_transferQueue[index].uploadType = type;
+ TileTransferData* data = &m_transferQueue[index];
+ addItemCommon(renderInfo, type, data);
if (type == CpuUpload && bitmap) {
// Lazily create the bitmap
if (!m_transferQueue[index].bitmap) {
@@ -467,38 +534,28 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
bitmap->copyTo(m_transferQueue[index].bitmap, bitmap->config());
}
- // Now fill the tileInfo.
- TextureTileInfo* textureInfo = &m_transferQueue[index].tileInfo;
-
- textureInfo->m_x = renderInfo->x;
- textureInfo->m_y = renderInfo->y;
- textureInfo->m_scale = renderInfo->scale;
- textureInfo->m_painter = renderInfo->tilePainter;
-
- textureInfo->m_picture = renderInfo->textureInfo->m_pictureCount;
-
m_emptyItemCount--;
}
void TransferQueue::setTextureUploadType(TextureUploadType type)
{
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
if (m_currentUploadType == type)
return;
- discardQueue();
+ setPendingDiscard();
- android::Mutex::Autolock lock(m_transferQueueItemLocks);
m_currentUploadType = type;
- XLOGC("Now we set the upload to %s", m_currentUploadType == GpuUpload ? "GpuUpload" : "CpuUpload");
+ ALOGD("Now we set the upload to %s", m_currentUploadType == GpuUpload ? "GpuUpload" : "CpuUpload");
}
-// Note: this need to be called within th lock.
-// Only called by updateDirtyBaseTiles() for now
-void TransferQueue::cleanupTransportQueue()
+// Note: this need to be called within the lock and on the UI thread.
+// Only called by updateDirtyBaseTiles() and emptyQueue() for now
+void TransferQueue::cleanupPendingDiscard()
{
int index = getNextTransferQueueIndex();
- for (int i = 0 ; i < ST_BUFFER_NUMBER; i++) {
+ for (int i = 0 ; i < m_transferQueueSize; i++) {
if (m_transferQueue[index].status == pendingDiscard) {
// No matter what the current upload type is, as long as there has
// been a Surf Tex enqueue operation, this updateTexImage need to
@@ -506,7 +563,7 @@ void TransferQueue::cleanupTransportQueue()
if (m_transferQueue[index].uploadType == GpuUpload) {
status_t result = m_sharedSurfaceTexture->updateTexImage();
if (result != OK)
- XLOGC("unexpected error: updateTexImage return %d", result);
+ ALOGE("unexpected error: updateTexImage return %d", result);
}
// since tiles in the queue may be from another webview, remove
@@ -517,14 +574,14 @@ void TransferQueue::cleanupTransportQueue()
// since tile destruction removes textures on the UI thread, the
// texture->owner ptr guarantees the tile is valid
tile->discardBackTexture();
- XLOG("transfer queue discarded tile %p, removed texture", tile);
+ ALOGV("transfer queue discarded tile %p, removed texture", tile);
}
m_transferQueue[index].savedBaseTilePtr = 0;
m_transferQueue[index].savedBaseTileTexturePtr = 0;
m_transferQueue[index].status = emptyItem;
}
- index = (index + 1) % ST_BUFFER_NUMBER;
+ index = (index + 1) % m_transferQueueSize;
}
}
@@ -533,7 +590,7 @@ void TransferQueue::saveGLState()
glGetIntegerv(GL_VIEWPORT, m_GLStateBeforeBlit.viewport);
glGetBooleanv(GL_SCISSOR_TEST, m_GLStateBeforeBlit.scissor);
glGetBooleanv(GL_DEPTH_TEST, m_GLStateBeforeBlit.depth);
-#if DEBUG
+#ifdef DEBUG
glGetFloatv(GL_COLOR_CLEAR_VALUE, m_GLStateBeforeBlit.clearColor);
#endif
}
@@ -545,7 +602,7 @@ void TransferQueue::setGLStateForCopy(int width, int height)
glDisable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
// Clear the content is only for debug purpose.
-#if DEBUG
+#ifdef DEBUG
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
#endif
@@ -563,7 +620,7 @@ void TransferQueue::restoreGLState()
if (m_GLStateBeforeBlit.depth[0])
glEnable(GL_DEPTH_TEST);
-#if DEBUG
+#ifdef DEBUG
glClearColor(m_GLStateBeforeBlit.clearColor[0],
m_GLStateBeforeBlit.clearColor[1],
m_GLStateBeforeBlit.clearColor[2],
@@ -573,7 +630,7 @@ void TransferQueue::restoreGLState()
int TransferQueue::getNextTransferQueueIndex()
{
- return (m_transferQueueIndex + 1) % ST_BUFFER_NUMBER;
+ return (m_transferQueueIndex + 1) % m_transferQueueSize;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h
index 63455de..b00ea17 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.h
@@ -31,7 +31,7 @@
#include "BaseTile.h"
#include "BaseTileTexture.h"
#include "ShaderProgram.h"
-#include "TiledPage.h"
+#include <EGL/eglext.h>
namespace WebCore {
@@ -86,12 +86,15 @@ public:
TransferItemStatus status;
BaseTile* savedBaseTilePtr;
BaseTileTexture* savedBaseTileTexturePtr;
- TextureTileInfo tileInfo;
+ IntRect invalRect;
TextureUploadType uploadType;
// This is only useful in Cpu upload code path, so it will be dynamically
// lazily allocated.
SkBitmap* bitmap;
+ // Specific data to the pure color tiles' queue.
+ Color pureColor;
+
// Sync object for GPU fence, this is the only the info passed from UI
// thread to Tex Gen thread. The reason of having this is due to the
// missing sync mechanism on Surface Texture on some vendor. b/5122031.
@@ -104,22 +107,20 @@ public:
class TransferQueue {
public:
- TransferQueue();
+ TransferQueue(bool useMinimalMem);
~TransferQueue();
// This will be called by the browser through nativeSetProperty
void setTextureUploadType(TextureUploadType type);
-
+ void cleanupGLResources();
void updateDirtyBaseTiles();
- void initSharedSurfaceTextures(int width, int height);
+ void initGLResources(int width, int height);
// insert the bitmap into the queue, mark the tile dirty if failing
- void updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
+ void updateQueueWithBitmap(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap);
- void discardQueue();
-
void addItemInTransferQueue(const TileRenderInfo* info,
TextureUploadType type,
const SkBitmap* bitmap);
@@ -132,6 +133,12 @@ public:
void lockQueue() { m_transferQueueItemLocks.lock(); }
void unlockQueue() { m_transferQueueItemLocks.unlock(); }
+ void addItemInPureColorQueue(const TileRenderInfo* renderInfo);
+
+ void setPendingDiscardWithLock();
+ void emptyQueue();
+
+ bool needsInit() { return !m_sharedSurfaceTextureId; }
// This queue can be accessed from UI and TexGen thread, therefore, we need
// a lock to protect its access
TileTransferData* m_transferQueue;
@@ -143,7 +150,7 @@ public:
private:
// return true if successfully inserted into queue
- bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
+ bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap);
bool getHasGLContext();
void setHasGLContext(bool hasContext);
@@ -156,16 +163,22 @@ private:
void restoreGLState();
// Check the current transfer queue item is obsolete or not.
- bool checkObsolete(int index);
+ bool checkObsolete(const TileTransferData* data);
+ void setPendingDiscard();
// Before each draw call and the blit operation, clean up all the
// pendingDiscard items.
- void cleanupTransportQueue();
+ void cleanupPendingDiscard();
void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
+ BaseTileTexture* frontTex,
GLuint srcTexId, GLenum srcTexTarget,
int index);
+ void addItemCommon(const TileRenderInfo* renderInfo,
+ TextureUploadType type, TileTransferData* data);
+
+ void updatePureColorTiles();
// Note that the m_transferQueueIndex only changed in the TexGen thread
// where we are going to move on to update the next item in the queue.
int m_transferQueueIndex;
@@ -201,6 +214,14 @@ private:
// This should be GpuUpload for production, but for debug purpose or working
// around driver/HW issue, we can set it to CpuUpload.
TextureUploadType m_currentUploadType;
+
+ // The non-pure-color tile are 1 to 1 mapping with Surface Texture which is
+ // resource limited. To get better performance, it is better to separate
+ // the pure color tile into another queue.
+ WTF::Vector<TileTransferData> m_pureColorTileQueue;
+
+ // The number of items transfer queue can buffer up.
+ int m_transferQueueSize;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TreeManager.cpp b/Source/WebCore/platform/graphics/android/TreeManager.cpp
deleted file mode 100644
index b7eaacf..0000000
--- a/Source/WebCore/platform/graphics/android/TreeManager.cpp
+++ /dev/null
@@ -1,331 +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.
- */
-
-#include "config.h"
-#include "TreeManager.h"
-
-#include "Layer.h"
-#include "BaseLayerAndroid.h"
-#include "ScrollableLayerAndroid.h"
-#include "TilesManager.h"
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TreeManager", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TreeManager", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-namespace WebCore {
-
-TreeManager::TreeManager()
- : m_drawingTree(0)
- , m_paintingTree(0)
- , m_queuedTree(0)
- , m_fastSwapMode(false)
-{
-}
-
-TreeManager::~TreeManager()
-{
- clearTrees();
-}
-
-// the painting tree has finished painting:
-// discard the drawing tree
-// swap the painting tree in place of the drawing tree
-// and start painting the queued tree
-void TreeManager::swap()
-{
- // swap can't be called unless painting just finished
- ASSERT(m_paintingTree);
-
- android::Mutex::Autolock lock(m_paintSwapLock);
-
- XLOG("SWAPPING, D %p, P %p, Q %p", m_drawingTree, m_paintingTree, m_queuedTree);
-
- // if we have a drawing tree, discard it since the painting tree is done
- if (m_drawingTree) {
- XLOG("destroying drawing tree %p", m_drawingTree);
- m_drawingTree->setIsDrawing(false);
- SkSafeUnref(m_drawingTree);
- }
-
- // painting tree becomes the drawing tree
- XLOG("drawing tree %p", m_paintingTree);
- m_paintingTree->setIsDrawing(true);
- if (m_paintingTree->countChildren())
- static_cast<LayerAndroid*>(m_paintingTree->getChild(0))->initAnimations();
-
- if (m_queuedTree) {
- // start painting with the queued tree
- XLOG("now painting tree %p", m_queuedTree);
- m_queuedTree->setIsPainting(m_paintingTree);
- }
- m_drawingTree = m_paintingTree;
- m_paintingTree = m_queuedTree;
- m_queuedTree = 0;
-
- TilesManager::instance()->paintedSurfacesCleanup();
-
- XLOG("SWAPPING COMPLETE, D %p, P %p, Q %p", m_drawingTree, m_paintingTree, m_queuedTree);
-}
-
-// clear all of the content in the three trees held by the tree manager
-void TreeManager::clearTrees()
-{
- // remove painted surfaces from any tree in this view, and set trees as no
- // longer drawing, to clear ptrs from surfaces to layers
- GLWebViewState* oldState = 0;
- if (m_drawingTree) {
- oldState = m_drawingTree->state();
- m_drawingTree->setIsDrawing(false);
- }
- if (m_paintingTree) {
- oldState = m_paintingTree->state();
- m_paintingTree->setIsDrawing(false);
- }
-
- XLOG("TreeManager %p removing PS from state %p", this, oldState);
- TilesManager::instance()->paintedSurfacesCleanup(oldState);
-
- SkSafeUnref(m_drawingTree);
- m_drawingTree = 0;
- SkSafeUnref(m_paintingTree);
- m_paintingTree = 0;
- SkSafeUnref(m_queuedTree);
- m_queuedTree = 0;
-}
-
-// a new layer tree has arrived, queue it if we're painting something already,
-// or start painting it if we aren't
-void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
-{
- XLOG("updateWithTree - %p, has children %d, has animations %d",
- newTree, newTree && newTree->countChildren(),
- newTree && newTree->countChildren()
- ? static_cast<LayerAndroid*>(newTree->getChild(0))->hasAnimations() : 0);
-
- // can't have a queued tree unless have a painting tree too
- ASSERT(m_paintingTree || !m_queuedTree);
-
- SkSafeRef(newTree);
-
- android::Mutex::Autolock lock(m_paintSwapLock);
-
- if (!newTree || brandNew) {
- clearTrees();
- if (brandNew) {
- m_paintingTree = newTree;
- m_paintingTree->setIsPainting(m_drawingTree);
- }
- return;
- }
-
- if (m_queuedTree || m_paintingTree) {
- // currently painting, so defer this new tree
- if (m_queuedTree) {
- // have a queued tree, copy over invals so the regions are
- // eventually repainted
- m_queuedTree->mergeInvalsInto(newTree);
-
- XLOG("DISCARDING tree - %p, has children %d, has animations %d",
- newTree, newTree && newTree->countChildren(),
- newTree && newTree->countChildren()
- ? static_cast<LayerAndroid*>(newTree->getChild(0))->hasAnimations() : 0);
- }
- SkSafeUnref(m_queuedTree);
- m_queuedTree = newTree;
- return;
- }
-
- // don't have painting tree, paint this one!
- m_paintingTree = newTree;
- m_paintingTree->setIsPainting(m_drawingTree);
-}
-
-void TreeManager::updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y)
-{
- LayerAndroid* layer;
- if (tree && tree->countChildren()) {
- layer = static_cast<LayerAndroid*>(tree->getChild(0))->findById(layerId);
- if (layer && layer->contentIsScrollable())
- static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
- }
-}
-
-void TreeManager::updateScrollableLayer(int layerId, int x, int y)
-{
- updateScrollableLayerInTree(m_queuedTree, layerId, x, y);
- updateScrollableLayerInTree(m_paintingTree, layerId, x, y);
- updateScrollableLayerInTree(m_drawingTree, layerId, x, y);
-}
-
-bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
- SkRect& visibleRect, float scale,
- bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr,
- TexturesResult* texturesResultPtr)
-{
- m_fastSwapMode |= enterFastSwapMode;
-
- XLOG("drawGL, D %p, P %p, Q %p, fastSwap %d",
- m_drawingTree, m_paintingTree, m_queuedTree, m_fastSwapMode);
-
- bool ret = false;
- bool didTreeSwap = false;
- if (m_paintingTree) {
- XLOG("preparing painting tree %p", m_paintingTree);
-
- LayerAndroid* laTree = 0;
- if (m_paintingTree->countChildren()) {
- laTree = static_cast<LayerAndroid*>(m_paintingTree->getChild(0));
- ret |= laTree->evaluateAnimations(currentTime);
- }
-
- ret |= m_paintingTree->prepare(currentTime, viewRect,
- visibleRect, scale);
-
- if (laTree)
- laTree->computeTexturesAmount(texturesResultPtr);
-
- if (/*!m_fastSwapMode && */ m_paintingTree->isReady()) {
- XLOG("have painting tree %p ready, swapping!", m_paintingTree);
- didTreeSwap = true;
- swap();
- if (treesSwappedPtr)
- *treesSwappedPtr = true;
- if (laTree && newTreeHasAnimPtr)
- *newTreeHasAnimPtr = laTree->hasAnimations();
- }
- } else if (m_drawingTree) {
- XLOG("preparing drawing tree %p", m_drawingTree);
- ret |= m_drawingTree->prepare(currentTime, viewRect,
- visibleRect, scale);
- if (m_drawingTree->countChildren()) {
- LayerAndroid* laTree = static_cast<LayerAndroid*>(m_drawingTree->getChild(0));
- laTree->computeTexturesAmount(texturesResultPtr);
- }
- }
-
-
- if (m_drawingTree) {
- bool drawingReady = didTreeSwap || m_drawingTree->isReady();
-
- if (didTreeSwap || m_fastSwapMode || (drawingReady && !m_paintingTree))
- m_drawingTree->swapTiles();
-
- if (drawingReady) {
- // exit fast swap mode, as content is up to date
- m_fastSwapMode = false;
- } else {
- // drawing isn't ready, must redraw
- ret = true;
- }
-
- if (m_drawingTree->countChildren()) {
- LayerAndroid* laTree = static_cast<LayerAndroid*>(m_drawingTree->getChild(0));
- ret |= laTree->evaluateAnimations(currentTime);
- }
- XLOG("drawing tree %p", m_drawingTree);
- ret |= m_drawingTree->drawGL(viewRect, visibleRect, scale);
- } else if (m_paintingTree && m_paintingTree->state()) {
- // Dont have a drawing tree, draw white background
- Color defaultBackground = Color::white;
- m_paintingTree->state()->drawBackground(defaultBackground);
- }
-
- if (m_paintingTree) {
- XLOG("still have painting tree %p", m_paintingTree);
- return true;
- }
-
- return ret;
-}
-
-int TreeManager::getTotalPaintedSurfaceCount()
-{
- return TilesManager::instance()->getPaintedSurfaceCount();
-}
-
-// draw for base tile - called on TextureGeneration thread
-void TreeManager::drawCanvas(SkCanvas* canvas, bool drawLayers)
-{
- BaseLayerAndroid* paintingTree = 0;
- m_paintSwapLock.lock();
- if (m_paintingTree)
- paintingTree = static_cast<BaseLayerAndroid*>(m_paintingTree);
- else
- paintingTree = static_cast<BaseLayerAndroid*>(m_drawingTree);
- SkSafeRef(paintingTree);
- m_paintSwapLock.unlock();
-
- if (!paintingTree)
- return;
-
-
- paintingTree->drawCanvas(canvas);
-
- if (drawLayers && paintingTree->countChildren()) {
- // draw the layers onto the canvas as well
- Layer* layers = paintingTree->getChild(0);
- static_cast<LayerAndroid*>(layers)->drawCanvas(canvas);
- }
-
- SkSafeUnref(paintingTree);
-}
-
-int TreeManager::baseContentWidth()
-{
- if (m_paintingTree) {
- return static_cast<BaseLayerAndroid*>(m_paintingTree)->content()->width();
- } else if (m_drawingTree) {
- return static_cast<BaseLayerAndroid*>(m_drawingTree)->content()->width();
- }
- return 0;
-}
-
-int TreeManager::baseContentHeight()
-{
- if (m_paintingTree) {
- return static_cast<BaseLayerAndroid*>(m_paintingTree)->content()->height();
- } else if (m_drawingTree) {
- return static_cast<BaseLayerAndroid*>(m_drawingTree)->content()->height();
- }
- return 0;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp b/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp
index 6e715e2..42aa385 100644
--- a/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp
+++ b/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp
@@ -33,28 +33,29 @@
#include <wtf/RefPtr.h>
static const UChar vTextCnvTable[][2] = {
- // TODO: uncomment mappings once we add glyphs for vertical forms.
- // {0x0021, 0xfe15}, // exclamation mark
+ {0x0021, 0xfe15}, // exclamation mark
{0x0028, 0xfe35}, // left paren
{0x0029, 0xfe36}, // right paren
- // {0x002c, 0xfe10}, // comma
+ {0x002c, 0xfe10}, // comma
+ {0x002d, 0xfe32}, // hyphen
{0x003a, 0xfe30}, // colon
- {0x003b, 0x007c}, // hyphen
- // {0x003f, 0xfe16}, // question mark
- // {0x005b, 0xfe14}, // semicolon
- {0x005d, 0xfe47}, // left square bracket
- {0x005f, 0xfe48}, // right square bracket
+ {0x003b, 0xfe14}, // semicolon
+ {0x003f, 0xfe16}, // question mark
+ {0x005b, 0xfe47}, // left square bracket
+ {0x005d, 0xfe48}, // right square bracket
{0x007b, 0xfe37}, // left curly bracket
{0x007d, 0xfe38}, // right curly bracket
{0x007e, 0x007c}, // tilde to vertical line
+ {0x00ab, 0xfe3d}, // left pointing double angle quotation mark
+ {0x00bb, 0xfe3e}, // right pointing double angle quotation mark
+ {0x2010, 0xfe32}, // hyphen
{0x2013, 0xfe32}, // en dash
{0x2014, 0xfe31}, // em dash
{0x2015, 0xfe31}, // horizontal bar
{0x2025, 0xfe30}, // two dot leader
- // TODO: change the mapping 0x2026 -> 0xFE19 once Android has the glyph for 0xFE19.
- {0x2026, 0xfe30}, // three dot leader
- // {0x3001, 0xfe11}, // Ideographic comma
- // {0x3002, 0xfe12}, // Ideographic full stop
+ {0x2026, 0xfe19}, // three dot leader
+ {0x3001, 0xfe11}, // Ideographic comma
+ {0x3002, 0xfe12}, // Ideographic full stop
{0x3008, 0xfe3f}, // left angle bracket
{0x3009, 0xfe40}, // right angle bracket
{0x300a, 0xfe3d}, // left double angle bracket
@@ -67,19 +68,21 @@ static const UChar vTextCnvTable[][2] = {
{0x3011, 0xfe3c}, // right black lenticular bracket
{0x3014, 0xfe39}, // left black lenticular bracket
{0x3015, 0xfe3a}, // right tortise shell bracket
- // {0x3016, 0xfe17}, // left white lenticular bracket
- // {0x3017, 0xfe18}, // right white lenticular bracket
- // {0x3019, 0xfe19}, // horizontal ellipses
+ {0x3016, 0xfe17}, // left white lenticular bracket
+ {0x3017, 0xfe18}, // right white lenticular bracket
{0x30fc, 0x3021}, // prolonged sound
{0xfe4f, 0xfe34}, // wavy low line
{0xff08, 0xfe35}, // full width left paren
{0xff09, 0xfe36}, // full width right paren
+ {0xff0c, 0xfe10}, // full width comma
{0xff3b, 0xfe47}, // full width left square bracket
{0xff3d, 0xfe48}, // full width right square bracket
{0xff5b, 0xfe37}, // full width left curly bracket
+ {0xff5c, 0xfe31}, // fullwidth vertical line
{0xff5d, 0xfe38}, // full width right curly bracket
- // {0xff64, 0xfe11}, // halfwidth ideo comma
- // {0xff61, 0xfe12}, // halfwidth ideo full stop
+ {0xff5e, 0x007c}, // tilde to vertical line
+ {0xff64, 0xfe11}, // halfwidth ideo comma
+ {0xff61, 0xfe12}, // halfwidth ideo full stop
};
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
index 482d711..756bf28 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp
@@ -23,42 +23,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "VideoLayerAndroid"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "VideoLayerAndroid.h"
-#include "RenderSkinMediaButton.h"
+#include "AndroidLog.h"
#include "TilesManager.h"
#include <GLES2/gl2.h>
#include <gui/SurfaceTexture.h>
#if USE(ACCELERATED_COMPOSITING)
-#ifdef DEBUG
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerAndroid", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
namespace WebCore {
-GLuint VideoLayerAndroid::m_spinnerOuterTextureId = 0;
-GLuint VideoLayerAndroid::m_spinnerInnerTextureId = 0;
-GLuint VideoLayerAndroid::m_posterTextureId = 0;
-GLuint VideoLayerAndroid::m_backgroundTextureId = 0;
-bool VideoLayerAndroid::m_createdTexture = false;
-
double VideoLayerAndroid::m_rotateDegree = 0;
-const IntRect VideoLayerAndroid::buttonRect(0, 0, IMAGESIZE, IMAGESIZE);
-
VideoLayerAndroid::VideoLayerAndroid()
: LayerAndroid((RenderLayer*)0)
{
@@ -87,144 +68,139 @@ void VideoLayerAndroid::setSurfaceTexture(sp<SurfaceTexture> texture,
TilesManager::instance()->videoLayerManager()->registerTexture(uniqueId(), textureName);
}
-GLuint VideoLayerAndroid::createSpinnerInnerTexture()
-{
- return createTextureFromImage(RenderSkinMediaButton::SPINNER_INNER);
-}
-
-GLuint VideoLayerAndroid::createSpinnerOuterTexture()
-{
- return createTextureFromImage(RenderSkinMediaButton::SPINNER_OUTER);
-}
-
-GLuint VideoLayerAndroid::createPosterTexture()
-{
- return createTextureFromImage(RenderSkinMediaButton::VIDEO);
-}
-
-GLuint VideoLayerAndroid::createTextureFromImage(int buttonType)
+void VideoLayerAndroid::showPreparingAnimation(const SkRect& rect,
+ const SkRect innerRect)
{
- SkRect rect = SkRect(buttonRect);
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
- bitmap.allocPixels();
- bitmap.eraseColor(0);
-
- SkCanvas canvas(bitmap);
- canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
- RenderSkinMediaButton::Draw(&canvas, buttonRect, buttonType, true);
-
- GLuint texture;
- glGenTextures(1, &texture);
-
- GLUtils::createTextureWithBitmap(texture, bitmap);
- bitmap.reset();
- return texture;
+ 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));
+
+ TransformationMatrix addReverseRotation;
+ TransformationMatrix addRotation = m_drawTransform;
+ addRotation.translate(innerRect.fLeft, innerRect.fTop);
+ double halfButtonSize = manager->getButtonSize() / 2;
+ addRotation.translate(halfButtonSize, halfButtonSize);
+ addReverseRotation = addRotation;
+ addRotation.rotate(m_rotateDegree);
+ addRotation.translate(-halfButtonSize, -halfButtonSize);
+
+ SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height());
+ shader->drawLayerQuad(addRotation, size,
+ manager->getSpinnerOuterTextureId(), 1, true);
+
+ addReverseRotation.rotate(-m_rotateDegree);
+ addReverseRotation.translate(-halfButtonSize, -halfButtonSize);
+
+ shader->drawLayerQuad(addReverseRotation, size,
+ manager->getSpinnerInnerTextureId(), 1, true);
+
+ m_rotateDegree += ROTATESTEP;
}
-GLuint VideoLayerAndroid::createBackgroundTexture()
+SkRect VideoLayerAndroid::calVideoRect(const SkRect& rect)
{
- GLuint texture;
- glGenTextures(1, &texture);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- GLubyte pixels[4 *3] = {
- 128, 128, 128,
- 128, 128, 128,
- 128, 128, 128,
- 128, 128, 128
- };
- glBindTexture(GL_TEXTURE_2D, texture);
- GLUtils::checkGlError("glBindTexture");
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
- GLUtils::checkGlError("glTexImage2D");
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- return texture;
+ SkRect videoRect = rect;
+ VideoLayerManager* manager = TilesManager::instance()->videoLayerManager();
+ float aspectRatio = manager->getAspectRatio(uniqueId());
+ float deltaY = rect.height() - rect.width() / aspectRatio;
+ if (deltaY >= 0)
+ videoRect.inset(0, deltaY / 2);
+ else {
+ float deltaX = rect.width() - rect.height() * aspectRatio;
+ if (deltaX >= 0)
+ videoRect.inset(deltaX / 2, 0);
+ }
+ return videoRect;
}
-bool VideoLayerAndroid::drawGL()
+bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
{
// Lazily allocated the textures.
- if (!m_createdTexture) {
- m_backgroundTextureId = createBackgroundTexture();
- m_spinnerOuterTextureId = createSpinnerOuterTexture();
- m_spinnerInnerTextureId = createSpinnerInnerTexture();
- m_posterTextureId = createPosterTexture();
- m_createdTexture = true;
- }
+ TilesManager* tilesManager = TilesManager::instance();
+ VideoLayerManager* manager = tilesManager->videoLayerManager();
+ manager->initGLResourcesIfNeeded();
+
+ ShaderProgram* shader = tilesManager->shader();
SkRect rect = SkRect::MakeSize(getSize());
GLfloat surfaceMatrix[16];
- SkRect innerRect = SkRect(buttonRect);
- if (innerRect.contains(rect))
- innerRect = rect;
+ // Calculate the video rect based on the aspect ratio and the element rect.
+ SkRect videoRect = calVideoRect(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));
+ }
+
+ // Inner rect is for the progressing / play / pause animation.
+ SkRect innerRect = SkRect::MakeWH(manager->getButtonSize(),
+ manager->getButtonSize());
+ if (innerRect.contains(videoRect))
+ innerRect = videoRect;
+ double buttonSize = manager->getButtonSize();
+ innerRect.offset(videoRect.fLeft + (videoRect.width() - buttonSize) / 2,
+ videoRect.fTop + (videoRect.height() - buttonSize) / 2);
- innerRect.offset((rect.width() - IMAGESIZE) / 2 , (rect.height() - IMAGESIZE) / 2);
+ // 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;
// Draw the poster image, the progressing image or the Video depending
// on the player's state.
if (m_playerState == PREPARING) {
// Show the progressing animation, with two rotating circles
- TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, rect,
- m_backgroundTextureId,
- 1, true);
-
- TransformationMatrix addReverseRotation;
- TransformationMatrix addRotation = m_drawTransform;
- addRotation.translate(innerRect.fLeft, innerRect.fTop);
- addRotation.translate(IMAGESIZE / 2, IMAGESIZE / 2);
- addReverseRotation = addRotation;
- addRotation.rotate(m_rotateDegree);
- addRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
-
- SkRect size = SkRect::MakeWH(innerRect.width(), innerRect.height());
- TilesManager::instance()->shader()->drawLayerQuad(addRotation, size,
- m_spinnerOuterTextureId,
- 1, true);
-
- addReverseRotation.rotate(-m_rotateDegree);
- addReverseRotation.translate(-IMAGESIZE / 2, -IMAGESIZE / 2);
-
- TilesManager::instance()->shader()->drawLayerQuad(addReverseRotation, size,
- m_spinnerInnerTextureId,
- 1, true);
-
- m_rotateDegree += ROTATESTEP;
-
+ showPreparingAnimation(videoRect, innerRect);
+ needRedraw = true;
} else if (m_playerState == PLAYING && m_surfaceTexture.get()) {
// Show the real video.
m_surfaceTexture->updateTexImage();
m_surfaceTexture->getTransformMatrix(surfaceMatrix);
- GLuint textureId =
- TilesManager::instance()->videoLayerManager()->getTextureId(uniqueId());
- TilesManager::instance()->shader()->drawVideoLayerQuad(m_drawTransform,
- surfaceMatrix,
- rect, textureId);
- TilesManager::instance()->videoLayerManager()->updateMatrix(uniqueId(),
- surfaceMatrix);
+ GLuint textureId = manager->getTextureId(uniqueId());
+ shader->drawVideoLayerQuad(m_drawTransform, surfaceMatrix,
+ videoRect, textureId);
+ manager->updateMatrix(uniqueId(), surfaceMatrix);
+
+ // Use the scale to control the fading the sizing during animation
+ double scale = manager->drawIcon(uniqueId(), PlayIcon);
+ if (scale) {
+ innerRect.inset(manager->getButtonSize() / 4 * scale,
+ manager->getButtonSize() / 4 * scale);
+ shader->drawLayerQuad(m_drawTransform, innerRect,
+ manager->getPlayTextureId(), scale, true);
+ needRedraw = true;
+ }
+
} else {
- GLuint textureId =
- TilesManager::instance()->videoLayerManager()->getTextureId(uniqueId());
- GLfloat* matrix =
- TilesManager::instance()->videoLayerManager()->getMatrix(uniqueId());
+ GLuint textureId = manager->getTextureId(uniqueId());
+ GLfloat* matrix = manager->getMatrix(uniqueId());
if (textureId && matrix) {
// Show the screen shot for each video.
- TilesManager::instance()->shader()->drawVideoLayerQuad(m_drawTransform,
- matrix,
- rect, textureId);
+ shader->drawVideoLayerQuad(m_drawTransform, matrix,
+ videoRect, textureId);
} else {
// Show the static poster b/c there is no screen shot available.
- TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, rect,
- m_backgroundTextureId,
- 1, true);
- TilesManager::instance()->shader()->drawLayerQuad(m_drawTransform, innerRect,
- m_posterTextureId,
- 1, true);
+ 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);
+ }
+
+ // Use the scale to control the fading and the sizing during animation.
+ double scale = manager->drawIcon(uniqueId(), PauseIcon);
+ if (scale) {
+ innerRect.inset(manager->getButtonSize() / 4 * scale,
+ manager->getButtonSize() / 4 * scale);
+ shader->drawLayerQuad(m_drawTransform, innerRect,
+ manager->getPauseTextureId(), scale, true);
+ needRedraw = true;
}
- }
- return drawChildrenGL();
+ }
+ return needRedraw;
}
}
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
index 8a064bb..29b1bdc 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
@@ -30,6 +30,7 @@
#include "GLUtils.h"
#include "LayerAndroid.h"
+#include "ShaderProgram.h"
#include <jni.h>
namespace android {
@@ -56,34 +57,23 @@ public:
virtual LayerAndroid* copy() const { return new VideoLayerAndroid(*this); }
// The following 3 functions are called in UI thread only.
- virtual bool drawGL();
+ virtual bool drawGL(bool layerTilesDisabled);
void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, PlayerState playerState);
- GLuint createBackgroundTexture();
- GLuint createSpinnerOuterTexture();
- GLuint createSpinnerInnerTexture();
- GLuint createPosterTexture();
private:
- GLuint createTextureFromImage(int buttonType);
void init();
+ void showPreparingAnimation(const SkRect& rect,
+ const SkRect innerRect);
+ SkRect calVideoRect(const SkRect& rect);
// Surface texture for showing the video is actually allocated in Java side
// and passed into this native code.
sp<android::SurfaceTexture> m_surfaceTexture;
PlayerState m_playerState;
- // Texture for showing the static image will be created at native side.
- static bool m_createdTexture;
- static GLuint m_backgroundTextureId;
- static GLuint m_posterTextureId;
- static GLuint m_spinnerOuterTextureId;
- static GLuint m_spinnerInnerTextureId;
-
static double m_rotateDegree;
static const int ROTATESTEP = 12;
- static const int IMAGESIZE = 64;
- static const IntRect buttonRect;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
index cec4d67..6501f98 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
+++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp
@@ -23,24 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "VideoLayerManager"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "VideoLayerManager.h"
-#if USE(ACCELERATED_COMPOSITING)
-
-#ifdef DEBUG
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoLayerManager", __VA_ARGS__)
-
-#else
+#include "AndroidLog.h"
+#include "RenderSkinMediaButton.h"
+#include "SkCanvas.h"
+#include <wtf/CurrentTime.h>
-#undef XLOG
-#define XLOG(...)
+#if USE(ACCELERATED_COMPOSITING)
-#endif // DEBUG
+// The animation of the play/pause icon will last for PLAY_PAUSE_ICON_SHOW_TIME
+// seconds.
+#define PLAY_PAUSE_ICON_SHOW_TIME 1
// Define the max sum of all the video's sizes.
// Note that video_size = width * height. If there is no compression, then the
@@ -49,11 +47,110 @@
// screenshots would not be above 8M.
#define MAX_VIDEOSIZE_SUM 2097152
+// We don't preload the video data, so we don't have the exact size yet.
+// Assuming 16:9 by default, this will be corrected after video prepared.
+#define DEFAULT_VIDEO_ASPECT_RATIO 1.78
+
+#define VIDEO_TEXTURE_NUMBER 5
+#define VIDEO_BUTTON_SIZE 64
+
namespace WebCore {
VideoLayerManager::VideoLayerManager()
+ : m_currentTimeStamp(0)
+ , m_createdTexture(false)
+ , m_posterTextureId(0)
+ , m_spinnerOuterTextureId(0)
+ , m_spinnerInnerTextureId(0)
+ , m_playTextureId(0)
+ , m_pauseTextureId(0)
+ , m_buttonRect(0, 0, VIDEO_BUTTON_SIZE, VIDEO_BUTTON_SIZE)
+{
+}
+
+int VideoLayerManager::getButtonSize()
+{
+ return VIDEO_BUTTON_SIZE;
+}
+
+GLuint VideoLayerManager::createTextureFromImage(int buttonType)
{
- m_currentTimeStamp = 0;
+ SkRect rect = SkRect(m_buttonRect);
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
+ bitmap.allocPixels();
+ bitmap.eraseColor(0);
+
+ SkCanvas canvas(bitmap);
+ canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ RenderSkinMediaButton::Draw(&canvas, m_buttonRect, buttonType, true, 0,
+ false);
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+
+ GLUtils::createTextureWithBitmap(texture, bitmap);
+ bitmap.reset();
+ return texture;
+}
+
+// Should be called at the VideoLayerAndroid::drawGL to make sure we allocate
+// the GL resources lazily.
+void VideoLayerManager::initGLResourcesIfNeeded()
+{
+ if (!m_createdTexture) {
+ ALOGD("Reinit GLResource for VideoLayer");
+ initGLResources();
+ }
+}
+
+void VideoLayerManager::initGLResources()
+{
+ GLUtils::checkGlError("before initGLResources()");
+ if (!m_createdTexture) {
+ m_spinnerOuterTextureId =
+ createTextureFromImage(RenderSkinMediaButton::SPINNER_OUTER);
+ m_spinnerInnerTextureId =
+ createTextureFromImage(RenderSkinMediaButton::SPINNER_INNER);
+ m_posterTextureId =
+ createTextureFromImage(RenderSkinMediaButton::VIDEO);
+ m_playTextureId = createTextureFromImage(RenderSkinMediaButton::PLAY);
+ m_pauseTextureId = createTextureFromImage(RenderSkinMediaButton::PAUSE);
+ }
+ m_createdTexture = !GLUtils::checkGlError("initGLResources()");
+ return;
+}
+
+void VideoLayerManager::cleanupGLResources()
+{
+ if (m_createdTexture) {
+ GLuint videoTextures[VIDEO_TEXTURE_NUMBER] = { m_spinnerOuterTextureId,
+ m_spinnerInnerTextureId, m_posterTextureId, m_playTextureId,
+ m_pauseTextureId };
+
+ glDeleteTextures(VIDEO_TEXTURE_NUMBER, videoTextures);
+ m_createdTexture = false;
+ }
+ // Delete the texture in retired mode, but have not hit draw call to be
+ // removed.
+ deleteUnusedTextures();
+
+ // Go over the registered GL textures (screen shot textures) and delete them.
+ android::Mutex::Autolock lock(m_videoLayerInfoMapLock);
+ InfoIterator end = m_videoLayerInfoMap.end();
+ for (InfoIterator it = m_videoLayerInfoMap.begin(); it != end; ++it) {
+ // The map include every video has been played, so their textureId can
+ // be deleted already, like hitting onTrimMemory multiple times.
+ if (it->second->textureId) {
+ ALOGV("delete texture from the map %d", it->second->textureId);
+ glDeleteTextures(1, &it->second->textureId);
+ // Set the textureID to 0 to show the video icon.
+ it->second->textureId = 0;
+ }
+ }
+
+ GLUtils::checkGlError("cleanupGLResources()");
+ return;
}
// Getting TextureId for GL draw call, in the UI thread.
@@ -66,6 +163,16 @@ GLuint VideoLayerManager::getTextureId(const int layerId)
return result;
}
+// Getting the aspect ratio for GL draw call, in the UI thread.
+float VideoLayerManager::getAspectRatio(const int layerId)
+{
+ android::Mutex::Autolock lock(m_videoLayerInfoMapLock);
+ float result = 0;
+ if (m_videoLayerInfoMap.contains(layerId))
+ result = m_videoLayerInfoMap.get(layerId)->aspectRatio;
+ return result;
+}
+
// Getting matrix for GL draw call, in the UI thread.
GLfloat* VideoLayerManager::getMatrix(const int layerId)
{
@@ -103,11 +210,14 @@ void VideoLayerManager::registerTexture(const int layerId, const GLuint textureI
pInfo->textureId = textureId;
memset(pInfo->surfaceMatrix, 0, sizeof(pInfo->surfaceMatrix));
pInfo->videoSize = 0;
+ pInfo->aspectRatio = DEFAULT_VIDEO_ASPECT_RATIO;
m_currentTimeStamp++;
pInfo->timeStamp = m_currentTimeStamp;
+ pInfo->lastIconShownTime = 0;
+ pInfo->iconState = Registered;
m_videoLayerInfoMap.add(layerId, pInfo);
- XLOG("GL texture %d regisered for layerId %d", textureId, layerId);
+ ALOGV("GL texture %d regisered for layerId %d", textureId, layerId);
return;
}
@@ -115,13 +225,16 @@ void VideoLayerManager::registerTexture(const int layerId, const GLuint textureI
// Only when the video is prepared, we got the video size. So we should update
// the size for the video accordingly.
// This is called from webcore thread, from MediaPlayerPrivateAndroid.
-void VideoLayerManager::updateVideoLayerSize(const int layerId, const int size )
+void VideoLayerManager::updateVideoLayerSize(const int layerId, const int size,
+ const float ratio)
{
android::Mutex::Autolock lock(m_videoLayerInfoMapLock);
if (m_videoLayerInfoMap.contains(layerId)) {
VideoLayerInfo* pInfo = m_videoLayerInfoMap.get(layerId);
- if (pInfo)
+ if (pInfo) {
pInfo->videoSize = size;
+ pInfo->aspectRatio = ratio;
+ }
}
// If the memory usage is out of bound, then just delete the oldest ones.
@@ -146,7 +259,7 @@ void VideoLayerManager::updateMatrix(const int layerId, const GLfloat* matrix)
return;
memcpy(pInfo->surfaceMatrix, matrix, sizeof(pInfo->surfaceMatrix));
} else {
- XLOG("Error: should not reach here, the layerId %d should exist!", layerId);
+ ALOGV("Error: should not reach here, the layerId %d should exist!", layerId);
ASSERT(false);
}
return;
@@ -164,10 +277,10 @@ bool VideoLayerManager::recycleTextureMem()
InfoIterator end = m_videoLayerInfoMap.end();
#ifdef DEBUG
- XLOG("VideoLayerManager::recycleTextureMem m_videoLayerInfoMap contains");
+ ALOGV("VideoLayerManager::recycleTextureMem m_videoLayerInfoMap contains");
for (InfoIterator it = m_videoLayerInfoMap.begin(); it != end; ++it)
- XLOG(" layerId %d, textureId %d, videoSize %d, timeStamp %d ",
- it->first, it->second->textureId, it->second->videoSize, it->second->timeStamp);
+ ALOGV(" layerId %d, textureId %d, videoSize %d, timeStamp %d ",
+ it->first, it->second->textureId, it->second->videoSize, it->second->timeStamp);
#endif
for (InfoIterator it = m_videoLayerInfoMap.begin(); it != end; ++it) {
if (it->second->timeStamp < oldestTimeStamp) {
@@ -199,7 +312,7 @@ void VideoLayerManager::deleteUnusedTextures()
if (textureName) {
textureNames[index] = textureName;
index++;
- XLOG("GL texture %d will be deleted", textureName);
+ ALOGV("GL texture %d will be deleted", textureName);
}
}
glDeleteTextures(size, textureNames);
@@ -207,6 +320,7 @@ void VideoLayerManager::deleteUnusedTextures()
m_retiredTextures.clear();
}
m_retiredTexturesLock.unlock();
+ GLUtils::checkGlError("deleteUnusedTextures");
return;
}
@@ -238,5 +352,34 @@ void VideoLayerManager::removeLayerInternal(const int layerId)
return;
}
+double VideoLayerManager::drawIcon(const int layerId, IconType type)
+{
+ // When ratio 0 is returned, the Icon should not be drawn.
+ double ratio = 0;
+
+ android::Mutex::Autolock lock(m_videoLayerInfoMapLock);
+ if (m_videoLayerInfoMap.contains(layerId)) {
+ VideoLayerInfo* pInfo = m_videoLayerInfoMap.get(layerId);
+ // If this is state switching moment, reset the time and state
+ if ((type == PlayIcon && pInfo->iconState != PlayIconShown)
+ || (type == PauseIcon && pInfo->iconState != PauseIconShown)) {
+ pInfo->lastIconShownTime = WTF::currentTime();
+ pInfo->iconState = (type == PlayIcon) ? PlayIconShown : PauseIconShown;
+ }
+
+ // After switching the state, we calculate the ratio depending on the
+ // time interval.
+ if ((type == PlayIcon && pInfo->iconState == PlayIconShown)
+ || (type == PauseIcon && pInfo->iconState == PauseIconShown)) {
+ double delta = WTF::currentTime() - pInfo->lastIconShownTime;
+ ratio = 1.0 - (delta / PLAY_PAUSE_ICON_SHOW_TIME);
+ }
+ }
+
+ if (ratio > 1 || ratio < 0)
+ ratio = 0;
+ return ratio;
+}
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/VideoLayerManager.h
index de2dafc..c8e420e 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.h
@@ -27,6 +27,7 @@
#define VideoLayerManager_h
#include "GLUtils.h"
+#include "IntRect.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
@@ -34,13 +35,28 @@
namespace WebCore {
+enum IconState {
+ Registered,
+ PlayIconShown,
+ PauseIconShown
+};
+
+enum IconType {
+ PlayIcon,
+ PauseIcon
+};
+
// Every video layer can use its uniqueId to query VideoLayerManager about such
// info globally.
struct VideoLayerInfo {
GLuint textureId; // GL texture bound with the surface texture.
int videoSize; // The size of the video.
+ float aspectRatio; // The aspect ratio of the video.
int timeStamp; // Used to decide which VideoLayerInfo is the oldest one.
GLfloat surfaceMatrix[16];
+
+ double lastIconShownTime;
+ IconState iconState;
};
@@ -54,7 +70,7 @@ public:
// Register the texture when we got setSurfaceTexture call.
void registerTexture(const int layerId, const GLuint textureId);
// Update the size when the video is prepared.
- void updateVideoLayerSize(const int layerId, const int size);
+ void updateVideoLayerSize(const int layerId, const int size, const float ratio);
// At draw time, update the matrix for every video frame update.
void updateMatrix(const int layerId, const GLfloat* matrix);
// Remove the layer info from the mapping.
@@ -64,10 +80,24 @@ public:
GLuint getTextureId(const int layerId);
// Return the matrix for surface texture corresponding to the layerId
GLfloat* getMatrix(const int layerId);
+ // Return the aspect ratio for the video corresponding to the layerId
+ float getAspectRatio(const int layerId);
// Delete the GL textures
void deleteUnusedTextures();
+ double drawIcon(const int layerId, IconType type);
+
+ GLuint getSpinnerInnerTextureId() { return m_spinnerInnerTextureId; }
+ GLuint getSpinnerOuterTextureId() { return m_spinnerOuterTextureId; }
+ GLuint getPosterTextureId() { return m_posterTextureId; }
+ GLuint getPlayTextureId() { return m_playTextureId; }
+ GLuint getPauseTextureId() { return m_pauseTextureId; }
+
+ void initGLResourcesIfNeeded();
+ void cleanupGLResources();
+
+ static int getButtonSize();
private:
// Get the sum of all the video size stored in m_videoLayerInfoMap.
int getTotalMemUsage();
@@ -75,7 +105,7 @@ private:
bool recycleTextureMem();
// The private function to remove layer.
void removeLayerInternal(const int layerId);
-
+ void initGLResources();
// Indexed by each layer's uniqueId, this map contains the important info
// used for showing the video when playing or the screenshot when paused.
HashMap<int, VideoLayerInfo*> m_videoLayerInfoMap;
@@ -89,6 +119,18 @@ private:
// thread, and really get deleted in the UI thread.
Vector<GLuint> m_retiredTextures;
android::Mutex m_retiredTexturesLock;
+
+ GLuint createTextureFromImage(int buttonType);
+
+ // Texture for showing the static image will be created at native side.
+ bool m_createdTexture;
+ GLuint m_posterTextureId;
+ GLuint m_spinnerOuterTextureId;
+ GLuint m_spinnerInnerTextureId;
+ GLuint m_playTextureId;
+ GLuint m_pauseTextureId;
+
+ IntRect m_buttonRect;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ZoomManager.cpp b/Source/WebCore/platform/graphics/android/ZoomManager.cpp
deleted file mode 100644
index 2cf9f06..0000000
--- a/Source/WebCore/platform/graphics/android/ZoomManager.cpp
+++ /dev/null
@@ -1,201 +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.
- */
-
-#include "config.h"
-#include "ZoomManager.h"
-
-#include "GLWebViewState.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include <wtf/CurrentTime.h>
-
-#include <cutils/log.h>
-#include <wtf/text/CString.h>
-
-#undef XLOGC
-#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "ZoomManager", __VA_ARGS__)
-
-#ifdef DEBUG
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ZoomManager", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
-
-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/android_graphics.cpp b/Source/WebCore/platform/graphics/android/android_graphics.cpp
deleted file mode 100644
index e88c65d..0000000
--- a/Source/WebCore/platform/graphics/android/android_graphics.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2007, 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 "CachedPrefix.h"
-#include "android_graphics.h"
-#include "CachedColor.h"
-#include "CachedRoot.h"
-#include "IntRect.h"
-#include "LayerAndroid.h"
-#include "SkCanvas.h"
-#include "SkCornerPathEffect.h"
-#include "SkPath.h"
-#include "SkRegion.h"
-#include "WebViewCore.h"
-
-namespace android {
-
-// The CSS values for the inner and outer widths may be specified as fractions
-#define WIDTH_SCALE 0.0625f // 1/16, to offset the scale in CSSStyleSelector
-
-void CursorRing::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval)
-{
- if (!m_lastBounds.isEmpty()) {
- *inval = m_lastBounds;
- m_lastBounds = IntRect(0, 0, 0, 0);
- }
-#if USE(ACCELERATED_COMPOSITING)
- int layerId = m_node->isInLayer() ? m_frame->layer(m_node)->uniqueId() : -1;
- if (layer->uniqueId() != layerId)
- return;
-#endif
- if (canvas->quickReject(m_bounds, SkCanvas::kAA_EdgeType)) {
- DBG_NAV_LOGD("canvas->quickReject cursorNode=%d (nodePointer=%p)"
- " bounds=(%d,%d,w=%d,h=%d)", m_node->index(), m_node->nodePointer(),
- m_bounds.x(), m_bounds.y(), m_bounds.width(), m_bounds.height());
- return;
- }
- const CachedColor& colors = m_frame->color(m_node);
- unsigned rectCount = m_rings.size();
- SkRegion rgn;
- SkPath path;
- for (unsigned i = 0; i < rectCount; i++)
- {
- SkRect r(m_rings[i]);
- SkIRect ir;
-
- r.round(&ir);
- ir.inset(-colors.outset(), -colors.outset());
- rgn.op(ir, SkRegion::kUnion_Op);
- }
- rgn.getBoundaryPath(&path);
-
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setPathEffect(new SkCornerPathEffect(
- SkIntToScalar(colors.radius())))->unref();
- SkColor outer;
- SkColor inner;
- if (m_isPressed) {
- SkColor pressed;
- pressed = colors.fillColor();
- paint.setColor(pressed);
- canvas->drawPath(path, paint);
- outer = colors.pressedOuterColor();
- inner = colors.pressedInnerColor();
- } else {
- outer = colors.selectedOuterColor();
- inner = colors.selectedInnerColor();
- }
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(colors.outerWidth() * WIDTH_SCALE);
- paint.setColor(outer);
- canvas->drawPath(path, paint);
- paint.setStrokeWidth(colors.innerWidth() * WIDTH_SCALE);
- paint.setColor(inner);
- canvas->drawPath(path, paint);
- SkRect localBounds, globalBounds;
- localBounds = path.getBounds();
- float width = std::max(colors.innerWidth(), colors.outerWidth());
- width *= WIDTH_SCALE;
- localBounds.inset(-width, -width);
- const SkMatrix& matrix = canvas->getTotalMatrix();
- matrix.mapRect(&globalBounds, localBounds);
- SkIRect globalIBounds;
- globalBounds.round(&globalIBounds);
- m_lastBounds = globalIBounds;
- inval->unite(m_lastBounds);
-}
-
-void CursorRing::setIsButton(const CachedNode* node)
-{
- m_isButton = false;
-}
-
-bool CursorRing::setup()
-{
- m_node->cursorRings(m_frame, &m_rings);
- if (!m_rings.size()) {
- DBG_NAV_LOG("!rings.size()");
- m_viewImpl->m_hasCursorBounds = false;
- return false;
- }
- setIsButton(m_node);
- m_bounds = m_node->bounds(m_frame);
- m_viewImpl->updateCursorBounds(m_root, m_frame, m_node);
-
- bool useHitBounds = m_node->useHitBounds();
- if (useHitBounds)
- m_bounds = m_node->hitBounds(m_frame);
- if (useHitBounds || m_node->useBounds()) {
- m_rings.clear();
- m_rings.append(m_bounds);
- }
- m_absBounds = m_node->bounds(m_frame);
- const CachedColor& colors = m_frame->color(m_node);
- m_bounds.inflate(SkScalarCeil(colors.outerWidth()));
- m_absBounds.inflate(SkScalarCeil(colors.outerWidth()));
- if (!m_node->hasCursorRing() || (m_node->isPlugin() && m_node->isFocus()))
- return false;
-#if DEBUG_NAV_UI
- const WebCore::IntRect& ring = m_rings[0];
- DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p) pressed=%s rings=%d"
- " (%d, %d, %d, %d) isPlugin=%s",
- m_node->index(), m_node->nodePointer(),
- m_isPressed ? "true" : "false",
- m_rings.size(), ring.x(), ring.y(), ring.width(), ring.height(),
- m_node->isPlugin() ? "true" : "false");
- DBG_NAV_LOGD("[%d] inner=%d outer=%d outset=%d radius=%d"
- " fill=0x%08x pin=0x%08x pout=0x%08x sin=0x%08x sout=0x%08x",
- m_node->colorIndex(), colors.innerWidth(), colors.outerWidth(),
- colors.outset(), colors.radius(), colors.fillColor(),
- colors.pressedInnerColor(), colors.pressedOuterColor(),
- colors.selectedInnerColor(), colors.selectedInnerColor());
-#endif
- return true;
-}
-
-}
diff --git a/Source/WebCore/platform/graphics/android/android_graphics.h b/Source/WebCore/platform/graphics/android/android_graphics.h
index 60ac115..7faa781 100644
--- a/Source/WebCore/platform/graphics/android/android_graphics.h
+++ b/Source/WebCore/platform/graphics/android/android_graphics.h
@@ -26,53 +26,17 @@
#ifndef android_graphics_DEFINED
#define android_graphics_DEFINED
-#include "DrawExtra.h"
-#include "IntRect.h"
-#include "SkTypes.h"
-#include "wtf/Vector.h"
-
namespace WebCore {
class GraphicsContext;
- class GLExtras;
}
+class SkCanvas;
-SkCanvas* android_gc2canvas(GraphicsContext* gc);
-
-namespace android {
-
-class CachedFrame;
-class CachedNode;
-class CachedRoot;
-class WebViewCore;
-
-// Data and methods for cursor rings
+// TODO: Move this somewhere else. The implementation for this is actually in
+// GraphicsContextAndroid.cpp, but this is used by a handful of other files
+SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc);
// used to inflate node cache entry
#define CURSOR_RING_HIT_TEST_RADIUS 5
-class CursorRing : public DrawExtra {
-public:
- CursorRing(WebViewCore* core) : m_viewImpl(core) {}
- virtual ~CursorRing() {}
- virtual void draw(SkCanvas* , LayerAndroid* , IntRect* );
- void setIsButton(const CachedNode* );
- bool setup();
- WTF::Vector<IntRect>& rings() { return m_rings; }
-private:
- friend class WebView;
- friend class WebCore::GLExtras;
- WebViewCore* m_viewImpl; // copy for convenience
- WTF::Vector<IntRect> m_rings;
- IntRect m_bounds;
- IntRect m_absBounds;
- IntRect m_lastBounds;
- const CachedRoot* m_root;
- const CachedFrame* m_frame;
- const CachedNode* m_node;
- bool m_isButton;
- bool m_isPressed;
-};
-
-}
#endif
diff --git a/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp b/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp
index 13a26f0..4bc918b 100644
--- a/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp
+++ b/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp
@@ -96,9 +96,7 @@ void ResourceHandle::platformSetDefersLoading(bool)
}
// This static method is called to check to see if a POST response is in
-// the cache. The JNI call through to the HTTP cache stored on the Java
-// side may be slow, but is only used during a navigation to
-// a POST response.
+// the cache.
bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
{
// set the cache policy correctly, copied from
diff --git a/Source/WebCore/platform/network/android/ResourceLoaderAndroid.h b/Source/WebCore/platform/network/android/ResourceLoaderAndroid.h
index f627d62..5ff2322 100644
--- a/Source/WebCore/platform/network/android/ResourceLoaderAndroid.h
+++ b/Source/WebCore/platform/network/android/ResourceLoaderAndroid.h
@@ -46,7 +46,6 @@ public:
virtual void pauseLoad(bool) = 0;
// END ANDROID TODO
- // Call to java to find out if this URL is in the cache
static bool willLoadFromCache(const WebCore::KURL&, int64_t identifier);
protected:
ResourceLoaderAndroid() { }
diff --git a/Source/WebCore/platform/network/android/ResourceRequestAndroid.cpp b/Source/WebCore/platform/network/android/ResourceRequestAndroid.cpp
index 00735f3..1519e9c 100644
--- a/Source/WebCore/platform/network/android/ResourceRequestAndroid.cpp
+++ b/Source/WebCore/platform/network/android/ResourceRequestAndroid.cpp
@@ -30,17 +30,10 @@ namespace WebCore {
unsigned initializeMaximumHTTPConnectionCountPerHost()
{
-#if USE(CHROME_NETWORK_STACK)
// The chromium network stack already handles limiting the number of
// parallel requests per host, so there's no need to do it here. Therefore,
// this is set to a high value that should never be hit in practice.
return 10000;
-#else
- // This is used by the loader to control the number of parallel load
- // requests. Our java framework has 4 threads that can each pipeline up to
- // 5 requests. Use 20 as a maximum number.
- return 20;
-#endif
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/android/HyphenationAndroid.cpp b/Source/WebCore/platform/text/android/HyphenationAndroid.cpp
index d1bd839..9933715 100644
--- a/Source/WebCore/platform/text/android/HyphenationAndroid.cpp
+++ b/Source/WebCore/platform/text/android/HyphenationAndroid.cpp
@@ -28,7 +28,7 @@
// For external hyphenation library.
#include "hyphen.h"
-#include <utils/AssetManager.h>
+#include <androidfw/AssetManager.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
diff --git a/Source/WebCore/plugins/PluginView.cpp b/Source/WebCore/plugins/PluginView.cpp
index c39ceac..ffefc71 100644
--- a/Source/WebCore/plugins/PluginView.cpp
+++ b/Source/WebCore/plugins/PluginView.cpp
@@ -830,8 +830,6 @@ PassRefPtr<JSC::Bindings::Instance> PluginView::bindingInstance()
}
#endif
-#if USE(V8)
-// This is really JS engine independent
NPObject* PluginView::getNPObject() {
#if ENABLE(NETSCAPE_PLUGIN_API)
if (!m_plugin || !m_plugin->pluginFuncs()->getvalue)
@@ -859,7 +857,6 @@ NPObject* PluginView::getNPObject() {
return 0;
#endif // NETSCAPE_PLUGIN_API
}
-#endif // V8
void PluginView::disconnectStream(PluginStream* stream)
{
diff --git a/Source/WebCore/plugins/PluginView.h b/Source/WebCore/plugins/PluginView.h
index 976c65c..bf77e51 100644
--- a/Source/WebCore/plugins/PluginView.h
+++ b/Source/WebCore/plugins/PluginView.h
@@ -202,9 +202,7 @@ namespace WebCore {
void (*timerFunc)(NPP, uint32_t timerID));
void unscheduleTimer(NPP, uint32_t timerID);
#endif
-#if USE(V8)
NPObject* getNPObject();
-#endif
virtual void invalidateRect(const IntRect&);
diff --git a/Source/WebCore/plugins/android/PluginViewAndroid.cpp b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
index dba7d3b..315d8a4 100644
--- a/Source/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -63,10 +63,6 @@
#include "ScriptController.h"
#include "Settings.h"
-#if USE(JSC)
-#include <runtime/JSLock.h>
-#endif
-
#include <wtf/ASCIICType.h>
// #include "runtime.h"
#include "WebViewCore.h"
@@ -484,9 +480,6 @@ void PluginView::setNPWindowIfNeeded()
m_npWindow.clipRect.bottom = m_pageRect.y() + m_pageRect.height();
if (m_plugin->pluginFuncs()->setwindow) {
-#if USE(JSC)
- JSC::JSLock::DropAllLocks dropAllLocks(false);
-#endif
setCallingPlugin(true);
m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
setCallingPlugin(false);
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index 5815b8b..d5eeeae 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -43,6 +43,7 @@
#include "Text.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
+#include <wtf/text/CString.h>
using namespace std;
@@ -1069,8 +1070,12 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
renderer()->theme()->platformInactiveTextSearchHighlightColor();
pt->save();
updateGraphicsContext(pt, color, color, 0, style->colorSpace()); // Don't draw text at all!
+#if PLATFORM(ANDROID)
+ pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos, marker.activeMatch);
+#else
pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos);
+#endif
pt->restore();
}
}
diff --git a/Source/WebCore/rendering/RenderArena.cpp b/Source/WebCore/rendering/RenderArena.cpp
index 57ed978..e15101f 100644
--- a/Source/WebCore/rendering/RenderArena.cpp
+++ b/Source/WebCore/rendering/RenderArena.cpp
@@ -136,11 +136,4 @@ void RenderArena::free(size_t size, void* ptr)
#endif
}
-#ifdef ANDROID_INSTRUMENT
-size_t RenderArena::reportPoolSize() const
-{
- return ReportPoolSize(&m_pool);
-}
-#endif
-
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderArena.h b/Source/WebCore/rendering/RenderArena.h
index 5d2559a..e1ff535 100644
--- a/Source/WebCore/rendering/RenderArena.h
+++ b/Source/WebCore/rendering/RenderArena.h
@@ -53,10 +53,6 @@ public:
void* allocate(size_t);
void free(size_t, void*);
-#ifdef ANDROID_INSTRUMENT
- size_t reportPoolSize() const;
-#endif
-
private:
// Underlying arena pool
ArenaPool m_pool;
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index df20063..a2469a0 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -895,6 +895,10 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, maxWidth);
m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, maxWidth);
+ // if overflow isn't visible, block elements may get clipped
+ // due to the limited content width. disable overflow clipping.
+ setHasOverflowClip(false);
+
IntRect overflow = layoutOverflowRect();
if (overflow.width() > maxWidth) {
overflow.setWidth(maxWidth);
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/RenderHTMLCanvas.cpp b/Source/WebCore/rendering/RenderHTMLCanvas.cpp
index de2a2c1..03b406b 100644
--- a/Source/WebCore/rendering/RenderHTMLCanvas.cpp
+++ b/Source/WebCore/rendering/RenderHTMLCanvas.cpp
@@ -47,6 +47,13 @@ RenderHTMLCanvas::RenderHTMLCanvas(HTMLCanvasElement* element)
bool RenderHTMLCanvas::requiresLayer() const
{
+#if PLATFORM(ANDROID)
+ // All Canvas are drawn on their own composited layer
+ // This improves performances a lot (as this simplify
+ // the repaint/inval chain dealing with the PictureSet)
+ return true;
+#endif
+
if (RenderReplaced::requiresLayer())
return true;
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index cdc4c05..66aab18 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -64,6 +64,7 @@
#include "HTMLNames.h"
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
#include "HTMLTextAreaElement.h"
+#include "GraphicsLayerAndroid.h"
#endif
#include "HitTestRequest.h"
#include "HitTestResult.h"
@@ -1389,11 +1390,27 @@ void RenderLayer::scrollTo(int x, int y)
view->updateWidgetPositions();
}
+#if PLATFORM(ANDROID)
+ GraphicsLayerAndroid* backingLayer = 0;
+ bool scrollableContent = false;
+#endif
+
#if USE(ACCELERATED_COMPOSITING)
if (compositor()->inCompositingMode()) {
// Our stacking context is guaranteed to contain all of our descendants that may need
// repositioning, so update compositing layers from there.
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (view && backing() && backing()->graphicsLayer()) {
+ backingLayer = static_cast<GraphicsLayerAndroid*>(backing()->graphicsLayer());
+ scrollableContent = backingLayer->contentLayer()
+ && backingLayer->contentLayer()->contentIsScrollable();
+ }
+ // If we have a scrollable content, no need to do this
+ RenderLayer* compositingAncestor = enclosingCompositingLayer();
+ if (!scrollableContent && compositingAncestor) {
+#else
if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
+#endif
if (compositor()->compositingConsultsOverlap())
compositor()->updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
else {
@@ -1422,8 +1439,10 @@ void RenderLayer::scrollTo(int x, int y)
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
// On android, scrollable areas are put on composited layers, so we
// do not need to repaint simply because we are scrolling
- if (view && !hasOverflowScroll())
+ if (view && !(hasOverflowScroll() || scrollableContent))
renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
+ if (backingLayer && (hasOverflowScroll() || scrollableContent))
+ backingLayer->updateScrollOffset();
#else
if (view)
renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h
index 02ab8e9..5e421f0 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -498,6 +498,12 @@ public:
bool hasOverflowScroll() const { return m_hasOverflowScroll; }
bool hasOverflowParent() const;
#endif
+#if PLATFORM(ANDROID)
+ bool intrinsicallyComposited() const { return m_intrinsicallyComposited; }
+ void setIntrinsicallyComposited(bool intrinsicallyComposited) {
+ m_intrinsicallyComposited = intrinsicallyComposited;
+ }
+#endif
private:
// The normal operator new is disallowed on all render objects.
@@ -751,6 +757,9 @@ protected:
bool m_shouldComposite : 1;
#endif
#endif
+#if PLATFORM(ANDROID)
+ bool m_intrinsicallyComposited : 1;
+#endif
bool m_containsDirtyOverlayScrollbars : 1;
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 33bf2f7..733a418 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -78,7 +78,7 @@ struct CompositingState {
: m_compositingAncestor(compAncestor)
, m_subtreeIsCompositing(false)
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- , m_fixedSibling(false)
+ , m_positionedSibling(false)
, m_hasFixedElement(false)
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
@@ -92,8 +92,12 @@ struct CompositingState {
RenderLayer* m_compositingAncestor;
bool m_subtreeIsCompositing;
+ // m_compositingBounds is only used in computeCompositingRequirements. It can be either the
+ // ancestor bounds or the bounds for the sibling layers which are above the composited layer.
+ // It is used to reject creating unnecesary layers.
+ IntRect m_compositingBounds;
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- bool m_fixedSibling;
+ bool m_positionedSibling;
bool m_hasFixedElement;
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
@@ -347,7 +351,11 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR
{
bool layerChanged = false;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (needsToBeComposited(layer) || layer->shouldComposite()) {
+#else
if (needsToBeComposited(layer)) {
+#endif
enableCompositingMode();
// 3D transforms turn off the testing of overlap.
@@ -613,23 +621,49 @@ bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, con
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
-// to properly support z-index with composited fixed elements, we need to turn
-// layers following a fixed layer into compositing mode; but if a layer is fully
-// contained into a previous layer already composited (that is not the fixed
-// layer), we don't need to composite it. This saves up quite a bit on the
-// number of layers we have to composite.
-//
-bool RenderLayerCompositor::checkForFixedLayers(Vector<RenderLayer*>* list, bool stopAtFixedLayer)
+bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* list)
{
int listSize = list->size();
int haveFixedLayer = -1;
bool fixedSibling = false;
+ bool positionedSibling = false;
+
+ // 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
+ // removed from the flow).
+ for (int i = 0; i < listSize; ++i) {
+ RenderLayer* currentLayer = list->at(i);
+ if (!needsToBeComposited(currentLayer)
+ && !currentLayer->shouldComposite()
+ && currentLayer->renderer()->isPositioned()) {
+ positionedSibling = true;
+ // check if there is a composited layer later, if so we should be
+ // composited.
+ for (int j = i + 1; j < listSize; ++j) {
+ RenderLayer* layer = list->at(j);
+ if (needsToBeComposited(layer)) {
+ currentLayer->setShouldComposite(true);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ // 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.
for (int j = 0; j < listSize; ++j) {
RenderLayer* currentLayer = list->at(j);
+ if (currentLayer->shouldComposite())
+ continue;
+
if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
haveFixedLayer = j;
fixedSibling = true;
}
+
+ // Bypass fixed layers with a width or height or 1 or less...
IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
if ((currentLayerBounds.width() <= 1
@@ -638,28 +672,11 @@ bool RenderLayerCompositor::checkForFixedLayers(Vector<RenderLayer*>* list, bool
haveFixedLayer = -1;
fixedSibling = false;
}
- if (haveFixedLayer != -1 && haveFixedLayer != j) {
- bool needComposite = true;
- int stop = 0;
- if (stopAtFixedLayer)
- stop = haveFixedLayer + 1;
-
- for (int k = j - 1; k >= stop; --k) {
- RenderLayer* aLayer = list->at(k);
- if (aLayer && aLayer->renderer()) {
- IntRect bounds = aLayer->renderer()->localToAbsoluteQuad(
- FloatRect(aLayer->localBoundingBox())).enclosingBoundingBox();
- if (bounds.contains(currentLayerBounds)
- && needsToBeComposited(aLayer) && aLayer->isStackingContext()) {
- needComposite = false;
- break;
- }
- }
- }
- currentLayer->setShouldComposite(needComposite);
- }
+
+ if (haveFixedLayer != -1 && haveFixedLayer != j)
+ currentLayer->setShouldComposite(true);
}
- return fixedSibling;
+ return positionedSibling || fixedSibling;
}
#endif
@@ -678,7 +695,12 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
layer->updateLayerPosition();
layer->updateZOrderLists();
layer->updateNormalFlowList();
-
+#if PLATFORM(ANDROID)
+ RenderObject* renderer = layer->renderer();
+ bool intCom = requiresCompositingLayer(layer);
+ layer->setIntrinsicallyComposited(intCom);
+#endif
+
// Clear the flag
layer->setHasCompositingDescendant(false);
@@ -693,28 +715,33 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (absBounds.isEmpty())
absBounds.setSize(IntSize(1, 1));
haveComputedBounds = true;
- mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
+ // If the current subtree is not compositing, and the layer is fully inside the current compositing bounnds,
+ // there is no need to do the overlap test. This reduces the total number of the composited layers.
+ if (compositingState.m_subtreeIsCompositing || !compositingState.m_compositingBounds.contains(absBounds))
+ mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
}
-
-#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- if (compositingState.m_fixedSibling)
- layer->setMustOverlapCompositedLayers(layer->shouldComposite());
- else
- layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
-#else
+
layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
-#endif
-
+
// The children of this layer don't need to composite, unless there is
// a compositing layer among them, so start by inheriting the compositing
// ancestor with m_subtreeIsCompositing set to false.
CompositingState childState(compositingState.m_compositingAncestor);
+ if (compositingState.m_subtreeIsCompositing)
+ childState.m_compositingBounds = absBounds;
+ else
+ childState.m_compositingBounds = compositingState.m_compositingBounds;
#ifndef NDEBUG
++childState.m_depth;
#endif
bool willBeComposited = needsToBeComposited(layer);
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ willBeComposited |= layer->shouldComposite();
+ layer->setMustOverlapCompositedLayers(layer->shouldComposite());
+#endif
+
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
// tell the parent it has scrollable descendants.
if (layer->hasOverflowScroll())
@@ -729,6 +756,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
compositingState.m_subtreeIsCompositing = true;
// This layer now acts as the ancestor for kids.
childState.m_compositingAncestor = layer;
+ childState.m_compositingBounds = absBounds;
if (overlapMap)
addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
}
@@ -746,9 +774,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
size_t listSize = negZOrderList->size();
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- childState.m_fixedSibling = compositingState.m_fixedSibling;
- if (checkForFixedLayers(negZOrderList, false))
- childState.m_fixedSibling = true;
+ childState.m_positionedSibling = compositingState.m_positionedSibling;
+ if (checkForPositionedElements(negZOrderList))
+ childState.m_positionedSibling = true;
#endif
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
@@ -783,9 +811,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
size_t listSize = normalFlowList->size();
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- childState.m_fixedSibling = compositingState.m_fixedSibling;
- if (checkForFixedLayers(normalFlowList, true))
- childState.m_fixedSibling = true;
+ childState.m_positionedSibling = compositingState.m_positionedSibling;
+ if (checkForPositionedElements(normalFlowList))
+ childState.m_positionedSibling = true;
#endif
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
@@ -797,9 +825,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
size_t listSize = posZOrderList->size();
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- childState.m_fixedSibling = compositingState.m_fixedSibling;
- if (checkForFixedLayers(posZOrderList, true))
- childState.m_fixedSibling = true;
+ childState.m_positionedSibling = compositingState.m_positionedSibling;
+ if (checkForPositionedElements(posZOrderList))
+ childState.m_positionedSibling = true;
#endif
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
@@ -1398,6 +1426,10 @@ bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLaye
if (layer->isFixed())
return true;
#endif
+
+ if (layer->renderer()->isCanvas())
+ return true;
+
return false;
}
#endif
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h
index 813e265..2de1037 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.h
+++ b/Source/WebCore/rendering/RenderLayerCompositor.h
@@ -219,7 +219,7 @@ private:
void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- bool checkForFixedLayers(Vector<RenderLayer*>* list, bool stopAtFixedLayer);
+ bool checkForPositionedElements(Vector<RenderLayer*>* list);
#endif
// Returns true if any layer's compositing changed
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index b35820a..6f4d3b7 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -37,6 +37,7 @@
#include "RenderCombineText.h"
#include "RenderLayer.h"
#include "RenderView.h"
+#include "Settings.h"
#include "Text.h"
#include "TextBreakIterator.h"
#include "TextResourceDecoder.h"
@@ -53,6 +54,37 @@ using namespace Unicode;
namespace WebCore {
+class SecureTextTimer;
+typedef HashMap<RenderText*, SecureTextTimer*> SecureTextTimerMap;
+static SecureTextTimerMap* gSecureTextTimers = 0;
+
+class SecureTextTimer : public TimerBase {
+public:
+ SecureTextTimer(RenderText* renderText)
+ : m_renderText(renderText)
+ , m_lastTypedCharacterOffset(-1)
+ {
+ }
+
+ void restartWithNewText(unsigned lastTypedCharacterOffset)
+ {
+ m_lastTypedCharacterOffset = lastTypedCharacterOffset;
+ startOneShot(m_renderText->document()->settings()->passwordEchoDurationInSeconds());
+ }
+ void invalidate() { m_lastTypedCharacterOffset = -1; }
+ unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; }
+
+private:
+ virtual void fired()
+ {
+ ASSERT(gSecureTextTimers->contains(m_renderText));
+ m_renderText->setText(m_renderText->text(), true /* forcing setting text as it may be masked later */);
+ }
+
+ RenderText* m_renderText;
+ int m_lastTypedCharacterOffset;
+};
+
static void makeCapitalized(String* string, UChar previous)
{
if (string->isNull())
@@ -196,6 +228,9 @@ void RenderText::removeAndDestroyTextBoxes()
void RenderText::destroy()
{
+ if (SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->take(this) : 0)
+ delete secureTextTimer;
+
removeAndDestroyTextBoxes();
RenderObject::destroy();
}
@@ -1140,13 +1175,13 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
case TSNONE:
break;
case TSCIRCLE:
- m_text.makeSecure(whiteBullet);
+ secureText(whiteBullet);
break;
case TSDISC:
- m_text.makeSecure(bullet);
+ secureText(bullet);
break;
case TSSQUARE:
- m_text.makeSecure(blackSquare);
+ secureText(blackSquare);
}
}
@@ -1156,6 +1191,28 @@ void RenderText::setTextInternal(PassRefPtr<StringImpl> text)
m_isAllASCII = m_text.containsOnlyASCII();
}
+void RenderText::secureText(UChar mask)
+{
+ if (!m_text.length())
+ return;
+
+ int lastTypedCharacterOffsetToReveal = -1;
+ String revealedText;
+ SecureTextTimer* secureTextTimer = gSecureTextTimers ? gSecureTextTimers->get(this) : 0;
+ if (secureTextTimer && secureTextTimer->isActive()) {
+ lastTypedCharacterOffsetToReveal = secureTextTimer->lastTypedCharacterOffset();
+ if (lastTypedCharacterOffsetToReveal >= 0)
+ revealedText.append(m_text[lastTypedCharacterOffsetToReveal]);
+ }
+
+ m_text.makeSecure(mask);
+ if (lastTypedCharacterOffsetToReveal >= 0) {
+ m_text.replace(lastTypedCharacterOffsetToReveal, 1, revealedText);
+ // m_text may be updated later before timer fires. We invalidate the lastTypedCharacterOffset to avoid inconsistency.
+ secureTextTimer->invalidate();
+ }
+}
+
void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
{
ASSERT(text);
@@ -1590,4 +1647,17 @@ void RenderText::checkConsistency() const
#endif
+void RenderText::momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset)
+{
+ if (!gSecureTextTimers)
+ gSecureTextTimers = new SecureTextTimerMap;
+
+ SecureTextTimer* secureTextTimer = gSecureTextTimers->get(this);
+ if (!secureTextTimer) {
+ secureTextTimer = new SecureTextTimer(this);
+ gSecureTextTimers->add(this, secureTextTimer);
+ }
+ secureTextTimer->restartWithNewText(lastTypedCharacterOffset);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderText.h b/Source/WebCore/rendering/RenderText.h
index 2008dad..f89a762 100644
--- a/Source/WebCore/rendering/RenderText.h
+++ b/Source/WebCore/rendering/RenderText.h
@@ -117,6 +117,9 @@ public:
bool containsReversedText() const { return m_containsReversedText; }
+ bool isSecure() const { return style()->textSecurity() != TSNONE; }
+ void momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset);
+
InlineTextBox* findNextInlineTextBox(int offset, int& pos) const;
bool allowTabs() const { return !style()->collapseWhiteSpace(); }
@@ -158,6 +161,7 @@ private:
void updateNeedsTranscoding();
inline void transformText(String&) const;
+ void secureText(UChar mask);
float m_minWidth; // here to minimize padding in 64-bit.
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index fad5a7b..ea01064 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -786,19 +786,6 @@ public:
ESpeak speak() { return static_cast<ESpeak>(rareInheritedData->speak); }
-#ifdef ANDROID_CSS_RING
- // called when building nav cache to determine if the ring data is unchanged
- const void* ringData() const { return reinterpret_cast<const void*>(rareInheritedData.get()); }
- Color ringFillColor() const { return rareInheritedData->ringFillColor; }
- Length ringInnerWidth() const { return rareInheritedData->ringInnerWidth; }
- Length ringOuterWidth() const { return rareInheritedData->ringOuterWidth; }
- Length ringOutset() const { return rareInheritedData->ringOutset; }
- Color ringPressedInnerColor() const { return rareInheritedData->ringPressedInnerColor; }
- Color ringPressedOuterColor() const { return rareInheritedData->ringPressedOuterColor; }
- Length ringRadius() const { return rareInheritedData->ringRadius; }
- Color ringSelectedInnerColor() const { return rareInheritedData->ringSelectedInnerColor; }
- Color ringSelectedOuterColor() const { return rareInheritedData->ringSelectedOuterColor; }
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
Color tapHighlightColor() const { return rareInheritedData->tapHighlightColor; }
#endif
@@ -1142,21 +1129,6 @@ public:
void setTextSizeAdjust(bool b) { SET_VAR(rareInheritedData, textSizeAdjust, b); }
void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); }
-#ifdef ANDROID_CSS_RING
- void setRingFillColor(const Color& v) { SET_VAR(rareInheritedData, ringFillColor, v); }
- void setRingInnerWidth(Length v) { SET_VAR(rareInheritedData, ringInnerWidth, v); }
- void setRingOuterWidth(Length v) { SET_VAR(rareInheritedData, ringOuterWidth, v); }
- void setRingOutset(Length v) { SET_VAR(rareInheritedData, ringOutset, v); }
- void setRingPressedInnerColor(const Color& v) {
- SET_VAR(rareInheritedData, ringPressedInnerColor, v); }
- void setRingPressedOuterColor(const Color& v) {
- SET_VAR(rareInheritedData, ringPressedOuterColor, v); }
- void setRingRadius(Length v) { SET_VAR(rareInheritedData, ringRadius, v); }
- void setRingSelectedInnerColor(const Color& v) {
- SET_VAR(rareInheritedData, ringSelectedInnerColor, v); }
- void setRingSelectedOuterColor(const Color& v) {
- SET_VAR(rareInheritedData, ringSelectedOuterColor, v); }
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
void setTapHighlightColor(const Color& v) { SET_VAR(rareInheritedData, tapHighlightColor, v); }
#endif
@@ -1359,17 +1331,6 @@ public:
static const Vector<StyleDashboardRegion>& noneDashboardRegions();
#endif
-#ifdef ANDROID_CSS_RING
- static Color initialRingFillColor() { return Color::ringFill; }
- static Length initialRingInnerWidth() { return Length(16, Fixed); } // 1.0
- static Length initialRingOuterWidth() { return Length(40, Fixed); } // 2.5
- static Length initialRingOutset() { return Length(3, Fixed); }
- static Color initialRingSelectedInnerColor() { return Color::ringSelectedInner; }
- static Color initialRingSelectedOuterColor() { return Color::ringSelectedOuter; }
- static Color initialRingPressedInnerColor() { return Color::ringPressedInner; }
- static Color initialRingPressedOuterColor() { return Color::ringPressedOuter; }
- static Length initialRingRadius() { return Length(1, Fixed); }
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
static Color initialTapHighlightColor() { return Color::tap; }
#endif
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
index 2253d1c..a7acc4a 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -32,17 +32,6 @@ namespace WebCore {
StyleRareInheritedData::StyleRareInheritedData()
: textStrokeWidth(RenderStyle::initialTextStrokeWidth())
-#ifdef ANDROID_CSS_RING
- , ringFillColor(RenderStyle::initialRingFillColor())
- , ringInnerWidth(RenderStyle::initialRingInnerWidth())
- , ringOuterWidth(RenderStyle::initialRingOuterWidth())
- , ringOutset(RenderStyle::initialRingOutset())
- , ringPressedInnerColor(RenderStyle::initialRingPressedInnerColor())
- , ringPressedOuterColor(RenderStyle::initialRingPressedOuterColor())
- , ringRadius(RenderStyle::initialRingRadius())
- , ringSelectedInnerColor(RenderStyle::initialRingSelectedInnerColor())
- , ringSelectedOuterColor(RenderStyle::initialRingSelectedOuterColor())
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
, tapHighlightColor(RenderStyle::initialTapHighlightColor())
#endif
@@ -77,18 +66,6 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, textStrokeColor(o.textStrokeColor)
, textStrokeWidth(o.textStrokeWidth)
, textFillColor(o.textFillColor)
- , textEmphasisColor(o.textEmphasisColor)
-#ifdef ANDROID_CSS_RING
- , ringFillColor(o.ringFillColor)
- , ringInnerWidth(o.ringInnerWidth)
- , ringOuterWidth(o.ringOuterWidth)
- , ringOutset(o.ringOutset)
- , ringPressedInnerColor(o.ringPressedInnerColor)
- , ringPressedOuterColor(o.ringPressedOuterColor)
- , ringRadius(o.ringRadius)
- , ringSelectedInnerColor(o.ringSelectedInnerColor)
- , ringSelectedOuterColor(o.ringSelectedOuterColor)
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
, tapHighlightColor(o.tapHighlightColor)
#endif
@@ -157,17 +134,6 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& nbspMode == o.nbspMode
&& khtmlLineBreak == o.khtmlLineBreak
&& textSizeAdjust == o.textSizeAdjust
-#ifdef ANDROID_CSS_RING
- && ringFillColor == o.ringFillColor
- && ringInnerWidth == o.ringInnerWidth
- && ringOuterWidth == o.ringOuterWidth
- && ringOutset == o.ringOutset
- && ringPressedInnerColor == o.ringPressedInnerColor
- && ringPressedOuterColor == o.ringPressedOuterColor
- && ringRadius == o.ringRadius
- && ringSelectedInnerColor == o.ringSelectedInnerColor
- && ringSelectedOuterColor == o.ringSelectedOuterColor
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
&& tapHighlightColor == o.tapHighlightColor
#endif
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h
index 39cfe3c..16fcc5f 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h
@@ -58,17 +58,6 @@ public:
Color textFillColor;
Color textEmphasisColor;
-#ifdef ANDROID_CSS_RING
- Color ringFillColor;
- Length ringInnerWidth;
- Length ringOuterWidth;
- Length ringOutset;
- Color ringPressedInnerColor;
- Color ringPressedOuterColor;
- Length ringRadius;
- Color ringSelectedInnerColor;
- Color ringSelectedOuterColor;
-#endif
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
Color tapHighlightColor;
#endif
diff --git a/Source/WebCore/storage/AbstractDatabase.h b/Source/WebCore/storage/AbstractDatabase.h
index 9279adc..e0a277f 100644
--- a/Source/WebCore/storage/AbstractDatabase.h
+++ b/Source/WebCore/storage/AbstractDatabase.h
@@ -36,7 +36,7 @@
#include "SQLiteDatabase.h"
#include <wtf/Forward.h>
#include <wtf/ThreadSafeRefCounted.h>
-#ifndef NDEBUG
+#if !LOG_DISABLED || !ERROR_DISABLED
#include "SecurityOrigin.h"
#endif
@@ -109,7 +109,7 @@ protected:
unsigned long m_estimatedSize;
String m_filename;
-#ifndef NDEBUG
+#if !LOG_DISABLED || !ERROR_DISABLED
String databaseDebugName() const { return m_contextThreadSecurityOrigin->toString() + "::" + m_name; }
#endif
diff --git a/Source/WebCore/storage/DatabaseTask.cpp b/Source/WebCore/storage/DatabaseTask.cpp
index 343ae1e..ad744e5 100644
--- a/Source/WebCore/storage/DatabaseTask.cpp
+++ b/Source/WebCore/storage/DatabaseTask.cpp
@@ -62,7 +62,7 @@ void DatabaseTaskSynchronizer::taskCompleted()
DatabaseTask::DatabaseTask(Database* database, DatabaseTaskSynchronizer* synchronizer)
: m_database(database)
, m_synchronizer(synchronizer)
-#ifndef NDEBUG
+#if !LOG_DISABLED
, m_complete(false)
#endif
{
@@ -70,13 +70,17 @@ DatabaseTask::DatabaseTask(Database* database, DatabaseTaskSynchronizer* synchro
DatabaseTask::~DatabaseTask()
{
+#if !LOG_DISABLED
ASSERT(m_complete || !m_synchronizer);
+#endif
}
void DatabaseTask::performTask()
{
// Database tasks are meant to be used only once, so make sure this one hasn't been performed before.
+#if !LOG_DISABLED
ASSERT(!m_complete);
+#endif
LOG(StorageAPI, "Performing %s %p\n", debugTaskName(), this);
@@ -86,7 +90,7 @@ void DatabaseTask::performTask()
if (m_synchronizer)
m_synchronizer->taskCompleted();
-#ifndef NDEBUG
+#if !LOG_DISABLED
m_complete = true;
#endif
}
@@ -108,7 +112,7 @@ void Database::DatabaseOpenTask::doPerformTask()
m_success = database()->performOpenAndVerify(m_setVersionInNewDatabase, m_code);
}
-#ifndef NDEBUG
+#if !LOG_DISABLED
const char* Database::DatabaseOpenTask::debugTaskName() const
{
return "DatabaseOpenTask";
@@ -128,7 +132,7 @@ void Database::DatabaseCloseTask::doPerformTask()
database()->close();
}
-#ifndef NDEBUG
+#if !LOG_DISABLED
const char* Database::DatabaseCloseTask::debugTaskName() const
{
return "DatabaseCloseTask";
@@ -150,7 +154,7 @@ void Database::DatabaseTransactionTask::doPerformTask()
m_transaction->database()->inProgressTransactionCompleted();
}
-#ifndef NDEBUG
+#if !LOG_DISABLED
const char* Database::DatabaseTransactionTask::debugTaskName() const
{
return "DatabaseTransactionTask";
@@ -172,7 +176,7 @@ void Database::DatabaseTableNamesTask::doPerformTask()
m_tableNames = database()->performGetTableNames();
}
-#ifndef NDEBUG
+#if !LOG_DISABLED
const char* Database::DatabaseTableNamesTask::debugTaskName() const
{
return "DatabaseTableNamesTask";
diff --git a/Source/WebCore/storage/DatabaseTask.h b/Source/WebCore/storage/DatabaseTask.h
index e1df591..faadc69 100644
--- a/Source/WebCore/storage/DatabaseTask.h
+++ b/Source/WebCore/storage/DatabaseTask.h
@@ -90,7 +90,7 @@ private:
Database* m_database;
DatabaseTaskSynchronizer* m_synchronizer;
-#ifndef NDEBUG
+#if !LOG_DISABLED
virtual const char* debugTaskName() const = 0;
bool m_complete;
#endif
@@ -107,7 +107,7 @@ private:
DatabaseOpenTask(Database*, bool setVersionInNewDatabase, DatabaseTaskSynchronizer*, ExceptionCode&, bool& success);
virtual void doPerformTask();
-#ifndef NDEBUG
+#if !LOG_DISABLED
virtual const char* debugTaskName() const;
#endif
@@ -127,7 +127,7 @@ private:
DatabaseCloseTask(Database*, DatabaseTaskSynchronizer*);
virtual void doPerformTask();
-#ifndef NDEBUG
+#if !LOG_DISABLED
virtual const char* debugTaskName() const;
#endif
};
@@ -146,7 +146,7 @@ private:
DatabaseTransactionTask(PassRefPtr<SQLTransaction>);
virtual void doPerformTask();
-#ifndef NDEBUG
+#if !LOG_DISABLED
virtual const char* debugTaskName() const;
#endif
@@ -164,7 +164,7 @@ private:
DatabaseTableNamesTask(Database*, DatabaseTaskSynchronizer*, Vector<String>& names);
virtual void doPerformTask();
-#ifndef NDEBUG
+#if !LOG_DISABLED
virtual const char* debugTaskName() const;
#endif
diff --git a/Source/WebCore/storage/SQLTransaction.cpp b/Source/WebCore/storage/SQLTransaction.cpp
index dfcd568..0b1ad25 100644
--- a/Source/WebCore/storage/SQLTransaction.cpp
+++ b/Source/WebCore/storage/SQLTransaction.cpp
@@ -117,7 +117,7 @@ void SQLTransaction::enqueueStatement(PassRefPtr<SQLStatement> statement)
m_statementQueue.append(statement);
}
-#ifndef NDEBUG
+#if !LOG_DISABLED
const char* SQLTransaction::debugStepName(SQLTransaction::TransactionStepMethod step)
{
if (step == &SQLTransaction::acquireLock)
diff --git a/Source/WebCore/storage/SQLTransaction.h b/Source/WebCore/storage/SQLTransaction.h
index 4c84f91..a0a83ed 100644
--- a/Source/WebCore/storage/SQLTransaction.h
+++ b/Source/WebCore/storage/SQLTransaction.h
@@ -105,7 +105,7 @@ private:
void deliverTransactionErrorCallback();
void cleanupAfterTransactionErrorCallback();
-#ifndef NDEBUG
+#if !LOG_DISABLED
static const char* debugStepName(TransactionStepMethod);
#endif
diff --git a/Source/WebCore/svg/SVGFontFaceUriElement.h b/Source/WebCore/svg/SVGFontFaceUriElement.h
index ad9ba97..3806315 100644
--- a/Source/WebCore/svg/SVGFontFaceUriElement.h
+++ b/Source/WebCore/svg/SVGFontFaceUriElement.h
@@ -45,22 +45,6 @@ private:
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void insertedIntoDocument();
-#ifdef ANDROID_INSTRUMENT
- void* operator new(size_t size) {
- return SVGElement::operator new(size);
- }
- void* operator new[](size_t size) {
- return SVGElement::operator new[](size);
- }
-
- void operator delete(void* p, size_t size) {
- SVGElement::operator delete(p, size);
- }
- void operator delete[](void* p, size_t size) {
- SVGElement::operator delete[](p, size);
- }
-#endif
-
void loadFont();
CachedResourceHandle<CachedFont> m_cachedFont;
diff --git a/Source/WebCore/workers/WorkerContext.idl b/Source/WebCore/workers/WorkerContext.idl
index e31f5ad..5a6c407 100644
--- a/Source/WebCore/workers/WorkerContext.idl
+++ b/Source/WebCore/workers/WorkerContext.idl
@@ -126,6 +126,7 @@ module threads {
attribute Int32ArrayConstructor Int32Array; // Usable with new operator
attribute Uint32ArrayConstructor Uint32Array; // Usable with new operator
attribute Float32ArrayConstructor Float32Array; // Usable with new operator
+ attribute Float64ArrayConstructor Float64Array; // Usable with new operator
};
}
diff --git a/Source/WebCore/xml/XSLImportRule.h b/Source/WebCore/xml/XSLImportRule.h
index 3c5939d..5c0ca8a 100644
--- a/Source/WebCore/xml/XSLImportRule.h
+++ b/Source/WebCore/xml/XSLImportRule.h
@@ -52,22 +52,6 @@ public:
bool isLoading();
void loadSheet();
-#ifdef ANDROID_INSTRUMENT
- void* operator new(size_t size) {
- return StyleBase::operator new(size);
- }
- void* operator new[](size_t size) {
- return StyleBase::operator new[](size);
- }
-
- void operator delete(void* p, size_t size) {
- StyleBase::operator delete(p, size);
- }
- void operator delete[](void* p, size_t size) {
- StyleBase::operator delete[](p, size);
- }
-#endif
-
private:
XSLImportRule(XSLStyleSheet* parentSheet, const String& href);