summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/Android.derived.v8bindings.mk13
-rw-r--r--Source/WebCore/Android.mk45
-rw-r--r--Source/WebCore/Android.v8bindings.mk8
-rw-r--r--Source/WebCore/ChangeLog379
-rw-r--r--Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h10
-rw-r--r--Source/WebCore/bindings/v8/custom/V8Uint8ClampedArrayCustom.cpp67
-rw-r--r--Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp5
-rw-r--r--Source/WebCore/css/CSSFontSelector.cpp3
-rw-r--r--Source/WebCore/css/CSSImageValue.cpp4
-rw-r--r--Source/WebCore/css/CSSImportRule.cpp5
-rw-r--r--Source/WebCore/css/CSSStyleSelector.cpp6
-rw-r--r--Source/WebCore/dom/Attr.cpp2
-rw-r--r--Source/WebCore/dom/CharacterData.cpp1
-rw-r--r--Source/WebCore/dom/ContainerNode.cpp47
-rw-r--r--Source/WebCore/dom/ContainerNode.h11
-rw-r--r--Source/WebCore/dom/Document.cpp55
-rw-r--r--Source/WebCore/dom/Document.h33
-rw-r--r--Source/WebCore/dom/DocumentOrderedMap.cpp2
-rw-r--r--Source/WebCore/dom/DynamicNodeList.cpp46
-rw-r--r--Source/WebCore/dom/DynamicNodeList.h8
-rw-r--r--Source/WebCore/dom/Element.cpp22
-rw-r--r--Source/WebCore/dom/Element.h23
-rw-r--r--Source/WebCore/dom/NamedNodeMap.cpp10
-rw-r--r--Source/WebCore/dom/NamedNodeMap.h14
-rw-r--r--Source/WebCore/dom/Node.cpp250
-rw-r--r--Source/WebCore/dom/Node.h84
-rw-r--r--Source/WebCore/dom/NodeRareData.h16
-rw-r--r--Source/WebCore/dom/ProcessingInstruction.cpp5
-rw-r--r--Source/WebCore/dom/RequestAnimationFrameCallback.h4
-rw-r--r--Source/WebCore/dom/ScriptElement.cpp3
-rw-r--r--Source/WebCore/dom/ScriptedAnimationController.cpp78
-rw-r--r--Source/WebCore/dom/ScriptedAnimationController.h15
-rw-r--r--Source/WebCore/dom/SelectorNodeList.cpp16
-rw-r--r--Source/WebCore/dom/TagNodeList.cpp35
-rw-r--r--Source/WebCore/dom/TagNodeList.h49
-rw-r--r--Source/WebCore/dom/Text.cpp2
-rw-r--r--Source/WebCore/dom/Text.h5
-rw-r--r--Source/WebCore/dom/TreeScope.cpp4
-rw-r--r--Source/WebCore/editing/MarkupAccumulator.cpp212
-rw-r--r--Source/WebCore/editing/MarkupAccumulator.h39
-rw-r--r--Source/WebCore/editing/markup.cpp48
-rw-r--r--Source/WebCore/history/PageCache.cpp4
-rw-r--r--Source/WebCore/html/CollectionCache.cpp1
-rw-r--r--Source/WebCore/html/CollectionCache.h2
-rw-r--r--Source/WebCore/html/HTMLAllCollection.cpp43
-rw-r--r--Source/WebCore/html/HTMLAllCollection.h6
-rw-r--r--Source/WebCore/html/HTMLAreaElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in1
-rw-r--r--Source/WebCore/html/HTMLBRElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLBaseElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp60
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h11
-rw-r--r--Source/WebCore/html/HTMLCollection.cpp226
-rw-r--r--Source/WebCore/html/HTMLCollection.h10
-rw-r--r--Source/WebCore/html/HTMLDataGridCellElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLDataGridColElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLElement.cpp45
-rw-r--r--Source/WebCore/html/HTMLElement.h2
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLFrameElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLHRElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLImageElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLImageElement.idl3
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp40
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h2
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h6
-rw-r--r--Source/WebCore/html/HTMLMediaElement.idl2
-rw-r--r--Source/WebCore/html/HTMLMetaElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLParamElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLSourceElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLTableColElement.cpp1
-rw-r--r--Source/WebCore/html/HTMLTagNames.in2
-rw-r--r--Source/WebCore/html/HTMLWbrElement.cpp62
-rw-r--r--Source/WebCore/html/HTMLWbrElement.h50
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.cpp38
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.h10
-rw-r--r--Source/WebCore/html/canvas/ArrayBuffer.idl3
-rw-r--r--Source/WebCore/html/canvas/ArrayBufferView.h2
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp63
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h21
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp10
-rw-r--r--Source/WebCore/html/canvas/Uint8Array.h3
-rw-r--r--Source/WebCore/html/canvas/Uint8ClampedArray.cpp73
-rw-r--r--Source/WebCore/html/canvas/Uint8ClampedArray.h64
-rw-r--r--Source/WebCore/html/canvas/Uint8ClampedArray.idl49
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp210
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h21
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.cpp17
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.h6
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.cpp10
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.h7
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.cpp84
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.h21
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp523
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h60
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.idl31
-rw-r--r--Source/WebCore/html/canvas/WebKitLoseContext.cpp9
-rw-r--r--Source/WebCore/html/canvas/WebKitLoseContext.h2
-rw-r--r--Source/WebCore/html/canvas/WebKitLoseContext.idl2
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.cpp6
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp7
-rw-r--r--Source/WebCore/loader/CrossOriginAccessControl.cpp41
-rw-r--r--Source/WebCore/loader/CrossOriginAccessControl.h20
-rw-r--r--Source/WebCore/loader/DocumentThreadableLoader.cpp38
-rw-r--r--Source/WebCore/loader/EmptyClients.h2
-rw-r--r--Source/WebCore/loader/ImageLoader.cpp13
-rw-r--r--Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp8
-rw-r--r--Source/WebCore/loader/cache/CachedCSSStyleSheet.h2
-rw-r--r--Source/WebCore/loader/cache/CachedFont.cpp4
-rw-r--r--Source/WebCore/loader/cache/CachedFont.h2
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp10
-rw-r--r--Source/WebCore/loader/cache/CachedImage.h2
-rw-r--r--Source/WebCore/loader/cache/CachedResource.cpp17
-rw-r--r--Source/WebCore/loader/cache/CachedResource.h49
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp195
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.h24
-rw-r--r--Source/WebCore/loader/cache/CachedResourceRequest.cpp25
-rw-r--r--Source/WebCore/loader/cache/CachedScript.cpp4
-rw-r--r--Source/WebCore/loader/cache/CachedScript.h2
-rw-r--r--Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp8
-rw-r--r--Source/WebCore/loader/cache/CachedXSLStyleSheet.h2
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.cpp4
-rw-r--r--Source/WebCore/make-hash-tools.pl14
-rw-r--r--Source/WebCore/page/Chrome.cpp2
-rw-r--r--Source/WebCore/page/ChromeClient.h2
-rw-r--r--Source/WebCore/page/DOMWindow.cpp8
-rw-r--r--Source/WebCore/page/DOMWindow.h5
-rw-r--r--Source/WebCore/page/DOMWindow.idl9
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp12
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.h3
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.cpp9
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h30
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h9
-rw-r--r--Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp102
-rw-r--r--Source/WebCore/platform/graphics/android/Extensions3DAndroid.h64
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp1368
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp1103
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h221
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp87
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h61
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp39
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h14
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/WebGLLayer.cpp82
-rw-r--r--Source/WebCore/platform/graphics/android/WebGLLayer.h62
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp14
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h4
-rw-r--r--Source/WebCore/platform/image-decoders/ImageDecoder.cpp8
-rw-r--r--Source/WebCore/platform/network/ResourceRequestBase.h1
-rw-r--r--Source/WebCore/platform/network/android/ResourceRequest.h1
-rw-r--r--Source/WebCore/rendering/HitTestResult.cpp2
-rw-r--r--Source/WebCore/rendering/RenderBlockLineLayout.cpp7
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp6
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.cpp124
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp10
-rw-r--r--Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp6
-rw-r--r--Source/WebCore/rendering/svg/SVGShadowTreeElements.h4
-rw-r--r--Source/WebCore/svg/SVGElement.cpp4
-rw-r--r--Source/WebCore/svg/SVGElement.h2
-rw-r--r--Source/WebCore/svg/SVGFEImageElement.cpp3
-rw-r--r--Source/WebCore/svg/SVGFontFaceUriElement.cpp3
-rw-r--r--Source/WebCore/svg/SVGGElement.cpp4
-rw-r--r--Source/WebCore/svg/SVGGElement.h2
-rw-r--r--Source/WebCore/svg/SVGStyledElement.cpp4
-rw-r--r--Source/WebCore/svg/SVGStyledElement.h2
-rw-r--r--Source/WebCore/svg/SVGStyledLocatableElement.cpp4
-rw-r--r--Source/WebCore/svg/SVGStyledLocatableElement.h2
-rw-r--r--Source/WebCore/svg/SVGStyledTransformableElement.cpp4
-rw-r--r--Source/WebCore/svg/SVGStyledTransformableElement.h2
-rw-r--r--Source/WebCore/xml/XSLImportRule.cpp4
178 files changed, 6466 insertions, 1260 deletions
diff --git a/Source/WebCore/Android.derived.v8bindings.mk b/Source/WebCore/Android.derived.v8bindings.mk
index 509d21e..ec04e1a 100644
--- a/Source/WebCore/Android.derived.v8bindings.mk
+++ b/Source/WebCore/Android.derived.v8bindings.mk
@@ -1,5 +1,7 @@
##
## Copyright 2009, The Android Open Source Project
+## Copyright (C) 2011 Sony Ericsson Mobile Communications AB
+## Copyright (C) 2012 Sony Mobile Communications AB
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
@@ -39,6 +41,8 @@ ifeq ($(ENABLE_SVG), true)
FEATURE_DEFINES += ENABLE_SVG=1
endif
+FEATURE_DEFINES += ENABLE_REQUEST_ANIMATION_FRAME
+
# CSS
GEN := \
$(intermediates)/bindings/V8CSSCharsetRule.h \
@@ -125,6 +129,7 @@ GEN := \
$(intermediates)/bindings/V8ProgressEvent.h \
$(intermediates)/bindings/V8Range.h \
$(intermediates)/bindings/V8RangeException.h \
+ $(intermediates)/bindings/V8RequestAnimationFrameCallback.h \
$(intermediates)/bindings/V8Text.h \
$(intermediates)/bindings/V8TextEvent.h \
$(intermediates)/bindings/V8Touch.h \
@@ -308,6 +313,7 @@ GEN := \
$(intermediates)/bindings/V8OESTextureFloat.h \
$(intermediates)/bindings/V8OESVertexArrayObject.h \
$(intermediates)/bindings/V8Uint8Array.h \
+ $(intermediates)/bindings/V8Uint8ClampedArray.h \
$(intermediates)/bindings/V8Uint16Array.h \
$(intermediates)/bindings/V8Uint32Array.h \
$(intermediates)/bindings/V8WebGLActiveInfo.h \
@@ -322,6 +328,13 @@ GEN := \
$(intermediates)/bindings/V8WebGLUniformLocation.h \
$(intermediates)/bindings/V8WebGLVertexArrayObjectOES.h
+ifeq ($(ENABLE_WEBGL), true)
+GEN += \
+ $(intermediates)/bindings/V8OESStandardDerivatives.h \
+ $(intermediates)/bindings/V8WebGLContextEvent.h \
+ $(intermediates)/bindings/V8WebKitLoseContext.h
+endif
+
$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(PRIVATE_PATH) perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --include html/canvas --outputdir $(dir $@) $<
$(GEN): $(intermediates)/bindings/V8%.h : $(LOCAL_PATH)/html/canvas/%.idl $(js_binding_scripts)
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index 10eb822..1f8868e 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -1,5 +1,7 @@
##
## Copyright 2009, The Android Open Source Project
+## Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+## Copyright (C) 2012 Sony Mobile Communications AB
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
@@ -339,6 +341,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/HTMLParserErrorCodes.cpp \
html/HTMLTableRowsCollection.cpp \
html/HTMLViewSourceDocument.cpp \
+ html/HTMLWbrElement.cpp \
html/HiddenInputType.cpp \
html/ImageData.cpp \
html/ImageDocument.cpp \
@@ -388,10 +391,30 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/canvas/Uint16Array.cpp \
html/canvas/Uint32Array.cpp \
html/canvas/Uint8Array.cpp \
+ html/canvas/Uint8ClampedArray.cpp \
html/canvas/WebGLExtension.cpp \
html/canvas/WebGLObject.cpp \
- html/canvas/WebGLVertexArrayObjectOES.cpp \
- \
+ html/canvas/WebGLVertexArrayObjectOES.cpp
+
+ifeq ($(ENABLE_WEBGL), true)
+LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
+ html/canvas/CanvasContextAttributes.cpp \
+ html/canvas/OESStandardDerivatives.cpp \
+ html/canvas/WebGLBuffer.cpp \
+ html/canvas/WebGLContextAttributes.cpp \
+ html/canvas/WebGLContextEvent.cpp \
+ html/canvas/WebGLFramebuffer.cpp \
+ html/canvas/WebGLGetInfo.cpp \
+ html/canvas/WebGLProgram.cpp \
+ html/canvas/WebGLRenderbuffer.cpp \
+ html/canvas/WebGLRenderingContext.cpp \
+ html/canvas/WebGLShader.cpp \
+ html/canvas/WebGLTexture.cpp \
+ html/canvas/WebGLUniformLocation.cpp \
+ html/canvas/WebKitLoseContext.cpp
+endif
+
+LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/parser/HTMLConstructionSite.cpp \
html/parser/HTMLDocumentParser.cpp \
html/parser/HTMLElementStack.cpp \
@@ -702,6 +725,18 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/utils/ClassTracker.cpp \
platform/graphics/android/utils/LinearAllocator.cpp
+ifeq ($(ENABLE_WEBGL), true)
+LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
+ platform/graphics/ANGLEWebKitBridge.cpp \
+ platform/graphics/GraphicsContext3D.cpp \
+ platform/graphics/android/Extensions3DAndroid.cpp \
+ platform/graphics/android/GraphicsContext3DAndroid.cpp \
+ platform/graphics/android/GraphicsContext3DInternal.cpp \
+ platform/graphics/android/GraphicsContext3DProxy.cpp \
+ platform/graphics/android/WebGLLayer.cpp \
+ platform/image-decoders/png/PNGImageDecoder.cpp
+endif
+
ifeq ($(ENABLE_SVG), true)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/filters/DistantLightSource.cpp \
@@ -752,6 +787,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/image-decoders/gif/GIFImageReader.cpp \
\
platform/image-encoders/skia/JPEGImageEncoder.cpp \
+ platform/image-encoders/skia/PNGImageEncoder.cpp \
\
platform/leveldb/LevelDBDatabase.cpp \
platform/leveldb/LevelDBIterator.cpp \
@@ -1274,3 +1310,8 @@ ifeq ($(SUPPORT_COMPLEX_SCRIPTS),true)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/fonts/HarfbuzzSkia.cpp
endif
+
+# HACK for qcom devices CPU upload mode
+ifeq ($(TARGET_FORCE_CPU_UPLOAD),true)
+LOCAL_CFLAGS += -DFORCE_CPU_UPLOAD
+endif
diff --git a/Source/WebCore/Android.v8bindings.mk b/Source/WebCore/Android.v8bindings.mk
index 7858ef3..9075657 100644
--- a/Source/WebCore/Android.v8bindings.mk
+++ b/Source/WebCore/Android.v8bindings.mk
@@ -1,5 +1,7 @@
##
## Copyright 2009, The Android Open Source Project
+## Copyright (C) 2011, Sony Ericsson Mobile Communications AB
+## Copyright (C) 2012 Sony Mobile Communications AB
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
@@ -171,9 +173,15 @@ LOCAL_SRC_FILES += \
bindings/v8/custom/V8Uint16ArrayCustom.cpp \
bindings/v8/custom/V8Uint32ArrayCustom.cpp \
bindings/v8/custom/V8Uint8ArrayCustom.cpp \
+ bindings/v8/custom/V8Uint8ClampedArrayCustom.cpp \
bindings/v8/custom/V8WebKitAnimationCustom.cpp \
bindings/v8/custom/V8WebSocketCustom.cpp
+ifeq ($(ENABLE_WEBGL), true)
+LOCAL_SRC_FILES += \
+ bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
+endif
+
ifeq ($(ENABLE_SVG), true)
LOCAL_SRC_FILES += \
bindings/v8/custom/V8SVGDocumentCustom.cpp \
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 11f0168..c877435 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,384 @@
+2012-03-16 Kentaro Hara <haraken@chromium.org>
+
+ [Performance] Optimize innerHTML and outerHTML
+ https://bugs.webkit.org/show_bug.cgi?id=81214
+
+ Reviewed by Adam Barth.
+
+ This patch makes innerHTML and outerHTML 2.4 times faster.
+
+ Performance test: https://bugs.webkit.org/attachment.cgi?id=132034
+ The performance test measures body.innerHTML for 3000 lines of HTML,
+ which is copied from the HTML spec.
+
+ - Chromium/Mac without the patch
+ div.innerHTML: 1658.6 ms
+ div.outerHTML: 4859.6 ms
+ body.innerHTML: 640.2 ms
+ body.outerHTML: 641.8 ms
+
+ - Chromium/Mac with the patch
+ div.innerHTML: 751.0 ms
+ div.outerHTML: 2096.0 ms
+ body.innerHTML: 271.2 ms
+ body.outerHTML: 271.2 ms
+
+ - Chromium/Linux without the patch
+ div.innerHTML: 950.4 ms
+ div.outerHTML: 2257.8 ms
+ body.innerHTML: 452.8 ms
+ body.outerHTML: 457.6 ms
+
+ - Chromium/Linux with the patch
+ div.innerHTML: 582.4 ms
+ div.outerHTML: 1283.0 ms
+ body.innerHTML: 233.0 ms
+ body.outerHTML: 233.4 ms
+
+ - AppleWebKit/Mac without the patch
+ div.innerHTML: 900.6 ms
+ div.outerHTML: 2245.2 ms
+ body.innerHTML: 462.6 ms
+ body.outerHTML: 468.0 ms
+
+ - AppleWebKit/Mac with the patch
+ div.innerHTML: 529.8 ms
+ div.outerHTML: 1090.2 ms
+ body.innerHTML: 239.2 ms
+ body.outerHTML: 239.2 ms
+
+ This patch applies the following two optimizations:
+
+ (a) Remove redundant copies between Vector<String> and StringBuilders
+ in MarkupAccumulator::serializeNodes(), MarkupAccumulator::appendStartTag(),
+ and MarkupAccumulator::appendEndTag().
+
+ (Previous behavior)
+ - Create a StringBuilder for each tag.
+ - Append a created string in each StringBuilder to Vector<String>,
+ parsing the DOM tree.
+ - After the parsing, allocate a StringBuilder whose size is the sum
+ of all Strings in Vector<String>.
+ - Append all Strings in Vector<String> to the StringBuilder.
+ (New behavior)
+ - Allocate a StringBuilder with a default buffer size.
+ - Append created strings to the StringBuilder, incrementally parsing
+ the DOM tree.
+
+ (b) Optimize stringBuilder.append().
+ (b-1) Replace stringBuilder.append("A") with stringBuilder.append('A').
+ stringBuilder.append("A") requires to cast the characters to LChar*,
+ and then call strlen("A"). stringBuilder.append('A') is faster.
+ (b-2) Replace stringBuilder.append("AB") with stringBuilder.append('A')
+ and stringBuilder.append('B'). In my experiment, appending characters
+ one by one is faster than appending the characters at a breath if the
+ number of characters is less than 3.
+ (b-3) Hard-code a string length; i.e. replace stringBuilder.append("ABCDE")
+ with stringBuilder.append("ABCDE", 5). While the former requires to call
+ strlen("ABCDE"), the latter does not.
+
+ (a) improves performance by 170% ~ 200%. (b) improves performance by 30 ~ 40%.
+
+ Tests: fast/dom/Range/range-extract-contents.html
+ fast/dom/serialize-nodes.xhtml
+ fast/dom/XMLSerializer.html
+ and all other tests that use innerHTML or outerHTML.
+ No change in the test results.
+
+ * editing/MarkupAccumulator.cpp:
+ (WebCore::MarkupAccumulator::serializeNodes):
+ (WebCore::MarkupAccumulator::appendString):
+ (WebCore::MarkupAccumulator::appendStartTag):
+ (WebCore::MarkupAccumulator::appendEndTag):
+ (WebCore::MarkupAccumulator::concatenateMarkup):
+ (WebCore::MarkupAccumulator::appendQuotedURLAttributeValue):
+ (WebCore::MarkupAccumulator::appendComment):
+ (WebCore::MarkupAccumulator::appendDocumentType):
+ (WebCore::MarkupAccumulator::appendProcessingInstruction):
+ (WebCore::MarkupAccumulator::appendOpenTag):
+ (WebCore::MarkupAccumulator::appendAttribute):
+ (WebCore::MarkupAccumulator::appendCDATASection):
+ * editing/MarkupAccumulator.h:
+ (MarkupAccumulator):
+
+2012-06-27 Kentaro Hara <haraken@chromium.org>
+
+ Performance: Optimize Dromaeo/dom-query.html by caching NodeRareData on Document
+ https://bugs.webkit.org/show_bug.cgi?id=90059
+
+ Reviewed by Ryosuke Niwa.
+
+ This patch improves performance of document.getElementsBy*().
+ e.g. the patch makes Dromaeo/dom-query.html 5.4% faster.
+
+ Dromaeo/dom-query.html without the patch (Chromium/Linux):
+ 784714 runs/s, 765947 runs/s, 803109 runs/s, 804450 runs/s
+
+ Dromaeo/dom-query.html with the patch (Chromium/Linux):
+ 839245 runs/s, 829867 runs/s, 811032 runs/s, 847486 runs/s
+
+ Based on the assumption that document.getElementsByClassName(),
+ document.getElementsByTagName() and document.getElementsByName()
+ would be used frequently in the real world, this patch implements
+ a fast path for Document methods that require to access NodeRareData.
+ Specifically, this patch caches a pointer to NodeRareData on Document,
+ by which Document can access NodeRareData without looking up a HashMap.
+
+ The only performance concern is the overhead of the isDocumentNode() check
+ that this patch added to Node::ensureRareData. However, I could not
+ observe any performance regression caused by the overhead.
+
+ No tests. No change in behavior.
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::setCachedRareData): I didn't inline this method,
+ since the inlining slightly regressed performance for some reason.
+ (WebCore):
+ * dom/Document.h:
+ (WebCore):
+ (WebCore::Document::cachedRareData):
+ (Document):
+ (~Document): Moved 'm_document = 0' to the tail of the destructor,
+ since isDocumentNode() has to return true in clearRareData() that is called
+ in ~Document().
+ * dom/Node.cpp:
+ (WebCore::Node::ensureRareData):
+ (~Node): Moved the assertion into clearRareData().
+
+2012-04-09 James Robinson <jamesr@chromium.org>
+
+ Remove partially implemented per-Element visibility checks from requestAnimationFrame logic
+ https://bugs.webkit.org/show_bug.cgi?id=74232
+
+ Reviewed by Dean Jackson.
+
+ The initial requestAnimationFrame implementation had an Element parameter as the second argument to the
+ function. This element was intended to convey the element associated with the animation so that when the element
+ was not visible the animation callback would not be run. The checked in implementation does a very limited check
+ - testing for display:none and being detached from the tree - but does it in a way that does not work correctly
+ if an element's visibility is manipulated by a callback running from a different document. It also adds
+ significant complexity to the code, making it less hackable and easy to introduce subtle security bugs or
+ infinite loops.
+
+ This patch removes the parameter. Since it has always been marked optional, there is no web compat risk.
+
+ If this functionality is added back in the future it needs to be implemented in a way that considers all
+ callbacks within a Page and not only those within a single Document.
+
+2011-12-16 Zhenyao Mo <zmo@google.com>
+
+ Postpone deleteRenderbuffer/deleteTexture until all framebuffer attachment points are removed.
+ https://bugs.webkit.org/show_bug.cgi?id=74741
+
+ Reviewed by Kenneth Russell.
+
+ Use WebGLObject's attachment count mechanism to track if a renderbuffer/texture
+ is still attached to framebuffers, and if its deletion should be delated or not.
+
+ * html/canvas/WebGLFramebuffer.cpp:
+ (WebCore::WebGLFramebuffer::setAttachmentForBoundFramebuffer):
+ (WebCore::WebGLFramebuffer::getAttachment):
+ (WebCore::WebGLFramebuffer::removeAttachmentFromBoundFramebuffer):
+ (WebCore::WebGLFramebuffer::deleteObjectImpl):
+ (WebCore::WebGLFramebuffer::isBound):
+ * html/canvas/WebGLFramebuffer.h:
+
+2012-04-10 Zhenyao Mo <zmo@google.com>
+
+ WebGLRenderingContext should defer caching program info
+ https://bugs.webkit.org/show_bug.cgi?id=83513
+
+ Reviewed by Kenneth Russell.
+
+ * html/canvas/WebGLProgram.cpp:
+ (WebCore::WebGLProgram::WebGLProgram):
+ (WebCore::WebGLProgram::numActiveAttribLocations): call cacheInfoIfNeeded();
+ (WebCore::WebGLProgram::getActiveAttribLocation): Ditto.
+ (WebCore::WebGLProgram::isUsingVertexAttrib0): Ditto.
+ (WebCore::WebGLProgram::getLinkStatus): Ditto.
+ (WebCore):
+ (WebCore::WebGLProgram::cacheActiveAttribLocations):
+ (WebCore::WebGLProgram::cacheInfoIfNeeded): Cache link status, active attire locations, etc if needed.
+ (WebCore::WebGLProgram::increaseLinkCount): also invalidate cached info.
+ * html/canvas/WebGLProgram.h:
+ (WebGLProgram):
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore):
+ (WebCore::WebGLRenderingContext::linkProgram): Do not cache program info immediately.
+
+2012-05-04 Zhenyao Mo <zmo@google.com>
+
+ vertexAttribPointer needs to reject large negative offsets
+ https://bugs.webkit.org/show_bug.cgi?id=85117
+
+ Reviewed by Kenneth Russell.
+
+ * html/canvas/WebGLRenderingContext.cpp: Use long long for GLsizeiptr and GLintptr
+ (WebCore):
+ (WebCore::WebGLRenderingContext::bufferData):
+ (WebCore::WebGLRenderingContext::bufferSubData):
+ (WebCore::WebGLRenderingContext::drawElements):
+ (WebCore::WebGLRenderingContext::getVertexAttribOffset):
+ (WebCore::WebGLRenderingContext::vertexAttribPointer):
+ * html/canvas/WebGLRenderingContext.h: Ditto
+ (WebGLRenderingContext):
+ * html/canvas/WebGLRenderingContext.idl: Ditto
+
+2011-05-11 Antoine Labour <piman@chromium.org>
+ * dom/Document.cpp:
+ (WebCore::Document::webkitRequestAnimationFrame):
+ * dom/Document.h:
+ * dom/RequestAnimationFrameCallback.h:
+ * dom/ScriptedAnimationController.cpp:
+ (WebCore::ScriptedAnimationController::registerCallback):
+ (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
+ * dom/ScriptedAnimationController.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::webkitRequestAnimationFrame):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+
+2011-12-12 James Robinson <jamesr@chromium.org>
+
+ Rename webkitCancelRequestAnimationFrame to webkitCancelAnimationFrame to match spec change
+ https://bugs.webkit.org/show_bug.cgi?id=74231
+
+ Reviewed by Simon Fraser.
+
+ The RequestAnimationFrame spec has renamed cancelRequestAnimationFrame to cancelAnimationFrame in response to
+ feedback from Mozilla and Microsoft that the old name was too long and didn't parallel setTimeout/clearTimeout
+ and setInterval/clearInterval very well. This updates our IDL to match, while preserving the old name as an
+ alias to be compatible with current content.
+
+ * dom/Document.cpp:
+ (WebCore::Document::webkitCancelAnimationFrame):
+ * dom/Document.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::webkitCancelAnimationFrame):
+ * page/DOMWindow.h:
+ (WebCore::DOMWindow::webkitCancelRequestAnimationFrame):
+ * page/DOMWindow.idl:
+
+2011-09-26 James Robinson <jamesr@chromium.org>
+
+ [mac] Timestamp parameter to requestAnimationFrame is busted in USE(REQUEST_ANIMATION_FRAME_TIMER) path
+ https://bugs.webkit.org/show_bug.cgi?id=68769
+
+ Reviewed by Simon Fraser.
+
+ Convert the time parameter from double to DOMTimeStamp using convertSecondsToDOMTimeStamp rather than relying on
+ implicit double->long conversion, which ignores the units of the value.
+
+ Test: fast/animation/request-animation-frame-timestamps-advance.html
+
+ * dom/ScriptedAnimationController.cpp:
+ (WebCore::ScriptedAnimationController::animationTimerFired):
+
+2011-09-09 Chris Marrin <cmarrin@apple.com>
+
+ requestAnimationFrame doesn't throttle on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=67171
+
+ Reviewed by Simon Fraser.
+
+ Changed requestAnimationFrame to use a Timer in ScriptedAnimationController
+ on Mac, rather than runLoopObservers. The Timer is throttled to fire no
+ faster than every 15ms. It is behind a WTF_USE_REQUEST_ANIMATION_FRAME_TIMER
+ flag and can be used by any implementation, but currently it is only enabled
+ by PLATFORM(MAC).
+
+ * dom/ScriptedAnimationController.cpp:
+ (WebCore::ScriptedAnimationController::ScriptedAnimationController):
+ (WebCore::ScriptedAnimationController::resume):
+ (WebCore::ScriptedAnimationController::registerCallback):
+ (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
+ (WebCore::ScriptedAnimationController::scheduleAnimation):
+ (WebCore::ScriptedAnimationController::animationTimerFired):
+ * dom/ScriptedAnimationController.h:
+ * loader/EmptyClients.h:
+ * page/Chrome.cpp:
+ (WebCore::Chrome::scheduleAnimation):
+ * page/ChromeClient.h:
+
2011-05-11 Antoine Labour <piman@chromium.org>
+ * dom/Document.cpp:
+ (WebCore::Document::webkitRequestAnimationFrame):
+ * dom/Document.h:
+ * dom/RequestAnimationFrameCallback.h:
+ * dom/ScriptedAnimationController.cpp:
+ (WebCore::ScriptedAnimationController::registerCallback):
+ (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
+ * dom/ScriptedAnimationController.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::webkitRequestAnimationFrame):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+
+2011-12-12 James Robinson <jamesr@chromium.org>
+
+ Rename webkitCancelRequestAnimationFrame to webkitCancelAnimationFrame to match spec change
+ https://bugs.webkit.org/show_bug.cgi?id=74231
+
+ Reviewed by Simon Fraser.
+
+ The RequestAnimationFrame spec has renamed cancelRequestAnimationFrame to cancelAnimationFrame in response to
+ feedback from Mozilla and Microsoft that the old name was too long and didn't parallel setTimeout/clearTimeout
+ and setInterval/clearInterval very well. This updates our IDL to match, while preserving the old name as an
+ alias to be compatible with current content.
+
+ * dom/Document.cpp:
+ (WebCore::Document::webkitCancelAnimationFrame):
+ * dom/Document.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::webkitCancelAnimationFrame):
+ * page/DOMWindow.h:
+ (WebCore::DOMWindow::webkitCancelRequestAnimationFrame):
+ * page/DOMWindow.idl:
+
+2011-09-26 James Robinson <jamesr@chromium.org>
+
+ [mac] Timestamp parameter to requestAnimationFrame is busted in USE(REQUEST_ANIMATION_FRAME_TIMER) path
+ https://bugs.webkit.org/show_bug.cgi?id=68769
+
+ Reviewed by Simon Fraser.
+
+ Convert the time parameter from double to DOMTimeStamp using convertSecondsToDOMTimeStamp rather than relying on
+ implicit double->long conversion, which ignores the units of the value.
+
+ Test: fast/animation/request-animation-frame-timestamps-advance.html
+
+ * dom/ScriptedAnimationController.cpp:
+ (WebCore::ScriptedAnimationController::animationTimerFired):
+
+2011-09-09 Chris Marrin <cmarrin@apple.com>
+
+ requestAnimationFrame doesn't throttle on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=67171
+
+ Reviewed by Simon Fraser.
+
+ Changed requestAnimationFrame to use a Timer in ScriptedAnimationController
+ on Mac, rather than runLoopObservers. The Timer is throttled to fire no
+ faster than every 15ms. It is behind a WTF_USE_REQUEST_ANIMATION_FRAME_TIMER
+ flag and can be used by any implementation, but currently it is only enabled
+ by PLATFORM(MAC).
+
+ * dom/ScriptedAnimationController.cpp:
+ (WebCore::ScriptedAnimationController::ScriptedAnimationController):
+ (WebCore::ScriptedAnimationController::resume):
+ (WebCore::ScriptedAnimationController::registerCallback):
+ (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
+ (WebCore::ScriptedAnimationController::scheduleAnimation):
+ (WebCore::ScriptedAnimationController::animationTimerFired):
+ * dom/ScriptedAnimationController.h:
+ * loader/EmptyClients.h:
+ * page/Chrome.cpp:
+ (WebCore::Chrome::scheduleAnimation):
+ * page/ChromeClient.h:
+
+2011-05-11 Antoine Labour <piman@chromium.org>
Reviewed by David Levin.
Expose shouldBufferData to ThreadableLoaderOptions to be able to disable buffering of the
diff --git a/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h b/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
index f842b6d..4a107d5 100644
--- a/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
+++ b/Source/WebCore/bindings/v8/custom/V8ArrayBufferViewCustom.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -54,15 +55,16 @@ v8::Handle<v8::Value> constructWebGLArrayWithArrayBufferArgument(const v8::Argum
if (!ok)
return throwError("Could not convert argument 1 to a number");
}
- if ((buf->byteLength() - offset) % sizeof(ElementType))
- return throwError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.", V8Proxy::RangeError);
- uint32_t length = (buf->byteLength() - offset) / sizeof(ElementType);
+ uint32_t length = 0;
if (argLen > 2) {
length = toUInt32(args[2], ok);
if (!ok)
return throwError("Could not convert argument 2 to a number");
+ } else {
+ if ((buf->byteLength() - offset) % sizeof(ElementType))
+ return throwError("ArrayBuffer length minus the byteOffset is not a multiple of the element size.", V8Proxy::RangeError);
+ length = (buf->byteLength() - offset) / sizeof(ElementType);
}
-
RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length);
if (!array) {
V8Proxy::setDOMException(INDEX_SIZE_ERR);
diff --git a/Source/WebCore/bindings/v8/custom/V8Uint8ClampedArrayCustom.cpp b/Source/WebCore/bindings/v8/custom/V8Uint8ClampedArrayCustom.cpp
new file mode 100644
index 0000000..6a89b1f
--- /dev/null
+++ b/Source/WebCore/bindings/v8/custom/V8Uint8ClampedArrayCustom.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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 "ArrayBuffer.h"
+#include "Uint8ClampedArray.h"
+
+#include "V8Binding.h"
+#include "V8ArrayBuffer.h"
+#include "V8ArrayBufferViewCustom.h"
+#include "V8Uint8ClampedArray.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8Uint8ClampedArray::constructorCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.Uint8ClampedArray.Contructor");
+
+ return constructWebGLArray<Uint8ClampedArray, unsigned char>(args, &info, v8::kExternalPixelArray);
+}
+
+v8::Handle<v8::Value> V8Uint8ClampedArray::setCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.Uint8ClampedArray.set()");
+ return setWebGLArrayHelper<Uint8ClampedArray, V8Uint8ClampedArray>(args);
+}
+
+v8::Handle<v8::Value> toV8(Uint8ClampedArray* impl)
+{
+ if (!impl)
+ return v8::Null();
+ v8::Handle<v8::Object> wrapper = V8Uint8ClampedArray::wrap(impl);
+ if (!wrapper.IsEmpty())
+ wrapper->SetIndexedPropertiesToExternalArrayData(impl->baseAddress(), v8::kExternalPixelArray, impl->length());
+ return wrapper;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
index fa915b6..2441dfb 100644
--- a/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -148,6 +149,8 @@ static v8::Handle<v8::Value> toV8Object(const WebGLGetInfo& info)
return toV8(info.getWebGLTexture());
case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
return toV8(info.getWebGLUnsignedByteArray());
+ case WebGLGetInfo::kTypeWebGLUnsignedIntArray:
+ return toV8(info.getWebGLUnsignedIntArray());
case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
return toV8(info.getWebGLVertexArrayObjectOES());
default:
@@ -161,7 +164,7 @@ static v8::Handle<v8::Value> toV8Object(WebGLExtension* extension, v8::Handle<v8
if (!extension)
return v8::Null();
v8::Handle<v8::Value> extensionObject;
- const char* referenceName;
+ const char* referenceName = 0;
switch (extension->getName()) {
case WebGLExtension::WebKitLoseContextName:
extensionObject = toV8(static_cast<WebKitLoseContext*>(extension));
diff --git a/Source/WebCore/css/CSSFontSelector.cpp b/Source/WebCore/css/CSSFontSelector.cpp
index 0f70664..c460857 100644
--- a/Source/WebCore/css/CSSFontSelector.cpp
+++ b/Source/WebCore/css/CSSFontSelector.cpp
@@ -245,7 +245,8 @@ void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
Settings* settings = m_document ? m_document->frame() ? m_document->frame()->settings() : 0 : 0;
bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
if (allowDownloading && item->isSupportedFormat() && m_document) {
- CachedFont* cachedFont = m_document->cachedResourceLoader()->requestFont(item->resource());
+ ResourceRequest request(m_document->completeURL(item->resource()));
+ CachedFont* cachedFont = m_document->cachedResourceLoader()->requestFont(request);
if (cachedFont) {
source = new CSSFontFaceSource(item->resource(), cachedFont);
#if ENABLE(SVG_FONTS)
diff --git a/Source/WebCore/css/CSSImageValue.cpp b/Source/WebCore/css/CSSImageValue.cpp
index a9038b9..ffc6763 100644
--- a/Source/WebCore/css/CSSImageValue.cpp
+++ b/Source/WebCore/css/CSSImageValue.cpp
@@ -22,6 +22,7 @@
#include "CSSImageValue.h"
#include "CSSValueKeywords.h"
+#include "Document.h"
#include "MemoryCache.h"
#include "CachedImage.h"
#include "CachedResourceLoader.h"
@@ -71,7 +72,8 @@ StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const
if (!m_accessedImage) {
m_accessedImage = true;
- if (CachedImage* cachedImage = loader->requestImage(url)) {
+ ResourceRequest request(loader->document()->completeURL(url));
+ if (CachedImage* cachedImage = loader->requestImage(request)) {
cachedImage->addClient(this);
m_image = StyleCachedImage::create(cachedImage);
}
diff --git a/Source/WebCore/css/CSSImportRule.cpp b/Source/WebCore/css/CSSImportRule.cpp
index 81ade39..82b4981 100644
--- a/Source/WebCore/css/CSSImportRule.cpp
+++ b/Source/WebCore/css/CSSImportRule.cpp
@@ -134,10 +134,11 @@ void CSSImportRule::insertedIntoParent()
root = curr;
}
+ ResourceRequest request(parentSheet->document()->completeURL(absHref));
if (parentSheet->isUserStyleSheet())
- m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(absHref, parentSheet->charset());
+ m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, parentSheet->charset());
else
- m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(absHref, parentSheet->charset());
+ m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, parentSheet->charset());
if (m_cachedSheet) {
// if the import rule is issued dynamically, the sheet may be
// removed from the pending sheet count, so let the doc know
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index d81cc9d..f1a7a44 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -6,7 +6,7 @@
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
* Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011, The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -7037,7 +7037,7 @@ void CSSStyleSelector::SelectorChecker::allVisitedStateChanged()
{
if (m_linksCheckedForVisitedState.isEmpty())
return;
- for (Node* node = m_document; node; node = node->traverseNextNode()) {
+ for (Node* node = m_document; node; node = node->traverseNextNodeFastPath()) {
if (node->isLink())
node->setNeedsStyleRecalc();
}
@@ -7047,7 +7047,7 @@ void CSSStyleSelector::SelectorChecker::visitedStateChanged(LinkHash visitedHash
{
if (!m_linksCheckedForVisitedState.contains(visitedHash))
return;
- for (Node* node = m_document; node; node = node->traverseNextNode()) {
+ for (Node* node = m_document; node; node = node->traverseNextNodeFastPath()) {
const AtomicString* attr = linkAttribute(node);
if (attr && visitedLinkHash(m_document->baseURL(), *attr) == visitedHash)
node->setNeedsStyleRecalc();
diff --git a/Source/WebCore/dom/Attr.cpp b/Source/WebCore/dom/Attr.cpp
index e3ae348..346a819 100644
--- a/Source/WebCore/dom/Attr.cpp
+++ b/Source/WebCore/dom/Attr.cpp
@@ -69,6 +69,8 @@ void Attr::createTextChild()
textNode->setParent(this);
setFirstChild(textNode.get());
setLastChild(textNode.get());
+ textNode->updateNextNode();
+ textNode->updatePreviousNode();
}
}
diff --git a/Source/WebCore/dom/CharacterData.cpp b/Source/WebCore/dom/CharacterData.cpp
index b4af02d..78f57d0 100644
--- a/Source/WebCore/dom/CharacterData.cpp
+++ b/Source/WebCore/dom/CharacterData.cpp
@@ -189,6 +189,7 @@ void CharacterData::updateRenderer(unsigned offsetOfReplacedData, unsigned lengt
void CharacterData::dispatchModifiedEvent(StringImpl* oldData)
{
+ updatePrevNextNodesInSubtree();
if (parentNode())
parentNode()->childrenChanged();
if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp
index 2d22fa9..5574aa5 100644
--- a/Source/WebCore/dom/ContainerNode.cpp
+++ b/Source/WebCore/dom/ContainerNode.cpp
@@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -74,6 +75,7 @@ static void collectTargetNodes(Node* node, NodeVector& nodes)
void ContainerNode::removeAllChildren()
{
removeAllChildrenInContainer<Node, ContainerNode>(this);
+ updateNextNode();
}
void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
@@ -208,6 +210,8 @@ void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
newChild->setParent(this);
newChild->setPreviousSibling(prev);
newChild->setNextSibling(nextChild);
+ newChild->updatePreviousNode();
+ newChild->lastDescendantNode(true)->updateNextNode();
allowEventDispatch();
}
@@ -335,6 +339,9 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
child->setParent(this);
child->setPreviousSibling(prev.get());
child->setNextSibling(next);
+ child->updatePreviousNode();
+ child->lastDescendantNode(true)->updateNextNode();
+
allowEventDispatch();
childrenChanged(false, prev.get(), next, 1);
@@ -362,12 +369,13 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
void ContainerNode::willRemove()
{
- Vector<RefPtr<Node>, 10> nodes;
- nodes.reserveInitialCapacity(childNodeCount());
- for (Node* n = m_lastChild; n; n = n->previousSibling())
- nodes.append(n);
- for (; nodes.size(); nodes.removeLast())
- nodes.last().get()->willRemove();
+ Node* next;
+ Node* child = m_firstChild;
+ while (child) {
+ next = child->nextSibling();
+ child->willRemove();
+ child = next;
+ }
Node::willRemove();
}
@@ -468,6 +476,8 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* ol
if (oldChild->attached())
oldChild->detach();
+ Node* previousNode = oldChild->traversePreviousNodeFastPath();
+
if (nextChild)
nextChild->setPreviousSibling(previousChild);
if (previousChild)
@@ -480,6 +490,10 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* ol
oldChild->setPreviousSibling(0);
oldChild->setNextSibling(0);
oldChild->setParent(0);
+ oldChild->setPreviousNode(0);
+ oldChild->lastDescendantNode(true)->setNextNode(0);
+ if (previousNode)
+ previousNode->updateNextNode();
allowEventDispatch();
}
@@ -530,6 +544,8 @@ void ContainerNode::removeChildren()
n->setPreviousSibling(0);
n->setNextSibling(0);
n->setParent(0);
+ n->lastDescendantNode(true)->setNextNode(0);
+ n->setPreviousNode(0);
m_firstChild = next;
if (n == m_lastChild)
@@ -552,6 +568,7 @@ void ContainerNode::removeChildren()
removedChild->detach();
}
+ updateNextNode();
allowEventDispatch();
// Dispatch a single post-removal mutation event denoting a modified subtree.
@@ -621,6 +638,8 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
} else
m_firstChild = child;
m_lastChild = child;
+ child->updatePreviousNode();
+ child->lastDescendantNode(true)->updateNextNode();
allowEventDispatch();
// Send notification about the children change.
@@ -658,6 +677,10 @@ void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
Node* last = m_lastChild;
// FIXME: This method should take a PassRefPtr.
appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
+ if (last)
+ last->updateNextNode();
+ newChild->updatePreviousNode();
+ newChild->lastDescendantNode(true)->updateNextNode();
allowEventDispatch();
// FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
@@ -1070,8 +1093,12 @@ static void dispatchChildInsertionEvents(Node* child)
// dispatch the DOMNodeInsertedIntoDocument event to all descendants
if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
- for (; c; c = c->traverseNextNode(child))
+ Node* last = child->lastDescendantNode(true);
+ for (; c; c = c->traverseNextNodeFastPath()) {
c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
+ if (last == c)
+ break;
+ }
}
}
@@ -1092,8 +1119,12 @@ static void dispatchChildRemovalEvents(Node* child)
// dispatch the DOMNodeRemovedFromDocument event to all descendants
if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
- for (; c; c = c->traverseNextNode(child))
+ Node* last = c->lastDescendantNode(true);
+ for (; c; c = c->traverseNextNodeFastPath()) {
c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
+ if (last == c)
+ break;
+ }
}
}
diff --git a/Source/WebCore/dom/ContainerNode.h b/Source/WebCore/dom/ContainerNode.h
index 76eb1bd..ee8252e 100644
--- a/Source/WebCore/dom/ContainerNode.h
+++ b/Source/WebCore/dom/ContainerNode.h
@@ -170,6 +170,17 @@ inline Node* Node::lastChild() const
return toContainerNode(this)->lastChild();
}
+inline RenderObject* Node::previousRenderer()
+{
+ // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
+ // however, when I tried adding it, several tests failed.
+ for (Node* n = previousSibling(); n; n = n->previousSibling()) {
+ if (n->renderer())
+ return n->renderer();
+ }
+ return 0;
+}
+
} // namespace WebCore
#endif // ContainerNode_h
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 063b8a2..f319cac 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -7,6 +7,9 @@
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008, 2009 Google Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (c) 2011, 2012 The Linux Foundation All rights reserved
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communcations AB
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -107,6 +110,7 @@
#include "NestingLevelIncrementer.h"
#include "NodeFilter.h"
#include "NodeIterator.h"
+#include "NodeRareData.h"
#include "NodeWithIndex.h"
#include "OverflowEvent.h"
#include "Page.h"
@@ -421,9 +425,13 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_sawElementsInKnownNamespaces(false)
, m_usingGeolocation(false)
, m_eventQueue(EventQueue::create(this))
+ , m_documentRareData(0)
#if ENABLE(WML)
, m_containsWMLContent(false)
#endif
+#if ENABLE(WEBGL) && PLATFORM(ANDROID)
+ , m_containsWebGLContent(false)
+#endif
, m_weakReference(DocumentWeakReference::create(this))
, m_idAttributeName(idAttr)
#if ENABLE(FULLSCREEN_API)
@@ -567,6 +575,13 @@ Document::~Document()
if (m_implementation)
m_implementation->ownerDocumentDestroyed();
+
+ if (hasRareData()) {
+ ASSERT(m_documentRareData);
+ delete m_documentRareData;
+ m_documentRareData = 0;
+ clearFlag(HasRareDataFlag);
+ }
}
void Document::removedLastRef()
@@ -1810,7 +1825,7 @@ void Document::removeAllEventListeners()
if (DOMWindow* domWindow = this->domWindow())
domWindow->removeAllEventListeners();
- for (Node* node = firstChild(); node; node = node->traverseNextNode())
+ for (Node* node = firstChild(); node; node = node->traverseNextNodeFastPath())
node->removeAllEventListeners();
}
@@ -3842,11 +3857,12 @@ static inline bool isValidNameASCII(const UChar* characters, unsigned length)
bool Document::isValidName(const String& name)
{
- unsigned length = name.length();
- if (!length)
+ if (name.isEmpty())
return false;
- const UChar* characters = name.characters();
+ StringImpl* impl = name.impl();
+ const UChar* characters = impl->characters();
+ unsigned length = impl->length();
return isValidNameASCII(characters, length) || isValidNameNonASCII(characters, length);
}
@@ -5026,15 +5042,15 @@ void Document::loadEventDelayTimerFired(Timer<Document>*)
}
#if ENABLE(REQUEST_ANIMATION_FRAME)
-int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback, Element* animationElement)
+int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback)
{
if (!m_scriptedAnimationController)
m_scriptedAnimationController = ScriptedAnimationController::create(this);
- return m_scriptedAnimationController->registerCallback(callback, animationElement);
+ return m_scriptedAnimationController->registerCallback(callback);
}
-void Document::webkitCancelRequestAnimationFrame(int id)
+void Document::webkitCancelAnimationFrame(int id)
{
if (!m_scriptedAnimationController)
return;
@@ -5082,4 +5098,29 @@ DocumentLoader* Document::loader() const
return loader;
}
+#if ENABLE(WEBGL) && PLATFORM(ANDROID)
+void Document::suspendDocument()
+{
+ HashSet<Element*>::iterator end = m_documentSuspendCallbackElements.end();
+ for (HashSet<Element*>::iterator i = m_documentSuspendCallbackElements.begin(); i != end; ++i)
+ (*i)->documentWasSuspended();
+}
+
+void Document::resumeDocument()
+{
+ HashSet<Element*>::iterator end = m_documentSuspendCallbackElements.end();
+ for (HashSet<Element*>::iterator i = m_documentSuspendCallbackElements.begin(); i != end; ++i)
+ (*i)->documentWillResume();
+}
+
+void Document::registerForDocumentSuspendCallbacks(Element* e)
+{
+ m_documentSuspendCallbackElements.add(e);
+}
+
+void Document::unregisterForDocumentSuspendCallbacks(Element* e)
+{
+ m_documentSuspendCallbackElements.remove(e);
+}
+#endif
} // namespace WebCore
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index c4ccb9c..a51861b 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -6,6 +6,9 @@
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (c) 2011, 2012 The Linux Foundation All rights reserved
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communcations AB
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -101,6 +104,7 @@ class MediaQueryMatcher;
class MouseEventWithHitTestResults;
class NodeFilter;
class NodeIterator;
+class NodeRareData;
class Page;
class PlatformMouseEvent;
class ProcessingInstruction;
@@ -1035,6 +1039,15 @@ public:
void initializeWMLPageState();
#endif
+#if ENABLE(WEBGL) && PLATFORM(ANDROID)
+ void setContainsWebGLContent(bool value) { m_containsWebGLContent = value; }
+ bool containsWebGLContent() const { return m_containsWebGLContent; }
+ void suspendDocument();
+ void resumeDocument();
+ void registerForDocumentSuspendCallbacks(Element*);
+ void unregisterForDocumentSuspendCallbacks(Element*);
+#endif
+
bool containsValidityStyleRules() const { return m_containsValidityStyleRules; }
void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }
@@ -1085,8 +1098,8 @@ public:
const DocumentTiming* timing() const { return &m_documentTiming; }
#if ENABLE(REQUEST_ANIMATION_FRAME)
- int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>, Element*);
- void webkitCancelRequestAnimationFrame(int id);
+ int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>);
+ void webkitCancelAnimationFrame(int id);
void serviceScriptedAnimations(DOMTimeStamp);
#endif
@@ -1097,12 +1110,14 @@ public:
ContentSecurityPolicy* contentSecurityPolicy() { return m_contentSecurityPolicy.get(); }
+ NodeRareData* documentRareData() const { return m_documentRareData; };
+ void setDocumentRareData(NodeRareData* rareData) { m_documentRareData = rareData; }
+
protected:
Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
void clearXMLVersion() { m_xmlVersion = String(); }
-
private:
friend class IgnoreDestructiveWriteCountIncrementer;
@@ -1364,10 +1379,17 @@ private:
RefPtr<EventQueue> m_eventQueue;
+ NodeRareData* m_documentRareData;
+
#if ENABLE(WML)
bool m_containsWMLContent;
#endif
+#if ENABLE(WEBGL) && PLATFORM(ANDROID)
+ bool m_containsWebGLContent;
+ HashSet<Element*> m_documentSuspendCallbackElements;
+#endif
+
RefPtr<DocumentWeakReference> m_weakReference;
HashSet<MediaCanStartListener*> m_mediaCanStartListeners;
@@ -1412,8 +1434,13 @@ inline Node::Node(Document* document, ConstructionType type)
: m_document(document)
, m_previous(0)
, m_next(0)
+#ifdef __ARM_USE_PLD
+ , m_prefetch(0)
+#endif
, m_renderer(0)
, m_nodeFlags(type)
+ , m_previousNode(0)
+ , m_nextNode(0)
{
if (m_document)
m_document->guardRef();
diff --git a/Source/WebCore/dom/DocumentOrderedMap.cpp b/Source/WebCore/dom/DocumentOrderedMap.cpp
index 47268c4..73a0843 100644
--- a/Source/WebCore/dom/DocumentOrderedMap.cpp
+++ b/Source/WebCore/dom/DocumentOrderedMap.cpp
@@ -117,7 +117,7 @@ inline Element* DocumentOrderedMap::get(AtomicStringImpl* key, const TreeScope*
if (m_duplicateCounts.contains(key)) {
// We know there's at least one node that matches; iterate to find the first one.
- for (Node* node = scope->firstChild(); node; node = node->traverseNextNode()) {
+ for (Node* node = scope->firstChild(); node; node = node->traverseNextNodeFastPath()) {
if (!node->isElementNode())
continue;
element = static_cast<Element*>(node);
diff --git a/Source/WebCore/dom/DynamicNodeList.cpp b/Source/WebCore/dom/DynamicNodeList.cpp
index 23664e8..bba1678 100644
--- a/Source/WebCore/dom/DynamicNodeList.cpp
+++ b/Source/WebCore/dom/DynamicNodeList.cpp
@@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -56,8 +57,18 @@ unsigned DynamicNodeList::length() const
unsigned length = 0;
- for (Node* n = m_rootNode->firstChild(); n; n = n->traverseNextNode(m_rootNode.get()))
- length += n->isElementNode() && nodeMatches(static_cast<Element*>(n));
+ Node* lastNode = m_rootNode->lastDescendantNode();
+ Vector<Node* >& cachedNodes = m_caches->cachedNodes;
+ for (Node* n = m_rootNode->firstChild(); n; n = n->traverseNextNodeFastPath()) {
+ if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) {
+ if (length >= cachedNodes.size())
+ cachedNodes.resize(length + 1);
+ cachedNodes.data()[length] = n;
+ length ++;
+ }
+ if (n == lastNode)
+ break;
+ }
m_caches->cachedLength = length;
m_caches->isLengthCacheValid = true;
@@ -68,7 +79,9 @@ unsigned DynamicNodeList::length() const
Node* DynamicNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
{
ASSERT(remainingOffset >= 0);
- for (Node* n = start; n; n = n->traverseNextNode(m_rootNode.get())) {
+ if (!m_caches->lastDecendantOfRoot)
+ m_caches->lastDecendantOfRoot = m_rootNode->lastDescendantNode();
+ for (Node* n = start; n; n = n->traverseNextNodeFastPath()) {
if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) {
if (!remainingOffset) {
m_caches->lastItem = n;
@@ -78,6 +91,8 @@ Node* DynamicNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int
}
--remainingOffset;
}
+ if (n == m_caches->lastDecendantOfRoot)
+ break;
}
return 0; // no matching node in this subtree
@@ -103,6 +118,14 @@ Node* DynamicNodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, in
Node* DynamicNodeList::item(unsigned offset) const
{
+ Node* result;
+ Vector<Node* >& cachedNodes = m_caches->cachedNodes;
+ if (offset < cachedNodes.size()) {
+ result = cachedNodes[offset];
+ if (result)
+ return result;
+ }
+
int remainingOffset = offset;
Node* start = m_rootNode->firstChild();
if (m_caches->isItemCacheValid) {
@@ -115,8 +138,16 @@ Node* DynamicNodeList::item(unsigned offset) const
}
if (remainingOffset < 0)
- return itemBackwardsFromCurrent(start, offset, remainingOffset);
- return itemForwardsFromCurrent(start, offset, remainingOffset);
+ result = itemBackwardsFromCurrent(start, offset, remainingOffset);
+ else
+ result = itemForwardsFromCurrent(start, offset, remainingOffset);
+
+ if (result) {
+ if (offset >= cachedNodes.size())
+ cachedNodes.resize(offset + 1);
+ cachedNodes.data()[offset] = result;
+ }
+ return result;
}
Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const
@@ -159,6 +190,7 @@ void DynamicNodeList::invalidateCache()
DynamicNodeList::Caches::Caches()
: lastItem(0)
+ , lastDecendantOfRoot(0)
, isLengthCacheValid(false)
, isItemCacheValid(false)
{
@@ -172,8 +204,10 @@ PassRefPtr<DynamicNodeList::Caches> DynamicNodeList::Caches::create()
void DynamicNodeList::Caches::reset()
{
lastItem = 0;
+ lastDecendantOfRoot = 0;
isLengthCacheValid = false;
- isItemCacheValid = false;
+ isItemCacheValid = false;
+ cachedNodes.clear();
}
} // namespace WebCore
diff --git a/Source/WebCore/dom/DynamicNodeList.h b/Source/WebCore/dom/DynamicNodeList.h
index 9c8f3cc..c8b6ca2 100644
--- a/Source/WebCore/dom/DynamicNodeList.h
+++ b/Source/WebCore/dom/DynamicNodeList.h
@@ -28,6 +28,12 @@
#include <wtf/RefCounted.h>
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WTF {
+ // Properties in Vector can be initialized with memset and moved using memcpy.
+ template<> struct VectorTraits<WebCore::Node*> : SimpleClassVectorTraits { };
+}
namespace WebCore {
@@ -42,9 +48,11 @@ namespace WebCore {
unsigned cachedLength;
Node* lastItem;
+ Node* lastDecendantOfRoot;
unsigned lastItemOffset;
bool isLengthCacheValid : 1;
bool isItemCacheValid : 1;
+ Vector<Node* > cachedNodes;
protected:
Caches();
};
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index 5fb6cdc..4b9de49 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -622,7 +622,7 @@ static inline bool shouldIgnoreAttributeCase(const Element* e)
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
}
-const AtomicString& Element::getAttribute(const String& name) const
+const AtomicString& Element::getAttribute(const AtomicString& name) const
{
bool ignoreCase = shouldIgnoreAttributeCase(this);
@@ -645,7 +645,7 @@ const AtomicString& Element::getAttribute(const String& name) const
return nullAtom;
}
-const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const
+const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
}
@@ -1471,11 +1471,11 @@ void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
setAttribute(qName, value, ec);
}
-void Element::removeAttribute(const String& name, ExceptionCode& ec)
+void Element::removeAttribute(const AtomicString& name, ExceptionCode& ec)
{
InspectorInstrumentation::willModifyDOMAttr(document(), this);
- String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
+ AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
if (m_attributeMap) {
m_attributeMap->removeNamedItem(localName, ec);
@@ -1486,21 +1486,21 @@ void Element::removeAttribute(const String& name, ExceptionCode& ec)
InspectorInstrumentation::didModifyDOMAttr(document(), this);
}
-void Element::removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
+void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionCode& ec)
{
removeAttribute(QualifiedName(nullAtom, localName, namespaceURI), ec);
}
-PassRefPtr<Attr> Element::getAttributeNode(const String& name)
+PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& name)
{
NamedNodeMap* attrs = attributes(true);
if (!attrs)
return 0;
- String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
+ AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
}
-PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
+PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
{
NamedNodeMap* attrs = attributes(true);
if (!attrs)
@@ -1508,7 +1508,7 @@ PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const S
return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
}
-bool Element::hasAttribute(const String& name) const
+bool Element::hasAttribute(const AtomicString& name) const
{
NamedNodeMap* attrs = attributes(true);
if (!attrs)
@@ -1516,11 +1516,11 @@ bool Element::hasAttribute(const String& name) const
// This call to String::lower() seems to be required but
// there may be a way to remove it.
- String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
+ AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
return attrs->getAttributeItem(localName, false);
}
-bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
+bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
NamedNodeMap* attrs = attributes(true);
if (!attrs)
diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h
index d269dbe..79815dd 100644
--- a/Source/WebCore/dom/Element.h
+++ b/Source/WebCore/dom/Element.h
@@ -4,6 +4,8 @@
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -126,11 +128,11 @@ public:
bool hasAttributes() const;
- bool hasAttribute(const String& name) const;
- bool hasAttributeNS(const String& namespaceURI, const String& localName) const;
+ bool hasAttribute(const AtomicString& name) const;
+ bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
- const AtomicString& getAttribute(const String& name) const;
- const AtomicString& getAttributeNS(const String& namespaceURI, const String& localName) const;
+ const AtomicString& getAttribute(const AtomicString& name) const;
+ const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
void setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode&, FragmentScriptingPermission = FragmentScriptingAllowed);
@@ -174,11 +176,11 @@ public:
// Returns the absolute bounding box translated into screen coordinates:
IntRect screenRect() const;
- void removeAttribute(const String& name, ExceptionCode&);
- void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
+ void removeAttribute(const AtomicString& name, ExceptionCode&);
+ void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionCode&);
- PassRefPtr<Attr> getAttributeNode(const String& name);
- PassRefPtr<Attr> getAttributeNodeNS(const String& namespaceURI, const String& localName);
+ PassRefPtr<Attr> getAttributeNode(const AtomicString& name);
+ PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&);
PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&);
PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&);
@@ -351,6 +353,11 @@ public:
PassRefPtr<WebKitAnimationList> webkitGetAnimations() const;
+#if ENABLE(WEBGL) && PLATFORM(ANDROID)
+ virtual void documentWasSuspended() {}
+ virtual void documentWillResume() {}
+#endif
+
protected:
Element(const QualifiedName& tagName, Document* document, ConstructionType type)
: ContainerNode(document, type)
diff --git a/Source/WebCore/dom/NamedNodeMap.cpp b/Source/WebCore/dom/NamedNodeMap.cpp
index 6fa30bf..253bc53 100644
--- a/Source/WebCore/dom/NamedNodeMap.cpp
+++ b/Source/WebCore/dom/NamedNodeMap.cpp
@@ -54,7 +54,7 @@ NamedNodeMap::~NamedNodeMap()
detachAttributesFromElement();
}
-PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const
+PassRefPtr<Node> NamedNodeMap::getNamedItem(const AtomicString& name) const
{
Attribute* a = getAttributeItem(name, shouldIgnoreAttributeCase(m_element));
if (!a)
@@ -63,12 +63,12 @@ PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const
return a->createAttrIfNeeded(m_element);
}
-PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const String& namespaceURI, const String& localName) const
+PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
return getNamedItem(QualifiedName(nullAtom, localName, namespaceURI));
}
-PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode& ec)
+PassRefPtr<Node> NamedNodeMap::removeNamedItem(const AtomicString& name, ExceptionCode& ec)
{
Attribute* a = getAttributeItem(name, shouldIgnoreAttributeCase(m_element));
if (!a) {
@@ -79,7 +79,7 @@ PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode
return removeNamedItem(a->name(), ec);
}
-PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
+PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionCode& ec)
{
return removeNamedItem(QualifiedName(nullAtom, localName, namespaceURI), ec);
}
@@ -171,7 +171,7 @@ void NamedNodeMap::copyAttributesToVector(Vector<RefPtr<Attribute> >& copy)
copy = m_attributes;
}
-Attribute* NamedNodeMap::getAttributeItemSlowCase(const String& name, bool shouldIgnoreAttributeCase) const
+Attribute* NamedNodeMap::getAttributeItemSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
unsigned len = length();
diff --git a/Source/WebCore/dom/NamedNodeMap.h b/Source/WebCore/dom/NamedNodeMap.h
index c3c2cd9..f4aedb0 100644
--- a/Source/WebCore/dom/NamedNodeMap.h
+++ b/Source/WebCore/dom/NamedNodeMap.h
@@ -46,11 +46,11 @@ public:
// Public DOM interface.
- PassRefPtr<Node> getNamedItem(const String& name) const;
- PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
+ PassRefPtr<Node> getNamedItem(const AtomicString& name) const;
+ PassRefPtr<Node> removeNamedItem(const AtomicString& name, ExceptionCode&);
- PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
- PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
+ PassRefPtr<Node> getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
+ PassRefPtr<Node> removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionCode&);
PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
@@ -111,8 +111,8 @@ private:
void detachAttributesFromElement();
void detachFromElement();
- Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
- Attribute* getAttributeItemSlowCase(const String& name, bool shouldIgnoreAttributeCase) const;
+ Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ Attribute* getAttributeItemSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
void clearAttributes();
int declCount() const;
@@ -135,7 +135,7 @@ inline Attribute* NamedNodeMap::getAttributeItem(const QualifiedName& name) cons
// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
-inline Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
+inline Attribute* NamedNodeMap::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
unsigned len = length();
bool doSlowCheck = shouldIgnoreAttributeCase;
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index da4312c..facb694 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -5,6 +5,7 @@
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -130,6 +131,8 @@ namespace WebCore {
using namespace HTMLNames;
+const int Node::cPrefetchTargetDepth = 7;
+
bool Node::isSupported(const String& feature, const String& version)
{
return DOMImplementation::hasFeature(feature, version);
@@ -391,7 +394,7 @@ Node::~Node()
else {
if (m_document && rareData()->nodeLists())
m_document->removeNodeListCache();
-
+
NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();
NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);
ASSERT(it != dataMap.end());
@@ -409,6 +412,8 @@ Node::~Node()
m_previous->setNextSibling(0);
if (m_next)
m_next->setPreviousSibling(0);
+ m_nextNode = 0;
+ m_previousNode = 0;
if (m_document)
m_document->guardDeref();
@@ -517,16 +522,21 @@ void Node::setTreeScopeRecursively(TreeScope* newTreeScope)
if (currentDocument && currentDocument != newDocument)
currentDocument->incDOMTreeVersion();
- for (Node* node = this; node; node = node->traverseNextNode(this)) {
+ Node* last = this->lastDescendantNode(true);
+ for (Node* node = this; node; node = node->traverseNextNodeFastPath()) {
node->setTreeScope(newTreeScope);
// FIXME: Once shadow scopes are landed, update parent scope, etc.
+ if (last == node)
+ break;
}
}
NodeRareData* Node::rareData() const
{
ASSERT(hasRareData());
- return NodeRareData::rareDataFromMap(this);
+ NodeRareData* data = isDocumentNode() ? static_cast<const Document*>(this)->documentRareData() : NodeRareData::rareDataFromMap(this);
+ ASSERT(data);
+ return data;
}
NodeRareData* Node::ensureRareData()
@@ -534,9 +544,15 @@ NodeRareData* Node::ensureRareData()
if (hasRareData())
return rareData();
- ASSERT(!NodeRareData::rareDataMap().contains(this));
NodeRareData* data = createRareData();
- NodeRareData::rareDataMap().set(this, data);
+ if (isDocumentNode()) {
+ // Fast path for a Document. A Document knows a pointer to NodeRareData.
+ ASSERT(!static_cast<Document*>(this)->documentRareData());
+ static_cast<Document*>(this)->setDocumentRareData(data);
+ } else {
+ ASSERT(!NodeRareData::rareDataMap().contains(this));
+ NodeRareData::rareDataMap().set(this, data);
+ }
setFlag(HasRareDataFlag);
return data;
}
@@ -548,18 +564,22 @@ NodeRareData* Node::createRareData()
Element* Node::shadowHost() const
{
- return toElement(getFlag(IsShadowRootFlag) ? parent() : 0);
+ return toElement(isShadowRoot() ? parent() : 0);
}
void Node::setShadowHost(Element* host)
{
ASSERT(!parentNode() && !isSVGShadowRoot());
if (host)
- setFlag(IsShadowRootFlag);
+ setFlag(IsShadowRootOrSVGShadowRootFlag);
else
- clearFlag(IsShadowRootFlag);
+ clearFlag(IsShadowRootOrSVGShadowRootFlag);
setParent(host);
+ updatePreviousNode();
+ lastDescendantNode(true)->updateNextNode();
+ if (host)
+ host->updateNextNode();
}
InputElement* Node::toInputElement()
@@ -607,14 +627,9 @@ void Node::setNodeValue(const String& /*nodeValue*/, ExceptionCode& ec)
PassRefPtr<NodeList> Node::childNodes()
{
- NodeRareData* data = ensureRareData();
- if (!data->nodeLists()) {
- data->setNodeLists(NodeListsNodeData::create());
- if (document())
- document()->addNodeListCache();
- }
+ NodeListsNodeData* data = ensureRareData()->ensureNodeLists(this);
- return ChildNodeList::create(this, data->nodeLists()->m_childNodeListCaches.get());
+ return ChildNodeList::create(this, data->m_childNodeListCaches.get());
}
Node *Node::lastDescendant() const
@@ -862,12 +877,15 @@ void Node::setDocumentRecursively(Document* newDocument)
{
ASSERT(document() != newDocument);
- for (Node* node = this; node; node = node->traverseNextNode(this)) {
+ Node* last = this->lastDescendantNode(true);
+ for (Node* node = this; node; node = node->traverseNextNodeFastPath()) {
node->setDocument(newDocument);
- if (!node->isElementNode())
- continue;
- if (Node* shadow = shadowRoot(node))
- shadow->setDocumentRecursively(newDocument);
+ if (node->isElementNode()) {
+ if (Node* shadow = shadowRoot(node))
+ shadow->setDocumentRecursively(newDocument);
+ }
+ if (node == last)
+ break;
}
}
@@ -911,12 +929,15 @@ void Node::setNeedsStyleRecalc(StyleChangeType changeType)
void Node::lazyAttach(ShouldSetAttached shouldSetAttached)
{
- for (Node* n = this; n; n = n->traverseNextNode(this)) {
+ Node* last = this->lastDescendantNode(true);
+ for (Node* n = this; n; n = n->traverseNextNodeFastPath()) {
if (n->firstChild())
n->setChildNeedsStyleRecalc();
n->setStyleChange(FullStyleChange);
if (shouldSetAttached == SetAttached)
n->setAttached();
+ if (n == last)
+ break;
}
markAncestorsWithChildNeedsStyleRecalc();
}
@@ -1092,7 +1113,7 @@ void Node::removeCachedNameNodeList(NameNodeList* list, const String& nodeName)
data->m_nameNodeListCache.remove(nodeName);
}
-void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)
+void Node::removeCachedTagNodeList(TagNodeList* list, const AtomicString& name)
{
ASSERT(rareData());
ASSERT(rareData()->nodeLists());
@@ -1103,6 +1124,17 @@ void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)
data->m_tagNodeListCache.remove(name.impl());
}
+void Node::removeCachedTagNodeListNS(TagNodeListNS* list, const QualifiedName& name)
+{
+ ASSERT(rareData());
+ ASSERT(rareData()->nodeLists());
+ ASSERT_UNUSED(list, list->hasOwnCaches());
+
+ NodeListsNodeData* data = rareData()->nodeLists();
+ ASSERT_UNUSED(list, list == data->m_tagNodeListCacheNS.get(name.impl()));
+ data->m_tagNodeListCacheNS.remove(name.impl());
+}
+
void Node::removeCachedLabelsNodeList(DynamicNodeList* list)
{
ASSERT(rareData());
@@ -1115,12 +1147,15 @@ void Node::removeCachedLabelsNodeList(DynamicNodeList* list)
Node* Node::traverseNextNode(const Node* stayWithin) const
{
- if (firstChild())
- return firstChild();
+ prefetchTarget();
+ Node* fc = firstChild();
+ if (fc)
+ return fc;
if (this == stayWithin)
return 0;
- if (nextSibling())
- return nextSibling();
+ Node* ns = nextSibling();
+ if (ns)
+ return ns;
const Node *n = this;
while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
@@ -1129,15 +1164,54 @@ Node* Node::traverseNextNode(const Node* stayWithin) const
return 0;
}
+Node* Node::lastDescendantNode(bool includeThis) const
+{
+ Node* n = lastChild();
+ if (!n && includeThis)
+ return const_cast<Node*>(this);
+
+ Node* p = n;
+ while(n) {
+ p = n;
+ n = n->lastChild();
+ }
+ return p;
+}
+
+void Node::updatePrevNextNodesInSubtree()
+{
+ Node* n = firstChild();
+ Node* next;
+ while(n) {
+ next = n->traverseNextNode(this);
+ if (next) {
+ n->setNextNode(next);
+ next->setPreviousNode(n);
+ } else {
+ next = n->traverseNextNode();
+ n->setNextNode(next);
+ if (next)
+ next->setPreviousNode(n);
+ break;
+ }
+ n = next;
+ }
+ updateNextNode();
+}
+
Node* Node::traverseNextSibling(const Node* stayWithin) const
{
if (this == stayWithin)
return 0;
- if (nextSibling())
- return nextSibling();
+ prefetchTarget();
+ Node* ns = nextSibling();
+ if (ns)
+ return ns;
const Node *n = this;
- while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
+ while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin)) {
+ n->prefetchTarget();
n = n->parentNode();
+ }
if (n)
return n->nextSibling();
return 0;
@@ -1157,10 +1231,11 @@ Node* Node::traversePreviousNode(const Node* stayWithin) const
{
if (this == stayWithin)
return 0;
- if (previousSibling()) {
- Node *n = previousSibling();
- while (n->lastChild())
- n = n->lastChild();
+ Node *n = previousSibling();
+ if (n) {
+ Node* lastChild;
+ while ((lastChild = n->lastChild()))
+ n = lastChild;
return n;
}
return parentNode();
@@ -1168,12 +1243,12 @@ Node* Node::traversePreviousNode(const Node* stayWithin) const
Node* Node::traversePreviousNodePostOrder(const Node* stayWithin) const
{
- if (lastChild())
- return lastChild();
+ if (Node* lc = lastChild())
+ return lc;
if (this == stayWithin)
return 0;
- if (previousSibling())
- return previousSibling();
+ if (Node* ps = previousSibling())
+ return ps;
const Node *n = this;
while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
@@ -1186,8 +1261,8 @@ Node* Node::traversePreviousSiblingPostOrder(const Node* stayWithin) const
{
if (this == stayWithin)
return 0;
- if (previousSibling())
- return previousSibling();
+ if (Node* ps = previousSibling())
+ return ps;
const Node *n = this;
while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
@@ -1333,14 +1408,20 @@ void Node::attach()
// FIXME: This is O(N^2) for the innerHTML case, where all children are replaced at once (and not attached).
// If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the
// result of Text::rendererIsNeeded() for those nodes.
- if (renderer()) {
+ RenderObject* renderer = this->renderer();
+ if (renderer) {
for (Node* next = nextSibling(); next; next = next->nextSibling()) {
if (next->renderer())
break;
if (!next->attached())
break; // Assume this means none of the following siblings are attached.
- if (next->isTextNode())
+ if (next->isTextNode()) {
+ static_cast<Text*>(next)->setPreviousRenderer(renderer);
next->createRendererIfNeeded();
+ if (next->renderer())
+ renderer = next->renderer();
+ static_cast<Text*>(next)->setPreviousRenderer(0);
+ }
}
}
@@ -1366,23 +1447,7 @@ void Node::detach()
if (inActiveChain())
doc->activeChainNodeDetached(this);
- clearFlag(IsActiveFlag);
- clearFlag(IsHoveredFlag);
- clearFlag(InActiveChainFlag);
- clearFlag(IsAttachedFlag);
-
- clearFlag(InDetachFlag);
-}
-
-RenderObject* Node::previousRenderer()
-{
- // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
- // however, when I tried adding it, several tests failed.
- for (Node* n = previousSibling(); n; n = n->previousSibling()) {
- if (n->renderer())
- return n->renderer();
- }
- return 0;
+ clearFlag(NodeDetachClearFlags);
}
RenderObject* Node::nextRenderer()
@@ -1697,44 +1762,45 @@ bool Node::inSameContainingBlockFlowElement(Node *n)
PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& name)
{
- return getElementsByTagNameNS(starAtom, name);
+ if (name.isNull())
+ return 0;
+
+ NodeListsNodeData* data = ensureRareData()->ensureNodeLists(this);
+
+ AtomicString localNameAtom = document()->isHTMLDocument() ? name.lower() : name;
+
+ pair<NodeListsNodeData::TagNodeListCache::iterator, bool> result = data->m_tagNodeListCache.add(localNameAtom.impl(), 0);
+ if (!result.second)
+ return PassRefPtr<TagNodeList>(result.first->second);
+
+ RefPtr<TagNodeList> list = TagNodeList::create(this, localNameAtom);
+ result.first->second = list.get();
+ return list.release();
}
PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
{
if (localName.isNull())
return 0;
-
- NodeRareData* data = ensureRareData();
- if (!data->nodeLists()) {
- data->setNodeLists(NodeListsNodeData::create());
- document()->addNodeListCache();
- }
- String name = localName;
- if (document()->isHTMLDocument())
- name = localName.lower();
-
- AtomicString localNameAtom = name;
-
- pair<NodeListsNodeData::TagNodeListCache::iterator, bool> result = data->nodeLists()->m_tagNodeListCache.add(QualifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0);
+ NodeListsNodeData* data = ensureRareData()->ensureNodeLists(this);
+
+ AtomicString localNameAtom = document()->isHTMLDocument() ? localName.lower() : localName;
+
+ pair<NodeListsNodeData::TagNodeListCacheNS::iterator, bool> result = data->m_tagNodeListCacheNS.add(QualifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0);
if (!result.second)
- return PassRefPtr<TagNodeList>(result.first->second);
-
- RefPtr<TagNodeList> list = TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom);
+ return PassRefPtr<TagNodeListNS>(result.first->second);
+
+ RefPtr<TagNodeListNS> list = TagNodeListNS::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom);
result.first->second = list.get();
return list.release();
}
PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
{
- NodeRareData* data = ensureRareData();
- if (!data->nodeLists()) {
- data->setNodeLists(NodeListsNodeData::create());
- document()->addNodeListCache();
- }
+ NodeListsNodeData* data = ensureRareData()->ensureNodeLists(this);
- pair<NodeListsNodeData::NameNodeListCache::iterator, bool> result = data->nodeLists()->m_nameNodeListCache.add(elementName, 0);
+ pair<NodeListsNodeData::NameNodeListCache::iterator, bool> result = data->m_nameNodeListCache.add(elementName, 0);
if (!result.second)
return PassRefPtr<NodeList>(result.first->second);
@@ -1745,13 +1811,9 @@ PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
{
- NodeRareData* data = ensureRareData();
- if (!data->nodeLists()) {
- data->setNodeLists(NodeListsNodeData::create());
- document()->addNodeListCache();
- }
+ NodeListsNodeData* data = ensureRareData()->ensureNodeLists(this);
- pair<NodeListsNodeData::ClassNodeListCache::iterator, bool> result = data->nodeLists()->m_classNodeListCache.add(classNames, 0);
+ pair<NodeListsNodeData::ClassNodeListCache::iterator, bool> result = data->m_classNodeListCache.add(classNames, 0);
if (!result.second)
return PassRefPtr<NodeList>(result.first->second);
@@ -1794,7 +1856,8 @@ PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode&
}
// FIXME: We can speed this up by implementing caching similar to the one use by getElementById
- for (Node* n = firstChild(); n; n = n->traverseNextNode(this)) {
+ Node* last = lastDescendantNode();
+ for (Node* n = firstChild(); n; n = n->traverseNextNodeFastPath()) {
if (n->isElementNode()) {
Element* element = static_cast<Element*>(n);
for (CSSSelector* selector = querySelectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
@@ -1802,6 +1865,8 @@ PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode&
return element;
}
}
+ if (n == last)
+ break;
}
return 0;
@@ -2429,6 +2494,9 @@ void NodeListsNodeData::invalidateCaches()
if (m_labelsNodeListCache)
m_labelsNodeListCache->invalidateCache();
+ TagNodeListCacheNS::const_iterator tagCacheEndNS = m_tagNodeListCacheNS.end();
+ for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheEndNS; ++it)
+ it->second->invalidateCache();
TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it)
it->second->invalidateCache();
@@ -2456,6 +2524,12 @@ bool NodeListsNodeData::isEmpty() const
if (m_childNodeListCaches->refCount())
return false;
+ TagNodeListCacheNS::const_iterator tagCacheEndNS = m_tagNodeListCacheNS.end();
+ for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheEndNS; ++it) {
+ if (it->second->refCount())
+ return false;
+ }
+
TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it) {
if (it->second->refCount())
diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h
index 76355c3..d75d064 100644
--- a/Source/WebCore/dom/Node.h
+++ b/Source/WebCore/dom/Node.h
@@ -4,6 +4,7 @@
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -75,6 +76,7 @@ class RenderStyle;
class SVGUseElement;
#endif
class TagNodeList;
+class TagNodeListNS;
class TreeScope;
typedef int ExceptionCode;
@@ -121,6 +123,8 @@ public:
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
};
+ static const int cPrefetchTargetDepth;
+
static bool isSupported(const String& feature, const String& version);
static void startIgnoringLeaks();
@@ -143,8 +147,8 @@ public:
virtual NodeType nodeType() const = 0;
ContainerNode* parentNode() const;
Element* parentElement() const;
- Node* previousSibling() const { return m_previous; }
- Node* nextSibling() const { return m_next; }
+ ALWAYS_INLINE Node* previousSibling() const { return m_previous; }
+ ALWAYS_INLINE Node* nextSibling() const { return m_next; }
PassRefPtr<NodeList> childNodes();
Node* firstChild() const;
Node* lastChild() const;
@@ -187,14 +191,14 @@ public:
// Other methods (not part of DOM)
- bool isElementNode() const { return getFlag(IsElementFlag); }
- bool isContainerNode() const { return getFlag(IsContainerFlag); }
+ ALWAYS_INLINE bool isElementNode() const { return getFlag(IsElementFlag); }
+ ALWAYS_INLINE bool isContainerNode() const { return getFlag(IsContainerFlag); }
bool isTextNode() const { return getFlag(IsTextFlag); }
bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
- bool isSVGElement() const { return getFlag(IsSVGFlag); }
- virtual bool isSVGShadowRoot() const { return false; }
+ ALWAYS_INLINE bool isSVGElement() const { return getFlag(IsSVGFlag); }
+ ALWAYS_INLINE bool isSVGShadowRoot() const { return getFlag(IsShadowRootOrSVGShadowRootFlag) && isSVGElement(); }
#if ENABLE(SVG)
SVGUseElement* svgShadowHost() const;
#endif
@@ -213,7 +217,7 @@ public:
bool isCommentNode() const { return getFlag(IsCommentFlag); }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
- bool isShadowRoot() const { return getFlag(IsShadowRootFlag); }
+ bool isShadowRoot() const { return getFlag(IsShadowRootOrSVGShadowRootFlag) && !isSVGElement(); }
// FIXME: Remove this when all shadow roots are ShadowRoots.
virtual bool isShadowBoundary() const { return false; }
virtual bool canHaveLightChildRendererWithShadow() const { return false; }
@@ -240,7 +244,30 @@ public:
// These low-level calls give the caller responsibility for maintaining the integrity of the tree.
void setPreviousSibling(Node* previous) { m_previous = previous; }
+#ifdef __ARM_USE_PLD
+ ALWAYS_INLINE void updatePrefetchTarget() {
+ if (m_next) {
+ int skew;
+ Node* from = this;
+ Node* n = from->traversePreviousNodePostOrder();
+ for (skew = cPrefetchTargetDepth - 1; skew && n; skew--) {
+ from = n;
+ n = n->traversePreviousNodePostOrder();
+ }
+ from->setPrefetchTarget(m_next);
+ }
+ }
+ void setPrefetchTarget(Node *prefetch) { m_prefetch = prefetch; }
+ void setNextSibling(Node* next) { m_next = next; updatePrefetchTarget(); }
+#else
void setNextSibling(Node* next) { m_next = next; }
+#endif
+ void updatePreviousNode() { m_previousNode = traversePreviousNode(); if (m_previousNode) m_previousNode->setNextNode(this); }
+ void updateNextNode() { m_nextNode = traverseNextNode(); if (m_nextNode) m_nextNode->setPreviousNode(this); }
+ void updatePrevNextNodesInSubtree();
+
+ void setPreviousNode(Node* previous) { m_previousNode = previous; }
+ void setNextNode(Node* next) { m_nextNode = next; }
// FIXME: These two functions belong in editing -- "atomic node" is an editing concept.
Node* previousNodeConsideringAtomicNodes() const;
@@ -314,6 +341,9 @@ public:
void setIsLink() { setFlag(IsLinkFlag); }
void clearIsLink() { clearFlag(IsLinkFlag); }
+ void setIeForbidsInsertHTML() { setFlag(IeForbidsInsertHTML); }
+ bool ieForbidsInsertHTML() const { return getFlag(IeForbidsInsertHTML); }
+
enum ShouldSetAttached {
SetAttached,
DoNotSetAttached
@@ -392,12 +422,27 @@ public:
// This can be used to restrict traversal to a particular sub-tree.
Node* traverseNextNode(const Node* stayWithin = 0) const;
+ Node* traverseNextNodeFastPath() const { prefetchTarget(); return m_nextNode; }
+
+ ALWAYS_INLINE void prefetchTarget() const {
+#ifdef __ARM_USE_PLD
+ if (m_prefetch) {
+ __builtin_prefetch(((char *) m_prefetch));
+ __builtin_prefetch(((char *) m_prefetch) + 64);
+ }
+#endif
+ }
+
+ Node* lastDescendantNode(bool includeThis = false) const;
+
// Like traverseNextNode, but skips children and starts with the next sibling.
Node* traverseNextSibling(const Node* stayWithin = 0) const;
// Does a reverse pre-order traversal to find the node that comes before the current one in document order
Node* traversePreviousNode(const Node* stayWithin = 0) const;
+ Node* traversePreviousNodeFastPath() const { return m_previousNode; }
+
// Like traverseNextNode, but visits parents after their children.
Node* traverseNextNodePostOrder() const;
@@ -515,9 +560,10 @@ public:
void notifyLocalNodeListsLabelChanged();
void removeCachedClassNodeList(ClassNodeList*, const String&);
void removeCachedNameNodeList(NameNodeList*, const String&);
- void removeCachedTagNodeList(TagNodeList*, const QualifiedName&);
+ void removeCachedTagNodeList(TagNodeList*, const AtomicString&);
+ void removeCachedTagNodeListNS(TagNodeListNS*, const QualifiedName&);
void removeCachedLabelsNodeList(DynamicNodeList*);
-
+
PassRefPtr<NodeList> getElementsByTagName(const AtomicString&);
PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
PassRefPtr<NodeList> getElementsByName(const String& elementName);
@@ -593,7 +639,7 @@ private:
InActiveChainFlag = 1 << 15,
InDetachFlag = 1 << 16,
HasRareDataFlag = 1 << 17,
- IsShadowRootFlag = 1 << 18,
+ IsShadowRootOrSVGShadowRootFlag = 1 << 18,
// These bits are used by derived classes, pulled up here so they can
// be stored in the same memory word as the Node bits above.
@@ -605,11 +651,14 @@ private:
IsSynchronizingSVGAttributesFlag = 1 << 23, // SVGElement
HasSVGRareDataFlag = 1 << 24, // SVGElement
#endif
-
StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
SelfOrAncestorHasDirAutoFlag = 1 << 27,
+ IeForbidsInsertHTML = 1 << 28,
+
+ NodeDetachClearFlags = IsActiveFlag | IsHoveredFlag | InActiveChainFlag | IsAttachedFlag | InDetachFlag,
+
#if ENABLE(SVG)
DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag
#else
@@ -619,7 +668,7 @@ private:
// 4 bits remaining
- bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
+ ALWAYS_INLINE bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
@@ -631,9 +680,11 @@ protected:
CreateComment = DefaultNodeFlags | IsCommentFlag,
CreateContainer = DefaultNodeFlags | IsContainerFlag,
CreateElement = CreateContainer | IsElementFlag,
+ CreateShadowRoot = CreateContainer | IsShadowRootOrSVGShadowRootFlag,
CreateStyledElement = CreateElement | IsStyledElementFlag,
CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
CreateSVGElement = CreateStyledElement | IsSVGFlag,
+ CreateSVGShadowRoot = CreateSVGElement | IsShadowRootOrSVGShadowRootFlag,
};
Node(Document*, ConstructionType);
@@ -690,8 +741,13 @@ private:
Document* m_document;
Node* m_previous;
Node* m_next;
+#ifdef __ARM_USE_PLD
+ Node* m_prefetch;
+#endif
RenderObject* m_renderer;
mutable uint32_t m_nodeFlags;
+ Node* m_previousNode;
+ Node* m_nextNode;
protected:
bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
@@ -728,7 +784,7 @@ inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
inline ContainerNode* Node::parentNode() const
{
- return getFlag(IsShadowRootFlag) || isSVGShadowRoot() ? 0 : parent();
+ return getFlag(IsShadowRootOrSVGShadowRootFlag) ? 0 : parent();
}
inline ContainerNode* Node::parentOrHostNode() const
@@ -738,7 +794,7 @@ inline ContainerNode* Node::parentOrHostNode() const
inline ContainerNode* Node::parentNodeGuaranteedHostFree() const
{
- ASSERT(!getFlag(IsShadowRootFlag) && !isSVGShadowRoot());
+ ASSERT(!getFlag(IsShadowRootOrSVGShadowRootFlag));
return parentOrHostNode();
}
diff --git a/Source/WebCore/dom/NodeRareData.h b/Source/WebCore/dom/NodeRareData.h
index ac05d3e..7bbd0c1 100644
--- a/Source/WebCore/dom/NodeRareData.h
+++ b/Source/WebCore/dom/NodeRareData.h
@@ -49,10 +49,13 @@ public:
typedef HashMap<String, NameNodeList*> NameNodeListCache;
NameNodeListCache m_nameNodeListCache;
-
- typedef HashMap<RefPtr<QualifiedName::QualifiedNameImpl>, TagNodeList*> TagNodeListCache;
+
+ typedef HashMap<AtomicStringImpl*, TagNodeList*> TagNodeListCache;
TagNodeListCache m_tagNodeListCache;
+ typedef HashMap<RefPtr<QualifiedName::QualifiedNameImpl>, TagNodeListNS*> TagNodeListCacheNS;
+ TagNodeListCacheNS m_tagNodeListCacheNS;
+
RefPtr<DynamicNodeList> m_labelsNodeListCache;
static PassOwnPtr<NodeListsNodeData> create()
@@ -106,6 +109,15 @@ public:
void clearNodeLists() { m_nodeLists.clear(); }
void setNodeLists(PassOwnPtr<NodeListsNodeData> lists) { m_nodeLists = lists; }
NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
+ NodeListsNodeData* ensureNodeLists(Node* n)
+ {
+ if (!m_nodeLists) {
+ m_nodeLists = NodeListsNodeData::create();
+ if (n->document())
+ n->document()->addNodeListCache();
+ }
+ return m_nodeLists.get();
+ }
short tabIndex() const { return m_tabIndex; }
void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; }
diff --git a/Source/WebCore/dom/ProcessingInstruction.cpp b/Source/WebCore/dom/ProcessingInstruction.cpp
index 30111d8..3feb0ab 100644
--- a/Source/WebCore/dom/ProcessingInstruction.cpp
+++ b/Source/WebCore/dom/ProcessingInstruction.cpp
@@ -161,9 +161,10 @@ void ProcessingInstruction::checkStyleSheet()
m_loading = true;
document()->addPendingSheet();
+ ResourceRequest request(document()->completeURL(href));
#if ENABLE(XSLT)
if (m_isXSL)
- m_cachedSheet = document()->cachedResourceLoader()->requestXSLStyleSheet(url);
+ m_cachedSheet = document()->cachedResourceLoader()->requestXSLStyleSheet(request);
else
#endif
{
@@ -171,7 +172,7 @@ void ProcessingInstruction::checkStyleSheet()
if (charset.isEmpty())
charset = document()->charset();
- m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(url, charset);
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset);
}
if (m_cachedSheet)
m_cachedSheet->addClient(this);
diff --git a/Source/WebCore/dom/RequestAnimationFrameCallback.h b/Source/WebCore/dom/RequestAnimationFrameCallback.h
index 3edeb9e..a867922 100644
--- a/Source/WebCore/dom/RequestAnimationFrameCallback.h
+++ b/Source/WebCore/dom/RequestAnimationFrameCallback.h
@@ -31,8 +31,7 @@
#ifndef RequestAnimationFrameCallback_h
#define RequestAnimationFrameCallback_h
-#include "Element.h"
-#include <wtf/PassRefPtr.h>
+#include "DOMTimeStamp.h"
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -42,7 +41,6 @@ public:
virtual ~RequestAnimationFrameCallback() { }
virtual bool handleEvent(DOMTimeStamp) = 0;
- RefPtr<Element> m_element;
int m_id;
bool m_firedOrCancelled;
};
diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp
index 55a7949..dc075ae 100644
--- a/Source/WebCore/dom/ScriptElement.cpp
+++ b/Source/WebCore/dom/ScriptElement.cpp
@@ -248,7 +248,8 @@ bool ScriptElement::requestScript(const String& sourceUrl)
ASSERT(!m_cachedScript);
// FIXME: If sourceUrl is empty, we should dispatchErrorEvent().
- m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(sourceUrl, scriptCharset());
+ ResourceRequest request(m_element->document()->completeURL(sourceUrl));
+ m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(request, scriptCharset());
m_isExternalScript = true;
if (m_cachedScript)
diff --git a/Source/WebCore/dom/ScriptedAnimationController.cpp b/Source/WebCore/dom/ScriptedAnimationController.cpp
index 0c70359..4fbf6d9 100644
--- a/Source/WebCore/dom/ScriptedAnimationController.cpp
+++ b/Source/WebCore/dom/ScriptedAnimationController.cpp
@@ -29,16 +29,29 @@
#if ENABLE(REQUEST_ANIMATION_FRAME)
#include "Document.h"
-#include "Element.h"
#include "FrameView.h"
#include "RequestAnimationFrameCallback.h"
+#if USE(REQUEST_ANIMATION_FRAME_TIMER)
+#include <algorithm>
+#include <wtf/CurrentTime.h>
+
+using namespace std;
+
+// Allow a little more than 60fps to make sure we can at least hit that frame rate.
+#define MinimumAnimationInterval 0.015
+#endif
+
namespace WebCore {
ScriptedAnimationController::ScriptedAnimationController(Document* document)
: m_document(document)
, m_nextCallbackId(0)
, m_suspendCount(0)
+#if USE(REQUEST_ANIMATION_FRAME_TIMER)
+ , m_animationTimer(this, &ScriptedAnimationController::animationTimerFired)
+ , m_lastAnimationFrameTime(0)
+#endif
{
}
@@ -51,20 +64,17 @@ void ScriptedAnimationController::resume()
{
--m_suspendCount;
if (!m_suspendCount && m_callbacks.size())
- if (FrameView* fv = m_document->view())
- fv->scheduleAnimation();
+ scheduleAnimation();
}
-ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(PassRefPtr<RequestAnimationFrameCallback> callback, Element* animationElement)
+ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCallback(PassRefPtr<RequestAnimationFrameCallback> callback)
{
ScriptedAnimationController::CallbackId id = m_nextCallbackId++;
callback->m_firedOrCancelled = false;
callback->m_id = id;
- callback->m_element = animationElement;
m_callbacks.append(callback);
if (!m_suspendCount)
- if (FrameView* view = m_document->view())
- view->scheduleAnimation();
+ scheduleAnimation();
return id;
}
@@ -83,37 +93,19 @@ void ScriptedAnimationController::serviceScriptedAnimations(DOMTimeStamp time)
{
if (!m_callbacks.size() || m_suspendCount)
return;
- // We want to run the callback for all elements in the document that have registered
- // for a callback and that are visible. Running the callbacks can cause new callbacks
- // to be registered, existing callbacks to be cancelled, and elements to gain or lose
- // visibility so this code has to iterate carefully.
-
- // FIXME: Currently, this code doesn't do any visibility tests beyond checking display:
// First, generate a list of callbacks to consider. Callbacks registered from this point
// on are considered only for the "next" frame, not this one.
CallbackList callbacks(m_callbacks);
- // Firing the callback may cause the visibility of other elements to change. To avoid
- // missing any callbacks, we keep iterating through the list of candiate callbacks and firing
- // them until nothing new becomes visible.
- bool firedCallback;
- do {
- firedCallback = false;
- // A previous iteration may have invalidated style (or layout). Update styles for each iteration
- // for now since all we check is the existence of a renderer.
- m_document->updateStyleIfNeeded();
- for (size_t i = 0; i < callbacks.size(); ++i) {
- RequestAnimationFrameCallback* callback = callbacks[i].get();
- if (!callback->m_firedOrCancelled && (!callback->m_element || callback->m_element->renderer())) {
- callback->m_firedOrCancelled = true;
- callback->handleEvent(time);
- firedCallback = true;
- callbacks.remove(i);
- break;
- }
+ for (size_t i = 0; i < callbacks.size(); ++i) {
+ RequestAnimationFrameCallback* callback = callbacks[i].get();
+ if (!callback->m_firedOrCancelled) {
+ callback->m_firedOrCancelled = true;
+ callback->handleEvent(time);
}
- } while (firedCallback);
+ }
+ m_document->updateStyleIfNeeded();
// Remove any callbacks we fired from the list of pending callbacks.
for (size_t i = 0; i < m_callbacks.size();) {
@@ -124,10 +116,28 @@ void ScriptedAnimationController::serviceScriptedAnimations(DOMTimeStamp time)
}
if (m_callbacks.size())
- if (FrameView* view = m_document->view())
- view->scheduleAnimation();
+ scheduleAnimation();
}
+void ScriptedAnimationController::scheduleAnimation()
+{
+#if USE(REQUEST_ANIMATION_FRAME_TIMER)
+ double scheduleDelay = max<double>(MinimumAnimationInterval - (currentTime() - m_lastAnimationFrameTime), 0);
+ m_animationTimer.startOneShot(scheduleDelay);
+#else
+ if (FrameView* frameView = m_document->view())
+ frameView->scheduleAnimation();
+#endif
+}
+
+#if USE(REQUEST_ANIMATION_FRAME_TIMER)
+void ScriptedAnimationController::animationTimerFired(Timer<ScriptedAnimationController>*)
+{
+ m_lastAnimationFrameTime = currentTime();
+ serviceScriptedAnimations(convertSecondsToDOMTimeStamp(m_lastAnimationFrameTime));
+}
+#endif
+
}
#endif
diff --git a/Source/WebCore/dom/ScriptedAnimationController.h b/Source/WebCore/dom/ScriptedAnimationController.h
index 7141968..f6f06a9 100644
--- a/Source/WebCore/dom/ScriptedAnimationController.h
+++ b/Source/WebCore/dom/ScriptedAnimationController.h
@@ -28,6 +28,9 @@
#if ENABLE(REQUEST_ANIMATION_FRAME)
#include "DOMTimeStamp.h"
+#if USE(REQUEST_ANIMATION_FRAME_TIMER)
+#include "Timer.h"
+#endif
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
@@ -36,7 +39,6 @@
namespace WebCore {
class Document;
-class Element;
class RequestAnimationFrameCallback;
class ScriptedAnimationController {
@@ -49,7 +51,7 @@ public:
typedef int CallbackId;
- CallbackId registerCallback(PassRefPtr<RequestAnimationFrameCallback>, Element*);
+ CallbackId registerCallback(PassRefPtr<RequestAnimationFrameCallback>);
void cancelCallback(CallbackId);
void serviceScriptedAnimations(DOMTimeStamp);
@@ -58,12 +60,21 @@ public:
private:
explicit ScriptedAnimationController(Document*);
+
typedef Vector<RefPtr<RequestAnimationFrameCallback> > CallbackList;
CallbackList m_callbacks;
Document* m_document;
CallbackId m_nextCallbackId;
int m_suspendCount;
+
+ void scheduleAnimation();
+
+#if USE(REQUEST_ANIMATION_FRAME_TIMER)
+ void animationTimerFired(Timer<ScriptedAnimationController>*);
+ Timer<ScriptedAnimationController> m_animationTimer;
+ double m_lastAnimationFrameTime;
+#endif
};
}
diff --git a/Source/WebCore/dom/SelectorNodeList.cpp b/Source/WebCore/dom/SelectorNodeList.cpp
index 7611488..82f1103 100644
--- a/Source/WebCore/dom/SelectorNodeList.cpp
+++ b/Source/WebCore/dom/SelectorNodeList.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,16 +56,25 @@ PassRefPtr<StaticNodeList> createSelectorNodeList(Node* rootNode, const CSSSelec
if (element && (rootNode->isDocumentNode() || element->isDescendantOf(rootNode)) && selectorChecker.checkSelector(onlySelector, element))
nodes.append(element);
} else {
- for (Node* n = rootNode->firstChild(); n; n = n->traverseNextNode(rootNode)) {
+ Vector<CSSSelector*> querySelectors;
+ querySelectors.reserveInitialCapacity(16);
+ for (CSSSelector* selector = querySelectorList.first(); selector; selector = CSSSelectorList::next(selector))
+ querySelectors.append(selector);
+ int querySelectorsCount = querySelectors.size();
+
+ Node* lastNode = rootNode->lastDescendantNode();
+ for (Node* n = rootNode->firstChild(); n; n = n->traverseNextNodeFastPath()) {
if (n->isElementNode()) {
Element* element = static_cast<Element*>(n);
- for (CSSSelector* selector = querySelectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
- if (selectorChecker.checkSelector(selector, element)) {
+ for (int i = 0; i < querySelectorsCount; i++) {
+ if (selectorChecker.checkSelector(querySelectors[i], element)) {
nodes.append(n);
break;
}
}
}
+ if (n == lastNode)
+ break;
}
}
diff --git a/Source/WebCore/dom/TagNodeList.cpp b/Source/WebCore/dom/TagNodeList.cpp
index 4914e09..df51fe1 100644
--- a/Source/WebCore/dom/TagNodeList.cpp
+++ b/Source/WebCore/dom/TagNodeList.cpp
@@ -4,6 +4,7 @@
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,25 +30,45 @@
namespace WebCore {
-TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+TagNodeListNS::TagNodeListNS(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
: DynamicNodeList(rootNode)
, m_namespaceURI(namespaceURI)
, m_localName(localName)
+ , m_isStarAtomNamespaceURI(m_namespaceURI == starAtom)
+ , m_isStarAtomlocalName(m_localName == starAtom)
{
ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
}
-TagNodeList::~TagNodeList()
+TagNodeListNS::~TagNodeListNS()
{
- m_rootNode->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI));
-}
+ m_rootNode->removeCachedTagNodeListNS(this, QualifiedName(nullAtom, m_localName, m_namespaceURI));
+}
-bool TagNodeList::nodeMatches(Element* testNode) const
+bool TagNodeListNS::nodeMatches(Element* testNode) const
{
- if (m_namespaceURI != starAtom && m_namespaceURI != testNode->namespaceURI())
+ if (!m_isStarAtomNamespaceURI && m_namespaceURI != testNode->namespaceURI())
return false;
- return m_localName == starAtom || m_localName == testNode->localName();
+ return m_isStarAtomlocalName || m_localName == testNode->localName();
}
+TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName)
+ : DynamicNodeList(rootNode)
+ , m_localName(localName)
+ , m_isStarAtomlocalName(m_localName == starAtom)
+{
+}
+
+TagNodeList::~TagNodeList()
+{
+ m_rootNode->removeCachedTagNodeList(this, m_localName);
+}
+
+bool TagNodeList::nodeMatches(Element* testNode) const
+{
+ return m_isStarAtomlocalName || m_localName == testNode->localName();
+}
+
+
} // namespace WebCore
diff --git a/Source/WebCore/dom/TagNodeList.h b/Source/WebCore/dom/TagNodeList.h
index 9053b53..f255532 100644
--- a/Source/WebCore/dom/TagNodeList.h
+++ b/Source/WebCore/dom/TagNodeList.h
@@ -29,24 +29,45 @@
namespace WebCore {
- // NodeList that limits to a particular tag.
- class TagNodeList : public DynamicNodeList {
- public:
- static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
- {
- return adoptRef(new TagNodeList(rootNode, namespaceURI, localName));
- }
+// NodeList with namespace that limits to a particular tag.
+class TagNodeListNS : public DynamicNodeList {
+public:
+ static PassRefPtr<TagNodeListNS> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+ {
+ return adoptRef(new TagNodeListNS(rootNode, namespaceURI, localName));
+ }
- virtual ~TagNodeList();
+ virtual ~TagNodeListNS();
- private:
- TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
+private:
+ TagNodeListNS(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
- virtual bool nodeMatches(Element*) const;
+ virtual bool nodeMatches(Element*) const;
- AtomicString m_namespaceURI;
- AtomicString m_localName;
- };
+ AtomicString m_namespaceURI;
+ AtomicString m_localName;
+ bool m_isStarAtomNamespaceURI : 1;
+ bool m_isStarAtomlocalName : 1;
+};
+
+// NodeList that limits to a particular tag.
+class TagNodeList : public DynamicNodeList {
+public:
+ static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& localName)
+ {
+ return adoptRef(new TagNodeList(rootNode, localName));
+ }
+
+ virtual ~TagNodeList();
+
+private:
+ TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName);
+
+ virtual bool nodeMatches(Element*) const;
+
+ AtomicString m_localName;
+ bool m_isStarAtomlocalName;
+};
} // namespace WebCore
diff --git a/Source/WebCore/dom/Text.cpp b/Source/WebCore/dom/Text.cpp
index c4ea0a6..01a454d 100644
--- a/Source/WebCore/dom/Text.cpp
+++ b/Source/WebCore/dom/Text.cpp
@@ -213,7 +213,7 @@ bool Text::rendererIsNeeded(RenderStyle *style)
if (style->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
return true;
- RenderObject *prev = previousRenderer();
+ RenderObject* prev = m_previousRenderer ? m_previousRenderer : previousRenderer();
if (prev && prev->isBR()) // <span><br/> <br/></span>
return false;
diff --git a/Source/WebCore/dom/Text.h b/Source/WebCore/dom/Text.h
index 5995f1f..4db3bb3 100644
--- a/Source/WebCore/dom/Text.h
+++ b/Source/WebCore/dom/Text.h
@@ -43,9 +43,12 @@ public:
virtual void attach();
+ void setPreviousRenderer(RenderObject* renderer) { m_previousRenderer = renderer; }
+
protected:
Text(Document* document, const String& data)
: CharacterData(document, data, CreateText)
+ , m_previousRenderer(0)
{
}
@@ -63,6 +66,8 @@ private:
#ifndef NDEBUG
virtual void formatForDebugger(char* buffer, unsigned length) const;
#endif
+
+ RenderObject* m_previousRenderer;
};
} // namespace WebCore
diff --git a/Source/WebCore/dom/TreeScope.cpp b/Source/WebCore/dom/TreeScope.cpp
index a995a2d..45c7a8f 100644
--- a/Source/WebCore/dom/TreeScope.cpp
+++ b/Source/WebCore/dom/TreeScope.cpp
@@ -97,7 +97,7 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
if (key.isEmpty())
return 0;
if (!m_accessKeyMapValid) {
- for (Node* n = firstChild(); n; n = n->traverseNextNode()) {
+ for (Node* n = firstChild(); n; n = n->traverseNextNodeFastPath()) {
if (!n->isElementNode())
continue;
Element* element = static_cast<Element*>(n);
@@ -149,7 +149,7 @@ Element* TreeScope::findAnchor(const String& name)
return 0;
if (Element* element = getElementById(name))
return element;
- for (Node* node = this; node; node = node->traverseNextNode()) {
+ for (Node* node = this; node; node = node->traverseNextNodeFastPath()) {
if (node->hasTagName(aTag)) {
HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(node);
if (document()->inQuirksMode()) {
diff --git a/Source/WebCore/editing/MarkupAccumulator.cpp b/Source/WebCore/editing/MarkupAccumulator.cpp
index f4489c5..8ef0594 100644
--- a/Source/WebCore/editing/MarkupAccumulator.cpp
+++ b/Source/WebCore/editing/MarkupAccumulator.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009, 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2012, The Linux Foundation All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -43,34 +44,57 @@ namespace WebCore {
using namespace HTMLNames;
-void appendCharactersReplacingEntities(Vector<UChar>& out, const UChar* content, size_t length, EntityMask entityMask)
+void appendCharactersReplacingEntities(StringBuilder& result, const UChar* content, size_t length, EntityMask entityMask)
{
- DEFINE_STATIC_LOCAL(const String, ampReference, ("&amp;"));
- DEFINE_STATIC_LOCAL(const String, ltReference, ("&lt;"));
- DEFINE_STATIC_LOCAL(const String, gtReference, ("&gt;"));
- DEFINE_STATIC_LOCAL(const String, quotReference, ("&quot;"));
- DEFINE_STATIC_LOCAL(const String, nbspReference, ("&nbsp;"));
-
- static const EntityDescription entityMaps[] = {
- { '&', ampReference, EntityAmp },
- { '<', ltReference, EntityLt },
- { '>', gtReference, EntityGt },
- { '"', quotReference, EntityQuot },
- { noBreakSpace, nbspReference, EntityNbsp },
- };
-
size_t positionAfterLastEntity = 0;
- for (size_t i = 0; i < length; ++i) {
- for (size_t m = 0; m < WTF_ARRAY_LENGTH(entityMaps); ++m) {
- if (content[i] == entityMaps[m].entity && entityMaps[m].mask & entityMask) {
- out.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
- append(out, entityMaps[m].reference);
+ if (entityMask & EntityNbsp) {
+ for (size_t i = 0; i < length; ++i) {
+ UChar c = content[i];
+ if (c == noBreakSpace) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&nbsp;", 6);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '&' && EntityAmp & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&amp;", 5);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '<' && EntityLt & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&lt;", 4);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '>' && EntityGt & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&gt;", 4);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '"' && EntityQuot & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&quot;", 6);
+ positionAfterLastEntity = i + 1;
+ }
+ }
+ }else if (entityMask) {
+ for (size_t i = 0; i < length; ++i) {
+ UChar c = content[i];
+ if (c == '&' && EntityAmp & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&amp;", 5);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '<' && EntityLt & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&lt;", 4);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '>' && EntityGt & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&gt;", 4);
+ positionAfterLastEntity = i + 1;
+ } else if (c == '"' && EntityQuot & entityMask) {
+ result.append(content + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append("&quot;", 6);
positionAfterLastEntity = i + 1;
- break;
}
}
}
- out.append(content + positionAfterLastEntity, length - positionAfterLastEntity);
+ result.append(content + positionAfterLastEntity, length - positionAfterLastEntity);
}
MarkupAccumulator::MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, const Range* range)
@@ -86,11 +110,8 @@ MarkupAccumulator::~MarkupAccumulator()
String MarkupAccumulator::serializeNodes(Node* node, Node* nodeToSkip, EChildrenOnly childrenOnly)
{
- Vector<UChar> out;
serializeNodesWithNamespaces(node, nodeToSkip, childrenOnly, 0);
- out.reserveInitialCapacity(length());
- concatenateMarkup(out);
- return String::adopt(out);
+ return m_markup.toString();
}
void MarkupAccumulator::serializeNodesWithNamespaces(Node* node, Node* nodeToSkip, EChildrenOnly childrenOnly, const Namespaces* namespaces)
@@ -116,23 +137,19 @@ void MarkupAccumulator::serializeNodesWithNamespaces(Node* node, Node* nodeToSki
void MarkupAccumulator::appendString(const String& string)
{
- m_succeedingMarkup.append(string);
+ m_markup.append(string);
}
void MarkupAccumulator::appendStartTag(Node* node, Namespaces* namespaces)
{
- Vector<UChar> markup;
- appendStartMarkup(markup, node, namespaces);
- appendString(String::adopt(markup));
+ appendStartMarkup(m_markup, node, namespaces);
if (m_nodes)
m_nodes->append(node);
}
void MarkupAccumulator::appendEndTag(Node* node)
{
- Vector<UChar> markup;
- appendEndMarkup(markup, node);
- appendString(String::adopt(markup));
+ appendEndMarkup(m_markup, node);
}
size_t MarkupAccumulator::totalLength(const Vector<String>& strings)
@@ -143,35 +160,31 @@ size_t MarkupAccumulator::totalLength(const Vector<String>& strings)
return length;
}
-// FIXME: This is a very inefficient way of accumulating the markup.
-// We're converting results of appendStartMarkup and appendEndMarkup from Vector<UChar> to String
-// and then back to Vector<UChar> and again to String here.
-void MarkupAccumulator::concatenateMarkup(Vector<UChar>& out)
+void MarkupAccumulator::concatenateMarkup(StringBuilder& result)
{
- for (size_t i = 0; i < m_succeedingMarkup.size(); ++i)
- append(out, m_succeedingMarkup[i]);
+ result.append(m_markup);
}
-void MarkupAccumulator::appendAttributeValue(Vector<UChar>& result, const String& attribute, bool documentIsHTML)
+void MarkupAccumulator::appendAttributeValue(StringBuilder& result, const String& attribute, bool documentIsHTML)
{
appendCharactersReplacingEntities(result, attribute.characters(), attribute.length(),
documentIsHTML ? EntityMaskInHTMLAttributeValue : EntityMaskInAttributeValue);
}
-void MarkupAccumulator::appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString)
+void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const String& urlString)
{
- UChar quoteChar = '\"';
+ UChar quoteChar = '"';
String strippedURLString = urlString.stripWhiteSpace();
if (protocolIsJavaScript(strippedURLString)) {
// minimal escaping for javascript urls
if (strippedURLString.contains('"')) {
if (strippedURLString.contains('\''))
- strippedURLString.replace('\"', "&quot;");
+ strippedURLString.replace('"', "&quot;");
else
quoteChar = '\'';
}
result.append(quoteChar);
- append(result, strippedURLString);
+ result.append(strippedURLString);
result.append(quoteChar);
return;
}
@@ -182,7 +195,7 @@ void MarkupAccumulator::appendQuotedURLAttributeValue(Vector<UChar>& result, con
result.append(quoteChar);
}
-void MarkupAccumulator::appendNodeValue(Vector<UChar>& out, const Node* node, const Range* range, EntityMask entityMask)
+void MarkupAccumulator::appendNodeValue(StringBuilder& out, const Node* node, const Range* range, EntityMask entityMask)
{
String str = node->nodeValue();
const UChar* characters = str.characters();
@@ -229,7 +242,7 @@ bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute,
return true;
}
-void MarkupAccumulator::appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces& namespaces)
+void MarkupAccumulator::appendNamespace(StringBuilder& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces& namespaces)
{
namespaces.checkConsistency();
if (namespaceURI.isEmpty())
@@ -241,10 +254,10 @@ void MarkupAccumulator::appendNamespace(Vector<UChar>& result, const AtomicStrin
if (foundNS != namespaceURI.impl()) {
namespaces.set(pre, namespaceURI.impl());
result.append(' ');
- append(result, xmlnsAtom.string());
+ result.append(xmlnsAtom.string());
if (!prefix.isEmpty()) {
result.append(':');
- append(result, prefix);
+ result.append(prefix);
}
result.append('=');
@@ -259,66 +272,75 @@ EntityMask MarkupAccumulator::entityMaskForText(Text* text) const
const QualifiedName* parentName = 0;
if (text->parentElement())
parentName = &static_cast<Element*>(text->parentElement())->tagQName();
-
+
if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag))
return EntityMaskInCDATA;
return text->document()->isHTMLDocument() ? EntityMaskInHTMLPCDATA : EntityMaskInPCDATA;
}
-void MarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
+void MarkupAccumulator::appendText(StringBuilder& result, Text* text)
{
- appendNodeValue(out, text, m_range, entityMaskForText(text));
+ appendNodeValue(result, text, m_range, entityMaskForText(text));
}
-void MarkupAccumulator::appendComment(Vector<UChar>& out, const String& comment)
+void MarkupAccumulator::appendComment(StringBuilder& result, const String& comment)
{
// FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".
- append(out, "<!--");
- append(out, comment);
- append(out, "-->");
+ static const char commentBegin[] = "<!--";
+ result.append(commentBegin, sizeof(commentBegin) - 1);
+ result.append(comment);
+ static const char commentEnd[] = "-->";
+ result.append(commentEnd, sizeof(commentEnd) - 1);
}
-void MarkupAccumulator::appendDocumentType(Vector<UChar>& result, const DocumentType* n)
+void MarkupAccumulator::appendDocumentType(StringBuilder& result, const DocumentType* n)
{
if (n->name().isEmpty())
return;
- append(result, "<!DOCTYPE ");
- append(result, n->name());
+ static const char doctypeString[] = "<!DOCTYPE ";
+ result.append(doctypeString, sizeof(doctypeString) - 1);
+ result.append(n->name());
if (!n->publicId().isEmpty()) {
- append(result, " PUBLIC \"");
- append(result, n->publicId());
- append(result, "\"");
+ static const char publicString[] = " PUBLIC \"";
+ result.append(publicString, sizeof(publicString) - 1);
+ result.append(n->publicId());
+ result.append('"');
if (!n->systemId().isEmpty()) {
- append(result, " \"");
- append(result, n->systemId());
- append(result, "\"");
+ result.append(' ');
+ result.append('"');
+ result.append(n->systemId());
+ result.append('"');
}
} else if (!n->systemId().isEmpty()) {
- append(result, " SYSTEM \"");
- append(result, n->systemId());
- append(result, "\"");
+ static const char systemString[] = " SYSTEM \"";
+ result.append(systemString, sizeof(systemString) - 1);
+ result.append(n->systemId());
+ result.append('"');
}
if (!n->internalSubset().isEmpty()) {
- append(result, " [");
- append(result, n->internalSubset());
- append(result, "]");
+ result.append(' ');
+ result.append('[');
+ result.append(n->internalSubset());
+ result.append(']');
}
- append(result, ">");
+ result.append('>');
}
-void MarkupAccumulator::appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data)
+void MarkupAccumulator::appendProcessingInstruction(StringBuilder& result, const String& target, const String& data)
{
// FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".
- append(out, "<?");
- append(out, target);
- append(out, " ");
- append(out, data);
- append(out, "?>");
+ result.append('<');
+ result.append('?');
+ result.append(target);
+ result.append(' ');
+ result.append(data);
+ result.append('?');
+ result.append('>');
}
-void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, Namespaces* namespaces)
+void MarkupAccumulator::appendElement(StringBuilder& out, Element* element, Namespaces* namespaces)
{
appendOpenTag(out, element, namespaces);
@@ -330,15 +352,15 @@ void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, Name
appendCloseTag(out, element);
}
-void MarkupAccumulator::appendOpenTag(Vector<UChar>& out, Element* element, Namespaces* namespaces)
+void MarkupAccumulator::appendOpenTag(StringBuilder& out, Element* element, Namespaces* namespaces)
{
out.append('<');
- append(out, element->nodeNamePreservingCase());
+ out.append(element->nodeNamePreservingCase());
if (!element->document()->isHTMLDocument() && namespaces && shouldAddNamespaceElement(element))
appendNamespace(out, element->prefix(), element->namespaceURI(), *namespaces);
}
-void MarkupAccumulator::appendCloseTag(Vector<UChar>& out, Element* element)
+void MarkupAccumulator::appendCloseTag(StringBuilder& out, Element* element)
{
if (shouldSelfClose(element)) {
if (element->isHTMLElement())
@@ -348,16 +370,16 @@ void MarkupAccumulator::appendCloseTag(Vector<UChar>& out, Element* element)
out.append('>');
}
-void MarkupAccumulator::appendAttribute(Vector<UChar>& out, Element* element, const Attribute& attribute, Namespaces* namespaces)
+void MarkupAccumulator::appendAttribute(StringBuilder& out, Element* element, const Attribute& attribute, Namespaces* namespaces)
{
bool documentIsHTML = element->document()->isHTMLDocument();
out.append(' ');
if (documentIsHTML)
- append(out, attribute.name().localName());
+ out.append(attribute.name().localName());
else
- append(out, attribute.name().toString());
+ out.append(attribute.name().toString());
out.append('=');
@@ -369,24 +391,26 @@ void MarkupAccumulator::appendAttribute(Vector<UChar>& out, Element* element, co
else
appendQuotedURLAttributeValue(out, attribute.value());
} else {
- out.append('\"');
+ out.append('"');
appendAttributeValue(out, attribute.value(), documentIsHTML);
- out.append('\"');
+ out.append('"');
}
if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
appendNamespace(out, attribute.prefix(), attribute.namespaceURI(), *namespaces);
}
-void MarkupAccumulator::appendCDATASection(Vector<UChar>& out, const String& section)
+void MarkupAccumulator::appendCDATASection(StringBuilder& result, const String& section)
{
// FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".
- append(out, "<![CDATA[");
- append(out, section);
- append(out, "]]>");
+ static const char cdataBegin[] = "<![CDATA[";
+ result.append(cdataBegin, sizeof(cdataBegin) - 1);
+ result.append(section);
+ static const char cdataEnd[] = "]]>";
+ result.append(cdataEnd, sizeof(cdataEnd) - 1);
}
-void MarkupAccumulator::appendStartMarkup(Vector<UChar>& result, const Node* node, Namespaces* namespaces)
+void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node* node, Namespaces* namespaces)
{
if (namespaces)
namespaces->checkConsistency();
@@ -443,7 +467,7 @@ bool MarkupAccumulator::elementCannotHaveEndTag(const Node* node)
{
if (!node->isHTMLElement())
return false;
-
+
// FIXME: ieForbidsInsertHTML may not be the right function to call here
// ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML
// or createContextualFragment. It does not necessarily align with
@@ -451,14 +475,14 @@ bool MarkupAccumulator::elementCannotHaveEndTag(const Node* node)
return static_cast<const HTMLElement*>(node)->ieForbidsInsertHTML();
}
-void MarkupAccumulator::appendEndMarkup(Vector<UChar>& result, const Node* node)
+void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node* node)
{
if (!node->isElementNode() || shouldSelfClose(node) || (!node->hasChildNodes() && elementCannotHaveEndTag(node)))
return;
result.append('<');
result.append('/');
- append(result, static_cast<const Element*>(node)->nodeNamePreservingCase());
+ result.append(static_cast<const Element*>(node)->nodeNamePreservingCase());
result.append('>');
}
diff --git a/Source/WebCore/editing/MarkupAccumulator.h b/Source/WebCore/editing/MarkupAccumulator.h
index 0bfc6e6..ba28288 100644
--- a/Source/WebCore/editing/MarkupAccumulator.h
+++ b/Source/WebCore/editing/MarkupAccumulator.h
@@ -30,6 +30,7 @@
#include "markup.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -76,28 +77,28 @@ protected:
void appendStartTag(Node*, Namespaces* = 0);
void appendEndTag(Node*);
static size_t totalLength(const Vector<String>&);
- size_t length() const { return totalLength(m_succeedingMarkup); }
- void concatenateMarkup(Vector<UChar>& out);
- void appendAttributeValue(Vector<UChar>& result, const String& attribute, bool documentIsHTML);
- void appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString);
- void appendNodeValue(Vector<UChar>& out, const Node*, const Range*, EntityMask);
+ size_t length() const { return m_markup.length(); }
+ void concatenateMarkup(StringBuilder& out);
+ void appendAttributeValue(StringBuilder& result, const String& attribute, bool documentIsHTML);
+ void appendQuotedURLAttributeValue(StringBuilder& result, const String& urlString);
+ void appendNodeValue(StringBuilder& out, const Node*, const Range*, EntityMask);
bool shouldAddNamespaceElement(const Element*);
bool shouldAddNamespaceAttribute(const Attribute&, Namespaces&);
- void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
+ void appendNamespace(StringBuilder& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
EntityMask entityMaskForText(Text* text) const;
- virtual void appendText(Vector<UChar>& out, Text*);
- void appendComment(Vector<UChar>& out, const String& comment);
- void appendDocumentType(Vector<UChar>& result, const DocumentType*);
- void appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data);
- virtual void appendElement(Vector<UChar>& out, Element*, Namespaces*);
- void appendOpenTag(Vector<UChar>& out, Element* element, Namespaces*);
- void appendCloseTag(Vector<UChar>& out, Element* element);
- void appendAttribute(Vector<UChar>& out, Element* element, const Attribute&, Namespaces*);
- void appendCDATASection(Vector<UChar>& out, const String& section);
- void appendStartMarkup(Vector<UChar>& result, const Node*, Namespaces*);
+ virtual void appendText(StringBuilder& out, Text*);
+ void appendComment(StringBuilder& out, const String& comment);
+ void appendDocumentType(StringBuilder& result, const DocumentType*);
+ void appendProcessingInstruction(StringBuilder& out, const String& target, const String& data);
+ virtual void appendElement(StringBuilder& out, Element*, Namespaces*);
+ void appendOpenTag(StringBuilder& out, Element* element, Namespaces*);
+ void appendCloseTag(StringBuilder& out, Element* element);
+ void appendAttribute(StringBuilder& out, Element* element, const Attribute&, Namespaces*);
+ void appendCDATASection(StringBuilder& out, const String& section);
+ void appendStartMarkup(StringBuilder& result, const Node*, Namespaces*);
bool shouldSelfClose(const Node*);
bool elementCannotHaveEndTag(const Node* node);
- void appendEndMarkup(Vector<UChar>& result, const Node*);
+ void appendEndMarkup(StringBuilder&, const Node*);
bool shouldResolveURLs() { return m_shouldResolveURLs == AbsoluteURLs; }
@@ -107,12 +108,12 @@ protected:
private:
void serializeNodesWithNamespaces(Node*, Node* nodeToSkip, EChildrenOnly, const Namespaces*);
- Vector<String> m_succeedingMarkup;
+ StringBuilder m_markup;
const bool m_shouldResolveURLs;
};
// FIXME: This method should be integrated with MarkupAccumulator.
-void appendCharactersReplacingEntities(Vector<UChar>& out, const UChar* content, size_t length, EntityMask entityMask);
+void appendCharactersReplacingEntities(StringBuilder& out, const UChar* content, size_t length, EntityMask entityMask);
}
diff --git a/Source/WebCore/editing/markup.cpp b/Source/WebCore/editing/markup.cpp
index 5ef3d7d..a02ff03 100644
--- a/Source/WebCore/editing/markup.cpp
+++ b/Source/WebCore/editing/markup.cpp
@@ -130,12 +130,12 @@ public:
String takeResults();
private:
- virtual void appendText(Vector<UChar>& out, Text*);
+ virtual void appendText(StringBuilder& out, Text*);
String renderedText(const Node*, const Range*);
String stringValueForRange(const Node*, const Range*);
void removeExteriorStyles(CSSMutableStyleDeclaration*);
- void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode);
- void appendElement(Vector<UChar>& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
+ void appendElement(StringBuilder& out, Element* element, bool addDisplayInline, RangeFullySelectsNode);
+ void appendElement(StringBuilder& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
@@ -145,12 +145,12 @@ private:
void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
{
- Vector<UChar> markup;
+ StringBuilder markup;
if (node->isElementNode())
appendElement(markup, static_cast<Element*>(node), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode);
else
appendStartMarkup(markup, node, 0);
- m_reversedPrecedingMarkup.append(String::adopt(markup));
+ m_reversedPrecedingMarkup.append(markup.toString());
appendEndTag(node);
if (m_nodes)
m_nodes->append(node);
@@ -165,30 +165,30 @@ void StyledMarkupAccumulator::wrapWithStyleNode(CSSStyleDeclaration* style, Docu
DEFINE_STATIC_LOCAL(const String, divClose, ("</div>"));
DEFINE_STATIC_LOCAL(const String, styleSpanOpen, ("<span class=\"" AppleStyleSpanClass "\" style=\""));
DEFINE_STATIC_LOCAL(const String, styleSpanClose, ("</span>"));
- Vector<UChar> openTag;
- append(openTag, isBlock ? divStyle : styleSpanOpen);
+ StringBuilder openTag;
+ openTag.append(isBlock ? divStyle : styleSpanOpen);
appendAttributeValue(openTag, style->cssText(), document->isHTMLDocument());
openTag.append('\"');
openTag.append('>');
- m_reversedPrecedingMarkup.append(String::adopt(openTag));
+ m_reversedPrecedingMarkup.append(openTag.toString());
appendString(isBlock ? divClose : styleSpanClose);
}
String StyledMarkupAccumulator::takeResults()
{
- Vector<UChar> result;
- result.reserveInitialCapacity(totalLength(m_reversedPrecedingMarkup) + length());
+ StringBuilder result;
+ result.reserveCapacity(totalLength(m_reversedPrecedingMarkup) + length());
for (size_t i = m_reversedPrecedingMarkup.size(); i > 0; --i)
- append(result, m_reversedPrecedingMarkup[i - 1]);
+ result.append(m_reversedPrecedingMarkup[i - 1]);
concatenateMarkup(result);
// We remove '\0' characters because they are not visibly rendered to the user.
- return String::adopt(result).replace(0, "");
+ return result.toString().replace(0, "");
}
-void StyledMarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
+void StyledMarkupAccumulator::appendText(StringBuilder& out, Text* text)
{
if (!shouldAnnotate() || (text->parentElement() && text->parentElement()->tagQName() == textareaTag)) {
MarkupAccumulator::appendText(out, text);
@@ -197,9 +197,9 @@ void StyledMarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(text), selectTag);
String content = useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range);
- Vector<UChar> buffer;
+ StringBuilder buffer;
appendCharactersReplacingEntities(buffer, content.characters(), content.length(), EntityMaskInPCDATA);
- append(out, convertHTMLTextToInterchangeFormat(String::adopt(buffer), text));
+ out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text));
}
String StyledMarkupAccumulator::renderedText(const Node* node, const Range* range)
@@ -252,7 +252,7 @@ static PassRefPtr<CSSMutableStyleDeclaration> styleFromMatchedRulesForElement(El
return style.release();
}
-void StyledMarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
+void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
{
bool documentIsHTML = element->document()->isHTMLDocument();
appendOpenTag(out, element, 0);
@@ -303,7 +303,7 @@ void StyledMarkupAccumulator::appendElement(Vector<UChar>& out, Element* element
removeExteriorStyles(style.get());
if (style->length() > 0) {
DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));
- append(out, stylePrefix);
+ out.append(stylePrefix);
appendAttributeValue(out, style->cssText(), documentIsHTML);
out.append('\"');
}
@@ -819,7 +819,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
if (s.isEmpty() && i + 1 == numLines) {
// For last line, use the "magic BR" rather than a P.
element = createBreakElement(document);
- element->setAttribute(classAttr, AppleInterchangeNewline);
+ element->setAttribute(classAttr, AppleInterchangeNewline);
} else {
if (useClonesOfEnclosingBlock)
element = block->cloneElementWithoutChildren();
@@ -905,13 +905,13 @@ String createFullMarkup(const Range* range)
String urlToMarkup(const KURL& url, const String& title)
{
- Vector<UChar> markup;
- append(markup, "<a href=\"");
- append(markup, url.string());
- append(markup, "\">");
+ StringBuilder markup;
+ markup.append("<a href=\"");
+ markup.append(url.string());
+ markup.append("\">");
appendCharactersReplacingEntities(markup, title.characters(), title.length(), EntityMaskInPCDATA);
- append(markup, "</a>");
- return String::adopt(markup);
+ markup.append("</a>");
+ return markup.toString();
}
}
diff --git a/Source/WebCore/history/PageCache.cpp b/Source/WebCore/history/PageCache.cpp
index 204ab36..818aa38 100644
--- a/Source/WebCore/history/PageCache.cpp
+++ b/Source/WebCore/history/PageCache.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -283,6 +284,9 @@ bool PageCache::canCachePageContainingThisFrame(Frame* frame)
&& !frame->document()->containsWMLContent()
&& !frame->document()->isWMLDocument()
#endif
+#if ENABLE(WEBGL) && PLATFORM(ANDROID)
+ && !frame->document()->containsWebGLContent()
+#endif
&& frame->loader()->client()->canCachePage();
}
diff --git a/Source/WebCore/html/CollectionCache.cpp b/Source/WebCore/html/CollectionCache.cpp
index 745cf6e..d831ad1 100644
--- a/Source/WebCore/html/CollectionCache.cpp
+++ b/Source/WebCore/html/CollectionCache.cpp
@@ -83,6 +83,7 @@ void CollectionCache::reset()
deleteAllValues(nameCache);
nameCache.clear();
hasNameCache = false;
+ lastDecendantOfBase = 0;
}
#if !ASSERT_DISABLED
diff --git a/Source/WebCore/html/CollectionCache.h b/Source/WebCore/html/CollectionCache.h
index d160db2..799263c 100644
--- a/Source/WebCore/html/CollectionCache.h
+++ b/Source/WebCore/html/CollectionCache.h
@@ -28,6 +28,7 @@
namespace WebCore {
class Element;
+class Node;
struct CollectionCache {
WTF_MAKE_FAST_ALLOCATED;
@@ -58,6 +59,7 @@ public:
NodeCacheMap nameCache;
bool hasLength;
bool hasNameCache;
+ Node* lastDecendantOfBase;
private:
static void copyCacheMap(NodeCacheMap&, const NodeCacheMap&);
diff --git a/Source/WebCore/html/HTMLAllCollection.cpp b/Source/WebCore/html/HTMLAllCollection.cpp
index dbfed28..8c92a00 100644
--- a/Source/WebCore/html/HTMLAllCollection.cpp
+++ b/Source/WebCore/html/HTMLAllCollection.cpp
@@ -26,17 +26,18 @@
#include "config.h"
#include "HTMLAllCollection.h"
+#include "Element.h"
#include "Node.h"
namespace WebCore {
-PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(PassRefPtr<Node> base)
+PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(PassRefPtr<Node> base, CollectionType type)
{
- return adoptRef(new HTMLAllCollection(base));
+ return adoptRef(new HTMLAllCollection(base, type));
}
-HTMLAllCollection::HTMLAllCollection(PassRefPtr<Node> base)
- : HTMLCollection(base, DocAll)
+HTMLAllCollection::HTMLAllCollection(PassRefPtr<Node> base, CollectionType type)
+ : HTMLCollection(base, type)
{
}
@@ -44,4 +45,38 @@ HTMLAllCollection::~HTMLAllCollection()
{
}
+Element* HTMLAllCollection::itemAfter(Element* previous) const
+{
+ bool includeChildren = (type() == DocAll);
+ Node* current;
+ Node* root = base();
+ if (!previous)
+ current = root->firstChild();
+ else
+ current = includeChildren ? previous->traverseNextNode(root) : previous->traverseNextSibling(root);
+
+ if (includeChildren) {
+ Node * lastDecendant = info()->lastDecendantOfBase;
+ if (!lastDecendant) {
+ info()->lastDecendantOfBase = root->lastDescendantNode();
+ lastDecendant = info()->lastDecendantOfBase;
+ }
+
+ for (; current; current = current->traverseNextNodeFastPath()) {
+ if (current->isElementNode())
+ return static_cast<Element*>(current);
+ if (current == lastDecendant)
+ break;
+ }
+ } else {
+ for (; current; current = current->traverseNextSibling(root)) {
+ if (current->isElementNode())
+ return static_cast<Element*>(current);
+ }
+ }
+
+ return 0;
+}
+
+
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLAllCollection.h b/Source/WebCore/html/HTMLAllCollection.h
index 1dd3ede..443e855 100644
--- a/Source/WebCore/html/HTMLAllCollection.h
+++ b/Source/WebCore/html/HTMLAllCollection.h
@@ -32,11 +32,13 @@ namespace WebCore {
class HTMLAllCollection : public HTMLCollection {
public:
- static PassRefPtr<HTMLAllCollection> create(PassRefPtr<Node>);
+ static PassRefPtr<HTMLAllCollection> create(PassRefPtr<Node>, CollectionType = DocAll);
virtual ~HTMLAllCollection();
private:
- HTMLAllCollection(PassRefPtr<Node>);
+ HTMLAllCollection(PassRefPtr<Node>, CollectionType = DocAll);
+
+ virtual Element* itemAfter(Element*) const;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp
index 4cb2748..cf37ff2 100644
--- a/Source/WebCore/html/HTMLAreaElement.cpp
+++ b/Source/WebCore/html/HTMLAreaElement.cpp
@@ -45,6 +45,7 @@ inline HTMLAreaElement::HTMLAreaElement(const QualifiedName& tagName, Document*
, m_shape(Unknown)
{
ASSERT(hasTagName(areaTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLAreaElement> HTMLAreaElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 578f717..866340d 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -83,6 +83,7 @@ content
contenteditable
controls
coords
+crossorigin
data
datetime
declare
diff --git a/Source/WebCore/html/HTMLBRElement.cpp b/Source/WebCore/html/HTMLBRElement.cpp
index e8f4520..da20fbf 100644
--- a/Source/WebCore/html/HTMLBRElement.cpp
+++ b/Source/WebCore/html/HTMLBRElement.cpp
@@ -36,6 +36,7 @@ HTMLBRElement::HTMLBRElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
{
ASSERT(hasTagName(brTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLBRElement> HTMLBRElement::create(Document* document)
diff --git a/Source/WebCore/html/HTMLBaseElement.cpp b/Source/WebCore/html/HTMLBaseElement.cpp
index 0dd16fa..961cc49 100644
--- a/Source/WebCore/html/HTMLBaseElement.cpp
+++ b/Source/WebCore/html/HTMLBaseElement.cpp
@@ -35,6 +35,7 @@ inline HTMLBaseElement::HTMLBaseElement(const QualifiedName& tagName, Document*
: HTMLElement(tagName, document)
{
ASSERT(hasTagName(baseTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLBaseElement> HTMLBaseElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index e67cbf9..35ce549 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -2,6 +2,9 @@
* Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation All rights reserved.
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -114,6 +117,11 @@ HTMLCanvasElement::~HTMLCanvasElement()
HashSet<CanvasObserver*>::iterator end = m_observers.end();
for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasDestroyed(this);
+
+#if ENABLE(WEBGL)
+ document()->unregisterForDocumentActivationCallbacks(this);
+ document()->unregisterForDocumentSuspendCallbacks(this);
+#endif
}
void HTMLCanvasElement::parseMappedAttribute(Attribute* attr)
@@ -203,6 +211,11 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
if (m_context) {
// Need to make sure a RenderLayer and compositing layer get created for the Canvas
setNeedsStyleRecalc(SyntheticStyleChange);
+#if PLATFORM(ANDROID)
+ document()->registerForDocumentActivationCallbacks(this);
+ document()->registerForDocumentSuspendCallbacks(this);
+ document()->setContainsWebGLContent(true);
+#endif
}
}
return m_context.get();
@@ -308,6 +321,11 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
if (is3D())
static_cast<WebGLRenderingContext*>(m_context.get())->markLayerComposited();
#endif
+#if ENABLE(DASHBOARD_SUPPORT)
+ Settings* settings = document()->settings();
+ if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ setIeForbidsInsertHTML();
+#endif
}
#if ENABLE(WEBGL)
@@ -315,6 +333,40 @@ bool HTMLCanvasElement::is3D() const
{
return m_context && m_context->is3d();
}
+
+#if PLATFORM(ANDROID)
+void HTMLCanvasElement::documentDidBecomeActive()
+{
+ if (m_context && m_context->is3d()) {
+ WebGLRenderingContext* context3D = static_cast<WebGLRenderingContext*>(m_context.get());
+ context3D->recreateSurface();
+ }
+}
+
+void HTMLCanvasElement::documentWillBecomeInactive()
+{
+ if (m_context && m_context->is3d()) {
+ WebGLRenderingContext* context3D = static_cast<WebGLRenderingContext*>(m_context.get());
+ context3D->releaseSurface();
+ }
+}
+
+void HTMLCanvasElement::documentWasSuspended()
+{
+ if (m_context && m_context->is3d()) {
+ WebGLRenderingContext* context3D = static_cast<WebGLRenderingContext*>(m_context.get());
+ context3D->releaseSurface();
+ }
+}
+
+void HTMLCanvasElement::documentWillResume()
+{
+ if (m_context && m_context->is3d()) {
+ WebGLRenderingContext* context3D = static_cast<WebGLRenderingContext*>(m_context.get());
+ context3D->recreateSurface();
+ }
+}
+#endif
#endif
void HTMLCanvasElement::makeRenderingResultsAvailable()
@@ -360,9 +412,7 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
lowercaseMimeType = "image/png";
-#if USE(CG) || (USE(SKIA) && !PLATFORM(ANDROID))
- // FIXME: Consider using this code path on Android. http://b/4572024
- // Try to get ImageData first, as that may avoid lossy conversions.
+#if USE(CG) || (USE(SKIA) || PLATFORM(ANDROID))
RefPtr<ImageData> imageData = getImageData();
if (imageData)
@@ -423,9 +473,9 @@ IntSize HTMLCanvasElement::convertToValidDeviceSize(float width, float height) c
return IntSize(width, height);
}
-const SecurityOrigin& HTMLCanvasElement::securityOrigin() const
+SecurityOrigin* HTMLCanvasElement::securityOrigin() const
{
- return *document()->securityOrigin();
+ return document()->securityOrigin();
}
CSSStyleSelector* HTMLCanvasElement::styleSelector()
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index e485835..39b6d36 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -2,6 +2,9 @@
* Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -114,7 +117,7 @@ public:
IntSize convertLogicalToDevice(const FloatSize&) const;
IntSize convertToValidDeviceSize(float width, float height) const;
- const SecurityOrigin& securityOrigin() const;
+ SecurityOrigin* securityOrigin() const;
void setOriginTainted() { m_originClean = false; }
bool originClean() const { return m_originClean; }
@@ -124,6 +127,12 @@ public:
#if ENABLE(WEBGL)
bool is3D() const;
+#if PLATFORM(ANDROID)
+ void documentDidBecomeActive();
+ void documentWillBecomeInactive();
+ void documentWasSuspended();
+ void documentWillResume();
+#endif
#endif
void makeRenderingResultsAvailable();
diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp
index 2782e50..2c6b135 100644
--- a/Source/WebCore/html/HTMLCollection.cpp
+++ b/Source/WebCore/html/HTMLCollection.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,6 +23,7 @@
#include "config.h"
#include "HTMLCollection.h"
+#include "HTMLAllCollection.h"
#include "HTMLDocument.h"
#include "HTMLElement.h"
@@ -38,24 +40,30 @@ using namespace HTMLNames;
HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type)
: m_idsDone(false)
+ , m_matchTag(htmlTag)
, m_base(base)
, m_type(type)
, m_info(m_base->isDocumentNode() ? static_cast<Document*>(m_base.get())->collectionInfo(type) : 0)
, m_ownsInfo(false)
{
+ init();
}
HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type, CollectionCache* info)
: m_idsDone(false)
+ , m_matchTag(htmlTag)
, m_base(base)
, m_type(type)
, m_info(info)
, m_ownsInfo(false)
{
+ init();
}
PassRefPtr<HTMLCollection> HTMLCollection::create(PassRefPtr<Node> base, CollectionType type)
{
+ if (type == DocAll || type == NodeChildren)
+ return HTMLAllCollection::create(base, type);
return adoptRef(new HTMLCollection(base, type));
}
@@ -65,32 +73,9 @@ HTMLCollection::~HTMLCollection()
delete m_info;
}
-void HTMLCollection::resetCollectionInfo() const
-{
- uint64_t docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion();
-
- if (!m_info) {
- m_info = new CollectionCache;
- m_ownsInfo = true;
- m_info->version = docversion;
- return;
- }
-
- if (m_info->version != docversion) {
- m_info->reset();
- m_info->version = docversion;
- }
-}
-
-static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
-{
- return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
-}
-
-Element* HTMLCollection::itemAfter(Element* previous) const
+void HTMLCollection::init()
{
- bool deep = true;
-
+ m_includeChildren = true;
switch (m_type) {
case DocAll:
case DocAnchors:
@@ -112,91 +97,158 @@ Element* HTMLCollection::itemAfter(Element* previous) const
case TRCells:
case TSectionRows:
case TableTBodies:
- deep = false;
+ m_includeChildren = false;
break;
}
- Node* current;
- if (!previous)
- current = m_base->firstChild();
- else
- current = nextNodeOrSibling(m_base.get(), previous, deep);
+ m_matchType = MatchNone;
+ switch (m_type) {
+ case DocImages:
+ m_matchTag = imgTag;
+ m_matchType = MatchTag;
+ break;
+ case DocScripts:
+ m_matchTag = scriptTag;
+ m_matchType = MatchTag;
+ break;
+ case DocForms:
+ m_matchTag = formTag;
+ m_matchType = MatchTag;
+ break;
+ case TableTBodies:
+ m_matchTag = tbodyTag;
+ m_matchType = MatchTag;
+ break;
+ case TSectionRows:
+ m_matchTag = trTag;
+ m_matchType = MatchTag;
+ break;
+ case SelectOptions:
+ m_matchTag = optionTag;
+ m_matchType = MatchTag;
+ break;
+ case MapAreas:
+ m_matchTag = areaTag;
+ m_matchType = MatchTag;
+ break;
+ case DocEmbeds:
+ m_matchTag = embedTag;
+ m_matchType = MatchTag;
+ break;
+ case DocObjects:
+ m_matchTag = objectTag;
+ m_matchType = MatchTag;
+ break;
+ case TRCells:
+ case DataListOptions:
+ case DocApplets: // all <applet> elements and <object> elements that contain Java Applets
+ case DocLinks: // all <a> and <area> elements with a value for href
+ case DocAnchors: // all <a> elements with a value for name
+ m_matchType = MatchCustom;
+ break;
+ case DocAll:
+ case NodeChildren:
+ m_matchType = MatchAll;
+ break;
+ case DocumentNamedItems:
+ case OtherCollection:
+ case WindowNamedItems:
+ m_matchType = MatchNone;
+ break;
+ }
+}
- for (; current; current = nextNodeOrSibling(m_base.get(), current, deep)) {
- if (!current->isElementNode())
- continue;
- Element* e = static_cast<Element*>(current);
+void HTMLCollection::resetCollectionInfo() const
+{
+ uint64_t docversion = static_cast<HTMLDocument*>(m_base->document())->domTreeVersion();
+
+ if (!m_info) {
+ m_info = new CollectionCache;
+ m_ownsInfo = true;
+ m_info->version = docversion;
+ return;
+ }
+
+ if (m_info->version != docversion) {
+ m_info->reset();
+ m_info->version = docversion;
+ }
+}
+
+static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
+{
+ return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
+}
+
+inline bool HTMLCollection::nodeMatchesShallow(Element* e) const
+{
+ if (m_matchType == MatchTag && e->hasLocalName(m_matchTag))
+ return true;
+ if (m_type == TRCells && (e->hasLocalName(tdTag) || e->hasLocalName(thTag)))
+ return true;
+
+ return false;
+}
+
+inline bool HTMLCollection::nodeMatchesDeep(Element* e) const
+{
+ if (m_matchType == MatchTag && e->hasLocalName(m_matchTag))
+ return true;
+ if (m_matchType == MatchCustom) {
switch (m_type) {
- case DocImages:
- if (e->hasLocalName(imgTag))
- return e;
- break;
- case DocScripts:
- if (e->hasLocalName(scriptTag))
- return e;
- break;
- case DocForms:
- if (e->hasLocalName(formTag))
- return e;
- break;
- case TableTBodies:
- if (e->hasLocalName(tbodyTag))
- return e;
- break;
- case TRCells:
- if (e->hasLocalName(tdTag) || e->hasLocalName(thTag))
- return e;
- break;
- case TSectionRows:
- if (e->hasLocalName(trTag))
- return e;
- break;
- case SelectOptions:
- if (e->hasLocalName(optionTag))
- return e;
- break;
case DataListOptions:
if (e->hasLocalName(optionTag)) {
HTMLOptionElement* option = static_cast<HTMLOptionElement*>(e);
if (!option->disabled() && !option->value().isEmpty())
- return e;
+ return true;
}
break;
- case MapAreas:
- if (e->hasLocalName(areaTag))
- return e;
- break;
case DocApplets: // all <applet> elements and <object> elements that contain Java Applets
if (e->hasLocalName(appletTag))
- return e;
+ return true;
if (e->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet())
- return e;
- break;
- case DocEmbeds:
- if (e->hasLocalName(embedTag))
- return e;
- break;
- case DocObjects:
- if (e->hasLocalName(objectTag))
- return e;
+ return true;
break;
case DocLinks: // all <a> and <area> elements with a value for href
if ((e->hasLocalName(aTag) || e->hasLocalName(areaTag)) && e->fastHasAttribute(hrefAttr))
- return e;
+ return true;
break;
case DocAnchors: // all <a> elements with a value for name
if (e->hasLocalName(aTag) && e->fastHasAttribute(nameAttr))
- return e;
+ return true;
break;
- case DocAll:
- case NodeChildren:
- return e;
- case DocumentNamedItems:
- case OtherCollection:
- case WindowNamedItems:
- ASSERT_NOT_REACHED();
+ }
+ }
+
+ return false;
+}
+
+Element* HTMLCollection::itemAfter(Element* previous) const
+{
+ Node* current;
+ Node* base = m_base.get();
+ if (!previous)
+ current = base->firstChild();
+ else
+ current = nextNodeOrSibling(base, previous, m_includeChildren);
+
+ if (m_includeChildren) {
+ if (!m_info->lastDecendantOfBase)
+ m_info->lastDecendantOfBase = base->lastDescendantNode();
+
+ for (; current; current = current->traverseNextNodeFastPath()) {
+ if (current->isElementNode() && HTMLCollection::nodeMatchesDeep(static_cast<Element*>(current)))
+ return static_cast<Element*>(current);
+ if (current == m_info->lastDecendantOfBase)
break;
}
+ } else {
+ for (; current; current = current->traverseNextSibling(base)) {
+ if (!current->isElementNode())
+ continue;
+ if (HTMLCollection::nodeMatchesShallow(static_cast<Element*>(current)))
+ return static_cast<Element*>(current);
+ }
}
return 0;
diff --git a/Source/WebCore/html/HTMLCollection.h b/Source/WebCore/html/HTMLCollection.h
index 4359724..47449da 100644
--- a/Source/WebCore/html/HTMLCollection.h
+++ b/Source/WebCore/html/HTMLCollection.h
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 The Linux Foundation All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,7 @@
#define HTMLCollection_h
#include "CollectionType.h"
+#include "QualifiedName.h"
#include <wtf/RefCounted.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
@@ -72,11 +74,19 @@ private:
virtual Element* itemAfter(Element*) const;
virtual unsigned calcLength() const;
virtual void updateNameCache() const;
+ void init();
+ bool nodeMatchesDeep(Element*) const;
+ bool nodeMatchesShallow(Element*) const;
bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
+ enum MatchType { MatchNone, MatchTag, MatchCustom, MatchAll };
+ MatchType m_matchType;
+ QualifiedName m_matchTag;
+
RefPtr<Node> m_base;
CollectionType m_type;
+ bool m_includeChildren;
mutable CollectionCache* m_info;
mutable bool m_ownsInfo;
diff --git a/Source/WebCore/html/HTMLDataGridCellElement.cpp b/Source/WebCore/html/HTMLDataGridCellElement.cpp
index 9596d63..a0a5e13 100644
--- a/Source/WebCore/html/HTMLDataGridCellElement.cpp
+++ b/Source/WebCore/html/HTMLDataGridCellElement.cpp
@@ -38,6 +38,7 @@ using namespace HTMLNames;
inline HTMLDataGridCellElement::HTMLDataGridCellElement(const QualifiedName& name, Document* document)
: HTMLElement(name, document)
{
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLDataGridCellElement> HTMLDataGridCellElement::create(const QualifiedName& name, Document* document)
diff --git a/Source/WebCore/html/HTMLDataGridColElement.cpp b/Source/WebCore/html/HTMLDataGridColElement.cpp
index 196c7b6..c546ce9 100644
--- a/Source/WebCore/html/HTMLDataGridColElement.cpp
+++ b/Source/WebCore/html/HTMLDataGridColElement.cpp
@@ -42,6 +42,7 @@ inline HTMLDataGridColElement::HTMLDataGridColElement(const QualifiedName& name,
: HTMLElement(name, document)
, m_dataGrid(0)
{
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLDataGridColElement> HTMLDataGridColElement::create(const QualifiedName& name, Document* document)
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index 0aa9664..f8f2113 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -71,49 +71,6 @@ String HTMLElement::nodeName() const
return Element::nodeName();
}
-bool HTMLElement::ieForbidsInsertHTML() const
-{
- // FIXME: Supposedly IE disallows settting innerHTML, outerHTML
- // and createContextualFragment on these tags. We have no tests to
- // verify this however, so this list could be totally wrong.
- // This list was moved from the previous endTagRequirement() implementation.
- // This is also called from editing and assumed to be the list of tags
- // for which no end tag should be serialized. It's unclear if the list for
- // IE compat and the list for serialization sanity are the same.
- if (hasLocalName(areaTag)
- || hasLocalName(baseTag)
- || hasLocalName(basefontTag)
- || hasLocalName(brTag)
- || hasLocalName(colTag)
-#if ENABLE(DATAGRID)
- || hasLocalName(dcellTag)
- || hasLocalName(dcolTag)
-#endif
- || hasLocalName(embedTag)
- || hasLocalName(frameTag)
- || hasLocalName(hrTag)
- || hasLocalName(imageTag)
- || hasLocalName(imgTag)
- || hasLocalName(inputTag)
- || hasLocalName(isindexTag)
- || hasLocalName(linkTag)
- || hasLocalName(metaTag)
- || hasLocalName(paramTag)
- || hasLocalName(sourceTag)
- || hasLocalName(wbrTag))
- return true;
- // FIXME: I'm not sure why dashboard mode would want to change the
- // serialization of <canvas>, that seems like a bad idea.
-#if ENABLE(DASHBOARD_SUPPORT)
- if (hasLocalName(canvasTag)) {
- Settings* settings = document()->settings();
- if (settings && settings->usesDashboardBackwardCompatibilityMode())
- return true;
- }
-#endif
- return false;
-}
-
bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
if (attrName == alignAttr
@@ -786,8 +743,6 @@ bool HTMLElement::rendererIsNeeded(RenderStyle *style)
RenderObject* HTMLElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
- if (hasLocalName(wbrTag))
- return new (arena) RenderWordBreak(this);
return RenderObject::createObject(this, style);
}
diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h
index 5a5fdfb..6e0b8c5 100644
--- a/Source/WebCore/html/HTMLElement.h
+++ b/Source/WebCore/html/HTMLElement.h
@@ -70,8 +70,6 @@ public:
virtual void accessKeyAction(bool sendToAnyElement);
- bool ieForbidsInsertHTML() const;
-
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp
index 851deb8..b6ad707 100644
--- a/Source/WebCore/html/HTMLEmbedElement.cpp
+++ b/Source/WebCore/html/HTMLEmbedElement.cpp
@@ -49,6 +49,7 @@ inline HTMLEmbedElement::HTMLEmbedElement(const QualifiedName& tagName, Document
: HTMLPlugInImageElement(tagName, document, createdByParser, ShouldPreferPlugInsForImages)
{
ASSERT(hasTagName(embedTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
diff --git a/Source/WebCore/html/HTMLFrameElement.cpp b/Source/WebCore/html/HTMLFrameElement.cpp
index 71c8f3f..f5297da 100644
--- a/Source/WebCore/html/HTMLFrameElement.cpp
+++ b/Source/WebCore/html/HTMLFrameElement.cpp
@@ -41,6 +41,7 @@ inline HTMLFrameElement::HTMLFrameElement(const QualifiedName& tagName, Document
, m_noResize(false)
{
ASSERT(hasTagName(frameTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLFrameElement> HTMLFrameElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLHRElement.cpp b/Source/WebCore/html/HTMLHRElement.cpp
index 44aa052..4de829c 100644
--- a/Source/WebCore/html/HTMLHRElement.cpp
+++ b/Source/WebCore/html/HTMLHRElement.cpp
@@ -36,6 +36,7 @@ HTMLHRElement::HTMLHRElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
{
ASSERT(hasTagName(hrTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLHRElement> HTMLHRElement::create(Document* document)
diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp
index d66075e..836388f 100644
--- a/Source/WebCore/html/HTMLImageElement.cpp
+++ b/Source/WebCore/html/HTMLImageElement.cpp
@@ -51,6 +51,7 @@ HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* docum
ASSERT(hasTagName(imgTag));
if (form)
form->registerImgElement(this);
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document* document)
diff --git a/Source/WebCore/html/HTMLImageElement.idl b/Source/WebCore/html/HTMLImageElement.idl
index 935b721..c6a88ea 100644
--- a/Source/WebCore/html/HTMLImageElement.idl
+++ b/Source/WebCore/html/HTMLImageElement.idl
@@ -26,7 +26,8 @@ module html {
attribute [Reflect] DOMString name;
attribute [Reflect] DOMString align;
attribute [Reflect] DOMString alt;
- attribute [Reflect] DOMString border;
+ attribute [Reflect] DOMString border;
+ attribute [Reflect] DOMString crossOrigin;
attribute long height;
attribute [Reflect] long hspace;
attribute [Reflect] boolean isMap;
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 27b29a8..626fdc0 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -85,6 +85,7 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* docum
, m_inputType(InputType::createText(this))
{
ASSERT(hasTagName(inputTag) || hasTagName(isindexTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index 4673109..223fcf6 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -61,6 +61,7 @@ inline HTMLLinkElement::HTMLLinkElement(const QualifiedName& tagName, Document*
, m_pendingSheetType(None)
{
ASSERT(hasTagName(linkTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLLinkElement> HTMLLinkElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
@@ -74,10 +75,10 @@ HTMLLinkElement::~HTMLLinkElement()
m_sheet->clearOwnerNode();
if (m_cachedSheet) {
- m_cachedSheet->removeClient(this);
+ m_cachedSheet->removeClient(this);
removePendingSheet();
}
-
+
#if ENABLE(LINK_PREFETCH)
if (m_cachedLinkResource)
m_cachedLinkResource->removeClient(this);
@@ -164,6 +165,7 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
relAttribute.m_isDNSPrefetch = false;
#if ENABLE(LINK_PREFETCH)
relAttribute.m_isLinkPrefetch = false;
+ relAttribute.m_isLinkPrerender = false;
relAttribute.m_isLinkSubresource = false;
#endif
#ifdef ANDROID_APPLE_TOUCH_ICON
@@ -202,6 +204,8 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
#if ENABLE(LINK_PREFETCH)
else if (equalIgnoringCase(*it, "prefetch"))
relAttribute.m_isLinkPrefetch = true;
+ else if (equalIgnoringCase(*it, "prerender"))
+ relAttribute.m_isLinkPrerender = true;
else if (equalIgnoringCase(*it, "subresource"))
relAttribute.m_isLinkSubresource = true;
#endif
@@ -232,7 +236,7 @@ void HTMLLinkElement::process()
// IE extension: location of small icon for locationbar / bookmarks
// We'll record this URL per document, even if we later only use it in top level frames
if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) {
- if (!checkBeforeLoadEvent())
+ if (!checkBeforeLoadEvent())
return;
document()->setIconURL(m_url.string(), type);
}
@@ -254,28 +258,35 @@ void HTMLLinkElement::process()
}
#if ENABLE(LINK_PREFETCH)
- if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) {
+ if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkPrerender || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) {
if (!checkBeforeLoadEvent())
return;
ResourceLoadPriority priority = ResourceLoadPriorityUnresolved;
- if (m_relAttribute.m_isLinkSubresource)
+ CachedResource::Type type = CachedResource::LinkPrefetch;
+ // We only make one request to the cachedresourcelodaer if multiple rel types are
+ // specified.
+ if (m_relAttribute.m_isLinkSubresource) {
priority = ResourceLoadPriorityLow;
+ type = CachedResource::LinkSubresource;
+ } else if (m_relAttribute.m_isLinkPrerender)
+ type = CachedResource::LinkPrerender;
- m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(m_url, priority);
+ ResourceRequest linkRequest(document()->completeURL(m_url));
+ m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(type, linkRequest, priority);
if (m_cachedLinkResource)
m_cachedLinkResource->addClient(this);
}
#endif
bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet();
-
- if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css")))
+
+ if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css")))
&& document()->frame() && m_url.isValid()) {
-
+
String charset = getAttribute(charsetAttr);
if (charset.isEmpty() && document()->frame())
charset = document()->charset();
-
+
if (m_cachedSheet) {
removePendingSheet();
m_cachedSheet->removeClient(this);
@@ -302,8 +313,9 @@ void HTMLLinkElement::process()
// Load stylesheets that are not needed for the rendering immediately with low priority.
ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow;
- m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(m_url, charset, priority);
-
+ ResourceRequest request(document()->completeURL(m_url));
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset, priority);
+
if (m_cachedSheet)
m_cachedSheet->addClient(this);
else {
@@ -495,10 +507,10 @@ void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
if (!m_relAttribute.m_isStyleSheet)
return;
-
+
// Append the URL of this link element.
addSubresourceURL(urls, href());
-
+
// Walk the URLs linked by the linked-to stylesheet.
if (StyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet())
styleSheet->addSubresourceStyleURLs(urls);
diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h
index 1a6eba9..de726d9 100644
--- a/Source/WebCore/html/HTMLLinkElement.h
+++ b/Source/WebCore/html/HTMLLinkElement.h
@@ -48,6 +48,7 @@ public:
#endif
#if ENABLE(LINK_PREFETCH)
bool m_isLinkPrefetch;
+ bool m_isLinkPrerender;
bool m_isLinkSubresource;
#endif
@@ -58,6 +59,7 @@ public:
, m_isDNSPrefetch(false)
#if ENABLE(LINK_PREFETCH)
, m_isLinkPrefetch(false)
+ , m_isLinkPrerender(false)
, m_isLinkSubresource(false)
#endif
{
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index f3cc170..afd1727 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -89,16 +89,16 @@ using namespace std;
namespace WebCore {
#if !LOG_DISABLED
-static String urlForLogging(const String& url)
+static const char* urlForLogging(const KURL& url)
{
static const unsigned maximumURLLengthForLogging = 128;
- if (url.length() < maximumURLLengthForLogging)
- return url;
- return url.substring(0, maximumURLLengthForLogging) + "...";
+ if (url.string().length() < maximumURLLengthForLogging)
+ return url.string().utf8().data();
+ return String(url.string().substring(0, maximumURLLengthForLogging) + "...").utf8().data();
}
-static const char *boolString(bool val)
+static const char* boolString(bool val)
{
return val ? "true" : "false";
}
@@ -474,11 +474,6 @@ void HTMLMediaElement::setSrc(const String& url)
setAttribute(srcAttr, url);
}
-String HTMLMediaElement::currentSrc() const
-{
- return m_currentSrc;
-}
-
HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
{
return m_networkState;
@@ -698,7 +693,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
{
ASSERT(isSafeToLoadURL(initialURL, Complain));
- LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL.string()).utf8().data(), contentType.raw().utf8().data());
+ LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL), contentType.raw().utf8().data());
Frame* frame = document()->frame();
if (!frame)
@@ -716,7 +711,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
m_currentSrc = url;
- LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc).utf8().data());
+ LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc));
if (m_sendProgressEvents)
startProgressEventTimer();
@@ -736,7 +731,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
else
m_player->setMediaElementType(MediaPlayer::Audio);
#endif
- m_player->load(m_currentSrc, contentType);
+ m_player->load(m_currentSrc.string(), contentType);
// If there is no poster to display, allow the media engine to render video frames as soon as
// they are available.
@@ -749,7 +744,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction actionIfInvalid)
{
if (!url.isValid()) {
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url.string()).utf8().data());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url));
return false;
}
@@ -757,7 +752,7 @@ bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction acti
if (!frame || !document()->securityOrigin()->canDisplay(url)) {
if (actionIfInvalid == Complain)
FrameLoader::reportLocalLoadFailed(frame, url.string());
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url.string()).utf8().data());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url));
return false;
}
@@ -1766,7 +1761,7 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSo
mediaURL = source->getNonEmptyURLAttribute(srcAttr);
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLogging(mediaURL).utf8().data());
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLogging(mediaURL));
#endif
if (mediaURL.isEmpty())
goto check_again;
@@ -1817,7 +1812,7 @@ check_again:
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL.string()).utf8().data() : "");
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL) : "");
#endif
return canUse ? mediaURL : KURL();
}
@@ -1829,7 +1824,7 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
#if !LOG_DISABLED
if (source->hasTagName(sourceTag)) {
KURL url = source->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLogging(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLogging(url));
}
#endif
@@ -1876,7 +1871,7 @@ void HTMLMediaElement::sourceWillBeRemoved(HTMLSourceElement* source)
#if !LOG_DISABLED
if (source->hasTagName(sourceTag)) {
KURL url = source->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::sourceWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::sourceWillBeRemoved - 'src' is %s", urlForLogging(url));
}
#endif
@@ -2499,10 +2494,10 @@ void HTMLMediaElement::getPluginProxyParams(KURL& url, Vector<String>& names, Ve
if (!isSafeToLoadURL(url, Complain))
url = selectNextSourceChild(0, DoNothing);
- m_currentSrc = url.string();
- if (url.isValid() && loader && loader->willLoadMediaElementURL(url)) {
+ m_currentSrc = url;
+ if (url.isValid() && frame && frame->loader()->willLoadMediaElementURL(url)) {
names.append("_media_element_src_");
- values.append(m_currentSrc);
+ values.append(m_currentSrc.string());
}
}
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 0b11861..26f27bf 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -86,7 +86,7 @@ public:
// network state
void setSrc(const String&);
- String currentSrc() const;
+ const KURL& currentSrc() const { return m_currentSrc; }
enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
NetworkState networkState() const;
@@ -342,8 +342,8 @@ private:
NetworkState m_networkState;
ReadyState m_readyState;
ReadyState m_readyStateMaximum;
- String m_currentSrc;
-
+ KURL m_currentSrc;
+
RefPtr<MediaError> m_error;
float m_volume;
diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl
index c7e6b07..0bca569 100644
--- a/Source/WebCore/html/HTMLMediaElement.idl
+++ b/Source/WebCore/html/HTMLMediaElement.idl
@@ -31,7 +31,7 @@ interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement {
// network state
attribute [Reflect, URL] DOMString src;
- readonly attribute DOMString currentSrc;
+ readonly attribute [URL] DOMString currentSrc;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp
index 4f65065..3c3db44 100644
--- a/Source/WebCore/html/HTMLMetaElement.cpp
+++ b/Source/WebCore/html/HTMLMetaElement.cpp
@@ -40,6 +40,7 @@ inline HTMLMetaElement::HTMLMetaElement(const QualifiedName& tagName, Document*
: HTMLElement(tagName, document)
{
ASSERT(hasTagName(metaTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLParamElement.cpp b/Source/WebCore/html/HTMLParamElement.cpp
index 45a74b2..830c1ad 100644
--- a/Source/WebCore/html/HTMLParamElement.cpp
+++ b/Source/WebCore/html/HTMLParamElement.cpp
@@ -35,6 +35,7 @@ inline HTMLParamElement::HTMLParamElement(const QualifiedName& tagName, Document
: HTMLElement(tagName, document)
{
ASSERT(hasTagName(paramTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLParamElement> HTMLParamElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLSourceElement.cpp b/Source/WebCore/html/HTMLSourceElement.cpp
index 59b3882..ca683c2 100644
--- a/Source/WebCore/html/HTMLSourceElement.cpp
+++ b/Source/WebCore/html/HTMLSourceElement.cpp
@@ -47,6 +47,7 @@ inline HTMLSourceElement::HTMLSourceElement(const QualifiedName& tagName, Docume
{
LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
ASSERT(hasTagName(sourceTag));
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLSourceElement> HTMLSourceElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLTableColElement.cpp b/Source/WebCore/html/HTMLTableColElement.cpp
index 96af708..f7b8f2b 100644
--- a/Source/WebCore/html/HTMLTableColElement.cpp
+++ b/Source/WebCore/html/HTMLTableColElement.cpp
@@ -40,6 +40,7 @@ inline HTMLTableColElement::HTMLTableColElement(const QualifiedName& tagName, Do
: HTMLTablePartElement(tagName, document)
, m_span(1)
{
+ setIeForbidsInsertHTML();
}
PassRefPtr<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName& tagName, Document* document)
diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in
index 0bf4ff9..0de0632 100644
--- a/Source/WebCore/html/HTMLTagNames.in
+++ b/Source/WebCore/html/HTMLTagNames.in
@@ -132,7 +132,7 @@ u interfaceName=HTMLElement
ul interfaceName=HTMLUListElement
var interfaceName=HTMLElement
video wrapperOnlyIfMediaIsAvailable, conditional=VIDEO
-wbr interfaceName=HTMLElement
+wbr interfaceName=HTMLWbrElement, JSInterfaceName=HTMLElement
xmp interfaceName=HTMLPreElement
#if ENABLE_XHTMLMP
diff --git a/Source/WebCore/html/HTMLWbrElement.cpp b/Source/WebCore/html/HTMLWbrElement.cpp
new file mode 100644
index 0000000..4de25ac
--- /dev/null
+++ b/Source/WebCore/html/HTMLWbrElement.cpp
@@ -0,0 +1,62 @@
+/*
+* Copyright (C) 2012, The Linux Foundation All rights reserved.
+*
+* 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.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* 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 "HTMLWbrElement.h"
+
+#include "HTMLNames.h"
+#include "RenderWordBreak.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLWbrElement::HTMLWbrElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+{
+ ASSERT(hasTagName(wbrTag));
+ setIeForbidsInsertHTML();
+}
+
+PassRefPtr<HTMLWbrElement> HTMLWbrElement::create(Document* document)
+{
+ return adoptRef(new HTMLWbrElement(wbrTag, document));
+}
+
+PassRefPtr<HTMLWbrElement> HTMLWbrElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLWbrElement(tagName, document));
+}
+
+RenderObject* HTMLWbrElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ return new (arena) RenderWordBreak(this);
+}
+
+}
diff --git a/Source/WebCore/html/HTMLWbrElement.h b/Source/WebCore/html/HTMLWbrElement.h
new file mode 100644
index 0000000..fa6856e
--- /dev/null
+++ b/Source/WebCore/html/HTMLWbrElement.h
@@ -0,0 +1,50 @@
+/*
+* Copyright (C) 2012, The Linux Foundation All rights reserved.
+*
+* 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.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* 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 HTMLWbrElement_h
+#define HTMLWbrElement_h
+
+#include "HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLWbrElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLWbrElement> create(Document*);
+ static PassRefPtr<HTMLWbrElement> create(const QualifiedName&, Document*);
+
+private:
+ HTMLWbrElement(const QualifiedName&, Document*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+};
+
+} // namespace
+
+#endif
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.cpp b/Source/WebCore/html/canvas/ArrayBuffer.cpp
index 4f75cc3..9c072ed 100644
--- a/Source/WebCore/html/canvas/ArrayBuffer.cpp
+++ b/Source/WebCore/html/canvas/ArrayBuffer.cpp
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +32,16 @@
namespace WebCore {
+static int clampValue(int x, int left, int right)
+{
+ ASSERT(left <= right);
+ if (x < left)
+ x = left;
+ if (right < x)
+ x = right;
+ return x;
+}
+
PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned elementByteSize)
{
void* data = tryAllocate(numElements, elementByteSize);
@@ -43,7 +55,7 @@ PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBuffer* other)
return ArrayBuffer::create(other->data(), other->byteLength());
}
-PassRefPtr<ArrayBuffer> ArrayBuffer::create(void* source, unsigned byteLength)
+PassRefPtr<ArrayBuffer> ArrayBuffer::create(const void* source, unsigned byteLength)
{
void* data = tryAllocate(byteLength, 1);
if (!data)
@@ -74,6 +86,30 @@ unsigned ArrayBuffer::byteLength() const
return m_sizeInBytes;
}
+PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin, int end) const
+{
+ return sliceImpl(clampIndex(begin), clampIndex(end));
+}
+
+PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin) const
+{
+ return sliceImpl(clampIndex(begin), byteLength());
+}
+
+PassRefPtr<ArrayBuffer> ArrayBuffer::sliceImpl(unsigned begin, unsigned end) const
+{
+ unsigned size = begin <= end ? end - begin : 0;
+ return ArrayBuffer::create(static_cast<const char*>(data()) + begin, size);
+}
+
+unsigned ArrayBuffer::clampIndex(int index) const
+{
+ unsigned currentLength = byteLength();
+ if (index < 0)
+ index = currentLength + index;
+ return clampValue(index, 0, currentLength);
+}
+
ArrayBuffer::~ArrayBuffer()
{
WTF::fastFree(m_data);
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.h b/Source/WebCore/html/canvas/ArrayBuffer.h
index ff5e599..bd18306 100644
--- a/Source/WebCore/html/canvas/ArrayBuffer.h
+++ b/Source/WebCore/html/canvas/ArrayBuffer.h
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,18 +37,24 @@ class ArrayBuffer : public RefCounted<ArrayBuffer> {
public:
static PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned elementByteSize);
static PassRefPtr<ArrayBuffer> create(ArrayBuffer*);
- static PassRefPtr<ArrayBuffer> create(void* source, unsigned byteLength);
+ static PassRefPtr<ArrayBuffer> create(const void* source, unsigned byteLength);
void* data();
const void* data() const;
unsigned byteLength() const;
+ PassRefPtr<ArrayBuffer> slice(int begin, int end) const;
+ PassRefPtr<ArrayBuffer> slice(int begin) const;
+
~ArrayBuffer();
private:
ArrayBuffer(void* data, unsigned sizeInBytes);
ArrayBuffer(unsigned numElements, unsigned elementByteSize);
static void* tryAllocate(unsigned numElements, unsigned elementByteSize);
+ PassRefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const;
+ unsigned clampIndex(int index) const;
+
unsigned m_sizeInBytes;
void* m_data;
};
diff --git a/Source/WebCore/html/canvas/ArrayBuffer.idl b/Source/WebCore/html/canvas/ArrayBuffer.idl
index 6f63e65..bd4e77f 100644
--- a/Source/WebCore/html/canvas/ArrayBuffer.idl
+++ b/Source/WebCore/html/canvas/ArrayBuffer.idl
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +34,7 @@ module html {
V8CustomConstructor,
] ArrayBuffer {
readonly attribute int byteLength;
+ ArrayBuffer slice(in long begin, in [Optional] long end);
};
}
diff --git a/Source/WebCore/html/canvas/ArrayBufferView.h b/Source/WebCore/html/canvas/ArrayBufferView.h
index d06fc8d..39a4583 100644
--- a/Source/WebCore/html/canvas/ArrayBufferView.h
+++ b/Source/WebCore/html/canvas/ArrayBufferView.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,6 +42,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
public:
virtual bool isByteArray() const { return false; }
virtual bool isUnsignedByteArray() const { return false; }
+ virtual bool isUnsignedByteClampedArray() const { return false; }
virtual bool isShortArray() const { return false; }
virtual bool isUnsignedShortArray() const { return false; }
virtual bool isIntArray() const { return false; }
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
index c814c66..3622b06 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -51,48 +51,73 @@ void CanvasRenderingContext::deref()
m_canvas->deref();
}
-void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern)
+bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
{
if (canvas()->originClean() && pattern && !pattern->originClean())
- canvas()->setOriginTainted();
+ return true;
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
{
if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
- canvas()->setOriginTainted();
+ return true;
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
{
if (!image || !canvas()->originClean())
- return;
+ return false;
CachedImage* cachedImage = image->cachedImage();
- checkOrigin(cachedImage->response().url());
+ if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) {
+ if (wouldTaintOrigin(cachedImage->response().url()))
+ return true;
+ }
- if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ if (!cachedImage->image()->hasSingleSecurityOrigin())
+ return true;
+
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
{
#if ENABLE(VIDEO)
- checkOrigin(KURL(KURL(), video->currentSrc()));
- if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ // FIXME: This check is likely wrong when a redirect is involved. We need
+ // to test the finalURL. Please be careful when fixing this issue not to
+ // make currentSrc be the final URL because then the
+ // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
+ if (!video || !canvas()->originClean())
+ return false;
+
+ if (wouldTaintOrigin(video->currentSrc()))
+ return true;
+
+ if (!video->hasSingleSecurityOrigin())
+ return true;
#endif
+
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const KURL& url)
+bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
{
- if (!canvas()->originClean() || m_cleanOrigins.contains(url.string()))
- return;
+ if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
+ return false;
- if (canvas()->securityOrigin().taintsCanvas(url))
+ if (canvas()->securityOrigin()->taintsCanvas(url))
+ return true;
+
+ m_cleanURLs.add(url.string());
+ return false;
+}
+
+void CanvasRenderingContext::checkOrigin(const KURL& url)
+{
+ if (wouldTaintOrigin(url))
canvas()->setOriginTainted();
- else
- m_cleanOrigins.add(url.string());
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
index a143596..8426752 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -27,6 +27,7 @@
#define CanvasRenderingContext_h
#include "GraphicsLayer.h"
+#include "HTMLCanvasElement.h"
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
@@ -35,7 +36,6 @@
namespace WebCore {
class CanvasPattern;
-class HTMLCanvasElement;
class HTMLImageElement;
class HTMLVideoElement;
class KURL;
@@ -44,7 +44,6 @@ class WebGLObject;
class CanvasRenderingContext {
WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
public:
- CanvasRenderingContext(HTMLCanvasElement*);
virtual ~CanvasRenderingContext() { }
// Ref and deref the m_canvas
@@ -65,15 +64,23 @@ public:
#endif
protected:
- void checkOrigin(const CanvasPattern*);
- void checkOrigin(const HTMLCanvasElement*);
- void checkOrigin(const HTMLImageElement*);
- void checkOrigin(const HTMLVideoElement*);
+ CanvasRenderingContext(HTMLCanvasElement*);
+ bool wouldTaintOrigin(const CanvasPattern*);
+ bool wouldTaintOrigin(const HTMLCanvasElement*);
+ bool wouldTaintOrigin(const HTMLImageElement*);
+ bool wouldTaintOrigin(const HTMLVideoElement*);
+ bool wouldTaintOrigin(const KURL&);
+
+ template<class T> void checkOrigin(const T* arg)
+ {
+ if (wouldTaintOrigin(arg))
+ canvas()->setOriginTainted();
+ }
void checkOrigin(const KURL&);
private:
HTMLCanvasElement* m_canvas;
- HashSet<String> m_cleanOrigins;
+ HashSet<String> m_cleanURLs;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 2051750..6261c2c 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -84,6 +84,14 @@ using namespace HTMLNames;
static const char* const defaultFont = "10px sans-serif";
+static bool isOriginClean(CachedImage* cachedImage, SecurityOrigin* securityOrigin)
+{
+ if (!cachedImage->image()->hasSingleSecurityOrigin())
+ return false;
+ if (cachedImage->passesAccessControlCheck(securityOrigin))
+ return true;
+ return !securityOrigin->taintsCanvas(cachedImage->response().url());
+}
class CanvasStrokeStyleApplier : public StrokeStyleApplier {
public:
@@ -1525,7 +1533,7 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme
if (!cachedImage || !image->cachedImage()->image())
return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
- bool originClean = !canvas()->securityOrigin().taintsCanvas(KURL(KURL(), cachedImage->response().url())) && cachedImage->image()->hasSingleSecurityOrigin();
+ bool originClean = isOriginClean(cachedImage, canvas()->securityOrigin());
return CanvasPattern::create(cachedImage->image(), repeatX, repeatY, originClean);
}
diff --git a/Source/WebCore/html/canvas/Uint8Array.h b/Source/WebCore/html/canvas/Uint8Array.h
index 3da1eaa..1cbd5b4 100644
--- a/Source/WebCore/html/canvas/Uint8Array.h
+++ b/Source/WebCore/html/canvas/Uint8Array.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,7 +47,7 @@ public:
PassRefPtr<Uint8Array> subarray(int start) const;
PassRefPtr<Uint8Array> subarray(int start, int end) const;
-private:
+protected:
Uint8Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
diff --git a/Source/WebCore/html/canvas/Uint8ClampedArray.cpp b/Source/WebCore/html/canvas/Uint8ClampedArray.cpp
new file mode 100644
index 0000000..32828d1
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8ClampedArray.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB.
+ *
+ * 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 "Uint8ClampedArray.h"
+
+namespace WebCore {
+
+PassRefPtr<Uint8ClampedArray> Uint8ClampedArray::create(unsigned length)
+{
+ return TypedArrayBase<unsigned char>::create<Uint8ClampedArray>(length);
+}
+
+PassRefPtr<Uint8ClampedArray> Uint8ClampedArray::create(unsigned char* array, unsigned length)
+{
+ return TypedArrayBase<unsigned char>::create<Uint8ClampedArray>(array, length);
+}
+
+PassRefPtr<Uint8ClampedArray> Uint8ClampedArray::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+{
+ return TypedArrayBase<unsigned char>::create<Uint8ClampedArray>(buffer, byteOffset, length);
+}
+
+void Uint8ClampedArray::set(unsigned index, double value)
+{
+ if (index >= m_length)
+ return;
+ if (isnan(value) || value < 0)
+ value = 0;
+ else if (value > 255)
+ value = 255;
+ data()[index] = static_cast<unsigned char>(value + 0.5);
+}
+
+Uint8ClampedArray::Uint8ClampedArray(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
+ : Uint8Array(buffer, byteOffset, length)
+{
+}
+
+PassRefPtr<Uint8ClampedArray> Uint8ClampedArray::subarray(int start) const
+{
+ return subarray(start, length());
+}
+
+PassRefPtr<Uint8ClampedArray> Uint8ClampedArray::subarray(int start, int end) const
+{
+ return subarrayImpl<Uint8ClampedArray>(start, end);
+}
+}
diff --git a/Source/WebCore/html/canvas/Uint8ClampedArray.h b/Source/WebCore/html/canvas/Uint8ClampedArray.h
new file mode 100644
index 0000000..79757d8
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8ClampedArray.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB.
+ *
+ * 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 Uint8ClampedArray_h
+#define Uint8ClampedArray_h
+
+#include "IntegralTypedArrayBase.h"
+#include "Uint8Array.h"
+
+namespace WebCore {
+
+class ArrayBuffer;
+
+class Uint8ClampedArray : public Uint8Array {
+public:
+ static PassRefPtr<Uint8ClampedArray> create(unsigned length);
+ static PassRefPtr<Uint8ClampedArray> create(unsigned char* array, unsigned length);
+ static PassRefPtr<Uint8ClampedArray> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
+
+ // Can't use "using" here due to a bug in the RVCT compiler.
+ void set(TypedArrayBase<unsigned char>* array, unsigned offset, ExceptionCode& ec) { TypedArrayBase<unsigned char>::set(array, offset, ec); }
+ void set(unsigned index, double value);
+
+ PassRefPtr<Uint8ClampedArray> subarray(int start) const;
+ PassRefPtr<Uint8ClampedArray> subarray(int start, int end) const;
+
+private:
+ Uint8ClampedArray(PassRefPtr<ArrayBuffer> buffer,
+ unsigned byteOffset,
+ unsigned length);
+ // Make constructor visible to superclass.
+ friend class TypedArrayBase<unsigned char>;
+
+ // Overridden from ArrayBufferView.
+ virtual bool isUnsignedByteClampedArray() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // Uint8Array_h
diff --git a/Source/WebCore/html/canvas/Uint8ClampedArray.idl b/Source/WebCore/html/canvas/Uint8ClampedArray.idl
new file mode 100644
index 0000000..5c5513a
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8ClampedArray.idl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB.
+ *
+ * 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
+ ] Uint8ClampedArray : Uint8Array {
+ const unsigned int BYTES_PER_ELEMENT = 1;
+
+ readonly attribute unsigned long length;
+ Uint8ClampedArray subarray(in long start, in [Optional] long end);
+
+ // void set(in Uint8ClampedArray 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/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
index 4b721eb..3c1c718 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,12 +36,47 @@ namespace WebCore {
namespace {
- // This function is only for depth/stencil/depth_stencil attachment.
- // Currently we assume these attachments are all renderbuffers.
- GC3Denum getInternalFormat(WebGLObject* buffer)
+ bool isAttachmentComplete(WebGLObject* attachedObject, GC3Denum attachment)
{
- ASSERT(buffer && buffer->isRenderbuffer());
- return (reinterpret_cast<WebGLRenderbuffer*>(buffer))->getInternalFormat();
+ ASSERT(attachedObject && attachedObject->object());
+ ASSERT(attachedObject->isRenderbuffer());
+ WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
+ return false;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
+ return false;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
+ return false;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ if (!buffer->getWidth() || !buffer->getHeight())
+ return false;
+ return true;
+ }
+
+ GC3Dsizei getImageWidth(WebGLObject* attachedObject)
+ {
+ ASSERT(attachedObject && attachedObject->object());
+ ASSERT(attachedObject->isRenderbuffer());
+ WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
+ return buffer->getWidth();
+ }
+
+ GC3Dsizei getImageHeight(WebGLObject* attachedObject)
+ {
+ ASSERT(attachedObject && attachedObject->object());
+ ASSERT(attachedObject->isRenderbuffer());
+ WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
+ return buffer->getHeight();
}
bool isUninitialized(WebGLObject* attachedObject)
@@ -82,10 +118,12 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
setObject(context()->graphicsContext3D()->createFramebuffer());
}
-void WebGLFramebuffer::setAttachment(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
{
+ ASSERT(isBound());
if (!object())
return;
+ removeAttachmentFromBoundFramebuffer(attachment);
if (texture && !texture->object())
texture = 0;
switch (attachment) {
@@ -106,14 +144,19 @@ void WebGLFramebuffer::setAttachment(GC3Denum attachment, GC3Denum texTarget, We
m_depthStencilAttachment = texture;
break;
default:
- return;
+ ASSERT_NOT_REACHED();
+ break;
}
+ if (texture)
+ texture->onAttached();
}
-void WebGLFramebuffer::setAttachment(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
{
+ ASSERT(isBound());
if (!object())
return;
+ removeAttachmentFromBoundFramebuffer(attachment);
if (renderbuffer && !renderbuffer->object())
renderbuffer = 0;
switch (attachment) {
@@ -130,8 +173,11 @@ void WebGLFramebuffer::setAttachment(GC3Denum attachment, WebGLRenderbuffer* ren
m_depthStencilAttachment = renderbuffer;
break;
default:
- return;
+ ASSERT_NOT_REACHED();
+ break;
}
+ if (renderbuffer)
+ renderbuffer->onAttached();
}
WebGLObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
@@ -148,24 +194,78 @@ WebGLObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
return m_depthStencilAttachment.get();
default:
+ ASSERT_NOT_REACHED();
return 0;
}
}
-void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
{
+ ASSERT(isBound());
if (!object())
return;
- if (attachment == m_colorAttachment.get())
- m_colorAttachment = 0;
- else if (attachment == m_depthAttachment.get())
- m_depthAttachment = 0;
- else if (attachment == m_stencilAttachment.get())
- m_stencilAttachment = 0;
- else if (attachment == m_depthStencilAttachment.get())
- m_depthStencilAttachment = 0;
- else
+
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ if (m_colorAttachment) {
+ m_colorAttachment->onDetached();
+ m_colorAttachment = 0;
+ m_texTarget = 0;
+ m_texLevel = -1;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ if (m_depthAttachment) {
+ m_depthAttachment->onDetached();
+ m_depthAttachment = 0;
+ }
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ if (m_stencilAttachment) {
+ m_stencilAttachment->onDetached();
+ m_stencilAttachment = 0;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ if (m_depthStencilAttachment) {
+ m_depthStencilAttachment->onDetached();
+ m_depthStencilAttachment = 0;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLObject* attachment)
+{
+ ASSERT(isBound());
+ if (!object())
+ return;
+ if (!attachment)
return;
+ GraphicsContext3D* gc3d = context()->graphicsContext3D();
+ if (attachment == m_colorAttachment.get()) {
+ if (attachment->isRenderbuffer())
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, 0);
+ else
+ gc3d->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, m_texTarget, 0, m_texLevel);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::COLOR_ATTACHMENT0);
+ }
+ if (attachment == m_depthAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::DEPTH_ATTACHMENT);
+ }
+ if (attachment == m_stencilAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::STENCIL_ATTACHMENT);
+ }
+ if (attachment == m_depthStencilAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT);
+ }
}
GC3Dsizei WebGLFramebuffer::getWidth() const
@@ -213,34 +313,67 @@ GC3Denum WebGLFramebuffer::getColorBufferFormat() const
return 0;
}
-bool WebGLFramebuffer::isIncomplete(bool checkInternalFormat) const
+GC3Denum WebGLFramebuffer::checkStatus() const
{
unsigned int count = 0;
+ GC3Dsizei width = 0, height = 0;
if (isDepthAttached()) {
- if (checkInternalFormat && getInternalFormat(m_depthAttachment.get()) != GraphicsContext3D::DEPTH_COMPONENT16)
- return true;
+ if (!isAttachmentComplete(m_depthAttachment.get(), GraphicsContext3D::DEPTH_ATTACHMENT))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ width = getImageWidth(m_depthAttachment.get());
+ height = getImageHeight(m_depthAttachment.get());
count++;
}
if (isStencilAttached()) {
- if (checkInternalFormat && getInternalFormat(m_stencilAttachment.get()) != GraphicsContext3D::STENCIL_INDEX8)
- return true;
+ if (!isAttachmentComplete(m_stencilAttachment.get(), GraphicsContext3D::STENCIL_ATTACHMENT))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ if (!count) {
+ width = getImageWidth(m_stencilAttachment.get());
+ height = getImageHeight(m_stencilAttachment.get());
+ } else {
+ if (width != getImageWidth(m_stencilAttachment.get()) || height != getImageHeight(m_stencilAttachment.get()))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
count++;
}
if (isDepthStencilAttached()) {
- if (checkInternalFormat && getInternalFormat(m_depthStencilAttachment.get()) != GraphicsContext3D::DEPTH_STENCIL)
- return true;
+ if (!isAttachmentComplete(m_depthStencilAttachment.get(), GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
if (!isValid(m_depthStencilAttachment.get()))
- return true;
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (!count) {
+ width = getImageWidth(m_depthStencilAttachment.get());
+ height = getImageHeight(m_depthStencilAttachment.get());
+ } else {
+ if (width != getImageWidth(m_depthStencilAttachment.get()) || height != getImageHeight(m_depthStencilAttachment.get()))
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
count++;
}
+ // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments.
if (count > 1)
- return true;
- return false;
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+ if (isColorAttached()) {
+ // FIXME: if color buffer is texture, is ALPHA, LUMINANCE or LUMINANCE_ALPHA valid?
+ if (!getColorBufferFormat())
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ if (!count) {
+ if (!getWidth() || !getHeight())
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ } else {
+ if (width != getWidth() || height != getHeight())
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+ } else {
+ if (!count)
+ return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ }
+ return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
}
bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
{
- if (isIncomplete(true))
+ if (checkStatus() != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
return false;
if (needToInitializeRenderbuffers)
return initializeRenderbuffers();
@@ -249,11 +382,15 @@ bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
{
+ if (m_colorAttachment)
+ m_colorAttachment->onDetached();
+ if (m_depthAttachment)
+ m_depthAttachment->onDetached();
+ if (m_stencilAttachment)
+ m_stencilAttachment->onDetached();
+ if (m_depthStencilAttachment)
+ m_depthStencilAttachment->onDetached();
context()->graphicsContext3D()->deleteFramebuffer(object);
- m_colorAttachment = 0;
- m_depthAttachment = 0;
- m_stencilAttachment = 0;
- m_depthStencilAttachment = 0;
}
bool WebGLFramebuffer::initializeRenderbuffers()
@@ -352,6 +489,11 @@ bool WebGLFramebuffer::initializeRenderbuffers()
return true;
}
+bool WebGLFramebuffer::isBound() const
+{
+ return (context()->m_framebufferBinding.get() == this);
+}
+
}
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
index a1cb86f..b03ec58 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,10 +43,12 @@ public:
static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
- void setAttachment(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
- void setAttachment(GC3Denum attachment, WebGLRenderbuffer*);
- // If an object is attached to the framebuffer, remove it.
- void removeAttachment(WebGLObject*);
+ void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
+ void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
+ // If an object is attached to the currently bound framebuffer, remove it.
+ void removeAttachmentFromBoundFramebuffer(WebGLObject*);
+ // If a given attachment point for the currently bound framebuffer is not null, remove the attached object.
+ void removeAttachmentFromBoundFramebuffer(GC3Denum);
WebGLObject* getAttachment(GC3Denum) const;
GC3Denum getColorBufferFormat() const;
@@ -60,8 +63,11 @@ public:
// needToInitializeRenderbuffers is true.
bool onAccess(bool needToInitializeRenderbuffers);
- // Return false does not mean COMPLETE, might still be INCOMPLETE.
- bool isIncomplete(bool checkInternalFormat) const;
+ // Software version of glCheckFramebufferStatus(), except that when
+ // FRAMEBUFFER_COMPLETE is returned, it is still possible for
+ // glCheckFramebufferStatus() to return FRAMEBUFFER_UNSUPPORTED,
+ // depending on hardware implementation.
+ GC3Denum checkStatus() const;
bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
@@ -78,6 +84,9 @@ private:
// Return false if framebuffer is incomplete.
bool initializeRenderbuffers();
+ // Check if the framebuffer is currently bound.
+ bool isBound() const;
+
bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); }
bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
index 17be974..5faec15 100644
--- a/Source/WebCore/html/canvas/WebGLGetInfo.cpp
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All Rights Reserved.
* Copyright (C) 2009 Google Inc. All Rights Reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -135,6 +136,16 @@ WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value)
{
}
+WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint32Array> value)
+ : m_type(kTypeWebGLUnsignedIntArray)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
+ , m_webglUnsignedIntArray(value)
+{
+}
+
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value)
: m_type(kTypeWebGLVertexArrayObjectOES)
, m_webglVertexArrayObject(value)
@@ -234,6 +245,12 @@ PassRefPtr<Uint8Array> WebGLGetInfo::getWebGLUnsignedByteArray() const
return m_webglUnsignedByteArray;
}
+PassRefPtr<Uint32Array> WebGLGetInfo::getWebGLUnsignedIntArray() const
+{
+ ASSERT(getType() == kTypeWebGLUnsignedIntArray);
+ return m_webglUnsignedIntArray;
+}
+
PassRefPtr<WebGLVertexArrayObjectOES> WebGLGetInfo::getWebGLVertexArrayObjectOES() const
{
ASSERT(getType() == kTypeWebGLVertexArrayObjectOES);
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.h b/Source/WebCore/html/canvas/WebGLGetInfo.h
index bc2aacc..0303399 100644
--- a/Source/WebCore/html/canvas/WebGLGetInfo.h
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All Rights Reserved.
* Copyright (C) 2009 Google Inc. All Rights Reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +32,7 @@
#include "Int32Array.h"
#include "PlatformString.h"
#include "Uint8Array.h"
+#include "Uint32Array.h"
#include "WebGLBuffer.h"
#include "WebGLFramebuffer.h"
#include "WebGLProgram.h"
@@ -67,6 +69,7 @@ public:
kTypeWebGLRenderbuffer,
kTypeWebGLTexture,
kTypeWebGLUnsignedByteArray,
+ kTypeWebGLUnsignedIntArray,
kTypeWebGLVertexArrayObjectOES,
};
@@ -88,6 +91,7 @@ public:
WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value);
WebGLGetInfo(PassRefPtr<WebGLTexture> value);
WebGLGetInfo(PassRefPtr<Uint8Array> value);
+ WebGLGetInfo(PassRefPtr<Uint32Array> value);
WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value);
virtual ~WebGLGetInfo();
@@ -110,6 +114,7 @@ public:
PassRefPtr<WebGLRenderbuffer> getWebGLRenderbuffer() const;
PassRefPtr<WebGLTexture> getWebGLTexture() const;
PassRefPtr<Uint8Array> getWebGLUnsignedByteArray() const;
+ PassRefPtr<Uint32Array> getWebGLUnsignedIntArray() const;
PassRefPtr<WebGLVertexArrayObjectOES> getWebGLVertexArrayObjectOES() const;
private:
@@ -130,6 +135,7 @@ private:
RefPtr<WebGLRenderbuffer> m_webglRenderbuffer;
RefPtr<WebGLTexture> m_webglTexture;
RefPtr<Uint8Array> m_webglUnsignedByteArray;
+ RefPtr<Uint32Array> m_webglUnsignedIntArray;
RefPtr<WebGLVertexArrayObjectOES> m_webglVertexArrayObject;
};
diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp
index d47013e..7b629a6 100644
--- a/Source/WebCore/html/canvas/WebGLObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLObject.cpp
@@ -66,6 +66,16 @@ void WebGLObject::deleteObject()
}
}
+void WebGLObject::detachContext()
+{
+ m_attachmentCount = 0; // Make sure OpenGL resource is deleted.
+ if (m_context) {
+ deleteObject();
+ m_context->removeObject(this);
+ m_context = 0;
+ }
+}
+
}
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLObject.h b/Source/WebCore/html/canvas/WebGLObject.h
index 3bb9f29..44cc36f 100644
--- a/Source/WebCore/html/canvas/WebGLObject.h
+++ b/Source/WebCore/html/canvas/WebGLObject.h
@@ -46,12 +46,7 @@ public:
// FIXME: revisit this when resource sharing between contexts are implemented.
void deleteObject();
- void detachContext()
- {
- m_attachmentCount = 0; // Make sure OpenGL resource is deleted.
- deleteObject();
- m_context = 0;
- }
+ void detachContext();
WebGLRenderingContext* context() const { return m_context; }
diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp
index d3efda4..ec99dc4 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.cpp
+++ b/Source/WebCore/html/canvas/WebGLProgram.cpp
@@ -42,6 +42,7 @@ WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
: WebGLObject(ctx)
, m_linkStatus(false)
, m_linkCount(0)
+ , m_infoValid(true)
{
setObject(context()->graphicsContext3D()->createProgram());
}
@@ -59,43 +60,23 @@ void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
}
}
-bool WebGLProgram::cacheActiveAttribLocations()
-{
- m_activeAttribLocations.clear();
- if (!object())
- return false;
- GraphicsContext3D* context3d = context()->graphicsContext3D();
-
- // Assume link status has already been cached.
- if (!m_linkStatus)
- return false;
-
- GC3Dint numAttribs = 0;
- context3d->getProgramiv(object(), GraphicsContext3D::ACTIVE_ATTRIBUTES, &numAttribs);
- m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
- for (int i = 0; i < numAttribs; ++i) {
- ActiveInfo info;
- context3d->getActiveAttrib(object(), i, info);
- m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.charactersWithNullTermination());
- }
-
- return true;
-}
-
-unsigned WebGLProgram::numActiveAttribLocations() const
+unsigned WebGLProgram::numActiveAttribLocations()
{
+ cacheInfoIfNeeded();
return m_activeAttribLocations.size();
}
-GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index) const
+GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index)
{
+ cacheInfoIfNeeded();
if (index >= numActiveAttribLocations())
return -1;
return m_activeAttribLocations[index];
}
-bool WebGLProgram::isUsingVertexAttrib0() const
+bool WebGLProgram::isUsingVertexAttrib0()
{
+ cacheInfoIfNeeded();
for (unsigned ii = 0; ii < numActiveAttribLocations(); ++ii) {
if (!getActiveAttribLocation(ii))
return true;
@@ -103,6 +84,24 @@ bool WebGLProgram::isUsingVertexAttrib0() const
return false;
}
+bool WebGLProgram::getLinkStatus()
+{
+ cacheInfoIfNeeded();
+ return m_linkStatus;
+}
+
+void WebGLProgram::setLinkStatus(bool status)
+{
+ cacheInfoIfNeeded();
+ m_linkStatus = status;
+}
+
+void WebGLProgram::increaseLinkCount()
+{
+ ++m_linkCount;
+ m_infoValid = false;
+}
+
WebGLShader* WebGLProgram::getAttachedShader(GC3Denum type)
{
switch (type) {
@@ -155,6 +154,39 @@ bool WebGLProgram::detachShader(WebGLShader* shader)
}
}
+void WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
+{
+ m_activeAttribLocations.clear();
+
+ GC3Dint numAttribs = 0;
+ context3d->getProgramiv(object(), GraphicsContext3D::ACTIVE_ATTRIBUTES, &numAttribs);
+ m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
+ for (int i = 0; i < numAttribs; ++i) {
+ ActiveInfo info;
+ context3d->getActiveAttrib(object(), i, info);
+ m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.charactersWithNullTermination());
+ }
+}
+
+void WebGLProgram::cacheInfoIfNeeded()
+{
+ if (m_infoValid)
+ return;
+
+ if (!object())
+ return;
+
+ GraphicsContext3D* ctx = context()->graphicsContext3D();
+ if (!ctx)
+ return;
+ GC3Dint linkStatus = 0;
+ ctx->getProgramiv(object(), GraphicsContext3D::LINK_STATUS, &linkStatus);
+ m_linkStatus = linkStatus;
+ if (m_linkStatus)
+ cacheActiveAttribLocations(ctx);
+ m_infoValid = true;
+}
+
}
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h
index 0dd3ba0..13a5bdd 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.h
+++ b/Source/WebCore/html/canvas/WebGLProgram.h
@@ -42,23 +42,21 @@ public:
static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
- // cacheActiveAttribLocation() is only called once after linkProgram()
- // succeeds.
- bool cacheActiveAttribLocations();
- unsigned numActiveAttribLocations() const;
- GC3Dint getActiveAttribLocation(GC3Duint index) const;
+ unsigned numActiveAttribLocations();
+ GC3Dint getActiveAttribLocation(GC3Duint index);
- bool isUsingVertexAttrib0() const;
+ bool isUsingVertexAttrib0();
- bool getLinkStatus() const { return m_linkStatus; }
- void setLinkStatus(bool status) { m_linkStatus = status; }
+ bool getLinkStatus();
+ void setLinkStatus(bool);
unsigned getLinkCount() const { return m_linkCount; }
// This is to be called everytime after the program is successfully linked.
// We don't deal with integer overflow here, assuming in reality a program
// will never be linked so many times.
- void increaseLinkCount() { ++m_linkCount; }
+ // Also, we invalidate the cached program info.
+ void increaseLinkCount();
WebGLShader* getAttachedShader(GC3Denum);
bool attachShader(WebGLShader*);
@@ -72,6 +70,9 @@ protected:
private:
virtual bool isProgram() const { return true; }
+ void cacheActiveAttribLocations(GraphicsContext3D*);
+ void cacheInfoIfNeeded();
+
Vector<GC3Dint> m_activeAttribLocations;
GC3Dint m_linkStatus;
@@ -82,6 +83,8 @@ private:
RefPtr<WebGLShader> m_vertexShader;
RefPtr<WebGLShader> m_fragmentShader;
+
+ bool m_infoValid;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 933d37f..7e7bfe3 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,6 +53,7 @@
#include "RenderLayer.h"
#include "Settings.h"
#include "Uint16Array.h"
+#include "Uint32Array.h"
#include "WebGLActiveInfo.h"
#include "WebGLBuffer.h"
#include "WebGLContextAttributes.h"
@@ -328,29 +331,14 @@ private:
void WebGLRenderingContext::WebGLRenderingContextRestoreTimer::fired()
{
- // Timer is started when m_contextLost is false. It will first call
- // onLostContext, which will set m_contextLost to true. Then it will keep
- // calling restoreContext and reschedule itself until m_contextLost is back
- // to false.
- if (!m_context->m_contextLost) {
- m_context->onLostContext();
- startOneShot(secondsBetweenRestoreAttempts);
- } else {
- // The rendering context is not restored if there is no handler for
- // the context restored event.
- if (!m_context->canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent))
- return;
-
- m_context->restoreContext();
- if (m_context->m_contextLost)
- startOneShot(secondsBetweenRestoreAttempts);
- }
+ m_context->maybeRestoreContext(RealLostContext);
}
class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
public:
WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_contextLostCallback(cb) {}
- virtual void onContextLost() { m_contextLostCallback->forceLostContext(); }
+ virtual void onContextLost() {
+ m_contextLostCallback->forceLostContext(WebGLRenderingContext::RealLostContext); }
virtual ~WebGLRenderingContextLostCallback() {}
private:
WebGLRenderingContext* m_contextLostCallback;
@@ -367,7 +355,11 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
attributes.antialias = false;
}
+#if PLATFORM(ANDROID)
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(canvas, attributes, 0));
+#else
RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes, hostWindow));
+#endif
if (!context) {
canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
@@ -381,6 +373,7 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
GraphicsContext3D::Attributes attributes)
: CanvasRenderingContext(passedCanvas)
, m_context(context)
+ , m_restoreAllowed(false)
, m_restoreTimer(this)
, m_videoCache(4)
, m_contextLost(false)
@@ -554,9 +547,10 @@ void WebGLRenderingContext::paintRenderingResultsToCanvas()
{
// Until the canvas is written to by the application, the clear that
// happened after it was composited should be ignored by the compositor.
- if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer)
+ if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
+ m_context->paintCompositedResultsToCanvas(this);
canvas()->makePresentationCopy();
- else
+ } else
canvas()->clearPresentationCopy();
clearIfComposited();
if (!m_markedCanvasDirty && !m_layerCleared)
@@ -577,6 +571,18 @@ bool WebGLRenderingContext::paintsIntoCanvasBuffer() const
return m_context->paintsIntoCanvasBuffer();
}
+#if PLATFORM(ANDROID)
+void WebGLRenderingContext::recreateSurface()
+{
+ m_context->recreateSurface();
+}
+
+void WebGLRenderingContext::releaseSurface()
+{
+ m_context->releaseSurface();
+}
+#endif
+
void WebGLRenderingContext::reshape(int width, int height)
{
if (m_needsUpdate) {
@@ -593,6 +599,20 @@ void WebGLRenderingContext::reshape(int width, int height)
m_context->reshape(width, height);
}
+GC3Dsizei WebGLRenderingContext::drawingBufferWidth()
+{
+ if (isContextLost())
+ return 0;
+ return m_context->getInternalFramebufferSize().width();
+}
+
+GC3Dsizei WebGLRenderingContext::drawingBufferHeight()
+{
+ if (isContextLost())
+ return 0;
+ return m_context->getInternalFramebufferSize().height();
+}
+
unsigned int WebGLRenderingContext::sizeInBytes(GC3Denum type)
{
switch (type) {
@@ -648,6 +668,8 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint i
UNUSED_PARAM(ec);
if (isContextLost() || !validateWebGLObject(program))
return;
+ if (!validateLocationLength(name))
+ return;
if (!validateString(name))
return;
m_context->bindAttribLocation(objectOrZero(program), index, name);
@@ -814,7 +836,7 @@ void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB,
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage, ExceptionCode& ec)
+void WebGLRenderingContext::bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
if (isContextLost())
@@ -827,13 +849,13 @@ void WebGLRenderingContext::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3De
return;
}
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferData(size)) {
+ if (!buffer->associateBufferData(static_cast<GC3Dsizeiptr>(size))) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
}
- m_context->bufferData(target, size, usage);
+ m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
cleanupAfterGraphicsCall(false);
}
@@ -856,7 +878,9 @@ void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3De
}
}
- m_context->bufferData(target, data->byteLength(), data->data(), usage);
+ // Some platforms incorrectly signal GL_OUT_OF_MEMORY if size == 0
+ if (data->byteLength() > 0)
+ m_context->bufferData(target, data->byteLength(), data->data(), usage);
cleanupAfterGraphicsCall(false);
}
@@ -879,11 +903,13 @@ void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, G
}
}
- m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
+ // Some platforms incorrectly signal GL_OUT_OF_MEMORY if size == 0
+ if (data->byteLength() > 0)
+ m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, ArrayBuffer* data, ExceptionCode& ec)
+void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
if (isContextLost())
@@ -898,17 +924,17 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar
if (!data)
return;
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferSubData(offset, data)) {
+ if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
}
- m_context->bufferSubData(target, offset, data->byteLength(), data->data());
+ m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, ArrayBufferView* data, ExceptionCode& ec)
+void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
if (isContextLost())
@@ -923,13 +949,13 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar
if (!data)
return;
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
- if (!buffer->associateBufferSubData(offset, data)) {
+ if (!buffer->associateBufferSubData(static_cast<GC3Dintptr>(offset), data)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
}
- m_context->bufferSubData(target, offset, data->byteLength(), data->baseAddress());
+ m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->baseAddress());
cleanupAfterGraphicsCall(false);
}
@@ -943,9 +969,10 @@ GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
}
if (!m_framebufferBinding || !m_framebufferBinding->object())
return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
- if (m_framebufferBinding->isIncomplete(true))
- return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
- unsigned long result = m_context->checkFramebufferStatus(target);
+ GC3Denum result = m_framebufferBinding->checkStatus();
+ if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+ return result;
+ result = m_context->checkFramebufferStatus(target);
cleanupAfterGraphicsCall(false);
return result;
}
@@ -1026,6 +1053,34 @@ void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec
cleanupAfterGraphicsCall(false);
}
+void WebGLRenderingContext::compressedTexImage2D(GC3Denum target, GC3Dint level,
+ GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border,
+ ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel(target, level))
+ return;
+
+ // Currently, we have no support for compressed textures:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+}
+
+void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum target, GC3Dint level,
+ GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel(target, level))
+ return;
+
+ // Currently, we have no support for compressed textures:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+}
+
void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
{
if (isContextLost())
@@ -1048,8 +1103,10 @@ void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3De
return;
}
clearIfComposited();
- if (isResourceSafe())
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ if (isResourceSafe()) {
+ if (width > 0 && height > 0)
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ }
else {
GC3Dint clippedX, clippedY;
GC3Dsizei clippedWidth, clippedHeight;
@@ -1060,8 +1117,11 @@ void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3De
m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
clippedX, clippedY, clippedWidth, clippedHeight);
}
- } else
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ } else {
+ if (width > 0 && height > 0)
+ m_context->copyTexImage2D(target, level, internalformat,
+ x, y, width, height, border);
+ }
}
// FIXME: if the framebuffer is not complete, none of the below should be executed.
tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
@@ -1256,7 +1316,7 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
if (renderbuffer == m_renderbufferBinding)
m_renderbufferBinding = 0;
if (m_framebufferBinding)
- m_framebufferBinding->removeAttachment(renderbuffer);
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
}
void WebGLRenderingContext::deleteShader(WebGLShader* shader)
@@ -1275,7 +1335,7 @@ void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
m_textureUnits[i].m_textureCubeMapBinding = 0;
}
if (m_framebufferBinding)
- m_framebufferBinding->removeAttachment(texture);
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
}
void WebGLRenderingContext::depthFunc(GC3Denum func)
@@ -1586,7 +1646,7 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c
cleanupAfterGraphicsCall(true);
}
-void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, ExceptionCode& ec)
+void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
@@ -1621,14 +1681,14 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
int numElements = 0;
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
// Ensure we have a valid rendering state
- if (!validateElementArraySize(count, type, offset)) {
+ if (!validateElementArraySize(count, type, static_cast<GC3Dintptr>(offset))) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
if (!count)
return;
if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) {
- if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
+ if (!validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements) || !validateRenderingState(numElements)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
@@ -1649,12 +1709,12 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
bool vertexAttrib0Simulated = false;
if (!isGLES2Compliant()) {
if (!numElements)
- validateIndexArrayPrecise(count, type, offset, numElements);
+ validateIndexArrayPrecise(count, type, static_cast<GC3Dintptr>(offset), numElements);
vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
}
if (!isGLES2NPOTStrict())
handleNPOTTextures(true);
- m_context->drawElements(mode, count, type, offset);
+ m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
if (!isGLES2Compliant() && vertexAttrib0Simulated)
restoreStatesAfterVertexAttrib0Simulation();
if (!isGLES2NPOTStrict())
@@ -1752,7 +1812,7 @@ void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum at
default:
m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
}
- m_framebufferBinding->setAttachment(attachment, buffer);
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
if (reattachDepth) {
Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_ATTACHMENT));
if (object)
@@ -1797,7 +1857,7 @@ void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attac
return;
}
m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level);
- m_framebufferBinding->setAttachment(attachment, textarget, texture, level);
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
cleanupAfterGraphicsCall(false);
}
@@ -1869,23 +1929,15 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Web
shaderObjects.clear();
if (isContextLost() || !validateWebGLObject(program))
return false;
- GC3Dint numShaders = 0;
- m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ATTACHED_SHADERS, &numShaders);
- if (numShaders) {
- OwnArrayPtr<Platform3DObject> shaders = adoptArrayPtr(new Platform3DObject[numShaders]);
- GC3Dsizei count = 0;
- m_context->getAttachedShaders(objectOrZero(program), numShaders, &count, shaders.get());
- if (count != numShaders)
- return false;
- shaderObjects.resize(numShaders);
- for (GC3Dint ii = 0; ii < numShaders; ++ii) {
- WebGLShader* shader = findShader(shaders[ii]);
- if (!shader) {
- shaderObjects.clear();
- return false;
- }
- shaderObjects[ii] = shader;
- }
+
+ const GC3Denum shaderType[] = {
+ GraphicsContext3D::VERTEX_SHADER,
+ GraphicsContext3D::FRAGMENT_SHADER
+ };
+ for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GC3Denum); ++i) {
+ WebGLShader* shader = program->getAttachedShader(shaderType[i]);
+ if (shader)
+ shaderObjects.append(shader);
}
return true;
}
@@ -1894,6 +1946,8 @@ GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const St
{
if (isContextLost())
return -1;
+ if (!validateLocationLength(name))
+ return -1;
if (!validateString(name))
return -1;
return m_context->getAttribLocation(objectOrZero(program), name);
@@ -1914,6 +1968,12 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum
return WebGLGetInfo();
}
+ // Some platforms fail to raise INVALID_OPERATION if no array buffer is bound
+ if (target == GraphicsContext3D::ARRAY_BUFFER && !m_boundArrayBuffer) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+
WebGLStateRestorer(this, false);
GC3Dint value = 0;
m_context->getBufferParameteriv(target, pname, &value);
@@ -1979,46 +2039,51 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum t
UNUSED_PARAM(ec);
if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
return WebGLGetInfo();
- switch (pname) {
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- break;
- default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
- return WebGLGetInfo();
- }
- if (!m_framebufferBinding || !m_framebufferBinding->object() || m_framebufferBinding->isIncomplete(false)) {
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return WebGLGetInfo();
}
- if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
- WebGLStateRestorer(this, false);
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ WebGLObject* object = m_framebufferBinding->getAttachment(attachment);
+ if (!object) {
if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
- return WebGLGetInfo(static_cast<unsigned int>(value));
- return WebGLGetInfo(value);
+ return WebGLGetInfo(static_cast<unsigned int>(GraphicsContext3D::NONE));
+ // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+ // specifies INVALID_OPERATION.
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
}
- WebGLStateRestorer(this, false);
- GC3Dint type = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
- if (!type)
- return WebGLGetInfo();
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value);
- switch (type) {
- case GraphicsContext3D::RENDERBUFFER:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(findRenderbuffer(static_cast<Platform3DObject>(value))));
- case GraphicsContext3D::TEXTURE:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(findTexture(static_cast<Platform3DObject>(value))));
- default:
- // FIXME: raise exception?
- return WebGLGetInfo();
+ ASSERT(object->isTexture() || object->isRenderbuffer());
+ if (object->isTexture()) {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(static_cast<unsigned int>(GraphicsContext3D::TEXTURE));
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(reinterpret_cast<WebGLTexture*>(object)));
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ {
+ WebGLStateRestorer(this, false);
+ GC3Dint value = 0;
+ m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ return WebGLGetInfo(value);
+ }
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ } else {
+ switch (pname) {
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(static_cast<unsigned int>(GraphicsContext3D::RENDERBUFFER));
+ case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
}
}
@@ -2062,8 +2127,8 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case GraphicsContext3D::COLOR_WRITEMASK:
return getBooleanArrayParameter(pname);
case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
- // Defined as null in the spec
- return WebGLGetInfo();
+ // Currently, we have no support for compressed textures:
+ return WebGLGetInfo(Uint32Array::create(0, 0));
case GraphicsContext3D::CULL_FACE:
return getBooleanParameter(pname);
case GraphicsContext3D::CULL_FACE_MODE:
@@ -2558,6 +2623,8 @@ PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGL
UNUSED_PARAM(ec);
if (isContextLost() || !validateWebGLObject(program))
return 0;
+ if (!validateLocationLength(name))
+ return 0;
if (!validateString(name))
return 0;
WebGLStateRestorer(this, false);
@@ -2603,13 +2670,13 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna
}
}
-GC3Dsizeiptr WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
+long long WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
{
if (isContextLost())
return 0;
GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
cleanupAfterGraphicsCall(false);
- return result;
+ return static_cast<long long>(result);
}
void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
@@ -2647,14 +2714,6 @@ GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
bool WebGLRenderingContext::isContextLost()
{
- if (m_restoreTimer.isActive())
- return true;
-
- bool newContextLost = m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR;
-
- if (newContextLost != m_contextLost)
- m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
-
return m_contextLost;
}
@@ -2736,12 +2795,6 @@ void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec
m_context->linkProgram(objectOrZero(program));
program->increaseLinkCount();
- // cache link status
- GC3Dint value = 0;
- m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::LINK_STATUS, &value);
- program->setLinkStatus(static_cast<bool>(value));
- // Need to cache link status before caching active attribute locations.
- program->cacheActiveAttribLocations();
cleanupAfterGraphicsCall(false);
}
@@ -2792,14 +2845,13 @@ void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
+void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&)
{
if (isContextLost())
return;
- if (!canvas()->originClean()) {
- ec = SECURITY_ERR;
- return;
- }
+ // Due to WebGL's same-origin restrictions, it is not possible to
+ // taint the origin using the WebGL API.
+ ASSERT(canvas()->originClean());
// Validate input parameters.
if (!pixels) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -2851,7 +2903,51 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC
}
clearIfComposited();
void* data = pixels->baseAddress();
- m_context->readPixels(x, y, width, height, format, type, data);
+
+ // WebGL requires that areas lying outside the frame buffer should be filled with 0.
+ // Most OpenGL platforms do not support this directly.
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(),
+ &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ unsigned int padding = 0;
+ m_context->computeImageSizeInBytes(format, type, clippedWidth, clippedHeight,
+ m_packAlignment, &totalBytesRequired, &padding);
+ char *tmp = (char *)fastMalloc(totalBytesRequired);
+ // Some platforms incorrectly signal GL_INVALID_VALUE if width == 0 || height == 0
+ if (clippedWidth > 0 && clippedHeight > 0)
+ m_context->readPixels(clippedX, clippedY, clippedWidth,
+ clippedHeight, format, type, tmp);
+
+ unsigned int bytesPerComponent, componentsPerPixel;
+ m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel,
+ &bytesPerComponent);
+ int clippedRowBytes = bytesPerComponent * componentsPerPixel * clippedWidth;
+ int clippedStride = clippedRowBytes + padding;
+ int rowBytes = bytesPerComponent * componentsPerPixel * width;
+ int stride = rowBytes + padding;
+ char *src = tmp;
+ char *dst = (char *)data;
+ int xdelta = (clippedX - x) * bytesPerComponent * componentsPerPixel;
+ for (int r = y; r < y + height; r++) {
+ if (r < y + height - 1)
+ memset(dst, 0, stride);
+ else
+ memset(dst, 0, rowBytes);
+ if (r >= clippedY && r < clippedY + clippedHeight) {
+ memcpy(dst + xdelta, src, clippedRowBytes);
+ src += clippedStride;
+ }
+ dst += stride;
+ }
+ fastFree(tmp);
+ }
+ else {
+ // Some platforms incorrectly signal GL_INVALID_VALUE if width == 0 || height == 0
+ if (width > 0 && height > 0)
+ m_context->readPixels(x, y, width, height, format, type, data);
+ }
+
#if OS(DARWIN)
// FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
// when alpha is off, readPixels should set alpha to 255 instead of 0.
@@ -3142,7 +3238,11 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
return;
if (!validateHTMLImageElement(image))
return;
- checkOrigin(image);
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3157,7 +3257,10 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- checkOrigin(canvas);
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ return;
+ }
RefPtr<ImageData> imageData = canvas->getImageData();
if (imageData)
texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
@@ -3167,7 +3270,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
}
#if ENABLE(VIDEO)
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video)
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec)
{
if (!video || !video->videoWidth() || !video->videoHeight()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -3179,7 +3282,10 @@ PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* vid
m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
return 0;
}
- checkOrigin(video);
+ if (wouldTaintOrigin(video)) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
IntRect destRect(0, 0, size.width(), size.height());
// FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
video->paintCurrentFrameInContext(buf->context(), destRect);
@@ -3192,8 +3298,8 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
ec = 0;
if (isContextLost())
return;
- RefPtr<Image> image = videoFrameToImage(video);
- if (!video)
+ RefPtr<Image> image = videoFrameToImage(video, ec);
+ if (!image)
return;
texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3334,7 +3440,10 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
return;
if (!validateHTMLImageElement(image))
return;
- checkOrigin(image);
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return;
+ }
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3349,7 +3458,10 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- checkOrigin(canvas);
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ return;
+ }
RefPtr<ImageData> imageData = canvas->getImageData();
if (imageData)
texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
@@ -3365,8 +3477,8 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
ec = 0;
if (isContextLost())
return;
- RefPtr<Image> image = videoFrameToImage(video);
- if (!video)
+ RefPtr<Image> image = videoFrameToImage(video, ec);
+ if (!image)
return;
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3799,7 +3911,7 @@ void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsi
vertexAttribfvImpl(index, v, size, 4);
}
-void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, ExceptionCode& ec)
+void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
if (isContextLost())
@@ -3833,7 +3945,7 @@ void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return;
}
- if ((stride % typeSize) || (offset % typeSize)) {
+ if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
@@ -3849,8 +3961,8 @@ void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC
state.normalized = normalized;
state.stride = validatedStride;
state.originalStride = stride;
- state.offset = offset;
- m_context->vertexAttribPointer(index, size, type, normalized, stride, offset);
+ state.offset = static_cast<GC3Dintptr>(offset);
+ m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
cleanupAfterGraphicsCall(false);
}
@@ -3872,17 +3984,30 @@ void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3D
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::forceLostContext()
+void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
{
if (isContextLost()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
- m_restoreTimer.startOneShot(0);
+ loseContext();
+
+ if (mode == RealLostContext)
+ m_restoreTimer.startOneShot(0);
}
-void WebGLRenderingContext::onLostContext()
+void WebGLRenderingContext::forceRestoreContext()
+{
+ if (!isContextLost()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ maybeRestoreContext(SyntheticLostContext);
+}
+
+void WebGLRenderingContext::loseContext()
{
m_contextLost = true;
@@ -3890,7 +4015,7 @@ void WebGLRenderingContext::onLostContext()
// There is no direct way to clear errors from a GL implementation and
// looping until getError() becomes NO_ERROR might cause an infinite loop if
- // the driver or context implementation had a bug. So, loop a reasonably
+ // the driver or context implementation had a bug. So, loop a reasonably
// large number of times to clear any existing errors.
for (int i = 0; i < 100; ++i) {
if (m_context->getError() == GraphicsContext3D::NO_ERROR)
@@ -3898,14 +4023,67 @@ void WebGLRenderingContext::onLostContext()
}
m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
- canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, ""));
+ RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, "");
+ canvas()->dispatchEvent(event);
+ m_restoreAllowed = event->defaultPrevented();
}
-void WebGLRenderingContext::restoreContext()
+void WebGLRenderingContext::maybeRestoreContext(WebGLRenderingContext::LostContextMode mode)
{
+ if (!m_contextLost) {
+ ASSERT(mode == SyntheticLostContext);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ // The rendering context is not restored unless the default
+ // behavior of the webglcontextlost event was prevented earlier.
+ if (!m_restoreAllowed) {
+ if (mode == SyntheticLostContext)
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
+
+ int contextLostReason = m_context->getExtensions()->getGraphicsResetStatusARB();
+
+ switch (contextLostReason) {
+ case GraphicsContext3D::NO_ERROR:
+ // The GraphicsContext3D implementation might not fully
+ // support GL_ARB_robustness semantics yet. Alternatively, the
+ // WebGL WEBKIT_lose_context extension might have been used to
+ // force a lost context.
+ break;
+ case Extensions3D::GUILTY_CONTEXT_RESET_ARB:
+ // The rendering context is not restored if this context was
+ // guilty of causing the graphics reset.
+ printWarningToConsole("WARNING: WebGL content on the page caused the graphics card to reset; not restoring the context");
+ return;
+ case Extensions3D::INNOCENT_CONTEXT_RESET_ARB:
+ // Always allow the context to be restored.
+ break;
+ case Extensions3D::UNKNOWN_CONTEXT_RESET_ARB:
+ // Warn. Ideally, prompt the user telling them that WebGL
+ // content on the page might have caused the graphics card to
+ // reset and ask them whether they want to continue running
+ // the content. Only if they say "yes" should we start
+ // attempting to restore the context.
+ printWarningToConsole("WARNING: WebGL content on the page might have caused the graphics card to reset");
+ break;
+ }
+
+#if PLATFORM(ANDROID)
+ RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(canvas(), m_attributes, 0));
+#else
RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, canvas()->document()->view()->root()->hostWindow()));
- if (!context)
+#endif
+ if (!context) {
+ if (mode == RealLostContext)
+ m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
+ else
+ // This likely shouldn't happen but is the best way to report it to the WebGL app.
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
+ }
m_context = context;
m_contextLost = false;
@@ -3927,59 +4105,10 @@ void WebGLRenderingContext::addObject(WebGLObject* object)
void WebGLRenderingContext::detachAndRemoveAllObjects()
{
- HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
- for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it)
+ while (m_canvasObjects.size() > 0) {
+ HashSet<WebGLObject*>::iterator it = m_canvasObjects.begin();
(*it)->detachContext();
-
- m_canvasObjects.clear();
-}
-
-WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj)
-{
- if (!obj)
- return 0;
- HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
- for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
- if ((*it)->isTexture() && (*it)->object() == obj)
- return reinterpret_cast<WebGLTexture*>((*it).get());
}
- return 0;
-}
-
-WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj)
-{
- if (!obj)
- return 0;
- HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
- for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
- if ((*it)->isRenderbuffer() && (*it)->object() == obj)
- return reinterpret_cast<WebGLRenderbuffer*>((*it).get());
- }
- return 0;
-}
-
-WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj)
-{
- if (!obj)
- return 0;
- HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
- for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
- if ((*it)->isBuffer() && (*it)->object() == obj)
- return reinterpret_cast<WebGLBuffer*>((*it).get());
- }
- return 0;
-}
-
-WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj)
-{
- if (!obj)
- return 0;
- HashSet<RefPtr<WebGLObject> >::iterator pend = m_canvasObjects.end();
- for (HashSet<RefPtr<WebGLObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
- if ((*it)->isShader() && (*it)->object() == obj)
- return reinterpret_cast<WebGLShader*>((*it).get());
- }
- return 0;
}
WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GC3Denum pname)
@@ -4198,6 +4327,16 @@ WebGLTexture* WebGLRenderingContext::validateTextureBinding(GC3Denum target, boo
return tex;
}
+bool WebGLRenderingContext::validateLocationLength(const String& string)
+{
+ const unsigned maxWebGLLocationLength = 256;
+ if (string.length() > maxWebGLLocationLength) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ return false;
+ }
+ return true;
+}
+
bool WebGLRenderingContext::validateSize(GC3Dint x, GC3Dint y)
{
if (x < 0 || y < 0) {
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index 23c147d..2a0a90d 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -71,6 +73,9 @@ public:
virtual bool isAccelerated() const { return true; }
virtual bool paintsIntoCanvasBuffer() const;
+ GC3Dsizei drawingBufferWidth();
+ GC3Dsizei drawingBufferHeight();
+
void activeTexture(GC3Denum texture, ExceptionCode&);
void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode&);
void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name, ExceptionCode&);
@@ -84,11 +89,11 @@ public:
void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
- void bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage, ExceptionCode&);
+ void bufferData(GC3Denum target, long long size, GC3Denum usage, ExceptionCode&);
void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage, ExceptionCode&);
void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage, ExceptionCode&);
- void bufferSubData(GC3Denum target, GC3Dintptr offset, ArrayBuffer* data, ExceptionCode&);
- void bufferSubData(GC3Denum target, GC3Dintptr offset, ArrayBufferView* data, ExceptionCode&);
+ void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data, ExceptionCode&);
+ void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data, ExceptionCode&);
GC3Denum checkFramebufferStatus(GC3Denum target);
void clear(GC3Dbitfield mask);
@@ -98,8 +103,12 @@ public:
void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
void compileShader(WebGLShader*, ExceptionCode&);
- // void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data);
- // void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data);
+ void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ ArrayBufferView* data);
+ void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset,
+ GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* data);
void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
@@ -127,7 +136,7 @@ public:
void disable(GC3Denum cap);
void disableVertexAttribArray(GC3Duint index, ExceptionCode&);
void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count, ExceptionCode&);
- void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, ExceptionCode&);
+ void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode&);
void enable(GC3Denum cap);
void enableVertexAttribArray(GC3Duint index, ExceptionCode&);
@@ -163,7 +172,7 @@ public:
WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*, ExceptionCode&);
PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&, ExceptionCode&);
WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode&);
- GC3Dsizeiptr getVertexAttribOffset(GC3Duint index, GC3Denum pname);
+ long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
void hint(GC3Denum target, GC3Denum mode);
GC3Dboolean isBuffer(WebGLBuffer*);
@@ -270,13 +279,20 @@ public:
void vertexAttrib4fv(GC3Duint index, Float32Array* values);
void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei size);
void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
- GC3Dsizei stride, GC3Dintptr offset, ExceptionCode&);
+ GC3Dsizei stride, long long offset, ExceptionCode&);
void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void forceLostContext();
- void onLostContext();
- void restoreContext();
+ // WEBKIT_lose_context support
+ enum LostContextMode {
+ // Lost context occurred at the graphics system level.
+ RealLostContext,
+
+ // Lost context provoked by WEBKIT_lose_context.
+ SyntheticLostContext
+ };
+ void forceLostContext(LostContextMode);
+ void forceRestoreContext();
GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
#if USE(ACCELERATED_COMPOSITING)
@@ -297,7 +313,13 @@ public:
int getNumberOfExtensions();
WebGLExtension* getExtensionNumber(int i);
+#if PLATFORM(ANDROID)
+ void recreateSurface();
+ void releaseSurface();
+#endif
+
private:
+ friend class WebGLFramebuffer;
friend class WebGLObject;
friend class OESVertexArrayObject;
@@ -307,10 +329,6 @@ public:
void addObject(WebGLObject*);
void detachAndRemoveAllObjects();
- WebGLTexture* findTexture(Platform3DObject);
- WebGLRenderbuffer* findRenderbuffer(Platform3DObject);
- WebGLBuffer* findBuffer(Platform3DObject);
- WebGLShader* findShader(Platform3DObject);
void markContextChanged();
void cleanupAfterGraphicsCall(bool changed)
@@ -348,7 +366,7 @@ public:
bool validateWebGLObject(WebGLObject*);
#if ENABLE(VIDEO)
- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*);
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&);
#endif
RefPtr<GraphicsContext3D> m_context;
@@ -361,11 +379,12 @@ public:
WebGLRenderingContext* m_context;
};
+ bool m_restoreAllowed;
WebGLRenderingContextRestoreTimer m_restoreTimer;
bool m_needsUpdate;
bool m_markedCanvasDirty;
- HashSet<RefPtr<WebGLObject> > m_canvasObjects;
+ HashSet<WebGLObject*> m_canvasObjects;
// List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
RefPtr<WebGLBuffer> m_boundArrayBuffer;
@@ -515,6 +534,9 @@ public:
// Helper function to get the bound framebuffer's height.
int getBoundFramebufferHeight();
+ // Helper function to verify limits on the length of uniform and attribute locations.
+ bool validateLocationLength(const String&);
+
// Helper function to check if size is non-negative.
// Generate GL error and return false for negative inputs; otherwise, return true.
bool validateSize(GC3Dint x, GC3Dint y);
@@ -612,6 +634,10 @@ public:
bool simulateVertexAttrib0(GC3Dsizei numVertex);
void restoreStatesAfterVertexAttrib0Simulation();
+ void loseContext();
+ // Helper for restoration after context lost.
+ void maybeRestoreContext(LostContextMode);
+
friend class WebGLStateRestorer;
};
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
index 7a19814..0a22c6d 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -450,6 +452,9 @@ module html {
const unsigned int UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
const unsigned int BROWSER_DEFAULT_WEBGL = 0x9244;
+ readonly attribute unsigned int drawingBufferWidth;
+ readonly attribute unsigned int drawingBufferHeight;
+
[StrictTypeChecking] void activeTexture(in unsigned long texture) raises(DOMException);
[StrictTypeChecking] void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
[StrictTypeChecking] void bindAttribLocation(in WebGLProgram program, in unsigned long index, in DOMString name) raises(DOMException);
@@ -464,9 +469,9 @@ module html {
[StrictTypeChecking] void blendFuncSeparate(in unsigned long srcRGB, in unsigned long dstRGB, in unsigned long srcAlpha, in unsigned long dstAlpha);
[StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBuffer data, in unsigned long usage) raises (DOMException);
[StrictTypeChecking] void bufferData(in unsigned long target, in ArrayBufferView data, in unsigned long usage) raises (DOMException);
- [StrictTypeChecking] void bufferData(in unsigned long target, in long size, in unsigned long usage) raises (DOMException);
- [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBuffer data) raises (DOMException);
- [StrictTypeChecking] void bufferSubData(in unsigned long target, in long offset, in ArrayBufferView data) raises (DOMException);
+ [StrictTypeChecking] void bufferData(in unsigned long target, in long long size, in unsigned long usage) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long long offset, in ArrayBuffer data) raises (DOMException);
+ [StrictTypeChecking] void bufferSubData(in unsigned long target, in long long offset, in ArrayBufferView data) raises (DOMException);
[StrictTypeChecking] unsigned long checkFramebufferStatus(in unsigned long target);
[StrictTypeChecking] void clear(in unsigned long mask);
@@ -476,8 +481,18 @@ module html {
[StrictTypeChecking] void colorMask(in boolean red, in boolean green, in boolean blue, in boolean alpha);
[StrictTypeChecking] void compileShader(in WebGLShader shader) raises(DOMException);
- //void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
- //void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
+ [StrictTypeChecking] void compressedTexImage2D(in unsigned long target,
+ in long level,
+ in unsigned long internalformat,
+ in long width, in long height,
+ in long border,
+ in ArrayBufferView data);
+ [StrictTypeChecking] void compressedTexSubImage2D(in unsigned long target,
+ in long level,
+ in long xoffset, in long yoffset,
+ in long width, in long height,
+ in unsigned long format,
+ in ArrayBufferView data);
[StrictTypeChecking] void copyTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long x, in long y, in long width, in long height, in long border);
[StrictTypeChecking] void copyTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long x, in long y, in long width, in long height);
@@ -506,7 +521,7 @@ module html {
[StrictTypeChecking] void disable(in unsigned long cap);
[StrictTypeChecking] void disableVertexAttribArray(in unsigned long index) raises(DOMException);
[StrictTypeChecking] void drawArrays(in unsigned long mode, in long first, in long count) raises(DOMException);
- [StrictTypeChecking] void drawElements(in unsigned long mode, in long count, in unsigned long type, in long offset) raises(DOMException);
+ [StrictTypeChecking] void drawElements(in unsigned long mode, in long count, in unsigned long type, in long long offset) raises(DOMException);
[StrictTypeChecking] void enable(in unsigned long cap);
[StrictTypeChecking] void enableVertexAttribArray(in unsigned long index) raises(DOMException);
@@ -567,7 +582,7 @@ module html {
// any getVertexAttrib(in unsigned long index, in unsigned long pname) raises(DOMException);
[StrictTypeChecking, Custom] void getVertexAttrib();
- [StrictTypeChecking] long getVertexAttribOffset(in unsigned long index, in unsigned long pname);
+ [StrictTypeChecking] long long getVertexAttribOffset(in unsigned long index, in unsigned long pname);
[StrictTypeChecking] void hint(in unsigned long target, in unsigned long mode);
[StrictTypeChecking] boolean isBuffer(in WebGLBuffer buffer);
@@ -661,7 +676,7 @@ module html {
[StrictTypeChecking] void vertexAttrib4f(in unsigned long indx, in float x, in float y, in float z, in float w);
[StrictTypeChecking, Custom] void vertexAttrib4fv(in unsigned long indx, in Float32Array values);
[StrictTypeChecking] void vertexAttribPointer(in unsigned long indx, in long size, in unsigned long type, in boolean normalized,
- in long stride, in long offset) raises(DOMException);
+ in long stride, in long long offset) raises(DOMException);
[StrictTypeChecking] void viewport(in long x, in long y, in long width, in long height);
};
diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.cpp b/Source/WebCore/html/canvas/WebKitLoseContext.cpp
index c594e32..3c0a5f3 100644
--- a/Source/WebCore/html/canvas/WebKitLoseContext.cpp
+++ b/Source/WebCore/html/canvas/WebKitLoseContext.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -56,7 +57,13 @@ PassRefPtr<WebKitLoseContext> WebKitLoseContext::create(WebGLRenderingContext* c
void WebKitLoseContext::loseContext()
{
if (m_context)
- m_context->forceLostContext();
+ m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+}
+
+void WebKitLoseContext::restoreContext()
+{
+ if (m_context)
+ m_context->forceRestoreContext();
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.h b/Source/WebCore/html/canvas/WebKitLoseContext.h
index b713bef..5822e54 100644
--- a/Source/WebCore/html/canvas/WebKitLoseContext.h
+++ b/Source/WebCore/html/canvas/WebKitLoseContext.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,6 +43,7 @@ public:
virtual ExtensionName getName() const;
void loseContext();
+ void restoreContext();
void contextDestroyed() { m_context = 0; }
private:
diff --git a/Source/WebCore/html/canvas/WebKitLoseContext.idl b/Source/WebCore/html/canvas/WebKitLoseContext.idl
index 83fc909..8b249bd 100644
--- a/Source/WebCore/html/canvas/WebKitLoseContext.idl
+++ b/Source/WebCore/html/canvas/WebKitLoseContext.idl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,5 +27,6 @@
module html {
interface [Conditional=WEBGL, OmitConstructor] WebKitLoseContext {
[StrictTypeChecking] void loseContext();
+ [StrictTypeChecking] void restoreContext();
};
}
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.cpp b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
index 3c23b9f..18c28c5 100644
--- a/Source/WebCore/html/parser/CSSPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
@@ -194,8 +194,10 @@ void CSSPreloadScanner::emitRule()
{
if (equalIgnoringCase("import", m_rule.data(), m_rule.size())) {
String value = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size());
- if (!value.isEmpty())
- m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, value, String(), m_scanningBody);
+ if (!value.isEmpty()) {
+ ResourceRequest request(m_document->completeURL(value));
+ m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, request, String(), m_scanningBody);
+ }
m_state = Initial;
} else if (equalIgnoringCase("charset", m_rule.data(), m_rule.size()))
m_state = Initial;
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
index 5514597..5ddff90 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -126,12 +126,13 @@ public:
return;
CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
+ ResourceRequest request = document->completeURL(m_urlToLoad);
if (m_tagName == scriptTag)
- cachedResourceLoader->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody);
+ cachedResourceLoader->preload(CachedResource::Script, request, m_charset, scanningBody);
else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage))
- cachedResourceLoader->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody);
+ cachedResourceLoader->preload(CachedResource::ImageResource, request, String(), scanningBody);
else if (m_tagName == linkTag && m_linkIsStyleSheet && m_linkMediaAttributeIsScreen)
- cachedResourceLoader->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody);
+ cachedResourceLoader->preload(CachedResource::CSSStyleSheet, request, m_charset, scanningBody);
}
const AtomicString& tagName() const { return m_tagName; }
diff --git a/Source/WebCore/loader/CrossOriginAccessControl.cpp b/Source/WebCore/loader/CrossOriginAccessControl.cpp
index 8ca821e..671c185 100644
--- a/Source/WebCore/loader/CrossOriginAccessControl.cpp
+++ b/Source/WebCore/loader/CrossOriginAccessControl.cpp
@@ -43,7 +43,10 @@ bool isOnAccessControlSimpleRequestMethodWhitelist(const String& method)
bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value)
{
- if (equalIgnoringCase(name, "accept") || equalIgnoringCase(name, "accept-language") || equalIgnoringCase(name, "content-language"))
+ if (equalIgnoringCase(name, "accept")
+ || equalIgnoringCase(name, "accept-language")
+ || equalIgnoringCase(name, "content-language")
+ || equalIgnoringCase(name, "origin"))
return true;
// Preflight is required for MIME types that can not be sent via form submission.
@@ -93,6 +96,42 @@ bool isOnAccessControlResponseHeaderWhitelist(const String& name)
return allowedCrossOriginResponseHeaders->contains(name);
}
+void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, bool allowCredentials)
+{
+ request.removeCredentials();
+ request.setAllowCookies(allowCredentials);
+ request.setHTTPOrigin(securityOrigin->toString());
+}
+
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, SecurityOrigin* securityOrigin, bool allowCredentials)
+{
+ ResourceRequest preflightRequest(request.url());
+ updateRequestForAccessControl(preflightRequest, securityOrigin, allowCredentials);
+ preflightRequest.setHTTPMethod("OPTIONS");
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
+ preflightRequest.setPriority(request.priority());
+
+ const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
+
+ if (requestHeaderFields.size() > 0) {
+ Vector<UChar> headerBuffer;
+ HTTPHeaderMap::const_iterator it = requestHeaderFields.begin();
+ append(headerBuffer, it->first);
+ ++it;
+
+ HTTPHeaderMap::const_iterator end = requestHeaderFields.end();
+ for (; it != end; ++it) {
+ headerBuffer.append(',');
+ headerBuffer.append(' ');
+ append(headerBuffer, it->first);
+ }
+
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", String::adopt(headerBuffer));
+ }
+
+ return preflightRequest;
+}
+
bool passesAccessControlCheck(const ResourceResponse& response, bool includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription)
{
// A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
diff --git a/Source/WebCore/loader/CrossOriginAccessControl.h b/Source/WebCore/loader/CrossOriginAccessControl.h
index 50c231e..74b4d58 100644
--- a/Source/WebCore/loader/CrossOriginAccessControl.h
+++ b/Source/WebCore/loader/CrossOriginAccessControl.h
@@ -27,20 +27,24 @@
#ifndef CrossOriginAccessControl_h
#define CrossOriginAccessControl_h
+#include "ResourceRequest.h"
#include <wtf/Forward.h>
namespace WebCore {
- class HTTPHeaderMap;
- class ResourceResponse;
- class SecurityOrigin;
+class HTTPHeaderMap;
+class ResourceResponse;
+class SecurityOrigin;
- bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
- bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
- bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
- bool isOnAccessControlResponseHeaderWhitelist(const String&);
+bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
+bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
+bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
+bool isOnAccessControlResponseHeaderWhitelist(const String&);
- bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*, String& errorDescription);
+void updateRequestForAccessControl(ResourceRequest&, SecurityOrigin*, bool allowCredentials);
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin*, bool allowCredentials);
+
+bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*, String& errorDescription);
} // namespace WebCore
diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp
index 2fbf324..7f545a1 100644
--- a/Source/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp
@@ -89,8 +89,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document* document, Threadabl
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
- crossOriginRequest->removeCredentials();
- crossOriginRequest->setAllowCookies(m_options.allowCredentials);
+ updateRequestForAccessControl(*crossOriginRequest, m_document->securityOrigin(), m_options.allowCredentials);
if (!m_options.forcePreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields()))
makeSimpleCrossOriginAccessRequest(*crossOriginRequest);
@@ -109,47 +108,18 @@ void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const Resource
ASSERT(isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
// Cross-origin requests are only defined for HTTP. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
+ // FIXME: Consider allowing simple CORS requests to non-HTTP URLs.
if (!request.url().protocolInHTTPFamily()) {
m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
return;
}
- // Make a copy of the passed request so that we can modify some details.
- ResourceRequest crossOriginRequest(request);
- crossOriginRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
-
- loadRequest(crossOriginRequest, DoSecurityCheck);
+ loadRequest(request, DoSecurityCheck);
}
void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request)
{
- ResourceRequest preflightRequest(request.url());
- preflightRequest.removeCredentials();
- preflightRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
- preflightRequest.setAllowCookies(m_options.allowCredentials);
- preflightRequest.setHTTPMethod("OPTIONS");
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
-
- const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
-
- if (requestHeaderFields.size() > 0) {
- Vector<UChar> headerBuffer;
- HTTPHeaderMap::const_iterator it = requestHeaderFields.begin();
- append(headerBuffer, it->first);
- ++it;
-
- HTTPHeaderMap::const_iterator end = requestHeaderFields.end();
- for (; it != end; ++it) {
- headerBuffer.append(',');
- headerBuffer.append(' ');
- append(headerBuffer, it->first);
- }
-
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", String::adopt(headerBuffer));
- }
-
- preflightRequest.setPriority(request.priority());
-
+ ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, m_document->securityOrigin(), m_options.allowCredentials);
loadRequest(preflightRequest, DoSecurityCheck);
}
diff --git a/Source/WebCore/loader/EmptyClients.h b/Source/WebCore/loader/EmptyClients.h
index 058db37..2f2ef9d 100644
--- a/Source/WebCore/loader/EmptyClients.h
+++ b/Source/WebCore/loader/EmptyClients.h
@@ -164,7 +164,7 @@ public:
#if ENABLE(TILED_BACKING_STORE)
virtual void delegatedScrollRequested(const IntPoint&) { }
#endif
-#if ENABLE(REQUEST_ANIMATION_FRAME)
+#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
virtual void scheduleAnimation() { }
#endif
diff --git a/Source/WebCore/loader/ImageLoader.cpp b/Source/WebCore/loader/ImageLoader.cpp
index 069b40e..0c1fe99 100644
--- a/Source/WebCore/loader/ImageLoader.cpp
+++ b/Source/WebCore/loader/ImageLoader.cpp
@@ -24,6 +24,7 @@
#include "CachedImage.h"
#include "CachedResourceLoader.h"
+#include "CrossOriginAccessControl.h"
#include "Document.h"
#include "Element.h"
#include "HTMLNames.h"
@@ -160,16 +161,24 @@ void ImageLoader::updateFromElement()
// need (<rdar://problem/5994621>).
CachedImage* newImage = 0;
if (!(attr.isNull() || (attr.isEmpty() && document->baseURI().isLocalFile()))) {
+ ResourceRequest request = ResourceRequest(document->completeURL(sourceURI(attr)));
+
+ String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull()) {
+ bool allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials");
+ updateRequestForAccessControl(request, document->securityOrigin(), allowCredentials);
+ }
+
if (m_loadManually) {
bool autoLoadOtherImages = document->cachedResourceLoader()->autoLoadImages();
document->cachedResourceLoader()->setAutoLoadImages(false);
- newImage = new CachedImage(sourceURI(attr));
+ newImage = new CachedImage(request);
newImage->setLoading(true);
newImage->setOwningCachedResourceLoader(document->cachedResourceLoader());
document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage);
document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages);
} else
- newImage = document->cachedResourceLoader()->requestImage(sourceURI(attr));
+ newImage = document->cachedResourceLoader()->requestImage(request);
// If we do not have an image here, it means that a cross-site
// violation occurred.
diff --git a/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp b/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
index ae7a03c..53a04fb 100644
--- a/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
+++ b/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
@@ -37,8 +37,8 @@
namespace WebCore {
-CachedCSSStyleSheet::CachedCSSStyleSheet(const String& url, const String& charset)
- : CachedResource(url, CSSStyleSheet)
+CachedCSSStyleSheet::CachedCSSStyleSheet(const ResourceRequest& resourceRequest, const String& charset)
+ : CachedResource(resourceRequest, CSSStyleSheet)
, m_decoder(TextResourceDecoder::create("text/css", charset))
{
// Prefer text/css but accept any type (dell.com serves a stylesheet
@@ -53,7 +53,7 @@ CachedCSSStyleSheet::~CachedCSSStyleSheet()
void CachedCSSStyleSheet::didAddClient(CachedResourceClient *c)
{
if (!isLoading())
- c->setCSSStyleSheet(m_url, m_response.url(), m_decoder->encoding().name(), this);
+ c->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), m_decoder->encoding().name(), this);
}
void CachedCSSStyleSheet::allClientsRemoved()
@@ -113,7 +113,7 @@ void CachedCSSStyleSheet::checkNotify()
CachedResourceClientWalker w(m_clients);
while (CachedResourceClient *c = w.next())
- c->setCSSStyleSheet(m_url, m_response.url(), m_decoder->encoding().name(), this);
+ c->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), m_decoder->encoding().name(), this);
}
void CachedCSSStyleSheet::error(CachedResource::Status status)
diff --git a/Source/WebCore/loader/cache/CachedCSSStyleSheet.h b/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
index a982e03..6398717 100644
--- a/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
+++ b/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
@@ -37,7 +37,7 @@ namespace WebCore {
class CachedCSSStyleSheet : public CachedResource {
public:
- CachedCSSStyleSheet(const String& URL, const String& charset);
+ CachedCSSStyleSheet(const ResourceRequest&, const String& charset);
virtual ~CachedCSSStyleSheet();
const String sheetText(bool enforceMIMEType = true, bool* hasValidMIMEType = 0) const;
diff --git a/Source/WebCore/loader/cache/CachedFont.cpp b/Source/WebCore/loader/cache/CachedFont.cpp
index 60f0d6c..3e8508c 100644
--- a/Source/WebCore/loader/cache/CachedFont.cpp
+++ b/Source/WebCore/loader/cache/CachedFont.cpp
@@ -55,8 +55,8 @@
namespace WebCore {
-CachedFont::CachedFont(const String &url)
- : CachedResource(url, FontResource)
+CachedFont::CachedFont(const ResourceRequest& resourceRequest)
+ : CachedResource(resourceRequest, FontResource)
, m_fontData(0)
, m_loadInitiated(false)
{
diff --git a/Source/WebCore/loader/cache/CachedFont.h b/Source/WebCore/loader/cache/CachedFont.h
index dd9d60e..68dd01d 100644
--- a/Source/WebCore/loader/cache/CachedFont.h
+++ b/Source/WebCore/loader/cache/CachedFont.h
@@ -49,7 +49,7 @@ struct FontCustomPlatformData;
class CachedFont : public CachedResource {
public:
- CachedFont(const String& url);
+ CachedFont(const ResourceRequest&);
virtual ~CachedFont();
virtual void load(CachedResourceLoader* cachedResourceLoader);
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index 6867302..e96d784 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -52,8 +52,8 @@ using std::max;
namespace WebCore {
-CachedImage::CachedImage(const String& url)
- : CachedResource(url, ImageResource)
+CachedImage::CachedImage(const ResourceRequest& resourceRequest)
+ : CachedResource(resourceRequest, ImageResource)
, m_image(0)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
, m_shouldPaintBrokenImage(true)
@@ -63,7 +63,7 @@ CachedImage::CachedImage(const String& url)
}
CachedImage::CachedImage(Image* image)
- : CachedResource(String(), ImageResource)
+ : CachedResource(ResourceRequest(), ImageResource)
, m_image(image)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
, m_shouldPaintBrokenImage(true)
@@ -86,7 +86,7 @@ void CachedImage::decodedDataDeletionTimerFired(Timer<CachedImage>*)
void CachedImage::load(CachedResourceLoader* cachedResourceLoader)
{
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- if (!cachedResourceLoader || (cachedResourceLoader->autoLoadImages() && !cachedResourceLoader->shouldBlockNetworkImage(m_url)))
+ if (!cachedResourceLoader || (cachedResourceLoader->autoLoadImages() && !cachedResourceLoader->shouldBlockNetworkImage(m_resourceRequest.url())))
#else
if (!cachedResourceLoader || cachedResourceLoader->autoLoadImages())
#endif
@@ -231,7 +231,7 @@ void CachedImage::checkShouldPaintBrokenImage()
if (!frame)
return;
- m_shouldPaintBrokenImage = frame->loader()->client()->shouldPaintBrokenImage(KURL(ParsedURLString, m_url));
+ m_shouldPaintBrokenImage = frame->loader()->client()->shouldPaintBrokenImage(m_resourceRequest.url());
}
void CachedImage::clear()
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index 79643d7..dc12ba2 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -38,7 +38,7 @@ class CachedImage : public CachedResource, public ImageObserver {
friend class MemoryCache;
public:
- CachedImage(const String& url);
+ CachedImage(const ResourceRequest&);
CachedImage(Image*);
virtual ~CachedImage();
diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp
index e599769..ab92bec 100644
--- a/Source/WebCore/loader/cache/CachedResource.cpp
+++ b/Source/WebCore/loader/cache/CachedResource.cpp
@@ -31,6 +31,7 @@
#include "CachedResourceHandle.h"
#include "CachedResourceLoader.h"
#include "CachedResourceRequest.h"
+#include "CrossOriginAccessControl.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
#include "KURL.h"
@@ -62,7 +63,11 @@ static ResourceLoadPriority defaultPriorityForResourceType(CachedResource::Type
case CachedResource::ImageResource:
return ResourceLoadPriorityLow;
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ return ResourceLoadPriorityVeryLow;
+ case CachedResource::LinkPrerender:
+ return ResourceLoadPriorityVeryLow;
+ case CachedResource::LinkSubresource:
return ResourceLoadPriorityVeryLow;
#endif
}
@@ -74,8 +79,8 @@ static ResourceLoadPriority defaultPriorityForResourceType(CachedResource::Type
static RefCountedLeakCounter cachedResourceLeakCounter("CachedResource");
#endif
-CachedResource::CachedResource(const String& url, Type type)
- : m_url(url)
+CachedResource::CachedResource(const ResourceRequest& request, Type type)
+ : m_resourceRequest(request)
, m_request(0)
, m_loadPriority(defaultPriorityForResourceType(type))
, m_responseTimestamp(currentTime())
@@ -168,6 +173,12 @@ void CachedResource::finish()
m_status = Cached;
}
+bool CachedResource::passesAccessControlCheck(SecurityOrigin* securityOrigin)
+{
+ String errorDescription;
+ return WebCore::passesAccessControlCheck(m_response, resourceRequest().allowCookies(), securityOrigin, errorDescription);
+}
+
bool CachedResource::isExpired() const
{
if (m_response.isNull())
diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h
index 2f33ac7..f216527 100644
--- a/Source/WebCore/loader/cache/CachedResource.h
+++ b/Source/WebCore/loader/cache/CachedResource.h
@@ -28,6 +28,7 @@
#include "PlatformString.h"
#include "PurgePriority.h"
#include "ResourceLoadPriority.h"
+#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
@@ -46,6 +47,7 @@ class CachedResourceRequest;
class Frame;
class InspectorResource;
class PurgeableBuffer;
+class SecurityOrigin;
// A resource that is held in the cache. Classes who want to use this object should derive
// from CachedResourceClient, to get the function calls in case the requested data has arrived.
@@ -54,7 +56,7 @@ class CachedResource {
WTF_MAKE_NONCOPYABLE(CachedResource); WTF_MAKE_FAST_ALLOCATED;
friend class MemoryCache;
friend class InspectorResource;
-
+
public:
enum Type {
ImageResource,
@@ -65,7 +67,9 @@ public:
, XSLStyleSheet
#endif
#if ENABLE(LINK_PREFETCH)
- , LinkResource
+ , LinkPrefetch
+ , LinkPrerender
+ , LinkSubresource
#endif
};
@@ -77,9 +81,9 @@ public:
DecodeError
};
- CachedResource(const String& url, Type);
+ CachedResource(const ResourceRequest&, Type);
virtual ~CachedResource();
-
+
virtual void load(CachedResourceLoader* cachedResourceLoader) { load(cachedResourceLoader, false, DoSecurityCheck, true); }
void load(CachedResourceLoader*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
@@ -90,9 +94,10 @@ public:
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; }
- const String &url() const { return m_url; }
+ ResourceRequest& resourceRequest() { return m_resourceRequest; }
+ const KURL& url() const { return m_resourceRequest.url();}
Type type() const { return static_cast<Type>(m_type); }
-
+
ResourceLoadPriority loadPriority() const { return m_loadPriority; }
void setLoadPriority(ResourceLoadPriority);
@@ -122,7 +127,7 @@ public:
unsigned encodedSize() const { return m_encodedSize; }
unsigned decodedSize() const { return m_decodedSize; }
unsigned overheadSize() const;
-
+
bool isLoaded() const { return !m_loading; } // FIXME. Method name is inaccurate. Loading might not have started yet.
bool isLoading() const { return m_loading; }
@@ -133,7 +138,7 @@ public:
bool isLinkResource() const
{
#if ENABLE(LINK_PREFETCH)
- return type() == LinkResource;
+ return type() == LinkPrefetch || type() == LinkPrerender || type() == LinkSubresource;
#else
return false;
#endif
@@ -142,20 +147,22 @@ public:
unsigned accessCount() const { return m_accessCount; }
void increaseAccessCount() { m_accessCount++; }
- // Computes the status of an object after loading.
+ // Computes the status of an object after loading.
// Updates the expire date on the cache entry file
void finish();
+ bool passesAccessControlCheck(SecurityOrigin*);
+
// Called by the cache if the object has been removed from the cache
// while still being referenced. This means the object should delete itself
// if the number of clients observing it ever drops to 0.
// The resource can be brought back to cache after successful revalidation.
void setInCache(bool inCache) { m_inCache = inCache; }
bool inCache() const { return m_inCache; }
-
+
void setInLiveDecodedResourcesList(bool b) { m_inLiveDecodedResourcesList = b; }
bool inLiveDecodedResourcesList() { return m_inLiveDecodedResourcesList; }
-
+
void setRequest(CachedResourceRequest*);
SharedBuffer* data() const { ASSERT(!m_purgeableData); return m_data.get(); }
@@ -186,26 +193,26 @@ public:
bool errorOccurred() const { return (status() == LoadError || status() == DecodeError); }
bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
-
+
virtual void destroyDecodedData() { }
void setOwningCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_owningCachedResourceLoader = cachedResourceLoader; }
-
+
bool isPreloaded() const { return m_preloadCount; }
void increasePreloadCount() { ++m_preloadCount; }
void decreasePreloadCount() { ASSERT(m_preloadCount); --m_preloadCount; }
-
+
void registerHandle(CachedResourceHandleBase* h);
void unregisterHandle(CachedResourceHandleBase* h);
-
+
bool canUseCacheValidator() const;
bool mustRevalidateDueToCacheHeaders(CachePolicy) const;
bool isCacheValidator() const { return m_resourceToRevalidate; }
CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
-
+
bool isPurgeable() const;
bool wasPurged() const;
-
+
// This is used by the archive machinery to get at a purged resource without
// triggering a load. We should make it protected again if we can find a
// better way to handle the archive case.
@@ -225,10 +232,10 @@ protected:
void didAccessDecodedData(double timeStamp);
bool isSafeToMakePurgeable() const;
-
+
HashCountedSet<CachedResourceClient*> m_clients;
- String m_url;
+ ResourceRequest m_resourceRequest;
String m_accept;
CachedResourceRequest* m_request;
ResourceLoadPriority m_loadPriority;
@@ -276,12 +283,12 @@ private:
CachedResource* m_nextInAllResourcesList;
CachedResource* m_prevInAllResourcesList;
-
+
CachedResource* m_nextInLiveResourcesList;
CachedResource* m_prevInLiveResourcesList;
CachedResourceLoader* m_owningCachedResourceLoader; // only non-0 for resources that are not in the cache
-
+
// If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
// using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
// to to be clients of m_resourceToRevalidate and the resource is deleted. If not, the field is zeroed and this
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index fe25a93..6511b5e 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -55,24 +55,28 @@
namespace WebCore {
-static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
+static CachedResource* createResource(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
switch (type) {
case CachedResource::ImageResource:
- return new CachedImage(url.string());
+ return new CachedImage(request);
case CachedResource::CSSStyleSheet:
- return new CachedCSSStyleSheet(url.string(), charset);
+ return new CachedCSSStyleSheet(request, charset);
case CachedResource::Script:
- return new CachedScript(url.string(), charset);
+ return new CachedScript(request, charset);
case CachedResource::FontResource:
- return new CachedFont(url.string());
+ return new CachedFont(request);
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
- return new CachedXSLStyleSheet(url.string());
+ return new CachedXSLStyleSheet(request);
#endif
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- return new CachedResource(url.string(), CachedResource::LinkResource);
+ case CachedResource::LinkPrefetch:
+ return new CachedResource(request, CachedResource::LinkPrefetch);
+ case CachedResource::LinkPrerender:
+ return new CachedResource(request, CachedResource::LinkPrerender);
+ case CachedResource::LinkSubresource:
+ return new CachedResource(request, CachedResource::LinkSubresource);
#endif
}
ASSERT_NOT_REACHED();
@@ -106,16 +110,16 @@ CachedResourceLoader::~CachedResourceLoader()
ASSERT(m_requestCount == 0);
}
-CachedResource* CachedResourceLoader::cachedResource(const String& resourceURL) const
+CachedResource* CachedResourceLoader::cachedResource(const String& resourceURL) const
{
KURL url = m_document->completeURL(resourceURL);
- return cachedResource(url);
+ return cachedResource(url);
}
CachedResource* CachedResourceLoader::cachedResource(const KURL& resourceURL) const
{
KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
- return m_documentResources.get(url).get();
+ return m_documentResources.get(url).get();
}
Frame* CachedResourceLoader::frame() const
@@ -123,7 +127,7 @@ Frame* CachedResourceLoader::frame() const
return m_document ? m_document->frame() : 0;
}
-CachedImage* CachedResourceLoader::requestImage(const String& url)
+CachedImage* CachedResourceLoader::requestImage(ResourceRequest& request)
{
if (Frame* f = frame()) {
Settings* settings = f->settings();
@@ -131,22 +135,22 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
return 0;
if (f->loader()->pageDismissalEventBeingDispatched()) {
- KURL completeURL = m_document->completeURL(url);
- if (completeURL.isValid() && canRequest(CachedResource::ImageResource, completeURL))
- PingLoader::loadImage(f, completeURL);
+ KURL requestURL = request.url();
+ if (requestURL.isValid() && canRequest(CachedResource::ImageResource, requestURL))
+ PingLoader::loadImage(f, requestURL);
return 0;
}
}
- CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, url, String()));
+ CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String()));
if (resource) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(url));
+ resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(request.url()));
#else
resource->setAutoLoadWasPreventedBySettings(!autoLoadImages());
#endif
if (autoLoadImages() && resource->stillNeedsLoad()) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- if (shouldBlockNetworkImage(url)) {
+ if (shouldBlockNetworkImage(request.url())) {
return resource;
}
#endif
@@ -157,56 +161,60 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
return resource;
}
-CachedFont* CachedResourceLoader::requestFont(const String& url)
+CachedFont* CachedResourceLoader::requestFont(ResourceRequest& request)
{
- return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, url, String()));
+ return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, request, String()));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& url, const String& charset, ResourceLoadPriority priority)
+CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
{
- return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, charset, priority));
+ return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, request, charset, priority));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
+CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequest& request, const String& charset)
{
- KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
+ KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.url());
if (CachedResource* existing = memoryCache()->resourceForURL(url)) {
if (existing->type() == CachedResource::CSSStyleSheet)
return static_cast<CachedCSSStyleSheet*>(existing);
memoryCache()->remove(existing);
}
- CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(url, charset);
-
+ if (url.string() != request.url())
+ request.setURL(url);
+
+ CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(request, charset);
+
bool inCache = memoryCache()->add(userSheet);
if (!inCache)
userSheet->setInCache(true);
-
+
userSheet->load(this, /*incremental*/ false, SkipSecurityCheck, /*sendResourceLoadCallbacks*/ false);
if (!inCache)
userSheet->setInCache(false);
-
+
return userSheet;
}
-CachedScript* CachedResourceLoader::requestScript(const String& url, const String& charset)
+CachedScript* CachedResourceLoader::requestScript(ResourceRequest& request, const String& charset)
{
- return static_cast<CachedScript*>(requestResource(CachedResource::Script, url, charset));
+ return static_cast<CachedScript*>(requestResource(CachedResource::Script, request, charset));
}
#if ENABLE(XSLT)
-CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(const String& url)
+CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(ResourceRequest& request)
{
- return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, url, String()));
+ return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, request, String()));
}
#endif
#if ENABLE(LINK_PREFETCH)
-CachedResource* CachedResourceLoader::requestLinkResource(const String& url, ResourceLoadPriority priority)
+CachedResource* CachedResourceLoader::requestLinkResource(CachedResource::Type type, ResourceRequest& request, ResourceLoadPriority priority)
{
ASSERT(frame());
- return requestResource(CachedResource::LinkResource, url, String(), priority);
+ ASSERT(type == CachedResource::LinkPrefetch || type == CachedResource::LinkPrerender || type == CachedResource::LinkSubresource);
+ return requestResource(type, request, String(), priority);
}
#endif
@@ -221,7 +229,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
case CachedResource::Script:
case CachedResource::FontResource:
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
#endif
// These types of resources can be loaded from any origin.
// FIXME: Are we sure about CachedResource::FontResource?
@@ -242,7 +252,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
// Note: Currently, we always allow mixed content, but we generate a
// callback to the FrameLoaderClient in case the embedder wants to
// update any security indicators.
- //
+ //
switch (type) {
case CachedResource::Script:
#if ENABLE(XSLT)
@@ -263,7 +273,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
break;
}
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
// Prefetch cannot affect the current document.
break;
#endif
@@ -292,9 +304,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
break;
}
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- if (!m_document->settings()->linkPrefetchEnabled())
- return false;
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
break;
#endif
}
@@ -302,18 +314,18 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
return true;
}
-CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
+CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority, bool forPreload)
{
- KURL url = m_document->completeURL(resourceURL);
-
+ KURL url = request.url();
+
LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.string().latin1().data(), charset.latin1().data(), priority, forPreload);
-
+
// If only the fragment identifiers differ, it is the same resource.
url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
if (!url.isValid())
return 0;
-
+
if (!canRequest(type, url))
return 0;
@@ -336,13 +348,16 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
// See if we can use an existing resource from the cache.
CachedResource* resource = memoryCache()->resourceForURL(url);
+ if (request.url() != url)
+ request.setURL(url);
+
switch (determineRevalidationPolicy(type, forPreload, resource)) {
case Load:
- resource = loadResource(type, url, charset, priority);
+ resource = loadResource(type, request, charset, priority);
break;
case Reload:
memoryCache()->remove(resource);
- resource = loadResource(type, url, charset, priority);
+ resource = loadResource(type, request, charset, priority);
break;
case Revalidate:
resource = revalidateResource(resource, priority);
@@ -358,10 +373,10 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
ASSERT(resource->url() == url.string());
m_documentResources.set(resource->url(), resource);
-
+
return resource;
}
-
+
CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority)
{
ASSERT(resource);
@@ -369,42 +384,42 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
ASSERT(!memoryCache()->disabled());
ASSERT(resource->canUseCacheValidator());
ASSERT(!resource->resourceToRevalidate());
-
+
// Copy the URL out of the resource to be revalidated in case it gets deleted by the remove() call below.
String url = resource->url();
- CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
-
+ CachedResource* newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding());
+
LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
newResource->setResourceToRevalidate(resource);
-
+
memoryCache()->remove(resource);
memoryCache()->add(newResource);
-
+
newResource->setLoadPriority(priority);
newResource->load(this);
-
+
m_validatedURLs.add(url);
return newResource;
}
-CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, const KURL& url, const String& charset, ResourceLoadPriority priority)
+CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
{
- ASSERT(!memoryCache()->resourceForURL(url));
-
- LOG(ResourceLoading, "Loading CachedResource for '%s'.", url.string().latin1().data());
-
- CachedResource* resource = createResource(type, url, charset);
-
+ ASSERT(!memoryCache()->resourceForURL(request.url()));
+
+ LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.url().string().latin1().data());
+
+ CachedResource* resource = createResource(type, request, charset);
+
bool inCache = memoryCache()->add(resource);
-
+
// Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
// FIXME: CachedResource should just use normal refcounting instead.
if (!inCache)
resource->setInCache(true);
-
+
resource->setLoadPriority(priority);
resource->load(this);
-
+
if (!inCache) {
resource->setOwningCachedResourceLoader(this);
resource->setInCache(false);
@@ -419,7 +434,7 @@ CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, co
return 0;
}
- m_validatedURLs.add(url.string());
+ m_validatedURLs.add(request.url());
return resource;
}
@@ -427,25 +442,25 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
{
if (!existingResource)
return Load;
-
+
// We already have a preload going for this URL.
if (forPreload && existingResource->isPreloaded())
return Use;
-
+
// If the same URL has been loaded as a different type, we need to reload.
if (existingResource->type() != type) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to type mismatch.");
return Reload;
}
-
+
// Don't reload resources while pasting.
if (m_allowStaleResources)
return Use;
-
+
// Alwaus use preloads.
if (existingResource->isPreloaded())
return Use;
-
+
// CachePolicyHistoryBuffer uses the cache no matter what.
if (cachePolicy() == CachePolicyHistoryBuffer)
return Use;
@@ -459,19 +474,19 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
// Avoid loading the same resource multiple times for a single document, even if the cache policies would tell us to.
if (m_validatedURLs.contains(existingResource->url()))
return Use;
-
+
// CachePolicyReload always reloads
if (cachePolicy() == CachePolicyReload) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to CachePolicyReload.");
return Reload;
}
-
+
// We'll try to reload the resource if it failed last time.
if (existingResource->errorOccurred()) {
LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicye reloading due to resource being in the error state");
return Reload;
}
-
+
// For resources that are not yet loaded we ignore the cache policy.
if (existingResource->isLoading())
return Use;
@@ -481,9 +496,9 @@ CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalida
// See if the resource has usable ETag or Last-modified headers.
if (existingResource->canUseCacheValidator())
return Revalidate;
-
+
// No, must reload.
- LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators.");
+ LOG(ResourceLoading, "CachedResourceLoader::determineRevalidationPolicy reloading due to missing cache validators.");
return Reload;
}
@@ -675,8 +690,8 @@ int CachedResourceLoader::requestCount()
return m_requestCount + 1;
return m_requestCount;
}
-
-void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
+
+void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset, bool referencedFromBody)
{
// FIXME: Rip this out when we are sure it is no longer necessary (even for mobile).
UNUSED_PARAM(referencedFromBody);
@@ -686,33 +701,33 @@ void CachedResourceLoader::preload(CachedResource::Type type, const String& url,
if (!hasRendering && !canBlockParser) {
// Don't preload subresources that can't block the parser before we have something to draw.
// This helps prevent preloads from delaying first display when bandwidth is limited.
- PendingPreload pendingPreload = { type, url, charset };
+ PendingPreload pendingPreload = { type, request, charset };
m_pendingPreloads.append(pendingPreload);
return;
}
- requestPreload(type, url, charset);
+ requestPreload(type, request, charset);
}
-void CachedResourceLoader::checkForPendingPreloads()
+void CachedResourceLoader::checkForPendingPreloads()
{
if (m_pendingPreloads.isEmpty() || !m_document->body() || !m_document->body()->renderer())
return;
while (!m_pendingPreloads.isEmpty()) {
PendingPreload preload = m_pendingPreloads.takeFirst();
// Don't request preload if the resource already loaded normally (this will result in double load if the page is being reloaded with cached results ignored).
- if (!cachedResource(m_document->completeURL(preload.m_url)))
- requestPreload(preload.m_type, preload.m_url, preload.m_charset);
+ if (!cachedResource(preload.m_request.url()))
+ requestPreload(preload.m_type, preload.m_request, preload.m_charset);
}
m_pendingPreloads.clear();
}
-void CachedResourceLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
+void CachedResourceLoader::requestPreload(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
String encoding;
if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
encoding = charset.isEmpty() ? m_document->charset() : charset;
- CachedResource* resource = requestResource(type, url, encoding, ResourceLoadPriorityUnresolved, true);
+ CachedResource* resource = requestResource(type, request, encoding, ResourceLoadPriorityUnresolved, true);
if (!resource || (m_preloads && m_preloads->contains(resource)))
return;
resource->increasePreloadCount();
@@ -769,7 +784,7 @@ void CachedResourceLoader::printPreloadStats()
printf("HIT COMPLETE PRELOAD %s\n", res->url().latin1().data());
else if (res->preloadResult() == CachedResource::PreloadReferencedWhileLoading)
printf("HIT LOADING PRELOAD %s\n", res->url().latin1().data());
-
+
if (res->type() == CachedResource::Script) {
scripts++;
if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading)
@@ -783,14 +798,14 @@ void CachedResourceLoader::printPreloadStats()
if (res->preloadResult() < CachedResource::PreloadReferencedWhileLoading)
imageMisses++;
}
-
+
if (res->errorOccurred())
memoryCache()->remove(res);
-
+
res->decreasePreloadCount();
}
m_preloads.clear();
-
+
if (scripts)
printf("SCRIPTS: %d (%d hits, hit rate %d%%)\n", scripts, scripts - scriptMisses, (scripts - scriptMisses) * 100 / scripts);
if (stylesheets)
@@ -799,5 +814,5 @@ void CachedResourceLoader::printPreloadStats()
printf("IMAGES: %d (%d hits, hit rate %d%%)\n", images, images - imageMisses, (images - imageMisses) * 100 / images);
}
#endif
-
+
}
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index 79c63b9..a3933f3 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -59,17 +59,17 @@ public:
CachedResourceLoader(Document*);
~CachedResourceLoader();
- CachedImage* requestImage(const String& url);
- CachedCSSStyleSheet* requestCSSStyleSheet(const String& url, const String& charset, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved);
- CachedCSSStyleSheet* requestUserCSSStyleSheet(const String& url, const String& charset);
- CachedScript* requestScript(const String& url, const String& charset);
- CachedFont* requestFont(const String& url);
+ CachedImage* requestImage(ResourceRequest&);
+ CachedCSSStyleSheet* requestCSSStyleSheet(ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
+ CachedCSSStyleSheet* requestUserCSSStyleSheet(ResourceRequest&, const String& charset);
+ CachedScript* requestScript(ResourceRequest&, const String& charset);
+ CachedFont* requestFont(ResourceRequest&);
#if ENABLE(XSLT)
- CachedXSLStyleSheet* requestXSLStyleSheet(const String& url);
+ CachedXSLStyleSheet* requestXSLStyleSheet(ResourceRequest&);
#endif
#if ENABLE(LINK_PREFETCH)
- CachedResource* requestLinkResource(const String &url, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved);
+ CachedResource* requestLinkResource(CachedResource::Type, ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
#endif
// Logs an access denied message to the console for the specified URL.
@@ -110,15 +110,15 @@ public:
void clearPreloads();
void clearPendingPreloads();
- void preload(CachedResource::Type, const String& url, const String& charset, bool referencedFromBody);
+ void preload(CachedResource::Type, ResourceRequest&, const String& charset, bool referencedFromBody);
void checkForPendingPreloads();
void printPreloadStats();
private:
- CachedResource* requestResource(CachedResource::Type, const String& url, const String& charset, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved, bool isPreload = false);
+ CachedResource* requestResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false);
CachedResource* revalidateResource(CachedResource*, ResourceLoadPriority priority);
- CachedResource* loadResource(CachedResource::Type, const KURL&, const String& charset, ResourceLoadPriority priority);
- void requestPreload(CachedResource::Type, const String& url, const String& charset);
+ CachedResource* loadResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority);
+ void requestPreload(CachedResource::Type, ResourceRequest& url, const String& charset);
enum RevalidationPolicy { Use, Revalidate, Reload, Load };
RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, bool forPreload, CachedResource* existingResource) const;
@@ -142,7 +142,7 @@ private:
OwnPtr<ListHashSet<CachedResource*> > m_preloads;
struct PendingPreload {
CachedResource::Type m_type;
- String m_url;
+ ResourceRequest m_request;
String m_charset;
};
Deque<PendingPreload> m_pendingPreloads;
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.cpp b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
index 9e7fe8f..e4e6b8b 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
@@ -42,11 +42,8 @@
namespace WebCore {
-static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource::Type type, ResourceLoadPriority priority)
+static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource::Type type)
{
-#if !ENABLE(LINK_PREFETCH)
- UNUSED_PARAM(priority);
-#endif
switch (type) {
case CachedResource::CSSStyleSheet:
#if ENABLE(XSLT)
@@ -60,9 +57,11 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource
case CachedResource::ImageResource:
return ResourceRequest::TargetIsImage;
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- if (priority == ResourceLoadPriorityLowest)
- return ResourceRequest::TargetIsPrefetch;
+ case CachedResource::LinkPrefetch:
+ return ResourceRequest::TargetIsPrefetch;
+ case CachedResource::LinkPrerender:
+ return ResourceRequest::TargetIsSubresource;
+ case CachedResource::LinkSubresource:
return ResourceRequest::TargetIsSubresource;
#endif
}
@@ -89,8 +88,8 @@ PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoad
{
RefPtr<CachedResourceRequest> request = adoptRef(new CachedResourceRequest(cachedResourceLoader, resource, incremental));
- ResourceRequest resourceRequest(resource->url());
- resourceRequest.setTargetType(cachedResourceTypeToTargetType(resource->type(), resource->loadPriority()));
+ ResourceRequest resourceRequest = resource->resourceRequest();
+ resourceRequest.setTargetType(cachedResourceTypeToTargetType(resource->type()));
if (!resource->accept().isEmpty())
resourceRequest.setHTTPAccept(resource->accept());
@@ -113,7 +112,7 @@ PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoad
}
#if ENABLE(LINK_PREFETCH)
- if (resource->type() == CachedResource::LinkResource)
+ if (resource->type() == CachedResource::LinkPrefetch || resource->type() == CachedResource::LinkPrerender || resource->type() == CachedResource::LinkSubresource)
resourceRequest.setHTTPHeaderField("Purpose", "prefetch");
#endif
@@ -124,7 +123,7 @@ PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoad
request.get(), resourceRequest, priority, securityCheck, sendResourceLoadCallbacks);
if (!loader || loader->reachedTerminalState()) {
// FIXME: What if resources in other frames were waiting for this revalidation?
- LOG(ResourceLoading, "Cannot start loading '%s'", resource->url().latin1().data());
+ LOG(ResourceLoading, "Cannot start loading '%s'", resource->url().string().latin1().data());
cachedResourceLoader->decrementRequestCount(resource);
cachedResourceLoader->loadFinishing();
if (resource->resourceToRevalidate())
@@ -149,7 +148,7 @@ void CachedResourceRequest::didFinishLoading(SubresourceLoader* loader, double)
ASSERT(loader == m_loader.get());
ASSERT(!m_resource->resourceToRevalidate());
- LOG(ResourceLoading, "Received '%s'.", m_resource->url().latin1().data());
+ LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());
// Prevent the document from being destroyed before we are done with
// the cachedResourceLoader that it will delete when the document gets deleted.
@@ -181,7 +180,7 @@ void CachedResourceRequest::didFail(bool cancelled)
if (m_finishing)
return;
- LOG(ResourceLoading, "Failed to load '%s' (cancelled=%d).\n", m_resource->url().latin1().data(), cancelled);
+ LOG(ResourceLoading, "Failed to load '%s' (cancelled=%d).\n", m_resource->url().string().latin1().data(), cancelled);
// Prevent the document from being destroyed before we are done with
// the cachedResourceLoader that it will delete when the document gets deleted.
diff --git a/Source/WebCore/loader/cache/CachedScript.cpp b/Source/WebCore/loader/cache/CachedScript.cpp
index e1a8a32..8c83bca 100644
--- a/Source/WebCore/loader/cache/CachedScript.cpp
+++ b/Source/WebCore/loader/cache/CachedScript.cpp
@@ -40,8 +40,8 @@
namespace WebCore {
-CachedScript::CachedScript(const String& url, const String& charset)
- : CachedResource(url, Script)
+CachedScript::CachedScript(const ResourceRequest& resourceRequest, const String& charset)
+ : CachedResource(resourceRequest, Script)
, m_decoder(TextResourceDecoder::create("application/javascript", charset))
, m_decodedDataDeletionTimer(this, &CachedScript::decodedDataDeletionTimerFired)
{
diff --git a/Source/WebCore/loader/cache/CachedScript.h b/Source/WebCore/loader/cache/CachedScript.h
index a4ea453..1a76c18 100644
--- a/Source/WebCore/loader/cache/CachedScript.h
+++ b/Source/WebCore/loader/cache/CachedScript.h
@@ -42,7 +42,7 @@ namespace WebCore {
class CachedScript : public CachedResource {
public:
- CachedScript(const String& url, const String& charset);
+ CachedScript(const ResourceRequest&, const String& charset);
virtual ~CachedScript();
const String& script();
diff --git a/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp b/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp
index ca7bf13..62e5048 100644
--- a/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp
+++ b/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp
@@ -37,8 +37,8 @@ namespace WebCore {
#if ENABLE(XSLT)
-CachedXSLStyleSheet::CachedXSLStyleSheet(const String &url)
- : CachedResource(url, XSLStyleSheet)
+CachedXSLStyleSheet::CachedXSLStyleSheet(const ResourceRequest& resourceRequest)
+ : CachedResource(resourceRequest, XSLStyleSheet)
, m_decoder(TextResourceDecoder::create("text/xsl"))
{
// It's XML we want.
@@ -49,7 +49,7 @@ CachedXSLStyleSheet::CachedXSLStyleSheet(const String &url)
void CachedXSLStyleSheet::didAddClient(CachedResourceClient* c)
{
if (!isLoading())
- c->setXSLStyleSheet(m_url, m_response.url(), m_sheet);
+ c->setXSLStyleSheet(m_resourceRequest.url(), m_response.url(), m_sheet);
}
void CachedXSLStyleSheet::setEncoding(const String& chs)
@@ -84,7 +84,7 @@ void CachedXSLStyleSheet::checkNotify()
CachedResourceClientWalker w(m_clients);
while (CachedResourceClient *c = w.next())
- c->setXSLStyleSheet(m_url, m_response.url(), m_sheet);
+ c->setXSLStyleSheet(m_resourceRequest.url(), m_response.url(), m_sheet);
}
void CachedXSLStyleSheet::error(CachedResource::Status status)
diff --git a/Source/WebCore/loader/cache/CachedXSLStyleSheet.h b/Source/WebCore/loader/cache/CachedXSLStyleSheet.h
index 8b29792..b8f7283 100644
--- a/Source/WebCore/loader/cache/CachedXSLStyleSheet.h
+++ b/Source/WebCore/loader/cache/CachedXSLStyleSheet.h
@@ -37,7 +37,7 @@ namespace WebCore {
#if ENABLE(XSLT)
class CachedXSLStyleSheet : public CachedResource {
public:
- CachedXSLStyleSheet(const String& url);
+ CachedXSLStyleSheet(const ResourceRequest&);
const String& sheet() const { return m_sheet; }
diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp
index cb11e15..363668c 100644
--- a/Source/WebCore/loader/cache/MemoryCache.cpp
+++ b/Source/WebCore/loader/cache/MemoryCache.cpp
@@ -93,7 +93,7 @@ bool MemoryCache::add(CachedResource* resource)
resourceAccessed(resource);
- LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().latin1().data(), resource);
+ LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource);
return true;
}
@@ -323,7 +323,7 @@ bool MemoryCache::makeResourcePurgeable(CachedResource* resource)
void MemoryCache::evict(CachedResource* resource)
{
- LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().latin1().data());
+ LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().string().latin1().data());
// The resource may have already been removed by someone other than our caller,
// who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
if (resource->inCache()) {
diff --git a/Source/WebCore/make-hash-tools.pl b/Source/WebCore/make-hash-tools.pl
index 37639eb..629af85 100644
--- a/Source/WebCore/make-hash-tools.pl
+++ b/Source/WebCore/make-hash-tools.pl
@@ -20,7 +20,7 @@
# Boston, MA 02110-1301, USA.
use strict;
-use Switch;
+use feature qw{ switch };
use File::Basename;
my $outdir = $ARGV[0];
@@ -28,9 +28,9 @@ shift;
my $option = basename($ARGV[0],".gperf");
-switch ($option) {
+given ($option) {
-case "DocTypeStrings" {
+when ("DocTypeStrings") {
my $docTypeStringsGenerated = "$outdir/DocTypeStrings.cpp";
my $docTypeStringsGperf = $ARGV[0];
@@ -38,9 +38,9 @@ case "DocTypeStrings" {
system("gperf --key-positions=\"*\" -s 2 $docTypeStringsGperf > $docTypeStringsGenerated") == 0 || die "calling gperf failed: $?";
-} # case "DocTypeStrings"
+} # when "DocTypeStrings"
-case "ColorData" {
+when ("ColorData") {
my $colorDataGenerated = "$outdir/ColorData.cpp";
my $colorDataGperf = $ARGV[0];
@@ -48,6 +48,6 @@ case "ColorData" {
system("gperf --key-positions=\"*\" -D -s 2 $colorDataGperf > $colorDataGenerated") == 0 || die "calling gperf failed: $?";
-} # case "ColorData"
+} # when "ColorData"
-} # switch ($option)
+} # given ($option)
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp
index dce7d33..33491fb 100644
--- a/Source/WebCore/page/Chrome.cpp
+++ b/Source/WebCore/page/Chrome.cpp
@@ -474,7 +474,9 @@ void Chrome::setCursor(const Cursor& cursor)
#if ENABLE(REQUEST_ANIMATION_FRAME)
void Chrome::scheduleAnimation()
{
+#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
m_client->scheduleAnimation();
+#endif
}
#endif
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
index 0ec366b..e422610 100644
--- a/Source/WebCore/page/ChromeClient.h
+++ b/Source/WebCore/page/ChromeClient.h
@@ -153,7 +153,7 @@ namespace WebCore {
virtual PlatformPageClient platformPageClient() const = 0;
virtual void scrollbarsModeDidChange() const = 0;
virtual void setCursor(const Cursor&) = 0;
-#if ENABLE(REQUEST_ANIMATION_FRAME)
+#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
virtual void scheduleAnimation() = 0;
#endif
// End methods used by HostWindow.
diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp
index c7f162a..177c498 100644
--- a/Source/WebCore/page/DOMWindow.cpp
+++ b/Source/WebCore/page/DOMWindow.cpp
@@ -1517,17 +1517,17 @@ void DOMWindow::clearInterval(int timeoutId)
}
#if ENABLE(REQUEST_ANIMATION_FRAME)
-int DOMWindow::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback, Element* e)
+int DOMWindow::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback)
{
if (Document* d = document())
- return d->webkitRequestAnimationFrame(callback, e);
+ return d->webkitRequestAnimationFrame(callback);
return 0;
}
-void DOMWindow::webkitCancelRequestAnimationFrame(int id)
+void DOMWindow::webkitCancelAnimationFrame(int id)
{
if (Document* d = document())
- d->webkitCancelRequestAnimationFrame(id);
+ d->webkitCancelAnimationFrame(id);
}
#endif
diff --git a/Source/WebCore/page/DOMWindow.h b/Source/WebCore/page/DOMWindow.h
index 14ae79c..21c0f98 100644
--- a/Source/WebCore/page/DOMWindow.h
+++ b/Source/WebCore/page/DOMWindow.h
@@ -249,8 +249,9 @@ namespace WebCore {
// WebKit animation extensions
#if ENABLE(REQUEST_ANIMATION_FRAME)
- int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>, Element*);
- void webkitCancelRequestAnimationFrame(int id);
+ int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>);
+ void webkitCancelAnimationFrame(int id);
+ void webkitCancelRequestAnimationFrame(int id) { webkitCancelAnimationFrame(id); }
#endif
// Events
diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl
index d5d3413..827c525 100644
--- a/Source/WebCore/page/DOMWindow.idl
+++ b/Source/WebCore/page/DOMWindow.idl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Sony Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -234,9 +235,10 @@ module window {
void clearInterval(in long handle);
#if defined(ENABLE_REQUEST_ANIMATION_FRAME)
- // WebKit animation extensions
- long webkitRequestAnimationFrame(in [Callback] RequestAnimationFrameCallback callback, in Element element);
- void webkitCancelRequestAnimationFrame(in long id);
+ // WebKit animation extensions, being standardized in the WebPerf WG
+ long webkitRequestAnimationFrame(in [Callback] RequestAnimationFrameCallback callback);
+ void webkitCancelAnimationFrame(in long id);
+ void webkitCancelRequestAnimationFrame(in long id); // This is a deprecated alias for webkitCancelAnimationFrame(). Remove this when removing vendor prefix.
#endif
// Base64
@@ -505,6 +507,7 @@ module window {
attribute [JSCCustomGetter] ArrayBufferConstructor ArrayBuffer; // Usable with new operator
attribute [JSCCustomGetter] Int8ArrayConstructor Int8Array; // Usable with new operator
attribute [JSCCustomGetter] Uint8ArrayConstructor Uint8Array; // Usable with new operator
+ attribute [JSCCustomGetter] Uint8ClampedArrayConstructor Uint8ClampedArray; // Usable with new operator
attribute [JSCCustomGetter] Int16ArrayConstructor Int16Array; // Usable with new operator
attribute [JSCCustomGetter] Uint16ArrayConstructor Uint16Array; // Usable with new operator
attribute [JSCCustomGetter] Int32ArrayConstructor Int32Array; // Usable with new operator
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
index 9e64904..43819b6 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -57,20 +57,20 @@ void ANGLEWebKitBridge::cleanupCompilers()
builtCompilers = false;
}
-
+
void ANGLEWebKitBridge::setResources(ShBuiltInResources resources)
{
// Resources are (possibly) changing - cleanup compilers if we had them already
cleanupCompilers();
-
+
m_resources = resources;
}
bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog)
{
if (!builtCompilers) {
- m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, &m_resources);
- m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, &m_resources);
+ m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, SH_GLSL_OUTPUT, &m_resources);
+ m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, SH_GLSL_OUTPUT, &m_resources);
if (!m_fragmentCompiler || !m_vertexCompiler) {
cleanupCompilers();
return false;
@@ -78,7 +78,7 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
builtCompilers = true;
}
-
+
ShHandle compiler;
if (shaderType == SHADER_TYPE_VERTEX)
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
index a9d2238..e8008a7 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,7 +30,7 @@
#include "PlatformString.h"
#include <wtf/text/CString.h>
-#if !PLATFORM(GTK)
+#if !PLATFORM(GTK) && !PLATFORM(ANDROID)
#include "ANGLE/ShaderLang.h"
#else
#include "ShaderLang.h"
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
index 324fed8..03bcd9e 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -21,7 +21,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -56,10 +56,13 @@ namespace {
} // anonymous namespace
-
PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize& size)
{
- return DrawingBuffer::create(this, size);
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ return DrawingBuffer::create(this, size);
+#else
+ return 0;
+#endif
}
bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 80226cf..b2a4d3a 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -88,6 +89,9 @@ class Extensions3D;
class Extensions3DOpenGL;
#endif
class HostWindow;
+#if PLATFORM(ANDROID)
+class HTMLCanvasElement;
+#endif
class Image;
class ImageData;
#if USE(CAIRO)
@@ -101,7 +105,7 @@ struct ActiveInfo {
};
// FIXME: ideally this would be used on all platforms.
-#if PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(ANDROID) || PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
class GraphicsContext3DInternal;
#endif
@@ -452,7 +456,12 @@ public:
void setContextLostCallback(PassOwnPtr<ContextLostCallback>);
+#if PLATFORM(ANDROID)
+ static PassRefPtr<GraphicsContext3D> create(HTMLCanvasElement*, Attributes,
+ HostWindow*, RenderStyle = RenderOffscreen);
+#else
static PassRefPtr<GraphicsContext3D> create(Attributes, HostWindow*, RenderStyle = RenderOffscreen);
+#endif
~GraphicsContext3D();
#if PLATFORM(MAC)
@@ -474,6 +483,12 @@ public:
#elif PLATFORM(GTK)
PlatformGraphicsContext3D platformGraphicsContext3D();
Platform3DObject platformTexture() const { return m_texture; }
+#elif PLATFORM(ANDROID)
+ PlatformGraphicsContext3D platformGraphicsContext3D();
+ Platform3DObject platformTexture() const;
+#if USE(ACCELERATED_COMPOSITING)
+ PlatformLayer* platformLayer() const;
+#endif
#else
PlatformGraphicsContext3D platformGraphicsContext3D() const { return NullPlatformGraphicsContext3D; }
Platform3DObject platformTexture() const { return NullPlatform3DObject; }
@@ -770,12 +785,18 @@ public:
int canvasWidth, int canvasHeight, PlatformContextCairo* context);
#endif
+#if PLATFORM(ANDROID)
+ void recreateSurface();
+ void releaseSurface();
+#endif
+
void markContextChanged();
void markLayerComposited();
bool layerComposited() const;
void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
PassRefPtr<ImageData> paintRenderingResultsToImageData();
+ bool paintCompositedResultsToCanvas(CanvasRenderingContext* context);
#if PLATFORM(QT)
bool paintsIntoCanvasBuffer() const { return true; }
@@ -821,7 +842,12 @@ public:
IntSize getInternalFramebufferSize();
private:
+#if PLATFORM(ANDROID)
+ GraphicsContext3D(HTMLCanvasElement* canvas, Attributes attrs,
+ HostWindow* hostWindow, bool renderDirectlyToHostWindow);
+#else
GraphicsContext3D(Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow);
+#endif
// Each platform must provide an implementation of this method.
//
@@ -929,7 +955,7 @@ public:
#endif
// FIXME: ideally this would be used on all platforms.
-#if PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(ANDROID) || PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
friend class GraphicsContext3DInternal;
OwnPtr<GraphicsContext3DInternal> m_internal;
#endif
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index c184bbe..fa546e3 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -33,6 +33,7 @@
#include "FloatRect.h"
#include "GraphicsTypes.h"
#include "IntSize.h"
+#include "ImageBuffer.h"
#include "ImageBufferData.h"
#include <wtf/ByteArray.h>
#include <wtf/Forward.h>
@@ -77,9 +78,9 @@ namespace WebCore {
const IntSize& size() const { return m_size; }
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
-
+
size_t dataSize() const;
-
+
GraphicsContext* context() const;
bool isAccelerated() const { return m_accelerateRendering; }
@@ -91,7 +92,7 @@ namespace WebCore {
void putUnmultipliedImageData(ByteArray*, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint);
void putPremultipliedImageData(ByteArray*, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint);
-
+
String toDataURL(const String& mimeType, const double* quality = 0) const;
#if !USE(CG)
AffineTransform baseTransform() const { return AffineTransform(); }
@@ -129,7 +130,7 @@ namespace WebCore {
ImageBuffer(const IntSize&, ColorSpace colorSpace, RenderingMode renderingMode, bool& success);
};
-#if USE(CG) || USE(SKIA)
+#if USE(CG) || USE(SKIA) || PLATFORM(ANDROID)
String ImageDataToDataURL(const ImageData& input, const String& mimeType, const double* quality);
#endif
diff --git a/Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp
new file mode 100644
index 0000000..36fbe15
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 SONY ERICSSON MOBILE COMMUNICATIONS AB 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"
+
+#if ENABLE(WEBGL)
+
+#include "Extensions3DAndroid.h"
+#include "GraphicsContext3D.h"
+
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+Extensions3DAndroid::Extensions3DAndroid(const String& extensions)
+ : m_extensions(extensions)
+{
+}
+
+Extensions3DAndroid::~Extensions3DAndroid()
+{
+}
+
+bool Extensions3DAndroid::supports(const String& ext)
+{
+ return m_extensions.contains(ext);
+}
+
+void Extensions3DAndroid::ensureEnabled(const String& name)
+{
+}
+
+bool Extensions3DAndroid::isEnabled(const String& name)
+{
+ return supports(name);
+}
+
+int Extensions3DAndroid::getGraphicsResetStatusARB()
+{
+ return GraphicsContext3D::NO_ERROR;
+}
+
+void Extensions3DAndroid::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1,
+ long dstX0, long dstY0, long dstX1, long dstY1,
+ unsigned long mask, unsigned long filter)
+{
+}
+
+void Extensions3DAndroid::renderbufferStorageMultisample(unsigned long target,
+ unsigned long samples,
+ unsigned long internalformat,
+ unsigned long width,
+ unsigned long height)
+{
+}
+
+Platform3DObject Extensions3DAndroid::createVertexArrayOES()
+{
+ return 0;
+}
+
+void Extensions3DAndroid::deleteVertexArrayOES(Platform3DObject)
+{
+}
+
+GC3Dboolean Extensions3DAndroid::isVertexArrayOES(Platform3DObject)
+{
+ return GL_FALSE;
+}
+
+void Extensions3DAndroid::bindVertexArrayOES(Platform3DObject)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/android/Extensions3DAndroid.h b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.h
new file mode 100644
index 0000000..ff50fa8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 SONY ERICSSON MOBILE COMMUNICATIONS AB 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 Extensions3DAndroid_h
+#define Extensions3DAndroid_h
+
+#include "Extensions3D.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Extensions3DAndroid : public Extensions3D {
+public:
+ Extensions3DAndroid(const String& extensions);
+ virtual ~Extensions3DAndroid();
+
+ // Extensions3D methods.
+ virtual bool supports(const String&);
+ virtual void ensureEnabled(const String&);
+ virtual bool isEnabled(const String&);
+ virtual int getGraphicsResetStatusARB();
+ virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1,
+ long dstX0, long dstY0, long dstX1, long dstY1,
+ unsigned long mask, unsigned long filter);
+ virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples,
+ unsigned long internalformat, unsigned long width,
+ unsigned long height);
+ virtual Platform3DObject createVertexArrayOES();
+ virtual void deleteVertexArrayOES(Platform3DObject);
+ virtual GC3Dboolean isVertexArrayOES(Platform3DObject);
+ virtual void bindVertexArrayOES(Platform3DObject);
+
+private:
+ String m_extensions;
+};
+
+} // namespace WebCore
+
+#endif // Extensions3DAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp
new file mode 100644
index 0000000..df706a2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp
@@ -0,0 +1,1368 @@
+/*
+ * Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 SONY ERICSSON MOBILE COMMUNICATIONS AB 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"
+
+#if ENABLE(WEBGL)
+#include "BitmapImage.h"
+#include "text/CString.h"
+#include "GraphicsContext3D.h"
+#include "GraphicsContext3DInternal.h"
+#include "Image.h"
+#include "ImageData.h"
+#include "ImageDecoder.h"
+#include "SkBitmap.h"
+#include "SkBitmapRef.h"
+
+namespace WebCore {
+
+
+PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(HTMLCanvasElement* canvas, Attributes attrs,
+ HostWindow *win, RenderStyle style)
+{
+ GraphicsContext3D *context = new GraphicsContext3D(canvas, attrs, win, false);
+ if (!context->m_internal->isValid()) {
+ // Something failed during initialization
+ delete context;
+ return 0;
+ }
+ return adoptRef(context);
+}
+
+GraphicsContext3D::GraphicsContext3D(HTMLCanvasElement* canvas, Attributes attrs,
+ HostWindow* hostWindow, bool renderDirectlyToHostWindow)
+ : m_internal(new GraphicsContext3DInternal(canvas, attrs, hostWindow))
+{
+ LOGWEBGL("GraphicsContext3D() = %p", this);
+ m_currentWidth = m_internal->width();
+ m_currentHeight = m_internal->height();
+}
+
+GraphicsContext3D::~GraphicsContext3D()
+{
+ LOGWEBGL("~GraphicsContext3D()");
+}
+
+PlatformLayer* GraphicsContext3D::platformLayer() const
+{
+ return m_internal->platformLayer();
+}
+
+void GraphicsContext3D::makeContextCurrent() {
+ m_internal->makeContextCurrent();
+}
+
+bool GraphicsContext3D::isGLES2Compliant() const
+{
+ return true;
+}
+
+void GraphicsContext3D::synthesizeGLError(GC3Denum error)
+{
+ m_internal->synthesizeGLError(error);
+}
+
+Extensions3D* GraphicsContext3D::getExtensions()
+{
+ return m_internal->getExtensions();
+}
+
+void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+{
+ makeContextCurrent();
+ m_internal->paintRenderingResultsToCanvas(context);
+}
+
+PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
+{
+ makeContextCurrent();
+ return m_internal->paintRenderingResultsToImageData();
+}
+
+bool GraphicsContext3D::paintCompositedResultsToCanvas(CanvasRenderingContext* context)
+{
+ makeContextCurrent();
+ return m_internal->paintCompositedResultsToCanvas(context);
+}
+
+bool GraphicsContext3D::getImageData(Image* image,
+ unsigned int format,
+ unsigned int type,
+ bool premultiplyAlpha,
+ bool ignoreGammaAndColorProfile,
+ Vector<uint8_t>& outputVector)
+{
+ LOGWEBGL("getImageData(%p, %u, %u, %s, %s)", image, format, type,
+ premultiplyAlpha ? "true" : "false", ignoreGammaAndColorProfile ? "true" : "false");
+ if (!image)
+ return false;
+
+ AlphaOp neededAlphaOp = AlphaDoNothing;
+ bool hasAlpha = (image->data() && image->isBitmapImage()) ?
+ static_cast<BitmapImage*>(image)->frameHasAlphaAtIndex(0) : true;
+ ImageDecoder* decoder = 0;
+ ImageFrame* buf = 0;
+
+ if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && image->data()) {
+ // Attempt to get raw unpremultiplied image data
+ decoder = ImageDecoder::create(*(image->data()),
+ premultiplyAlpha ?
+ ImageSource::AlphaPremultiplied :
+ ImageSource::AlphaNotPremultiplied,
+ ignoreGammaAndColorProfile ?
+ ImageSource::GammaAndColorProfileIgnored :
+ ImageSource::GammaAndColorProfileApplied);
+ if (decoder) {
+ decoder->setData(image->data(), true);
+ buf = decoder->frameBufferAtIndex(0);
+ if (buf && buf->hasAlpha() && premultiplyAlpha)
+ neededAlphaOp = AlphaDoPremultiply;
+ }
+ }
+
+ SkBitmapRef* bitmapRef = 0;
+ if (!buf) {
+ bitmapRef = image->nativeImageForCurrentFrame();
+ if (!bitmapRef)
+ return false;
+ if (!premultiplyAlpha && hasAlpha)
+ neededAlphaOp = AlphaDoUnmultiply;
+ }
+
+ SkBitmap& bitmap = buf ? buf->bitmap() : bitmapRef->bitmap();
+ unsigned char* pixels = 0;
+ int rowBytes = 0;
+ uint32_t* tmpPixels = 0;
+
+ int width = bitmap.width();
+ int height = bitmap.height();
+ int iwidth = image->width();
+ int iheight = image->height();
+ LOGWEBGL(" bitmap.width() = %d, image->width() = %d, bitmap.height = %d, image->height() = %d",
+ width, iwidth, height, iheight);
+ if (width != iwidth || height != iheight) {
+ // This image has probably been subsampled because it was too big.
+ // Currently, we cannot handle this in WebGL: give up.
+ return false;
+ }
+ SkBitmap::Config skiaConfig = bitmap.getConfig();
+
+ bitmap.lockPixels();
+ if (skiaConfig == SkBitmap::kARGB_8888_Config) {
+ LOGWEBGL(" skiaConfig = kARGB_8888_Config");
+ pixels = reinterpret_cast<unsigned char*>(bitmap.getPixels());
+ rowBytes = bitmap.rowBytes();
+ if (!pixels) {
+ bitmap.unlockPixels();
+ return false;
+ }
+ }
+ else if (skiaConfig == SkBitmap::kIndex8_Config) {
+ LOGWEBGL(" skiaConfig = kIndex8_Config");
+ rowBytes = width * 4;
+ tmpPixels = (uint32_t*)fastMalloc(width * height * 4);
+ if (!tmpPixels) {
+ bitmap.unlockPixels();
+ return false;
+ }
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ SkPMColor c = bitmap.getIndex8Color(j, i);
+ tmpPixels[i * width + j] = c;//SkExpand_8888(c);
+ }
+ }
+ pixels = (unsigned char*)tmpPixels;
+ }
+
+ outputVector.resize(rowBytes * height);
+ LOGWEBGL("rowBytes() = %d, width() = %d, height() = %d", rowBytes, width, height);
+
+ bool res = packPixels(pixels,
+ SourceFormatRGBA8, width, height, 0,
+ format, type, neededAlphaOp, outputVector.data());
+ bitmap.unlockPixels();
+
+ if (decoder)
+ delete decoder;
+
+ if (tmpPixels)
+ fastFree(tmpPixels);
+
+ return res;
+}
+
+unsigned GraphicsContext3D::createBuffer()
+{
+ LOGWEBGL("glCreateBuffer()");
+ makeContextCurrent();
+ GLuint b = 0;
+ glGenBuffers(1, &b);
+ return b;
+}
+
+unsigned GraphicsContext3D::createFramebuffer()
+{
+ LOGWEBGL("glCreateFramebuffer()");
+ makeContextCurrent();
+ GLuint fb = 0;
+ glGenFramebuffers(1, &fb);
+ return fb;
+}
+
+unsigned GraphicsContext3D::createProgram()
+{
+ LOGWEBGL("glCreateProgram()");
+ makeContextCurrent();
+ return glCreateProgram();
+}
+
+unsigned GraphicsContext3D::createRenderbuffer()
+{
+ LOGWEBGL("glCreateRenderbuffer()");
+ makeContextCurrent();
+ GLuint rb = 0;
+ glGenRenderbuffers(1, &rb);
+ return rb;
+}
+
+unsigned GraphicsContext3D::createShader(GC3Denum type)
+{
+ LOGWEBGL("glCreateShader()");
+ makeContextCurrent();
+ return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
+}
+
+unsigned GraphicsContext3D::createTexture()
+{
+ LOGWEBGL("glCreateTexture()");
+ makeContextCurrent();
+ GLuint t = 0;
+ glGenTextures(1, &t);
+ return t;
+}
+
+void GraphicsContext3D::deleteBuffer(unsigned buffer)
+{
+ LOGWEBGL("glDeleteBuffers()");
+ makeContextCurrent();
+ glDeleteBuffers(1, &buffer);
+}
+
+void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
+{
+ LOGWEBGL("glDeleteFramebuffers()");
+ makeContextCurrent();
+ glDeleteFramebuffers(1, &framebuffer);
+}
+
+void GraphicsContext3D::deleteProgram(unsigned program)
+{
+ LOGWEBGL("glDeleteProgram()");
+ makeContextCurrent();
+ glDeleteProgram(program);
+}
+
+void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
+{
+ LOGWEBGL("glDeleteRenderbuffers()");
+ makeContextCurrent();
+ glDeleteRenderbuffers(1, &renderbuffer);
+}
+
+void GraphicsContext3D::deleteShader(unsigned shader)
+{
+ LOGWEBGL("glDeleteShader()");
+ makeContextCurrent();
+ glDeleteShader(shader);
+}
+
+void GraphicsContext3D::deleteTexture(unsigned texture)
+{
+ LOGWEBGL("glDeleteTextures()");
+ makeContextCurrent();
+ glDeleteTextures(1, &texture);
+}
+
+
+void GraphicsContext3D::activeTexture(GC3Denum texture)
+{
+ LOGWEBGL("glActiveTexture(%ld)", texture);
+ makeContextCurrent();
+ glActiveTexture(texture);
+}
+
+void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
+{
+ LOGWEBGL("glAttachShader(%d, %d)", program, shader);
+ makeContextCurrent();
+ glAttachShader(program, shader);
+}
+
+void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index,
+ const String& name)
+{
+ CString cs = name.utf8();
+ LOGWEBGL("glBindAttribLocation(%d, %d, %s)", program, index, cs.data());
+ if (!program)
+ return;
+ makeContextCurrent();
+ glBindAttribLocation(program, index, cs.data());
+}
+
+void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
+{
+ LOGWEBGL("glBindBuffer(%d, %d)", target, buffer);
+ makeContextCurrent();
+ glBindBuffer(target, buffer);
+}
+
+void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject framebuffer)
+{
+ LOGWEBGL("bindFrameBuffer(%d, %d)", target, framebuffer);
+ m_internal->bindFramebuffer(target, framebuffer);
+}
+
+void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer)
+{
+ LOGWEBGL("glBindRenderBuffer(%d, %d)", target, renderbuffer);
+ makeContextCurrent();
+ glBindRenderbuffer(target, renderbuffer);
+}
+
+void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
+{
+ LOGWEBGL("glBindTexture(%d, %d)", target, texture);
+ makeContextCurrent();
+ glBindTexture(target, texture);
+}
+
+void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green,
+ GC3Dclampf blue, GC3Dclampf alpha)
+{
+ LOGWEBGL("glBlendColor(%lf, %lf, %lf, %lf)", red, green, blue, alpha);
+ makeContextCurrent();
+ glBlendColor(CLAMP(red), CLAMP(green), CLAMP(blue), CLAMP(alpha));
+}
+
+void GraphicsContext3D::blendEquation(GC3Denum mode)
+{
+ LOGWEBGL("glBlendEquation(%d)", mode);
+ makeContextCurrent();
+ glBlendEquation(mode);
+}
+
+void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
+{
+ LOGWEBGL("glBlendEquationSeparate(%d, %d)", modeRGB, modeAlpha);
+ makeContextCurrent();
+ glBlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+void GraphicsContext3D::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
+{
+ LOGWEBGL("glBlendFunc(%d, %d)", sfactor, dfactor);
+ makeContextCurrent();
+ glBlendFunc(sfactor, dfactor);
+}
+
+void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB,
+ GC3Denum srcAlpha, GC3Denum dstAlpha)
+{
+ LOGWEBGL("glBlendFuncSeparate(%lu, %lu, %lu, %lu)", srcRGB, dstRGB, srcAlpha, dstAlpha);
+ makeContextCurrent();
+ glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
+{
+ LOGWEBGL("glBufferData(%lu, %d, %lu)", target, size, usage);
+ makeContextCurrent();
+ glBufferData(target, size, 0, usage);
+}
+
+void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size,
+ const void* data, GC3Denum usage)
+{
+ LOGWEBGL("glBufferData(%lu, %d, %p, %lu)", target, size, data, usage);
+ makeContextCurrent();
+ glBufferData(target, size, data, usage);
+}
+
+void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset,
+ GC3Dsizeiptr size, const void* data)
+{
+ LOGWEBGL("glBufferSubData(%lu, %ld, %d, %p)", target, offset, size, data);
+ makeContextCurrent();
+ glBufferSubData(target, offset, size, data);
+}
+
+GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
+{
+ LOGWEBGL("glCheckFramebufferStatus(%lu)", target);
+ makeContextCurrent();
+ return glCheckFramebufferStatus(target);
+}
+
+void GraphicsContext3D::clear(GC3Dbitfield mask)
+{
+ LOGWEBGL("glClear(%lu)", mask);
+ makeContextCurrent();
+ glClear(mask);
+}
+
+void GraphicsContext3D::clearColor(GC3Dclampf red, GC3Dclampf green,
+ GC3Dclampf blue, GC3Dclampf alpha)
+{
+ LOGWEBGL("glClearColor(%.2lf, %.2lf, %.2lf, %.2lf)", red, green, blue, alpha);
+ makeContextCurrent();
+ glClearColor(CLAMP(red), CLAMP(green), CLAMP(blue), CLAMP(alpha));
+}
+
+void GraphicsContext3D::clearDepth(GC3Dclampf depth)
+{
+ LOGWEBGL("glClearDepthf(%.2lf)", depth);
+ makeContextCurrent();
+ glClearDepthf(CLAMP(depth));
+}
+
+void GraphicsContext3D::clearStencil(GC3Dint s)
+{
+ LOGWEBGL("glClearStencil(%ld)", s);
+ makeContextCurrent();
+ glClearStencil(s);
+}
+
+void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green,
+ GC3Dboolean blue, GC3Dboolean alpha)
+{
+ LOGWEBGL("glColorMask(%s, %s, %s, %s)", red ? "true" : "false", green ? "true" : "false",
+ blue ? "true" : "false", alpha ? "true" : "false");
+ makeContextCurrent();
+ glColorMask(red, green, blue, alpha);
+}
+
+void GraphicsContext3D::compileShader(Platform3DObject shader)
+{
+ LOGWEBGL("compileShader(%lu)", shader);
+ makeContextCurrent();
+ m_internal->compileShader(shader);
+}
+
+void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dint x, GC3Dint y, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border)
+{
+ LOGWEBGL("glCopyTexImage2D(%lu, %ld, %lu, %ld, %ld, %lu, %lu, %ld",
+ target, level, internalformat, x, y, width, height, border);
+ makeContextCurrent();
+ glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset,
+ GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width,
+ GC3Dsizei height)
+{
+ LOGWEBGL("glCopyTexSubImage2D(%lu, %ld, %ld, %ld, %ld, %ld, %lu, %lu)",
+ target, level, xoffset, yoffset, x, y, width, height);
+ makeContextCurrent();
+ glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+void GraphicsContext3D::cullFace(GC3Denum mode)
+{
+ LOGWEBGL("glCullFace(%lu)", mode);
+ makeContextCurrent();
+ glCullFace(mode);
+}
+
+void GraphicsContext3D::depthFunc(GC3Denum func)
+{
+ LOGWEBGL("glDepthFunc(%lu)", func);
+ makeContextCurrent();
+ glDepthFunc(func);
+}
+
+void GraphicsContext3D::depthMask(GC3Dboolean flag)
+{
+ LOGWEBGL("glDepthMask(%s)", flag ? "true" : "false");
+ makeContextCurrent();
+ glDepthMask(flag);
+}
+
+void GraphicsContext3D::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
+{
+ LOGWEBGL("glDepthRangef(%.2lf, %.2lf)", zNear, zFar);
+ makeContextCurrent();
+ glDepthRangef(CLAMP(zNear), CLAMP(zFar));
+}
+
+void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
+{
+ LOGWEBGL("glDetachShader(%lu, %lu)", program, shader);
+ makeContextCurrent();
+ glDetachShader(program, shader);
+}
+
+void GraphicsContext3D::disable(GC3Denum cap)
+{
+ LOGWEBGL("glDisable(%lu)", cap);
+ makeContextCurrent();
+ glDisable(cap);
+}
+
+void GraphicsContext3D::disableVertexAttribArray(GC3Duint index)
+{
+ LOGWEBGL("glDisableVertexAttribArray(%lu)", index);
+ makeContextCurrent();
+ glDisableVertexAttribArray(index);
+}
+
+void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
+{
+ LOGWEBGL("glDrawArrays(%lu, %ld, %ld)", mode, first, count);
+ makeContextCurrent();
+ glDrawArrays(mode, first, count);
+}
+
+void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count,
+ GC3Denum type, GC3Dintptr offset)
+{
+ LOGWEBGL("glDrawElements(%lu, %lu, %lu, %ld)", mode, count, type, offset);
+ makeContextCurrent();
+ glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
+}
+
+void GraphicsContext3D::enable(GC3Denum cap)
+{
+ LOGWEBGL("glEnable(0x%04x)", cap);
+ makeContextCurrent();
+ glEnable(cap);
+}
+
+void GraphicsContext3D::enableVertexAttribArray(GC3Duint index)
+{
+ LOGWEBGL("glEnableVertexAttribArray(%lu)", index);
+ makeContextCurrent();
+ glEnableVertexAttribArray(index);
+}
+
+void GraphicsContext3D::finish()
+{
+ LOGWEBGL("glFinish()");
+ makeContextCurrent();
+ glFinish();
+}
+
+void GraphicsContext3D::flush()
+{
+ LOGWEBGL("glFlush()");
+ makeContextCurrent();
+ glFlush();
+}
+
+void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment,
+ GC3Denum renderbuffertarget,
+ Platform3DObject renderbuffer)
+{
+ LOGWEBGL("glFramebufferRenderbuffer(%lu, %lu, %lu, %lu)", target, attachment,
+ renderbuffertarget, renderbuffer);
+ makeContextCurrent();
+ glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment,
+ GC3Denum textarget, Platform3DObject texture,
+ GC3Dint level)
+{
+ LOGWEBGL("glFramebufferTexture2D(%lu, %lu, %lu, %lu, %ld)",
+ target, attachment, textarget, texture, level);
+ makeContextCurrent();
+ glFramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void GraphicsContext3D::frontFace(GC3Denum mode)
+{
+ LOGWEBGL("glFrontFace(%lu)", mode);
+ makeContextCurrent();
+ glFrontFace(mode);
+}
+
+void GraphicsContext3D::generateMipmap(GC3Denum target)
+{
+ LOGWEBGL("glGenerateMipmap(%lu)", target);
+ makeContextCurrent();
+ glGenerateMipmap(target);
+}
+
+bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
+{
+ LOGWEBGL("glGetActiveAttrib(%lu, %lu)", program, index);
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return false;
+ }
+ makeContextCurrent();
+ GLint maxAttributeSize = 0;
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
+ GLchar name[maxAttributeSize];
+ GLsizei nameLength = 0;
+ GLint size = 0;
+ GLenum type = 0;
+ glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name);
+ if (!nameLength)
+ return false;
+ info.name = String(name, nameLength);
+ info.type = type;
+ info.size = size;
+ return true;
+}
+
+bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
+{
+ LOGWEBGL("glGetActiveUniform(%lu, %lu)", program, index);
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return false;
+ }
+ makeContextCurrent();
+ GLint maxUniformSize = 0;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
+ GLchar name[maxUniformSize];
+ GLsizei nameLength = 0;
+ GLint size = 0;
+ GLenum type = 0;
+ glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name);
+ if (!nameLength)
+ return false;
+ info.name = String(name, nameLength);
+ info.type = type;
+ info.size = size;
+ return true;
+}
+
+void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount,
+ GC3Dsizei* count, Platform3DObject* shaders)
+{
+ LOGWEBGL("glGetAttachedShaders(%lu, %d, %p, %p)", program, maxCount, count, shaders);
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return;
+ }
+ makeContextCurrent();
+ glGetAttachedShaders(program, maxCount, count, shaders);
+}
+
+GC3Dint GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
+{
+ CString cs = name.utf8();
+ LOGWEBGL("glGetAttribLocation(%lu, %s)", program, cs.data());
+ if (!program) {
+ return -1;
+ }
+ makeContextCurrent();
+
+ return glGetAttribLocation(program, cs.data());
+}
+
+void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value)
+{
+ LOGWEBGL("glGetBooleanv(%lu, %p)", pname, value);
+ makeContextCurrent();
+ glGetBooleanv(pname, value);
+}
+
+void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetBufferParameteriv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetBufferParameteriv(target, pname, value);
+}
+
+GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
+{
+ LOGWEBGL("getContextAttributes()");
+ return m_internal->getContextAttributes();
+}
+
+GC3Denum GraphicsContext3D::getError()
+{
+ LOGWEBGL("getError()");
+ return m_internal->getError();
+}
+
+void GraphicsContext3D::getFloatv(GC3Denum pname, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetFloatv(%lu, %p)", pname, value);
+ makeContextCurrent();
+ glGetFloatv(pname, value);
+}
+
+void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment,
+ GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetFramebufferAttachmentParameteriv(%lu, %lu, %lu, %p)",
+ target, attachment, pname, value);
+ makeContextCurrent();
+ if (attachment == DEPTH_STENCIL_ATTACHMENT)
+ attachment = DEPTH_ATTACHMENT;
+ glGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
+}
+
+void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetIntegerv(%lu, %p)", pname, value);
+ makeContextCurrent();
+ glGetIntegerv(pname, value);
+}
+
+void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetProgramiv(%lu, %lu, %p)", program, pname, value);
+ makeContextCurrent();
+ glGetProgramiv(program, pname, value);
+}
+
+String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
+{
+ LOGWEBGL("glGetProgramInfoLog(%lu)", program);
+ makeContextCurrent();
+ GLint length;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
+ if (!length)
+ return "";
+
+ GLsizei size;
+ GLchar* info = (GLchar*)fastMalloc(length);
+ glGetProgramInfoLog(program, length, &size, info);
+ String s(info);
+ fastFree(info);
+
+ return s;
+}
+
+void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetRenderbufferParameteriv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetRenderbufferParameteriv(target, pname, value);
+}
+
+void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetShaderiv(%lu, %lu, %p)", shader, pname, value);
+ makeContextCurrent();
+ glGetShaderiv(shader, pname, value);
+}
+
+String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderInfoLog(%lu)", shader);
+ makeContextCurrent();
+ return m_internal->getShaderInfoLog(shader);
+}
+
+String GraphicsContext3D::getShaderSource(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderSource(%lu)", shader);
+ makeContextCurrent();
+ return m_internal->getShaderSource(shader);
+}
+
+String GraphicsContext3D::getString(GC3Denum name)
+{
+ LOGWEBGL("glGetString(%lu)", name);
+ makeContextCurrent();
+ return String(reinterpret_cast<const char*>(glGetString(name)));
+}
+
+void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetTexParameterfv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetTexParameterfv(target, pname, value);
+}
+
+void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetTexParameteriv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetTexParameteriv(target, pname, value);
+}
+
+void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetUniformfv(%lu, %ld, %p)", program, location, value);
+ makeContextCurrent();
+ glGetUniformfv(program, location, value);
+}
+
+void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
+{
+ LOGWEBGL("glGetUniformiv(%lu, %ld, %p)", program, location, value);
+ makeContextCurrent();
+ glGetUniformiv(program, location, value);
+}
+
+GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
+{
+ CString cs = name.utf8();
+ LOGWEBGL("glGetUniformLocation(%lu, %s)", program, cs.data());
+ makeContextCurrent();
+ return glGetUniformLocation(program, cs.data());
+}
+
+void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetVertexAttribfv(%lu, %lu, %p)", index, pname, value);
+ makeContextCurrent();
+ glGetVertexAttribfv(index, pname, value);
+}
+
+void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetVertexAttribiv(%lu, %lu, %p)", index, pname, value);
+ makeContextCurrent();
+ glGetVertexAttribiv(index, pname, value);
+}
+
+GC3Dsizeiptr GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
+{
+ LOGWEBGL("glGetVertexAttribOffset(%lu, %lu)", index, pname);
+ GLvoid* pointer = 0;
+ glGetVertexAttribPointerv(index, pname, &pointer);
+ return static_cast<GC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
+}
+
+void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode)
+{
+ LOGWEBGL("glHint(%lu, %lu)", target, mode);
+ makeContextCurrent();
+ glHint(target, mode);
+}
+
+GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer)
+{
+ LOGWEBGL("glIsBuffer(%lu)", buffer);
+ if (!buffer)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsBuffer(buffer);
+}
+
+GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
+{
+ LOGWEBGL("glIsEnabled(%lu)", cap);
+ makeContextCurrent();
+ return glIsEnabled(cap);
+}
+
+GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
+{
+ LOGWEBGL("glIsFramebuffer(%lu)", framebuffer);
+ if (!framebuffer)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsFramebuffer(framebuffer);
+}
+
+GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject program)
+{
+ LOGWEBGL("glIsProgram(%lu)", program);
+ if (!program)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsProgram(program);
+}
+
+GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
+{
+ LOGWEBGL("glIsRenderbuffer(%lu)", renderbuffer);
+ if (!renderbuffer)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsRenderbuffer(renderbuffer);
+}
+
+GC3Dboolean GraphicsContext3D::isShader(Platform3DObject shader)
+{
+ LOGWEBGL("glIsShader(%lu)", shader);
+ if (!shader)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsShader(shader);
+}
+
+GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture)
+{
+ LOGWEBGL("glIsTexture(%lu)", texture);
+ if (!texture)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsTexture(texture);
+}
+
+void GraphicsContext3D::lineWidth(GC3Dfloat width)
+{
+ LOGWEBGL("glLineWidth(%.2lf)", width);
+ makeContextCurrent();
+ glLineWidth((GLfloat)width);
+}
+
+void GraphicsContext3D::linkProgram(Platform3DObject program)
+{
+ LOGWEBGL("glLinkProgram(%lu)", program);
+ makeContextCurrent();
+ glLinkProgram(program);
+}
+
+void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param)
+{
+ LOGWEBGL("glPixelStorei(%lu, %ld)", pname, param);
+ makeContextCurrent();
+ glPixelStorei(pname, param);
+}
+
+void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
+{
+ LOGWEBGL("glPolygonOffset(%.2lf, %.2lf)", factor, units);
+ makeContextCurrent();
+ glPolygonOffset((GLfloat)factor, (GLfloat)units);
+}
+
+void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, void* data)
+{
+ LOGWEBGL("glReadPixels(%ld, %ld, %lu, %lu, %lu, %lu, %p)",
+ x, y, width, height, format, type, data);
+ makeContextCurrent();
+ glReadPixels(x, y, width, height, format, type, data);
+}
+
+void GraphicsContext3D::releaseShaderCompiler()
+{
+ LOGWEBGL("glReleaseShaderCompiler()");
+ makeContextCurrent();
+ glReleaseShaderCompiler();
+}
+
+void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height)
+{
+ LOGWEBGL("glRenderbufferStorage(%lu, %lu, %lu, %lu)",
+ target, internalformat, width, height);
+ makeContextCurrent();
+ glRenderbufferStorage(target, internalformat, width, height);
+}
+
+void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
+{
+ LOGWEBGL("glSampleCoverage(%.2lf, %s)", value, invert ? "true" : "false");
+ makeContextCurrent();
+ glSampleCoverage(CLAMP(value), invert);
+}
+
+void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ LOGWEBGL("glScissor(%ld, %ld, %lu, %lu)", x, y, width, height);
+ makeContextCurrent();
+ glScissor(x, y, width, height);
+}
+
+void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& source)
+{
+ LOGWEBGL("shaderSource(%lu, %s)", shader, source.utf8().data());
+ makeContextCurrent();
+ m_internal->shaderSource(shader, source);
+}
+
+void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ LOGWEBGL("glStencilFunc(%lu, %ld, %lu)", func, ref, mask);
+ makeContextCurrent();
+ glStencilFunc(func, ref, mask);
+}
+
+void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ LOGWEBGL("glStencilFuncSeparate(%lu, %lu, %ld, %lu)", face, func, ref, mask);
+ makeContextCurrent();
+ glStencilFuncSeparate(face, func, ref, mask);
+}
+
+void GraphicsContext3D::stencilMask(GC3Duint mask)
+{
+ LOGWEBGL("glStencilMask(%lu)", mask);
+ makeContextCurrent();
+ glStencilMask(mask);
+}
+
+void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
+{
+ LOGWEBGL("glStencilMaskSeparate(%lu, %lu)", face, mask);
+ makeContextCurrent();
+ glStencilMaskSeparate(face, mask);
+}
+
+void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+ LOGWEBGL("glStencilOp(%lu, %lu, %lu)", fail, zfail, zpass);
+ makeContextCurrent();
+ glStencilOp(fail, zfail, zpass);
+}
+
+void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail,
+ GC3Denum zfail, GC3Denum zpass)
+{
+ LOGWEBGL("glStencilOpSeparate(%lu, %lu, %lu, %lu)", face, fail, zfail, zpass);
+ makeContextCurrent();
+ glStencilOpSeparate(face, fail, zfail, zpass);
+}
+
+bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type, const void* pixels)
+{
+ LOGWEBGL("glTexImage2D(%u, %u, %u, %u, %u, %u, %u, %u, %p)",
+ target, level, internalformat, width, height, border, format, type, pixels);
+ if (width && height && !pixels) {
+ synthesizeGLError(INVALID_VALUE);
+ return false;
+ }
+ makeContextCurrent();
+ glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+ return true;
+}
+
+void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
+{
+ LOGWEBGL("glTexParameterf(%u, %u, %f)", target, pname, param);
+ makeContextCurrent();
+ glTexParameterf(target, pname, param);
+}
+
+void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
+{
+ LOGWEBGL("glTexParameteri(%u, %u, %d)", target, pname, param);
+ makeContextCurrent();
+ glTexParameteri(target, pname, param);
+}
+
+void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset,
+ GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, const void* pixels)
+{
+ LOGWEBGL("glTexSubImage2D(%u, %u, %u, %u, %u, %u, %u, %u, %p)", target, level, xoffset,
+ yoffset, width, height, format, type, pixels);
+ if (width && height && !pixels) {
+ synthesizeGLError(INVALID_VALUE);
+ return;
+ }
+ makeContextCurrent();
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat x)
+{
+ LOGWEBGL("glUniform1f(%ld, %f)", location, x);
+ makeContextCurrent();
+ glUniform1f(location, x);
+}
+
+void GraphicsContext3D::uniform1fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform1fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform1fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint x)
+{
+ LOGWEBGL("glUniform1i(%ld, %d)", location, x);
+ makeContextCurrent();
+ glUniform1i(location, x);
+}
+
+void GraphicsContext3D::uniform1iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform1iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform1iv(location, size, v);
+}
+
+void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat x, float y)
+{
+ LOGWEBGL("glUniform2f(%ld, %f, %f)", location, x, y);
+ makeContextCurrent();
+ glUniform2f(location, x, y);
+}
+
+void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform2fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform2fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint x, GC3Dint y)
+{
+ LOGWEBGL("glUniform2i(%ld, %d, %d)", location, x, y);
+ makeContextCurrent();
+ glUniform2i(location, x, y);
+}
+
+void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform2iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform2iv(location, size, v);
+}
+
+void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
+{
+ LOGWEBGL("glUniform3f(%ld, %f, %f, %f)", location, x, y, z);
+ makeContextCurrent();
+ glUniform3f(location, x, y, z);
+}
+
+void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform3fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform3fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z)
+{
+ LOGWEBGL("glUniform3i(%ld, %d, %d, %d)", location, x, y, z);
+ makeContextCurrent();
+ glUniform3i(location, x, y, z);
+}
+
+void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform3iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform3iv(location, size, v);
+}
+
+void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y,
+ GC3Dfloat z, GC3Dfloat w)
+{
+ LOGWEBGL("glUniform4f(%ld, %f, %f, %f, %f)", location, x, y, z, w);
+ makeContextCurrent();
+ glUniform4f(location, x, y, z, w);
+}
+
+void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform4fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform4fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
+{
+ LOGWEBGL("glUniform4i(%ld, %d, %d, %d, %d)", location, x, y, z, w);
+ makeContextCurrent();
+ glUniform4i(location, x, y, z, w);
+}
+
+void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform4iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform4iv(location, size, v);
+}
+
+void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dboolean transpose,
+ GC3Dfloat* value, GC3Dsizei size)
+{
+ LOGWEBGL("glUniformMatrix2fv(%ld, %s, %p, %d)",
+ location, transpose ? "true" : "false", value, size);
+ makeContextCurrent();
+ glUniformMatrix2fv(location, size, transpose, value);
+}
+
+void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dboolean transpose,
+ GC3Dfloat* value, GC3Dsizei size)
+{
+ LOGWEBGL("glUniformMatrix3fv(%ld, %s, %p, %d)",
+ location, transpose ? "true" : "false", value, size);
+ makeContextCurrent();
+ glUniformMatrix3fv(location, size, transpose, value);
+}
+
+void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dboolean transpose,
+ GC3Dfloat* value, GC3Dsizei size)
+{
+ LOGWEBGL("glUniformMatrix4fv(%ld, %s, %p, %d)",
+ location, transpose ? "true" : "false", value, size);
+ makeContextCurrent();
+ glUniformMatrix4fv(location, size, transpose, value);
+}
+
+void GraphicsContext3D::useProgram(Platform3DObject program)
+{
+ LOGWEBGL("glUseProgram(%lu)", program);
+ makeContextCurrent();
+ glUseProgram(program);
+}
+
+void GraphicsContext3D::validateProgram(Platform3DObject program)
+{
+ LOGWEBGL("glValidateProgram(%lu)", program);
+ makeContextCurrent();
+ glValidateProgram(program);
+}
+
+void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat x)
+{
+ LOGWEBGL("glVertexAttrib1f(%lu, %f)", index, x);
+ makeContextCurrent();
+ glVertexAttrib1f(index, x);
+}
+
+void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib1fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib1fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y)
+{
+ LOGWEBGL("glVertexAttrib2f(%lu, %f, %f)", index, x, y);
+ makeContextCurrent();
+ glVertexAttrib2f(index, x, y);
+}
+
+void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib2fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib2fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
+{
+ LOGWEBGL("glVertexAttrib3f(%lu, %f, %f, %f)", index, x, y, z);
+ makeContextCurrent();
+ glVertexAttrib3f(index, x, y, z);
+}
+
+void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib3fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib3fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y,
+ GC3Dfloat z, GC3Dfloat w)
+{
+ LOGWEBGL("glVertexAttrib4f(%lu, %f, %f, %f, %f)", index, x, y, z, w);
+ makeContextCurrent();
+ glVertexAttrib4f(index, x, y, z, w);
+}
+
+void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib4fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib4fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type,
+ GC3Dboolean normalized, GC3Dsizei stride,
+ GC3Dintptr offset)
+{
+ LOGWEBGL("glVertexAttribPointer(%lu, %d, %d, %s, %lu, %lu)", index, size, type,
+ normalized ? "true" : "false", stride, offset);
+ makeContextCurrent();
+ glVertexAttribPointer(index, size, type, normalized, stride,
+ reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
+}
+
+void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ LOGWEBGL("viewport(%ld, %ld, %lu, %lu)", x, y, width, height);
+ makeContextCurrent();
+ m_internal->viewport(x, y, width, height);
+}
+
+void GraphicsContext3D::reshape(int width, int height)
+{
+ LOGWEBGL("reshape(%d, %d)", width, height);
+ if ((width == m_currentWidth) && (height == m_currentHeight)) {
+ return;
+ }
+ m_internal->reshape(width, height);
+ m_currentWidth = m_internal->width();
+ m_currentHeight = m_internal->height();
+}
+
+void GraphicsContext3D::recreateSurface()
+{
+ LOGWEBGL("recreateSurface()");
+ m_internal->recreateSurface();
+}
+
+void GraphicsContext3D::releaseSurface()
+{
+ LOGWEBGL("releaseSurface()");
+ m_internal->releaseSurface();
+}
+
+IntSize GraphicsContext3D::getInternalFramebufferSize()
+{
+ return IntSize(m_currentWidth, m_currentHeight);
+}
+
+void GraphicsContext3D::markContextChanged()
+{
+ LOGWEBGL("markContextChanged()");
+ m_internal->markContextChanged();
+}
+
+void GraphicsContext3D::markLayerComposited()
+{
+ LOGWEBGL("markLayerComposited()");
+ m_internal->markLayerComposited();
+}
+
+bool GraphicsContext3D::layerComposited() const
+{
+ LOGWEBGL("layerComposited()");
+ return m_internal->layerComposited();
+}
+
+void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
+{
+}
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp
new file mode 100644
index 0000000..7855739
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 SONY ERICSSON MOBILE COMMUNICATIONS AB 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 "GraphicsContext3DInternal.h"
+
+#include "CurrentTime.h"
+#include "Frame.h"
+#include "HostWindow.h"
+#include "HTMLCanvasElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "PlatformGraphicsContext.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#include "RenderObject.h"
+#include "TilesManager.h"
+#include "TransformationMatrix.h"
+#include "WebViewCore.h"
+
+#include "SkBitmap.h"
+#include "SkDevice.h"
+#include <binder/IBinder.h>
+#include <hardware/hardware.h>
+#include <private/gui/ComposerService.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <JNIUtility.h>
+
+#if ENABLE(WEBGL)
+namespace WebCore {
+
+class WebGLFPSTimer {
+public:
+ WebGLFPSTimer()
+ : m_ticks(0)
+ {
+ m_startTime = currentTime();
+ }
+
+ void tick()
+ {
+ if (++m_ticks == s_sampleRate)
+ reset();
+ }
+
+ void reset()
+ {
+ double totalTime = currentTime() - m_startTime;
+ if (totalTime > 0) {
+ double averageFPS = m_ticks / totalTime;
+ LOGWEBGL("Average FPS: %0.3f", averageFPS);
+ }
+
+ m_ticks = 0;
+ m_startTime = currentTime();
+ }
+
+private:
+ long m_ticks;
+ double m_startTime;
+
+ static const int s_sampleRate;
+};
+
+const int WebGLFPSTimer::s_sampleRate = 15;
+
+#define OLD_GRAPHICBUFFER_ALLOC
+class FBO {
+public:
+ static FBO* createFBO(EGLDisplay dpy, int width, int height, GraphicsContext3D::Attributes attrs);
+ ~FBO();
+
+ EGLSyncKHR sync() { return m_sync; }
+ void setSync(EGLSyncKHR sync) { m_sync = sync; }
+
+ GLuint fbo() { return m_fbo; }
+ EGLImageKHR image() { return m_image; }
+
+ bool isLocked() { return m_locked; }
+ void setLocked(bool locked) { m_locked = locked; }
+
+ bool lockGraphicBuffer(void** ptr) {
+ return (m_grBuffer.get() &&
+ (m_grBuffer->lock(GraphicBuffer::USAGE_SW_READ_RARELY, ptr) == NO_ERROR));
+ }
+ void unlockGraphicBuffer() {
+ if (m_grBuffer.get())
+ m_grBuffer->unlock();
+ }
+
+ int bytesPerRow() { return m_grBuffer.get() ? m_grBuffer->getStride() * 4 : 0; }
+
+private:
+ FBO(EGLDisplay dpy);
+ bool init(int width, int height, GraphicsContext3D::Attributes attrs);
+
+ GLuint createTexture(EGLImageKHR image, int width, int height);
+
+ EGLDisplay m_dpy;
+ GLuint m_texture;
+ GLuint m_fbo;
+ GLuint m_depthBuffer;
+ GLuint m_stencilBuffer;
+ EGLImageKHR m_image;
+ EGLSyncKHR m_sync;
+ sp<IGraphicBufferAlloc> m_graphicBufferAlloc;
+ sp<GraphicBuffer> m_grBuffer;
+ bool m_locked;
+};
+
+
+#define CANVAS_MAX_WIDTH 1280
+#define CANVAS_MAX_HEIGHT 1280
+
+bool GraphicsContext3DInternal::s_loggingEnabled = false;
+
+EGLint GraphicsContext3DInternal::checkEGLError(const char* s)
+{
+ EGLint error = eglGetError();
+ if (error == EGL_SUCCESS) {
+ LOGWEBGL("%s() OK", s);
+ }
+ else {
+ LOGWEBGL("after %s() eglError = 0x%x", s, error);
+ }
+
+ return error;
+}
+
+GLint GraphicsContext3DInternal::checkGLError(const char* s)
+{
+ GLint error = glGetError();
+ if (error == GL_NO_ERROR) {
+ LOGWEBGL("%s() OK", s);
+ }
+ else {
+ LOGWEBGL("after %s() glError (0x%x)", s, error);
+ }
+
+ return error;
+}
+
+GraphicsContext3DInternal::GraphicsContext3DInternal(HTMLCanvasElement* canvas,
+ GraphicsContext3D::Attributes attrs,
+ HostWindow* hostWindow)
+ : m_proxy(adoptRef(new GraphicsContext3DProxy()))
+ , m_compositingLayer(new WebGLLayer(m_proxy))
+ , m_canvas(canvas)
+ , m_attrs(attrs)
+ , m_layerComposited(false)
+ , m_canvasDirty(false)
+ , m_width(1)
+ , m_height(1)
+ , m_maxwidth(CANVAS_MAX_WIDTH)
+ , m_maxheight(CANVAS_MAX_HEIGHT)
+ , m_dpy(EGL_NO_DISPLAY)
+ , m_config(0)
+ , m_surface(EGL_NO_SURFACE)
+ , m_context(EGL_NO_CONTEXT)
+ , m_syncThread(0)
+ , m_threadState(THREAD_STATE_STOPPED)
+ , m_syncTimer(this, &GraphicsContext3DInternal::syncTimerFired)
+ , m_syncRequested(false)
+ , m_webGLFPSTimer(0)
+ , m_extensions(0)
+ , m_contextId(0)
+{
+ enableLogging();
+
+ //Need to initialize to a NULL state so that if you FBO creation fails later on, its in a valid state during destruction
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ m_fbo[i] = NULL;
+ }
+
+ LOGWEBGL("GraphicsContext3DInternal() = %p, m_compositingLayer = %p", this, m_compositingLayer);
+ m_proxy->setGraphicsContext(this);
+
+ if (!m_canvas || !m_canvas->document() || !m_canvas->document()->view())
+ return;
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ WebViewCore* core = WebViewCore::getWebViewCore(m_canvas->document()->view());
+ if (!core)
+ return;
+ jobject tmp = core->getWebViewJavaObject();
+ m_webView = env->NewGlobalRef(tmp);
+ if (!m_webView)
+ return;
+ jclass webViewClass = env->GetObjectClass(m_webView);
+ m_postInvalidate = env->GetMethodID(webViewClass, "postInvalidate", "()V");
+ env->DeleteLocalRef(webViewClass);
+ if (!m_postInvalidate)
+ return;
+
+ if (!initEGL())
+ return;
+
+ if (!createContext(true)) {
+ LOGWEBGL("Create context failed. Perform JS garbage collection and try again.");
+ // Probably too many contexts. Force a JS garbage collection, and then try again.
+ // This typically only happens in Khronos Conformance tests.
+ m_canvas->document()->frame()->script()->lowMemoryNotification();
+ if (!createContext(true)) {
+ LOGWEBGL("Create context still failed: aborting.");
+ return;
+ }
+ }
+
+ m_webGLFPSTimer.set(new WebGLFPSTimer());
+
+ const char *ext = (const char *)glGetString(GL_EXTENSIONS);
+ LOGWEBGL("GL_EXTENSIONS = %s", ext);
+ // Want to keep control of which extensions are used
+ String extensions = "";
+ if (strstr(ext, "GL_OES_texture_npot"))
+ extensions.append("GL_OES_texture_npot");
+ if (strstr(ext, "GL_OES_packed_depth_stencil"))
+ extensions.append(" GL_OES_packed_depth_stencil");
+ if (strstr(ext, "GL_OES_texture_float"))
+ extensions.append(" GL_OES_texture_float");
+ m_extensions.set(new Extensions3DAndroid(extensions));
+
+ // ANGLE initialization.
+ ShBuiltInResources resources;
+ ShInitBuiltInResources(&resources);
+
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &resources.MaxVertexAttribs);
+ glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &resources.MaxVertexUniformVectors);
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &resources.MaxVaryingVectors);
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &resources.MaxVertexTextureImageUnits);
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &resources.MaxCombinedTextureImageUnits);
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &resources.MaxTextureImageUnits);
+ glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &resources.MaxFragmentUniformVectors);
+
+ resources.MaxDrawBuffers = 1;
+ m_compiler.setResources(resources);
+
+ m_savedViewport.x = 0;
+ m_savedViewport.y = 0;
+ m_savedViewport.width = m_width;
+ m_savedViewport.height = m_height;
+
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ startSyncThread();
+
+ static int contextCounter = 1;
+ m_contextId = contextCounter++;
+}
+
+GraphicsContext3DInternal::~GraphicsContext3DInternal()
+{
+ LOGWEBGL("~GraphicsContext3DInternal(), this = %p", this);
+
+ stopSyncThread();
+
+ m_proxy->setGraphicsContext(0);
+ MutexLocker lock(m_fboMutex);
+ SkSafeUnref(m_compositingLayer);
+ m_compositingLayer = 0;
+ deleteContext(true);
+
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->DeleteGlobalRef(m_webView);
+}
+
+bool GraphicsContext3DInternal::initEGL()
+{
+ m_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_dpy == EGL_NO_DISPLAY)
+ return false;
+
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLBoolean returnValue = eglInitialize(m_dpy, &majorVersion, &minorVersion);
+ if (returnValue != EGL_TRUE)
+ return false;
+
+ LOGWEBGL("EGL version %d.%d", majorVersion, minorVersion);
+ const char *s = eglQueryString(m_dpy, EGL_VENDOR);
+ LOGWEBGL("EGL_VENDOR = %s", s);
+ s = eglQueryString(m_dpy, EGL_VERSION);
+ LOGWEBGL("EGL_VERSION = %s", s);
+ s = eglQueryString(m_dpy, EGL_EXTENSIONS);
+ LOGWEBGL("EGL_EXTENSIONS = %s", s);
+ s = eglQueryString(m_dpy, EGL_CLIENT_APIS);
+ LOGWEBGL("EGL_CLIENT_APIS = %s", s);
+
+ EGLint config_attribs[21];
+ int p = 0;
+ config_attribs[p++] = EGL_BLUE_SIZE;
+ config_attribs[p++] = 8;
+ config_attribs[p++] = EGL_GREEN_SIZE;
+ config_attribs[p++] = 8;
+ config_attribs[p++] = EGL_RED_SIZE;
+ config_attribs[p++] = 8;
+ config_attribs[p++] = EGL_SURFACE_TYPE;
+ config_attribs[p++] = EGL_PBUFFER_BIT;
+ config_attribs[p++] = EGL_RENDERABLE_TYPE;
+ config_attribs[p++] = EGL_OPENGL_ES2_BIT;
+ config_attribs[p++] = EGL_ALPHA_SIZE;
+ config_attribs[p++] = m_attrs.alpha ? 8 : 0;
+ if (m_attrs.depth) {
+ config_attribs[p++] = EGL_DEPTH_SIZE;
+ config_attribs[p++] = 16;
+ }
+ if (m_attrs.stencil) {
+ config_attribs[p++] = EGL_STENCIL_SIZE;
+ config_attribs[p++] = 8;
+ }
+ // Antialiasing currently is not supported.
+ m_attrs.antialias = false;
+ config_attribs[p] = EGL_NONE;
+
+ EGLint num_configs = 0;
+ return (eglChooseConfig(m_dpy, config_attribs, &m_config, 1, &num_configs) == EGL_TRUE);
+}
+
+bool GraphicsContext3DInternal::createContext(bool createEGLContext)
+{
+ LOGWEBGL("createContext()");
+ EGLint context_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE};
+
+ if (createEGLContext) {
+ EGLint surface_attribs[] = {
+ EGL_WIDTH, 1,
+ EGL_HEIGHT, 1,
+ EGL_NONE};
+ m_surface = eglCreatePbufferSurface(m_dpy, m_config, surface_attribs);
+ m_context = eglCreateContext(m_dpy, m_config, EGL_NO_CONTEXT, context_attribs);
+ }
+ if (m_context == EGL_NO_CONTEXT) {
+ deleteContext(createEGLContext);
+ return false;
+ }
+
+ makeContextCurrent();
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ FBO* tmp = FBO::createFBO(m_dpy, m_width > 0 ? m_width : 1, m_height > 0 ? m_height : 1, m_attrs);
+ if (tmp == 0) {
+ LOGWEBGL("Failed to create FBO");
+ deleteContext(createEGLContext);
+ return false;
+ }
+ m_fbo[i] = tmp;
+ m_freeBuffers.append(tmp);
+ }
+
+ m_currentFBO = dequeueBuffer();
+ m_boundFBO = m_currentFBO->fbo();
+ m_frontFBO = 0;
+ glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
+
+ return true;
+}
+
+void GraphicsContext3DInternal::deleteContext(bool deleteEGLContext)
+{
+ LOGWEBGL("deleteContext(%s)", deleteEGLContext ? "true" : "false");
+
+ makeContextCurrent();
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ m_freeBuffers.clear();
+ m_queuedBuffers.clear();
+ m_preparedBuffers.clear();
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ if (m_fbo[i]) {
+ delete m_fbo[i];
+ m_fbo[i] = 0;
+ }
+ }
+ m_currentFBO = 0;
+ m_frontFBO = 0;
+
+ eglMakeCurrent(m_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (deleteEGLContext) {
+ if (m_surface != EGL_NO_SURFACE) {
+ eglDestroySurface(m_dpy, m_surface);
+ m_surface = EGL_NO_SURFACE;
+ }
+ if (m_context != EGL_NO_CONTEXT) {
+ eglDestroyContext(m_dpy, m_context);
+ m_context = EGL_NO_CONTEXT;
+ }
+ }
+}
+
+void GraphicsContext3DInternal::makeContextCurrent()
+{
+ if (eglGetCurrentContext() != m_context && m_context != EGL_NO_CONTEXT) {
+ eglMakeCurrent(m_dpy, m_surface, m_surface, m_context);
+ }
+}
+
+GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes()
+{
+ return m_attrs;
+}
+
+unsigned long GraphicsContext3DInternal::getError()
+{
+ if (m_syntheticErrors.size() > 0) {
+ ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
+ unsigned long err = *iter;
+ m_syntheticErrors.remove(iter);
+ return err;
+ }
+ LOGWEBGL("glGetError()");
+ makeContextCurrent();
+ return glGetError();
+}
+
+void GraphicsContext3DInternal::synthesizeGLError(unsigned long error)
+{
+ m_syntheticErrors.add(error);
+}
+
+FBO* FBO::createFBO(EGLDisplay dpy, int width, int height, GraphicsContext3D::Attributes attributes)
+{
+ LOGWEBGL("createFBO()");
+ FBO* fbo = new FBO(dpy);
+
+ if (!fbo->init(width, height, attributes)) {
+ delete fbo;
+ return 0;
+ }
+ return fbo;
+}
+
+FBO::FBO(EGLDisplay dpy)
+ : m_dpy(dpy)
+ , m_texture(0)
+ , m_fbo(0)
+ , m_depthBuffer(0)
+ , m_image(0)
+ , m_sync(0)
+ , m_grBuffer(0)
+ , m_locked(false)
+{
+}
+
+bool FBO::init(int width, int height, GraphicsContext3D::Attributes attributes)
+{
+ // 1. Allocate a graphic buffer
+ sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+ m_graphicBufferAlloc = composer->createGraphicBufferAlloc();
+
+ status_t error;
+
+ PixelFormat format = attributes.alpha ? HAL_PIXEL_FORMAT_RGBA_8888 : HAL_PIXEL_FORMAT_RGBX_8888;
+
+ m_grBuffer = m_graphicBufferAlloc->createGraphicBuffer(width, height, format,
+ GRALLOC_USAGE_HW_TEXTURE, &error);
+ if (error != NO_ERROR) {
+ LOGWEBGL(" failed to allocate GraphicBuffer, error = %d", error);
+ return false;
+ }
+
+ void *addr = 0;
+ if (m_grBuffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, &addr) != NO_ERROR) {
+ LOGWEBGL(" failed to lock the GraphicBuffer");
+ return false;
+ }
+ // WebGL requires all buffers to be initialized to 0.
+ memset(addr, 0, width * height * 4);
+ m_grBuffer->unlock();
+
+ ANativeWindowBuffer* clientBuf = m_grBuffer->getNativeBuffer();
+ if (clientBuf->handle == 0) {
+ LOGWEBGL(" empty handle in GraphicBuffer");
+ return false;
+ }
+
+ // 2. Create an EGLImage from the graphic buffer
+ const EGLint attrs[] = {
+ EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+ EGL_NONE, EGL_NONE
+ };
+
+ m_image = eglCreateImageKHR(m_dpy,
+ EGL_NO_CONTEXT,
+ EGL_NATIVE_BUFFER_ANDROID,
+ (EGLClientBuffer)clientBuf,
+ attrs);
+ if (GraphicsContext3DInternal::checkEGLError("eglCreateImageKHR") != EGL_SUCCESS) {
+ LOGWEBGL("eglCreateImageKHR() failed");
+ return false;
+ }
+
+ // 3. Create a texture from the EGLImage
+ m_texture = createTexture(m_image, width, height);
+ if (m_texture == 0) {
+ LOGWEBGL("createTexture() failed");
+ return false;
+ }
+
+ // 4. Create the Framebuffer Object from the texture
+ glGenFramebuffers(1, &m_fbo);
+
+ if (attributes.depth) {
+ glGenRenderbuffers(1, &m_depthBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
+ if (GraphicsContext3DInternal::checkGLError("glRenderbufferStorage") != GL_NO_ERROR)
+ return false;
+ }
+
+ if (attributes.stencil) {
+ glGenRenderbuffers(1, &m_stencilBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
+ if (GraphicsContext3DInternal::checkGLError("glRenderbufferStorage") != GL_NO_ERROR)
+ return false;
+ }
+
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
+ if (GraphicsContext3DInternal::checkGLError("glFramebufferTexture2D") != GL_NO_ERROR)
+ return false;
+
+ if (attributes.depth) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
+ if (GraphicsContext3DInternal::checkGLError("glFramebufferRenderbuffer") != GL_NO_ERROR)
+ return false;
+ }
+
+ if (attributes.stencil) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer);
+ if (GraphicsContext3DInternal::checkGLError("glFramebufferRenderbuffer") != GL_NO_ERROR)
+ return false;
+ }
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOGWEBGL("Framebuffer incomplete: %d", status);
+ return false;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return true;
+}
+
+FBO::~FBO()
+{
+ LOGWEBGL("FBO::~FBO()");
+ if (m_image) {
+ eglDestroyImageKHR(m_dpy, m_image);
+ GraphicsContext3DInternal::checkEGLError("eglDestroyImageKHR");
+ }
+ if (m_texture)
+ glDeleteTextures(1, &m_texture);
+ if (m_depthBuffer)
+ glDeleteRenderbuffers(1, &m_depthBuffer);
+ if (m_stencilBuffer)
+ glDeleteRenderbuffers(1, &m_stencilBuffer);
+ if (m_fbo)
+ glDeleteFramebuffers(1, &m_fbo);
+}
+
+GLuint FBO::createTexture(EGLImageKHR image, int width, int height)
+{
+ LOGWEBGL("createTexture(image = %p)", image);
+ GLuint texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ bool error = false;
+ if (image) {
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+ error = (GraphicsContext3DInternal::checkGLError("glEGLImageTargetTexture2DOES")
+ != GL_NO_ERROR);
+ }
+ else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ error = (GraphicsContext3DInternal::checkGLError("glTexImage2D()") != GL_NO_ERROR);
+ }
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if (error) {
+ glDeleteTextures(1, &texture);
+ texture = 0;
+ }
+
+ return texture;
+}
+
+void GraphicsContext3DInternal::startSyncThread()
+{
+ LOGWEBGL("+startSyncThread()");
+ MutexLocker lock(m_threadMutex);
+ m_threadState = THREAD_STATE_STOPPED;
+ m_syncThread = createThread(syncThreadStart, this, "GraphicsContext3DInternal");
+ // Wait for thread to start
+ while (m_threadState != THREAD_STATE_RUN) {
+ m_threadCondition.wait(m_threadMutex);
+ }
+ LOGWEBGL("-startSyncThread()");
+}
+
+void GraphicsContext3DInternal::stopSyncThread()
+{
+ LOGWEBGL("+stopSyncThread()");
+ MutexLocker lock(m_threadMutex);
+ if (m_syncThread) {
+ m_threadState = THREAD_STATE_STOP;
+ // Signal thread to wake up
+ m_threadCondition.broadcast();
+ // Wait for thread to stop
+ while (m_threadState != THREAD_STATE_STOPPED) {
+ m_threadCondition.wait(m_threadMutex);
+ }
+ m_syncThread = 0;
+ }
+ LOGWEBGL("-stopSyncThread()");
+}
+
+void* GraphicsContext3DInternal::syncThreadStart(void* ctx)
+{
+ GraphicsContext3DInternal* context = static_cast<GraphicsContext3DInternal*>(ctx);
+ context->runSyncThread();
+
+ return 0;
+}
+
+void GraphicsContext3DInternal::runSyncThread()
+{
+ LOGWEBGL("SyncThread: starting");
+ FBO* fbo = 0;
+
+ MutexLocker lock(m_threadMutex);
+ m_threadState = THREAD_STATE_RUN;
+ // Signal to creator that we are up and running
+ m_threadCondition.broadcast();
+
+ while (m_threadState == THREAD_STATE_RUN) {
+ while (m_threadState == THREAD_STATE_RUN) {
+ {
+ MutexLocker lock(m_fboMutex);
+ if (!m_queuedBuffers.isEmpty()) {
+ fbo = m_queuedBuffers.takeFirst();
+ break;
+ }
+ }
+ m_threadCondition.wait(m_threadMutex);
+ }
+ LOGWEBGL("SyncThread: woke after waiting for FBO, fbo = %p", fbo);
+ if (m_threadState != THREAD_STATE_RUN)
+ break;
+
+ if (fbo->sync() != EGL_NO_SYNC_KHR) {
+ eglClientWaitSyncKHR(m_dpy, fbo->sync(), 0, 0);
+ eglDestroySyncKHR(m_dpy, fbo->sync());
+ fbo->setSync(EGL_NO_SYNC_KHR);
+ LOGWEBGL("SyncThread: returned after waiting for Sync");
+ }
+
+ {
+ MutexLocker lock(m_fboMutex);
+ m_preparedBuffers.append(fbo);
+ LOGWEBGL("SyncThread: prepared buffer = %p", fbo);
+ updateFrontBuffer();
+ }
+
+ // Invalidate the canvas region
+ if (m_postInvalidate) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_webView, m_postInvalidate);
+ }
+ }
+
+ // Signal to calling thread that we have stopped
+ m_threadState = THREAD_STATE_STOPPED;
+ m_threadCondition.broadcast();
+ LOGWEBGL("SyncThread: terminating");
+}
+
+PlatformLayer* GraphicsContext3DInternal::platformLayer() const
+{
+ LOGWEBGL("platformLayer()");
+ return m_compositingLayer;
+}
+
+void GraphicsContext3DInternal::reshape(int width, int height)
+{
+ LOGWEBGL("reshape(%d, %d)", width, height);
+ bool mustRestoreFBO = (m_boundFBO != (m_currentFBO ? m_currentFBO->fbo() : 0));
+
+ m_width = width > m_maxwidth ? m_maxwidth : width;
+ m_height = height > m_maxheight ? m_maxheight : height;
+
+ stopSyncThread();
+ makeContextCurrent();
+ m_proxy->setGraphicsContext(0);
+ {
+ MutexLocker lock(m_fboMutex);
+ deleteContext(false);
+
+ if (createContext(false)) {
+ if (!mustRestoreFBO) {
+ m_boundFBO = m_currentFBO->fbo();
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
+ }
+ }
+ m_proxy->setGraphicsContext(this);
+ startSyncThread();
+}
+
+void GraphicsContext3DInternal::recreateSurface()
+{
+ LOGWEBGL("recreateSurface()");
+ if (m_currentFBO != 0)
+ // We already have a current surface
+ return;
+ reshape(m_width, m_height);
+ glViewport(m_savedViewport.x, m_savedViewport.y, m_savedViewport.width, m_savedViewport.height);
+}
+
+void GraphicsContext3DInternal::releaseSurface()
+{
+ LOGWEBGL("releaseSurface(%d)", m_contextId);
+ if (m_currentFBO == 0)
+ // We don't have any current surface
+ return;
+ stopSyncThread();
+ m_proxy->setGraphicsContext(0);
+ {
+ MutexLocker lock(m_fboMutex);
+ deleteContext(false);
+ }
+ makeContextCurrent();
+ m_proxy->setGraphicsContext(this);
+}
+
+void GraphicsContext3DInternal::syncTimerFired(Timer<GraphicsContext3DInternal>*)
+{
+ m_syncRequested = false;
+
+ // Do not perform the composition step if it is an offscreen canvas
+ if (m_canvas->renderer())
+ swapBuffers();
+}
+
+void GraphicsContext3DInternal::markContextChanged()
+{
+ if (!m_syncRequested) {
+ m_syncTimer.startOneShot(0);
+ m_syncRequested = true;
+ }
+ m_canvasDirty = true;
+ m_layerComposited = false;
+}
+
+/*
+ * Must hold m_fboMutex when calling this function.
+ */
+FBO* GraphicsContext3DInternal::dequeueBuffer()
+{
+ LOGWEBGL("GraphicsContext3DInternal::dequeueBuffer()");
+ while (m_freeBuffers.isEmpty()) {
+ m_fboCondition.wait(m_fboMutex);
+ }
+ FBO* fbo = m_freeBuffers.takeFirst();
+
+ if (fbo->sync() != EGL_NO_SYNC_KHR) {
+ eglClientWaitSyncKHR(m_dpy, fbo->sync(), 0, 0);
+ eglDestroySyncKHR(m_dpy, fbo->sync());
+ fbo->setSync(EGL_NO_SYNC_KHR);
+ }
+
+ return fbo;
+}
+
+void GraphicsContext3DInternal::swapBuffers()
+{
+ if (s_loggingEnabled)
+ m_webGLFPSTimer->tick();
+
+ LOGWEBGL("+swapBuffers()");
+
+ MutexLocker lock(m_fboMutex);
+ FBO* fbo = m_currentFBO;
+ if (fbo == 0)
+ return;
+
+ makeContextCurrent();
+
+ bool mustRestoreFBO = (m_boundFBO != fbo->fbo());
+ if (mustRestoreFBO) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo());
+ }
+
+ // Create the fence sync and notify the sync thread
+ fbo->setSync(eglCreateSyncKHR(m_dpy, EGL_SYNC_FENCE_KHR, 0));
+ glFlush();
+ m_queuedBuffers.append(fbo);
+ m_threadCondition.broadcast();
+
+ // Dequeue a new buffer
+ fbo = dequeueBuffer();
+ m_currentFBO = fbo;
+
+ if (!mustRestoreFBO) {
+ m_boundFBO = m_currentFBO->fbo();
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
+ m_canvasDirty = false;
+ m_layerComposited = true;
+ LOGWEBGL("-swapBuffers()");
+}
+
+void GraphicsContext3DInternal::updateFrontBuffer()
+{
+ if (!m_preparedBuffers.isEmpty()) {
+ if (m_frontFBO == 0) {
+ m_frontFBO = m_preparedBuffers.takeFirst();
+ }
+ else if (!m_frontFBO->isLocked()) {
+ m_freeBuffers.append(m_frontFBO);
+ m_frontFBO = m_preparedBuffers.takeFirst();
+ m_fboCondition.broadcast();
+ }
+ }
+}
+
+bool GraphicsContext3DInternal::lockFrontBuffer(EGLImageKHR& image, SkRect& rect)
+{
+ LOGWEBGL("GraphicsContext3DInternal::lockFrontBuffer()");
+ MutexLocker lock(m_fboMutex);
+ FBO* fbo = m_frontFBO;
+
+ if (!fbo || !fbo->image()) {
+ LOGWEBGL("-GraphicsContext3DInternal::lockFrontBuffer(), fbo = %p", fbo);
+ return false;
+ }
+
+ fbo->setLocked(true);
+ image = fbo->image();
+
+ RenderObject* renderer = m_canvas->renderer();
+ if (renderer && renderer->isBox()) {
+ RenderBox* box = (RenderBox*)renderer;
+ rect.setXYWH(box->borderLeft() + box->paddingLeft(),
+ box->borderTop() + box->paddingTop(),
+ box->contentWidth(),
+ box->contentHeight());
+ }
+
+ return true;
+}
+
+void GraphicsContext3DInternal::releaseFrontBuffer()
+{
+ LOGWEBGL("GraphicsContext3DInternal::releaseFrontBuffer()");
+ MutexLocker lock(m_fboMutex);
+ FBO* fbo = m_frontFBO;
+
+ if (fbo) {
+ fbo->setLocked(false);
+ if (fbo->sync() != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(m_dpy, fbo->sync());
+ }
+ fbo->setSync(eglCreateSyncKHR(m_dpy, EGL_SYNC_FENCE_KHR, 0));
+ }
+ updateFrontBuffer();
+}
+
+void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+{
+ LOGWEBGL("paintRenderingResultsToCanvas()");
+ ImageBuffer* imageBuffer = context->canvas()->buffer();
+ const SkBitmap& canvasBitmap =
+ imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false);
+ SkCanvas canvas(canvasBitmap);
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height);
+ bitmap.allocPixels();
+ unsigned char *pixels = static_cast<unsigned char*>(bitmap.getPixels());
+ glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ SkRect dstRect;
+ dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height());
+ canvas.drawBitmapRect(bitmap, 0, dstRect);
+}
+
+PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageData()
+{
+ LOGWEBGL("paintRenderingResultsToImageData()");
+
+ // Reading premultiplied alpha would involve unpremultiplying, which is lossy.
+ if (m_attrs.premultipliedAlpha)
+ return 0;
+
+ RefPtr<ImageData> imageData = ImageData::create(IntSize(m_width, m_height));
+ unsigned char* pixels = imageData->data()->data()->data();
+
+ glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ return imageData;
+}
+
+bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingContext* context)
+{
+ LOGWEBGL("paintCompositedResultsToCanvas()");
+ ImageBuffer* imageBuffer = context->canvas()->buffer();
+ const SkBitmap& canvasBitmap =
+ imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false);
+ SkCanvas canvas(canvasBitmap);
+
+ MutexLocker lock(m_fboMutex);
+
+ FBO* fbo = m_frontFBO;
+ if (!fbo)
+ return false;
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height, fbo->bytesPerRow());
+
+ unsigned char* bits = NULL;
+ if (fbo->lockGraphicBuffer((void**)&bits)) {
+ bitmap.setPixels(bits);
+
+ SkRect dstRect;
+ dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height());
+ canvas.save();
+ canvas.translate(0, SkIntToScalar(imageBuffer->size().height()));
+ canvas.scale(SK_Scalar1, -SK_Scalar1);
+ canvas.drawBitmapRect(bitmap, 0, dstRect);
+ canvas.restore();
+ bitmap.setPixels(0);
+ fbo->unlockGraphicBuffer();
+ }
+
+ return true;
+}
+
+void GraphicsContext3DInternal::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
+{
+ LOGWEBGL("glBindFrameBuffer(%d, %d)", target, buffer);
+ makeContextCurrent();
+ MutexLocker lock(m_fboMutex);
+ if (!buffer && m_currentFBO) {
+ buffer = m_currentFBO->fbo();
+ }
+ glBindFramebuffer(target, buffer);
+ m_boundFBO = buffer;
+}
+
+void GraphicsContext3DInternal::compileShader(Platform3DObject shader)
+{
+ LOGWEBGL("compileShader()");
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+ if (result == m_shaderSourceMap.end()) {
+ LOGWEBGL(" shader not found");
+ return;
+ }
+ ShaderSourceEntry& entry = result->second;
+
+ int shaderType;
+ glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType);
+
+ ANGLEShaderType ast = shaderType == GL_VERTEX_SHADER ?
+ SHADER_TYPE_VERTEX : SHADER_TYPE_FRAGMENT;
+
+ String src;
+ String log;
+ bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), ast, src, log);
+
+ entry.log = log;
+ entry.isValid = isValid;
+
+ if (!isValid) {
+ LOGWEBGL(" shader validation failed");
+ return;
+ }
+ int len = entry.source.length();
+ CString cstr = entry.source.utf8();
+ const char* s = cstr.data();
+
+ LOGWEBGL("glShaderSource(%s)", cstr.data());
+ glShaderSource(shader, 1, &s, &len);
+
+ LOGWEBGL("glCompileShader()");
+ glCompileShader(shader);
+}
+
+String GraphicsContext3DInternal::getShaderInfoLog(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderInfoLog()");
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+ if (result == m_shaderSourceMap.end()) {
+ LOGWEBGL(" shader not found");
+ return "";
+ }
+
+ ShaderSourceEntry entry = result->second;
+
+ if (entry.isValid) {
+ LOGWEBGL(" validated shader, retrieve OpenGL log");
+ GLuint shaderID = shader;
+ GLint logLength;
+ glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);
+ if (!logLength)
+ return "";
+
+ char* log = 0;
+ if ((log = (char *)fastMalloc(logLength * sizeof(char))) == 0)
+ return "";
+ GLsizei returnedLogLength;
+ glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log);
+ String res = String(log, returnedLogLength);
+ fastFree(log);
+
+ return res;
+ }
+ else {
+ LOGWEBGL(" non-validated shader, use ANGLE log");
+ return entry.log;
+ }
+}
+
+String GraphicsContext3DInternal::getShaderSource(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderSource()");
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+ if (result == m_shaderSourceMap.end())
+ return "";
+
+ return result->second.source;
+}
+
+void GraphicsContext3DInternal::shaderSource(Platform3DObject shader, const String& string)
+{
+ LOGWEBGL("shaderSource()");
+ ShaderSourceEntry entry;
+
+ entry.source = string;
+
+ m_shaderSourceMap.set(shader, entry);
+}
+
+void GraphicsContext3DInternal::viewport(long x, long y, unsigned long width, unsigned long height)
+{
+ LOGWEBGL("glViewport(%d, %d, %d, %d)", x, y, width, height);
+ glViewport(x, y, width, height);
+ m_savedViewport.x = x;
+ m_savedViewport.y = y;
+ m_savedViewport.width = width;
+ m_savedViewport.height = height;
+}
+
+void GraphicsContext3DInternal::enableLogging()
+{
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.webgl", value, "0");
+ s_loggingEnabled = atoi(value) ? true : false;
+}
+
+}
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h
new file mode 100644
index 0000000..513de49
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012, Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 SONY ERICSSON MOBILE COMMUNICATIONS AB 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 GraphicsContext3DInternal_h
+#define GraphicsContext3D3DInternal_h
+
+#include "ANGLEWebKitBridge.h"
+#include "CanvasRenderingContext.h"
+#include "Extensions3DAndroid.h"
+#include "GraphicsContext3D.h"
+#include "HTMLCanvasElement.h"
+#include "SkRect.h"
+#include "Threading.h"
+#include "Timer.h"
+#include "TransformationMatrix.h"
+#include "WebGLLayer.h"
+
+#include <wtf/Deque.h>
+#include <wtf/RefPtr.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <ui/GraphicBuffer.h>
+
+// This can be increased to 3, for example, if that has a positive impact on performance.
+#define NUM_BUFFERS 2
+
+#include <cutils/properties.h>
+#include <cutils/log.h>
+
+#define LOGWEBGL(...) (GraphicsContext3DInternal::s_loggingEnabled ? \
+ (void)android_printLog(ANDROID_LOG_DEBUG, "WebGL", __VA_ARGS__) : (void)0)
+
+using namespace android;
+
+namespace WebCore {
+
+#define CLAMP(x) GraphicsContext3DInternal::clampValue(x)
+
+typedef enum {
+ THREAD_STATE_STOPPED,
+ THREAD_STATE_RUN,
+ THREAD_STATE_RESTART,
+ THREAD_STATE_STOP
+} thread_state_t;
+
+class WebGLFPSTimer;
+class GraphicsContext3DProxy;
+class FBO;
+
+class GraphicsContext3DInternal : public RefCounted<GraphicsContext3DInternal> {
+public:
+ GraphicsContext3DInternal(HTMLCanvasElement* canvas, GraphicsContext3D::Attributes attrs,
+ HostWindow* hostWindow);
+ ~GraphicsContext3DInternal();
+
+ bool isValid() { return m_contextId > 0; }
+
+ PlatformLayer* platformLayer() const;
+
+ void makeContextCurrent();
+ GraphicsContext3D::Attributes getContextAttributes();
+ void reshape(int width, int height);
+
+ unsigned long getError();
+ void synthesizeGLError(unsigned long error);
+
+ void recreateSurface();
+ void releaseSurface();
+
+ void markContextChanged();
+ void markLayerComposited() { m_layerComposited = true; }
+ bool layerComposited() const { return m_layerComposited; }
+
+ void updateFrontBuffer();
+ bool lockFrontBuffer(EGLImageKHR& image, SkRect& rect);
+ void releaseFrontBuffer();
+
+ void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
+ PassRefPtr<ImageData> paintRenderingResultsToImageData();
+ bool paintCompositedResultsToCanvas(CanvasRenderingContext* context);
+
+ // Shader handling, required since we validate shader source with ANGLE
+ void compileShader(Platform3DObject shader);
+ String getShaderInfoLog(Platform3DObject shader);
+ String getShaderSource(Platform3DObject shader);
+ void shaderSource(Platform3DObject shader, const String& string);
+
+ void viewport(long x, long y, unsigned long width, unsigned long height);
+
+ int width() { return m_width; }
+ int height() { return m_height; }
+
+ Extensions3D* getExtensions() { return m_extensions.get(); }
+
+ void bindFramebuffer(GC3Denum target, Platform3DObject buffer);
+
+ static GLclampf clampValue(GLclampf x) {
+ GLclampf tmp = x;
+ if (tmp < 0.0f)
+ tmp = 0.0f;
+ else if (tmp > 1.0f)
+ tmp = 1.0f;
+ return tmp;
+ }
+
+ static GLclampf clampValue(double d) {
+ GLclampf tmp = (GLclampf)d;
+ if (tmp < 0.0f)
+ tmp = 0.0f;
+ else if (tmp > 1.0f)
+ tmp = 1.0f;
+ return tmp;
+ }
+
+ static EGLint checkEGLError(const char* s);
+ static GLint checkGLError(const char* s);
+ static void enableLogging();
+ static bool s_loggingEnabled;
+
+private:
+ bool initEGL();
+ bool createContext(bool createEGLContext);
+ void deleteContext(bool deleteEGLContext);
+
+ RefPtr<GraphicsContext3DProxy> m_proxy;
+ WebGLLayer *m_compositingLayer;
+ HTMLCanvasElement* m_canvas;
+ GraphicsContext3D::Attributes m_attrs;
+ bool m_layerComposited;
+ bool m_canvasDirty;
+
+ int m_width;
+ int m_height;
+ int m_maxwidth;
+ int m_maxheight;
+
+ EGLDisplay m_dpy;
+ EGLConfig m_config;
+ EGLSurface m_surface;
+ EGLContext m_context;
+
+ // Routines for FBOs
+ FBO* m_fbo[NUM_BUFFERS];
+ GLuint m_boundFBO;
+ FBO* m_currentFBO;
+ FBO* m_frontFBO;
+ Deque<FBO*> m_freeBuffers;
+ Deque<FBO*> m_queuedBuffers;
+ Deque<FBO*> m_preparedBuffers;
+ WTF::Mutex m_fboMutex;
+ WTF::ThreadCondition m_fboCondition;
+
+ void startSyncThread();
+ void stopSyncThread();
+ static void* syncThreadStart(void* ctx);
+ void runSyncThread();
+ ThreadIdentifier m_syncThread;
+ thread_state_t m_threadState;
+ WTF::Mutex m_threadMutex;
+ WTF::ThreadCondition m_threadCondition;
+
+ void syncTimerFired(Timer<GraphicsContext3DInternal>*);
+ FBO* dequeueBuffer();
+ void swapBuffers();
+ Timer<GraphicsContext3DInternal> m_syncTimer;
+ bool m_syncRequested;
+
+ OwnPtr<WebGLFPSTimer> m_webGLFPSTimer;
+
+ typedef struct {
+ String source;
+ String log;
+ bool isValid;
+ } ShaderSourceEntry;
+ HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap;
+ ANGLEWebKitBridge m_compiler;
+
+ // Errors raised by synthesizeGLError().
+ ListHashSet<unsigned long> m_syntheticErrors;
+
+ struct {
+ GLint x, y;
+ GLsizei width, height;
+ } m_savedViewport;
+ OwnPtr<Extensions3DAndroid> m_extensions;
+ int m_contextId;
+
+ // Java method used for invalidating the canvas area
+ jobject m_webView;
+ jmethodID m_postInvalidate;
+};
+
+} // namespace WebCore
+
+#endif // GraphicsContext3DInternal_h
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp
new file mode 100644
index 0000000..e2ab6f9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * 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"
+
+#if ENABLE(WEBGL)
+
+#include "GraphicsContext3DProxy.h"
+#include "GraphicsContext3DInternal.h"
+
+namespace WebCore {
+
+GraphicsContext3DProxy::GraphicsContext3DProxy()
+ : m_texture(0)
+{
+ LOGWEBGL("GraphicsContext3DProxy::GraphicsContext3DProxy(), this = %p", this);
+}
+
+GraphicsContext3DProxy::~GraphicsContext3DProxy()
+{
+ LOGWEBGL("GraphicsContext3DProxy::~GraphicsContext3DProxy(), this = %p", this);
+}
+
+void GraphicsContext3DProxy::setGraphicsContext(GraphicsContext3DInternal* context)
+{
+ MutexLocker lock(m_mutex);
+ m_context = context;
+}
+
+bool GraphicsContext3DProxy::lockFrontBuffer(GLuint& texture, SkRect& rect)
+{
+ MutexLocker lock(m_mutex);
+ if (!m_context) {
+ return false;
+ }
+ EGLImageKHR image;
+ bool locked = m_context->lockFrontBuffer(image, rect);
+ if (locked) {
+ if (m_texture == 0)
+ glGenTextures(1, &m_texture);
+
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_texture);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ texture = m_texture;
+ }
+
+ return locked;
+}
+
+void GraphicsContext3DProxy::releaseFrontBuffer()
+{
+ MutexLocker lock(m_mutex);
+ if (m_texture) {
+ glDeleteTextures(1, &m_texture);
+ m_texture = 0;
+ }
+ if (!m_context) {
+ return;
+ }
+ m_context->releaseFrontBuffer();
+}
+}
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h
new file mode 100644
index 0000000..1cc1453
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * 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 GraphicsContext3DProxy_h
+#define GraphicsContext3DProxy_h
+
+#include "config.h"
+
+#include "SkRect.h"
+#include "Threading.h"
+#include <wtf/RefCounted.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+class GraphicsContext3DInternal;
+
+class GraphicsContext3DProxy: public RefCounted<GraphicsContext3DProxy> {
+public:
+ GraphicsContext3DProxy();
+ ~GraphicsContext3DProxy();
+
+ void setGraphicsContext(GraphicsContext3DInternal* context);
+
+ bool lockFrontBuffer(GLuint& texture, SkRect& rect);
+ void releaseFrontBuffer();
+
+private:
+ WTF::Mutex m_mutex;
+ GraphicsContext3DInternal* m_context;
+ GLuint m_texture;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 6edbe6a..7d11030 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -106,6 +107,9 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_haveContents(false),
m_newImage(false),
m_image(0),
+#if ENABLE(WEBGL)
+ m_is3DCanvas(false),
+#endif
m_fixedBackgroundLayer(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
@@ -478,6 +482,14 @@ void GraphicsLayerAndroid::setNeedsDisplay()
setNeedsDisplayInRect(rect);
}
+#if ENABLE(WEBGL)
+void GraphicsLayerAndroid::setContentsNeedsDisplay()
+{
+ if (m_is3DCanvas)
+ setNeedsDisplay();
+}
+#endif
+
// Helper to set and clear the painting phase as well as auto restore the
// original phase.
class PaintingPhase {
@@ -1074,6 +1086,33 @@ void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
}
}
+#if ENABLE(WEBGL)
+void GraphicsLayerAndroid::setContentsToCanvas(PlatformLayer* canvasLayer)
+{
+ if (m_contentLayer != canvasLayer && canvasLayer) {
+ // Copy data from the original content layer to the new one
+ canvasLayer->setPosition(m_contentLayer->getPosition().fX,
+ m_contentLayer->getPosition().fY);
+ canvasLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight());
+ canvasLayer->setDrawTransform(*m_contentLayer->drawTransform());
+
+ canvasLayer->ref();
+ m_contentLayer->unref();
+ m_contentLayer = canvasLayer;
+
+ // If the parent exists then notify it to re-sync it's children
+ if (m_parent) {
+ GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
+ parent->m_needsSyncChildren = true;
+ }
+ m_needsSyncChildren = true;
+ m_is3DCanvas = true;
+
+ setDrawsContent(true);
+ }
+}
+#endif
+
PlatformLayer* GraphicsLayerAndroid::platformLayer() const
{
ALOGV("platformLayer");
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 28d4b09..5418745 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -92,6 +93,10 @@ public:
virtual void setNeedsDisplay();
virtual void setNeedsDisplayInRect(const FloatRect&);
+#if ENABLE(WEBGL)
+ virtual void setContentsNeedsDisplay();
+#endif
+
virtual bool addAnimation(const KeyframeValueList& valueList,
const IntSize& boxSize,
const Animation* anim,
@@ -116,6 +121,9 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsToMedia(PlatformLayer*);
+#if ENABLE(WEBGL)
+ virtual void setContentsToCanvas(PlatformLayer*);
+#endif
virtual PlatformLayer* platformLayer() const;
void pauseDisplay(bool state);
@@ -165,6 +173,12 @@ private:
bool m_newImage;
Image* m_image;
+#if ENABLE(WEBGL)
+ bool m_is3DCanvas;
+#endif
+
+ SkRegion m_dirtyRegion;
+
LayerAndroid* m_contentLayer;
FixedBackgroundImageLayerAndroid* m_fixedBackgroundLayer;
LayerAndroid* m_foregroundLayer;
diff --git a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index f36200d..9571ec2 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -30,6 +30,7 @@
#include "BitmapImage.h"
#include "ColorSpace.h"
#include "GraphicsContext.h"
+#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
#include "PlatformBridge.h"
#include "PlatformGraphicsContext.h"
@@ -43,6 +44,10 @@
#include "SkStream.h"
#include "SkUnPreMultiply.h"
+#include "image-encoders/skia/JPEGImageEncoder.h"
+#include "image-encoders/skia/PNGImageEncoder.h"
+#include <wtf/text/StringConcatenate.h>
+
using namespace std;
namespace WebCore {
@@ -245,8 +250,36 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
}
}
+template <typename T>
+static String ImageToDataURL(T& source, const String& mimeType, const double* quality)
+{
+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
+
+ Vector<unsigned char> encodedImage;
+ if (mimeType == "image/jpeg") {
+ int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality;
+ if (quality && *quality >= 0.0 && *quality <= 1.0)
+ compressionQuality = static_cast<int>(*quality * 100 + 0.5);
+ if (!JPEGImageEncoder::encode(source, compressionQuality, &encodedImage))
+ return "data:,";
+ } else {
+ if (!PNGImageEncoder::encode(source, &encodedImage))
+ return "data:,";
+ ASSERT(mimeType == "image/png");
+ }
+
+ Vector<char> base64Data;
+ base64Encode(*reinterpret_cast<Vector<char>*>(&encodedImage), base64Data);
+
+ return makeString("data:", mimeType, ";base64,", base64Data);
+}
+
+String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality)
+{
+ return ImageToDataURL(source, mimeType, quality);
+}
-String ImageBuffer::toDataURL(const String&, const double*) const
+String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
{
// Encode the image into a vector.
SkDynamicMemoryWStream pngStream;
diff --git a/Source/WebCore/platform/graphics/android/WebGLLayer.cpp b/Source/WebCore/platform/graphics/android/WebGLLayer.cpp
new file mode 100644
index 0000000..9feb2e1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/WebGLLayer.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * 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"
+
+#if ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
+
+#include "WebGLLayer.h"
+
+#include "GraphicsContext3DInternal.h"
+#include "DrawQuadData.h"
+#include "SkRect.h"
+#include "TilesManager.h"
+#include "TransformationMatrix.h"
+
+namespace WebCore {
+
+WebGLLayer::WebGLLayer(PassRefPtr<GraphicsContext3DProxy> proxy)
+ : LayerAndroid((RenderLayer*)0)
+ , m_proxy(proxy)
+{
+}
+
+WebGLLayer::WebGLLayer(const WebGLLayer& layer)
+ : LayerAndroid(layer)
+ , m_proxy(layer.m_proxy)
+{
+}
+
+WebGLLayer::~WebGLLayer()
+{
+}
+
+bool WebGLLayer::drawGL(bool layerTilesDisabled)
+{
+ bool askScreenUpdate = false;
+
+ askScreenUpdate |= LayerAndroid::drawGL(layerTilesDisabled);
+
+ if (m_proxy.get()) {
+ GLuint texture;
+ SkRect localBounds;
+ bool locked = m_proxy->lockFrontBuffer(texture, localBounds);
+ if (locked) {
+ // Flip the y-coordinate
+ TransformationMatrix transform = m_drawTransform;
+ transform = transform.translate(0, 2 * localBounds.top() + localBounds.height());
+ transform = transform.scale3d(1.0, -1.0, 1.0);
+ TextureQuadData data(texture, GL_TEXTURE_EXTERNAL_OES, GL_LINEAR, LayerQuad, &transform, &localBounds);
+ TilesManager::instance()->shader()->drawQuad(&data);
+ m_proxy->releaseFrontBuffer();
+ }
+ }
+
+ return askScreenUpdate;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/WebGLLayer.h b/Source/WebCore/platform/graphics/android/WebGLLayer.h
new file mode 100644
index 0000000..6a69082
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/WebGLLayer.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * 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 WebGLLayer_h
+#define WebGLLayer_h
+
+#include "config.h"
+
+#if ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
+
+#include "GLUtils.h"
+#include "GraphicsContext3DProxy.h"
+#include "LayerAndroid.h"
+#include "PassRefPtr.h"
+#include "RefPtr.h"
+#include <jni.h>
+
+namespace WebCore {
+
+class GraphicsContext3DInternal;
+
+class WebGLLayer : public LayerAndroid {
+public:
+ WebGLLayer(PassRefPtr<GraphicsContext3DProxy> proxy);
+ WebGLLayer(const WebGLLayer& layer);
+ virtual ~WebGLLayer();
+
+ virtual LayerAndroid* copy() const { return new WebGLLayer(*this); }
+ virtual bool drawGL(bool layerTilesDisabled);
+ virtual bool isWebGL() const { return true; }
+
+private:
+ RefPtr<GraphicsContext3DProxy> m_proxy;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
+#endif // WebGLLayer_h
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 1064388..d58c4ee 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -27,7 +27,7 @@
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkTypeface.h"
-#include "Surface.h"
+#include "rendering/Surface.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
@@ -148,8 +148,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
}
if (hasAbsoluteChildren && !hasOnlyAbsoluteFollowers) {
- Vector<LayerAndroid*> normalLayers;
- Vector<LayerAndroid*> absoluteLayers;
+ WTF::Vector<LayerAndroid*> normalLayers;
+ WTF::Vector<LayerAndroid*> absoluteLayers;
for (int i = 0; i < layer.countChildren(); i++) {
LayerAndroid* child = layer.getChild(i);
if (child->isPositionAbsolute()
@@ -307,7 +307,7 @@ void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim)
void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
{
KeyframesMap::const_iterator end = m_animations.end();
- Vector<pair<String, int> > toDelete;
+ WTF::Vector<pair<String, int> > toDelete;
for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
if ((it->second)->type() == property)
toDelete.append(it->first);
@@ -320,7 +320,7 @@ void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
void LayerAndroid::removeAnimationsForKeyframes(const String& name)
{
KeyframesMap::const_iterator end = m_animations.end();
- Vector<pair<String, int> > toDelete;
+ WTF::Vector<pair<String, int> > toDelete;
for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
if ((it->second)->isNamed(name))
toDelete.append(it->first);
@@ -704,7 +704,7 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
int count = this->countChildren();
if (count > 0) {
mergeState->depth++;
- Vector <LayerAndroid*> sublayers;
+ WTF::Vector <LayerAndroid*> sublayers;
for (int i = 0; i < count; i++)
sublayers.append(getChild(i));
@@ -895,7 +895,7 @@ bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style)
bool askScreenUpdate = false;
int count = this->countChildren();
if (count > 0) {
- Vector <LayerAndroid*> sublayers;
+ WTF::Vector <LayerAndroid*> sublayers;
for (int i = 0; i < count; i++)
sublayers.append(this->getChild(i));
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 6c2e43d..b3518e9 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -243,6 +243,7 @@ public:
virtual bool isIFrame() const { return false; }
virtual bool isIFrameContent() const { return false; }
virtual bool isFixedBackground() const { return false; }
+ virtual bool isWebGL() const { return false; }
bool isPositionFixed() const { return m_fixedPosition; }
void setAbsolutePosition(bool isAbsolute) { m_isPositionAbsolute = isAbsolute; }
diff --git a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
index 346afe4..e0975ee 100644
--- a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
@@ -120,7 +120,7 @@ private:
// The retiredTextures is used to communicate between UI thread and webcore
// thread. Basically, GL textures are determined to retire in the webcore
// thread, and really get deleted in the UI thread.
- Vector<GLuint> m_retiredTextures;
+ WTF::Vector<GLuint> m_retiredTextures;
android::Mutex m_retiredTexturesLock;
GLuint createTextureFromImage(RenderSkinMediaButton::MediaButton buttonType);
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 6caf93b..24d8fc9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -419,14 +419,6 @@ bool Surface::blitFromContents(Tile* tile)
if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content())
return false;
- if (tile->frontTexture() != tile->lastDrawnTexture()) {
- // the below works around an issue where glTexSubImage2d can't update a
- // texture that hasn't drawn yet by drawing it off screen.
- // glFlush() and glFinish() work also, but are likely more wasteful.
- SkRect rect = SkRect::MakeXYWH(-100, -100, 0, 0);
- FloatRect fillPortion(0, 0, 0, 0);
- tile->frontTexture()->drawGL(false, rect, 1.0f, 0, false, true, fillPortion);
- }
LayerContent* content = getFirstLayer()->content();
// Extract the dirty rect from the region. Note that this is *NOT* constrained
// to this tile
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
index 76be981..e2b9554 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
@@ -52,7 +52,6 @@ Tile::Tile(bool isLayerTile)
, m_y(-1)
, m_frontTexture(0)
, m_backTexture(0)
- , m_lastDrawnTexture(0)
, m_scale(1)
, m_dirty(true)
, m_repaintsPending(0)
@@ -240,7 +239,6 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale,
m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform,
forceBlending, usePointSampling, fillPortion);
- m_lastDrawnTexture = m_frontTexture;
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h
index f467bb0..1a50587 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h
@@ -127,7 +127,6 @@ public:
int y() const { return m_y; }
TileTexture* frontTexture() { return m_frontTexture; }
TileTexture* backTexture() { return m_backTexture; }
- TileTexture* lastDrawnTexture() { return m_lastDrawnTexture; }
// only used for prioritization - the higher, the more relevant the tile is
unsigned long long drawCount() { return m_drawCount; }
@@ -152,7 +151,6 @@ private:
TileTexture* m_frontTexture;
TileTexture* m_backTexture;
- TileTexture* m_lastDrawnTexture;
float m_scale;
// used to signal that the that the tile is out-of-date and needs to be
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
index b15fa6d..fd7b92e 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
@@ -512,7 +512,11 @@ void TransferQueue::setTextureUploadType(TextureUploadType type)
setPendingDiscard();
+#ifdef FORCE_CPU_UPLOAD
+ m_currentUploadType = CpuUpload; // force to cpu upload mode for now until gpu upload mode is fixed
+#else
m_currentUploadType = type;
+#endif
ALOGD("Now we set the upload to %s", m_currentUploadType == GpuUpload ? "GpuUpload" : "CpuUpload");
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index 55011b0..4ced1ea 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -69,7 +69,11 @@ enum TextureUploadType {
GpuUpload = 1
};
+#ifdef FORCE_CPU_UPLOAD
+#define DEFAULT_UPLOAD_TYPE CpuUpload
+#else
#define DEFAULT_UPLOAD_TYPE GpuUpload
+#endif
class TileTransferData {
public:
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
index 24a9f90..504eb08 100644
--- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008-2009 Torch Mobile, Inc.
* Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ * Copyright (C) 2012, Sony Ericsson Mobile Communications AB
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -94,10 +95,10 @@ bool matchesCURSignature(char* contents)
}
-#if !OS(ANDROID)
// This method requires BMPImageDecoder, PNGImageDecoder, ICOImageDecoder and
// JPEGDecoder, which aren't used on Android, and which don't all compile.
// TODO: Find a better fix.
+// WebGL: Activated the GIF and PNG image decoders for Android.
ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
{
static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP"
@@ -109,9 +110,12 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO
if (matchesGIFSignature(contents))
return new GIFImageDecoder(alphaOption, gammaAndColorProfileOption);
+#if !OS(ANDROID) || ENABLE(WEBGL)
if (matchesPNGSignature(contents))
return new PNGImageDecoder(alphaOption, gammaAndColorProfileOption);
+#endif
+#if !OS(ANDROID)
if (matchesJPEGSignature(contents))
return new JPEGImageDecoder(alphaOption, gammaAndColorProfileOption);
@@ -125,10 +129,10 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO
if (matchesICOSignature(contents) || matchesCURSignature(contents))
return new ICOImageDecoder(alphaOption, gammaAndColorProfileOption);
+#endif // !OS(ANDROID)
return 0;
}
-#endif // !OS(ANDROID)
#if !USE(SKIA)
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.h b/Source/WebCore/platform/network/ResourceRequestBase.h
index 53e1160..4c7abcb 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.h
+++ b/Source/WebCore/platform/network/ResourceRequestBase.h
@@ -65,6 +65,7 @@ namespace WebCore {
TargetIsWorker,
TargetIsSharedWorker,
TargetIsPrefetch,
+ TargetIsPrerender,
TargetIsFavicon,
};
diff --git a/Source/WebCore/platform/network/android/ResourceRequest.h b/Source/WebCore/platform/network/android/ResourceRequest.h
index 745c2ef..456f016 100644
--- a/Source/WebCore/platform/network/android/ResourceRequest.h
+++ b/Source/WebCore/platform/network/android/ResourceRequest.h
@@ -28,7 +28,6 @@
#ifndef ResourceRequest_h
#define ResourceRequest_h
-#include "CachedResource.h"
#include "ResourceRequestBase.h"
namespace WebCore {
diff --git a/Source/WebCore/rendering/HitTestResult.cpp b/Source/WebCore/rendering/HitTestResult.cpp
index 77ccc4b..cb2a607 100644
--- a/Source/WebCore/rendering/HitTestResult.cpp
+++ b/Source/WebCore/rendering/HitTestResult.cpp
@@ -327,7 +327,7 @@ KURL HitTestResult::absoluteMediaURL() const
{
#if ENABLE(VIDEO)
if (HTMLMediaElement* mediaElt = mediaElement())
- return m_innerNonSharedNode->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(mediaElt->currentSrc()));
+ return mediaElt->currentSrc();
return KURL();
#else
return KURL();
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index a2469a0..3189ad0 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -1141,6 +1141,13 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
lineMidpointState.reset();
resolver.setPosition(end);
+ // Exit loop if we have already filled the container
+ // when overflow mode is 'hidden'
+ if (style()->height().value()) {
+ EOverflow ov = style()->overflowY();
+ if (ov == OHIDDEN && logicalHeight() > style()->height().value())
+ break;
+ }
}
if (endLine) {
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index b6662f6..3cdeda8 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -4049,6 +4049,9 @@ bool RenderLayer::shouldBeNormalFlowOnly() const
|| renderer()->hasReflection()
|| renderer()->hasMask()
|| renderer()->isVideo()
+#if PLATFORM(ANDROID)
+ || renderer()->isCanvas()
+#endif
|| renderer()->isEmbeddedObject()
|| renderer()->isApplet()
|| renderer()->isRenderIFrame()
@@ -4070,6 +4073,9 @@ bool RenderLayer::isSelfPaintingLayer() const
|| renderer()->hasMask()
|| renderer()->isTableRow()
|| renderer()->isVideo()
+#if PLATFORM(ANDROID)
+ || renderer()->isCanvas()
+#endif
|| renderer()->isEmbeddedObject()
|| renderer()->isApplet()
|| renderer()->isRenderIFrame();
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index c0c562a..7154a8d 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -103,7 +103,7 @@ RenderLayerBacking::~RenderLayerBacking()
void RenderLayerBacking::createGraphicsLayer()
{
m_graphicsLayer = GraphicsLayer::create(this);
-
+
#ifndef NDEBUG
m_graphicsLayer->setName(nameForLayer());
#endif // NDEBUG
@@ -143,7 +143,7 @@ void RenderLayerBacking::updateLayerTransform(const RenderStyle* style)
style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
makeMatrixRenderable(t, compositor()->canRender3DTransforms());
}
-
+
m_graphicsLayer->setTransform(t);
}
@@ -160,14 +160,14 @@ static bool layerOrAncestorIsTransformed(RenderLayer* layer)
if (curr->hasTransform())
return true;
}
-
+
return false;
}
-
+
#if ENABLE(FULLSCREEN_API)
static bool layerOrAncestorIsFullScreen(RenderLayer* layer)
{
- // Don't traverse through the render layer tree if we do not yet have a full screen renderer.
+ // Don't traverse through the render layer tree if we do not yet have a full screen renderer.
if (!layer->renderer()->document()->fullScreenRenderer())
return false;
@@ -175,7 +175,7 @@ static bool layerOrAncestorIsFullScreen(RenderLayer* layer)
if (curr->renderer()->isRenderFullScreen())
return true;
}
-
+
return false;
}
#endif
@@ -189,7 +189,7 @@ void RenderLayerBacking::updateCompositedBounds()
// We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist. If this
// is a fullscreen renderer, don't clip to the viewport, as the renderer will be asked to
// display outside of the viewport bounds.
- if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer)
+ if (compositor()->compositingConsultsOverlap() && !layerOrAncestorIsTransformed(m_owningLayer)
#if ENABLE(FULLSCREEN_API)
&& !layerOrAncestorIsFullScreen(m_owningLayer)
#endif
@@ -210,7 +210,7 @@ void RenderLayerBacking::updateCompositedBounds()
layerBounds.intersect(clippingBounds);
}
-
+
// If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
// then we need to ensure that the compositing layer has non-zero size so that we can apply
// the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
@@ -240,14 +240,14 @@ void RenderLayerBacking::updateAfterLayout(UpdateDepth updateDepth, bool isUpdat
if (!layerCompositor->compositingLayersNeedRebuild()) {
// Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
// position of this layer's GraphicsLayer depends on the position of our compositing
- // ancestor's GraphicsLayer. That cannot be determined until all the descendant
+ // ancestor's GraphicsLayer. That cannot be determined until all the descendant
// RenderLayers of that ancestor have been processed via updateLayerPositions().
//
// The solution is to update compositing children of this layer here,
// via updateCompositingChildrenGeometry().
updateCompositedBounds();
layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, updateDepth);
-
+
if (isUpdateRoot) {
updateGraphicsLayerGeometry();
layerCompositor->updateRootLayerPosition();
@@ -263,7 +263,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
bool layerConfigChanged = false;
if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
layerConfigChanged = true;
-
+
if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), compositor->clipsCompositingDescendants(m_owningLayer)))
layerConfigChanged = true;
@@ -339,13 +339,13 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
// Set opacity, if it is not animating.
if (!renderer()->animation()->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
updateLayerOpacity(renderer()->style());
-
+
RenderStyle* style = renderer()->style();
m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
-
+
// We compute everything relative to the enclosing compositing layer.
IntRect ancestorCompositingBounds;
if (compAncestor) {
@@ -368,7 +368,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
graphicsLayerParentLocation = clippingBox.location();
} else
graphicsLayerParentLocation = ancestorCompositingBounds.location();
-
+
if (compAncestor && m_ancestorClippingLayer) {
// Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
// layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
@@ -387,14 +387,14 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation));
-
+
IntSize oldOffsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - IntPoint());
-
+
// If the compositing layer offset changes, we need to repaint.
if (oldOffsetFromRenderer != m_graphicsLayer->offsetFromRenderer())
m_graphicsLayer->setNeedsDisplay();
-
+
FloatSize oldSize = m_graphicsLayer->size();
FloatSize newSize = relativeCompositingBounds.size();
if (oldSize != newSize) {
@@ -413,7 +413,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
m_clippingLayer->setSize(clippingBox.size());
m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
}
-
+
if (m_maskLayer) {
if (m_maskLayer->size() != m_graphicsLayer->size()) {
m_maskLayer->setSize(m_graphicsLayer->size());
@@ -421,7 +421,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
m_maskLayer->setPosition(FloatPoint());
}
-
+
if (m_owningLayer->hasTransform()) {
const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
@@ -439,7 +439,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
RenderStyle* style = renderer()->style();
if (style->hasPerspective()) {
TransformationMatrix t = owningLayer()->perspectiveTransform();
-
+
if (m_clippingLayer) {
m_clippingLayer->setChildrenTransform(t);
m_graphicsLayer->setChildrenTransform(TransformationMatrix());
@@ -475,7 +475,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
reflectionBacking->updateGraphicsLayerGeometry();
-
+
// The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
// but the reflected layer is the bounds of this layer, so we need to position it appropriately.
FloatRect layerBounds = compositedBounds();
@@ -544,7 +544,7 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs
m_ancestorClippingLayer = 0;
layersChanged = true;
}
-
+
if (needsDescendantClip) {
if (!m_clippingLayer) {
m_clippingLayer = GraphicsLayer::create(this);
@@ -559,7 +559,7 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs
m_clippingLayer = 0;
layersChanged = true;
}
-
+
return layersChanged;
}
@@ -702,18 +702,18 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co
float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
{
float finalOpacity = rendererOpacity;
-
+
for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
// We only care about parents that are stacking contexts.
// Recall that opacity creates stacking context.
if (!curr->isStackingContext())
continue;
-
+
// If we found a compositing layer, we want to compute opacity
// relative to it. So we can break here.
if (curr->isComposited())
break;
-
+
finalOpacity *= curr->renderer()->opacity();
}
@@ -742,17 +742,17 @@ bool RenderLayerBacking::rendererHasBackground() const
RenderObject* htmlObject = renderer()->firstChild();
if (!htmlObject)
return false;
-
+
if (htmlObject->hasBackground())
return true;
-
+
RenderObject* bodyObject = htmlObject->firstChild();
if (!bodyObject)
return false;
-
+
return bodyObject->hasBackground();
}
-
+
return renderer()->hasBackground();
}
@@ -795,42 +795,42 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
// If we have got this far and the renderer has no children, then we're ok.
if (!renderObject->firstChild())
return true;
-
+
if (renderObject->node() && renderObject->node()->isDocumentNode()) {
// Look to see if the root object has a non-simple backgound
RenderObject* rootObject = renderObject->document()->documentElement()->renderer();
if (!rootObject)
return false;
-
+
style = rootObject->style();
-
+
// Reject anything that has a border, a border-radius or outline,
// or is not a simple background (no background, or solid color).
if (hasBoxDecorationsOrBackgroundImage(style))
return false;
-
+
// Now look at the body's renderer.
HTMLElement* body = renderObject->document()->body();
RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
if (!bodyObject)
return false;
-
+
style = bodyObject->style();
-
+
if (hasBoxDecorationsOrBackgroundImage(style))
return false;
// Check to see if all the body's children are compositing layers.
if (hasNonCompositingDescendants())
return false;
-
+
return true;
}
// Check to see if all the renderer's children are compositing layers.
if (hasNonCompositingDescendants())
return false;
-
+
return true;
}
@@ -846,7 +846,7 @@ bool RenderLayerBacking::hasNonCompositingDescendants() const
if (!child->hasLayer()) {
if (child->isRenderInline() || !child->isBox())
return true;
-
+
if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
return true;
}
@@ -913,7 +913,7 @@ bool RenderLayerBacking::containsPaintedContent() const
bool RenderLayerBacking::isDirectlyCompositedImage() const
{
RenderObject* renderObject = renderer();
-
+
if (!renderObject->isImage() || hasBoxDecorationsOrBackground(renderObject) || renderObject->hasClip())
return false;
@@ -932,7 +932,7 @@ void RenderLayerBacking::contentChanged(RenderLayer::ContentChangeType changeTyp
updateImageContents();
return;
}
-
+
if ((changeType == RenderLayer::MaskImageChanged) && m_maskLayer) {
// The composited layer bounds relies on box->maskClipRect(), which changes
// when the mask image becomes available.
@@ -967,7 +967,7 @@ void RenderLayerBacking::updateImageContents()
// This is a no-op if the layer doesn't have an inner layer for the image.
m_graphicsLayer->setContentsToImage(image);
-
+
// Image animation is "lazy", in that it automatically stops unless someone is drawing
// the image. So we have to kick the animation each time; this has the downside that the
// image will keep animating, even if its layer is not visible.
@@ -1029,7 +1029,7 @@ bool RenderLayerBacking::paintingGoesToWindow() const
{
if (m_owningLayer->isRootLayer())
return compositor()->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame;
-
+
return false;
}
@@ -1037,7 +1037,7 @@ void RenderLayerBacking::setContentsNeedDisplay()
{
if (m_graphicsLayer && m_graphicsLayer->drawsContent())
m_graphicsLayer->setNeedsDisplay();
-
+
if (m_foregroundLayer && m_foregroundLayer->drawsContent())
m_foregroundLayer->setNeedsDisplay();
@@ -1092,13 +1092,13 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
ASSERT_NOT_REACHED();
return;
}
-
+
m_owningLayer->updateLayerListsIfNeeded();
-
+
// Calculate the clip rects we should use.
IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
m_owningLayer->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
-
+
int x = layerBounds.x(); // layerBounds is computed relative to rootLayer
int y = layerBounds.y();
int tx = x - m_owningLayer->renderBoxX();
@@ -1123,7 +1123,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Paint our background first, before painting any child layers.
// Establish the clip used to paint our background.
setClip(context, paintDirtyRect, damageRect);
-
+
#if PLATFORM(ANDROID)
PaintPhase phase = PaintPhaseBlockBackground;
if (paintingPhase & GraphicsLayerPaintBackgroundDecorations)
@@ -1138,7 +1138,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// z-index. We paint after we painted the background/border, so that the scrollbars will
// sit above the background/border.
m_owningLayer->paintOverflowControls(context, x, y, damageRect);
-
+
// Restore the clip.
restoreClip(context, paintDirtyRect, damageRect);
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
@@ -1156,14 +1156,14 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint.
m_owningLayer->paintList(m_owningLayer->negZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0);
}
-
+
bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly;
if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) {
// Set up the clip used when painting our children.
setClip(context, paintDirtyRect, clipRectToApply);
- PaintInfo paintInfo(context, clipRectToApply,
+ PaintInfo paintInfo(context, clipRectToApply,
selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
forceBlackText, paintingRootForRenderer, 0);
renderer()->paint(paintInfo, tx, ty);
@@ -1200,7 +1200,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Now walk the sorted list of children with positive z-indices.
m_owningLayer->paintList(m_owningLayer->posZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0);
}
-
+
if (shouldPaint && (paintingPhase & GraphicsLayerPaintMask)) {
if (renderer()->hasMask() && !selectionOnly && !damageRect.isEmpty()) {
setClip(context, paintDirtyRect, damageRect);
@@ -1208,7 +1208,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Paint the mask.
PaintInfo paintInfo(context, damageRect, PaintPhaseMask, false, paintingRootForRenderer, 0);
renderer()->paint(paintInfo, tx, ty);
-
+
// Restore the clip.
restoreClip(context, paintDirtyRect, damageRect);
}
@@ -1288,10 +1288,10 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
{
bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
-
+
if (!hasOpacity && !hasTransform)
return false;
-
+
KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
KeyframeValueList opacityVector(AnimatedPropertyOpacity);
@@ -1303,21 +1303,21 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
if (!keyframeStyle)
continue;
-
+
// Get timing function.
RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0)->timingFunction() : 0;
-
+
bool isFirstOrLastKeyframe = key == 0 || key == 1;
if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf));
-
+
if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
}
bool didAnimateTransform = false;
bool didAnimateOpacity = false;
-
+
if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) {
didAnimateTransform = true;
compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
@@ -1381,7 +1381,7 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
if (didAnimateTransform)
compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
-
+
return didAnimateOpacity || didAnimateTransform;
}
@@ -1489,7 +1489,7 @@ CompositingLayerType RenderLayerBacking::compositingLayerType() const
if (m_graphicsLayer->drawsContent())
return m_graphicsLayer->usingTiledLayer() ? TiledCompositingLayer : NormalCompositingLayer;
-
+
return ContainerCompositingLayer;
}
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index f5dddc0..1381dcb 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1564,11 +1564,11 @@ bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer)
if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
return false;
- if (renderer->isCanvas()) {
- HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
- return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
- }
- return false;
+ if (!renderer->isCanvas())
+ return false;
+
+ HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
+ return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
}
bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
diff --git a/Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp b/Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp
index ac4a63e..a5cf4ca 100644
--- a/Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp
+++ b/Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp
@@ -32,8 +32,8 @@ namespace WebCore {
// SVGShadowTreeContainerElement
-SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document)
- : SVGGElement(SVGNames::gTag, document)
+SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document, ConstructionType constructionType)
+ : SVGGElement(SVGNames::gTag, document, constructionType)
{
}
@@ -54,7 +54,7 @@ PassRefPtr<Element> SVGShadowTreeContainerElement::cloneElementWithoutAttributes
// SVGShadowTreeRootElement
inline SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, SVGUseElement* host)
- : SVGShadowTreeContainerElement(document)
+ : SVGShadowTreeContainerElement(document, CreateSVGShadowRoot)
{
setParent(host);
setInDocument();
diff --git a/Source/WebCore/rendering/svg/SVGShadowTreeElements.h b/Source/WebCore/rendering/svg/SVGShadowTreeElements.h
index 8cbd4b7..9ccda36 100644
--- a/Source/WebCore/rendering/svg/SVGShadowTreeElements.h
+++ b/Source/WebCore/rendering/svg/SVGShadowTreeElements.h
@@ -41,7 +41,7 @@ public:
}
protected:
- SVGShadowTreeContainerElement(Document*);
+ SVGShadowTreeContainerElement(Document*, ConstructionType = CreateSVGElement);
private:
virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
@@ -58,8 +58,6 @@ public:
void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
void clearSVGShadowHost();
- virtual bool isSVGShadowRoot() const { return true; }
-
private:
SVGShadowTreeRootElement(Document*, SVGUseElement* host);
};
diff --git a/Source/WebCore/svg/SVGElement.cpp b/Source/WebCore/svg/SVGElement.cpp
index 044f439..9ddc383 100644
--- a/Source/WebCore/svg/SVGElement.cpp
+++ b/Source/WebCore/svg/SVGElement.cpp
@@ -54,8 +54,8 @@ namespace WebCore {
using namespace HTMLNames;
-SVGElement::SVGElement(const QualifiedName& tagName, Document* document)
- : StyledElement(tagName, document, CreateSVGElement)
+SVGElement::SVGElement(const QualifiedName& tagName, Document* document, ConstructionType constructionType)
+ : StyledElement(tagName, document, constructionType)
{
}
diff --git a/Source/WebCore/svg/SVGElement.h b/Source/WebCore/svg/SVGElement.h
index 380fa0e..1bb10d9 100644
--- a/Source/WebCore/svg/SVGElement.h
+++ b/Source/WebCore/svg/SVGElement.h
@@ -110,7 +110,7 @@ public:
virtual void updateAnimatedSVGAttribute(const QualifiedName&) const;
protected:
- SVGElement(const QualifiedName&, Document*);
+ SVGElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
virtual void parseMappedAttribute(Attribute*);
diff --git a/Source/WebCore/svg/SVGFEImageElement.cpp b/Source/WebCore/svg/SVGFEImageElement.cpp
index f33cd36..2b8b21c 100644
--- a/Source/WebCore/svg/SVGFEImageElement.cpp
+++ b/Source/WebCore/svg/SVGFEImageElement.cpp
@@ -70,7 +70,8 @@ void SVGFEImageElement::requestImageResource()
if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer())
return;
- m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(href());
+ ResourceRequest request(ownerDocument()->completeURL(href()));
+ m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(request);
if (m_cachedImage)
m_cachedImage->addClient(this);
diff --git a/Source/WebCore/svg/SVGFontFaceUriElement.cpp b/Source/WebCore/svg/SVGFontFaceUriElement.cpp
index b017143..57b2ab7 100644
--- a/Source/WebCore/svg/SVGFontFaceUriElement.cpp
+++ b/Source/WebCore/svg/SVGFontFaceUriElement.cpp
@@ -95,7 +95,8 @@ void SVGFontFaceUriElement::loadFont()
String href = getAttribute(XLinkNames::hrefAttr);
if (!href.isNull()) {
CachedResourceLoader* cachedResourceLoader = document()->cachedResourceLoader();
- m_cachedFont = cachedResourceLoader->requestFont(href);
+ ResourceRequest request(document()->completeURL(href));
+ m_cachedFont = cachedResourceLoader->requestFont(request);
if (m_cachedFont) {
m_cachedFont->addClient(this);
m_cachedFont->beginLoadIfNeeded(cachedResourceLoader);
diff --git a/Source/WebCore/svg/SVGGElement.cpp b/Source/WebCore/svg/SVGGElement.cpp
index f7a48ec..1be08bf 100644
--- a/Source/WebCore/svg/SVGGElement.cpp
+++ b/Source/WebCore/svg/SVGGElement.cpp
@@ -33,8 +33,8 @@ namespace WebCore {
// Animated property declarations
DEFINE_ANIMATED_BOOLEAN(SVGGElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-SVGGElement::SVGGElement(const QualifiedName& tagName, Document* document)
- : SVGStyledTransformableElement(tagName, document)
+SVGGElement::SVGGElement(const QualifiedName& tagName, Document* document, ConstructionType constructionType)
+ : SVGStyledTransformableElement(tagName, document, constructionType)
{
}
diff --git a/Source/WebCore/svg/SVGGElement.h b/Source/WebCore/svg/SVGGElement.h
index c306f4a..8126957 100644
--- a/Source/WebCore/svg/SVGGElement.h
+++ b/Source/WebCore/svg/SVGGElement.h
@@ -40,7 +40,7 @@ public:
virtual bool isShadowTreeContainerElement() const { return false; }
protected:
- SVGGElement(const QualifiedName&, Document*);
+ SVGGElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
diff --git a/Source/WebCore/svg/SVGStyledElement.cpp b/Source/WebCore/svg/SVGStyledElement.cpp
index 79e1633..5a2fe5d 100644
--- a/Source/WebCore/svg/SVGStyledElement.cpp
+++ b/Source/WebCore/svg/SVGStyledElement.cpp
@@ -59,8 +59,8 @@ void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToId
propertyNameToIdMap->set(attrName.localName().impl(), propertyId);
}
-SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* document)
- : SVGElement(tagName, document)
+SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* document, ConstructionType constructionType)
+ : SVGElement(tagName, document, constructionType)
{
}
diff --git a/Source/WebCore/svg/SVGStyledElement.h b/Source/WebCore/svg/SVGStyledElement.h
index b6c0b96..1de3ac6 100644
--- a/Source/WebCore/svg/SVGStyledElement.h
+++ b/Source/WebCore/svg/SVGStyledElement.h
@@ -60,7 +60,7 @@ public:
virtual CSSStyleDeclaration* style() { return StyledElement::style(); }
protected:
- SVGStyledElement(const QualifiedName&, Document*);
+ SVGStyledElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
virtual bool rendererIsNeeded(RenderStyle*);
diff --git a/Source/WebCore/svg/SVGStyledLocatableElement.cpp b/Source/WebCore/svg/SVGStyledLocatableElement.cpp
index f29121b..5ccfb4b 100644
--- a/Source/WebCore/svg/SVGStyledLocatableElement.cpp
+++ b/Source/WebCore/svg/SVGStyledLocatableElement.cpp
@@ -29,8 +29,8 @@
namespace WebCore {
-SVGStyledLocatableElement::SVGStyledLocatableElement(const QualifiedName& tagName, Document* document)
- : SVGStyledElement(tagName, document)
+SVGStyledLocatableElement::SVGStyledLocatableElement(const QualifiedName& tagName, Document* document, ConstructionType constructionType)
+ : SVGStyledElement(tagName, document, constructionType)
{
}
diff --git a/Source/WebCore/svg/SVGStyledLocatableElement.h b/Source/WebCore/svg/SVGStyledLocatableElement.h
index 114ae83..3a9baf7 100644
--- a/Source/WebCore/svg/SVGStyledLocatableElement.h
+++ b/Source/WebCore/svg/SVGStyledLocatableElement.h
@@ -42,7 +42,7 @@ public:
virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const { return SVGLocatable::localCoordinateSpaceTransform(mode); }
protected:
- SVGStyledLocatableElement(const QualifiedName&, Document*);
+ SVGStyledLocatableElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
private:
virtual bool isStyledLocatable() const { return true; }
diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.cpp b/Source/WebCore/svg/SVGStyledTransformableElement.cpp
index 1e32f9a..bdb3fab 100644
--- a/Source/WebCore/svg/SVGStyledTransformableElement.cpp
+++ b/Source/WebCore/svg/SVGStyledTransformableElement.cpp
@@ -34,8 +34,8 @@ namespace WebCore {
// Animated property definitions
DEFINE_ANIMATED_TRANSFORM_LIST(SVGStyledTransformableElement, SVGNames::transformAttr, Transform, transform)
-SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* document)
- : SVGStyledLocatableElement(tagName, document)
+SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* document, ConstructionType constructionType)
+ : SVGStyledLocatableElement(tagName, document, constructionType)
{
}
diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.h b/Source/WebCore/svg/SVGStyledTransformableElement.h
index 9d6834a..e16dbc6 100644
--- a/Source/WebCore/svg/SVGStyledTransformableElement.h
+++ b/Source/WebCore/svg/SVGStyledTransformableElement.h
@@ -55,7 +55,7 @@ public:
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
protected:
- SVGStyledTransformableElement(const QualifiedName&, Document*);
+ SVGStyledTransformableElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
virtual void parseMappedAttribute(Attribute*);
virtual void svgAttributeChanged(const QualifiedName&);
diff --git a/Source/WebCore/xml/XSLImportRule.cpp b/Source/WebCore/xml/XSLImportRule.cpp
index c32da4e..d23f182 100644
--- a/Source/WebCore/xml/XSLImportRule.cpp
+++ b/Source/WebCore/xml/XSLImportRule.cpp
@@ -26,6 +26,7 @@
#include "CachedXSLStyleSheet.h"
#include "CachedResourceLoader.h"
+#include "Document.h"
#include "XSLStyleSheet.h"
namespace WebCore {
@@ -98,7 +99,8 @@ void XSLImportRule::loadSheet()
return;
}
- m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet(absHref);
+ ResourceRequest request(cachedResourceLoader->document()->completeURL(absHref));
+ m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet(request);
if (m_cachedSheet) {
m_cachedSheet->addClient(this);